@adminide-stack/yantra-mobile 12.0.52-alpha.0 → 12.0.52-alpha.3

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 (56) hide show
  1. package/lib/components/CustomDrawer.js +1 -38
  2. package/lib/components/CustomDrawer.js.map +1 -1
  3. package/lib/components/KeyboardComposerDock.js +4 -3
  4. package/lib/components/KeyboardComposerDock.js.map +1 -1
  5. package/lib/compute.js +58 -1
  6. package/lib/compute.js.map +1 -1
  7. package/lib/features/apps/AppsCatalog.js +9 -0
  8. package/lib/features/apps/AppsCatalog.js.map +1 -1
  9. package/lib/features/apps/mobileAppCatalog.js +10 -0
  10. package/lib/features/apps/mobileAppCatalog.js.map +1 -1
  11. package/lib/features/attachments/buildGatewayMedia.js +22 -15
  12. package/lib/features/attachments/buildGatewayMedia.js.map +1 -1
  13. package/lib/features/attachments/uploadChatAttachments.js +6 -4
  14. package/lib/features/attachments/uploadChatAttachments.js.map +1 -1
  15. package/lib/features/attachments/useImageAttachments.js +63 -17
  16. package/lib/features/attachments/useImageAttachments.js.map +1 -1
  17. package/lib/features/chat/AskUserCard.js +244 -121
  18. package/lib/features/chat/AskUserCard.js.map +1 -1
  19. package/lib/features/chat/ChatTranscript.js +206 -130
  20. package/lib/features/chat/ChatTranscript.js.map +1 -1
  21. package/lib/features/chat/askUser.js +111 -15
  22. package/lib/features/chat/askUser.js.map +1 -1
  23. package/lib/features/chat/streamingMarkdown.js +7 -0
  24. package/lib/features/chat/streamingMarkdown.js.map +1 -0
  25. package/lib/features/chat/transcriptGroups.js +29 -0
  26. package/lib/features/chat/transcriptGroups.js.map +1 -0
  27. package/lib/features/messaging/nativeChatRegistry.js +7 -0
  28. package/lib/features/messaging/nativeChatRegistry.js.map +1 -0
  29. package/lib/features/messaging/useChatViewer.js +32 -0
  30. package/lib/features/messaging/useChatViewer.js.map +1 -0
  31. package/lib/hooks/mintSurfaceSystemToken.js +28 -14
  32. package/lib/hooks/mintSurfaceSystemToken.js.map +1 -1
  33. package/lib/hooks/systemTokenJwt.js +75 -0
  34. package/lib/hooks/systemTokenJwt.js.map +1 -0
  35. package/lib/hooks/useCdecliAutoConnect.js +116 -138
  36. package/lib/hooks/useCdecliAutoConnect.js.map +1 -1
  37. package/lib/hooks/useChatApi.js +43 -17
  38. package/lib/hooks/useChatApi.js.map +1 -1
  39. package/lib/hooks/useChatStream.js +61 -13
  40. package/lib/hooks/useChatStream.js.map +1 -1
  41. package/lib/hooks/useObtainSystemToken.js +121 -36
  42. package/lib/hooks/useObtainSystemToken.js.map +1 -1
  43. package/lib/index.js +1 -1
  44. package/lib/index.js.map +1 -1
  45. package/lib/routes.json +53 -0
  46. package/lib/screens/Chat/index.js +25 -6
  47. package/lib/screens/Chat/index.js.map +1 -1
  48. package/lib/screens/ChatNative/index.js +69 -0
  49. package/lib/screens/ChatNative/index.js.map +1 -0
  50. package/lib/screens/Home/HomeScreen.js +21 -6
  51. package/lib/screens/Home/HomeScreen.js.map +1 -1
  52. package/lib/screens/Home/components/ChatHistoryLanding.js +46 -16
  53. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  54. package/lib/utils/authUserDisplay.js +37 -0
  55. package/lib/utils/authUserDisplay.js.map +1 -0
  56. package/package.json +3 -3
@@ -1,27 +1,123 @@
1
1
  const MAX_ASK_USER_QUESTIONS = 4;
2
2
  const ASK_USER_RE = /\[ASK_USER\]([\s\S]*?)\[\/ASK_USER\]/;
