@adminide-stack/yantra-mobile 12.0.69-alpha.9 โ†’ 12.0.70-alpha.0

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 (522) hide show
  1. package/lib/components/GatewayConnector/GatewayConnector.js +2 -2
  2. package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -1
  3. package/lib/components/KeyboardComposerDock.js +8 -1
  4. package/lib/components/KeyboardComposerDock.js.map +1 -1
  5. package/lib/components/NavigationHeader/NavigationHeader.js +2 -2
  6. package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
  7. package/lib/config/env-config.js +4 -0
  8. package/lib/config/env-config.js.map +1 -1
  9. package/lib/contexts/ChatLiveStreamContext.js +4 -1
  10. package/lib/contexts/ChatLiveStreamContext.js.map +1 -1
  11. package/lib/features/agent-chat/NativeAgentChat.js +2 -0
  12. package/lib/features/agent-chat/NativeAgentChat.js.map +1 -1
  13. package/lib/features/apps/AppsCatalog.js +2 -2
  14. package/lib/features/apps/AppsCatalog.js.map +1 -1
  15. package/lib/features/audio-input/MicErrorBoundary.js +2 -2
  16. package/lib/features/audio-input/MicErrorBoundary.js.map +1 -1
  17. package/lib/features/canvas/AudioEditorExperience.js +308 -0
  18. package/lib/features/canvas/AudioEditorExperience.js.map +1 -0
  19. package/lib/features/canvas/CanvasAgentChatPane.js +310 -0
  20. package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -0
  21. package/lib/features/canvas/CanvasBoardsGrid.js +414 -0
  22. package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -0
  23. package/lib/features/canvas/CanvasChatResultCard.js +113 -0
  24. package/lib/features/canvas/CanvasChatResultCard.js.map +1 -0
  25. package/lib/features/canvas/CanvasEditToolsPanel.js +179 -0
  26. package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -0
  27. package/lib/features/canvas/CanvasExperience.js +859 -0
  28. package/lib/features/canvas/CanvasExperience.js.map +1 -0
  29. package/lib/features/canvas/CanvasGeneratePanel.js +514 -0
  30. package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -0
  31. package/lib/features/canvas/CanvasLibrarySheet.js +355 -0
  32. package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -0
  33. package/lib/features/canvas/CanvasLooksPanel.js +184 -0
  34. package/lib/features/canvas/CanvasLooksPanel.js.map +1 -0
  35. package/lib/features/canvas/CanvasTasksPanel.js +138 -0
  36. package/lib/features/canvas/CanvasTasksPanel.js.map +1 -0
  37. package/lib/features/canvas/CanvasTemplatesPanel.js +226 -0
  38. package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -0
  39. package/lib/features/canvas/CanvasToolDock.js +423 -0
  40. package/lib/features/canvas/CanvasToolDock.js.map +1 -0
  41. package/lib/features/canvas/FrameExtractorExperience.js +242 -0
  42. package/lib/features/canvas/FrameExtractorExperience.js.map +1 -0
  43. package/lib/features/canvas/ImageEditorExperience.js +491 -0
  44. package/lib/features/canvas/ImageEditorExperience.js.map +1 -0
  45. package/lib/features/canvas/InfluencerStudioExperience.js +288 -0
  46. package/lib/features/canvas/InfluencerStudioExperience.js.map +1 -0
  47. package/lib/features/canvas/MoodboardExperience.js +205 -0
  48. package/lib/features/canvas/MoodboardExperience.js.map +1 -0
  49. package/lib/features/canvas/NativeCanvasViewer.js +929 -0
  50. package/lib/features/canvas/NativeCanvasViewer.js.map +1 -0
  51. package/lib/features/canvas/PromoContextFields.js +150 -0
  52. package/lib/features/canvas/PromoContextFields.js.map +1 -0
  53. package/lib/features/canvas/SetStudioExperience.js +323 -0
  54. package/lib/features/canvas/SetStudioExperience.js.map +1 -0
  55. package/lib/features/canvas/VideoClipsExperience.js +175 -0
  56. package/lib/features/canvas/VideoClipsExperience.js.map +1 -0
  57. package/lib/features/canvas/VideoEditExperience.js +824 -0
  58. package/lib/features/canvas/VideoEditExperience.js.map +1 -0
  59. package/lib/features/canvas/VideoEditorExperience.js +3050 -0
  60. package/lib/features/canvas/VideoEditorExperience.js.map +1 -0
  61. package/lib/features/canvas/VideoGeneratorExperience.js +415 -0
  62. package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -0
  63. package/lib/features/canvas/aiEdit.js +53 -0
  64. package/lib/features/canvas/aiEdit.js.map +1 -0
  65. package/lib/features/canvas/canvasAgentChat.js +76 -0
  66. package/lib/features/canvas/canvasAgentChat.js.map +1 -0
  67. package/lib/features/canvas/canvasBoardsCatalog.js +59 -0
  68. package/lib/features/canvas/canvasBoardsCatalog.js.map +1 -0
  69. package/lib/features/canvas/canvasBoardsSnapshot.js +14 -1
  70. package/lib/features/canvas/canvasBoardsSnapshot.js.map +1 -1
  71. package/lib/features/canvas/canvasChatDisplay.js +38 -0
  72. package/lib/features/canvas/canvasChatDisplay.js.map +1 -0
  73. package/lib/features/canvas/canvasChatTemplates.js +219 -0
  74. package/lib/features/canvas/canvasChatTemplates.js.map +1 -0
  75. package/lib/features/canvas/canvasCore.js +138 -1
  76. package/lib/features/canvas/canvasCore.js.map +1 -1
  77. package/lib/features/canvas/canvasEditOps.js +224 -0
  78. package/lib/features/canvas/canvasEditOps.js.map +1 -0
  79. package/lib/features/canvas/canvasTasks.js +187 -0
  80. package/lib/features/canvas/canvasTasks.js.map +1 -0
  81. package/lib/features/canvas/designPromptTemplates.js +3084 -0
  82. package/lib/features/canvas/designPromptTemplates.js.map +1 -0
  83. package/lib/features/canvas/editTools.js +54 -0
  84. package/lib/features/canvas/editTools.js.map +1 -0
  85. package/lib/features/canvas/extendVideo.js +5 -0
  86. package/lib/features/canvas/extendVideo.js.map +1 -0
  87. package/lib/features/canvas/frameExtract.js +33 -0
  88. package/lib/features/canvas/frameExtract.js.map +1 -0
  89. package/lib/features/canvas/generationModels.js +201 -0
  90. package/lib/features/canvas/generationModels.js.map +1 -0
  91. package/lib/features/canvas/influencer/influencerPipeline.js +170 -0
  92. package/lib/features/canvas/influencer/influencerPipeline.js.map +1 -0
  93. package/lib/features/canvas/influencer/productReel.js +72 -0
  94. package/lib/features/canvas/influencer/productReel.js.map +1 -0
  95. package/lib/features/canvas/influencer/reelPlan.js +159 -0
  96. package/lib/features/canvas/influencer/reelPlan.js.map +1 -0
  97. package/lib/features/canvas/moodboardCore.js +13 -0
  98. package/lib/features/canvas/moodboardCore.js.map +1 -0
  99. package/lib/features/canvas/promoProjectImport.js +99 -0
  100. package/lib/features/canvas/promoProjectImport.js.map +1 -0
  101. package/lib/features/canvas/promoVideo.js +312 -0
  102. package/lib/features/canvas/promoVideo.js.map +1 -0
  103. package/lib/features/canvas/recorder/CameraRecorderExperience.js +109 -0
  104. package/lib/features/canvas/recorder/CameraRecorderExperience.js.map +1 -0
  105. package/lib/features/canvas/sessionIdentity.js +28 -1
  106. package/lib/features/canvas/sessionIdentity.js.map +1 -1
  107. package/lib/features/canvas/set/SetViewportWebView.js +133 -0
  108. package/lib/features/canvas/set/SetViewportWebView.js.map +1 -0
  109. package/lib/features/canvas/set/cameraPath.js +194 -0
  110. package/lib/features/canvas/set/cameraPath.js.map +1 -0
  111. package/lib/features/canvas/set/setProject.js +24 -0
  112. package/lib/features/canvas/set/setProject.js.map +1 -0
  113. package/lib/features/canvas/storageLibrary.js +184 -0
  114. package/lib/features/canvas/storageLibrary.js.map +1 -0
  115. package/lib/features/canvas/studioCatalog.js +129 -0
  116. package/lib/features/canvas/studioCatalog.js.map +1 -0
  117. package/lib/features/canvas/studioLooks.js +189 -0
  118. package/lib/features/canvas/studioLooks.js.map +1 -0
  119. package/lib/features/canvas/surfaceIndex.js +63 -1
  120. package/lib/features/canvas/surfaceIndex.js.map +1 -1
  121. package/lib/features/canvas/templateImport/invideoNative.js +221 -0
  122. package/lib/features/canvas/templateImport/invideoNative.js.map +1 -0
  123. package/lib/features/canvas/templateImport/loadTemplate.js +43 -0
  124. package/lib/features/canvas/templateImport/loadTemplate.js.map +1 -0
  125. package/lib/features/canvas/templateImport/renderConfig.js +93 -0
  126. package/lib/features/canvas/templateImport/renderConfig.js.map +1 -0
  127. package/lib/features/canvas/useStudioCatalogTemplates.js +134 -0
  128. package/lib/features/canvas/useStudioCatalogTemplates.js.map +1 -0
  129. package/lib/features/canvas/video3d.js +109 -0
  130. package/lib/features/canvas/video3d.js.map +1 -0
  131. package/lib/features/canvas/videoClips.js +42 -0
  132. package/lib/features/canvas/videoClips.js.map +1 -0
  133. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +120 -0
  134. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -0
  135. package/lib/features/canvas/videoEditor/agent/agentLoop.js +69 -0
  136. package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -0
  137. package/lib/features/canvas/videoEditor/agent/brainClient.js +45 -0
  138. package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -0
  139. package/lib/features/canvas/videoEditor/agent/cutTools.js +129 -0
  140. package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -0
  141. package/lib/features/canvas/videoEditor/editorModel.js +346 -0
  142. package/lib/features/canvas/videoEditor/editorModel.js.map +1 -0
  143. package/lib/features/canvas/videoEditor/exportRenderer.js +214 -0
  144. package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -0
  145. package/lib/features/canvas/videoEditor/filters.js +41 -0
  146. package/lib/features/canvas/videoEditor/filters.js.map +1 -0
  147. package/lib/features/canvas/videoEditor/mediaActions.js +57 -0
  148. package/lib/features/canvas/videoEditor/mediaActions.js.map +1 -0
  149. package/lib/features/canvas/videoEditor/remoteMediaClient.js +129 -0
  150. package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -0
  151. package/lib/features/canvas/videoEditor/solidColorPng.js +115 -0
  152. package/lib/features/canvas/videoEditor/solidColorPng.js.map +1 -0
  153. package/lib/features/canvas/videoEditor/videoEditOps.js +191 -0
  154. package/lib/features/canvas/videoEditor/videoEditOps.js.map +1 -0
  155. package/lib/features/canvas/videoEditor/videoProjectsStore.js +82 -0
  156. package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -0
  157. package/lib/features/canvas/videoRenderer.js +8 -0
  158. package/lib/features/canvas/videoRenderer.js.map +1 -0
  159. package/lib/features/canvas/withRemoteSafeArea.js +2 -2
  160. package/lib/features/canvas/withRemoteSafeArea.js.map +1 -1
  161. package/lib/features/characters/characterStudioProps.js +14 -0
  162. package/lib/features/characters/characterStudioProps.js.map +1 -0
  163. package/lib/features/chat/ChatCodeBlock.js +7 -3
  164. package/lib/features/chat/ChatCodeBlock.js.map +1 -1
  165. package/lib/features/chat/ChatTranscript.js +7 -3
  166. package/lib/features/chat/ChatTranscript.js.map +1 -1
  167. package/lib/features/chat/ChatWidgetCard.js +13 -0
  168. package/lib/features/chat/ChatWidgetCard.js.map +1 -0
  169. package/lib/features/chat/ConnectorConnectCard.js +166 -0
  170. package/lib/features/chat/ConnectorConnectCard.js.map +1 -0
  171. package/lib/features/chat/ConnectorConnectPrompt.js +272 -0
  172. package/lib/features/chat/ConnectorConnectPrompt.js.map +1 -0
  173. package/lib/features/chat/MessageActionBar.js.map +1 -1
  174. package/lib/features/chat/QueuedFollowUps.js +71 -0
  175. package/lib/features/chat/QueuedFollowUps.js.map +1 -0
  176. package/lib/features/chat/chatWidgets.js +37 -0
  177. package/lib/features/chat/chatWidgets.js.map +1 -0
  178. package/lib/features/chat/connectorConnect.js +207 -0
  179. package/lib/features/chat/connectorConnect.js.map +1 -0
  180. package/lib/features/chat/connectorConnectHandbacks.js +55 -0
  181. package/lib/features/chat/connectorConnectHandbacks.js.map +1 -0
  182. package/lib/features/design/DesignEditorExperience.js +643 -0
  183. package/lib/features/design/DesignEditorExperience.js.map +1 -0
  184. package/lib/features/design/DesignExperience.js +444 -0
  185. package/lib/features/design/DesignExperience.js.map +1 -0
  186. package/lib/features/design/designCore.js +298 -0
  187. package/lib/features/design/designCore.js.map +1 -0
  188. package/lib/features/design/designIndex.js +150 -0
  189. package/lib/features/design/designIndex.js.map +1 -0
  190. package/lib/features/design/exportDesign.js +133 -0
  191. package/lib/features/design/exportDesign.js.map +1 -0
  192. package/lib/features/job-search/ApplicationsPanel.js +907 -0
  193. package/lib/features/job-search/ApplicationsPanel.js.map +1 -0
  194. package/lib/features/job-search/ContactsPanel.js +627 -0
  195. package/lib/features/job-search/ContactsPanel.js.map +1 -0
  196. package/lib/features/job-search/InsightsPanel.js +299 -0
  197. package/lib/features/job-search/InsightsPanel.js.map +1 -0
  198. package/lib/features/job-search/InterviewPanel.js +637 -0
  199. package/lib/features/job-search/InterviewPanel.js.map +1 -0
  200. package/lib/features/job-search/JdPastePrompt.js +130 -0
  201. package/lib/features/job-search/JdPastePrompt.js.map +1 -0
  202. package/lib/features/job-search/JobCard.js +199 -0
  203. package/lib/features/job-search/JobCard.js.map +1 -0
  204. package/lib/features/job-search/JobDetailSheet.js +255 -0
  205. package/lib/features/job-search/JobDetailSheet.js.map +1 -0
  206. package/lib/features/job-search/JobSearchAgentChatPane.js +377 -0
  207. package/lib/features/job-search/JobSearchAgentChatPane.js.map +1 -0
  208. package/lib/features/job-search/JobSearchExperience.js +1324 -0
  209. package/lib/features/job-search/JobSearchExperience.js.map +1 -0
  210. package/lib/features/job-search/JobSearchLocationField.js +231 -0
  211. package/lib/features/job-search/JobSearchLocationField.js.map +1 -0
  212. package/lib/features/job-search/ProfilePanel.js +679 -0
  213. package/lib/features/job-search/ProfilePanel.js.map +1 -0
  214. package/lib/features/job-search/RepliesPanel.js +344 -0
  215. package/lib/features/job-search/RepliesPanel.js.map +1 -0
  216. package/lib/features/job-search/SavedPanel.js +297 -0
  217. package/lib/features/job-search/SavedPanel.js.map +1 -0
  218. package/lib/features/job-search/chat/widgetContent.js +29 -0
  219. package/lib/features/job-search/chat/widgetContent.js.map +1 -0
  220. package/lib/features/job-search/cvText.js +91 -0
  221. package/lib/features/job-search/cvText.js.map +1 -0
  222. package/lib/features/job-search/jobAgentSwipe.js +7 -0
  223. package/lib/features/job-search/jobAgentSwipe.js.map +1 -0
  224. package/lib/features/job-search/jobSearchClient.js +184 -0
  225. package/lib/features/job-search/jobSearchClient.js.map +1 -0
  226. package/lib/features/job-search/jobSearchExec.js +14 -0
  227. package/lib/features/job-search/jobSearchExec.js.map +1 -0
  228. package/lib/features/job-search/jobSearchRuntime.js +50 -0
  229. package/lib/features/job-search/jobSearchRuntime.js.map +1 -0
  230. package/lib/features/job-search/jobSearchTheme.js +44 -0
  231. package/lib/features/job-search/jobSearchTheme.js.map +1 -0
  232. package/lib/features/job-search/savedJobs.js +85 -0
  233. package/lib/features/job-search/savedJobs.js.map +1 -0
  234. package/lib/features/job-search/searchHistory.js +117 -0
  235. package/lib/features/job-search/searchHistory.js.map +1 -0
  236. package/lib/features/job-search/types.js +36 -0
  237. package/lib/features/job-search/types.js.map +1 -0
  238. package/lib/features/job-search/useJobSearchSession.js +558 -0
  239. package/lib/features/job-search/useJobSearchSession.js.map +1 -0
  240. package/lib/features/messaging/ChatComponents.js +529 -0
  241. package/lib/features/messaging/ChatComponents.js.map +1 -0
  242. package/lib/features/messaging/ChatInviteDeepLink.js +116 -0
  243. package/lib/features/messaging/ChatInviteDeepLink.js.map +1 -0
  244. package/lib/features/messaging/ContactsScreen.js +288 -0
  245. package/lib/features/messaging/ContactsScreen.js.map +1 -0
  246. package/lib/features/messaging/ConversationListScreen.js +147 -0
  247. package/lib/features/messaging/ConversationListScreen.js.map +1 -0
  248. package/lib/features/messaging/MessageActions.js +290 -0
  249. package/lib/features/messaging/MessageActions.js.map +1 -0
  250. package/lib/features/messaging/NativeChatExperience.js +189 -0
  251. package/lib/features/messaging/NativeChatExperience.js.map +1 -0
  252. package/lib/features/messaging/RegistrationScreen.js +11 -14
  253. package/lib/features/messaging/RegistrationScreen.js.map +1 -1
  254. package/lib/features/messaging/ThreadScreen.js +215 -0
  255. package/lib/features/messaging/ThreadScreen.js.map +1 -0
  256. package/lib/features/messaging/chatInviteLink.js +52 -0
  257. package/lib/features/messaging/chatInviteLink.js.map +1 -0
  258. package/lib/features/messaging/chatModel.js +278 -0
  259. package/lib/features/messaging/chatModel.js.map +1 -0
  260. package/lib/features/messaging/chatOperations.js +106 -1
  261. package/lib/features/messaging/chatOperations.js.map +1 -1
  262. package/lib/features/messaging/emojiCatalog.js +60 -0
  263. package/lib/features/messaging/emojiCatalog.js.map +1 -0
  264. package/lib/features/messaging/emojiKeywords.js +1592 -0
  265. package/lib/features/messaging/emojiKeywords.js.map +1 -0
  266. package/lib/features/messaging/nativeChatChannelQuery.js +27 -0
  267. package/lib/features/messaging/nativeChatChannelQuery.js.map +1 -0
  268. package/lib/features/messaging/phoneNumbers.js +52 -1
  269. package/lib/features/messaging/phoneNumbers.js.map +1 -1
  270. package/lib/features/messaging/sha256.js +68 -0
  271. package/lib/features/messaging/sha256.js.map +1 -0
  272. package/lib/features/messaging/useChatData.js +421 -0
  273. package/lib/features/messaging/useChatData.js.map +1 -0
  274. package/lib/features/messaging/useContactMatches.js +191 -0
  275. package/lib/features/messaging/useContactMatches.js.map +1 -0
  276. package/lib/features/messaging/usePhoneVerification.js +12 -12
  277. package/lib/features/messaging/usePhoneVerification.js.map +1 -1
  278. package/lib/features/messaging/yantraChatOrg.js +8 -3
  279. package/lib/features/messaging/yantraChatOrg.js.map +1 -1
  280. package/lib/features/resume/AnnotateModal.js +100 -0
  281. package/lib/features/resume/AnnotateModal.js.map +1 -0
  282. package/lib/features/resume/AnnotationBar.js +69 -0
  283. package/lib/features/resume/AnnotationBar.js.map +1 -0
  284. package/lib/features/resume/ExportSheet.js +105 -0
  285. package/lib/features/resume/ExportSheet.js.map +1 -0
  286. package/lib/features/resume/ResumeAgentChatPane.js +95 -0
  287. package/lib/features/resume/ResumeAgentChatPane.js.map +1 -0
  288. package/lib/features/resume/ResumeEditor.js +676 -0
  289. package/lib/features/resume/ResumeEditor.js.map +1 -0
  290. package/lib/features/resume/ResumeExperience.js +235 -0
  291. package/lib/features/resume/ResumeExperience.js.map +1 -0
  292. package/lib/features/resume/ResumeListPanel.js +262 -0
  293. package/lib/features/resume/ResumeListPanel.js.map +1 -0
  294. package/lib/features/resume/ResumeToolbar.js +236 -0
  295. package/lib/features/resume/ResumeToolbar.js.map +1 -0
  296. package/lib/features/resume/annotations.js +17 -0
  297. package/lib/features/resume/annotations.js.map +1 -0
  298. package/lib/features/resume/documentCss.js +52 -0
  299. package/lib/features/resume/documentCss.js.map +1 -0
  300. package/lib/features/resume/draft.js +89 -0
  301. package/lib/features/resume/draft.js.map +1 -0
  302. package/lib/features/resume/exportResume.js +43 -0
  303. package/lib/features/resume/exportResume.js.map +1 -0
  304. package/lib/features/resume/pickResumePhoto.js +22 -0
  305. package/lib/features/resume/pickResumePhoto.js.map +1 -0
  306. package/lib/features/resume/renderResume.js +121 -0
  307. package/lib/features/resume/renderResume.js.map +1 -0
  308. package/lib/features/resume/resumeClient.js +69 -0
  309. package/lib/features/resume/resumeClient.js.map +1 -0
  310. package/lib/features/resume/resumeExec.js +14 -0
  311. package/lib/features/resume/resumeExec.js.map +1 -0
  312. package/lib/features/resume/resumeIndex.js +244 -0
  313. package/lib/features/resume/resumeIndex.js.map +1 -0
  314. package/lib/features/resume/resumeRuntime.js +50 -0
  315. package/lib/features/resume/resumeRuntime.js.map +1 -0
  316. package/lib/features/resume/resumeTheme.js +34 -0
  317. package/lib/features/resume/resumeTheme.js.map +1 -0
  318. package/lib/features/resume/resumeToolbox.js +49 -0
  319. package/lib/features/resume/resumeToolbox.js.map +1 -0
  320. package/lib/features/resume/templates.js +90 -0
  321. package/lib/features/resume/templates.js.map +1 -0
  322. package/lib/features/resume/types.js +10 -0
  323. package/lib/features/resume/types.js.map +1 -0
  324. package/lib/features/resume/useResumeSession.js +183 -0
  325. package/lib/features/resume/useResumeSession.js.map +1 -0
  326. package/lib/features/shopping/DealsPanel.js +254 -0
  327. package/lib/features/shopping/DealsPanel.js.map +1 -0
  328. package/lib/features/shopping/HistoryPanel.js +147 -0
  329. package/lib/features/shopping/HistoryPanel.js.map +1 -0
  330. package/lib/features/shopping/OrdersPanel.js +157 -0
  331. package/lib/features/shopping/OrdersPanel.js.map +1 -0
  332. package/lib/features/shopping/ProductCard.js +326 -0
  333. package/lib/features/shopping/ProductCard.js.map +1 -0
  334. package/lib/features/shopping/ProductDetailSheet.js +313 -0
  335. package/lib/features/shopping/ProductDetailSheet.js.map +1 -0
  336. package/lib/features/shopping/ProductFilterBar.js +153 -0
  337. package/lib/features/shopping/ProductFilterBar.js.map +1 -0
  338. package/lib/features/shopping/ProductPhoto.js +27 -0
  339. package/lib/features/shopping/ProductPhoto.js.map +1 -0
  340. package/lib/features/shopping/SavedPanel.js +139 -0
  341. package/lib/features/shopping/SavedPanel.js.map +1 -0
  342. package/lib/features/shopping/ShoppingAgentChatPane.js +436 -0
  343. package/lib/features/shopping/ShoppingAgentChatPane.js.map +1 -0
  344. package/lib/features/shopping/ShoppingExperience.js +888 -0
  345. package/lib/features/shopping/ShoppingExperience.js.map +1 -0
  346. package/lib/features/shopping/TrendingSections.js +199 -0
  347. package/lib/features/shopping/TrendingSections.js.map +1 -0
  348. package/lib/features/shopping/WatchlistPanel.js +148 -0
  349. package/lib/features/shopping/WatchlistPanel.js.map +1 -0
  350. package/lib/features/shopping/catalog.js +238 -0
  351. package/lib/features/shopping/catalog.js.map +1 -0
  352. package/lib/features/shopping/chat/ShoppingChatResultCard.js +175 -0
  353. package/lib/features/shopping/chat/ShoppingChatResultCard.js.map +1 -0
  354. package/lib/features/shopping/chat/streamAssistantReply.js +34 -0
  355. package/lib/features/shopping/chat/streamAssistantReply.js.map +1 -0
  356. package/lib/features/shopping/chat/widgetContent.js +233 -0
  357. package/lib/features/shopping/chat/widgetContent.js.map +1 -0
  358. package/lib/features/shopping/hooks/useTrendingProducts.js +162 -0
  359. package/lib/features/shopping/hooks/useTrendingProducts.js.map +1 -0
  360. package/lib/features/shopping/productImage.js +42 -0
  361. package/lib/features/shopping/productImage.js.map +1 -0
  362. package/lib/features/shopping/savedProducts.js +84 -0
  363. package/lib/features/shopping/savedProducts.js.map +1 -0
  364. package/lib/features/shopping/services/catalogActions.js +166 -0
  365. package/lib/features/shopping/services/catalogActions.js.map +1 -0
  366. package/lib/features/shopping/services/parsePriceCheckIntent.js +58 -0
  367. package/lib/features/shopping/services/parsePriceCheckIntent.js.map +1 -0
  368. package/lib/features/shopping/services/parseShoppingIntent.js +67 -0
  369. package/lib/features/shopping/services/parseShoppingIntent.js.map +1 -0
  370. package/lib/features/shopping/services/productAvailability.js +25 -0
  371. package/lib/features/shopping/services/productAvailability.js.map +1 -0
  372. package/lib/features/shopping/services/productFilters.js +72 -0
  373. package/lib/features/shopping/services/productFilters.js.map +1 -0
  374. package/lib/features/shopping/services/retailerUrl.js +75 -0
  375. package/lib/features/shopping/services/retailerUrl.js.map +1 -0
  376. package/lib/features/shopping/services/shoppingChatReply.js +46 -0
  377. package/lib/features/shopping/services/shoppingChatReply.js.map +1 -0
  378. package/lib/features/shopping/services/shoppingProductSearch.js +336 -0
  379. package/lib/features/shopping/services/shoppingProductSearch.js.map +1 -0
  380. package/lib/features/shopping/services/shoppingSearchConnectorClient.js +41 -0
  381. package/lib/features/shopping/services/shoppingSearchConnectorClient.js.map +1 -0
  382. package/lib/features/shopping/shopAgentSwipe.js +7 -0
  383. package/lib/features/shopping/shopAgentSwipe.js.map +1 -0
  384. package/lib/features/shopping/shoppingCart.js +116 -0
  385. package/lib/features/shopping/shoppingCart.js.map +1 -0
  386. package/lib/features/shopping/shoppingExec.js +14 -0
  387. package/lib/features/shopping/shoppingExec.js.map +1 -0
  388. package/lib/features/shopping/shoppingHistoryStore.js +176 -0
  389. package/lib/features/shopping/shoppingHistoryStore.js.map +1 -0
  390. package/lib/features/shopping/shoppingRuntime.js +63 -0
  391. package/lib/features/shopping/shoppingRuntime.js.map +1 -0
  392. package/lib/features/shopping/timeAgo.js +14 -0
  393. package/lib/features/shopping/timeAgo.js.map +1 -0
  394. package/lib/features/shopping/useShoppingSearch.js +262 -0
  395. package/lib/features/shopping/useShoppingSearch.js.map +1 -0
  396. package/lib/features/travel/BookHeaderGlow.js +48 -0
  397. package/lib/features/travel/BookHeaderGlow.js.map +1 -0
  398. package/lib/features/travel/BookingsPanel.js +29 -0
  399. package/lib/features/travel/BookingsPanel.js.map +1 -0
  400. package/lib/features/travel/DiscoverPanel.js +155 -0
  401. package/lib/features/travel/DiscoverPanel.js.map +1 -0
  402. package/lib/features/travel/FlightCompareBar.js +86 -0
  403. package/lib/features/travel/FlightCompareBar.js.map +1 -0
  404. package/lib/features/travel/FlightDealsBoard.js +100 -0
  405. package/lib/features/travel/FlightDealsBoard.js.map +1 -0
  406. package/lib/features/travel/HistoryPanel.js +82 -0
  407. package/lib/features/travel/HistoryPanel.js.map +1 -0
  408. package/lib/features/travel/PopularDestinations.js +144 -0
  409. package/lib/features/travel/PopularDestinations.js.map +1 -0
  410. package/lib/features/travel/SavedPanel.js +27 -0
  411. package/lib/features/travel/SavedPanel.js.map +1 -0
  412. package/lib/features/travel/TravelAgentChatPane.js +303 -0
  413. package/lib/features/travel/TravelAgentChatPane.js.map +1 -0
  414. package/lib/features/travel/TravelBookHero.js +425 -0
  415. package/lib/features/travel/TravelBookHero.js.map +1 -0
  416. package/lib/features/travel/TravelDatesField.js +234 -0
  417. package/lib/features/travel/TravelDatesField.js.map +1 -0
  418. package/lib/features/travel/TravelDetailSheet.js +106 -0
  419. package/lib/features/travel/TravelDetailSheet.js.map +1 -0
  420. package/lib/features/travel/TravelExperience.js +624 -0
  421. package/lib/features/travel/TravelExperience.js.map +1 -0
  422. package/lib/features/travel/TravelGuestsField.js +85 -0
  423. package/lib/features/travel/TravelGuestsField.js.map +1 -0
  424. package/lib/features/travel/TravelLanding.js +318 -0
  425. package/lib/features/travel/TravelLanding.js.map +1 -0
  426. package/lib/features/travel/TravelLocationField.js +179 -0
  427. package/lib/features/travel/TravelLocationField.js.map +1 -0
  428. package/lib/features/travel/TravelPropertyCard.js +266 -0
  429. package/lib/features/travel/TravelPropertyCard.js.map +1 -0
  430. package/lib/features/travel/TravelPropertyPhoto.js +22 -0
  431. package/lib/features/travel/TravelPropertyPhoto.js.map +1 -0
  432. package/lib/features/travel/TravelRailFlyout.js +79 -0
  433. package/lib/features/travel/TravelRailFlyout.js.map +1 -0
  434. package/lib/features/travel/TravelResultsMap.js +126 -0
  435. package/lib/features/travel/TravelResultsMap.js.map +1 -0
  436. package/lib/features/travel/WorkspacePanel.js +148 -0
  437. package/lib/features/travel/WorkspacePanel.js.map +1 -0
  438. package/lib/features/travel/appNav.js +244 -0
  439. package/lib/features/travel/appNav.js.map +1 -0
  440. package/lib/features/travel/calendarDays.js +50 -0
  441. package/lib/features/travel/calendarDays.js.map +1 -0
  442. package/lib/features/travel/catalog.js +72 -0
  443. package/lib/features/travel/catalog.js.map +1 -0
  444. package/lib/features/travel/chat/TravelChatResultCard.js +107 -0
  445. package/lib/features/travel/chat/TravelChatResultCard.js.map +1 -0
  446. package/lib/features/travel/chat/widgetContent.js +107 -0
  447. package/lib/features/travel/chat/widgetContent.js.map +1 -0
  448. package/lib/features/travel/flightDeals.js +65 -0
  449. package/lib/features/travel/flightDeals.js.map +1 -0
  450. package/lib/features/travel/mapCoordinates.js +36 -0
  451. package/lib/features/travel/mapCoordinates.js.map +1 -0
  452. package/lib/features/travel/parseTravelIntent.js +303 -0
  453. package/lib/features/travel/parseTravelIntent.js.map +1 -0
  454. package/lib/features/travel/savedStays.js +66 -0
  455. package/lib/features/travel/savedStays.js.map +1 -0
  456. package/lib/features/travel/services/flightDealsBoard.js +111 -0
  457. package/lib/features/travel/services/flightDealsBoard.js.map +1 -0
  458. package/lib/features/travel/services/flightSearchConnectorClient.js +42 -0
  459. package/lib/features/travel/services/flightSearchConnectorClient.js.map +1 -0
  460. package/lib/features/travel/services/geocodeLocation.js +79 -0
  461. package/lib/features/travel/services/geocodeLocation.js.map +1 -0
  462. package/lib/features/travel/services/placePredictions.js +113 -0
  463. package/lib/features/travel/services/placePredictions.js.map +1 -0
  464. package/lib/features/travel/services/resolveOriginCity.js +27 -0
  465. package/lib/features/travel/services/resolveOriginCity.js.map +1 -0
  466. package/lib/features/travel/services/resortifiConnectorClient.js +76 -0
  467. package/lib/features/travel/services/resortifiConnectorClient.js.map +1 -0
  468. package/lib/features/travel/services/travelFlightSearch.js +289 -0
  469. package/lib/features/travel/services/travelFlightSearch.js.map +1 -0
  470. package/lib/features/travel/services/travelPropertySearch.js +377 -0
  471. package/lib/features/travel/services/travelPropertySearch.js.map +1 -0
  472. package/lib/features/travel/travelAgentSwipe.js +7 -0
  473. package/lib/features/travel/travelAgentSwipe.js.map +1 -0
  474. package/lib/features/travel/travelExec.js +14 -0
  475. package/lib/features/travel/travelExec.js.map +1 -0
  476. package/lib/features/travel/travelHistoryStore.js +108 -0
  477. package/lib/features/travel/travelHistoryStore.js.map +1 -0
  478. package/lib/features/travel/travelRuntime.js +62 -0
  479. package/lib/features/travel/travelRuntime.js.map +1 -0
  480. package/lib/features/travel/types.js +9 -0
  481. package/lib/features/travel/types.js.map +1 -0
  482. package/lib/features/travel/useTravelSearch.js +330 -0
  483. package/lib/features/travel/useTravelSearch.js.map +1 -0
  484. package/lib/features/travel/workspaceContent.js +548 -0
  485. package/lib/features/travel/workspaceContent.js.map +1 -0
  486. package/lib/hooks/useCdecliChannel.js +128 -6
  487. package/lib/hooks/useCdecliChannel.js.map +1 -1
  488. package/lib/hooks/useChatApi.js +4 -2
  489. package/lib/hooks/useChatApi.js.map +1 -1
  490. package/lib/hooks/useChatStream.js +77 -63
  491. package/lib/hooks/useChatStream.js.map +1 -1
  492. package/lib/hooks/useHostConnectorCard.js +24 -0
  493. package/lib/hooks/useHostConnectorCard.js.map +1 -0
  494. package/lib/hooks/useObtainSystemToken.js +23 -5
  495. package/lib/hooks/useObtainSystemToken.js.map +1 -1
  496. package/lib/hooks/webViewRetentionPolicy.js +1 -0
  497. package/lib/hooks/webViewRetentionPolicy.js.map +1 -1
  498. package/lib/index.js +1 -1
  499. package/lib/index.js.map +1 -1
  500. package/lib/screens/Chat/index.js +51 -22
  501. package/lib/screens/Chat/index.js.map +1 -1
  502. package/lib/screens/ChatNative/index.js +13 -2
  503. package/lib/screens/ChatNative/index.js.map +1 -1
  504. package/lib/screens/Home/HomeScreen.js +3 -3
  505. package/lib/screens/Home/HomeScreen.js.map +1 -1
  506. package/lib/screens/Home/components/ChatHistoryLanding.js +32 -32
  507. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  508. package/lib/screens/JobSearchNative/useJobSearchHostChat.js +12 -6
  509. package/lib/screens/JobSearchNative/useJobSearchHostChat.js.map +1 -1
  510. package/lib/screens/ResumeNative/useResumeHostChat.js +12 -6
  511. package/lib/screens/ResumeNative/useResumeHostChat.js.map +1 -1
  512. package/lib/screens/ShoppingNative/useShoppingHostChat.js +12 -6
  513. package/lib/screens/ShoppingNative/useShoppingHostChat.js.map +1 -1
  514. package/lib/screens/TravelNative/useTravelHostChat.js +12 -6
  515. package/lib/screens/TravelNative/useTravelHostChat.js.map +1 -1
  516. package/lib/screens/WebBuilder/WebViewWithNavigation.js +2 -2
  517. package/lib/screens/WebBuilder/WebViewWithNavigation.js.map +1 -1
  518. package/lib/services/brainQuickReply.js +38 -1
  519. package/lib/services/brainQuickReply.js.map +1 -1
  520. package/lib/state/chatThreadMerge.js +6 -1
  521. package/lib/state/chatThreadMerge.js.map +1 -1
  522. package/package.json +6 -4
