@adminide-stack/yantra-mobile 12.0.28-alpha.8 → 12.0.28-alpha.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/stt.js +54 -0
- package/lib/api/stt.js.map +1 -0
- package/lib/assets/icon.png +0 -0
- package/lib/components/CustomDrawer.js +479 -0
- package/lib/components/CustomDrawer.js.map +1 -0
- package/lib/components/GatewayConnector/GatewayConnector.js +18 -0
- package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -0
- package/lib/components/GatewayToolbarButtonMobile.js +84 -0
- package/lib/components/GatewayToolbarButtonMobile.js.map +1 -0
- package/lib/components/NavigationHeader/NavigationHeader.js +214 -0
- package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -0
- package/lib/components/ThinkingIndicator.js +55 -0
- package/lib/components/ThinkingIndicator.js.map +1 -0
- package/lib/components/YantraBrandLoader.js +94 -0
- package/lib/components/YantraBrandLoader.js.map +1 -0
- package/lib/compute.js +114 -5
- package/lib/compute.js.map +1 -1
- package/lib/config/constants.js +18 -0
- package/lib/config/constants.js.map +1 -0
- package/lib/config/env-config.js +75 -19
- package/lib/config/env-config.js.map +1 -1
- package/lib/contexts/CdecliConnectionContext.js +47 -0
- package/lib/contexts/CdecliConnectionContext.js.map +1 -0
- package/lib/contexts/GatewayContext.js +77 -0
- package/lib/contexts/GatewayContext.js.map +1 -0
- package/lib/features/audio-input/AudioRecorderPanel.js +220 -0
- package/lib/features/audio-input/AudioRecorderPanel.js.map +1 -0
- package/lib/features/audio-input/MicErrorBoundary.js +34 -0
- package/lib/features/audio-input/MicErrorBoundary.js.map +1 -0
- package/lib/features/audio-input/useAudioPermission.js +24 -0
- package/lib/features/audio-input/useAudioPermission.js.map +1 -0
- package/lib/graphql/agentGatewayDocuments.js +53 -0
- package/lib/graphql/agentGatewayDocuments.js.map +1 -0
- package/lib/hooks/useAccountDefaultSettings.js +38 -0
- package/lib/hooks/useAccountDefaultSettings.js.map +1 -0
- package/lib/hooks/useCdecliAutoConnect.js +244 -0
- package/lib/hooks/useCdecliAutoConnect.js.map +1 -0
- package/lib/hooks/useCdecliChannel.js +161 -0
- package/lib/hooks/useCdecliChannel.js.map +1 -0
- package/lib/hooks/useChatApi.js +390 -171
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/useChatStream.js +179 -137
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/hooks/useGatewayConnection.js +123 -0
- package/lib/hooks/useGatewayConnection.js.map +1 -0
- package/lib/hooks/useGatewayRegistry.js +28 -0
- package/lib/hooks/useGatewayRegistry.js.map +1 -0
- package/lib/hooks/usePrerequisiteIds.js +209 -0
- package/lib/hooks/usePrerequisiteIds.js.map +1 -0
- package/lib/hooks/useWorkspaceProvisioner.js +236 -0
- package/lib/hooks/useWorkspaceProvisioner.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/routes.json +120 -5
- package/lib/screens/Chat/index.js +409 -0
- package/lib/screens/Chat/index.js.map +1 -0
- package/lib/screens/ChatHistory/index.js +56 -0
- package/lib/screens/ChatHistory/index.js.map +1 -0
- package/lib/screens/Home/HomeScreen.js +364 -144
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/ChatHistoryLanding.js +487 -0
- package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -0
- package/lib/screens/Home/components/DeepSearchModal.js +349 -0
- package/lib/screens/Home/components/DeepSearchModal.js.map +1 -0
- package/lib/screens/Home/deepSearchUtils.js +41 -0
- package/lib/screens/Home/deepSearchUtils.js.map +1 -0
- package/lib/screens/NewChat/index.js +43 -0
- package/lib/screens/NewChat/index.js.map +1 -0
- package/lib/services/agentSessionManager.js +451 -0
- package/lib/services/agentSessionManager.js.map +1 -0
- package/lib/services/gatewayApiKeyBridge.js +4 -0
- package/lib/services/gatewayApiKeyBridge.js.map +1 -0
- package/lib/services/gatewayClient.js +470 -0
- package/lib/services/gatewayClient.js.map +1 -0
- package/lib/theme/mobileTokens.js +18 -0
- package/lib/theme/mobileTokens.js.map +1 -0
- package/lib/utils/cdecodeUri.js +68 -0
- package/lib/utils/cdecodeUri.js.map +1 -0
- package/lib/utils/gatewaySelectionStorage.js +21 -0
- package/lib/utils/gatewaySelectionStorage.js.map +1 -0
- package/lib/utils/syncMobileOrgRouteContext.js +61 -0
- package/lib/utils/syncMobileOrgRouteContext.js.map +1 -0
- package/package.json +7 -3
- package/lib/api/chatApi.js +0 -102
- package/lib/api/chatApi.js.map +0 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import {useState,useRef,useCallback,useEffect}from'react';import {useGatewayConnectMutation,useGatewayDisconnectMutation,useCreateSecretApiTokenMutation,useRevealSecretApiTokenMutation,useGetUserSystemTokenQuery}from'common/graphql';import {SecretApiTokenAlgorithm}from'common';import {config}from'../config/env-config.js';import {usePrerequisiteIds}from'./usePrerequisiteIds.js';var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
const SYSTEM_TOKEN_ALGORITHM = __DEV__ ? SecretApiTokenAlgorithm.Hs256 : SecretApiTokenAlgorithm.Rs256;
|
|
21
|
+
const CHANNEL_TYPE = "cdecli-serve";
|
|
22
|
+
function useCdecliAutoConnect(isSelected, channelId) {
|
|
23
|
+
const [status, setStatus] = useState("idle");
|
|
24
|
+
const [error, setError] = useState(null);
|
|
25
|
+
const [persistenceMode, setPersistenceMode] = useState(void 0);
|
|
26
|
+
const [activeSkill, setActiveSkill] = useState(null);
|
|
27
|
+
const connectingRef = useRef(false);
|
|
28
|
+
const connectedRef = useRef(false);
|
|
29
|
+
const {
|
|
30
|
+
orgName,
|
|
31
|
+
projectId,
|
|
32
|
+
tagId,
|
|
33
|
+
accountUserId,
|
|
34
|
+
loading: prerequisitesLoading
|
|
35
|
+
} = usePrerequisiteIds();
|
|
36
|
+
const accountId = accountUserId != null ? accountUserId : "default";
|
|
37
|
+
const prevChannelIdRef = useRef(channelId);
|
|
38
|
+
const [connectMutation] = useGatewayConnectMutation();
|
|
39
|
+
const [disconnectMutation] = useGatewayDisconnectMutation();
|
|
40
|
+
const [createTokenMutation] = useCreateSecretApiTokenMutation();
|
|
41
|
+
const [revealTokenMutation] = useRevealSecretApiTokenMutation();
|
|
42
|
+
const {
|
|
43
|
+
data: systemTokenData,
|
|
44
|
+
loading: systemTokenLoading,
|
|
45
|
+
refetch: refetchSystemToken
|
|
46
|
+
} = useGetUserSystemTokenQuery({
|
|
47
|
+
skip: !isSelected,
|
|
48
|
+
fetchPolicy: "network-only"
|
|
49
|
+
});
|
|
50
|
+
const isAlreadyHasSystemTokenError = (err) => {
|
|
51
|
+
const message = err instanceof Error ? err.message : String(err != null ? err : "");
|
|
52
|
+
return /already have a system token/i.test(message);
|
|
53
|
+
};
|
|
54
|
+
const obtainSystemToken = useCallback(async () => {
|
|
55
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
56
|
+
try {
|
|
57
|
+
let tokenId = (_b = (_a = systemTokenData == null ? void 0 : systemTokenData.getUserSystemToken) == null ? void 0 : _a.id) != null ? _b : null;
|
|
58
|
+
if (!tokenId) {
|
|
59
|
+
if (!orgName || !projectId) {
|
|
60
|
+
const refetchResult = await refetchSystemToken().catch(() => null);
|
|
61
|
+
tokenId = (_e = (_d = (_c = refetchResult == null ? void 0 : refetchResult.data) == null ? void 0 : _c.getUserSystemToken) == null ? void 0 : _d.id) != null ? _e : null;
|
|
62
|
+
if (!tokenId) return null;
|
|
63
|
+
} else {
|
|
64
|
+
try {
|
|
65
|
+
const {
|
|
66
|
+
data: createData
|
|
67
|
+
} = await createTokenMutation({
|
|
68
|
+
variables: {
|
|
69
|
+
input: {
|
|
70
|
+
name: "System Token",
|
|
71
|
+
expiryInSeconds: 31536e3,
|
|
72
|
+
isSystemToken: true,
|
|
73
|
+
environmentTagId: tagId,
|
|
74
|
+
orgName: orgName || "default",
|
|
75
|
+
projectId: projectId || "default",
|
|
76
|
+
algorithm: SYSTEM_TOKEN_ALGORITHM
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
tokenId = (_g = (_f = createData == null ? void 0 : createData.createSecretApiToken) == null ? void 0 : _f.id) != null ? _g : null;
|
|
81
|
+
await refetchSystemToken();
|
|
82
|
+
} catch (createErr) {
|
|
83
|
+
if (!isAlreadyHasSystemTokenError(createErr)) throw createErr;
|
|
84
|
+
const refetchResult = await refetchSystemToken().catch(() => null);
|
|
85
|
+
tokenId = (_j = (_i = (_h = refetchResult == null ? void 0 : refetchResult.data) == null ? void 0 : _h.getUserSystemToken) == null ? void 0 : _i.id) != null ? _j : null;
|
|
86
|
+
if (!tokenId) {
|
|
87
|
+
console.warn("[useCdecliAutoConnect] System token already exists but refetch returned no id; retrying");
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!tokenId) return null;
|
|
94
|
+
const {
|
|
95
|
+
data: revealData
|
|
96
|
+
} = await revealTokenMutation({
|
|
97
|
+
variables: {
|
|
98
|
+
id: tokenId
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
return (revealData == null ? void 0 : revealData.revealSecretApiToken) || null;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.error("[useCdecliAutoConnect] obtainSystemToken error:", err);
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}, [systemTokenData, createTokenMutation, revealTokenMutation, refetchSystemToken, orgName, projectId, tagId]);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (!isSelected) {
|
|
109
|
+
connectingRef.current = false;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (prerequisitesLoading || !accountUserId) return;
|
|
113
|
+
if (systemTokenLoading) return;
|
|
114
|
+
let isSilentReconnect = false;
|
|
115
|
+
if (connectedRef.current || connectingRef.current) {
|
|
116
|
+
if (channelId && prevChannelIdRef.current !== channelId) {
|
|
117
|
+
isSilentReconnect = connectedRef.current;
|
|
118
|
+
prevChannelIdRef.current = channelId;
|
|
119
|
+
connectedRef.current = false;
|
|
120
|
+
} else {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const doConnect = async () => {
|
|
125
|
+
var _a;
|
|
126
|
+
connectingRef.current = true;
|
|
127
|
+
if (!isSilentReconnect) setStatus("connecting");
|
|
128
|
+
setError(null);
|
|
129
|
+
try {
|
|
130
|
+
const endpoint = config.CDECLI_AGENT_ENDPOINT || "https://cdecli-agent.cdebase.dev";
|
|
131
|
+
const token = await obtainSystemToken();
|
|
132
|
+
if (!token) {
|
|
133
|
+
console.warn("[useCdecliAutoConnect] No system token, connecting without auth");
|
|
134
|
+
}
|
|
135
|
+
const {
|
|
136
|
+
data
|
|
137
|
+
} = await connectMutation({
|
|
138
|
+
variables: {
|
|
139
|
+
input: {
|
|
140
|
+
channelType: CHANNEL_TYPE,
|
|
141
|
+
accountId,
|
|
142
|
+
options: __spreadValues(__spreadValues({
|
|
143
|
+
endpoint: endpoint.trim()
|
|
144
|
+
}, token ? {
|
|
145
|
+
token
|
|
146
|
+
} : {}), channelId ? {
|
|
147
|
+
chatId: channelId
|
|
148
|
+
} : {})
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
const result = data == null ? void 0 : data.gatewayConnect;
|
|
153
|
+
console.log("[useCdecliAutoConnect] connectMutation result (account=%s):", accountId, JSON.stringify(result));
|
|
154
|
+
if (result == null ? void 0 : result.persistenceMode) {
|
|
155
|
+
setPersistenceMode(result.persistenceMode);
|
|
156
|
+
}
|
|
157
|
+
if ((result == null ? void 0 : result.state) === "CONNECTED" || (result == null ? void 0 : result.connected)) {
|
|
158
|
+
setStatus("connected");
|
|
159
|
+
connectedRef.current = true;
|
|
160
|
+
} else if ((result == null ? void 0 : result.state) === "ERROR") {
|
|
161
|
+
setStatus("error");
|
|
162
|
+
setError((_a = result.lastError) != null ? _a : "Failed to connect to CDeCLI agent");
|
|
163
|
+
connectedRef.current = false;
|
|
164
|
+
} else {
|
|
165
|
+
setStatus("connected");
|
|
166
|
+
connectedRef.current = true;
|
|
167
|
+
}
|
|
168
|
+
} catch (err) {
|
|
169
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
170
|
+
console.error("[useCdecliAutoConnect] connect error:", msg);
|
|
171
|
+
setStatus("error");
|
|
172
|
+
setError(msg);
|
|
173
|
+
connectedRef.current = false;
|
|
174
|
+
} finally {
|
|
175
|
+
connectingRef.current = false;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
doConnect();
|
|
179
|
+
}, [isSelected, obtainSystemToken, connectMutation, accountId, prerequisitesLoading, accountUserId, channelId, systemTokenLoading]);
|
|
180
|
+
const connectWithSkill = useCallback(async (skill, model, systemPrompt, skillId) => {
|
|
181
|
+
var _a;
|
|
182
|
+
console.log("[useCdecliAutoConnect] connectWithSkill called with skill=%s skillId=%s model=%s systemPrompt=%d chars", skill, skillId != null ? skillId : "", model, (_a = systemPrompt == null ? void 0 : systemPrompt.length) != null ? _a : 0);
|
|
183
|
+
setStatus("connecting");
|
|
184
|
+
setError(null);
|
|
185
|
+
try {
|
|
186
|
+
const endpoint = config.CDECLI_AGENT_ENDPOINT || "https://cdecli-agent.cdebase.dev";
|
|
187
|
+
const token = await obtainSystemToken();
|
|
188
|
+
console.log("[useCdecliAutoConnect] connectWithSkill sending mutation with skill=%s", skill);
|
|
189
|
+
const {
|
|
190
|
+
data
|
|
191
|
+
} = await connectMutation({
|
|
192
|
+
variables: {
|
|
193
|
+
input: {
|
|
194
|
+
channelType: CHANNEL_TYPE,
|
|
195
|
+
accountId,
|
|
196
|
+
options: __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadProps(__spreadValues({
|
|
197
|
+
endpoint: endpoint.trim()
|
|
198
|
+
}, token ? {
|
|
199
|
+
token
|
|
200
|
+
} : {}), {
|
|
201
|
+
skill
|
|
202
|
+
}), skillId ? {
|
|
203
|
+
skillId
|
|
204
|
+
} : {}), model ? {
|
|
205
|
+
model
|
|
206
|
+
} : {}), systemPrompt ? {
|
|
207
|
+
systemPrompt
|
|
208
|
+
} : {}), channelId ? {
|
|
209
|
+
chatId: channelId
|
|
210
|
+
} : {})
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
console.log("[useCdecliAutoConnect] connectWithSkill result:", JSON.stringify(data == null ? void 0 : data.gatewayConnect));
|
|
215
|
+
const result = data == null ? void 0 : data.gatewayConnect;
|
|
216
|
+
if (result == null ? void 0 : result.persistenceMode) {
|
|
217
|
+
setPersistenceMode(result.persistenceMode);
|
|
218
|
+
}
|
|
219
|
+
if ((result == null ? void 0 : result.state) === "CONNECTED" || (result == null ? void 0 : result.connected)) {
|
|
220
|
+
setStatus("connected");
|
|
221
|
+
connectedRef.current = true;
|
|
222
|
+
setActiveSkill(skill);
|
|
223
|
+
} else {
|
|
224
|
+
setStatus("connected");
|
|
225
|
+
connectedRef.current = true;
|
|
226
|
+
setActiveSkill(skill);
|
|
227
|
+
}
|
|
228
|
+
} catch (err) {
|
|
229
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
230
|
+
console.error("[useCdecliAutoConnect] connectWithSkill error:", msg);
|
|
231
|
+
setStatus("error");
|
|
232
|
+
setError(msg);
|
|
233
|
+
}
|
|
234
|
+
}, [connectMutation, obtainSystemToken, accountId, channelId]);
|
|
235
|
+
return {
|
|
236
|
+
channelConnected: status === "connected",
|
|
237
|
+
status,
|
|
238
|
+
error,
|
|
239
|
+
persistenceMode,
|
|
240
|
+
activeSkill,
|
|
241
|
+
accountId,
|
|
242
|
+
connectWithSkill
|
|
243
|
+
};
|
|
244
|
+
}export{useCdecliAutoConnect};//# sourceMappingURL=useCdecliAutoConnect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCdecliAutoConnect.js","sources":["../../src/hooks/useCdecliAutoConnect.ts"],"sourcesContent":["/**\n * Auto-connects the cdecli-serve messenger-gateway channel when the CDeCLI\n * gateway is selected from the dropdown. Obtains/creates a system token and\n * calls the `gatewayConnect` mutation so the backend provider has a live\n * session with the cdecli-agent endpoint.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n useGatewayConnectMutation,\n useGatewayDisconnectMutation,\n useGetUserSystemTokenQuery,\n useCreateSecretApiTokenMutation,\n useRevealSecretApiTokenMutation,\n} from 'common/graphql';\nimport { SecretApiTokenAlgorithm } from 'common';\nimport { config } from '../config/env-config';\nimport { usePrerequisiteIds } from './usePrerequisiteIds';\n\n/** Local backend ships RS256 public key but often no private key; HS256 uses dev JWT secret. */\nconst SYSTEM_TOKEN_ALGORITHM = __DEV__ ? SecretApiTokenAlgorithm.Hs256 : SecretApiTokenAlgorithm.Rs256;\n\n// ─── Types ───────────────────────────────────────────────────────\n\nexport type CdecliAutoConnectStatus = 'idle' | 'connecting' | 'connected' | 'error';\n\nexport interface UseCdecliAutoConnectResult {\n /** Whether the backend cdecli-serve channel is connected. */\n channelConnected: boolean;\n /** Current connection status. */\n status: CdecliAutoConnectStatus;\n /** Error message if status is 'error'. */\n error: string | null;\n /** Persistence mode reported by the backend provider ('backend' | 'frontend'). */\n persistenceMode: 'backend' | 'frontend' | undefined;\n /** Active skill name on the current CDeCLI session (null if none). */\n activeSkill: string | null;\n /** Per-user accountId used for this gateway connection. */\n accountId: string;\n /** Reconnect the CDeCLI session with a specific skill pre-activated. */\n connectWithSkill: (skill: string, model?: string, systemPrompt?: string, skillId?: string) => Promise<void>;\n}\n\n// ─── Constants ───────────────────────────────────────────────────\n\nconst CHANNEL_TYPE = 'cdecli-serve';\n\n// ─── Hook ────────────────────────────────────────────────────────\n\n/**\n * When `isSelected` is true, auto-connects the cdecli-serve channel on the\n * messenger-gateway backend using the hosted endpoint and a system token.\n */\nexport function useCdecliAutoConnect(isSelected: boolean, channelId?: string): UseCdecliAutoConnectResult {\n const [status, setStatus] = useState<CdecliAutoConnectStatus>('idle');\n const [error, setError] = useState<string | null>(null);\n const [persistenceMode, setPersistenceMode] = useState<'backend' | 'frontend' | undefined>(undefined);\n const [activeSkill, setActiveSkill] = useState<string | null>(null);\n const connectingRef = useRef(false);\n const connectedRef = useRef(false);\n\n const { orgName, projectId, tagId, accountUserId, loading: prerequisitesLoading } = usePrerequisiteIds();\n\n // Per-user accountId so each user gets their own cdecli-agent session.\n // Wait for the profile query to load before connecting — otherwise all\n // users fall back to 'default' and share a single cdecli-agent session.\n const accountId = accountUserId ?? 'default';\n\n // Track the previous channelId so we can reconnect when the user opens a new chat.\n const prevChannelIdRef = useRef<string | undefined>(channelId);\n\n const [connectMutation] = useGatewayConnectMutation();\n const [disconnectMutation] = useGatewayDisconnectMutation();\n const [createTokenMutation] = useCreateSecretApiTokenMutation();\n const [revealTokenMutation] = useRevealSecretApiTokenMutation();\n const {\n data: systemTokenData,\n loading: systemTokenLoading,\n refetch: refetchSystemToken,\n } = useGetUserSystemTokenQuery({\n skip: !isSelected,\n fetchPolicy: 'network-only',\n });\n\n /** True when the backend rejects createSecretApiToken because the user already has one. */\n const isAlreadyHasSystemTokenError = (err: unknown): boolean => {\n const message = err instanceof Error ? err.message : String(err ?? '');\n return /already have a system token/i.test(message);\n };\n\n const obtainSystemToken = useCallback(async (): Promise<string | null> => {\n try {\n let tokenId: string | null = systemTokenData?.getUserSystemToken?.id ?? null;\n\n /**\n * Race recovery: if the GetUserSystemToken query hasn't returned yet (or returned\n * stale data) we'll fall through to createSecretApiToken. The backend rejects that\n * with \"you already have a system token\" — catch it, refetch, and use the existing\n * token id instead of falling back to an unauthenticated connection.\n */\n if (!tokenId) {\n if (!orgName || !projectId) {\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) return null;\n } else {\n try {\n const { data: createData } = await createTokenMutation({\n variables: {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId: tagId,\n orgName: orgName || 'default',\n projectId: projectId || 'default',\n algorithm: SYSTEM_TOKEN_ALGORITHM,\n },\n },\n });\n tokenId = createData?.createSecretApiToken?.id ?? null;\n await refetchSystemToken();\n } catch (createErr) {\n if (!isAlreadyHasSystemTokenError(createErr)) throw createErr;\n const refetchResult = await refetchSystemToken().catch(() => null);\n tokenId = refetchResult?.data?.getUserSystemToken?.id ?? null;\n if (!tokenId) {\n console.warn(\n '[useCdecliAutoConnect] System token already exists but refetch returned no id; retrying',\n );\n return null;\n }\n }\n }\n }\n\n if (!tokenId) return null;\n\n const { data: revealData } = await revealTokenMutation({\n variables: { id: tokenId },\n });\n return (revealData?.revealSecretApiToken as string) || null;\n } catch (err) {\n console.error('[useCdecliAutoConnect] obtainSystemToken error:', err);\n return null;\n }\n }, [systemTokenData, createTokenMutation, revealTokenMutation, refetchSystemToken, orgName, projectId, tagId]);\n\n // Auto-connect when CDeCLI gateway is selected\n useEffect(() => {\n if (!isSelected) {\n // Reset when deselected, but don't disconnect — keep the session alive\n // so switching back is instant.\n connectingRef.current = false;\n return;\n }\n\n // Wait until the user profile has loaded so accountId is the real\n // user id instead of the 'default' fallback.\n if (prerequisitesLoading || !accountUserId) return;\n\n /**\n * Wait for the GetUserSystemToken query to resolve before we connect — otherwise we\n * race the network and try to create a duplicate token, which the backend rejects with\n * \"you already have a system token\" and we fall back to an unauthenticated session.\n */\n if (systemTokenLoading) return;\n\n /**\n * If we're already connected and just switching channels, the gateway needs a reconnect\n * (the session is bound server-side to chatId), but the user already had a working\n * connection. Skip flipping the visible status to 'connecting' so the toolbar pill\n * doesn't briefly show \"Checking...\" every time someone taps a history row.\n */\n let isSilentReconnect = false;\n if (connectedRef.current || connectingRef.current) {\n if (channelId && prevChannelIdRef.current !== channelId) {\n isSilentReconnect = connectedRef.current;\n prevChannelIdRef.current = channelId;\n connectedRef.current = false;\n } else {\n return;\n }\n }\n\n const doConnect = async () => {\n connectingRef.current = true;\n if (!isSilentReconnect) setStatus('connecting');\n setError(null);\n\n try {\n const endpoint = config.CDECLI_AGENT_ENDPOINT || 'https://cdecli-agent.cdebase.dev';\n const token = await obtainSystemToken();\n if (!token) {\n console.warn('[useCdecliAutoConnect] No system token, connecting without auth');\n }\n\n const { data } = await connectMutation({\n variables: {\n input: {\n channelType: CHANNEL_TYPE,\n accountId,\n options: {\n endpoint: endpoint.trim(),\n ...(token ? { token } : {}),\n ...(channelId ? { chatId: channelId } : {}),\n },\n },\n },\n });\n\n const result = data?.gatewayConnect as\n | ((typeof data)['gatewayConnect'] & { persistenceMode?: string })\n | undefined;\n console.log(\n '[useCdecliAutoConnect] connectMutation result (account=%s):',\n accountId,\n JSON.stringify(result),\n );\n if (result?.persistenceMode) {\n setPersistenceMode(result.persistenceMode as 'backend' | 'frontend');\n }\n if (result?.state === 'CONNECTED' || result?.connected) {\n setStatus('connected');\n connectedRef.current = true;\n } else if (result?.state === 'ERROR') {\n setStatus('error');\n setError(result.lastError ?? 'Failed to connect to CDeCLI agent');\n connectedRef.current = false;\n } else {\n // Assume connecting — the subscription will push the final state\n setStatus('connected');\n connectedRef.current = true;\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[useCdecliAutoConnect] connect error:', msg);\n setStatus('error');\n setError(msg);\n connectedRef.current = false;\n } finally {\n connectingRef.current = false;\n }\n };\n\n doConnect();\n }, [\n isSelected,\n obtainSystemToken,\n connectMutation,\n accountId,\n prerequisitesLoading,\n accountUserId,\n channelId,\n systemTokenLoading,\n ]);\n\n // Keep the backend session alive across page refreshes and SPA navigations.\n // The backend CdecliServeProvider.connect() will reuse the existing session\n // if the endpoint hasn't changed, preserving conversation context.\n // Only disconnect when the user explicitly switches to a different gateway.\n\n /** Reconnect the CDeCLI session with a specific skill pre-activated. */\n const connectWithSkill = useCallback(\n async (skill: string, model?: string, systemPrompt?: string, skillId?: string) => {\n console.log(\n '[useCdecliAutoConnect] connectWithSkill called with skill=%s skillId=%s model=%s systemPrompt=%d chars',\n skill,\n skillId ?? '',\n model,\n systemPrompt?.length ?? 0,\n );\n setStatus('connecting');\n setError(null);\n\n try {\n const endpoint = config.CDECLI_AGENT_ENDPOINT || 'https://cdecli-agent.cdebase.dev';\n const token = await obtainSystemToken();\n\n console.log('[useCdecliAutoConnect] connectWithSkill sending mutation with skill=%s', skill);\n const { data } = await connectMutation({\n variables: {\n input: {\n channelType: CHANNEL_TYPE,\n accountId,\n options: {\n endpoint: endpoint.trim(),\n ...(token ? { token } : {}),\n skill,\n ...(skillId ? { skillId } : {}),\n ...(model ? { model } : {}),\n ...(systemPrompt ? { systemPrompt } : {}),\n ...(channelId ? { chatId: channelId } : {}),\n },\n },\n },\n });\n\n console.log('[useCdecliAutoConnect] connectWithSkill result:', JSON.stringify(data?.gatewayConnect));\n const result = data?.gatewayConnect as\n | ((typeof data)['gatewayConnect'] & { persistenceMode?: string })\n | undefined;\n if (result?.persistenceMode) {\n setPersistenceMode(result.persistenceMode as 'backend' | 'frontend');\n }\n if (result?.state === 'CONNECTED' || result?.connected) {\n setStatus('connected');\n connectedRef.current = true;\n setActiveSkill(skill);\n } else {\n setStatus('connected');\n connectedRef.current = true;\n setActiveSkill(skill);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[useCdecliAutoConnect] connectWithSkill error:', msg);\n setStatus('error');\n setError(msg);\n }\n },\n [connectMutation, obtainSystemToken, accountId, channelId],\n );\n\n return {\n channelConnected: status === 'connected',\n status,\n error,\n persistenceMode,\n activeSkill,\n accountId,\n connectWithSkill,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {useRef,useCallback,useEffect}from'react';import {useGatewaySendMessageMutation,useMessengerStreamDeltaSubscription,useGatewayInboundMessageByChannelSubscription}from'common/graphql';var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
17
|
+
function stripModelCostHeader(content) {
|
|
18
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
19
|
+
return normalized.replace(/^\s*(?:[^\w\n]+\s*)?[a-z0-9][a-z0-9._-]*\s*\(\s*\$[\d.]+\s*\/\s*MTok\s+in\s*\)\s*\n+/i, "");
|
|
20
|
+
}
|
|
21
|
+
const CDECLI_RESPONSE_TIMEOUT_MS = 3e5;
|
|
22
|
+
function useCdecliChannel(isConnected, accountId, channelId, callbacks, model, skill) {
|
|
23
|
+
const [sendMutation] = useGatewaySendMessageMutation();
|
|
24
|
+
const cbRef = useRef(callbacks);
|
|
25
|
+
cbRef.current = callbacks;
|
|
26
|
+
const pendingRef = useRef(null);
|
|
27
|
+
const hasReceivedDeltasRef = useRef(false);
|
|
28
|
+
const reconnectedStreamRef = useRef(false);
|
|
29
|
+
const streamCompletedRef = useRef(false);
|
|
30
|
+
const accumulatedLenRef = useRef(0);
|
|
31
|
+
const timeoutRef = useRef(null);
|
|
32
|
+
const streamSkip = !channelId;
|
|
33
|
+
const streamChannelId = channelId || accountId;
|
|
34
|
+
useMessengerStreamDeltaSubscription({
|
|
35
|
+
variables: {
|
|
36
|
+
channelId: streamChannelId
|
|
37
|
+
},
|
|
38
|
+
skip: streamSkip,
|
|
39
|
+
onData: ({
|
|
40
|
+
data
|
|
41
|
+
}) => {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
const delta = (_a = data == null ? void 0 : data.data) == null ? void 0 : _a.messengerStreamDelta;
|
|
44
|
+
if (!delta) return;
|
|
45
|
+
if (delta.isFinal) return;
|
|
46
|
+
if (streamCompletedRef.current) return;
|
|
47
|
+
if (!pendingRef.current) {
|
|
48
|
+
if (!reconnectedStreamRef.current) {
|
|
49
|
+
reconnectedStreamRef.current = true;
|
|
50
|
+
accumulatedLenRef.current = 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
hasReceivedDeltasRef.current = true;
|
|
54
|
+
const fullText = stripModelCostHeader((_b = delta.text) != null ? _b : "");
|
|
55
|
+
const newChunk = fullText.substring(accumulatedLenRef.current);
|
|
56
|
+
accumulatedLenRef.current = fullText.length;
|
|
57
|
+
if (newChunk) {
|
|
58
|
+
cbRef.current.onChunk(newChunk);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
onError: (err) => {
|
|
62
|
+
console.error("[useCdecliChannel] stream delta subscription error:", err);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
useGatewayInboundMessageByChannelSubscription({
|
|
66
|
+
variables: {
|
|
67
|
+
channelId: streamChannelId
|
|
68
|
+
},
|
|
69
|
+
skip: !isConnected || streamSkip,
|
|
70
|
+
onData: ({
|
|
71
|
+
data
|
|
72
|
+
}) => {
|
|
73
|
+
var _a;
|
|
74
|
+
const msg = (_a = data == null ? void 0 : data.data) == null ? void 0 : _a.gatewayInboundMessageByChannel;
|
|
75
|
+
if (!(msg == null ? void 0 : msg.text)) return;
|
|
76
|
+
const sanitizedText = stripModelCostHeader(msg.text);
|
|
77
|
+
if (!hasReceivedDeltasRef.current) {
|
|
78
|
+
cbRef.current.onChunk(sanitizedText);
|
|
79
|
+
}
|
|
80
|
+
cbRef.current.onComplete(sanitizedText);
|
|
81
|
+
pendingRef.current = null;
|
|
82
|
+
hasReceivedDeltasRef.current = false;
|
|
83
|
+
reconnectedStreamRef.current = false;
|
|
84
|
+
streamCompletedRef.current = true;
|
|
85
|
+
accumulatedLenRef.current = 0;
|
|
86
|
+
if (timeoutRef.current) {
|
|
87
|
+
clearTimeout(timeoutRef.current);
|
|
88
|
+
timeoutRef.current = null;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
onError: (err) => {
|
|
92
|
+
console.error("[useCdecliChannel] subscription error:", err);
|
|
93
|
+
cbRef.current.onError(err.message || "CDeCLI subscription error");
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
const sendMessage = useCallback(async (text, chatId = "messenger") => {
|
|
97
|
+
var _a;
|
|
98
|
+
if (!isConnected) return false;
|
|
99
|
+
pendingRef.current = {
|
|
100
|
+
text,
|
|
101
|
+
sentAt: Date.now()
|
|
102
|
+
};
|
|
103
|
+
hasReceivedDeltasRef.current = false;
|
|
104
|
+
reconnectedStreamRef.current = false;
|
|
105
|
+
streamCompletedRef.current = false;
|
|
106
|
+
accumulatedLenRef.current = 0;
|
|
107
|
+
try {
|
|
108
|
+
const result = await sendMutation({
|
|
109
|
+
variables: {
|
|
110
|
+
input: __spreadValues({
|
|
111
|
+
channelType: "cdecli-serve",
|
|
112
|
+
accountId,
|
|
113
|
+
chatId,
|
|
114
|
+
text
|
|
115
|
+
}, model || skill ? {
|
|
116
|
+
metadata: __spreadValues(__spreadValues({}, model && {
|
|
117
|
+
model
|
|
118
|
+
}), skill && {
|
|
119
|
+
skill
|
|
120
|
+
})
|
|
121
|
+
} : {})
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
const payload = (_a = result.data) == null ? void 0 : _a.gatewaySendMessage;
|
|
125
|
+
if (!(payload == null ? void 0 : payload.success)) {
|
|
126
|
+
const errMsg = (payload == null ? void 0 : payload.error) || "CDeCLI send failed";
|
|
127
|
+
cbRef.current.onError(errMsg);
|
|
128
|
+
pendingRef.current = null;
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
timeoutRef.current = setTimeout(() => {
|
|
132
|
+
if (pendingRef.current) {
|
|
133
|
+
pendingRef.current = null;
|
|
134
|
+
hasReceivedDeltasRef.current = false;
|
|
135
|
+
timeoutRef.current = null;
|
|
136
|
+
cbRef.current.onError("CDeCLI agent did not respond within 300 seconds. The query may still be processing.");
|
|
137
|
+
}
|
|
138
|
+
}, CDECLI_RESPONSE_TIMEOUT_MS);
|
|
139
|
+
return true;
|
|
140
|
+
} catch (err) {
|
|
141
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
142
|
+
cbRef.current.onError(msg);
|
|
143
|
+
pendingRef.current = null;
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}, [isConnected, accountId, channelId, sendMutation, model, skill]);
|
|
147
|
+
useEffect(() => () => {
|
|
148
|
+
pendingRef.current = null;
|
|
149
|
+
hasReceivedDeltasRef.current = false;
|
|
150
|
+
reconnectedStreamRef.current = false;
|
|
151
|
+
streamCompletedRef.current = false;
|
|
152
|
+
accumulatedLenRef.current = 0;
|
|
153
|
+
if (timeoutRef.current) {
|
|
154
|
+
clearTimeout(timeoutRef.current);
|
|
155
|
+
timeoutRef.current = null;
|
|
156
|
+
}
|
|
157
|
+
}, []);
|
|
158
|
+
return {
|
|
159
|
+
sendMessage
|
|
160
|
+
};
|
|
161
|
+
}export{useCdecliChannel};//# sourceMappingURL=useCdecliChannel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCdecliChannel.js","sources":["../../src/hooks/useCdecliChannel.ts"],"sourcesContent":["/**\n * useCdecliChannel — wires the cdecli-serve messenger-gateway channel into the mobile chat UI.\n *\n * Kept in sync with `packages-modules/account/browser/src/hooks/useCdecliChannel.ts`.\n * When the CDeCLI channel is connected:\n * - `sendMessage(text)` calls `gatewaySendMessage`\n * - `MessengerStreamDelta` subscription delivers streaming chunks via `onChunk`\n * - `GatewayInboundMessageByChannel` delivers the final reply via `onComplete`\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\nimport {\n useGatewaySendMessageMutation,\n useGatewayInboundMessageByChannelSubscription,\n useMessengerStreamDeltaSubscription,\n} from 'common/graphql';\n\nfunction stripModelCostHeader(content: string): string {\n const normalized = content.replace(/\\r\\n/g, '\\n');\n return normalized.replace(\n /^\\s*(?:[^\\w\\n]+\\s*)?[a-z0-9][a-z0-9._-]*\\s*\\(\\s*\\$[\\d.]+\\s*\\/\\s*MTok\\s+in\\s*\\)\\s*\\n+/i,\n '',\n );\n}\n\nexport interface CdecliChannelCallbacks {\n onChunk: (text: string) => void;\n onComplete: (text: string) => void;\n onError: (error: string) => void;\n}\n\n/** Same 120s window as web — deep CDeCLI queries can exceed 45s. */\nconst CDECLI_RESPONSE_TIMEOUT_MS = 300_000;\n\nexport function useCdecliChannel(\n isConnected: boolean,\n accountId: string,\n channelId: string | undefined,\n callbacks: CdecliChannelCallbacks,\n model?: string,\n skill?: string,\n) {\n const [sendMutation] = useGatewaySendMessageMutation();\n const cbRef = useRef(callbacks);\n cbRef.current = callbacks;\n\n const pendingRef = useRef<{ text: string; sentAt: number } | null>(null);\n const hasReceivedDeltasRef = useRef(false);\n const reconnectedStreamRef = useRef(false);\n const streamCompletedRef = useRef(false);\n const accumulatedLenRef = useRef(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const streamSkip = !channelId;\n const streamChannelId = channelId || accountId;\n\n useMessengerStreamDeltaSubscription({\n variables: { channelId: streamChannelId },\n skip: streamSkip,\n onData: ({ data }) => {\n const delta = data?.data?.messengerStreamDelta;\n if (!delta) return;\n\n if (delta.isFinal) return;\n\n if (streamCompletedRef.current) return;\n\n if (!pendingRef.current) {\n if (!reconnectedStreamRef.current) {\n reconnectedStreamRef.current = true;\n accumulatedLenRef.current = 0;\n }\n }\n\n hasReceivedDeltasRef.current = true;\n\n const fullText = stripModelCostHeader(delta.text ?? '');\n const newChunk = fullText.substring(accumulatedLenRef.current);\n accumulatedLenRef.current = fullText.length;\n\n if (newChunk) {\n cbRef.current.onChunk(newChunk);\n }\n },\n onError: (err) => {\n console.error('[useCdecliChannel] stream delta subscription error:', err);\n },\n });\n\n useGatewayInboundMessageByChannelSubscription({\n variables: { channelId: streamChannelId },\n skip: !isConnected || streamSkip,\n onData: ({ data }) => {\n const msg = data?.data?.gatewayInboundMessageByChannel;\n if (!msg?.text) return;\n const sanitizedText = stripModelCostHeader(msg.text);\n\n if (!hasReceivedDeltasRef.current) {\n cbRef.current.onChunk(sanitizedText);\n }\n\n cbRef.current.onComplete(sanitizedText);\n pendingRef.current = null;\n hasReceivedDeltasRef.current = false;\n reconnectedStreamRef.current = false;\n streamCompletedRef.current = true;\n accumulatedLenRef.current = 0;\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n },\n onError: (err) => {\n console.error('[useCdecliChannel] subscription error:', err);\n cbRef.current.onError(err.message || 'CDeCLI subscription error');\n },\n });\n\n const sendMessage = useCallback(\n async (text: string, chatId = 'messenger'): Promise<boolean> => {\n if (!isConnected) return false;\n\n pendingRef.current = { text, sentAt: Date.now() };\n hasReceivedDeltasRef.current = false;\n reconnectedStreamRef.current = false;\n streamCompletedRef.current = false;\n accumulatedLenRef.current = 0;\n\n try {\n const result = await sendMutation({\n variables: {\n input: {\n channelType: 'cdecli-serve',\n accountId,\n chatId,\n text,\n ...(model || skill\n ? { metadata: { ...(model && { model }), ...(skill && { skill }) } }\n : {}),\n },\n },\n });\n\n const payload = result.data?.gatewaySendMessage;\n if (!payload?.success) {\n const errMsg = payload?.error || 'CDeCLI send failed';\n cbRef.current.onError(errMsg);\n pendingRef.current = null;\n return false;\n }\n\n timeoutRef.current = setTimeout(() => {\n if (pendingRef.current) {\n pendingRef.current = null;\n hasReceivedDeltasRef.current = false;\n timeoutRef.current = null;\n cbRef.current.onError(\n 'CDeCLI agent did not respond within 300 seconds. The query may still be processing.',\n );\n }\n }, CDECLI_RESPONSE_TIMEOUT_MS);\n\n return true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n cbRef.current.onError(msg);\n pendingRef.current = null;\n return false;\n }\n },\n [isConnected, accountId, channelId, sendMutation, model, skill],\n );\n\n useEffect(\n () => () => {\n pendingRef.current = null;\n hasReceivedDeltasRef.current = false;\n reconnectedStreamRef.current = false;\n streamCompletedRef.current = false;\n accumulatedLenRef.current = 0;\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n },\n [],\n );\n\n return { sendMessage };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAYA,SAAS,qBAAqB,OAAyB,EAAA;AACrD,EAAA,MAAM,UAAa,GAAA,OAAA,CAAQ,OAAQ,CAAA,OAAA,EAAS,IAAI,CAAA;AAChD,EAAO,OAAA,UAAA,CAAW,OAAQ,CAAA,uFAAA,EAAyF,EAAE,CAAA;AACvH;AAQA,MAAM,0BAA6B,GAAA,GAAA;AAC5B,SAAS,iBAAiB,WAAsB,EAAA,SAAA,EAAmB,SAA+B,EAAA,SAAA,EAAmC,OAAgB,KAAgB,EAAA;AAC1K,EAAM,MAAA,CAAC,YAAY,CAAA,GAAI,6BAA8B,EAAA;AACrD,EAAM,MAAA,KAAA,GAAQ,OAAO,SAAS,CAAA;AAC9B,EAAA,KAAA,CAAM,OAAU,GAAA,SAAA;AAChB,EAAM,MAAA,UAAA,GAAa,OAGT,IAAI,CAAA;AACd,EAAM,MAAA,oBAAA,GAAuB,OAAO,KAAK,CAAA;AACzC,EAAM,MAAA,oBAAA,GAAuB,OAAO,KAAK,CAAA;AACzC,EAAM,MAAA,kBAAA,GAAqB,OAAO,KAAK,CAAA;AACvC,EAAM,MAAA,iBAAA,GAAoB,OAAO,CAAC,CAAA;AAClC,EAAM,MAAA,UAAA,GAAa,OAA6C,IAAI,CAAA;AACpE,EAAA,MAAM,aAAa,CAAC,SAAA;AACpB,EAAA,MAAM,kBAAkB,SAAa,IAAA,SAAA;AACrC,EAAoC,mCAAA,CAAA;AAAA,IAClC,SAAW,EAAA;AAAA,MACT,SAAW,EAAA;AAAA,KACb;AAAA,IACA,IAAM,EAAA,UAAA;AAAA,IACN,QAAQ,CAAC;AAAA,MACP;AAAA,KACI,KAAA;AA9CV,MAAA,IAAA,EAAA,EAAA,EAAA;AA+CM,MAAM,MAAA,KAAA,GAAA,CAAQ,EAAM,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,IAAA,KAAN,IAAY,GAAA,MAAA,GAAA,EAAA,CAAA,oBAAA;AAC1B,MAAA,IAAI,CAAC,KAAO,EAAA;AACZ,MAAA,IAAI,MAAM,OAAS,EAAA;AACnB,MAAA,IAAI,mBAAmB,OAAS,EAAA;AAChC,MAAI,IAAA,CAAC,WAAW,OAAS,EAAA;AACvB,QAAI,IAAA,CAAC,qBAAqB,OAAS,EAAA;AACjC,UAAA,oBAAA,CAAqB,OAAU,GAAA,IAAA;AAC/B,UAAA,iBAAA,CAAkB,OAAU,GAAA,CAAA;AAAA;AAC9B;AAEF,MAAA,oBAAA,CAAqB,OAAU,GAAA,IAAA;AAC/B,MAAA,MAAM,QAAW,GAAA,oBAAA,CAAA,CAAqB,EAAM,GAAA,KAAA,CAAA,IAAA,KAAN,YAAc,EAAE,CAAA;AACtD,MAAA,MAAM,QAAW,GAAA,QAAA,CAAS,SAAU,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAC7D,MAAA,iBAAA,CAAkB,UAAU,QAAS,CAAA,MAAA;AACrC,MAAA,IAAI,QAAU,EAAA;AACZ,QAAM,KAAA,CAAA,OAAA,CAAQ,QAAQ,QAAQ,CAAA;AAAA;AAChC,KACF;AAAA,IACA,SAAS,CAAO,GAAA,KAAA;AACd,MAAQ,OAAA,CAAA,KAAA,CAAM,uDAAuD,GAAG,CAAA;AAAA;AAC1E,GACD,CAAA;AACD,EAA8C,6CAAA,CAAA;AAAA,IAC5C,SAAW,EAAA;AAAA,MACT,SAAW,EAAA;AAAA,KACb;AAAA,IACA,IAAA,EAAM,CAAC,WAAe,IAAA,UAAA;AAAA,IACtB,QAAQ,CAAC;AAAA,MACP;AAAA,KACI,KAAA;AA5EV,MAAA,IAAA,EAAA;AA6EM,MAAM,MAAA,GAAA,GAAA,CAAM,EAAM,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,IAAA,KAAN,IAAY,GAAA,MAAA,GAAA,EAAA,CAAA,8BAAA;AACxB,MAAI,IAAA,EAAC,2BAAK,IAAM,CAAA,EAAA;AAChB,MAAM,MAAA,aAAA,GAAgB,oBAAqB,CAAA,GAAA,CAAI,IAAI,CAAA;AACnD,MAAI,IAAA,CAAC,qBAAqB,OAAS,EAAA;AACjC,QAAM,KAAA,CAAA,OAAA,CAAQ,QAAQ,aAAa,CAAA;AAAA;AAErC,MAAM,KAAA,CAAA,OAAA,CAAQ,WAAW,aAAa,CAAA;AACtC,MAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,MAAA,oBAAA,CAAqB,OAAU,GAAA,KAAA;AAC/B,MAAA,oBAAA,CAAqB,OAAU,GAAA,KAAA;AAC/B,MAAA,kBAAA,CAAmB,OAAU,GAAA,IAAA;AAC7B,MAAA,iBAAA,CAAkB,OAAU,GAAA,CAAA;AAC5B,MAAA,IAAI,WAAW,OAAS,EAAA;AACtB,QAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAC/B,QAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AAAA;AACvB,KACF;AAAA,IACA,SAAS,CAAO,GAAA,KAAA;AACd,MAAQ,OAAA,CAAA,KAAA,CAAM,0CAA0C,GAAG,CAAA;AAC3D,MAAA,KAAA,CAAM,OAAQ,CAAA,OAAA,CAAQ,GAAI,CAAA,OAAA,IAAW,2BAA2B,CAAA;AAAA;AAClE,GACD,CAAA;AACD,EAAA,MAAM,WAAc,GAAA,WAAA,CAAY,OAAO,IAAA,EAAc,SAAS,WAAkC,KAAA;AAnGlG,IAAA,IAAA,EAAA;AAoGI,IAAI,IAAA,CAAC,aAAoB,OAAA,KAAA;AACzB,IAAA,UAAA,CAAW,OAAU,GAAA;AAAA,MACnB,IAAA;AAAA,MACA,MAAA,EAAQ,KAAK,GAAI;AAAA,KACnB;AACA,IAAA,oBAAA,CAAqB,OAAU,GAAA,KAAA;AAC/B,IAAA,oBAAA,CAAqB,OAAU,GAAA,KAAA;AAC/B,IAAA,kBAAA,CAAmB,OAAU,GAAA,KAAA;AAC7B,IAAA,iBAAA,CAAkB,OAAU,GAAA,CAAA;AAC5B,IAAI,IAAA;AACF,MAAM,MAAA,MAAA,GAAS,MAAM,YAAa,CAAA;AAAA,QAChC,SAAW,EAAA;AAAA,UACT,KAAO,EAAA,cAAA,CAAA;AAAA,YACL,WAAa,EAAA,cAAA;AAAA,YACb,SAAA;AAAA,YACA,MAAA;AAAA,YACA;AAAA,WAAA,EACI,SAAS,KAAQ,GAAA;AAAA,YACnB,QAAA,EAAU,kCACJ,KAAS,IAAA;AAAA,cACX;AAAA,gBAEE,KAAS,IAAA;AAAA,cACX;AAAA,aACF;AAAA,cAEA,EAAC;AAAA;AAET,OACD,CAAA;AACD,MAAM,MAAA,OAAA,GAAA,CAAU,EAAO,GAAA,MAAA,CAAA,IAAA,KAAP,IAAa,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,kBAAA;AAC7B,MAAI,IAAA,EAAC,mCAAS,OAAS,CAAA,EAAA;AACrB,QAAM,MAAA,MAAA,GAAA,CAAS,mCAAS,KAAS,KAAA,oBAAA;AACjC,QAAM,KAAA,CAAA,OAAA,CAAQ,QAAQ,MAAM,CAAA;AAC5B,QAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,QAAO,OAAA,KAAA;AAAA;AAET,MAAW,UAAA,CAAA,OAAA,GAAU,WAAW,MAAM;AACpC,QAAA,IAAI,WAAW,OAAS,EAAA;AACtB,UAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,UAAA,oBAAA,CAAqB,OAAU,GAAA,KAAA;AAC/B,UAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,UAAM,KAAA,CAAA,OAAA,CAAQ,QAAQ,qFAAqF,CAAA;AAAA;AAC7G,SACC,0BAA0B,CAAA;AAC7B,MAAO,OAAA,IAAA;AAAA,aACA,GAAK,EAAA;AACZ,MAAA,MAAM,MAAM,GAAe,YAAA,KAAA,GAAQ,GAAI,CAAA,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,MAAM,KAAA,CAAA,OAAA,CAAQ,QAAQ,GAAG,CAAA;AACzB,MAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,MAAO,OAAA,KAAA;AAAA;AACT,GACF,EAAG,CAAC,WAAa,EAAA,SAAA,EAAW,WAAW,YAAc,EAAA,KAAA,EAAO,KAAK,CAAC,CAAA;AAClE,EAAA,SAAA,CAAU,MAAM,MAAM;AACpB,IAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AACrB,IAAA,oBAAA,CAAqB,OAAU,GAAA,KAAA;AAC/B,IAAA,oBAAA,CAAqB,OAAU,GAAA,KAAA;AAC/B,IAAA,kBAAA,CAAmB,OAAU,GAAA,KAAA;AAC7B,IAAA,iBAAA,CAAkB,OAAU,GAAA,CAAA;AAC5B,IAAA,IAAI,WAAW,OAAS,EAAA;AACtB,MAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAC/B,MAAA,UAAA,CAAW,OAAU,GAAA,IAAA;AAAA;AACvB,GACF,EAAG,EAAE,CAAA;AACL,EAAO,OAAA;AAAA,IACL;AAAA,GACF;AACF"}
|