3
+ const ASK_USER_OPEN_RE = /\[ASK_USER\]/;
4
+ function unwrapJsonCandidate(inner) {
5
+ let s = inner.trim();
6
+ const fence = /^```(?:json)?\s*([\s\S]*?)\s*```$/i.exec(s);
7
+ if (fence) s = fence[1].trim();
8
+ return s;
9
+ }
10
+ function parseJsonObject(s) {
11
+ const start = s.indexOf("{");
12
+ if (start < 0) return null;
13
+ let depth = 0;
14
+ let inStr = false;
15
+ let esc = false;
16
+ for (let i = start; i < s.length; i++) {
17
+ const c = s[i];
18
+ if (inStr) {
19
+ if (esc) {
20
+ esc = false;
21
+ continue;
22
+ }
23
+ if (c === "\\") {
24
+ esc = true;
25
+ continue;
26
+ }
27
+ if (c === '"') inStr = false;
28
+ continue;
29
+ }
30
+ if (c === '"') {
31
+ inStr = true;
32
+ continue;
33
+ }
34
+ if (c === "{") depth += 1;
35
+ else if (c === "}") {
36
+ depth -= 1;
37
+ if (depth === 0) {
38
+ try {
39
+ return JSON.parse(s.slice(start, i + 1));
40
+ } catch (e) {
41
+ return null;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ return null;
47
+ }
48
+ function normalizeQuestion(raw) {
49
+ if (!raw || typeof raw !== "object") return null;
50
+ const q = raw;
51
+ const id = typeof q.id === "string" ? q.id : "";
52
+ const title = typeof q.title === "string" ? q.title : typeof q.question === "string" ? q.question : "";
53
+ if (!id || !title.trim()) return null;
54
+ const options = Array.isArray(q.options) ? q.options.filter((o) => !!o && typeof o === "object" && typeof o.id === "string" && typeof o.label === "string") : void 0;
55
+ return {
56
+ id,
57
+ title: title.trim(),
58
+ header: typeof q.header === "string" ? q.header : void 0,
59
+ options,
60
+ allowText: q.allowText !== false,
61
+ textPlaceholder: typeof q.textPlaceholder === "string" ? q.textPlaceholder : void 0,
62
+ multiSelect: q.multiSelect === true
63
+ };
64
+ }
3
65
  function parseAskUser(raw) {
66
+ var _a;
4
67
  if (!(raw == null ? void 0 : raw.trim())) return null;
5
- const m = ASK_USER_RE.exec(raw);
6
- if (!m) return null;
7
- try {
8
- const parsed = JSON.parse(m[1]);
9
- if (!(parsed == null ? void 0 : parsed.requestId) || !Array.isArray(parsed.questions)) return null;
10
- const questions = parsed.questions.filter((q) => q && typeof q.id === "string" && typeof q.title === "string" && q.title.trim()).slice(0, MAX_ASK_USER_QUESTIONS);
11
- return questions.length ? {
12
- requestId: parsed.requestId,
13
- questions
14
- } : null;
15
- } catch (e) {
16
- return null;
17
- }
68
+ const tagged = (_a = ASK_USER_RE.exec(raw)) != null ? _a : ASK_USER_OPEN_RE.test(raw) ? /\[ASK_USER\]([\s\S]*)$/.exec(raw) : null;
69
+ if (!tagged) return null;
70
+ const parsed = parseJsonObject(unwrapJsonCandidate(tagged[1]));
71
+ if (!parsed || typeof parsed !== "object") return null;
72
+ const body = parsed;
73
+ if (typeof body.requestId !== "string" || !Array.isArray(body.questions)) return null;
74
+ const questions = body.questions.map(normalizeQuestion).filter((q) => q !== null).slice(0, MAX_ASK_USER_QUESTIONS);
75
+ return questions.length ? {
76
+ requestId: body.requestId,
77
+ questions
78
+ } : null;
18
79
  }
19
80
  function stripAskUser(raw) {
20
81
  if (!raw) return "";
21
- const stripped = raw.replace(new RegExp(ASK_USER_RE.source, "g"), "");
82
+ let stripped = raw.replace(new RegExp(ASK_USER_RE.source, "g"), "");
83
+ stripped = stripped.replace(/\[ASK_USER\][\s\S]*$/, "");
22
84
  if (stripped === raw) return raw;
23
85
  return stripped.replace(/\n{3,}/g, "\n\n").trim();
24
86
  }
87
+ function splitAskUserParts(raw) {
88
+ if (!raw) return {
89
+ before: "",
90
+ after: "",
91
+ hasMarker: false
92
+ };
93
+ const tagged = ASK_USER_RE.exec(raw);
94
+ if (tagged && tagged.index !== void 0) {
95
+ return {
96
+ before: raw.slice(0, tagged.index).trim(),
97
+ after: raw.slice(tagged.index + tagged[0].length).trim(),
98
+ hasMarker: true
99
+ };
100
+ }
101
+ const open = raw.search(ASK_USER_OPEN_RE);
102
+ if (open >= 0) {
103
+ return {
104
+ before: raw.slice(0, open).trim(),
105
+ after: "",
106
+ hasMarker: true
107
+ };
108
+ }
109
+ return {
110
+ before: "",
111
+ after: "",
112
+ hasMarker: false
113
+ };
114
+ }
115
+ function displayAskUserAssistantText(raw, answered) {
116
+ const parts = splitAskUserParts(raw);
117
+ if (!parts.hasMarker) return stripAskUser(raw);
118
+ const keep = answered ? parts.after : [parts.before, parts.after].filter(Boolean).join("\n\n");
119
+ return stripAskUser(keep || (answered ? "" : parts.before));
120
+ }
25
121
  function pendingAskUser(messages) {
26
122
  for (let i = messages.length - 1; i >= 0; i--) {
27
123
  const msg = messages[i];
@@ -37,4 +133,4 @@ function formatAskUserAnswers(questions, answers) {
37
133
  const answer = (_a = answers[q.id]) == null ? void 0 : _a.trim();
38
134
  return answer ? `**${q.title.replace(/:\s*$/, "")}:** ${answer}` : null;
39
135
  }).filter(Boolean).join("\n\n");
40
- }export{MAX_ASK_USER_QUESTIONS,formatAskUserAnswers,parseAskUser,pendingAskUser,stripAskUser};//# sourceMappingURL=askUser.js.map
136
+ }export{MAX_ASK_USER_QUESTIONS,displayAskUserAssistantText,formatAskUserAnswers,parseAskUser,pendingAskUser,splitAskUserParts,stripAskUser};//# sourceMappingURL=askUser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"askUser.js","sources":["../../../src/features/chat/askUser.ts"],"sourcesContent":["/**\n * The `[ASK_USER]` clarifying-question protocol, mobile side (Clockbook #1643).\n *\n * cdecli emits the block itself — from Claude's AskUserQuestion and its own\n * ask_user_question tool — and PARKS the run until the answer arrives:\n *\n * [ASK_USER]{\"requestId\":\"ask-…\",\"questions\":[{\"id\":\"q1\",\"title\":\"Which\n * database?\",\"header\":\"Database\",\"options\":[{\"id\":\"o1\",\"label\":\"Postgres\",\n * \"detail\":\"…\"}],\"allowText\":true}]}[/ASK_USER]\n *\n * The reply is deliberately NOT a marker: answers are formatted into one visible\n * user message (`**Title:** answer` lines) and sent through the normal chat path,\n * so the producer needs no reply-protocol support. Only the question side is\n * structured.\n *\n * Deliberately a copy of the web's `responsePromptProtocol` rather than an\n * import — mobile is a separate bundle and shares no code with the web shell.\n * The reply side is plain text, so the two stay compatible without a shared\n * version.\n */\n\nexport interface AskUserOption {\n id: string;\n label: string;\n /** Secondary line under the label. */\n detail?: string;\n /** \"Something else\": focuses the free-text row instead of answering. */\n other?: boolean;\n}\n\nexport interface AskUserQuestion {\n id: string;\n /** Also the bold prefix of the formatted answer. */\n title: string;\n /** Short category eyebrow above the title, e.g. \"Database\". */\n header?: string;\n options?: AskUserOption[];\n /** Show the free-text row (default true). */\n allowText?: boolean;\n textPlaceholder?: string;\n /** Pick several options; the answer is sent as comma-joined labels. */\n multiSelect?: boolean;\n}\n\nexport interface AskUserPayload {\n requestId: string;\n questions: AskUserQuestion[];\n}\n\n/** Anything longer is a form, not a prompt — the web caps it the same way. */\nexport const MAX_ASK_USER_QUESTIONS = 4;\n\n// Not anchored: the channel layer may prepend a stream envelope or cost banner.\nconst ASK_USER_RE = /\\[ASK_USER\\]([\\s\\S]*?)\\[\\/ASK_USER\\]/;\n\n/** Parse an `[ASK_USER]…[/ASK_USER]` message, or null if it isn't one. */\nexport function parseAskUser(raw: string | null | undefined): AskUserPayload | null {\n if (!raw?.trim()) return null;\n const m = ASK_USER_RE.exec(raw);\n if (!m) return null;\n try {\n const parsed = JSON.parse(m[1]) as AskUserPayload;\n if (!parsed?.requestId || !Array.isArray(parsed.questions)) return null;\n const questions = parsed.questions\n .filter((q) => q && typeof q.id === 'string' && typeof q.title === 'string' && q.title.trim())\n .slice(0, MAX_ASK_USER_QUESTIONS);\n return questions.length ? { requestId: parsed.requestId, questions } : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Remove every `[ASK_USER]` block, leaving the rest of the message intact.\n *\n * cdecli emits the block MID-turn and keeps streaming its reply into the SAME\n * message once the answer releases the parked run, so the block and the reply it\n * was asked for share one message. Hiding the whole message — which is what a\n * naive implementation does — would swallow that reply.\n */\nexport function stripAskUser(raw: string | null | undefined): string {\n if (!raw) return '';\n const stripped = raw.replace(new RegExp(ASK_USER_RE.source, 'g'), '');\n if (stripped === raw) return raw;\n return stripped.replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n/**\n * The question still awaiting an answer: the last assistant block, unless the\n * user has already replied after it. Scanning backwards means a stale card from\n * earlier in the thread never reappears.\n */\nexport function pendingAskUser(messages: ReadonlyArray<{ role: string; content: string }>): AskUserPayload | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'user') return null;\n const parsed = msg.role === 'assistant' ? parseAskUser(msg.content) : null;\n if (parsed) return parsed;\n }\n return null;\n}\n\n/**\n * Fold the answers into the single visible reply message:\n *\n * **Which database?:** Postgres\n *\n * Skipped questions are omitted; an empty result means \"nothing to send\", which\n * the card treats as a dismiss.\n */\nexport function formatAskUserAnswers(questions: readonly AskUserQuestion[], answers: Record<string, string>): string {\n return questions\n .map((q) => {\n const answer = answers[q.id]?.trim();\n return answer ? `**${q.title.replace(/:\\s*$/, '')}:** ${answer}` : null;\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n"],"names":[],"mappings":"AAgDO,MAAM,sBAAyB,GAAA;AAGtC,MAAM,WAAc,GAAA,sCAAA;AAGb,SAAS,aAAa,GAAuD,EAAA;AAClF,EAAI,IAAA,EAAC,GAAK,IAAA,IAAA,GAAA,MAAA,GAAA,GAAA,CAAA,IAAA,EAAA,CAAA,EAAe,OAAA,IAAA;AACzB,EAAM,MAAA,CAAA,GAAI,WAAY,CAAA,IAAA,CAAK,GAAG,CAAA;AAC9B,EAAI,IAAA,CAAC,GAAU,OAAA,IAAA;AACf,EAAI,IAAA;AACF,IAAA,MAAM,MAAS,GAAA,IAAA,CAAK,KAAM,CAAA,CAAA,CAAE,CAAC,CAAC,CAAA;AAC9B,IAAI,IAAA,EAAC,iCAAQ,SAAa,CAAA,IAAA,CAAC,MAAM,OAAQ,CAAA,MAAA,CAAO,SAAS,CAAA,EAAU,OAAA,IAAA;AACnE,IAAM,MAAA,SAAA,GAAY,OAAO,SAAU,CAAA,MAAA,CAAO,OAAK,CAAK,IAAA,OAAO,EAAE,EAAO,KAAA,QAAA,IAAY,OAAO,CAAE,CAAA,KAAA,KAAU,YAAY,CAAE,CAAA,KAAA,CAAM,MAAM,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,sBAAsB,CAAA;AAC9J,IAAA,OAAO,UAAU,MAAS,GAAA;AAAA,MACxB,WAAW,MAAO,CAAA,SAAA;AAAA,MAClB;AAAA,KACE,GAAA,IAAA;AAAA,GACE,CAAA,OAAA,CAAA,EAAA;AACN,IAAO,OAAA,IAAA;AAAA;AAEX;AAUO,SAAS,aAAa,GAAwC,EAAA;AACnE,EAAI,IAAA,CAAC,KAAY,OAAA,EAAA;AACjB,EAAM,MAAA,QAAA,GAAW,IAAI,OAAQ,CAAA,IAAI,OAAO,WAAY,CAAA,MAAA,EAAQ,GAAG,CAAA,EAAG,EAAE,CAAA;AACpE,EAAI,IAAA,QAAA,KAAa,KAAY,OAAA,GAAA;AAC7B,EAAA,OAAO,QAAS,CAAA,OAAA,CAAQ,SAAW,EAAA,MAAM,EAAE,IAAK,EAAA;AAClD;AAOO,SAAS,eAAe,QAGJ,EAAA;AACzB,EAAA,KAAA,IAAS,IAAI,QAAS,CAAA,MAAA,GAAS,CAAG,EAAA,CAAA,IAAK,GAAG,CAAK,EAAA,EAAA;AAC7C,IAAM,MAAA,GAAA,GAAM,SAAS,CAAC,CAAA;AACtB,IAAI,IAAA,GAAA,CAAI,IAAS,KAAA,MAAA,EAAe,OAAA,IAAA;AAChC,IAAA,MAAM,SAAS,GAAI,CAAA,IAAA,KAAS,cAAc,YAAa,CAAA,GAAA,CAAI,OAAO,CAAI,GAAA,IAAA;AACtE,IAAA,IAAI,QAAe,OAAA,MAAA;AAAA;AAErB,EAAO,OAAA,IAAA;AACT;AAUgB,SAAA,oBAAA,CAAqB,WAAuC,OAAyC,EAAA;AACnH,EAAO,OAAA,SAAA,CAAU,IAAI,CAAK,CAAA,KAAA;AAjH5B,IAAA,IAAA,EAAA;AAkHI,IAAA,MAAM,MAAS,GAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,CAAE,CAAA,EAAE,MAAZ,IAAe,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA;AAC9B,IAAO,OAAA,MAAA,GAAS,CAAK,EAAA,EAAA,CAAA,CAAE,KAAM,CAAA,OAAA,CAAQ,SAAS,EAAE,CAAC,CAAO,IAAA,EAAA,MAAM,CAAK,CAAA,GAAA,IAAA;AAAA,GACpE,CAAE,CAAA,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,MAAM,CAAA;AAChC"}
1
+ {"version":3,"file":"askUser.js","sources":["../../../src/features/chat/askUser.ts"],"sourcesContent":["/**\n * The `[ASK_USER]` clarifying-question protocol, mobile side (Clockbook #1643).\n *\n * cdecli emits the block itself — from Claude's AskUserQuestion and its own\n * ask_user_question tool — and PARKS the run until the answer arrives:\n *\n * [ASK_USER]{\"requestId\":\"ask-…\",\"questions\":[{\"id\":\"q1\",\"title\":\"Which\n * database?\",\"header\":\"Database\",\"options\":[{\"id\":\"o1\",\"label\":\"Postgres\",\n * \"detail\":\"…\"}],\"allowText\":true}]}[/ASK_USER]\n *\n * The reply is deliberately NOT a marker: answers are formatted into one visible\n * user message (`**Title:** answer` lines) and sent through the normal chat path,\n * so the producer needs no reply-protocol support. Only the question side is\n * structured.\n *\n * Deliberately a copy of the web's `responsePromptProtocol` rather than an\n * import — mobile is a separate bundle and shares no code with the web shell.\n * The reply side is plain text, so the two stay compatible without a shared\n * version.\n */\n\nexport interface AskUserOption {\n id: string;\n label: string;\n /** Secondary line under the label. */\n detail?: string;\n /** \"Something else\": focuses the free-text row instead of answering. */\n other?: boolean;\n}\n\nexport interface AskUserQuestion {\n id: string;\n /** Also the bold prefix of the formatted answer. */\n title: string;\n /** Short category eyebrow above the title, e.g. \"Database\". */\n header?: string;\n options?: AskUserOption[];\n /** Show the free-text row (default true). */\n allowText?: boolean;\n textPlaceholder?: string;\n /** Pick several options; the answer is sent as comma-joined labels. */\n multiSelect?: boolean;\n}\n\nexport interface AskUserPayload {\n requestId: string;\n questions: AskUserQuestion[];\n}\n\n/** Anything longer is a form, not a prompt — the web caps it the same way. */\nexport const MAX_ASK_USER_QUESTIONS = 4;\n\n// Not anchored: the channel layer may prepend a stream envelope or cost banner.\nconst ASK_USER_RE = /\\[ASK_USER\\]([\\s\\S]*?)\\[\\/ASK_USER\\]/;\nconst ASK_USER_OPEN_RE = /\\[ASK_USER\\]/;\n\nfunction unwrapJsonCandidate(inner: string): string {\n let s = inner.trim();\n const fence = /^```(?:json)?\\s*([\\s\\S]*?)\\s*```$/i.exec(s);\n if (fence) s = fence[1].trim();\n return s;\n}\n\n/** First complete `{...}` object in `s`, or null while the JSON is still streaming. */\nfunction parseJsonObject(s: string): unknown | null {\n const start = s.indexOf('{');\n if (start < 0) return null;\n let depth = 0;\n let inStr = false;\n let esc = false;\n for (let i = start; i < s.length; i++) {\n const c = s[i];\n if (inStr) {\n if (esc) {\n esc = false;\n continue;\n }\n if (c === '\\\\') {\n esc = true;\n continue;\n }\n if (c === '\"') inStr = false;\n continue;\n }\n if (c === '\"') {\n inStr = true;\n continue;\n }\n if (c === '{') depth += 1;\n else if (c === '}') {\n depth -= 1;\n if (depth === 0) {\n try {\n return JSON.parse(s.slice(start, i + 1));\n } catch {\n return null;\n }\n }\n }\n }\n return null;\n}\n\nfunction normalizeQuestion(raw: unknown): AskUserQuestion | null {\n if (!raw || typeof raw !== 'object') return null;\n const q = raw as Record<string, unknown>;\n const id = typeof q.id === 'string' ? q.id : '';\n const title = typeof q.title === 'string' ? q.title : typeof q.question === 'string' ? q.question : '';\n if (!id || !title.trim()) return null;\n const options = Array.isArray(q.options)\n ? q.options.filter(\n (o): o is AskUserOption =>\n !!o &&\n typeof o === 'object' &&\n typeof (o as AskUserOption).id === 'string' &&\n typeof (o as AskUserOption).label === 'string',\n )\n : undefined;\n return {\n id,\n title: title.trim(),\n header: typeof q.header === 'string' ? q.header : undefined,\n options,\n allowText: q.allowText !== false,\n textPlaceholder: typeof q.textPlaceholder === 'string' ? q.textPlaceholder : undefined,\n multiSelect: q.multiSelect === true,\n };\n}\n\n/** Parse an `[ASK_USER]…[/ASK_USER]` message, or null if it isn't one. */\nexport function parseAskUser(raw: string | null | undefined): AskUserPayload | null {\n if (!raw?.trim()) return null;\n const tagged = ASK_USER_RE.exec(raw) ?? (ASK_USER_OPEN_RE.test(raw) ? /\\[ASK_USER\\]([\\s\\S]*)$/.exec(raw) : null);\n if (!tagged) return null;\n const parsed = parseJsonObject(unwrapJsonCandidate(tagged[1]));\n if (!parsed || typeof parsed !== 'object') return null;\n const body = parsed as { requestId?: unknown; questions?: unknown };\n if (typeof body.requestId !== 'string' || !Array.isArray(body.questions)) return null;\n const questions = body.questions\n .map(normalizeQuestion)\n .filter((q): q is AskUserQuestion => q !== null)\n .slice(0, MAX_ASK_USER_QUESTIONS);\n return questions.length ? { requestId: body.requestId, questions } : null;\n}\n\n/**\n * Remove every `[ASK_USER]` block, leaving the rest of the message intact.\n *\n * cdecli emits the block MID-turn and keeps streaming its reply into the SAME\n * message once the answer releases the parked run, so the block and the reply it\n * was asked for share one message. Hiding the whole message — which is what a\n * naive implementation does — would swallow that reply.\n *\n * An unclosed `[ASK_USER]` (still streaming) is also stripped so the raw JSON\n * never paints in the bubble the way it does on web after `stripAskUser`.\n */\nexport function stripAskUser(raw: string | null | undefined): string {\n if (!raw) return '';\n let stripped = raw.replace(new RegExp(ASK_USER_RE.source, 'g'), '');\n stripped = stripped.replace(/\\[ASK_USER\\][\\s\\S]*$/, '');\n if (stripped === raw) return raw;\n return stripped.replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n/**\n * Text around an `[ASK_USER]` marker. cdecli often speaks an intro *before* the\n * card (\"I'll need a couple more details…\") and streams the real reply *after*\n * the user answers. Once there is a user reply, the intro is stale.\n */\nexport function splitAskUserParts(raw: string | null | undefined): {\n before: string;\n after: string;\n hasMarker: boolean;\n} {\n if (!raw) return { before: '', after: '', hasMarker: false };\n const tagged = ASK_USER_RE.exec(raw);\n if (tagged && tagged.index !== undefined) {\n return {\n before: raw.slice(0, tagged.index).trim(),\n after: raw.slice(tagged.index + tagged[0].length).trim(),\n hasMarker: true,\n };\n }\n const open = raw.search(ASK_USER_OPEN_RE);\n if (open >= 0) {\n return { before: raw.slice(0, open).trim(), after: '', hasMarker: true };\n }\n return { before: '', after: '', hasMarker: false };\n}\n\n/**\n * Assistant prose to paint. After the user answers the card, drop the intro that\n * sat above `[ASK_USER]` so we don't re-ask for details already in the thread.\n */\nexport function displayAskUserAssistantText(raw: string | null | undefined, answered: boolean): string {\n const parts = splitAskUserParts(raw);\n if (!parts.hasMarker) return stripAskUser(raw);\n const keep = answered ? parts.after : [parts.before, parts.after].filter(Boolean).join('\\n\\n');\n return stripAskUser(keep || (answered ? '' : parts.before));\n}\n\n/**\n * The question still awaiting an answer: the last assistant block, unless the\n * user has already replied after it. Scanning backwards means a stale card from\n * earlier in the thread never reappears.\n */\nexport function pendingAskUser(messages: ReadonlyArray<{ role: string; content: string }>): AskUserPayload | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'user') return null;\n const parsed = msg.role === 'assistant' ? parseAskUser(msg.content) : null;\n if (parsed) return parsed;\n }\n return null;\n}\n\n/**\n * Fold the answers into the single visible reply message:\n *\n * **Which database?:** Postgres\n *\n * Skipped questions are omitted; an empty result means \"nothing to send\", which\n * the card treats as a dismiss.\n */\nexport function formatAskUserAnswers(questions: readonly AskUserQuestion[], answers: Record<string, string>): string {\n return questions\n .map((q) => {\n const answer = answers[q.id]?.trim();\n return answer ? `**${q.title.replace(/:\\s*$/, '')}:** ${answer}` : null;\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ function closeOpenMarkdownFences(text) {
2
+ if (!text) return text;
3
+ const opens = text.match(/^ {0,3}```/gm);
4
+ if (!opens || opens.length % 2 === 0) return text;
5
+ return `${text}
6
+ \`\`\``;
7
+ }export{closeOpenMarkdownFences};//# sourceMappingURL=streamingMarkdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamingMarkdown.js","sources":["../../../src/features/chat/streamingMarkdown.ts"],"sourcesContent":["/**\n * Streaming markdown is incomplete: the model often has an open ``` fence\n * when the next token has not arrived. Closing it for the preview makes\n * react-native-markdown-display paint a code block instead of raw fences.\n */\nexport function closeOpenMarkdownFences(text: string): string {\n if (!text) return text;\n const opens = text.match(/^ {0,3}```/gm);\n if (!opens || opens.length % 2 === 0) return text;\n return `${text}\\n\\`\\`\\``;\n}\n"],"names":[],"mappings":"AAKO,SAAS,wBAAwB,IAAsB,EAAA;AAC5D,EAAI,IAAA,CAAC,MAAa,OAAA,IAAA;AAClB,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,KAAA,CAAM,cAAc,CAAA;AACvC,EAAA,IAAI,CAAC,KAAS,IAAA,KAAA,CAAM,MAAS,GAAA,CAAA,KAAM,GAAU,OAAA,IAAA;AAC7C,EAAA,OAAO,GAAG,IAAI;AAAA,MAAA,CAAA;AAChB"}
@@ -0,0 +1,29 @@
1
+ function collapseDuplicateUserRows(rows) {
2
+ const out = [];
3
+ for (const row of rows) {
4
+ const last = out[out.length - 1];
5
+ const trimmed = row.content.trim();
6
+ if (row.role === "user" && (last == null ? void 0 : last.role) === "user" && last.content.trim() === trimmed && trimmed) {
7
+ continue;
8
+ }
9
+ out.push(row);
10
+ }
11
+ return out;
12
+ }
13
+ function groupConsecutiveRoleRows(rows) {
14
+ const groups = [];
15
+ for (const row of rows) {
16
+ const last = groups[groups.length - 1];
17
+ if (last && last.role === row.role) {
18
+ last.items.push(row);
19
+ last.id = `${last.items[0].id}..${row.id}`;
20
+ } else {
21
+ groups.push({
22
+ id: row.id,
23
+ role: row.role,
24
+ items: [row]
25
+ });
26
+ }
27
+ }
28
+ return groups;
29
+ }export{collapseDuplicateUserRows,groupConsecutiveRoleRows};//# sourceMappingURL=transcriptGroups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcriptGroups.js","sources":["../../../src/features/chat/transcriptGroups.ts"],"sourcesContent":["/**\n * Consecutive same-role turns share one visual cluster, matching web\n * (stacked bubbles, not one concatenated blob). ASK_USER-only assistant rows\n * are stripped first, so a card answer sits under the original prompt as its\n * own bubble in the same right-aligned stack.\n */\n\nexport type RoleRow = {\n id: string;\n role: string;\n content: string;\n};\n\nexport type RoleGroup<T extends RoleRow> = {\n id: string;\n role: string;\n items: T[];\n};\n\n/** Drop an immediately-repeated user bubble (web planMessages). */\nexport function collapseDuplicateUserRows<T extends RoleRow>(rows: readonly T[]): T[] {\n const out: T[] = [];\n for (const row of rows) {\n const last = out[out.length - 1];\n const trimmed = row.content.trim();\n if (row.role === 'user' && last?.role === 'user' && last.content.trim() === trimmed && trimmed) {\n continue;\n }\n out.push(row);\n }\n return out;\n}\n\nexport function groupConsecutiveRoleRows<T extends RoleRow>(rows: readonly T[]): Array<RoleGroup<T>> {\n const groups: Array<RoleGroup<T>> = [];\n for (const row of rows) {\n const last = groups[groups.length - 1];\n if (last && last.role === row.role) {\n last.items.push(row);\n last.id = `${last.items[0].id}..${row.id}`;\n } else {\n groups.push({ id: row.id, role: row.role, items: [row] });\n }\n }\n return groups;\n}\n\n/** Visible user-group copy, one block — follow-ups append to the previous send. */\nexport function joinGroupedTexts(texts: readonly string[]): string {\n return texts\n .map((t) => t.trim())\n .filter(Boolean)\n .join('\\n\\n');\n}\n"],"names":[],"mappings":"AAmBO,SAAS,0BAA6C,IAAyB,EAAA;AACpF,EAAA,MAAM,MAAW,EAAC;AAClB,EAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,IAAA,MAAM,IAAO,GAAA,GAAA,CAAI,GAAI,CAAA,MAAA,GAAS,CAAC,CAAA;AAC/B,IAAM,MAAA,OAAA,GAAU,GAAI,CAAA,OAAA,CAAQ,IAAK,EAAA;AACjC,IAAI,IAAA,GAAA,CAAI,IAAS,KAAA,MAAA,IAAA,CAAU,IAAM,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,IAAA,MAAS,MAAU,IAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,EAAW,KAAA,OAAA,IAAW,OAAS,EAAA;AAC9F,MAAA;AAAA;AAEF,IAAA,GAAA,CAAI,KAAK,GAAG,CAAA;AAAA;AAEd,EAAO,OAAA,GAAA;AACT;AACO,SAAS,yBAA4C,IAAyC,EAAA;AACnG,EAAA,MAAM,SAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,IAAA,MAAM,IAAO,GAAA,MAAA,CAAO,MAAO,CAAA,MAAA,GAAS,CAAC,CAAA;AACrC,IAAA,IAAI,IAAQ,IAAA,IAAA,CAAK,IAAS,KAAA,GAAA,CAAI,IAAM,EAAA;AAClC,MAAK,IAAA,CAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACnB,MAAK,IAAA,CAAA,EAAA,GAAK,GAAG,IAAK,CAAA,KAAA,CAAM,CAAC,CAAE,CAAA,EAAE,CAAK,EAAA,EAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AAAA,KACnC,MAAA;AACL,MAAA,MAAA,CAAO,IAAK,CAAA;AAAA,QACV,IAAI,GAAI,CAAA,EAAA;AAAA,QACR,MAAM,GAAI,CAAA,IAAA;AAAA,QACV,KAAA,EAAO,CAAC,GAAG;AAAA,OACZ,CAAA;AAAA;AACH;AAEF,EAAO,OAAA,MAAA;AACT"}
@@ -0,0 +1,7 @@
1
+ let current = null;
2
+ function registerNativeChatExperience(component) {
3
+ current = component;
4
+ }
5
+ function getNativeChatExperience() {
6
+ return current;
7
+ }export{getNativeChatExperience,registerNativeChatExperience};//# sourceMappingURL=nativeChatRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeChatRegistry.js","sources":["../../../src/features/messaging/nativeChatRegistry.ts"],"sourcesContent":["/**\n * The chat surface seam - same pattern as the canvas and characters registries:\n * the APP (the Module Federation host) registers the federated component at\n * startup and the ChatNative screen in this package reads it back. The package\n * itself never names the remote, so rollup's lib/ build stays free of\n * `chat_native/...` specifiers, which it cannot resolve.\n *\n * Exported from the package index ON PURPOSE: reachability from the entry is\n * what stops rollup tree-shaking `registerNativeChatExperience` as\n * internally-unused and constant-folding readers to undefined (the exact\n * failure ya#965 fixed for canvas).\n */\nimport type * as React from 'react';\nimport type { FederatedChatProps } from './chatHost';\n\n/**\n * The registered component is the HOST's loader, which injects the seams, so\n * the screen only owes it identity + navigation (`FederatedChatProps`).\n */\ntype ChatComponent = React.ComponentType<FederatedChatProps>;\n\nlet current: ChatComponent | null = null;\n\nexport function registerNativeChatExperience(component: ChatComponent): void {\n current = component;\n}\n\n/** Null when the host app has not injected a loader (a build without federation). */\nexport function getNativeChatExperience(): ChatComponent | null {\n return current;\n}\n"],"names":[],"mappings":"AAoBA,IAAI,OAAgC,GAAA,IAAA;AAC7B,SAAS,6BAA6B,SAAgC,EAAA;AAC3E,EAAU,OAAA,GAAA,SAAA;AACZ;AAGO,SAAS,uBAAgD,GAAA;AAC9D,EAAO,OAAA,OAAA;AACT"}
@@ -0,0 +1,32 @@
1
+ import {useMemo}from'react';import {useSelector}from'react-redux';import {userSelector}from'@adminide-stack/user-auth0-client';import {useAccountProfileQuery}from'common/graphql';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {pickPrimaryDisplayName,pickAuthPicture}from'../../utils/authUserDisplay.js';function useChatViewer() {
2
+ var _a, _b, _c, _d;
3
+ const authUser = useSelector(userSelector);
4
+ const {
5
+ orgName,
6
+ orgLoading
7
+ } = usePrerequisiteIds();
8
+ const {
9
+ data,
10
+ loading: profileLoading,
11
+ error: profileError
12
+ } = useAccountProfileQuery({
13
+ fetchPolicy: "cache-and-network",
14
+ errorPolicy: "all"
15
+ });
16
+ const userId = (_c = (_b = (_a = data == null ? void 0 : data.accountProfile) == null ? void 0 : _a.user) == null ? void 0 : _b.id) != null ? _c : null;
17
+ const displayName = useMemo(() => pickPrimaryDisplayName(authUser), [authUser]);
18
+ const avatarUrl = useMemo(() => pickAuthPicture(authUser), [authUser]);
19
+ const viewer = useMemo(() => userId ? {
20
+ userId,
21
+ displayName,
22
+ avatarUrl,
23
+ orgName: orgName != null ? orgName : null
24
+ } : null, [userId, displayName, avatarUrl, orgName]);
25
+ const ready = !profileLoading && !orgLoading;
26
+ const error = !viewer && ready ? (_d = profileError == null ? void 0 : profileError.message) != null ? _d : "Could not load your account." : null;
27
+ return {
28
+ viewer,
29
+ error,
30
+ ready
31
+ };
32
+ }export{useChatViewer};//# sourceMappingURL=useChatViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatViewer.js","sources":["../../../src/features/messaging/useChatViewer.ts"],"sourcesContent":["/**\n * Who the chat surface thinks you are.\n *\n * Deliberately NOT the canvas session (`useCanvasSession`). That mints an\n * org/project-scoped HS256 *system* token because canvas talks to\n * out-of-process surfaces that cannot see the user's Auth0 session.\n * messenger-box lives inside the same `ideback` the app is already\n * authenticated against, so chat rides the app's ordinary Apollo client and\n * Auth0 identity - and `viewer.userId` must be the id messenger-box actually\n * keys membership on.\n *\n * `accountProfile.user.id` is that id: the `UserAccount` ObjectId that lands in\n * `ChannelMember.user` and is what `createDirectChannel(receiver: [ID!])`\n * expects. Auth0 subs and MessengerUser ids are different id spaces and will\n * silently match nothing.\n */\nimport { useMemo } from 'react';\nimport { useSelector } from 'react-redux';\nimport type { IUserState } from '@adminide-stack/core';\nimport { Store, userSelector } from '@adminide-stack/user-auth0-client';\nimport { useAccountProfileQuery } from 'common/graphql';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport { pickAuthPicture, pickPrimaryDisplayName } from '../../utils/authUserDisplay';\nimport type { ChatViewer } from './chatHost';\n\nexport interface ChatViewerState {\n /** Null until the account id resolves - render a spinner, not an error. */\n viewer: ChatViewer | null;\n /** Plain sentence when the session genuinely failed, else null. */\n error: string | null;\n /** False while org/profile are still in flight; gate `error` on this. */\n ready: boolean;\n}\n\nexport function useChatViewer(): ChatViewerState {\n const authUser = useSelector<Store.Auth, IUserState>(userSelector);\n const { orgName, orgLoading } = usePrerequisiteIds();\n\n const {\n data,\n loading: profileLoading,\n error: profileError,\n } = useAccountProfileQuery({ fetchPolicy: 'cache-and-network', errorPolicy: 'all' });\n\n const userId = data?.accountProfile?.user?.id ?? null;\n const displayName = useMemo(() => pickPrimaryDisplayName(authUser), [authUser]);\n const avatarUrl = useMemo(() => pickAuthPicture(authUser), [authUser]);\n\n const viewer = useMemo<ChatViewer | null>(\n () => (userId ? { userId, displayName, avatarUrl, orgName: orgName ?? null } : null),\n [userId, displayName, avatarUrl, orgName],\n );\n\n const ready = !profileLoading && !orgLoading;\n\n // A profile error only matters once we have stopped loading AND have no id;\n // `errorPolicy: 'all'` means a partial result can carry both.\n const error = !viewer && ready ? (profileError?.message ?? 'Could not load your account.') : null;\n\n return { viewer, error, ready };\n}\n"],"names":[],"mappings":"0UAgCO,SAAS,aAAiC,GAAA;AAhCjD,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAiCE,EAAM,MAAA,QAAA,GAAW,YAAoC,YAAY,CAAA;AACjE,EAAM,MAAA;AAAA,IACJ,OAAA;AAAA,IACA;AAAA,MACE,kBAAmB,EAAA;AACvB,EAAM,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,OAAS,EAAA,cAAA;AAAA,IACT,KAAO,EAAA;AAAA,MACL,sBAAuB,CAAA;AAAA,IACzB,WAAa,EAAA,mBAAA;AAAA,IACb,WAAa,EAAA;AAAA,GACd,CAAA;AACD,EAAA,MAAM,UAAS,EAAM,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,cAAA,KAAN,mBAAsB,IAAtB,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA4B,OAA5B,IAAkC,GAAA,EAAA,GAAA,IAAA;AACjD,EAAM,MAAA,WAAA,GAAc,QAAQ,MAAM,sBAAA,CAAuB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AAC9E,EAAM,MAAA,SAAA,GAAY,QAAQ,MAAM,eAAA,CAAgB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AACrE,EAAM,MAAA,MAAA,GAAS,OAA2B,CAAA,MAAM,MAAS,GAAA;AAAA,IACvD,MAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAS,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA;AAAA,MAClB,IAAM,EAAA,CAAC,QAAQ,WAAa,EAAA,SAAA,EAAW,OAAO,CAAC,CAAA;AACnD,EAAM,MAAA,KAAA,GAAQ,CAAC,cAAA,IAAkB,CAAC,UAAA;AAIlC,EAAA,MAAM,QAAQ,CAAC,MAAA,IAAU,SAAQ,EAAc,GAAA,YAAA,IAAA,IAAA,GAAA,MAAA,GAAA,YAAA,CAAA,OAAA,KAAd,YAAyB,8BAAiC,GAAA,IAAA;AAC3F,EAAO,OAAA;AAAA,IACL,MAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF"}
@@ -80,6 +80,11 @@ async function gqlFetch(graphqlUrl, idToken, query, variables) {
80
80
  }
81
81
  return await res.json();
82
82
  }
83
+ const REVOKE_SECRET_API_TOKEN = `
84
+ mutation RevokeSecretApiToken($id: ID!) {
85
+ revokeSecretApiToken(id: $id)
86
+ }
87
+ `;
83
88
  const DEV_TESTING_PROJECT_UUID = "9a8ac704-1040-4836-9b72-48b771ca91b1";
84
89
  const OBJECT_ID_HEX = /^[a-fA-F0-9]{24}$/;
85
90
  const PROJECT_UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
@@ -140,7 +145,7 @@ function assertMintableProjectId(projectId) {
140
145
  }
141
146
  }
142
147
  async function mintSurfaceSystemToken(input) {
143
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
148
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
144
149
  const idToken = await readAuth0IdToken();
145
150
  if (!idToken) {
146
151
  throw new Error("No Auth0 id_token in storage \u2014 sign in to the mobile app first.");
@@ -175,6 +180,15 @@ async function mintSurfaceSystemToken(input) {
175
180
  throw new Error("Missing environmentTagId \u2014 cannot mint system token.");
176
181
  }
177
182
  assertMintableProjectId(projectId);
183
+ if (input.forceRemint) {
184
+ const existing = await gqlFetch(graphqlUrl, idToken, GET_USER_SYSTEM_TOKEN);
185
+ const existingId = (_f = (_e = (_d = existing.data) == null ? void 0 : _d.getUserSystemToken) == null ? void 0 : _e.id) != null ? _f : null;
186
+ if (existingId) {
187
+ await gqlFetch(graphqlUrl, idToken, REVOKE_SECRET_API_TOKEN, {
188
+ id: existingId
189
+ }).catch(() => void 0);
190
+ }
191
+ }
178
192
  try {
179
193
  const obtained = await gqlFetch(graphqlUrl, idToken, OBTAIN_USER_SYSTEM_TOKEN, {
180
194
  input: {
@@ -185,8 +199,8 @@ async function mintSurfaceSystemToken(input) {
185
199
  algorithm: "HS256"
186
200
  }
187
201
  });
188
- const token2 = (_f = (_e = (_d = obtained.data) == null ? void 0 : _d.obtainUserSystemToken) == null ? void 0 : _e.token) == null ? void 0 : _f.trim();
189
- if (token2 && !((_g = obtained.errors) == null ? void 0 : _g.length)) {
202
+ const token2 = (_i = (_h = (_g = obtained.data) == null ? void 0 : _g.obtainUserSystemToken) == null ? void 0 : _h.token) == null ? void 0 : _i.trim();
203
+ if (token2 && !((_j = obtained.errors) == null ? void 0 : _j.length)) {
190
204
  if (__DEV__) {
191
205
  console.log("[WebBuilder] obtained system token length=", token2.length);
192
206
  }
@@ -195,8 +209,8 @@ async function mintSurfaceSystemToken(input) {
195
209
  backend: graphqlUrl
196
210
  };
197
211
  }
198
- if ((_h = obtained.errors) == null ? void 0 : _h.length) {
199
- throw new Error(((_i = obtained.errors[0]) == null ? void 0 : _i.message) || "obtainUserSystemToken failed");
212
+ if ((_k = obtained.errors) == null ? void 0 : _k.length) {
213
+ throw new Error(((_l = obtained.errors[0]) == null ? void 0 : _l.message) || "obtainUserSystemToken failed");
200
214
  }
201
215
  } catch (err) {
202
216
  if (__DEV__) {
@@ -213,10 +227,10 @@ async function mintSurfaceSystemToken(input) {
213
227
  }
214
228
  }
215
229
  const getResult = await gqlFetch(graphqlUrl, idToken, GET_USER_SYSTEM_TOKEN);
216
- if ((_j = getResult.errors) == null ? void 0 : _j.length) {
217
- throw new Error(((_k = getResult.errors[0]) == null ? void 0 : _k.message) || "GetUserSystemToken failed");
230
+ if ((_m = getResult.errors) == null ? void 0 : _m.length) {
231
+ throw new Error(((_n = getResult.errors[0]) == null ? void 0 : _n.message) || "GetUserSystemToken failed");
218
232
  }
219
- let tokenId = (_n = (_m = (_l = getResult.data) == null ? void 0 : _l.getUserSystemToken) == null ? void 0 : _m.id) != null ? _n : null;
233
+ let tokenId = (_q = (_p = (_o = getResult.data) == null ? void 0 : _o.getUserSystemToken) == null ? void 0 : _p.id) != null ? _q : null;
220
234
  if (!tokenId) {
221
235
  const createResult = await gqlFetch(graphqlUrl, idToken, CREATE_SECRET_API_TOKEN, {
222
236
  input: {
@@ -229,18 +243,18 @@ async function mintSurfaceSystemToken(input) {
229
243
  algorithm: "HS256"
230
244
  }
231
245
  });
232
- const createErr = ((_p = (_o = createResult.errors) == null ? void 0 : _o[0]) == null ? void 0 : _p.message) || "";
246
+ const createErr = ((_s = (_r = createResult.errors) == null ? void 0 : _r[0]) == null ? void 0 : _s.message) || "";
233
247
  if (createErr && !/already have a system token/i.test(createErr)) {
234
248
  if (/12 bytes|24 hex/i.test(createErr)) {
235
249
  throw new Error(`Project "${projectId}" is not valid on this backend. Pick/create a real project in the app, then retry.`);
236
250
  }
237
251
  throw new Error(createErr);
238
252
  }
239
- if ((_r = (_q = createResult.data) == null ? void 0 : _q.createSecretApiToken) == null ? void 0 : _r.id) {
253
+ if ((_u = (_t = createResult.data) == null ? void 0 : _t.createSecretApiToken) == null ? void 0 : _u.id) {
240
254
  tokenId = createResult.data.createSecretApiToken.id;
241
255
  } else {
242
256
  const refetch = await gqlFetch(graphqlUrl, idToken, GET_USER_SYSTEM_TOKEN);
243
- tokenId = (_u = (_t = (_s = refetch.data) == null ? void 0 : _s.getUserSystemToken) == null ? void 0 : _t.id) != null ? _u : null;
257
+ tokenId = (_x = (_w = (_v = refetch.data) == null ? void 0 : _v.getUserSystemToken) == null ? void 0 : _w.id) != null ? _x : null;
244
258
  }
245
259
  }
246
260
  if (!tokenId) {
@@ -249,10 +263,10 @@ async function mintSurfaceSystemToken(input) {
249
263
  const reveal = await gqlFetch(graphqlUrl, idToken, REVEAL_SECRET_API_TOKEN, {
250
264
  id: tokenId
251
265
  });
252
- if ((_v = reveal.errors) == null ? void 0 : _v.length) {
253
- throw new Error(((_w = reveal.errors[0]) == null ? void 0 : _w.message) || "RevealSecretApiToken failed");
266
+ if ((_y = reveal.errors) == null ? void 0 : _y.length) {
267
+ throw new Error(((_z = reveal.errors[0]) == null ? void 0 : _z.message) || "RevealSecretApiToken failed");
254
268
  }
255
- const token = (_y = (_x = reveal.data) == null ? void 0 : _x.revealSecretApiToken) == null ? void 0 : _y.trim();
269
+ const token = (_B = (_A = reveal.data) == null ? void 0 : _A.revealSecretApiToken) == null ? void 0 : _B.trim();
256
270
  if (!token) {
257
271
  throw new Error("RevealSecretApiToken returned empty token");
258
272
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mintSurfaceSystemToken.js","sources":["../../src/hooks/mintSurfaceSystemToken.ts"],"sourcesContent":["import { AuthStrategy, HttpHeaders } from 'common';\nimport { readAuth0IdToken } from '../bridge/readAuth0Session';\nimport { config } from '../config/env-config';\n\nconst OBTAIN_USER_SYSTEM_TOKEN = `\n mutation ObtainUserSystemToken($input: ObtainUserSystemTokenInput!) {\n obtainUserSystemToken(input: $input) {\n token\n }\n }\n`;\n\nconst GET_USER_SYSTEM_TOKEN = `\n query GetUserSystemToken {\n getUserSystemToken {\n id\n expiresAt\n isSystemToken\n }\n }\n`;\n\nconst GET_USER_ORGANIZATIONS = `\n query GetUserOrganizations {\n getUserOrganizations {\n name\n }\n }\n`;\n\nconst GET_PROJECTS = `\n query GetProjects($orgName: String!) {\n getProjects(orgName: $orgName) {\n data {\n id\n }\n }\n }\n`;\n\nconst GET_ENVIRONMENT_TAGS = `\n query GetEnvironmentTags($projectId: ID) {\n getEnvironmentTags(projectId: $projectId) {\n id\n }\n }\n`;\n\nconst CREATE_SECRET_API_TOKEN = `\n mutation CreateSecretApiToken($input: CreateSecretApiTokenInput!) {\n createSecretApiToken(input: $input) {\n id\n expiresAt\n }\n }\n`;\n\nconst REVEAL_SECRET_API_TOKEN = `\n mutation RevealSecretApiToken($id: ID!) {\n revealSecretApiToken(id: $id)\n }\n`;\n\ntype GqlResult<T> = {\n data?: T;\n errors?: Array<{ message?: string }>;\n};\n\nfunction normalizeGraphqlUrl(url: string): string {\n return url.trim().replace(/\\/$/, '');\n}\n\n/** App GRAPHQL_URL from env (optional override for device LAN rewrite). */\nexport function resolveSurfaceCatalogBackend(graphqlUrl?: string): string {\n const raw = graphqlUrl?.trim() || config.GRAPHQL_URL;\n if (!raw?.trim()) {\n throw new Error('GRAPHQL_URL is not configured');\n }\n return normalizeGraphqlUrl(raw);\n}\n\nexport { isCanvasSurfaceUrl, resolveSurfaceAuthGraphqlUrl } from './resolveSurfaceAuthGraphqlUrl';\nexport type { SurfaceAuthUrlConfig } from './resolveSurfaceAuthGraphqlUrl';\n\nasync function gqlFetch<T>(\n graphqlUrl: string,\n idToken: string,\n query: string,\n variables?: Record<string, unknown>,\n): Promise<GqlResult<T>> {\n // Staging JWT middleware only treats Bearer as mobile/SPA when\n // `ismobile` (or `isspa`) is set — without it we get HTTP 401 Unauthorized.\n // Match Apollo mobile authHeadersLink + Auth0Client.commonFetchRequestHeaders.\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers: {\n [HttpHeaders.CONTENT_TYPE]: 'application/json',\n [HttpHeaders.AUTHORIZATION]: `Bearer ${idToken}`,\n [HttpHeaders.IS_MOBILE]: 'true',\n [HttpHeaders.AUTH_STRATEGY]: AuthStrategy.Auth0,\n },\n body: JSON.stringify({ query, variables }),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`GraphQL HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n return (await res.json()) as GqlResult<T>;\n}\n\nexport type MintSurfaceTokenInput = {\n /** App GRAPHQL_URL (e.g. device-rewritten). Defaults to env GRAPHQL_URL. */\n graphqlUrl?: string;\n orgName?: string | null;\n projectId?: string | null;\n tagId?: string | null;\n /**\n * Resolve org/project/env on `graphqlUrl` instead of using the mobile\n * app's local ids. Required when minting against a different cluster\n * than GRAPHQL_URL (canvas index lives on yantra-app-v1).\n */\n discoverScope?: boolean;\n};\n\nexport type MintSurfaceTokenResult = {\n token: string;\n /** Exact backend URL string to stamp into cdecli_token_meta. */\n backend: string;\n};\n\n/**\n * Reveal (or obtain) a system token on GRAPHQL_URL.\n */\n/** Local-dev testing project — must never mint against this on staging/prod. */\nconst DEV_TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nconst OBJECT_ID_HEX = /^[a-fA-F0-9]{24}$/;\nconst PROJECT_UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\nasync function discoverMintScope(\n graphqlUrl: string,\n idToken: string,\n): Promise<{ orgName: string; projectId: string; environmentTagId: string }> {\n const orgs = await gqlFetch<{ getUserOrganizations?: Array<{ name?: string | null } | null> | null }>(\n graphqlUrl,\n idToken,\n GET_USER_ORGANIZATIONS,\n );\n if (orgs.errors?.length) {\n throw new Error(orgs.errors[0]?.message || 'getUserOrganizations failed');\n }\n const orgName = orgs.data?.getUserOrganizations?.find((o) => o?.name?.trim())?.name?.trim() || '';\n if (!orgName) {\n throw new Error(\n 'No organization on the canvas backend. Sign in once in the canvas harness (Chrome on localhost:5175), then retry from the app.',\n );\n }\n\n const projects = await gqlFetch<{ getProjects?: { data?: Array<{ id?: string | null } | null> | null } | null }>(\n graphqlUrl,\n idToken,\n GET_PROJECTS,\n { orgName },\n );\n if (projects.errors?.length) {\n throw new Error(projects.errors[0]?.message || 'getProjects failed');\n }\n const projectId = projects.data?.getProjects?.data?.find((p) => p?.id?.trim())?.id?.trim() || '';\n if (!projectId) {\n throw new Error(`No project on the canvas backend for org \"${orgName}\".`);\n }\n\n const tags = await gqlFetch<{ getEnvironmentTags?: Array<{ id?: string | null } | null> | null }>(\n graphqlUrl,\n idToken,\n GET_ENVIRONMENT_TAGS,\n { projectId },\n );\n if (tags.errors?.length) {\n throw new Error(tags.errors[0]?.message || 'getEnvironmentTags failed');\n }\n const environmentTagId = tags.data?.getEnvironmentTags?.find((t) => t?.id?.trim())?.id?.trim() || '';\n if (!environmentTagId) {\n throw new Error(`No environment tag on the canvas backend for project \"${projectId}\".`);\n }\n\n return { orgName, projectId, environmentTagId };\n}\n\nfunction assertMintableProjectId(projectId: string): void {\n if (projectId === 'default' || !projectId.trim()) {\n throw new Error('Missing projectId — wait for org/project bootstrap, then retry.');\n }\n if (!__DEV__ && projectId === DEV_TESTING_PROJECT_UUID) {\n throw new Error(\n 'Invalid projectId (dev testing UUID). Open Home so a real project can be created, then retry.',\n );\n }\n if (!OBJECT_ID_HEX.test(projectId) && !PROJECT_UUID.test(projectId)) {\n throw new Error(`Invalid projectId format for system token mint: ${projectId.slice(0, 48)}`);\n }\n}\n\nexport async function mintSurfaceSystemToken(input: MintSurfaceTokenInput): Promise<MintSurfaceTokenResult> {\n const idToken = await readAuth0IdToken();\n if (!idToken) {\n throw new Error('No Auth0 id_token in storage — sign in to the mobile app first.');\n }\n\n const graphqlUrl = resolveSurfaceCatalogBackend(input.graphqlUrl);\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minting system token via', graphqlUrl, input.discoverScope ? '(discover scope)' : '');\n }\n\n let orgName = input.orgName?.trim() || '';\n let projectId = input.projectId?.trim() || '';\n let environmentTagId = input.tagId?.trim() || '';\n\n if (input.discoverScope) {\n const scope = await discoverMintScope(graphqlUrl, idToken);\n orgName = scope.orgName;\n projectId = scope.projectId;\n environmentTagId = scope.environmentTagId;\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] discovered canvas scope', { orgName, projectId, environmentTagId });\n }\n }\n\n if (!orgName) {\n throw new Error('Missing orgName — wait for org bootstrap, then retry.');\n }\n if (!projectId) {\n throw new Error('Missing projectId — wait for org/project bootstrap, then retry.');\n }\n if (!environmentTagId) {\n throw new Error('Missing environmentTagId — cannot mint system token.');\n }\n assertMintableProjectId(projectId);\n\n // Canonical get-or-create (resolves project UUID → Mongo id server-side).\n try {\n const obtained = await gqlFetch<{ obtainUserSystemToken?: { token?: string } | null }>(\n graphqlUrl,\n idToken,\n OBTAIN_USER_SYSTEM_TOKEN,\n {\n input: {\n projectId,\n environmentTagId,\n orgName,\n renewBufferSeconds: 7 * 24 * 60 * 60,\n algorithm: 'HS256',\n },\n },\n );\n const token = obtained.data?.obtainUserSystemToken?.token?.trim();\n if (token && !obtained.errors?.length) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] obtained system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n }\n if (obtained.errors?.length) {\n throw new Error(obtained.errors[0]?.message || 'obtainUserSystemToken failed');\n }\n } catch (err) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.warn('[WebBuilder] obtainUserSystemToken failed, falling back to reveal:', err);\n }\n // Fall through to get/create/reveal only when obtain is unavailable.\n const msg = err instanceof Error ? err.message : String(err);\n if (/12 bytes|24 hex|Project not found/i.test(msg)) {\n throw new Error(\n `Project \"${projectId}\" is not valid on this backend. Pick/create a real project in the app, then retry.`,\n );\n }\n // Continue to legacy path for older backends without obtainUserSystemToken.\n if (!/Unknown field|Cannot query field|obtainUserSystemToken/i.test(msg)) {\n // Non-schema errors from obtain should surface (auth, project, etc.).\n if (/Unauthorized|401|Project not found|Invalid project/i.test(msg)) {\n throw err instanceof Error ? err : new Error(msg);\n }\n }\n }\n\n const getResult = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n if (getResult.errors?.length) {\n throw new Error(getResult.errors[0]?.message || 'GetUserSystemToken failed');\n }\n\n let tokenId = getResult.data?.getUserSystemToken?.id ?? null;\n\n if (!tokenId) {\n const createResult = await gqlFetch<{ createSecretApiToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n CREATE_SECRET_API_TOKEN,\n {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId,\n orgName,\n projectId,\n algorithm: 'HS256',\n },\n },\n );\n\n const createErr = createResult.errors?.[0]?.message || '';\n if (createErr && !/already have a system token/i.test(createErr)) {\n if (/12 bytes|24 hex/i.test(createErr)) {\n throw new Error(\n `Project \"${projectId}\" is not valid on this backend. Pick/create a real project in the app, then retry.`,\n );\n }\n throw new Error(createErr);\n }\n\n if (createResult.data?.createSecretApiToken?.id) {\n tokenId = createResult.data.createSecretApiToken.id;\n } else {\n const refetch = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n tokenId = refetch.data?.getUserSystemToken?.id ?? null;\n }\n }\n\n if (!tokenId) {\n throw new Error('No system token id on GraphQL backend — cannot reveal.');\n }\n\n const reveal = await gqlFetch<{ revealSecretApiToken?: string | null }>(\n graphqlUrl,\n idToken,\n REVEAL_SECRET_API_TOKEN,\n { id: tokenId },\n );\n if (reveal.errors?.length) {\n throw new Error(reveal.errors[0]?.message || 'RevealSecretApiToken failed');\n }\n\n const token = reveal.data?.revealSecretApiToken?.trim();\n if (!token) {\n throw new Error('RevealSecretApiToken returned empty token');\n }\n\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minted system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n}\n\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state: string): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('code', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&code=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\nfunction tokenFingerprint(token: string): string {\n const sig = token.split('.')[2] ?? token;\n return sig.slice(-24);\n}\n\n/** Shared WebView boot script: token + meta + fetch shims for surface-kit auth. */\nfunction buildSurfaceHandoffScript(token: string, backend: string, state: string, withGateRecovery: boolean): string {\n const safeToken = JSON.stringify(token);\n const safeBackend = JSON.stringify(backend);\n const safeState = JSON.stringify(state);\n const fp = JSON.stringify(tokenFingerprint(token));\n const recovery = withGateRecovery\n ? `\n function tryRecover() {\n stamp();\n var gate = document.querySelector('[data-surface-login]');\n if (!gate) return;\n if (sessionStorage.getItem('__yantra_wb_token_reload')) return;\n sessionStorage.setItem('__yantra_wb_token_reload', '1');\n var u = new URL(window.location.href);\n u.searchParams.set('token', t);\n u.searchParams.set('code', t);\n u.searchParams.set('state', state);\n window.location.replace(u.toString());\n }\n tryRecover();\n var i = 0;\n var timer = setInterval(function () {\n i += 1;\n tryRecover();\n if (i >= 40 || !document.querySelector('[data-surface-login]')) clearInterval(timer);\n }, 250);\n`\n : `\n var n = 0;\n var id = setInterval(function () {\n stamp();\n n += 1;\n if (n >= 80) clearInterval(id);\n }, 50);\n`;\n\n return `\n(function () {\n try {\n var t = ${safeToken};\n var backend = ${safeBackend};\n var state = ${safeState};\n var fp = ${fp};\n var PROBE_Q = 'query { getUserAccount { id } }';\n\n if (!window.__yantraWbFetchPatched) {\n window.__yantraWbFetchPatched = true;\n var origFetch = window.fetch.bind(window);\n window.fetch = function (input, init) {\n try {\n var url = typeof input === 'string' ? input : (input && input.url) ? String(input.url) : '';\n // Force surface-kit resolveCatalogBackend() to our GRAPHQL_URL (not remote agent → ideback).\n if (url.indexOf('/v1/auth/context') !== -1) {\n return Promise.resolve(new Response(\n JSON.stringify({ backendGraphqlUrl: backend }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n var body = init && typeof init.body === 'string' ? init.body : '';\n if (body && body.indexOf('getUserAccount') !== -1) {\n var parsed = JSON.parse(body);\n var q = parsed && typeof parsed.query === 'string' ? parsed.query.replace(/\\\\s+/g, ' ').trim() : '';\n if (q === PROBE_Q) {\n return Promise.resolve(new Response(\n JSON.stringify({ data: { getUserAccount: { id: 'mobile-webview-handoff' } } }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n }\n } catch (e0) {}\n return origFetch(input, init);\n };\n }\n\n function stamp() {\n try {\n sessionStorage.setItem('cdecli_oauth_state', state);\n localStorage.setItem('cdecli_token', t);\n sessionStorage.setItem('cdecli_token', t);\n localStorage.setItem('cdecli_system_token', t);\n localStorage.setItem('cdecli_token_meta', JSON.stringify({\n backend: backend,\n verifiedAt: Date.now(),\n fp: fp\n }));\n } catch (e1) {}\n }\n stamp();\n ${recovery}\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n\nexport function buildCdecliTokenInjection(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, false);\n}\n\nexport function buildSurfaceGateRecoveryScript(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, true);\n}\n"],"names":["_a","token"],"mappings":"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"}
1
+ {"version":3,"file":"mintSurfaceSystemToken.js","sources":["../../src/hooks/mintSurfaceSystemToken.ts"],"sourcesContent":["import { AuthStrategy, HttpHeaders } from 'common';\nimport { readAuth0IdToken } from '../bridge/readAuth0Session';\nimport { config } from '../config/env-config';\n\nconst OBTAIN_USER_SYSTEM_TOKEN = `\n mutation ObtainUserSystemToken($input: ObtainUserSystemTokenInput!) {\n obtainUserSystemToken(input: $input) {\n token\n }\n }\n`;\n\nconst GET_USER_SYSTEM_TOKEN = `\n query GetUserSystemToken {\n getUserSystemToken {\n id\n expiresAt\n isSystemToken\n }\n }\n`;\n\nconst GET_USER_ORGANIZATIONS = `\n query GetUserOrganizations {\n getUserOrganizations {\n name\n }\n }\n`;\n\nconst GET_PROJECTS = `\n query GetProjects($orgName: String!) {\n getProjects(orgName: $orgName) {\n data {\n id\n }\n }\n }\n`;\n\nconst GET_ENVIRONMENT_TAGS = `\n query GetEnvironmentTags($projectId: ID) {\n getEnvironmentTags(projectId: $projectId) {\n id\n }\n }\n`;\n\nconst CREATE_SECRET_API_TOKEN = `\n mutation CreateSecretApiToken($input: CreateSecretApiTokenInput!) {\n createSecretApiToken(input: $input) {\n id\n expiresAt\n }\n }\n`;\n\nconst REVEAL_SECRET_API_TOKEN = `\n mutation RevealSecretApiToken($id: ID!) {\n revealSecretApiToken(id: $id)\n }\n`;\n\ntype GqlResult<T> = {\n data?: T;\n errors?: Array<{ message?: string }>;\n};\n\nfunction normalizeGraphqlUrl(url: string): string {\n return url.trim().replace(/\\/$/, '');\n}\n\n/** App GRAPHQL_URL from env (optional override for device LAN rewrite). */\nexport function resolveSurfaceCatalogBackend(graphqlUrl?: string): string {\n const raw = graphqlUrl?.trim() || config.GRAPHQL_URL;\n if (!raw?.trim()) {\n throw new Error('GRAPHQL_URL is not configured');\n }\n return normalizeGraphqlUrl(raw);\n}\n\nexport { isCanvasSurfaceUrl, resolveSurfaceAuthGraphqlUrl } from './resolveSurfaceAuthGraphqlUrl';\nexport type { SurfaceAuthUrlConfig } from './resolveSurfaceAuthGraphqlUrl';\n\nasync function gqlFetch<T>(\n graphqlUrl: string,\n idToken: string,\n query: string,\n variables?: Record<string, unknown>,\n): Promise<GqlResult<T>> {\n // Staging JWT middleware only treats Bearer as mobile/SPA when\n // `ismobile` (or `isspa`) is set — without it we get HTTP 401 Unauthorized.\n // Match Apollo mobile authHeadersLink + Auth0Client.commonFetchRequestHeaders.\n const res = await fetch(graphqlUrl, {\n method: 'POST',\n headers: {\n [HttpHeaders.CONTENT_TYPE]: 'application/json',\n [HttpHeaders.AUTHORIZATION]: `Bearer ${idToken}`,\n [HttpHeaders.IS_MOBILE]: 'true',\n [HttpHeaders.AUTH_STRATEGY]: AuthStrategy.Auth0,\n },\n body: JSON.stringify({ query, variables }),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`GraphQL HTTP ${res.status}: ${text.slice(0, 200)}`);\n }\n return (await res.json()) as GqlResult<T>;\n}\n\nconst REVOKE_SECRET_API_TOKEN = `\n mutation RevokeSecretApiToken($id: ID!) {\n revokeSecretApiToken(id: $id)\n }\n`;\n\nexport type MintSurfaceTokenInput = {\n /** App GRAPHQL_URL (e.g. device-rewritten). Defaults to env GRAPHQL_URL. */\n graphqlUrl?: string;\n orgName?: string | null;\n projectId?: string | null;\n tagId?: string | null;\n /**\n * Resolve org/project/env on `graphqlUrl` instead of using the mobile\n * app's local ids. Required when minting against a different cluster\n * than GRAPHQL_URL (canvas index lives on yantra-app-v1).\n */\n discoverScope?: boolean;\n /** Revoke the existing system-token row before obtain/create (dead HS256 signature). */\n forceRemint?: boolean;\n};\n\nexport type MintSurfaceTokenResult = {\n token: string;\n /** Exact backend URL string to stamp into cdecli_token_meta. */\n backend: string;\n};\n\n/**\n * Reveal (or obtain) a system token on GRAPHQL_URL.\n */\n/** Local-dev testing project — must never mint against this on staging/prod. */\nconst DEV_TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nconst OBJECT_ID_HEX = /^[a-fA-F0-9]{24}$/;\nconst PROJECT_UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\nasync function discoverMintScope(\n graphqlUrl: string,\n idToken: string,\n): Promise<{ orgName: string; projectId: string; environmentTagId: string }> {\n const orgs = await gqlFetch<{ getUserOrganizations?: Array<{ name?: string | null } | null> | null }>(\n graphqlUrl,\n idToken,\n GET_USER_ORGANIZATIONS,\n );\n if (orgs.errors?.length) {\n throw new Error(orgs.errors[0]?.message || 'getUserOrganizations failed');\n }\n const orgName = orgs.data?.getUserOrganizations?.find((o) => o?.name?.trim())?.name?.trim() || '';\n if (!orgName) {\n throw new Error(\n 'No organization on the canvas backend. Sign in once in the canvas harness (Chrome on localhost:5175), then retry from the app.',\n );\n }\n\n const projects = await gqlFetch<{ getProjects?: { data?: Array<{ id?: string | null } | null> | null } | null }>(\n graphqlUrl,\n idToken,\n GET_PROJECTS,\n { orgName },\n );\n if (projects.errors?.length) {\n throw new Error(projects.errors[0]?.message || 'getProjects failed');\n }\n const projectId = projects.data?.getProjects?.data?.find((p) => p?.id?.trim())?.id?.trim() || '';\n if (!projectId) {\n throw new Error(`No project on the canvas backend for org \"${orgName}\".`);\n }\n\n const tags = await gqlFetch<{ getEnvironmentTags?: Array<{ id?: string | null } | null> | null }>(\n graphqlUrl,\n idToken,\n GET_ENVIRONMENT_TAGS,\n { projectId },\n );\n if (tags.errors?.length) {\n throw new Error(tags.errors[0]?.message || 'getEnvironmentTags failed');\n }\n const environmentTagId = tags.data?.getEnvironmentTags?.find((t) => t?.id?.trim())?.id?.trim() || '';\n if (!environmentTagId) {\n throw new Error(`No environment tag on the canvas backend for project \"${projectId}\".`);\n }\n\n return { orgName, projectId, environmentTagId };\n}\n\nfunction assertMintableProjectId(projectId: string): void {\n if (projectId === 'default' || !projectId.trim()) {\n throw new Error('Missing projectId — wait for org/project bootstrap, then retry.');\n }\n if (!__DEV__ && projectId === DEV_TESTING_PROJECT_UUID) {\n throw new Error(\n 'Invalid projectId (dev testing UUID). Open Home so a real project can be created, then retry.',\n );\n }\n if (!OBJECT_ID_HEX.test(projectId) && !PROJECT_UUID.test(projectId)) {\n throw new Error(`Invalid projectId format for system token mint: ${projectId.slice(0, 48)}`);\n }\n}\n\nexport async function mintSurfaceSystemToken(input: MintSurfaceTokenInput): Promise<MintSurfaceTokenResult> {\n const idToken = await readAuth0IdToken();\n if (!idToken) {\n throw new Error('No Auth0 id_token in storage — sign in to the mobile app first.');\n }\n\n const graphqlUrl = resolveSurfaceCatalogBackend(input.graphqlUrl);\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minting system token via', graphqlUrl, input.discoverScope ? '(discover scope)' : '');\n }\n\n let orgName = input.orgName?.trim() || '';\n let projectId = input.projectId?.trim() || '';\n let environmentTagId = input.tagId?.trim() || '';\n\n if (input.discoverScope) {\n const scope = await discoverMintScope(graphqlUrl, idToken);\n orgName = scope.orgName;\n projectId = scope.projectId;\n environmentTagId = scope.environmentTagId;\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] discovered canvas scope', { orgName, projectId, environmentTagId });\n }\n }\n\n if (!orgName) {\n throw new Error('Missing orgName — wait for org bootstrap, then retry.');\n }\n if (!projectId) {\n throw new Error('Missing projectId — wait for org/project bootstrap, then retry.');\n }\n if (!environmentTagId) {\n throw new Error('Missing environmentTagId — cannot mint system token.');\n }\n assertMintableProjectId(projectId);\n\n if (input.forceRemint) {\n const existing = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n const existingId = existing.data?.getUserSystemToken?.id ?? null;\n if (existingId) {\n await gqlFetch(graphqlUrl, idToken, REVOKE_SECRET_API_TOKEN, { id: existingId }).catch(() => undefined);\n }\n }\n\n // Canonical get-or-create (resolves project UUID → Mongo id server-side).\n try {\n const obtained = await gqlFetch<{ obtainUserSystemToken?: { token?: string } | null }>(\n graphqlUrl,\n idToken,\n OBTAIN_USER_SYSTEM_TOKEN,\n {\n input: {\n projectId,\n environmentTagId,\n orgName,\n renewBufferSeconds: 7 * 24 * 60 * 60,\n algorithm: 'HS256',\n },\n },\n );\n const token = obtained.data?.obtainUserSystemToken?.token?.trim();\n if (token && !obtained.errors?.length) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] obtained system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n }\n if (obtained.errors?.length) {\n throw new Error(obtained.errors[0]?.message || 'obtainUserSystemToken failed');\n }\n } catch (err) {\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.warn('[WebBuilder] obtainUserSystemToken failed, falling back to reveal:', err);\n }\n // Fall through to get/create/reveal only when obtain is unavailable.\n const msg = err instanceof Error ? err.message : String(err);\n if (/12 bytes|24 hex|Project not found/i.test(msg)) {\n throw new Error(\n `Project \"${projectId}\" is not valid on this backend. Pick/create a real project in the app, then retry.`,\n );\n }\n // Continue to legacy path for older backends without obtainUserSystemToken.\n if (!/Unknown field|Cannot query field|obtainUserSystemToken/i.test(msg)) {\n // Non-schema errors from obtain should surface (auth, project, etc.).\n if (/Unauthorized|401|Project not found|Invalid project/i.test(msg)) {\n throw err instanceof Error ? err : new Error(msg);\n }\n }\n }\n\n const getResult = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n if (getResult.errors?.length) {\n throw new Error(getResult.errors[0]?.message || 'GetUserSystemToken failed');\n }\n\n let tokenId = getResult.data?.getUserSystemToken?.id ?? null;\n\n if (!tokenId) {\n const createResult = await gqlFetch<{ createSecretApiToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n CREATE_SECRET_API_TOKEN,\n {\n input: {\n name: 'System Token',\n expiryInSeconds: 31536000,\n isSystemToken: true,\n environmentTagId,\n orgName,\n projectId,\n algorithm: 'HS256',\n },\n },\n );\n\n const createErr = createResult.errors?.[0]?.message || '';\n if (createErr && !/already have a system token/i.test(createErr)) {\n if (/12 bytes|24 hex/i.test(createErr)) {\n throw new Error(\n `Project \"${projectId}\" is not valid on this backend. Pick/create a real project in the app, then retry.`,\n );\n }\n throw new Error(createErr);\n }\n\n if (createResult.data?.createSecretApiToken?.id) {\n tokenId = createResult.data.createSecretApiToken.id;\n } else {\n const refetch = await gqlFetch<{ getUserSystemToken?: { id?: string } | null }>(\n graphqlUrl,\n idToken,\n GET_USER_SYSTEM_TOKEN,\n );\n tokenId = refetch.data?.getUserSystemToken?.id ?? null;\n }\n }\n\n if (!tokenId) {\n throw new Error('No system token id on GraphQL backend — cannot reveal.');\n }\n\n const reveal = await gqlFetch<{ revealSecretApiToken?: string | null }>(\n graphqlUrl,\n idToken,\n REVEAL_SECRET_API_TOKEN,\n { id: tokenId },\n );\n if (reveal.errors?.length) {\n throw new Error(reveal.errors[0]?.message || 'RevealSecretApiToken failed');\n }\n\n const token = reveal.data?.revealSecretApiToken?.trim();\n if (!token) {\n throw new Error('RevealSecretApiToken returned empty token');\n }\n\n if (__DEV__) {\n // eslint-disable-next-line no-console\n console.log('[WebBuilder] minted system token length=', token.length);\n }\n return { token, backend: graphqlUrl };\n}\n\nexport function appendSurfaceAuthParams(baseUrl: string, token: string, state: string): string {\n try {\n const url = new URL(baseUrl);\n url.searchParams.set('token', token);\n url.searchParams.set('code', token);\n url.searchParams.set('state', state);\n return url.toString();\n } catch {\n const sep = baseUrl.includes('?') ? '&' : '?';\n return `${baseUrl}${sep}token=${encodeURIComponent(token)}&code=${encodeURIComponent(token)}&state=${encodeURIComponent(state)}`;\n }\n}\n\nfunction tokenFingerprint(token: string): string {\n const sig = token.split('.')[2] ?? token;\n return sig.slice(-24);\n}\n\n/** Shared WebView boot script: token + meta + fetch shims for surface-kit auth. */\nfunction buildSurfaceHandoffScript(token: string, backend: string, state: string, withGateRecovery: boolean): string {\n const safeToken = JSON.stringify(token);\n const safeBackend = JSON.stringify(backend);\n const safeState = JSON.stringify(state);\n const fp = JSON.stringify(tokenFingerprint(token));\n const recovery = withGateRecovery\n ? `\n function tryRecover() {\n stamp();\n var gate = document.querySelector('[data-surface-login]');\n if (!gate) return;\n if (sessionStorage.getItem('__yantra_wb_token_reload')) return;\n sessionStorage.setItem('__yantra_wb_token_reload', '1');\n var u = new URL(window.location.href);\n u.searchParams.set('token', t);\n u.searchParams.set('code', t);\n u.searchParams.set('state', state);\n window.location.replace(u.toString());\n }\n tryRecover();\n var i = 0;\n var timer = setInterval(function () {\n i += 1;\n tryRecover();\n if (i >= 40 || !document.querySelector('[data-surface-login]')) clearInterval(timer);\n }, 250);\n`\n : `\n var n = 0;\n var id = setInterval(function () {\n stamp();\n n += 1;\n if (n >= 80) clearInterval(id);\n }, 50);\n`;\n\n return `\n(function () {\n try {\n var t = ${safeToken};\n var backend = ${safeBackend};\n var state = ${safeState};\n var fp = ${fp};\n var PROBE_Q = 'query { getUserAccount { id } }';\n\n if (!window.__yantraWbFetchPatched) {\n window.__yantraWbFetchPatched = true;\n var origFetch = window.fetch.bind(window);\n window.fetch = function (input, init) {\n try {\n var url = typeof input === 'string' ? input : (input && input.url) ? String(input.url) : '';\n // Force surface-kit resolveCatalogBackend() to our GRAPHQL_URL (not remote agent → ideback).\n if (url.indexOf('/v1/auth/context') !== -1) {\n return Promise.resolve(new Response(\n JSON.stringify({ backendGraphqlUrl: backend }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n var body = init && typeof init.body === 'string' ? init.body : '';\n if (body && body.indexOf('getUserAccount') !== -1) {\n var parsed = JSON.parse(body);\n var q = parsed && typeof parsed.query === 'string' ? parsed.query.replace(/\\\\s+/g, ' ').trim() : '';\n if (q === PROBE_Q) {\n return Promise.resolve(new Response(\n JSON.stringify({ data: { getUserAccount: { id: 'mobile-webview-handoff' } } }),\n { status: 200, headers: { 'Content-Type': 'application/json' } }\n ));\n }\n }\n } catch (e0) {}\n return origFetch(input, init);\n };\n }\n\n function stamp() {\n try {\n sessionStorage.setItem('cdecli_oauth_state', state);\n localStorage.setItem('cdecli_token', t);\n sessionStorage.setItem('cdecli_token', t);\n localStorage.setItem('cdecli_system_token', t);\n localStorage.setItem('cdecli_token_meta', JSON.stringify({\n backend: backend,\n verifiedAt: Date.now(),\n fp: fp\n }));\n } catch (e1) {}\n }\n stamp();\n ${recovery}\n } catch (e) {}\n true;\n})();\ntrue;\n`;\n}\n\nexport function buildCdecliTokenInjection(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, false);\n}\n\nexport function buildSurfaceGateRecoveryScript(token: string, backend: string, state: string): string {\n return buildSurfaceHandoffScript(token, backend, state, true);\n}\n"],"names":["_a","token"],"mappings":"uPAGA,MAAM,wBAA2B,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAOjC,MAAM,qBAAwB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAS9B,MAAM,sBAAyB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAO/B,MAAM,YAAe,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AASrB,MAAM,oBAAuB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAO7B,MAAM,uBAA0B,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAQhC,MAAM,uBAA0B,GAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAWhC,SAAS,oBAAoB,GAAqB,EAAA;AAChD,EAAA,OAAO,GAAI,CAAA,IAAA,EAAO,CAAA,OAAA,CAAQ,OAAO,EAAE,CAAA;AACrC;AAGO,SAAS,6BAA6B,UAA6B,EAAA;AACxE,EAAM,MAAA,GAAA,GAAA,CAAM,UAAY,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAA,IAAA,EAAA,KAAU,MAAO,CAAA,WAAA;AACzC,EAAI,IAAA,EAAC,2BAAK,IAAQ,EAAA,CAAA,EAAA;AAChB,IAAM,MAAA,IAAI,MAAM,+BAA+B,CAAA;AAAA;AAEjD,EAAA,OAAO,oBAAoB,GAAG,CAAA;AAChC;AAGA,eAAe,QAAY,CAAA,UAAA,EAAoB,OAAiB,EAAA,KAAA,EAAe,SAA4D,EAAA;AAIzI,EAAM,MAAA,GAAA,GAAM,MAAM,KAAA,CAAM,UAAY,EAAA;AAAA,IAClC,MAAQ,EAAA,MAAA;AAAA,IACR,OAAS,EAAA;AAAA,MACP,CAAC,WAAY,CAAA,YAAY,GAAG,kBAAA;AAAA,MAC5B,CAAC,WAAA,CAAY,aAAa,GAAG,UAAU,OAAO,CAAA,CAAA;AAAA,MAC9C,CAAC,WAAY,CAAA,SAAS,GAAG,MAAA;AAAA,MACzB,CAAC,WAAA,CAAY,aAAa,GAAG,YAAa,CAAA;AAAA,KAC5C;AAAA,IACA,IAAA,EAAM,KAAK,SAAU,CAAA;AAAA,MACnB,KAAA;AAAA,MACA;AAAA,KACD;AAAA,GACF,CAAA;AACD,EAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACX,IAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAO,CAAA,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,IAAM,MAAA,IAAI,KAAM,CAAA,CAAA,aAAA,EAAgB,GAAI,CAAA,MAAM,CAAK,EAAA,EAAA,IAAA,CAAK,KAAM,CAAA,CAAA,EAAG,GAAG,CAAC,CAAE,CAAA,CAAA;AAAA;AAErE,EAAQ,OAAA,MAAM,IAAI,IAAK,EAAA;AACzB;AACA,MAAM,uBAA0B,GAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA8BhC,MAAM,wBAA2B,GAAA,sCAAA;AACjC,MAAM,aAAgB,GAAA,mBAAA;AACtB,MAAM,YAAe,GAAA,+EAAA;AACrB,eAAe,iBAAA,CAAkB,YAAoB,OAIlD,EAAA;AAvIH,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAwIE,EAAA,MAAM,IAAO,GAAA,MAAM,QAIhB,CAAA,UAAA,EAAY,SAAS,sBAAsB,CAAA;AAC9C,EAAI,IAAA,CAAA,EAAA,GAAA,IAAA,CAAK,MAAL,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAa,MAAQ,EAAA;AACvB,IAAM,MAAA,IAAI,QAAM,EAAK,GAAA,IAAA,CAAA,MAAA,CAAO,CAAC,CAAb,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAgB,YAAW,6BAA6B,CAAA;AAAA;AAE1E,EAAA,MAAM,YAAU,EAAK,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAA,IAAA,KAAL,mBAAW,oBAAX,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiC,KAAK,CAAE,CAAA,KAAA;AAhJ1D,IAAAA,IAAAA,GAAAA;AAgJ6D,IAAA,OAAA,CAAAA,GAAA,GAAA,CAAA,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAG,IAAH,KAAA,IAAA,GAAA,MAAA,GAAAA,GAAS,CAAA,IAAA,EAAA;AAAA,GAApD,CAAA,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA6D,IAA7D,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAmE,IAAU,EAAA,KAAA,EAAA;AAC7F,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,gIAAgI,CAAA;AAAA;AAElJ,EAAA,MAAM,QAAW,GAAA,MAAM,QAMpB,CAAA,UAAA,EAAY,SAAS,YAAc,EAAA;AAAA,IACpC;AAAA,GACD,CAAA;AACD,EAAI,IAAA,CAAA,EAAA,GAAA,QAAA,CAAS,MAAT,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiB,MAAQ,EAAA;AAC3B,IAAM,MAAA,IAAI,QAAM,EAAS,GAAA,QAAA,CAAA,MAAA,CAAO,CAAC,CAAjB,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,YAAW,oBAAoB,CAAA;AAAA;AAErE,EAAM,MAAA,SAAA,GAAA,CAAA,CAAY,sCAAS,IAAT,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,gBAAf,IAA4B,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,KAA5B,IAAkC,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAK,CAAE,CAAA,KAAA;AAhK7D,IAAAA,IAAAA,GAAAA;AAgKgE,IAAA,OAAA,CAAAA,GAAA,GAAA,CAAA,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAG,EAAH,KAAA,IAAA,GAAA,MAAA,GAAAA,GAAO,CAAA,IAAA,EAAA;AAAA,GAAnD,CAAA,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA4D,EAA5D,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAgE,IAAU,EAAA,KAAA,EAAA;AAC5F,EAAA,IAAI,CAAC,SAAW,EAAA;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAA6C,0CAAA,EAAA,OAAO,CAAI,EAAA,CAAA,CAAA;AAAA;AAE1E,EAAA,MAAM,IAAO,GAAA,MAAM,QAIhB,CAAA,UAAA,EAAY,SAAS,oBAAsB,EAAA;AAAA,IAC5C;AAAA,GACD,CAAA;AACD,EAAI,IAAA,CAAA,EAAA,GAAA,IAAA,CAAK,MAAL,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAa,MAAQ,EAAA;AACvB,IAAM,MAAA,IAAI,QAAM,EAAK,GAAA,IAAA,CAAA,MAAA,CAAO,CAAC,CAAb,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAgB,YAAW,2BAA2B,CAAA;AAAA;AAExE,EAAA,MAAM,qBAAmB,EAAK,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAA,IAAA,KAAL,mBAAW,kBAAX,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA+B,KAAK,CAAE,CAAA,KAAA;AA9KjE,IAAAA,IAAAA,GAAAA;AA8KoE,IAAA,OAAA,CAAAA,GAAA,GAAA,CAAA,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAG,EAAH,KAAA,IAAA,GAAA,MAAA,GAAAA,GAAO,CAAA,IAAA,EAAA;AAAA,GAAhD,CAAA,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAyD,EAAzD,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAA6D,IAAU,EAAA,KAAA,EAAA;AAChG,EAAA,IAAI,CAAC,gBAAkB,EAAA;AACrB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAyD,sDAAA,EAAA,SAAS,CAAI,EAAA,CAAA,CAAA;AAAA;AAExF,EAAO,OAAA;AAAA,IACL,OAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AACA,SAAS,wBAAwB,SAAyB,EAAA;AACxD,EAAA,IAAI,SAAc,KAAA,SAAA,IAAa,CAAC,SAAA,CAAU,MAAQ,EAAA;AAChD,IAAM,MAAA,IAAI,MAAM,sEAAiE,CAAA;AAAA;AAEnF,EAAI,IAAA,CAAC,OAAW,IAAA,SAAA,KAAc,wBAA0B,EAAA;AACtD,IAAM,MAAA,IAAI,MAAM,+FAA+F,CAAA;AAAA;AAEjH,EAAI,IAAA,CAAC,cAAc,IAAK,CAAA,SAAS,KAAK,CAAC,YAAA,CAAa,IAAK,CAAA,SAAS,CAAG,EAAA;AACnE,IAAM,MAAA,IAAI,MAAM,CAAmD,gDAAA,EAAA,SAAA,CAAU,MAAM,CAAG,EAAA,EAAE,CAAC,CAAE,CAAA,CAAA;AAAA;AAE/F;AACA,eAAsB,uBAAuB,KAA+D,EAAA;AAnM5G,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAoME,EAAM,MAAA,OAAA,GAAU,MAAM,gBAAiB,EAAA;AACvC,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,sEAAiE,CAAA;AAAA;AAEnF,EAAM,MAAA,UAAA,GAAa,4BAA6B,CAAA,KAAA,CAAM,UAAU,CAAA;AAChE,EAAA,IAAI,OAAS,EAAA;AAEX,IAAA,OAAA,CAAQ,IAAI,uCAAyC,EAAA,UAAA,EAAY,KAAM,CAAA,aAAA,GAAgB,qBAAqB,EAAE,CAAA;AAAA;AAEhH,EAAA,IAAI,OAAU,GAAA,CAAA,CAAA,EAAA,GAAA,KAAA,CAAM,OAAN,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,IAAU,EAAA,KAAA,EAAA;AACvC,EAAA,IAAI,SAAY,GAAA,CAAA,CAAA,EAAA,GAAA,KAAA,CAAM,SAAN,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiB,IAAU,EAAA,KAAA,EAAA;AAC3C,EAAA,IAAI,gBAAmB,GAAA,CAAA,CAAA,EAAA,GAAA,KAAA,CAAM,KAAN,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAa,IAAU,EAAA,KAAA,EAAA;AAC9C,EAAA,IAAI,MAAM,aAAe,EAAA;AACvB,IAAA,MAAM,KAAQ,GAAA,MAAM,iBAAkB,CAAA,UAAA,EAAY,OAAO,CAAA;AACzD,IAAA,OAAA,GAAU,KAAM,CAAA,OAAA;AAChB,IAAA,SAAA,GAAY,KAAM,CAAA,SAAA;AAClB,IAAA,gBAAA,GAAmB,KAAM,CAAA,gBAAA;AACzB,IAAA,IAAI,OAAS,EAAA;AAEX,MAAA,OAAA,CAAQ,IAAI,sCAAwC,EAAA;AAAA,QAClD,OAAA;AAAA,QACA,SAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA;AACH;AAEF,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,4DAAuD,CAAA;AAAA;AAEzE,EAAA,IAAI,CAAC,SAAW,EAAA;AACd,IAAM,MAAA,IAAI,MAAM,sEAAiE,CAAA;AAAA;AAEnF,EAAA,IAAI,CAAC,gBAAkB,EAAA;AACrB,IAAM,MAAA,IAAI,MAAM,2DAAsD,CAAA;AAAA;AAExE,EAAA,uBAAA,CAAwB,SAAS,CAAA;AACjC,EAAA,IAAI,MAAM,WAAa,EAAA;AACrB,IAAA,MAAM,QAAW,GAAA,MAAM,QAIpB,CAAA,UAAA,EAAY,SAAS,qBAAqB,CAAA;AAC7C,IAAA,MAAM,cAAa,EAAS,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,QAAA,CAAA,IAAA,KAAT,mBAAe,kBAAf,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAmC,OAAnC,IAAyC,GAAA,EAAA,GAAA,IAAA;AAC5D,IAAA,IAAI,UAAY,EAAA;AACd,MAAM,MAAA,QAAA,CAAS,UAAY,EAAA,OAAA,EAAS,uBAAyB,EAAA;AAAA,QAC3D,EAAI,EAAA;AAAA,OACL,CAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAAA;AAC1B;AAIF,EAAI,IAAA;AACF,IAAA,MAAM,QAAW,GAAA,MAAM,QAIpB,CAAA,UAAA,EAAY,SAAS,wBAA0B,EAAA;AAAA,MAChD,KAAO,EAAA;AAAA,QACL,SAAA;AAAA,QACA,gBAAA;AAAA,QACA,OAAA;AAAA,QACA,kBAAA,EAAoB,CAAI,GAAA,EAAA,GAAK,EAAK,GAAA,EAAA;AAAA,QAClC,SAAW,EAAA;AAAA;AACb,KACD,CAAA;AACD,IAAA,MAAMC,UAAQ,EAAS,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,QAAA,CAAA,IAAA,KAAT,mBAAe,qBAAf,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAsC,UAAtC,IAA6C,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,EAAA;AAC3D,IAAA,IAAIA,MAAS,IAAA,EAAA,CAAC,EAAS,GAAA,QAAA,CAAA,MAAA,KAAT,mBAAiB,MAAQ,CAAA,EAAA;AACrC,MAAA,IAAI,OAAS,EAAA;AAEX,QAAQ,OAAA,CAAA,GAAA,CAAI,4CAA8CA,EAAAA,MAAAA,CAAM,MAAM,CAAA;AAAA;AAExE,MAAO,OAAA;AAAA,QACL,KAAAA,EAAAA,MAAAA;AAAA,QACA,OAAS,EAAA;AAAA,OACX;AAAA;AAEF,IAAI,IAAA,CAAA,EAAA,GAAA,QAAA,CAAS,MAAT,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAiB,MAAQ,EAAA;AAC3B,MAAM,MAAA,IAAI,QAAM,EAAS,GAAA,QAAA,CAAA,MAAA,CAAO,CAAC,CAAjB,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAoB,YAAW,8BAA8B,CAAA;AAAA;AAC/E,WACO,GAAK,EAAA;AACZ,IAAA,IAAI,OAAS,EAAA;AAEX,MAAQ,OAAA,CAAA,IAAA,CAAK,sEAAsE,GAAG,CAAA;AAAA;AAGxF,IAAA,MAAM,MAAM,GAAe,YAAA,KAAA,GAAQ,GAAI,CAAA,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,IAAI,IAAA,oCAAA,CAAqC,IAAK,CAAA,GAAG,CAAG,EAAA;AAClD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAY,SAAA,EAAA,SAAS,CAAoF,kFAAA,CAAA,CAAA;AAAA;AAG3H,IAAA,IAAI,CAAC,yDAAA,CAA0D,IAAK,CAAA,GAAG,CAAG,EAAA;AAExE,MAAI,IAAA,qDAAA,CAAsD,IAAK,CAAA,GAAG,CAAG,EAAA;AACnE,QAAA,MAAM,GAAe,YAAA,KAAA,GAAQ,GAAM,GAAA,IAAI,MAAM,GAAG,CAAA;AAAA;AAClD;AACF;AAEF,EAAA,MAAM,SAAY,GAAA,MAAM,QAIrB,CAAA,UAAA,EAAY,SAAS,qBAAqB,CAAA;AAC7C,EAAI,IAAA,CAAA,EAAA,GAAA,SAAA,CAAU,MAAV,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAkB,MAAQ,EAAA;AAC5B,IAAM,MAAA,IAAI,QAAM,EAAU,GAAA,SAAA,CAAA,MAAA,CAAO,CAAC,CAAlB,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAqB,YAAW,2BAA2B,CAAA;AAAA;AAE7E,EAAA,IAAI,WAAU,EAAU,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,SAAA,CAAA,IAAA,KAAV,mBAAgB,kBAAhB,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoC,OAApC,IAA0C,GAAA,EAAA,GAAA,IAAA;AACxD,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAA,MAAM,YAAe,GAAA,MAAM,QAIxB,CAAA,UAAA,EAAY,SAAS,uBAAyB,EAAA;AAAA,MAC/C,KAAO,EAAA;AAAA,QACL,IAAM,EAAA,cAAA;AAAA,QACN,eAAiB,EAAA,OAAA;AAAA,QACjB,aAAe,EAAA,IAAA;AAAA,QACf,gBAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA;AAAA,QACA,SAAW,EAAA;AAAA;AACb,KACD,CAAA;AACD,IAAA,MAAM,cAAY,EAAa,GAAA,CAAA,EAAA,GAAA,YAAA,CAAA,MAAA,KAAb,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,CAAA,CAAA,KAAtB,mBAA0B,OAAW,KAAA,EAAA;AACvD,IAAA,IAAI,SAAa,IAAA,CAAC,8BAA+B,CAAA,IAAA,CAAK,SAAS,CAAG,EAAA;AAChE,MAAI,IAAA,kBAAA,CAAmB,IAAK,CAAA,SAAS,CAAG,EAAA;AACtC,QAAA,MAAM,IAAI,KAAA,CAAM,CAAY,SAAA,EAAA,SAAS,CAAoF,kFAAA,CAAA,CAAA;AAAA;AAE3H,MAAM,MAAA,IAAI,MAAM,SAAS,CAAA;AAAA;AAE3B,IAAA,IAAA,CAAI,EAAa,GAAA,CAAA,EAAA,GAAA,YAAA,CAAA,IAAA,KAAb,IAAmB,GAAA,MAAA,GAAA,EAAA,CAAA,oBAAA,KAAnB,mBAAyC,EAAI,EAAA;AAC/C,MAAU,OAAA,GAAA,YAAA,CAAa,KAAK,oBAAqB,CAAA,EAAA;AAAA,KAC5C,MAAA;AACL,MAAA,MAAM,OAAU,GAAA,MAAM,QAInB,CAAA,UAAA,EAAY,SAAS,qBAAqB,CAAA;AAC7C,MAAA,OAAA,GAAA,CAAU,yBAAQ,IAAR,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAc,kBAAd,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAkC,OAAlC,IAAwC,GAAA,EAAA,GAAA,IAAA;AAAA;AACpD;AAEF,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAM,MAAA,IAAI,MAAM,6DAAwD,CAAA;AAAA;AAE1E,EAAA,MAAM,MAAS,GAAA,MAAM,QAElB,CAAA,UAAA,EAAY,SAAS,uBAAyB,EAAA;AAAA,IAC/C,EAAI,EAAA;AAAA,GACL,CAAA;AACD,EAAI,IAAA,CAAA,EAAA,GAAA,MAAA,CAAO,MAAP,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,MAAQ,EAAA;AACzB,IAAM,MAAA,IAAI,QAAM,EAAO,GAAA,MAAA,CAAA,MAAA,CAAO,CAAC,CAAf,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAkB,YAAW,6BAA6B,CAAA;AAAA;AAE5E,EAAA,MAAM,KAAQ,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,MAAA,CAAO,IAAP,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAa,yBAAb,IAAmC,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA;AACjD,EAAA,IAAI,CAAC,KAAO,EAAA;AACV,IAAM,MAAA,IAAI,MAAM,2CAA2C,CAAA;AAAA;AAE7D,EAAA,IAAI,OAAS,EAAA;AAEX,IAAQ,OAAA,CAAA,GAAA,CAAI,0CAA4C,EAAA,KAAA,CAAM,MAAM,CAAA;AAAA;AAEtE,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA,OAAS,EAAA;AAAA,GACX;AACF;AACgB,SAAA,uBAAA,CAAwB,OAAiB,EAAA,KAAA,EAAe,KAAuB,EAAA;AAC7F,EAAI,IAAA;AACF,IAAM,MAAA,GAAA,GAAM,IAAI,GAAA,CAAI,OAAO,CAAA;AAC3B,IAAI,GAAA,CAAA,YAAA,CAAa,GAAI,CAAA,OAAA,EAAS,KAAK,CAAA;AACnC,IAAI,GAAA,CAAA,YAAA,CAAa,GAAI,CAAA,MAAA,EAAQ,KAAK,CAAA;AAClC,IAAI,GAAA,CAAA,YAAA,CAAa,GAAI,CAAA,OAAA,EAAS,KAAK,CAAA;AACnC,IAAA,OAAO,IAAI,QAAS,EAAA;AAAA,GACd,CAAA,OAAA,CAAA,EAAA;AACN,IAAA,MAAM,GAAM,GAAA,OAAA,CAAQ,QAAS,CAAA,GAAG,IAAI,GAAM,GAAA,GAAA;AAC1C,IAAA,OAAO,CAAG,EAAA,OAAO,CAAG,EAAA,GAAG,SAAS,kBAAmB,CAAA,KAAK,CAAC,CAAA,MAAA,EAAS,mBAAmB,KAAK,CAAC,CAAU,OAAA,EAAA,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAAA;AAElI;AACA,SAAS,iBAAiB,KAAuB,EAAA;AApXjD,EAAA,IAAA,EAAA;AAqXE,EAAA,MAAM,OAAM,EAAM,GAAA,KAAA,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,CAAC,MAAlB,IAAuB,GAAA,EAAA,GAAA,KAAA;AACnC,EAAO,OAAA,GAAA,CAAI,MAAM,GAAG,CAAA;AACtB;AAGA,SAAS,yBAA0B,CAAA,KAAA,EAAe,OAAiB,EAAA,KAAA,EAAe,gBAAmC,EAAA;AACnH,EAAM,MAAA,SAAA,GAAY,IAAK,CAAA,SAAA,CAAU,KAAK,CAAA;AACtC,EAAM,MAAA,WAAA,GAAc,IAAK,CAAA,SAAA,CAAU,OAAO,CAAA;AAC1C,EAAM,MAAA,SAAA,GAAY,IAAK,CAAA,SAAA,CAAU,KAAK,CAAA;AACtC,EAAA,MAAM,EAAK,GAAA,IAAA,CAAK,SAAU,CAAA,gBAAA,CAAiB,KAAK,CAAC,CAAA;AACjD,EAAA,MAAM,WAAW,gBAAmB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAoBlC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAQF,EAAO,OAAA;AAAA;AAAA;AAAA,YAAA,EAGK,SAAS,CAAA;AAAA,kBAAA,EACH,WAAW,CAAA;AAAA,gBAAA,EACb,SAAS,CAAA;AAAA,aAAA,EACZ,EAAE,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,EA8CX,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAMd;AACgB,SAAA,yBAAA,CAA0B,KAAe,EAAA,OAAA,EAAiB,KAAuB,EAAA;AAC/F,EAAA,OAAO,yBAA0B,CAAA,KAAA,EAAO,OAAS,EAAA,KAAA,EAAO,KAAK,CAAA;AAC/D;AACgB,SAAA,8BAAA,CAA+B,KAAe,EAAA,OAAA,EAAiB,KAAuB,EAAA;AACpG,EAAA,OAAO,yBAA0B,CAAA,KAAA,EAAO,OAAS,EAAA,KAAA,EAAO,IAAI,CAAA;AAC9D"}