@@ -0,0 +1,278 @@
1
+ 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
+ function displayNameOf(user, fallback = "Unknown") {
21
+ var _a, _b, _c, _d;
22
+ if (!user) return fallback;
23
+ const profileName = (_b = (_a = user.profile) == null ? void 0 : _a.displayName) == null ? void 0 : _b.trim();
24
+ if (profileName) return profileName;
25
+ const fullName = [user.givenName, user.familyName].filter(Boolean).join(" ").trim();
26
+ if (fullName) return fullName;
27
+ const username = (_c = user.username) == null ? void 0 : _c.trim();
28
+ if (username) return username;
29
+ const email = (_d = user.email) == null ? void 0 : _d.trim();
30
+ if (email) return email.split("@")[0] || fallback;
31
+ return fallback;
32
+ }
33
+ function memberNames(channel, viewerId) {
34
+ var _a;
35
+ return ((_a = channel.members) != null ? _a : []).map((member) => member == null ? void 0 : member.user).filter((user) => Boolean(user == null ? void 0 : user.id) && String(user.id) !== viewerId).map((user) => displayNameOf(user, "")).filter(Boolean).slice(0, 3);
36
+ }
37
+ function pickAuthor(post) {
38
+ var _a, _b;
39
+ return (_b = (_a = post.author) != null ? _a : post.creator) != null ? _b : null;
40
+ }
41
+ function toEpoch(value) {
42
+ if (value == null) return 0;
43
+ if (typeof value === "number") return Number.isFinite(value) ? value : 0;
44
+ const parsed = Date.parse(value);
45
+ return Number.isNaN(parsed) ? 0 : parsed;
46
+ }
47
+ function toChatMessage(post, viewerId) {
48
+ var _a, _b, _c, _d, _e;
49
+ const author = pickAuthor(post);
50
+ return {
51
+ id: String(post.id),
52
+ body: (_a = post.message) != null ? _a : "",
53
+ createdAt: toEpoch(post.createdAt),
54
+ authorId: (author == null ? void 0 : author.id) ? String(author.id) : null,
55
+ authorName: displayNameOf(author),
56
+ authorAvatar: (_d = (_c = author == null ? void 0 : author.picture) != null ? _c : (_b = author == null ? void 0 : author.profile) == null ? void 0 : _b.picture) != null ? _d : null,
57
+ isMine: !!(author == null ? void 0 : author.id) && String(author.id) === viewerId,
58
+ isDeleted: !!post.deletedAt,
59
+ isEdited: !!post.editedAt,
60
+ attachments: ((_e = post.filenames) != null ? _e : []).filter((f) => typeof f === "string" && f.length > 0),
61
+ reactions: toChatReactions(post.reactionSummary, viewerId)
62
+ };
63
+ }
64
+ function toChatReactions(summary, viewerId) {
65
+ return (summary != null ? summary : []).filter((r) => r && r.reaction && r.count > 0).map((r) => {
66
+ var _a;
67
+ const userIds = ((_a = r.userIds) != null ? _a : []).filter((u) => typeof u === "string" && u.length > 0);
68
+ return {
69
+ reaction: r.reaction,
70
+ count: r.count,
71
+ userIds,
72
+ mine: userIds.includes(viewerId)
73
+ };
74
+ });
75
+ }
76
+ function applyReactionSummary(messages, messageId, summary, viewerId) {
77
+ return messages.map((m) => m.id === messageId ? __spreadProps(__spreadValues({}, m), {
78
+ reactions: toChatReactions(summary, viewerId)
79
+ }) : m);
80
+ }
81
+ function withViewerReaction(reactions, emoji, viewerId) {
82
+ var _a, _b;
83
+ const current = (_b = (_a = reactions.find((r) => r.mine)) == null ? void 0 : _a.reaction) != null ? _b : null;
84
+ const next = emoji && emoji !== current ? emoji : null;
85
+ const out = reactions.map((r) => r.mine ? __spreadProps(__spreadValues({}, r), {
86
+ mine: false,
87
+ count: r.count - 1,
88
+ userIds: r.userIds.filter((u) => u !== viewerId)
89
+ }) : r).filter((r) => r.count > 0);
90
+ if (!next) return out;
91
+ const idx = out.findIndex((r) => r.reaction === next);
92
+ if (idx >= 0) {
93
+ const r = out[idx];
94
+ out[idx] = __spreadProps(__spreadValues({}, r), {
95
+ mine: true,
96
+ count: r.count + 1,
97
+ userIds: [...r.userIds, viewerId]
98
+ });
99
+ return out;
100
+ }
101
+ return [...out, {
102
+ reaction: next,
103
+ count: 1,
104
+ mine: true,
105
+ userIds: [viewerId]
106
+ }];
107
+ }
108
+ function mergeMessages(existing, incoming) {
109
+ const byId = /* @__PURE__ */ new Map();
110
+ for (const m of existing) byId.set(m.id, m);
111
+ for (const m of incoming) byId.set(m.id, m);
112
+ return Array.from(byId.values()).sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
113
+ }
114
+ function reconcileOptimistic(messages, confirmed, windowMs = 6e4) {
115
+ if (!confirmed.isMine) return mergeMessages(messages, [confirmed]);
116
+ const pendingIdx = messages.findIndex((m) => m.sendState === "sending" && m.isMine && m.body === confirmed.body && // Same author, not merely both "mine" - guards the same collision
117
+ // when authorId is populated on both sides.
118
+ (!m.authorId || !confirmed.authorId || m.authorId === confirmed.authorId) && Math.abs(m.createdAt - confirmed.createdAt) <= windowMs);
119
+ if (pendingIdx === -1) return mergeMessages(messages, [confirmed]);
120
+ const next = messages.slice();
121
+ next[pendingIdx] = __spreadProps(__spreadValues({}, confirmed), {
122
+ sendState: "sent",
123
+ replacedClientId: messages[pendingIdx].id
124
+ });
125
+ return mergeMessages(next.filter((m) => m.id !== confirmed.id || m.replacedClientId), [next[pendingIdx]]);
126
+ }
127
+ function peerOf(channel, viewerId) {
128
+ var _a, _b;
129
+ const members = ((_a = channel.members) != null ? _a : []).filter(Boolean);
130
+ const other = members.find((m) => {
131
+ var _a2;
132
+ return ((_a2 = m.user) == null ? void 0 : _a2.id) && String(m.user.id) !== viewerId;
133
+ });
134
+ return (_b = other == null ? void 0 : other.user) != null ? _b : null;
135
+ }
136
+ function unreadOf(channel, viewerId) {
137
+ var _a, _b, _c;
138
+ const mine = ((_a = channel.members) != null ? _a : []).find((m) => {
139
+ var _a2;
140
+ return ((_a2 = m == null ? void 0 : m.user) == null ? void 0 : _a2.id) && String(m.user.id) === viewerId;
141
+ });
142
+ if (!mine) return 0;
143
+ const total = (_b = channel.totalMsgCount) != null ? _b : 0;
144
+ const seen = (_c = mine.msgCount) != null ? _c : 0;
145
+ return Math.max(0, total - seen);
146
+ }
147
+ const DIRECT_TYPES = /* @__PURE__ */ new Set(["DIRECT", "Direct", "direct"]);
148
+ function looksLikeMachineTitle(value) {
149
+ var _a;
150
+ const label = (_a = value == null ? void 0 : value.trim()) != null ? _a : "";
151
+ if (!label) return true;
152
+ if (/^chat[\s_-]*channel\b/i.test(label) || /^chat-channel-/i.test(label)) return true;
153
+ if (/^[a-f0-9]{8,}$/i.test(label)) return true;
154
+ if (label.includes("__")) return true;
155
+ if (/^group(\s+chat)?$/i.test(label)) return true;
156
+ return false;
157
+ }
158
+ function toConversation(channel, viewerId) {
159
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
160
+ const peerCandidate = peerOf(channel, viewerId);
161
+ const explicitDirect = DIRECT_TYPES.has(String((_a = channel.type) != null ? _a : ""));
162
+ const populatedMembers = ((_b = channel.members) != null ? _b : []).filter(Boolean);
163
+ const twoParty = populatedMembers.length === 2 && Boolean(peerCandidate);
164
+ const hasMachineLabel = looksLikeMachineTitle(channel.displayName) && looksLikeMachineTitle(channel.title);
165
+ const isDirect = explicitDirect || twoParty || !channel.type && hasMachineLabel && Boolean(peerCandidate);
166
+ const peer = isDirect ? peerCandidate : null;
167
+ const names = memberNames(channel, viewerId);
168
+ const lastAuthor = channel.lastMessage ? pickAuthor(channel.lastMessage) : null;
169
+ const lastAuthorName = lastAuthor && String(lastAuthor.id) !== viewerId ? displayNameOf(lastAuthor, "") : "";
170
+ const creatorName = displayNameOf(channel.creator, "");
171
+ const groupFallback = names.length ? names.join(", ") : lastAuthorName || (creatorName && creatorName !== "Unknown" ? creatorName : "Chat");
172
+ const storedLabel = !looksLikeMachineTitle(channel.displayName) ? channel.displayName.trim() : !looksLikeMachineTitle(channel.title) ? channel.title.trim() : "";
173
+ const title = isDirect ? displayNameOf(peer, storedLabel || lastAuthorName || "Direct message") : storedLabel || groupFallback;
174
+ const topic = looksLikeMachineTitle(channel.topic) ? "" : ((_c = channel.topic) != null ? _c : "").trim();
175
+ const preview = ((_e = (_d = channel.lastMessage) == null ? void 0 : _d.message) == null ? void 0 : _e.trim()) || topic;
176
+ return {
177
+ id: String(channel.id),
178
+ title,
179
+ subtitle: preview === title ? "" : preview,
180
+ avatarUrl: (_o = (_n = (_l = (_k = (_g = peer == null ? void 0 : peer.picture) != null ? _g : (_f = peer == null ? void 0 : peer.profile) == null ? void 0 : _f.picture) != null ? _k : (_j = (_i = (_h = channel.members) == null ? void 0 : _h.find((member) => {
181
+ var _a2;
182
+ return (_a2 = member == null ? void 0 : member.user) == null ? void 0 : _a2.picture;
183
+ })) == null ? void 0 : _i.user) == null ? void 0 : _j.picture) != null ? _l : lastAuthor == null ? void 0 : lastAuthor.picture) != null ? _n : (_m = lastAuthor == null ? void 0 : lastAuthor.profile) == null ? void 0 : _m.picture) != null ? _o : null,
184
+ lastActivity: toEpoch(channel.lastPostAt) || toEpoch(channel.createdAt),
185
+ unreadCount: unreadOf(channel, viewerId),
186
+ isDirect,
187
+ peer
188
+ };
189
+ }
190
+ function sortConversations(list) {
191
+ return list.slice().sort((a, b) => b.lastActivity - a.lastActivity || a.title.localeCompare(b.title) || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
192
+ }
193
+ function conversationListKey(c) {
194
+ var _a;
195
+ if ((_a = c.peer) == null ? void 0 : _a.id) return `peer:${String(c.peer.id)}`;
196
+ const title = c.title.trim().toLowerCase();
197
+ if (!title || title === "chat" || title === "unknown") return `id:${c.id}`;
198
+ if (title.includes(",")) return `id:${c.id}`;
199
+ if (c.isDirect) return `title:${title}`;
200
+ return `title:${title}`;
201
+ }
202
+ function dedupeConversationList(list) {
203
+ const sorted = sortConversations(list);
204
+ const seen = /* @__PURE__ */ new Set();
205
+ const out = [];
206
+ for (const c of sorted) {
207
+ const key = conversationListKey(c);
208
+ if (seen.has(key)) continue;
209
+ seen.add(key);
210
+ out.push(c);
211
+ }
212
+ return out;
213
+ }
214
+ function mergeConversations(existing, incoming) {
215
+ const byId = /* @__PURE__ */ new Map();
216
+ for (const c of existing) byId.set(c.id, c);
217
+ for (const c of incoming) byId.set(c.id, c);
218
+ return dedupeConversationList(Array.from(byId.values()));
219
+ }
220
+ function patchConversationAfterPost(conv, post, viewerId) {
221
+ var _a;
222
+ const preview = (_a = post.message) == null ? void 0 : _a.trim();
223
+ const nextSubtitle = preview == null || preview === "" ? conv.subtitle : preview === conv.title ? "" : preview;
224
+ const activity = toEpoch(post.createdAt) || Date.now();
225
+ const author = pickAuthor(post);
226
+ const fromPeer = author && String(author.id) !== viewerId;
227
+ return __spreadProps(__spreadValues({}, conv), {
228
+ subtitle: nextSubtitle,
229
+ lastActivity: activity,
230
+ unreadCount: fromPeer ? conv.unreadCount + 1 : conv.unreadCount
231
+ });
232
+ }
233
+ function dayLabel(epoch, now) {
234
+ if (!epoch) return "";
235
+ const d = new Date(epoch);
236
+ const n = new Date(now);
237
+ const sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
238
+ if (sameDay(d, n)) return "Today";
239
+ const yesterday = new Date(now);
240
+ yesterday.setDate(yesterday.getDate() - 1);
241
+ if (sameDay(d, yesterday)) return "Yesterday";
242
+ return d.toLocaleDateString(void 0, {
243
+ month: "short",
244
+ day: "numeric",
245
+ year: d.getFullYear() === n.getFullYear() ? void 0 : "numeric"
246
+ });
247
+ }
248
+ function timeLabel(epoch) {
249
+ if (!epoch) return "";
250
+ return new Date(epoch).toLocaleTimeString(void 0, {
251
+ hour: "numeric",
252
+ minute: "2-digit"
253
+ });
254
+ }
255
+ function relativeLabel(epoch, now) {
256
+ if (!epoch) return "";
257
+ const diff = now - epoch;
258
+ if (diff < 6e4) return "now";
259
+ if (diff < 36e5) return `${Math.floor(diff / 6e4)}m`;
260
+ const d = new Date(epoch);
261
+ const n = new Date(now);
262
+ if (d.getFullYear() === n.getFullYear() && d.getMonth() === n.getMonth() && d.getDate() === n.getDate()) {
263
+ return timeLabel(epoch);
264
+ }
265
+ if (diff < 7 * 864e5) return d.toLocaleDateString(void 0, {
266
+ weekday: "short"
267
+ });
268
+ return d.toLocaleDateString(void 0, {
269
+ month: "numeric",
270
+ day: "numeric"
271
+ });
272
+ }
273
+ function initialsOf(name) {
274
+ const parts = name.trim().split(/\s+/).filter(Boolean);
275
+ if (!parts.length) return "?";
276
+ if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
277
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
278
+ }export{applyReactionSummary,conversationListKey,dayLabel,dedupeConversationList,displayNameOf,initialsOf,mergeConversations,mergeMessages,patchConversationAfterPost,peerOf,pickAuthor,reconcileOptimistic,relativeLabel,sortConversations,timeLabel,toChatMessage,toChatReactions,toConversation,toEpoch,unreadOf,withViewerReaction};//# sourceMappingURL=chatModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatModel.js","sources":["../../../src/features/messaging/chatModel.ts"],"sourcesContent":["/**\n * Pure shaping between messenger-box's wire types and what the chat UI renders.\n *\n * Everything here is a plain function over plain data - no React, no seams, no\n * clock beyond what is passed in - because this is where the bugs that actually\n * ruin a chat client live: messages in the wrong order, a duplicate after a\n * reconnect, an optimistic row that never resolves, a DM titled with your own\n * name. Those are all cheap to unit-test and expensive to debug on a device.\n */\n\nexport interface ChatUser {\n id: string;\n givenName?: string | null;\n familyName?: string | null;\n username?: string | null;\n email?: string | null;\n picture?: string | null;\n profile?: { displayName?: string | null; picture?: string | null } | null;\n}\n\nexport interface WirePost {\n id: string;\n message?: string | null;\n type?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n editedAt?: string | null;\n deletedAt?: string | null;\n rootId?: string | null;\n parentId?: string | null;\n filenames?: (string | null)[] | null;\n props?: Record<string, unknown> | null;\n author?: ChatUser | null;\n creator?: ChatUser | null;\n reactionSummary?: WireReaction[] | null;\n}\n\nexport interface WireReaction {\n reaction: string;\n count: number;\n userIds?: (string | null)[] | null;\n}\n\n/** One Tapback on a message, grouped across users. */\nexport interface ChatReaction {\n reaction: string;\n count: number;\n /** The viewer is one of the reactors. */\n mine: boolean;\n userIds: string[];\n}\n\nexport interface WireChannelMember {\n id?: string | null;\n user?: ChatUser | null;\n msgCount?: number | null;\n lastViewedAt?: string | null;\n}\n\nexport interface WireChannel {\n id: string;\n type?: string | null;\n orgName?: string | null;\n title?: string | null;\n displayName?: string | null;\n topic?: string | null;\n lastPostAt?: string | null;\n totalMsgCount?: number | null;\n createdAt?: string | null;\n lastMessage?: WirePost | null;\n creator?: ChatUser | null;\n members?: (WireChannelMember | null)[] | null;\n}\n\n/** Where an optimistic message is in its lifecycle. */\nexport type ChatSendState = 'sending' | 'sent' | 'failed';\n\nexport interface ChatMessage {\n id: string;\n body: string;\n createdAt: number;\n authorId: string | null;\n authorName: string;\n authorAvatar?: string | null;\n isMine: boolean;\n isDeleted: boolean;\n isEdited: boolean;\n attachments: string[];\n /** Tapbacks, in first-use order. Empty when nobody reacted. */\n reactions: ChatReaction[];\n /** Present only on messages this device is still sending. */\n sendState?: ChatSendState;\n /** The optimistic id this row replaced, so the UI can animate rather than jump. */\n replacedClientId?: string;\n}\n\nexport interface ChatConversation {\n id: string;\n title: string;\n subtitle: string;\n avatarUrl?: string | null;\n /** Sort key; 0 when the channel has never had a message. */\n lastActivity: number;\n unreadCount: number;\n isDirect: boolean;\n /** The other participant, for a DM. Null for groups. */\n peer: ChatUser | null;\n}\n\n/**\n * A person's display name, in the order a human would expect.\n *\n * Email is the last resort and is truncated at the `@`: a transcript full of\n * `someone@example.com` is worse than one full of `someone`.\n */\nexport function displayNameOf(user?: ChatUser | null, fallback = 'Unknown'): string {\n if (!user) return fallback;\n const profileName = user.profile?.displayName?.trim();\n if (profileName) return profileName;\n const fullName = [user.givenName, user.familyName].filter(Boolean).join(' ').trim();\n if (fullName) return fullName;\n const username = user.username?.trim();\n if (username) return username;\n const email = user.email?.trim();\n if (email) return email.split('@')[0] || fallback;\n return fallback;\n}\n\nfunction memberNames(channel: WireChannel, viewerId: string): string[] {\n return (channel.members ?? [])\n .map((member) => member?.user)\n .filter((user): user is ChatUser => Boolean(user?.id) && String(user.id) !== viewerId)\n .map((user) => displayNameOf(user, ''))\n .filter(Boolean)\n .slice(0, 3);\n}\n\n/**\n * messenger-box populates `author` on some write paths and `creator` on others\n * (`sendMessage` sets creator). Reading only one shows \"Unknown\" for a large\n * fraction of real transcripts.\n */\nexport function pickAuthor(post: WirePost): ChatUser | null {\n return post.author ?? post.creator ?? null;\n}\n\n/** Epoch millis, tolerant of nulls and unparseable values. */\nexport function toEpoch(value?: string | number | null): number {\n if (value == null) return 0;\n if (typeof value === 'number') return Number.isFinite(value) ? value : 0;\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? 0 : parsed;\n}\n\nexport function toChatMessage(post: WirePost, viewerId: string): ChatMessage {\n const author = pickAuthor(post);\n return {\n id: String(post.id),\n body: post.message ?? '',\n createdAt: toEpoch(post.createdAt),\n authorId: author?.id ? String(author.id) : null,\n authorName: displayNameOf(author),\n authorAvatar: author?.picture ?? author?.profile?.picture ?? null,\n isMine: !!author?.id && String(author.id) === viewerId,\n isDeleted: !!post.deletedAt,\n isEdited: !!post.editedAt,\n attachments: (post.filenames ?? []).filter((f): f is string => typeof f === 'string' && f.length > 0),\n reactions: toChatReactions(post.reactionSummary, viewerId),\n };\n}\n\nexport function toChatReactions(summary: WireReaction[] | null | undefined, viewerId: string): ChatReaction[] {\n return (summary ?? [])\n .filter((r) => r && r.reaction && r.count > 0)\n .map((r) => {\n const userIds = (r.userIds ?? []).filter((u): u is string => typeof u === 'string' && u.length > 0);\n return { reaction: r.reaction, count: r.count, userIds, mine: userIds.includes(viewerId) };\n });\n}\n\n/** Replace one message's reactions with the server's latest summary. */\nexport function applyReactionSummary(\n messages: ChatMessage[],\n messageId: string,\n summary: WireReaction[] | null | undefined,\n viewerId: string,\n): ChatMessage[] {\n return messages.map((m) => (m.id === messageId ? { ...m, reactions: toChatReactions(summary, viewerId) } : m));\n}\n\n/**\n * The viewer's reactions after picking `emoji` (null = remove). One Tapback per person,\n * like iMessage: a new pick replaces the old one, the same pick removes it.\n */\nexport function withViewerReaction(reactions: ChatReaction[], emoji: string | null, viewerId: string): ChatReaction[] {\n const current = reactions.find((r) => r.mine)?.reaction ?? null;\n const next = emoji && emoji !== current ? emoji : null;\n const out = reactions\n .map((r) =>\n r.mine ? { ...r, mine: false, count: r.count - 1, userIds: r.userIds.filter((u) => u !== viewerId) } : r,\n )\n .filter((r) => r.count > 0);\n if (!next) return out;\n const idx = out.findIndex((r) => r.reaction === next);\n if (idx >= 0) {\n const r = out[idx];\n out[idx] = { ...r, mine: true, count: r.count + 1, userIds: [...r.userIds, viewerId] };\n return out;\n }\n return [...out, { reaction: next, count: 1, mine: true, userIds: [viewerId] }];\n}\n\n/**\n * Merge a batch of messages into the transcript: de-duplicated by id, oldest\n * first.\n *\n * De-duplication is the whole point. The same message arrives twice all the\n * time - the subscription delivers it while the head-page refetch that follows\n * a reconnect also returns it, and offset paging re-reads a row when something\n * lands mid-scroll. LAST WRITE WINS on a collision, so a server row replaces\n * the optimistic copy rather than the other way round.\n *\n * Ties break on id, not on insertion order: two messages can share a timestamp\n * to the millisecond, and an unstable comparator makes them swap places on\n * every render.\n */\nexport function mergeMessages(existing: ChatMessage[], incoming: ChatMessage[]): ChatMessage[] {\n const byId = new Map<string, ChatMessage>();\n for (const m of existing) byId.set(m.id, m);\n for (const m of incoming) byId.set(m.id, m);\n return Array.from(byId.values()).sort(\n (a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0),\n );\n}\n\n/**\n * Reconcile a server message with the optimistic row it confirms.\n *\n * Matched on (author, body, nearby timestamp) rather than an echoed client id,\n * because `sendMessage` does not round-trip one. The window is deliberately\n * generous - a slow network is normal - and the cost of a miss is a brief\n * duplicate that the next refetch cleans up, not a lost message.\n */\nexport function reconcileOptimistic(messages: ChatMessage[], confirmed: ChatMessage, windowMs = 60_000): ChatMessage[] {\n // Only the viewer's OWN message can confirm the viewer's pending row.\n // Without this, someone else sending the identical text inside the window\n // consumes the optimistic slot: their message is relabelled as yours and\n // yours disappears. \"ok\", \"thanks\" and \"๐Ÿ‘\" collide constantly.\n if (!confirmed.isMine) return mergeMessages(messages, [confirmed]);\n\n const pendingIdx = messages.findIndex(\n (m) =>\n m.sendState === 'sending' &&\n m.isMine &&\n m.body === confirmed.body &&\n // Same author, not merely both \"mine\" - guards the same collision\n // when authorId is populated on both sides.\n (!m.authorId || !confirmed.authorId || m.authorId === confirmed.authorId) &&\n Math.abs(m.createdAt - confirmed.createdAt) <= windowMs,\n );\n if (pendingIdx === -1) return mergeMessages(messages, [confirmed]);\n\n const next = messages.slice();\n next[pendingIdx] = { ...confirmed, sendState: 'sent', replacedClientId: messages[pendingIdx].id };\n // Still merge: the same id may already be present from a concurrent refetch.\n return mergeMessages(\n next.filter((m) => m.id !== confirmed.id || m.replacedClientId),\n [next[pendingIdx]],\n );\n}\n\n/**\n * The other participant in a DM.\n *\n * Falls back to null rather than to the viewer: a conversation labelled with\n * your own name is a bug users notice immediately, and every DM the viewer\n * created before members were populated would hit it.\n */\nexport function peerOf(channel: WireChannel, viewerId: string): ChatUser | null {\n const members = (channel.members ?? []).filter(Boolean) as WireChannelMember[];\n const other = members.find((m) => m.user?.id && String(m.user.id) !== viewerId);\n return other?.user ?? null;\n}\n\n/**\n * How many messages the viewer has not read.\n *\n * `member.msgCount` is the count the member has SEEN, so unread is the channel\n * total minus that - clamped at zero because the two counters are updated on\n * different write paths and briefly disagree.\n */\nexport function unreadOf(channel: WireChannel, viewerId: string): number {\n const mine = (channel.members ?? []).find((m) => m?.user?.id && String(m.user.id) === viewerId);\n if (!mine) return 0;\n const total = channel.totalMsgCount ?? 0;\n const seen = mine.msgCount ?? 0;\n return Math.max(0, total - seen);\n}\n\nconst DIRECT_TYPES = new Set(['DIRECT', 'Direct', 'direct']);\n\nfunction looksLikeMachineTitle(value?: string | null): boolean {\n const label = value?.trim() ?? '';\n if (!label) return true;\n if (/^chat[\\s_-]*channel\\b/i.test(label) || /^chat-channel-/i.test(label)) return true;\n if (/^[a-f0-9]{8,}$/i.test(label)) return true;\n if (label.includes('__')) return true;\n if (/^group(\\s+chat)?$/i.test(label)) return true;\n return false;\n}\n\nexport function toConversation(channel: WireChannel, viewerId: string): ChatConversation {\n const peerCandidate = peerOf(channel, viewerId);\n const explicitDirect = DIRECT_TYPES.has(String(channel.type ?? ''));\n const populatedMembers = (channel.members ?? []).filter(Boolean);\n const twoParty = populatedMembers.length === 2 && Boolean(peerCandidate);\n const hasMachineLabel = looksLikeMachineTitle(channel.displayName) && looksLikeMachineTitle(channel.title);\n const isDirect = explicitDirect || twoParty || (!channel.type && hasMachineLabel && Boolean(peerCandidate));\n const peer = isDirect ? peerCandidate : null;\n\n const names = memberNames(channel, viewerId);\n const lastAuthor = channel.lastMessage ? pickAuthor(channel.lastMessage) : null;\n const lastAuthorName = lastAuthor && String(lastAuthor.id) !== viewerId ? displayNameOf(lastAuthor, '') : '';\n const creatorName = displayNameOf(channel.creator, '');\n const groupFallback = names.length\n ? names.join(', ')\n : lastAuthorName || (creatorName && creatorName !== 'Unknown' ? creatorName : 'Chat');\n const storedLabel = !looksLikeMachineTitle(channel.displayName)\n ? channel.displayName!.trim()\n : !looksLikeMachineTitle(channel.title)\n ? channel.title!.trim()\n : '';\n const title = isDirect\n ? displayNameOf(peer, storedLabel || lastAuthorName || 'Direct message')\n : storedLabel || groupFallback;\n const topic = looksLikeMachineTitle(channel.topic) ? '' : (channel.topic ?? '').trim();\n const preview = channel.lastMessage?.message?.trim() || topic;\n\n return {\n id: String(channel.id),\n title,\n subtitle: preview === title ? '' : preview,\n avatarUrl:\n peer?.picture ??\n peer?.profile?.picture ??\n channel.members?.find((member) => member?.user?.picture)?.user?.picture ??\n lastAuthor?.picture ??\n lastAuthor?.profile?.picture ??\n null,\n lastActivity: toEpoch(channel.lastPostAt) || toEpoch(channel.createdAt),\n unreadCount: unreadOf(channel, viewerId),\n isDirect,\n peer,\n };\n}\n\n/**\n * Conversation list order: most recent first, then title, then id.\n *\n * The trailing keys matter more than they look. A channel with no messages has\n * `lastActivity === 0`, so a fresh account is entirely ties; without a stable\n * tiebreak the list reshuffles on every poll.\n */\nexport function sortConversations(list: ChatConversation[]): ChatConversation[] {\n return list\n .slice()\n .sort(\n (a, b) =>\n b.lastActivity - a.lastActivity ||\n a.title.localeCompare(b.title) ||\n (a.id < b.id ? -1 : a.id > b.id ? 1 : 0),\n );\n}\n\n/** Stable key for collapsing duplicate list rows (same person, multiple channel ids). */\nexport function conversationListKey(c: ChatConversation): string {\n if (c.peer?.id) return `peer:${String(c.peer.id)}`;\n const title = c.title.trim().toLowerCase();\n if (!title || title === 'chat' || title === 'unknown') return `id:${c.id}`;\n // Multi-person groups use comma-separated titles; keep those distinct.\n if (title.includes(',')) return `id:${c.id}`;\n if (c.isDirect) return `title:${title}`;\n // Server often returns duplicate 1:1 channels as untyped GROUP rows with the peer's name.\n return `title:${title}`;\n}\n\n/** Newest row wins per list key. */\nexport function dedupeConversationList(list: ChatConversation[]): ChatConversation[] {\n const sorted = sortConversations(list);\n const seen = new Set<string>();\n const out: ChatConversation[] = [];\n for (const c of sorted) {\n const key = conversationListKey(c);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(c);\n }\n return out;\n}\n\n/** @deprecated Use dedupeConversationList */\nexport function dedupeDirectConversations(list: ChatConversation[]): ChatConversation[] {\n return dedupeConversationList(list);\n}\n\nexport function mergeConversations(existing: ChatConversation[], incoming: ChatConversation[]): ChatConversation[] {\n const byId = new Map<string, ChatConversation>();\n for (const c of existing) byId.set(c.id, c);\n for (const c of incoming) byId.set(c.id, c);\n return dedupeConversationList(Array.from(byId.values()));\n}\n\n/** Refresh preview + sort key when a new post lands (send echo or subscription). */\nexport function patchConversationAfterPost(conv: ChatConversation, post: WirePost, viewerId: string): ChatConversation {\n const preview = post.message?.trim();\n const nextSubtitle = preview == null || preview === '' ? conv.subtitle : preview === conv.title ? '' : preview;\n const activity = toEpoch(post.createdAt) || Date.now();\n const author = pickAuthor(post);\n const fromPeer = author && String(author.id) !== viewerId;\n return {\n ...conv,\n subtitle: nextSubtitle,\n lastActivity: activity,\n unreadCount: fromPeer ? conv.unreadCount + 1 : conv.unreadCount,\n };\n}\n\n/**\n * Day separators, computed against a caller-supplied \"now\".\n *\n * The clock is a parameter so this is testable and so a device with a skewed\n * clock does not silently label everything \"Today\".\n */\nexport function dayLabel(epoch: number, now: number): string {\n if (!epoch) return '';\n const d = new Date(epoch);\n const n = new Date(now);\n const sameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n if (sameDay(d, n)) return 'Today';\n const yesterday = new Date(now);\n yesterday.setDate(yesterday.getDate() - 1);\n if (sameDay(d, yesterday)) return 'Yesterday';\n return d.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n year: d.getFullYear() === n.getFullYear() ? undefined : 'numeric',\n });\n}\n\n/** Short clock label for a bubble. */\nexport function timeLabel(epoch: number): string {\n if (!epoch) return '';\n return new Date(epoch).toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n}\n\n/** Relative age for the conversation list. */\nexport function relativeLabel(epoch: number, now: number): string {\n if (!epoch) return '';\n const diff = now - epoch;\n if (diff < 60_000) return 'now';\n if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m`;\n const d = new Date(epoch);\n const n = new Date(now);\n if (d.getFullYear() === n.getFullYear() && d.getMonth() === n.getMonth() && d.getDate() === n.getDate()) {\n return timeLabel(epoch);\n }\n if (diff < 7 * 86_400_000) return d.toLocaleDateString(undefined, { weekday: 'short' });\n return d.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' });\n}\n\n/** Initials for the avatar fallback; never more than two glyphs. */\nexport function initialsOf(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (!parts.length) return '?';\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n}\n"],"names":["_a"],"mappings":"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"}
@@ -1,3 +1,99 @@
1
+ const POST_FIELDS = `
2
+ id
3
+ message
4
+ type
5
+ createdAt
6
+ updatedAt
7
+ editedAt
8
+ deletedAt
9
+ rootId
10
+ parentId
11
+ filenames
12
+ props
13
+ author { id givenName familyName username email picture }
14
+ creator { id givenName familyName username email picture }
15
+ reactionSummary { reaction count userIds }
16
+ `;
17
+ const CHANNEL_FIELDS = `
18
+ id
19
+ type
20
+ orgName
21
+ title
22
+ displayName
23
+ topic
24
+ lastPostAt
25
+ totalMsgCount
26
+ createdAt
27
+ lastMessage { ${POST_FIELDS} }
28
+ creator { id givenName familyName username email picture }
29
+ members { id user { id givenName familyName username email picture } msgCount lastViewedAt }
30
+ `;
31
+ const CHANNELS_QUERY = `
32
+ query ChatChannels($limit: Int, $skip: Int, $criteria: AnyObject, $sort: Sort) {
33
+ channelsByUser(limit: $limit, skip: $skip, criteria: $criteria, sort: $sort) {
34
+ ${CHANNEL_FIELDS}
35
+ }
36
+ }
37
+ `;
38
+ const MESSAGES_QUERY = `
39
+ query ChatMessages($channelId: ID, $limit: Int! = 30, $skip: Int! = 0, $sort: Sort) {
40
+ messages(channelId: $channelId, limit: $limit, skip: $skip, sort: $sort) {
41
+ totalCount
42
+ data {
43
+ ${POST_FIELDS}
44
+ }
45
+ }
46
+ }
47
+ `;
48
+ const SEND_MESSAGE_MUTATION = `
49
+ mutation ChatSendMessage($channelId: String!, $messageInput: MessageInput!) {
50
+ sendMessage(channelId: $channelId, messageInput: $messageInput) {
51
+ ${POST_FIELDS}
52
+ }
53
+ }
54
+ `;
55
+ const VIEW_CHANNEL_MUTATION = `
56
+ mutation ChatViewChannel($id: ID!) {
57
+ viewChannel(id: $id)
58
+ }
59
+ `;
60
+ const CREATE_DIRECT_CHANNEL_MUTATION = `
61
+ mutation ChatCreateDirectChannel($receiver: [ID]!, $displayName: String!) {
62
+ createDirectChannel(receiver: $receiver, displayName: $displayName) {
63
+ ${CHANNEL_FIELDS}
64
+ }
65
+ }
66
+ `;
67
+ const MESSAGE_ADDED_SUBSCRIPTION_WS = `
68
+ subscription ChatMessageAdded_WS($channelId: String) {
69
+ chatMessageAdded(channelId: $channelId) {
70
+ ${POST_FIELDS}
71
+ }
72
+ }
73
+ `;
74
+ const SET_MESSAGE_REACTION_MUTATION = `
75
+ mutation ChatSetMessageReaction($channelId: String!, $postId: ID!, $reaction: String) {
76
+ setMessageReaction(channelId: $channelId, postId: $postId, reaction: $reaction) {
77
+ reaction
78
+ count
79
+ userIds
80
+ }
81
+ }
82
+ `;
83
+ const REACTION_CHANGED_SUBSCRIPTION_WS = `
84
+ subscription ChatReactionChanged_WS($channelId: String!) {
85
+ chatReactionChanged(channelId: $channelId) {
86
+ channelId
87
+ postId
88
+ reactions { reaction count userIds }
89
+ }
90
+ }
91
+ `;
92
+ const CONTACT_MATCHES_QUERY = `
93
+ query ChatContactMatches($phoneHashes: [String!]!) {
94
+ chatContactMatches(phoneHashes: $phoneHashes)
95
+ }
96
+ `;
1
97
  const YANTRA_CHAT_REGISTRATION_STATUS_QUERY = `
2
98
  query YantraChatRegistrationStatus {
3
99
  yantraChatRegistrationStatus {
@@ -17,4 +113,13 @@ const REGISTER_YANTRA_CHAT_MEMBER_MUTATION = `
17
113
  organizationId
18
114
  }
19
115
  }
20
- `;export{REGISTER_YANTRA_CHAT_MEMBER_MUTATION,YANTRA_CHAT_REGISTRATION_STATUS_QUERY};//# sourceMappingURL=chatOperations.js.map
116
+ `;
117
+ const YANTRA_CHAT_INVITER_QUERY = `
118
+ query YantraChatInviter($userId: String!) {
119
+ yantraChatInviter(userId: $userId) {
120
+ userId
121
+ displayName
122
+ avatarUrl
123
+ }
124
+ }
125
+ `;export{CHANNELS_QUERY,CONTACT_MATCHES_QUERY,CREATE_DIRECT_CHANNEL_MUTATION,MESSAGES_QUERY,MESSAGE_ADDED_SUBSCRIPTION_WS,POST_FIELDS,REACTION_CHANGED_SUBSCRIPTION_WS,REGISTER_YANTRA_CHAT_MEMBER_MUTATION,SEND_MESSAGE_MUTATION,SET_MESSAGE_REACTION_MUTATION,VIEW_CHANNEL_MUTATION,YANTRA_CHAT_INVITER_QUERY,YANTRA_CHAT_REGISTRATION_STATUS_QUERY};//# sourceMappingURL=chatOperations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chatOperations.js","sources":["../../../src/features/messaging/chatOperations.ts"],"sourcesContent":["/**\n * Every GraphQL operation the chat remote sends, as plain strings.\n *\n * Strings, not `gql` documents, because the remote must not import\n * @apollo/client or graphql - the host parses and executes these on the app's\n * own client (see `ChatGraphQLSeam`). The upside beyond bundle size is that the\n * QUERY SHAPE ships over the air: a missing field or a wrong argument is a\n * surface deploy, not an App Store release.\n *\n * HARD REQUIREMENT - every operation is NAMED, and every subscription's name\n * ends in `_WS`. `portable-devices/mobile/src/config/base-apollo-client.ts`\n * routes ws-vs-http with `operationName.endsWith('_WS')`; an anonymous\n * operation makes that `undefined.endsWith(...)`, which throws for EVERY\n * operation the app sends, not just this one. `chatOperations.test.ts` asserts\n * both properties over every export in this file, so a new operation cannot\n * quietly break the app's transport.\n */\n\n/**\n * Shared field set for a message.\n *\n * `author` and `creator` are both selected on purpose: messenger-box populates\n * `author` on some write paths and `creator` on others (`sendMessage` sets\n * creator), and a transcript that reads only one shows \"Unknown\" for half the\n * messages. `chatModel.pickAuthor` collapses them.\n */\nexport const POST_FIELDS = `\n id\n message\n type\n createdAt\n updatedAt\n editedAt\n deletedAt\n rootId\n parentId\n filenames\n props\n author { id givenName familyName username email picture }\n creator { id givenName familyName username email picture }\n reactionSummary { reaction count userIds }\n`;\n\nconst CHANNEL_FIELDS = `\n id\n type\n orgName\n title\n displayName\n topic\n lastPostAt\n totalMsgCount\n createdAt\n lastMessage { ${POST_FIELDS} }\n creator { id givenName familyName username email picture }\n members { id user { id givenName familyName username email picture } msgCount lastViewedAt }\n`;\n\n/**\n * The conversation list.\n *\n * `criteria.members.$elemMatch.user` is NOT sent: the server derives membership\n * from the session (`accountId`) and a client-supplied member filter is exactly\n * the kind of thing that lets a caller read someone else's list. Org scoping is\n * likewise server-side now (`channelOrgScope`). Native Messages passes\n * `criteria: { type: DIRECT, orgName: yantra-chat }` via `nativeChatChannelQuery`.\n */\nexport const CHANNELS_QUERY = `\n query ChatChannels($limit: Int, $skip: Int, $criteria: AnyObject, $sort: Sort) {\n channelsByUser(limit: $limit, skip: $skip, criteria: $criteria, sort: $sort) {\n ${CHANNEL_FIELDS}\n }\n }\n`;\n\n/**\n * One page of a transcript, newest first.\n *\n * Paged with `skip`, which is what the server exposes. That is offset paging and\n * it can repeat or drop a row if messages arrive mid-scroll; `chatModel.mergePosts`\n * de-duplicates by id so the visible effect is bounded. A cursor (`before: id`)\n * would be strictly better and is worth adding server-side later.\n */\nexport const MESSAGES_QUERY = `\n query ChatMessages($channelId: ID, $limit: Int! = 30, $skip: Int! = 0, $sort: Sort) {\n messages(channelId: $channelId, limit: $limit, skip: $skip, sort: $sort) {\n totalCount\n data {\n ${POST_FIELDS}\n }\n }\n }\n`;\n\nexport const SEND_MESSAGE_MUTATION = `\n mutation ChatSendMessage($channelId: String!, $messageInput: MessageInput!) {\n sendMessage(channelId: $channelId, messageInput: $messageInput) {\n ${POST_FIELDS}\n }\n }\n`;\n\n/** Marks the channel read for the caller; drives the unread badge to zero. */\nexport const VIEW_CHANNEL_MUTATION = `\n mutation ChatViewChannel($id: ID!) {\n viewChannel(id: $id)\n }\n`;\n\n/**\n * Opens (or returns) the 1:1 conversation with `receiver`.\n *\n * Idempotent server-side: an existing DM for the pair comes back rather than a\n * duplicate, so the UI can call this every time someone taps a contact without\n * checking first.\n */\nexport const CREATE_DIRECT_CHANNEL_MUTATION = `\n mutation ChatCreateDirectChannel($receiver: [ID]!, $displayName: String!) {\n createDirectChannel(receiver: $receiver, displayName: $displayName) {\n ${CHANNEL_FIELDS}\n }\n }\n`;\n\n/**\n * Live messages for one channel.\n *\n * `_WS` suffix is load-bearing - see the file header. `directTo` is left unset:\n * the server treats it as a second, user-scoped topic and passing the wrong one\n * silently delivers nothing.\n */\nexport const MESSAGE_ADDED_SUBSCRIPTION_WS = `\n subscription ChatMessageAdded_WS($channelId: String) {\n chatMessageAdded(channelId: $channelId) {\n ${POST_FIELDS}\n }\n }\n`;\n\n/**\n * Set the viewer's single Tapback on a message; `reaction: null` removes it.\n * Returns the message's reactions after the change.\n */\nexport const SET_MESSAGE_REACTION_MUTATION = `\n mutation ChatSetMessageReaction($channelId: String!, $postId: ID!, $reaction: String) {\n setMessageReaction(channelId: $channelId, postId: $postId, reaction: $reaction) {\n reaction\n count\n userIds\n }\n }\n`;\n\n/** Live reaction changes for one channel. `_WS` suffix is load-bearing - see the file header. */\nexport const REACTION_CHANGED_SUBSCRIPTION_WS = `\n subscription ChatReactionChanged_WS($channelId: String!) {\n chatReactionChanged(channelId: $channelId) {\n channelId\n postId\n reactions { reaction count userIds }\n }\n }\n`;\n\n/**\n * Which of these phone numbers already have an account.\n *\n * Sends SHA-256 hashes of E.164 numbers, never the numbers - the server never\n * receives a plaintext address book. Returns AnyObject: a list of\n * `{phoneHash, userId, username, displayName, picture}`.\n */\nexport const CONTACT_MATCHES_QUERY = `\n query ChatContactMatches($phoneHashes: [String!]!) {\n chatContactMatches(phoneHashes: $phoneHashes)\n }\n`;\n\nexport const YANTRA_CHAT_REGISTRATION_STATUS_QUERY = `\n query YantraChatRegistrationStatus {\n yantraChatRegistrationStatus {\n registered\n phoneE164\n memberId\n organizationId\n }\n }\n`;\n\nexport const REGISTER_YANTRA_CHAT_MEMBER_MUTATION = `\n mutation RegisterYantraChatMember($phoneE164: String!, $displayName: String) {\n registerYantraChatMember(phoneE164: $phoneE164, displayName: $displayName) {\n registered\n phoneE164\n memberId\n organizationId\n }\n }\n`;\n\nexport const MATCH_YANTRA_CHAT_MEMBERS_QUERY = `\n query MatchYantraChatMembersByPhone($phones: [String!]!, $viewerPhoneE164: String) {\n matchYantraChatMembersByPhone(phones: $phones, viewerPhoneE164: $viewerPhoneE164) {\n phoneE164\n userId\n displayName\n avatarUrl\n }\n }\n`;\n\nexport const YANTRA_CHAT_MEMBERS_QUERY = `\n query YantraChatMembers {\n yantraChatMembers {\n phoneE164\n userId\n displayName\n avatarUrl\n }\n }\n`;\n\n/** Composer draft persistence, server-side and per (member, channel). */\nexport const SET_DRAFT_MUTATION = `\n mutation ChatSetDraft($channelId: ID!, $text: String!) {\n setChannelDraft(channelId: $channelId, text: $text)\n }\n`;\n\nexport const DRAFT_QUERY = `\n query ChatDraft($channelId: ID!) {\n channelDraft(channelId: $channelId)\n }\n`;\n\n/** Every operation, for the contract test and for host-side preflight. */\nexport const CHAT_OPERATIONS: Readonly<Record<string, string>> = Object.freeze({\n CHANNELS_QUERY,\n CONTACT_MATCHES_QUERY,\n YANTRA_CHAT_REGISTRATION_STATUS_QUERY,\n REGISTER_YANTRA_CHAT_MEMBER_MUTATION,\n MATCH_YANTRA_CHAT_MEMBERS_QUERY,\n YANTRA_CHAT_MEMBERS_QUERY,\n MESSAGES_QUERY,\n SEND_MESSAGE_MUTATION,\n VIEW_CHANNEL_MUTATION,\n CREATE_DIRECT_CHANNEL_MUTATION,\n MESSAGE_ADDED_SUBSCRIPTION_WS,\n SET_MESSAGE_REACTION_MUTATION,\n REACTION_CHANGED_SUBSCRIPTION_WS,\n SET_DRAFT_MUTATION,\n DRAFT_QUERY,\n});\n\n/**\n * The operation name inside a document string.\n *\n * Used by the contract test and by the host seam for logging. Intentionally a\n * regex rather than a parse: pulling in `graphql` to read a name would defeat\n * the whole point of shipping strings.\n */\nexport function operationNameOf(document: string): string | null {\n const match = /\\b(?:query|mutation|subscription)\\s+([A-Za-z_][A-Za-z0-9_]*)/.exec(document);\n return match ? match[1] : null;\n}\n\nexport function operationTypeOf(document: string): 'query' | 'mutation' | 'subscription' | null {\n const match = /\\b(query|mutation|subscription)\\s+[A-Za-z_]/.exec(document);\n return match ? (match[1] as 'query' | 'mutation' | 'subscription') : null;\n}\n"],"names":[],"mappings":"AA8KO,MAAM,qCAAwC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU9C,MAAM,oCAAuC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA"}
1
+ {"version":3,"file":"chatOperations.js","sources":["../../../src/features/messaging/chatOperations.ts"],"sourcesContent":["/**\n * Every GraphQL operation the chat remote sends, as plain strings.\n *\n * Strings, not `gql` documents, because the remote must not import\n * @apollo/client or graphql - the host parses and executes these on the app's\n * own client (see `ChatGraphQLSeam`). The upside beyond bundle size is that the\n * QUERY SHAPE ships over the air: a missing field or a wrong argument is a\n * surface deploy, not an App Store release.\n *\n * HARD REQUIREMENT - every operation is NAMED, and every subscription's name\n * ends in `_WS`. `portable-devices/mobile/src/config/base-apollo-client.ts`\n * routes ws-vs-http with `operationName.endsWith('_WS')`; an anonymous\n * operation makes that `undefined.endsWith(...)`, which throws for EVERY\n * operation the app sends, not just this one. `chatOperations.test.ts` asserts\n * both properties over every export in this file, so a new operation cannot\n * quietly break the app's transport.\n */\n\n/**\n * Shared field set for a message.\n *\n * `author` and `creator` are both selected on purpose: messenger-box populates\n * `author` on some write paths and `creator` on others (`sendMessage` sets\n * creator), and a transcript that reads only one shows \"Unknown\" for half the\n * messages. `chatModel.pickAuthor` collapses them.\n */\nexport const POST_FIELDS = `\n id\n message\n type\n createdAt\n updatedAt\n editedAt\n deletedAt\n rootId\n parentId\n filenames\n props\n author { id givenName familyName username email picture }\n creator { id givenName familyName username email picture }\n reactionSummary { reaction count userIds }\n`;\n\nconst CHANNEL_FIELDS = `\n id\n type\n orgName\n title\n displayName\n topic\n lastPostAt\n totalMsgCount\n createdAt\n lastMessage { ${POST_FIELDS} }\n creator { id givenName familyName username email picture }\n members { id user { id givenName familyName username email picture } msgCount lastViewedAt }\n`;\n\n/**\n * The conversation list.\n *\n * `criteria.members.$elemMatch.user` is NOT sent: the server derives membership\n * from the session (`accountId`) and a client-supplied member filter is exactly\n * the kind of thing that lets a caller read someone else's list. Org scoping is\n * likewise server-side now (`channelOrgScope`). Native Messages passes\n * `criteria: { type: DIRECT, orgName: yantra-chat }` via `nativeChatChannelQuery`.\n */\nexport const CHANNELS_QUERY = `\n query ChatChannels($limit: Int, $skip: Int, $criteria: AnyObject, $sort: Sort) {\n channelsByUser(limit: $limit, skip: $skip, criteria: $criteria, sort: $sort) {\n ${CHANNEL_FIELDS}\n }\n }\n`;\n\n/**\n * One page of a transcript, newest first.\n *\n * Paged with `skip`, which is what the server exposes. That is offset paging and\n * it can repeat or drop a row if messages arrive mid-scroll; `chatModel.mergePosts`\n * de-duplicates by id so the visible effect is bounded. A cursor (`before: id`)\n * would be strictly better and is worth adding server-side later.\n */\nexport const MESSAGES_QUERY = `\n query ChatMessages($channelId: ID, $limit: Int! = 30, $skip: Int! = 0, $sort: Sort) {\n messages(channelId: $channelId, limit: $limit, skip: $skip, sort: $sort) {\n totalCount\n data {\n ${POST_FIELDS}\n }\n }\n }\n`;\n\nexport const SEND_MESSAGE_MUTATION = `\n mutation ChatSendMessage($channelId: String!, $messageInput: MessageInput!) {\n sendMessage(channelId: $channelId, messageInput: $messageInput) {\n ${POST_FIELDS}\n }\n }\n`;\n\n/** Marks the channel read for the caller; drives the unread badge to zero. */\nexport const VIEW_CHANNEL_MUTATION = `\n mutation ChatViewChannel($id: ID!) {\n viewChannel(id: $id)\n }\n`;\n\n/**\n * Opens (or returns) the 1:1 conversation with `receiver`.\n *\n * Idempotent server-side: an existing DM for the pair comes back rather than a\n * duplicate, so the UI can call this every time someone taps a contact without\n * checking first.\n */\nexport const CREATE_DIRECT_CHANNEL_MUTATION = `\n mutation ChatCreateDirectChannel($receiver: [ID]!, $displayName: String!) {\n createDirectChannel(receiver: $receiver, displayName: $displayName) {\n ${CHANNEL_FIELDS}\n }\n }\n`;\n\n/**\n * Live messages for one channel.\n *\n * `_WS` suffix is load-bearing - see the file header. `directTo` is left unset:\n * the server treats it as a second, user-scoped topic and passing the wrong one\n * silently delivers nothing.\n */\nexport const MESSAGE_ADDED_SUBSCRIPTION_WS = `\n subscription ChatMessageAdded_WS($channelId: String) {\n chatMessageAdded(channelId: $channelId) {\n ${POST_FIELDS}\n }\n }\n`;\n\n/**\n * Set the viewer's single Tapback on a message; `reaction: null` removes it.\n * Returns the message's reactions after the change.\n */\nexport const SET_MESSAGE_REACTION_MUTATION = `\n mutation ChatSetMessageReaction($channelId: String!, $postId: ID!, $reaction: String) {\n setMessageReaction(channelId: $channelId, postId: $postId, reaction: $reaction) {\n reaction\n count\n userIds\n }\n }\n`;\n\n/** Live reaction changes for one channel. `_WS` suffix is load-bearing - see the file header. */\nexport const REACTION_CHANGED_SUBSCRIPTION_WS = `\n subscription ChatReactionChanged_WS($channelId: String!) {\n chatReactionChanged(channelId: $channelId) {\n channelId\n postId\n reactions { reaction count userIds }\n }\n }\n`;\n\n/**\n * Which of these phone numbers already have an account.\n *\n * Sends SHA-256 hashes of E.164 numbers, never the numbers - the server never\n * receives a plaintext address book. Returns AnyObject: a list of\n * `{phoneHash, userId, username, displayName, picture}`.\n */\nexport const CONTACT_MATCHES_QUERY = `\n query ChatContactMatches($phoneHashes: [String!]!) {\n chatContactMatches(phoneHashes: $phoneHashes)\n }\n`;\n\nexport const YANTRA_CHAT_REGISTRATION_STATUS_QUERY = `\n query YantraChatRegistrationStatus {\n yantraChatRegistrationStatus {\n registered\n phoneE164\n memberId\n organizationId\n }\n }\n`;\n\nexport const REGISTER_YANTRA_CHAT_MEMBER_MUTATION = `\n mutation RegisterYantraChatMember($phoneE164: String!, $displayName: String) {\n registerYantraChatMember(phoneE164: $phoneE164, displayName: $displayName) {\n registered\n phoneE164\n memberId\n organizationId\n }\n }\n`;\n\nexport const MATCH_YANTRA_CHAT_MEMBERS_QUERY = `\n query MatchYantraChatMembersByPhone($phones: [String!]!, $viewerPhoneE164: String) {\n matchYantraChatMembersByPhone(phones: $phones, viewerPhoneE164: $viewerPhoneE164) {\n phoneE164\n userId\n displayName\n avatarUrl\n }\n }\n`;\n\nexport const YANTRA_CHAT_MEMBERS_QUERY = `\n query YantraChatMembers {\n yantraChatMembers {\n phoneE164\n userId\n displayName\n avatarUrl\n }\n }\n`;\n\n/**\n * The sender of a chat invite link, as the server knows them. The link's own `n=` name\n * is editable by anyone, so the conversation is opened with this name, and only when\n * the id belongs to a registered member (null otherwise).\n */\nexport const YANTRA_CHAT_INVITER_QUERY = `\n query YantraChatInviter($userId: String!) {\n yantraChatInviter(userId: $userId) {\n userId\n displayName\n avatarUrl\n }\n }\n`;\n\n/** Composer draft persistence, server-side and per (member, channel). */\nexport const SET_DRAFT_MUTATION = `\n mutation ChatSetDraft($channelId: ID!, $text: String!) {\n setChannelDraft(channelId: $channelId, text: $text)\n }\n`;\n\nexport const DRAFT_QUERY = `\n query ChatDraft($channelId: ID!) {\n channelDraft(channelId: $channelId)\n }\n`;\n\n/** Every operation, for the contract test and for host-side preflight. */\nexport const CHAT_OPERATIONS: Readonly<Record<string, string>> = Object.freeze({\n CHANNELS_QUERY,\n CONTACT_MATCHES_QUERY,\n YANTRA_CHAT_REGISTRATION_STATUS_QUERY,\n REGISTER_YANTRA_CHAT_MEMBER_MUTATION,\n MATCH_YANTRA_CHAT_MEMBERS_QUERY,\n YANTRA_CHAT_MEMBERS_QUERY,\n YANTRA_CHAT_INVITER_QUERY,\n MESSAGES_QUERY,\n SEND_MESSAGE_MUTATION,\n VIEW_CHANNEL_MUTATION,\n CREATE_DIRECT_CHANNEL_MUTATION,\n MESSAGE_ADDED_SUBSCRIPTION_WS,\n SET_MESSAGE_REACTION_MUTATION,\n REACTION_CHANGED_SUBSCRIPTION_WS,\n SET_DRAFT_MUTATION,\n DRAFT_QUERY,\n});\n\n/**\n * The operation name inside a document string.\n *\n * Used by the contract test and by the host seam for logging. Intentionally a\n * regex rather than a parse: pulling in `graphql` to read a name would defeat\n * the whole point of shipping strings.\n */\nexport function operationNameOf(document: string): string | null {\n const match = /\\b(?:query|mutation|subscription)\\s+([A-Za-z_][A-Za-z0-9_]*)/.exec(document);\n return match ? match[1] : null;\n}\n\nexport function operationTypeOf(document: string): 'query' | 'mutation' | 'subscription' | null {\n const match = /\\b(query|mutation|subscription)\\s+[A-Za-z_]/.exec(document);\n return match ? (match[1] as 'query' | 'mutation' | 'subscription') : null;\n}\n"],"names":[],"mappings":"AA0BO,MAAM,WAAc,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgB3B,MAAM,cAAiB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAA,EAUH,WAAW,CAAA;AAAA;AAAA;AAAA,CAAA;AAcxB,MAAM,cAAiB,GAAA;AAAA;AAAA;AAAA,YAAA,EAGhB,cAAc;AAAA;AAAA;AAAA;AAarB,MAAM,cAAiB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAA,EAKZ,WAAW;AAAA;AAAA;AAAA;AAAA;AAKtB,MAAM,qBAAwB,GAAA;AAAA;AAAA;AAAA,YAAA,EAGvB,WAAW;AAAA;AAAA;AAAA;AAMlB,MAAM,qBAAwB,GAAA;AAAA;AAAA;AAAA;AAAA;AAa9B,MAAM,8BAAiC,GAAA;AAAA;AAAA;AAAA,YAAA,EAGhC,cAAc;AAAA;AAAA;AAAA;AAYrB,MAAM,6BAAgC,GAAA;AAAA;AAAA;AAAA,YAAA,EAG/B,WAAW;AAAA;AAAA;AAAA;AASlB,MAAM,6BAAgC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWtC,MAAM,gCAAmC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBzC,MAAM,qBAAwB,GAAA;AAAA;AAAA;AAAA;AAAA;AAK9B,MAAM,qCAAwC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU9C,MAAM,oCAAuC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoC7C,MAAM,yBAA4B,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA"}
@@ -0,0 +1,60 @@
1
+ import {EMOJI_KEYWORDS_SOURCE}from'./emojiKeywords.js';const list = (s) => Array.from(s.replace(/\s+/g, " ").trim().split(" "));
2
+ const EMOJI_CATEGORIES = [{
3
+ key: "smileys",
4
+ title: "Smileys & People",
5
+ emojis: list(`\u{1F600} \u{1F603} \u{1F604} \u{1F601} \u{1F606} \u{1F605} \u{1F923} \u{1F602} \u{1F642} \u{1F643} \u{1F609} \u{1F60A} \u{1F607} \u{1F970} \u{1F60D} \u{1F929} \u{1F618} \u{1F617} \u{1F61A} \u{1F619} \u{1F972} \u{1F60B} \u{1F61B} \u{1F61C} \u{1F92A} \u{1F61D} \u{1F911} \u{1F917} \u{1F92D} \u{1F92B} \u{1F914} \u{1F910} \u{1F928} \u{1F610} \u{1F611} \u{1F636} \u{1F60F} \u{1F612} \u{1F644} \u{1F62C} \u{1F62E}\u200D\u{1F4A8} \u{1F925} \u{1F60C} \u{1F614} \u{1F62A} \u{1F924} \u{1F634} \u{1F637} \u{1F912} \u{1F915} \u{1F922} \u{1F92E} \u{1F975} \u{1F976} \u{1F974} \u{1F635} \u{1F92F} \u{1F920} \u{1F973} \u{1F978} \u{1F60E} \u{1F913} \u{1F9D0} \u{1F615} \u{1F61F} \u{1F641} \u{1F62E} \u{1F62F} \u{1F632} \u{1F633} \u{1F97A} \u{1F626} \u{1F627} \u{1F628} \u{1F630} \u{1F625} \u{1F622} \u{1F62D} \u{1F631} \u{1F616} \u{1F623} \u{1F61E} \u{1F613} \u{1F629} \u{1F62B} \u{1F971} \u{1F624} \u{1F621} \u{1F620} \u{1F92C} \u{1F608} \u{1F47F} \u{1F480} \u{1F4A9} \u{1F921} \u{1F47B} \u{1F47D} \u{1F916} \u{1F63A} \u{1F638} \u{1F639} \u{1F63B} \u{1F63C} \u{1F63D} \u{1F640} \u{1F63F} \u{1F63E}`)
6
+ }, {
7
+ key: "gestures",
8
+ title: "Gestures & Body",
9
+ emojis: list(`\u{1F44B} \u{1F91A} \u{1F590}\uFE0F \u270B \u{1F596} \u{1F44C} \u{1F90C} \u{1F90F} \u270C\uFE0F \u{1F91E} \u{1F91F} \u{1F918} \u{1F919} \u{1F448} \u{1F449} \u{1F446} \u{1F447} \u261D\uFE0F \u{1F44D} \u{1F44E} \u270A \u{1F44A} \u{1F91B} \u{1F91C} \u{1F44F} \u{1F64C} \u{1F450} \u{1F932} \u{1F91D} \u{1F64F} \u270D\uFE0F \u{1F485} \u{1F4AA} \u{1F9BE} \u{1F9E0} \u{1F440} \u{1F441}\uFE0F \u{1F445} \u{1F444} \u{1F48B} \u{1FAF6} \u{1FAE1} \u{1FAE0} \u{1FAE2} \u{1FAE3} \u{1FAE5}`)
10
+ }, {
11
+ key: "hearts",
12
+ title: "Hearts & Symbols",
13
+ emojis: list(`\u2764\uFE0F \u{1F9E1} \u{1F49B} \u{1F49A} \u{1F499} \u{1F49C} \u{1F5A4} \u{1F90D} \u{1F90E} \u{1F494} \u2764\uFE0F\u200D\u{1F525} \u2764\uFE0F\u200D\u{1FA79} \u2763\uFE0F \u{1F495} \u{1F49E} \u{1F493} \u{1F497} \u{1F496} \u{1F498} \u{1F49D} \u{1F4AF} \u{1F4A2} \u{1F4A5} \u{1F4AB} \u{1F4A6} \u{1F4A8} \u{1F573}\uFE0F \u{1F4AC} \u{1F4AD} \u{1F4A4} \u2728 \u2B50 \u{1F31F} \u{1F525} \u26A1 \u203C\uFE0F \u2049\uFE0F \u2753 \u2757 \u2705 \u274C \u2B55 \u{1F6AB} \u{1F4A1} \u{1F3AF} \u{1F514} \u{1F3B5} \u{1F3B6} \u2795 \u2796 \u2714\uFE0F \u{1F197} \u{1F192} \u{1F195} \u{1F51D}`)
14
+ }, {
15
+ key: "animals",
16
+ title: "Animals & Nature",
17
+ emojis: list(`\u{1F436} \u{1F431} \u{1F42D} \u{1F439} \u{1F430} \u{1F98A} \u{1F43B} \u{1F43C} \u{1F428} \u{1F42F} \u{1F981} \u{1F42E} \u{1F437} \u{1F438} \u{1F435} \u{1F648} \u{1F649} \u{1F64A} \u{1F414} \u{1F427} \u{1F426} \u{1F986} \u{1F985} \u{1F989} \u{1F43A} \u{1F434} \u{1F984} \u{1F41D} \u{1F98B} \u{1F40C} \u{1F41E} \u{1F422} \u{1F40D} \u{1F419} \u{1F980} \u{1F420} \u{1F42C} \u{1F433} \u{1F988} \u{1F40A} \u{1F418} \u{1F992} \u{1F42A} \u{1F415} \u{1F408} \u{1F335} \u{1F384} \u{1F332} \u{1F334} \u{1F331} \u{1F340} \u{1F341} \u{1F342} \u{1F337} \u{1F339} \u{1F33A} \u{1F338} \u{1F33C} \u{1F33B} \u{1F31E} \u{1F31D} \u{1F31A} \u{1F319} \u{1F308} \u2600\uFE0F \u26C5 \u2601\uFE0F \u{1F327}\uFE0F \u26C8\uFE0F \u2744\uFE0F \u2603\uFE0F \u{1F30A}`)
18
+ }, {
19
+ key: "food",
20
+ title: "Food & Drink",
21
+ emojis: list(`\u{1F34F} \u{1F34E} \u{1F350} \u{1F34A} \u{1F34B} \u{1F34C} \u{1F349} \u{1F347} \u{1F353} \u{1FAD0} \u{1F352} \u{1F351} \u{1F96D} \u{1F34D} \u{1F965} \u{1F95D} \u{1F345} \u{1F951} \u{1F336}\uFE0F \u{1F33D} \u{1F955} \u{1F954} \u{1F950} \u{1F35E} \u{1F9C0} \u{1F95A} \u{1F373} \u{1F95E} \u{1F953} \u{1F357} \u{1F356} \u{1F32D} \u{1F354} \u{1F35F} \u{1F355} \u{1F96A} \u{1F32E} \u{1F32F} \u{1F957} \u{1F35D} \u{1F35C} \u{1F372} \u{1F35B} \u{1F363} \u{1F371} \u{1F95F} \u{1F364} \u{1F35A} \u{1F366} \u{1F369} \u{1F36A} \u{1F382} \u{1F370} \u{1F9C1} \u{1F36B} \u{1F36C} \u{1F36D} \u{1F37F} \u2615 \u{1F375} \u{1F9C3} \u{1F964} \u{1F9CB} \u{1F37A} \u{1F37B} \u{1F942} \u{1F377} \u{1F378} \u{1F379}`)
22
+ }, {
23
+ key: "activity",
24
+ title: "Activity & Objects",
25
+ emojis: list(`\u26BD \u{1F3C0} \u{1F3C8} \u26BE \u{1F3BE} \u{1F3D0} \u{1F3C9} \u{1F3B1} \u{1F3D3} \u{1F3F8} \u{1F3CF} \u26F3 \u{1F94A} \u{1F3C6} \u{1F947} \u{1F948} \u{1F949} \u{1F3C5} \u{1F396}\uFE0F \u{1F389} \u{1F38A} \u{1F388} \u{1F381} \u{1F380} \u{1F3AE} \u{1F579}\uFE0F \u{1F3B2} \u{1F9E9} \u{1F3A8} \u{1F3AC} \u{1F3A4} \u{1F3A7} \u{1F3B8} \u{1F3B9} \u{1F941} \u{1F4F7} \u{1F4F1} \u{1F4BB} \u2328\uFE0F \u{1F5A5}\uFE0F \u{1F50B} \u{1F4B0} \u{1F4B5} \u{1F4B3} \u{1F4C8} \u{1F4C9} \u{1F4CC} \u{1F4CE} \u270F\uFE0F \u{1F4DD} \u{1F4DA} \u{1F4C5} \u23F0 \u231B \u{1F511} \u{1F512} \u{1F528} \u{1F6E0}\uFE0F \u{1F48A} \u{1F697} \u{1F695} \u{1F68C} \u{1F680} \u2708\uFE0F \u{1F6B2} \u{1F3E0} \u{1F3E2} \u{1F5FA}\uFE0F \u{1F3D6}\uFE0F \u26F0\uFE0F`)
26
+ }, {
27
+ key: "flags",
28
+ title: "Flags",
29
+ emojis: list(`\u{1F3F3}\uFE0F \u{1F3F4} \u{1F3C1} \u{1F6A9} \u{1F3F3}\uFE0F\u200D\u{1F308} \u{1F1EE}\u{1F1F3} \u{1F1FA}\u{1F1F8} \u{1F1EC}\u{1F1E7} \u{1F1E8}\u{1F1E6} \u{1F1E6}\u{1F1FA} \u{1F1E9}\u{1F1EA} \u{1F1EB}\u{1F1F7} \u{1F1EA}\u{1F1F8} \u{1F1EE}\u{1F1F9} \u{1F1EF}\u{1F1F5} \u{1F1F0}\u{1F1F7} \u{1F1E8}\u{1F1F3} \u{1F1E7}\u{1F1F7} \u{1F1F2}\u{1F1FD} \u{1F1E6}\u{1F1EA} \u{1F1F8}\u{1F1E6} \u{1F1F8}\u{1F1EC} \u{1F1F3}\u{1F1FF} \u{1F1FF}\u{1F1E6} \u{1F1F3}\u{1F1EC} \u{1F1F7}\u{1F1FA} \u{1F1F9}\u{1F1F7} \u{1F1F3}\u{1F1F1} \u{1F1F8}\u{1F1EA} \u{1F1E8}\u{1F1ED}`)
30
+ }];
31
+ function emojiFromInput(text) {
32
+ const value = text.trim();
33
+ if (!value || value.length > 16) return null;
34
+ if (/[A-Za-z0-9\s.,;:'"!?@#$%^&*()\-_=+[\]{}<>/\\|`~]/.test(value)) return null;
35
+ return value;
36
+ }
37
+ let emojiIndex = null;
38
+ function getEmojiIndex() {
39
+ if (!emojiIndex) {
40
+ emojiIndex = EMOJI_KEYWORDS_SOURCE.split("\n").map((line) => line.trim().split(" ")).filter((parts) => parts.length > 1).map(([emoji, ...words]) => ({
41
+ emoji,
42
+ words
43
+ }));
44
+ }
45
+ return emojiIndex;
46
+ }
47
+ function searchEmoji(query, limit = 96) {
48
+ const terms = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
49
+ if (!terms.length) return [];
50
+ const named = [];
51
+ const tagged = [];
52
+ for (const {
53
+ emoji,
54
+ words
55
+ } of getEmojiIndex()) {
56
+ if (!terms.every((t) => words.some((w) => w.startsWith(t)))) continue;
57
+ (words[0].startsWith(terms[0]) ? named : tagged).push(emoji);
58
+ }
59
+ return [...named, ...tagged].slice(0, limit);
60
+ }export{EMOJI_CATEGORIES,emojiFromInput,searchEmoji};//# sourceMappingURL=emojiCatalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emojiCatalog.js","sources":["../../../src/features/messaging/emojiCatalog.ts"],"sourcesContent":["import { EMOJI_KEYWORDS_SOURCE } from './emojiKeywords';\n\n/**\n * Emoji grid for the \"+\" Tapback picker. Plain data rather than an emoji\n * package: the remote ships no extra dependencies, and the system emoji\n * keyboard in the picker covers everything not listed here.\n */\nexport interface EmojiCategory {\n key: string;\n title: string;\n emojis: string[];\n}\n\nconst list = (s: string) => Array.from(s.replace(/\\s+/g, ' ').trim().split(' '));\n\nexport const EMOJI_CATEGORIES: EmojiCategory[] = [\n {\n key: 'smileys',\n title: 'Smileys & People',\n emojis: list(\n `๐Ÿ˜€ ๐Ÿ˜ƒ ๐Ÿ˜„ ๐Ÿ˜ ๐Ÿ˜† ๐Ÿ˜… ๐Ÿคฃ ๐Ÿ˜‚ ๐Ÿ™‚ ๐Ÿ™ƒ ๐Ÿ˜‰ ๐Ÿ˜Š ๐Ÿ˜‡ ๐Ÿฅฐ ๐Ÿ˜ ๐Ÿคฉ ๐Ÿ˜˜ ๐Ÿ˜— ๐Ÿ˜š ๐Ÿ˜™ ๐Ÿฅฒ ๐Ÿ˜‹ ๐Ÿ˜› ๐Ÿ˜œ ๐Ÿคช ๐Ÿ˜ ๐Ÿค‘ ๐Ÿค— ๐Ÿคญ ๐Ÿคซ ๐Ÿค” ๐Ÿค ๐Ÿคจ ๐Ÿ˜ ๐Ÿ˜‘ ๐Ÿ˜ถ ๐Ÿ˜ ๐Ÿ˜’ ๐Ÿ™„ ๐Ÿ˜ฌ ๐Ÿ˜ฎโ€๐Ÿ’จ ๐Ÿคฅ ๐Ÿ˜Œ ๐Ÿ˜” ๐Ÿ˜ช ๐Ÿคค ๐Ÿ˜ด ๐Ÿ˜ท ๐Ÿค’ ๐Ÿค• ๐Ÿคข ๐Ÿคฎ ๐Ÿฅต ๐Ÿฅถ ๐Ÿฅด ๐Ÿ˜ต ๐Ÿคฏ ๐Ÿค  ๐Ÿฅณ ๐Ÿฅธ ๐Ÿ˜Ž ๐Ÿค“ ๐Ÿง ๐Ÿ˜• ๐Ÿ˜Ÿ ๐Ÿ™ ๐Ÿ˜ฎ ๐Ÿ˜ฏ ๐Ÿ˜ฒ ๐Ÿ˜ณ ๐Ÿฅบ ๐Ÿ˜ฆ ๐Ÿ˜ง ๐Ÿ˜จ ๐Ÿ˜ฐ ๐Ÿ˜ฅ ๐Ÿ˜ข ๐Ÿ˜ญ ๐Ÿ˜ฑ ๐Ÿ˜– ๐Ÿ˜ฃ ๐Ÿ˜ž ๐Ÿ˜“ ๐Ÿ˜ฉ ๐Ÿ˜ซ ๐Ÿฅฑ ๐Ÿ˜ค ๐Ÿ˜ก ๐Ÿ˜  ๐Ÿคฌ ๐Ÿ˜ˆ ๐Ÿ‘ฟ ๐Ÿ’€ ๐Ÿ’ฉ ๐Ÿคก ๐Ÿ‘ป ๐Ÿ‘ฝ ๐Ÿค– ๐Ÿ˜บ ๐Ÿ˜ธ ๐Ÿ˜น ๐Ÿ˜ป ๐Ÿ˜ผ ๐Ÿ˜ฝ ๐Ÿ™€ ๐Ÿ˜ฟ ๐Ÿ˜พ`,\n ),\n },\n {\n key: 'gestures',\n title: 'Gestures & Body',\n emojis: list(\n `๐Ÿ‘‹ ๐Ÿคš ๐Ÿ–๏ธ โœ‹ ๐Ÿ–– ๐Ÿ‘Œ ๐ŸคŒ ๐Ÿค โœŒ๏ธ ๐Ÿคž ๐ŸคŸ ๐Ÿค˜ ๐Ÿค™ ๐Ÿ‘ˆ ๐Ÿ‘‰ ๐Ÿ‘† ๐Ÿ‘‡ โ˜๏ธ ๐Ÿ‘ ๐Ÿ‘Ž โœŠ ๐Ÿ‘Š ๐Ÿค› ๐Ÿคœ ๐Ÿ‘ ๐Ÿ™Œ ๐Ÿ‘ ๐Ÿคฒ ๐Ÿค ๐Ÿ™ โœ๏ธ ๐Ÿ’… ๐Ÿ’ช ๐Ÿฆพ ๐Ÿง  ๐Ÿ‘€ ๐Ÿ‘๏ธ ๐Ÿ‘… ๐Ÿ‘„ ๐Ÿ’‹ ๐Ÿซถ ๐Ÿซก ๐Ÿซ  ๐Ÿซข ๐Ÿซฃ ๐Ÿซฅ`,\n ),\n },\n {\n key: 'hearts',\n title: 'Hearts & Symbols',\n emojis: list(\n `โค๏ธ ๐Ÿงก ๐Ÿ’› ๐Ÿ’š ๐Ÿ’™ ๐Ÿ’œ ๐Ÿ–ค ๐Ÿค ๐ŸคŽ ๐Ÿ’” โค๏ธโ€๐Ÿ”ฅ โค๏ธโ€๐Ÿฉน โฃ๏ธ ๐Ÿ’• ๐Ÿ’ž ๐Ÿ’“ ๐Ÿ’— ๐Ÿ’– ๐Ÿ’˜ ๐Ÿ’ ๐Ÿ’ฏ ๐Ÿ’ข ๐Ÿ’ฅ ๐Ÿ’ซ ๐Ÿ’ฆ ๐Ÿ’จ ๐Ÿ•ณ๏ธ ๐Ÿ’ฌ ๐Ÿ’ญ ๐Ÿ’ค โœจ โญ ๐ŸŒŸ ๐Ÿ”ฅ โšก โ€ผ๏ธ โ‰๏ธ โ“ โ— โœ… โŒ โญ• ๐Ÿšซ ๐Ÿ’ก ๐ŸŽฏ ๐Ÿ”” ๐ŸŽต ๐ŸŽถ โž• โž– โœ”๏ธ ๐Ÿ†— ๐Ÿ†’ ๐Ÿ†• ๐Ÿ”`,\n ),\n },\n {\n key: 'animals',\n title: 'Animals & Nature',\n emojis: list(\n `๐Ÿถ ๐Ÿฑ ๐Ÿญ ๐Ÿน ๐Ÿฐ ๐ŸฆŠ ๐Ÿป ๐Ÿผ ๐Ÿจ ๐Ÿฏ ๐Ÿฆ ๐Ÿฎ ๐Ÿท ๐Ÿธ ๐Ÿต ๐Ÿ™ˆ ๐Ÿ™‰ ๐Ÿ™Š ๐Ÿ” ๐Ÿง ๐Ÿฆ ๐Ÿฆ† ๐Ÿฆ… ๐Ÿฆ‰ ๐Ÿบ ๐Ÿด ๐Ÿฆ„ ๐Ÿ ๐Ÿฆ‹ ๐ŸŒ ๐Ÿž ๐Ÿข ๐Ÿ ๐Ÿ™ ๐Ÿฆ€ ๐Ÿ  ๐Ÿฌ ๐Ÿณ ๐Ÿฆˆ ๐ŸŠ ๐Ÿ˜ ๐Ÿฆ’ ๐Ÿช ๐Ÿ• ๐Ÿˆ ๐ŸŒต ๐ŸŽ„ ๐ŸŒฒ ๐ŸŒด ๐ŸŒฑ ๐Ÿ€ ๐Ÿ ๐Ÿ‚ ๐ŸŒท ๐ŸŒน ๐ŸŒบ ๐ŸŒธ ๐ŸŒผ ๐ŸŒป ๐ŸŒž ๐ŸŒ ๐ŸŒš ๐ŸŒ™ ๐ŸŒˆ โ˜€๏ธ โ›… โ˜๏ธ ๐ŸŒง๏ธ โ›ˆ๏ธ โ„๏ธ โ˜ƒ๏ธ ๐ŸŒŠ`,\n ),\n },\n {\n key: 'food',\n title: 'Food & Drink',\n emojis: list(\n `๐Ÿ ๐ŸŽ ๐Ÿ ๐ŸŠ ๐Ÿ‹ ๐ŸŒ ๐Ÿ‰ ๐Ÿ‡ ๐Ÿ“ ๐Ÿซ ๐Ÿ’ ๐Ÿ‘ ๐Ÿฅญ ๐Ÿ ๐Ÿฅฅ ๐Ÿฅ ๐Ÿ… ๐Ÿฅ‘ ๐ŸŒถ๏ธ ๐ŸŒฝ ๐Ÿฅ• ๐Ÿฅ” ๐Ÿฅ ๐Ÿž ๐Ÿง€ ๐Ÿฅš ๐Ÿณ ๐Ÿฅž ๐Ÿฅ“ ๐Ÿ— ๐Ÿ– ๐ŸŒญ ๐Ÿ” ๐ŸŸ ๐Ÿ• ๐Ÿฅช ๐ŸŒฎ ๐ŸŒฏ ๐Ÿฅ— ๐Ÿ ๐Ÿœ ๐Ÿฒ ๐Ÿ› ๐Ÿฃ ๐Ÿฑ ๐ŸฅŸ ๐Ÿค ๐Ÿš ๐Ÿฆ ๐Ÿฉ ๐Ÿช ๐ŸŽ‚ ๐Ÿฐ ๐Ÿง ๐Ÿซ ๐Ÿฌ ๐Ÿญ ๐Ÿฟ โ˜• ๐Ÿต ๐Ÿงƒ ๐Ÿฅค ๐Ÿง‹ ๐Ÿบ ๐Ÿป ๐Ÿฅ‚ ๐Ÿท ๐Ÿธ ๐Ÿน`,\n ),\n },\n {\n key: 'activity',\n title: 'Activity & Objects',\n emojis: list(\n `โšฝ ๐Ÿ€ ๐Ÿˆ โšพ ๐ŸŽพ ๐Ÿ ๐Ÿ‰ ๐ŸŽฑ ๐Ÿ“ ๐Ÿธ ๐Ÿ โ›ณ ๐ŸฅŠ ๐Ÿ† ๐Ÿฅ‡ ๐Ÿฅˆ ๐Ÿฅ‰ ๐Ÿ… ๐ŸŽ–๏ธ ๐ŸŽ‰ ๐ŸŽŠ ๐ŸŽˆ ๐ŸŽ ๐ŸŽ€ ๐ŸŽฎ ๐Ÿ•น๏ธ ๐ŸŽฒ ๐Ÿงฉ ๐ŸŽจ ๐ŸŽฌ ๐ŸŽค ๐ŸŽง ๐ŸŽธ ๐ŸŽน ๐Ÿฅ ๐Ÿ“ท ๐Ÿ“ฑ ๐Ÿ’ป โŒจ๏ธ ๐Ÿ–ฅ๏ธ ๐Ÿ”‹ ๐Ÿ’ฐ ๐Ÿ’ต ๐Ÿ’ณ ๐Ÿ“ˆ ๐Ÿ“‰ ๐Ÿ“Œ ๐Ÿ“Ž โœ๏ธ ๐Ÿ“ ๐Ÿ“š ๐Ÿ“… โฐ โŒ› ๐Ÿ”‘ ๐Ÿ”’ ๐Ÿ”จ ๐Ÿ› ๏ธ ๐Ÿ’Š ๐Ÿš— ๐Ÿš• ๐ŸšŒ ๐Ÿš€ โœˆ๏ธ ๐Ÿšฒ ๐Ÿ  ๐Ÿข ๐Ÿ—บ๏ธ ๐Ÿ–๏ธ โ›ฐ๏ธ`,\n ),\n },\n {\n key: 'flags',\n title: 'Flags',\n emojis: list(`๐Ÿณ๏ธ ๐Ÿด ๐Ÿ ๐Ÿšฉ ๐Ÿณ๏ธโ€๐ŸŒˆ ๐Ÿ‡ฎ๐Ÿ‡ณ ๐Ÿ‡บ๐Ÿ‡ธ ๐Ÿ‡ฌ๐Ÿ‡ง ๐Ÿ‡จ๐Ÿ‡ฆ ๐Ÿ‡ฆ๐Ÿ‡บ ๐Ÿ‡ฉ๐Ÿ‡ช ๐Ÿ‡ซ๐Ÿ‡ท ๐Ÿ‡ช๐Ÿ‡ธ ๐Ÿ‡ฎ๐Ÿ‡น ๐Ÿ‡ฏ๐Ÿ‡ต ๐Ÿ‡ฐ๐Ÿ‡ท ๐Ÿ‡จ๐Ÿ‡ณ ๐Ÿ‡ง๐Ÿ‡ท ๐Ÿ‡ฒ๐Ÿ‡ฝ ๐Ÿ‡ฆ๐Ÿ‡ช ๐Ÿ‡ธ๐Ÿ‡ฆ ๐Ÿ‡ธ๐Ÿ‡ฌ ๐Ÿ‡ณ๐Ÿ‡ฟ ๐Ÿ‡ฟ๐Ÿ‡ฆ ๐Ÿ‡ณ๐Ÿ‡ฌ ๐Ÿ‡ท๐Ÿ‡บ ๐Ÿ‡น๐Ÿ‡ท ๐Ÿ‡ณ๐Ÿ‡ฑ ๐Ÿ‡ธ๐Ÿ‡ช ๐Ÿ‡จ๐Ÿ‡ญ`),\n },\n];\n\n/**\n * The reaction to use from what the user typed in the picker's text field, or\n * null while it holds nothing emoji-like. Letters, digits and plain punctuation\n * are ignored so the field cannot turn into a free-text reaction.\n */\nexport function emojiFromInput(text: string): string | null {\n const value = text.trim();\n if (!value || value.length > 16) return null;\n if (/[A-Za-z0-9\\s.,;:'\"!?@#$%^&*()\\-_=+[\\]{}<>/\\\\|`~]/.test(value)) return null;\n return value;\n}\n\ninterface EmojiEntry {\n emoji: string;\n words: string[];\n}\n\nlet emojiIndex: EmojiEntry[] | null = null;\n\n/** Parsed on first search only; the picker's grid does not need it. */\nfunction getEmojiIndex(): EmojiEntry[] {\n if (!emojiIndex) {\n emojiIndex = EMOJI_KEYWORDS_SOURCE.split('\\n')\n .map((line) => line.trim().split(' '))\n .filter((parts) => parts.length > 1)\n .map(([emoji, ...words]) => ({ emoji, words }));\n }\n return emojiIndex;\n}\n\n/**\n * Emoji whose name or keywords start with every word typed (\"sleep\" -> ๐Ÿ˜ด ๐Ÿ˜ช ๐Ÿ›Œ ๐Ÿ’ค,\n * \"red heart\" -> โค๏ธ). Emoji whose name starts with the first word come first.\n */\nexport function searchEmoji(query: string, limit = 96): string[] {\n const terms = query.toLowerCase().trim().split(/\\s+/).filter(Boolean);\n if (!terms.length) return [];\n const named: string[] = [];\n const tagged: string[] = [];\n for (const { emoji, words } of getEmojiIndex()) {\n if (!terms.every((t) => words.some((w) => w.startsWith(t)))) continue;\n (words[0].startsWith(terms[0]) ? named : tagged).push(emoji);\n }\n return [...named, ...tagged].slice(0, limit);\n}\n"],"names":[],"mappings":"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"}