@candypoets/nipworker 0.89.0 → 0.90.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 (258) hide show
  1. package/dist/cache/index.js +2 -2
  2. package/dist/cache/index.js.map +1 -1
  3. package/dist/cache/pkg/cache.d.ts +2 -2
  4. package/dist/cache/pkg/cache_bg.wasm.d.ts +2 -2
  5. package/dist/connections/index.d.ts +0 -5
  6. package/dist/connections/index.d.ts.map +1 -1
  7. package/dist/connections/index.js +2 -2
  8. package/dist/connections/index.js.map +1 -1
  9. package/dist/connections/pkg/connections.d.ts +5 -5
  10. package/dist/connections/pkg/connections_bg.wasm.d.ts +5 -5
  11. package/dist/connections/proxy.d.ts +2 -0
  12. package/dist/connections/proxy.d.ts.map +1 -0
  13. package/dist/connections/proxy.js +1 -0
  14. package/dist/connections/proxy.js.map +1 -0
  15. package/dist/connections/types.d.ts +4 -0
  16. package/dist/connections/types.d.ts.map +1 -0
  17. package/dist/generated/nostr/fb/buffer-full.d.ts.map +1 -1
  18. package/dist/generated/nostr/fb/cache-input-message.d.ts.map +1 -1
  19. package/dist/generated/nostr/fb/cache-input.d.ts.map +1 -1
  20. package/dist/generated/nostr/fb/cache-request.d.ts +6 -8
  21. package/dist/generated/nostr/fb/cache-request.d.ts.map +1 -1
  22. package/dist/generated/nostr/fb/cache-response.d.ts +4 -6
  23. package/dist/generated/nostr/fb/cache-response.d.ts.map +1 -1
  24. package/dist/generated/nostr/fb/cashu-data.d.ts +4 -6
  25. package/dist/generated/nostr/fb/cashu-data.d.ts.map +1 -1
  26. package/dist/generated/nostr/fb/code-data.d.ts +7 -9
  27. package/dist/generated/nostr/fb/code-data.d.ts.map +1 -1
  28. package/dist/generated/nostr/fb/connection-status.d.ts +10 -12
  29. package/dist/generated/nostr/fb/connection-status.d.ts.map +1 -1
  30. package/dist/generated/nostr/fb/contact.d.ts +9 -11
  31. package/dist/generated/nostr/fb/contact.d.ts.map +1 -1
  32. package/dist/generated/nostr/fb/content-block.d.ts +7 -9
  33. package/dist/generated/nostr/fb/content-block.d.ts.map +1 -1
  34. package/dist/generated/nostr/fb/content-data.d.ts.map +1 -1
  35. package/dist/generated/nostr/fb/coordinate.d.ts +9 -11
  36. package/dist/generated/nostr/fb/coordinate.d.ts.map +1 -1
  37. package/dist/generated/nostr/fb/count-response.d.ts.map +1 -1
  38. package/dist/generated/nostr/fb/counter-pipe-config.d.ts +4 -6
  39. package/dist/generated/nostr/fb/counter-pipe-config.d.ts.map +1 -1
  40. package/dist/generated/nostr/fb/dleqproof.d.ts +10 -12
  41. package/dist/generated/nostr/fb/dleqproof.d.ts.map +1 -1
  42. package/dist/generated/nostr/fb/emoji.d.ts +7 -9
  43. package/dist/generated/nostr/fb/emoji.d.ts.map +1 -1
  44. package/dist/generated/nostr/fb/eoce.d.ts +4 -6
  45. package/dist/generated/nostr/fb/eoce.d.ts.map +1 -1
  46. package/dist/generated/nostr/fb/event-pointer.d.ts +9 -11
  47. package/dist/generated/nostr/fb/event-pointer.d.ts.map +1 -1
  48. package/dist/generated/nostr/fb/get-public-key.d.ts.map +1 -1
  49. package/dist/generated/nostr/fb/hashtag-data.d.ts +4 -6
  50. package/dist/generated/nostr/fb/hashtag-data.d.ts.map +1 -1
  51. package/dist/generated/nostr/fb/history-tag.d.ts +13 -15
  52. package/dist/generated/nostr/fb/history-tag.d.ts.map +1 -1
  53. package/dist/generated/nostr/fb/htlcwitness.d.ts +6 -8
  54. package/dist/generated/nostr/fb/htlcwitness.d.ts.map +1 -1
  55. package/dist/generated/nostr/fb/image-data.d.ts +10 -12
  56. package/dist/generated/nostr/fb/image-data.d.ts.map +1 -1
  57. package/dist/generated/nostr/fb/imeta-tag.d.ts +24 -26
  58. package/dist/generated/nostr/fb/imeta-tag.d.ts.map +1 -1
  59. package/dist/generated/nostr/fb/kind-filter-pipe-config.d.ts.map +1 -1
  60. package/dist/generated/nostr/fb/kind0-parsed.d.ts +61 -63
  61. package/dist/generated/nostr/fb/kind0-parsed.d.ts.map +1 -1
  62. package/dist/generated/nostr/fb/kind1-parsed.d.ts.map +1 -1
  63. package/dist/generated/nostr/fb/kind10002-parsed.d.ts.map +1 -1
  64. package/dist/generated/nostr/fb/kind10019-parsed.d.ts +6 -8
  65. package/dist/generated/nostr/fb/kind10019-parsed.d.ts.map +1 -1
  66. package/dist/generated/nostr/fb/kind1111-parsed.d.ts +32 -34
  67. package/dist/generated/nostr/fb/kind1111-parsed.d.ts.map +1 -1
  68. package/dist/generated/nostr/fb/kind1311-parsed.d.ts +4 -6
  69. package/dist/generated/nostr/fb/kind1311-parsed.d.ts.map +1 -1
  70. package/dist/generated/nostr/fb/kind17-parsed.d.ts +10 -12
  71. package/dist/generated/nostr/fb/kind17-parsed.d.ts.map +1 -1
  72. package/dist/generated/nostr/fb/kind17375-parsed.d.ts +9 -11
  73. package/dist/generated/nostr/fb/kind17375-parsed.d.ts.map +1 -1
  74. package/dist/generated/nostr/fb/kind20-parsed.d.ts +18 -20
  75. package/dist/generated/nostr/fb/kind20-parsed.d.ts.map +1 -1
  76. package/dist/generated/nostr/fb/kind22-parsed.d.ts +15 -17
  77. package/dist/generated/nostr/fb/kind22-parsed.d.ts.map +1 -1
  78. package/dist/generated/nostr/fb/kind3-parsed.d.ts.map +1 -1
  79. package/dist/generated/nostr/fb/kind30023-parsed.d.ts +24 -26
  80. package/dist/generated/nostr/fb/kind30023-parsed.d.ts.map +1 -1
  81. package/dist/generated/nostr/fb/kind4-parsed.d.ts +10 -12
  82. package/dist/generated/nostr/fb/kind4-parsed.d.ts.map +1 -1
  83. package/dist/generated/nostr/fb/kind6-parsed.d.ts.map +1 -1
  84. package/dist/generated/nostr/fb/kind7-parsed.d.ts +10 -12
  85. package/dist/generated/nostr/fb/kind7-parsed.d.ts.map +1 -1
  86. package/dist/generated/nostr/fb/kind7374-parsed.d.ts +7 -9
  87. package/dist/generated/nostr/fb/kind7374-parsed.d.ts.map +1 -1
  88. package/dist/generated/nostr/fb/kind7375-parsed.d.ts +6 -8
  89. package/dist/generated/nostr/fb/kind7375-parsed.d.ts.map +1 -1
  90. package/dist/generated/nostr/fb/kind7376-parsed.d.ts +10 -12
  91. package/dist/generated/nostr/fb/kind7376-parsed.d.ts.map +1 -1
  92. package/dist/generated/nostr/fb/kind9321-parsed.d.ts +22 -24
  93. package/dist/generated/nostr/fb/kind9321-parsed.d.ts.map +1 -1
  94. package/dist/generated/nostr/fb/kind9735-parsed.d.ts +25 -27
  95. package/dist/generated/nostr/fb/kind9735-parsed.d.ts.map +1 -1
  96. package/dist/generated/nostr/fb/link-preview-data.d.ts +13 -15
  97. package/dist/generated/nostr/fb/link-preview-data.d.ts.map +1 -1
  98. package/dist/generated/nostr/fb/list-parsed.d.ts +27 -22
  99. package/dist/generated/nostr/fb/list-parsed.d.ts.map +1 -1
  100. package/dist/generated/nostr/fb/live-activity-ref.d.ts +10 -12
  101. package/dist/generated/nostr/fb/live-activity-ref.d.ts.map +1 -1
  102. package/dist/generated/nostr/fb/live-chat-participant.d.ts +7 -9
  103. package/dist/generated/nostr/fb/live-chat-participant.d.ts.map +1 -1
  104. package/dist/generated/nostr/fb/live-chat-thread-ref.d.ts +7 -9
  105. package/dist/generated/nostr/fb/live-chat-thread-ref.d.ts.map +1 -1
  106. package/dist/generated/nostr/fb/main-content.d.ts.map +1 -1
  107. package/dist/generated/nostr/fb/main-message.d.ts.map +1 -1
  108. package/dist/generated/nostr/fb/media-group-data.d.ts.map +1 -1
  109. package/dist/generated/nostr/fb/media-item.d.ts.map +1 -1
  110. package/dist/generated/nostr/fb/message-type.d.ts.map +1 -1
  111. package/dist/generated/nostr/fb/message.d.ts.map +1 -1
  112. package/dist/generated/nostr/fb/mint-info.d.ts +6 -8
  113. package/dist/generated/nostr/fb/mint-info.d.ts.map +1 -1
  114. package/dist/generated/nostr/fb/mint-proofs.d.ts +4 -6
  115. package/dist/generated/nostr/fb/mint-proofs.d.ts.map +1 -1
  116. package/dist/generated/nostr/fb/mute-filter-pipe-config.d.ts +8 -10
  117. package/dist/generated/nostr/fb/mute-filter-pipe-config.d.ts.map +1 -1
  118. package/dist/generated/nostr/fb/nostr-data.d.ts +12 -14
  119. package/dist/generated/nostr/fb/nostr-data.d.ts.map +1 -1
  120. package/dist/generated/nostr/fb/nostr-event.d.ts +13 -15
  121. package/dist/generated/nostr/fb/nostr-event.d.ts.map +1 -1
  122. package/dist/generated/nostr/fb/npub-limiter-pipe-config.d.ts.map +1 -1
  123. package/dist/generated/nostr/fb/p2-pkwitness.d.ts +2 -4
  124. package/dist/generated/nostr/fb/p2-pkwitness.d.ts.map +1 -1
  125. package/dist/generated/nostr/fb/parse-pipe-config.d.ts.map +1 -1
  126. package/dist/generated/nostr/fb/parsed-data-union.d.ts.map +1 -1
  127. package/dist/generated/nostr/fb/parsed-data.d.ts.map +1 -1
  128. package/dist/generated/nostr/fb/parsed-event.d.ts +9 -11
  129. package/dist/generated/nostr/fb/parsed-event.d.ts.map +1 -1
  130. package/dist/generated/nostr/fb/pipe-config.d.ts.map +1 -1
  131. package/dist/generated/nostr/fb/pipe.d.ts.map +1 -1
  132. package/dist/generated/nostr/fb/pipeline-config.d.ts.map +1 -1
  133. package/dist/generated/nostr/fb/pre-generic-parsed.d.ts +40 -42
  134. package/dist/generated/nostr/fb/pre-generic-parsed.d.ts.map +1 -1
  135. package/dist/generated/nostr/fb/pre-participant.d.ts +13 -15
  136. package/dist/generated/nostr/fb/pre-participant.d.ts.map +1 -1
  137. package/dist/generated/nostr/fb/pre-ref-event.d.ts +10 -12
  138. package/dist/generated/nostr/fb/pre-ref-event.d.ts.map +1 -1
  139. package/dist/generated/nostr/fb/private-key.d.ts +4 -6
  140. package/dist/generated/nostr/fb/private-key.d.ts.map +1 -1
  141. package/dist/generated/nostr/fb/profile-pointer.d.ts +6 -8
  142. package/dist/generated/nostr/fb/profile-pointer.d.ts.map +1 -1
  143. package/dist/generated/nostr/fb/proof-verification-pipe-config.d.ts.map +1 -1
  144. package/dist/generated/nostr/fb/proof.d.ts +10 -12
  145. package/dist/generated/nostr/fb/proof.d.ts.map +1 -1
  146. package/dist/generated/nostr/fb/pubkey.d.ts +4 -6
  147. package/dist/generated/nostr/fb/pubkey.d.ts.map +1 -1
  148. package/dist/generated/nostr/fb/publish.d.ts +6 -8
  149. package/dist/generated/nostr/fb/publish.d.ts.map +1 -1
  150. package/dist/generated/nostr/fb/raw.d.ts +4 -6
  151. package/dist/generated/nostr/fb/raw.d.ts.map +1 -1
  152. package/dist/generated/nostr/fb/reaction-type.d.ts.map +1 -1
  153. package/dist/generated/nostr/fb/relay-info.d.ts +4 -6
  154. package/dist/generated/nostr/fb/relay-info.d.ts.map +1 -1
  155. package/dist/generated/nostr/fb/request.d.ts +10 -12
  156. package/dist/generated/nostr/fb/request.d.ts.map +1 -1
  157. package/dist/generated/nostr/fb/save-to-db-pipe-config.d.ts.map +1 -1
  158. package/dist/generated/nostr/fb/serialize-events-pipe-config.d.ts +4 -6
  159. package/dist/generated/nostr/fb/serialize-events-pipe-config.d.ts.map +1 -1
  160. package/dist/generated/nostr/fb/set-signer.d.ts.map +1 -1
  161. package/dist/generated/nostr/fb/sign-event.d.ts.map +1 -1
  162. package/dist/generated/nostr/fb/signed-event.d.ts.map +1 -1
  163. package/dist/generated/nostr/fb/signer-op.d.ts.map +1 -1
  164. package/dist/generated/nostr/fb/signer-request.d.ts +13 -15
  165. package/dist/generated/nostr/fb/signer-request.d.ts.map +1 -1
  166. package/dist/generated/nostr/fb/signer-response.d.ts +7 -9
  167. package/dist/generated/nostr/fb/signer-response.d.ts.map +1 -1
  168. package/dist/generated/nostr/fb/signer-type.d.ts.map +1 -1
  169. package/dist/generated/nostr/fb/string-vec.d.ts +2 -4
  170. package/dist/generated/nostr/fb/string-vec.d.ts.map +1 -1
  171. package/dist/generated/nostr/fb/subscribe-kind.d.ts.map +1 -1
  172. package/dist/generated/nostr/fb/subscribe.d.ts +4 -6
  173. package/dist/generated/nostr/fb/subscribe.d.ts.map +1 -1
  174. package/dist/generated/nostr/fb/subscription-config.d.ts +4 -6
  175. package/dist/generated/nostr/fb/subscription-config.d.ts.map +1 -1
  176. package/dist/generated/nostr/fb/tag.d.ts +29 -0
  177. package/dist/generated/nostr/fb/tag.d.ts.map +1 -0
  178. package/dist/generated/nostr/fb/template.d.ts +4 -6
  179. package/dist/generated/nostr/fb/template.d.ts.map +1 -1
  180. package/dist/generated/nostr/fb/unsubscribe.d.ts +4 -6
  181. package/dist/generated/nostr/fb/unsubscribe.d.ts.map +1 -1
  182. package/dist/generated/nostr/fb/valid-proofs.d.ts.map +1 -1
  183. package/dist/generated/nostr/fb/video-data.d.ts +7 -9
  184. package/dist/generated/nostr/fb/video-data.d.ts.map +1 -1
  185. package/dist/generated/nostr/fb/video-variant.d.ts +21 -23
  186. package/dist/generated/nostr/fb/video-variant.d.ts.map +1 -1
  187. package/dist/generated/nostr/fb/witness-string.d.ts +4 -6
  188. package/dist/generated/nostr/fb/witness-string.d.ts.map +1 -1
  189. package/dist/generated/nostr/fb/witness.d.ts.map +1 -1
  190. package/dist/generated/nostr/fb/worker-message.d.ts +7 -9
  191. package/dist/generated/nostr/fb/worker-message.d.ts.map +1 -1
  192. package/dist/generated/nostr/fb/zap-request.d.ts +10 -12
  193. package/dist/generated/nostr/fb/zap-request.d.ts.map +1 -1
  194. package/dist/generated/nostr/fb.d.ts +1 -0
  195. package/dist/generated/nostr/fb.d.ts.map +1 -1
  196. package/dist/index.d.ts +8 -9
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js +1 -1
  199. package/dist/index2.js +1 -1
  200. package/dist/index2.js.map +1 -1
  201. package/dist/lib/ConnectionTracker.d.ts.map +1 -1
  202. package/dist/parser/index.js +2 -2
  203. package/dist/parser/index.js.map +1 -1
  204. package/dist/proxy/index.d.ts +1 -1
  205. package/dist/proxy/index.d.ts.map +1 -1
  206. package/dist/proxy/index.js +0 -1
  207. package/dist/proxy/index.js.map +1 -1
  208. package/dist/proxy/relayProxyServer.d.ts +2 -2
  209. package/dist/proxy/relayProxyServer.d.ts.map +1 -1
  210. package/dist/relayProxyServer.js +1 -1
  211. package/dist/relayProxyServer.js.map +1 -1
  212. package/dist/signer-response.js +1 -1
  213. package/dist/signer-response.js.map +1 -1
  214. package/dist/utils.d.ts +0 -1
  215. package/dist/utils.d.ts.map +1 -1
  216. package/dist/utils.js +4 -4
  217. package/dist/utils.js.map +1 -1
  218. package/dist/worker-message.js +1 -1
  219. package/dist/worker-message.js.map +1 -1
  220. package/package.json +2 -2
  221. package/dist/generated/message.d.ts +0 -91
  222. package/dist/generated/message.d.ts.map +0 -1
  223. package/dist/generated/nostr/fb/kind0parsed.d.ts +0 -100
  224. package/dist/generated/nostr/fb/kind0parsed.d.ts.map +0 -1
  225. package/dist/generated/nostr/fb/kind10002parsed.d.ts +0 -25
  226. package/dist/generated/nostr/fb/kind10002parsed.d.ts.map +0 -1
  227. package/dist/generated/nostr/fb/kind10019parsed.d.ts +0 -38
  228. package/dist/generated/nostr/fb/kind10019parsed.d.ts.map +0 -1
  229. package/dist/generated/nostr/fb/kind17375parsed.d.ts +0 -38
  230. package/dist/generated/nostr/fb/kind17375parsed.d.ts.map +0 -1
  231. package/dist/generated/nostr/fb/kind17parsed.d.ts +0 -42
  232. package/dist/generated/nostr/fb/kind17parsed.d.ts.map +0 -1
  233. package/dist/generated/nostr/fb/kind1parsed.d.ts +0 -50
  234. package/dist/generated/nostr/fb/kind1parsed.d.ts.map +0 -1
  235. package/dist/generated/nostr/fb/kind30023parsed.d.ts +0 -58
  236. package/dist/generated/nostr/fb/kind30023parsed.d.ts.map +0 -1
  237. package/dist/generated/nostr/fb/kind3parsed.d.ts +0 -25
  238. package/dist/generated/nostr/fb/kind3parsed.d.ts.map +0 -1
  239. package/dist/generated/nostr/fb/kind4parsed.d.ts +0 -39
  240. package/dist/generated/nostr/fb/kind4parsed.d.ts.map +0 -1
  241. package/dist/generated/nostr/fb/kind6parsed.d.ts +0 -22
  242. package/dist/generated/nostr/fb/kind6parsed.d.ts.map +0 -1
  243. package/dist/generated/nostr/fb/kind7374parsed.d.ts +0 -31
  244. package/dist/generated/nostr/fb/kind7374parsed.d.ts.map +0 -1
  245. package/dist/generated/nostr/fb/kind7375parsed.d.ts +0 -41
  246. package/dist/generated/nostr/fb/kind7375parsed.d.ts.map +0 -1
  247. package/dist/generated/nostr/fb/kind7376parsed.d.ts +0 -58
  248. package/dist/generated/nostr/fb/kind7376parsed.d.ts.map +0 -1
  249. package/dist/generated/nostr/fb/kind7parsed.d.ts +0 -42
  250. package/dist/generated/nostr/fb/kind7parsed.d.ts.map +0 -1
  251. package/dist/generated/nostr/fb/kind9321parsed.d.ts +0 -64
  252. package/dist/generated/nostr/fb/kind9321parsed.d.ts.map +0 -1
  253. package/dist/generated/nostr/fb/kind9735parsed.d.ts +0 -64
  254. package/dist/generated/nostr/fb/kind9735parsed.d.ts.map +0 -1
  255. package/dist/generated/nostr/fb/p2pkwitness.d.ts +0 -27
  256. package/dist/generated/nostr/fb/p2pkwitness.d.ts.map +0 -1
  257. package/dist/lib/ByteString.d.ts +0 -32
  258. package/dist/lib/ByteString.d.ts.map +0 -1
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../src/lib/ConnectionTracker.ts","../src/lib/ParseContent.ts","../src/utils.ts"],"sourcesContent":["import { ConnectionStatus, WorkerMessage } from \"src/generated/nostr/fb\";\nimport { isConnectionStatus } from \"./NarrowTypes\";\n\nexport class ConnectionTracker {\n private knownRelays: Map<number, ConnectionStatus> = new Map();\n private incomingCount = 0;\n private resolvedCount = 0;\n\n /**\n * Feed a new message into the tracker\n */\n handleMessage(msg: WorkerMessage) {\n const status = isConnectionStatus(msg);\n if (!status) return; // not a connection status, ignore\n\n const id = status.relayUrl()?.fnv1aHash()\n if(id && !this.knownRelays.has(id)) {\n this.incomingCount++;\n this.knownRelays.set(id, status);\n }\n if (this.isResolved(status)) {\n this.resolvedCount++;\n }\n }\n\n /**\n * Define what counts as a \"resolved\" connection.\n * Adjust based on your real ConnectionStatus enum/shape.\n */\n private isResolved(status: ConnectionStatus): boolean {\n return status.status()?.toString() === \"EOSE\";\n }\n\n /** Total connection attempts processed */\n get totalIncoming(): number {\n return this.incomingCount;\n }\n\n /** How many actually resolved */\n get totalResolved(): number {\n return this.resolvedCount;\n }\n\n /** Quick ratio (0...1) of resolved vs incoming */\n get resolutionRate(): number {\n return this.incomingCount === 0 ? 0 : this.resolvedCount / this.incomingCount;\n }\n}\n","import { nip19 } from 'nostr-tools';\n\nimport { ContentBlockT } from 'src/generated/nostr/fb/content-block';\nimport { ContentData } from 'src/generated/nostr/fb/content-data';\nimport { CodeDataT } from 'src/generated/nostr/fb/code-data';\nimport { CashuDataT } from 'src/generated/nostr/fb/cashu-data';\nimport { HashtagDataT } from 'src/generated/nostr/fb/hashtag-data';\nimport { ImageDataT } from 'src/generated/nostr/fb/image-data';\nimport { VideoDataT } from 'src/generated/nostr/fb/video-data';\nimport { MediaGroupDataT } from 'src/generated/nostr/fb/media-group-data';\nimport { MediaItemT } from 'src/generated/nostr/fb/media-item';\nimport { LinkPreviewDataT } from 'src/generated/nostr/fb/link-preview-data';\nimport { NostrDataT } from 'src/generated/nostr/fb/nostr-data';\n\ntype MatchProcessor = (match: RegExpExecArray) => ContentBlockT | Promise<ContentBlockT>;\n\nconst textEncoder = new TextEncoder();\n\nexport async function parseContent(content: string): Promise<ContentBlockT[]> {\n\tconst blocks: ContentBlockT[] = [];\n\n\t// Helpers\n\tconst textBlock = (text: string): ContentBlockT =>\n\t\tnew ContentBlockT(textEncoder.encode('text'), textEncoder.encode(text), ContentData.NONE, null);\n\n\tconst imageBlock = (url: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('image'),\n\t\t\ttextEncoder.encode(url),\n\t\t\tContentData.ImageData,\n\t\t\tnew ImageDataT(textEncoder.encode(url), null)\n\t\t);\n\n\tconst videoBlock = (url: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('video'),\n\t\t\ttextEncoder.encode(url),\n\t\t\tContentData.VideoData,\n\t\t\tnew VideoDataT(textEncoder.encode(url), null)\n\t\t);\n\n\tconst codeBlock = (raw: string, full: string): ContentBlockT => {\n\t\t// Try to extract optional language from first line of fenced code\n\t\t// Supports patterns like ```lang\\ncode\\n```\n\t\tconst nl = raw.indexOf('\\n');\n\t\tlet language: string | null = null;\n\t\tlet code = raw;\n\t\tif (nl !== -1) {\n\t\t\tconst firstLine = raw.slice(0, nl).trim();\n\t\t\tconst rest = raw.slice(nl + 1);\n\t\t\tif (firstLine && /^[a-zA-Z0-9+#\\.\\-_]+$/.test(firstLine)) {\n\t\t\t\tlanguage = firstLine;\n\t\t\t\tcode = rest;\n\t\t\t}\n\t\t}\n\n\t\treturn new ContentBlockT(\n\t\t\ttextEncoder.encode('code'),\n\t\t\ttextEncoder.encode(full),\n\t\t\tContentData.CodeData,\n\t\t\tnew CodeDataT(textEncoder.encode(language || ''), textEncoder.encode(code))\n\t\t);\n\t};\n\n\tconst cashuBlock = (token: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('cashu'),\n\t\t\ttextEncoder.encode(token),\n\t\t\tContentData.CashuData,\n\t\t\tnew CashuDataT(textEncoder.encode(token))\n\t\t);\n\n\tconst hashtagBlock = (tag: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('hashtag'),\n\t\t\ttextEncoder.encode(`#${tag}`),\n\t\t\tContentData.HashtagData,\n\t\t\tnew HashtagDataT(textEncoder.encode(tag))\n\t\t);\n\n\tconst linkBlock = (url: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('link'),\n\t\t\ttextEncoder.encode(url),\n\t\t\tContentData.LinkPreviewData,\n\t\t\tnew LinkPreviewDataT(textEncoder.encode(url), null, null, null)\n\t\t);\n\n\tconst nostrBlock = (bech32: string, fullText: string): ContentBlockT => {\n\t\ttry {\n\t\t\tconst decoded = nip19.decode(bech32);\n\t\t\tconst type = decoded.type as 'npub' | 'nprofile' | 'note' | 'nevent' | 'naddr';\n\n\t\t\tlet id: string | null = null;\n\t\t\tlet relays: string[] = [];\n\t\t\tlet author: string | null = null;\n\t\t\tlet kind: bigint = BigInt(0);\n\n\t\t\tconst d = decoded.data as any;\n\n\t\t\tswitch (type) {\n\t\t\t\tcase 'npub':\n\t\t\t\t\t// data: hex pubkey\n\t\t\t\t\tid = d as string;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'nprofile':\n\t\t\t\t\t// data: { pubkey, relays? }\n\t\t\t\t\tid = d.pubkey;\n\t\t\t\t\trelays = Array.isArray(d.relays) ? d.relays : [];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'note':\n\t\t\t\t\t// data: hex event id\n\t\t\t\t\tid = d as string;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'nevent':\n\t\t\t\t\t// data: { id, relays?, author?, kind? }\n\t\t\t\t\tid = d.id;\n\t\t\t\t\trelays = Array.isArray(d.relays) ? d.relays : [];\n\t\t\t\t\tauthor = typeof d.author === 'string' ? d.author : null;\n\t\t\t\t\tif (typeof d.kind === 'number') kind = BigInt(d.kind);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'naddr':\n\t\t\t\t\t// data: { identifier, pubkey, kind, relays? }\n\t\t\t\t\t// Build a stable id\n\t\t\t\t\tid = `${d.kind}:${d.pubkey}:${d.identifier}`;\n\t\t\t\t\trelays = Array.isArray(d.relays) ? d.relays : [];\n\t\t\t\t\tif (typeof d.kind === 'number') kind = BigInt(d.kind);\n\t\t\t\t\tauthor = typeof d.pubkey === 'string' ? d.pubkey : null;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Ensure required fields for NostrDataT: id and entity are required\n\t\t\tif (!id) {\n\t\t\t\tid = bech32;\n\t\t\t}\n\n\t\t\treturn new ContentBlockT(\n\t\t\t\ttextEncoder.encode(type),\n\t\t\t\ttextEncoder.encode(fullText),\n\t\t\t\tContentData.NostrData,\n\t\t\t\tnew NostrDataT(\n\t\t\t\t\ttextEncoder.encode(id),\n\t\t\t\t\ttextEncoder.encode(bech32),\n\t\t\t\t\trelays,\n\t\t\t\t\ttextEncoder.encode(author || ''),\n\t\t\t\t\tkind\n\t\t\t\t)\n\t\t\t);\n\t\t} catch {\n\t\t\t// Fallback to plain text block when decode fails\n\t\t\treturn textBlock(fullText);\n\t\t}\n\t};\n\n\t// Define all the patterns we want to match\n\tconst patterns: Array<{\n\t\ttype: string;\n\t\tregex: RegExp;\n\t\tprocessMatch: MatchProcessor;\n\t}> = [\n\t\t{\n\t\t\ttype: 'code',\n\t\t\tregex: /```([\\s\\S]*?)```/g,\n\t\t\tprocessMatch: (match) => codeBlock(match[1] || '', match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'cashu',\n\t\t\tregex: /(cashuA[A-Za-z0-9_-]+)/g,\n\t\t\tprocessMatch: (match) => cashuBlock(match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'hashtag',\n\t\t\t// Match hashtags that are not part of a URL\n\t\t\tregex: /(?<![^\\s\"'(])(#[a-zA-Z0-9_]+)(?![a-zA-Z0-9_])/g,\n\t\t\tprocessMatch: (match) => hashtagBlock(match[0].substring(1))\n\t\t},\n\t\t{\n\t\t\ttype: 'image',\n\t\t\tregex: /(https?:\\/\\/\\S+\\.(?:jpg|jpeg|png|gif|webp|svg|ico)(?:\\?\\S*)?)/gi,\n\t\t\tprocessMatch: (match) => imageBlock(match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'video',\n\t\t\tregex: /(https?:\\/\\/\\S+\\.(?:mp4|mov|avi|mkv|webm|m4v)(?:\\?\\S*)?)/gi,\n\t\t\tprocessMatch: (match) => videoBlock(match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'nostr',\n\t\t\tregex: /nostr:([a-z0-9]+)/gi,\n\t\t\tprocessMatch: (match) => {\n\t\t\t\tconst bech32 = match[1];\n\t\t\t\treturn nostrBlock(bech32 || '', match[0]);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\ttype: 'link',\n\t\t\tregex: /(https?:\\/\\/\\S+)(?![\\)])/gi,\n\t\t\tprocessMatch: async (match) => linkBlock(match[0])\n\t\t}\n\t];\n\n\t// Find all matches with their positions\n\tconst allMatches: Array<{\n\t\tstart: number;\n\t\tend: number;\n\t\tblock: ContentBlockT;\n\t}> = [];\n\n\t// First, find all matches for all patterns\n\tfor (const pattern of patterns) {\n\t\tlet match: RegExpExecArray | null;\n\t\tpattern.regex.lastIndex = 0;\n\n\t\twhile ((match = pattern.regex.exec(content)) !== null) {\n\t\t\tconst start = match.index;\n\t\t\tconst end = start + match[0].length;\n\t\t\tconst block = await pattern.processMatch(match);\n\n\t\t\tallMatches.push({ start, end, block });\n\t\t}\n\t}\n\n\t// Sort matches by start position\n\tallMatches.sort((a, b) => a.start - b.start);\n\n\t// Remove overlapping matches (prioritize earlier patterns in the array)\n\tconst filteredMatches: typeof allMatches = [];\n\n\tfor (const match of allMatches) {\n\t\tconst overlaps = filteredMatches.some(\n\t\t\t(existing) =>\n\t\t\t\t(match.start >= existing.start && match.start < existing.end) ||\n\t\t\t\t(match.end > existing.start && match.end <= existing.end) ||\n\t\t\t\t(match.start <= existing.start && match.end >= existing.end)\n\t\t);\n\n\t\tif (!overlaps) {\n\t\t\tfilteredMatches.push(match);\n\t\t}\n\t}\n\n\t// Re-sort filtered matches\n\tfilteredMatches.sort((a, b) => a.start - b.start);\n\n\t// Build the final result, including text between matches\n\tlet lastIndex = 0;\n\n\tfor (const { start, end, block } of filteredMatches) {\n\t\t// Add text before this match\n\t\tif (start > lastIndex) {\n\t\t\tblocks.push(textBlock(content.substring(lastIndex, start)));\n\t\t}\n\n\t\t// Add the match\n\t\tblocks.push(block);\n\n\t\tlastIndex = end;\n\t}\n\n\t// Add any remaining text after the last match\n\tif (lastIndex < content.length) {\n\t\tblocks.push(textBlock(content.substring(lastIndex)));\n\t}\n\n\t// Post-processing: group consecutive media into grids\n\tconst processedBlocks: ContentBlockT[] = [];\n\tlet mediaGroup: ContentBlockT[] = [];\n\n\tconst isWhitespace = (s: string) => /^\\s+$/.test(s);\n\n\tfor (let i = 0; i < blocks.length; i++) {\n\t\tconst block = blocks[i];\n\n\t\t// If this is an image or video\n\t\tif (block?.type?.toString() === 'image' || block?.type?.toString() === 'video') {\n\t\t\tmediaGroup.push(block);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If this is whitespace or newlines between media, check what follows\n\t\tif (\n\t\t\tblock?.type?.toString() === 'text' &&\n\t\t\ttypeof block?.text?.toString() === 'string' &&\n\t\t\tisWhitespace(block.text?.toString())\n\t\t) {\n\t\t\tif (\n\t\t\t\tmediaGroup.length > 0 &&\n\t\t\t\ti + 1 < blocks.length &&\n\t\t\t\t(blocks[i + 1]?.type?.toString() === 'image' || blocks[i + 1]?.type?.toString() === 'video')\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// If we have collected media and the current block breaks the sequence\n\t\tif (mediaGroup.length > 0) {\n\t\t\t// Add media group if it contains more than one item\n\t\t\tif (mediaGroup.length > 1) {\n\t\t\t\tconst items: MediaItemT[] = mediaGroup.map((m) => {\n\t\t\t\t\tif (m.dataType === ContentData.ImageData) {\n\t\t\t\t\t\tconst d = m.data as ImageDataT;\n\t\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\t\tnew ImageDataT(textEncoder.encode(d.url ?? (m.text as string)), null),\n\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (m.dataType === ContentData.VideoData) {\n\t\t\t\t\t\tconst d = m.data as VideoDataT;\n\t\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\tnew VideoDataT(textEncoder.encode(d.url ?? (m.text as string)), null)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// Fallback — shouldn't occur because we only collect image/video\n\t\t\t\t\treturn new MediaItemT(null, null);\n\t\t\t\t});\n\n\t\t\t\tconst text = mediaGroup.map((m) => String(m.text ?? '')).join('\\n');\n\t\t\t\tprocessedBlocks.push(\n\t\t\t\t\tnew ContentBlockT(\n\t\t\t\t\t\ttextEncoder.encode('mediaGrid'),\n\t\t\t\t\t\ttextEncoder.encode(text),\n\t\t\t\t\t\tContentData.MediaGroupData,\n\t\t\t\t\t\tnew MediaGroupDataT(items)\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Just add the single media item\n\t\t\t\tprocessedBlocks.push(mediaGroup[0]);\n\t\t\t}\n\t\t\tmediaGroup = [];\n\t\t}\n\n\t\t// Add the current non-media block\n\t\tprocessedBlocks.push(block);\n\t}\n\n\t// Don't forget any remaining media\n\tif (mediaGroup.length > 0) {\n\t\tif (mediaGroup.length > 1) {\n\t\t\tconst items: MediaItemT[] = mediaGroup.map((m) => {\n\t\t\t\tif (m.dataType === ContentData.ImageData) {\n\t\t\t\t\tconst d = m.data as ImageDataT;\n\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\tnew ImageDataT(textEncoder.encode(d.url ?? (m.text as string)), null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t} else if (m.dataType === ContentData.VideoData) {\n\t\t\t\t\tconst d = m.data as VideoDataT;\n\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\tnew VideoDataT(textEncoder.encode(d.url ?? (m.text as string)), null)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn new MediaItemT(null, null);\n\t\t\t});\n\n\t\t\tconst text = mediaGroup.map((m) => String(m.text ?? '')).join('\\n');\n\t\t\tprocessedBlocks.push(\n\t\t\t\tnew ContentBlockT(\n\t\t\t\t\ttextEncoder.encode('mediaGrid'),\n\t\t\t\t\ttextEncoder.encode(text),\n\t\t\t\t\tContentData.MediaGroupData,\n\t\t\t\t\tnew MediaGroupDataT(items)\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\tprocessedBlocks.push(mediaGroup[0]);\n\t\t}\n\t}\n\n\treturn processedBlocks;\n}\n","import { generateSecretKey, getPublicKey } from 'nostr-tools';\nimport { manager } from '.';\n\nexport { ConnectionTracker } from './lib/ConnectionTracker';\nexport { ByteString } from './lib/ByteString';\n\nexport * from './lib/NarrowTypes';\nexport * from './lib/ParseContent';\n\n/**\n * Extracts keys from T where the value is a `function(i: number): any`\n */\ntype FlatBufferKeys<T> = {\n\t[K in keyof T]: T[K] extends (i: number) => any ? K : never;\n}[keyof T];\n\n/**\n * Non-nullable version: Filters out null results\n */\nexport function fbIterable<T, K extends FlatBufferKeys<T>>(\n\tobj: T,\n\tfieldName: K\n): Iterable<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\tconst length = (obj as any)[`${String(fieldName)}Length`]();\n\treturn {\n\t\t[Symbol.iterator](): Iterator<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\t\t\tlet i = 0;\n\t\t\treturn {\n\t\t\t\tnext(): IteratorResult<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\t\t\t\t\twhile (i < length) {\n\t\t\t\t\t\tconst value = (obj as any)[fieldName](i);\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tif (value != null) {\n\t\t\t\t\t\t\treturn { value, done: false };\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if null → skip this index\n\t\t\t\t\t}\n\t\t\t\t\treturn { value: undefined as any, done: true };\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n}\n\n/**\n * Eager array version (non-null)\n */\nexport function fbArray<T, K extends FlatBufferKeys<T>>(\n\tobj: T,\n\tfieldName: K\n): Array<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\tif (!obj) return [];\n\tconst lengthGetter = (obj as any)[`${String(fieldName)}Length`]?.bind(obj);\n\tif (!lengthGetter) return [];\n\tconst length = lengthGetter();\n\n\tconst result: Array<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> = [];\n\tfor (let i = 0; i < length; i++) {\n\t\tconst v = (obj as any)[fieldName](i);\n\t\tif (v != null) result.push(v);\n\t}\n\treturn result;\n}\n\n// In your frontend application\nexport async function connectWithQRCode(appName: string, relays: string[]) {\n\t// Generate a client keypair\n\tconst clientKeys = generateSecretKey();\n\tconst clientPubkey = getPublicKey(clientKeys);\n\tconst clientSecretHex = Array.from(clientKeys)\n\t\t.map((b) => b.toString(16).padStart(2, '0'))\n\t\t.join('');\n\n\t// Generate a random secret\n\tconst secret = getPublicKey(generateSecretKey());\n\n\tconst params = new URLSearchParams();\n\n\tfor (const relay of relays) {\n\t\tparams.append('relay', relay);\n\t}\n\n\tparams.set('secret', secret);\n\tparams.set('name', appName);\n\n\tconst nostrconnectUrl = `nostrconnect://${clientPubkey}?${params.toString()}`;\n\n\tconsole.log('connect url:', nostrconnectUrl);\n\n\t// Set up the NIP-46 signer with the client's pubkey and relays\n\t// Note: We don't know the remote signer's pubkey yet - that's what we're discovering\n\tmanager.setNip46QR(nostrconnectUrl, clientSecretHex);\n\n\treturn nostrconnectUrl;\n}\n"],"names":["ConnectionTracker","msg","status","isConnectionStatus","id","textEncoder","parseContent","content","blocks","textBlock","text","ContentBlockT","ContentData","imageBlock","url","ImageDataT","videoBlock","VideoDataT","codeBlock","raw","full","nl","language","code","firstLine","rest","CodeDataT","cashuBlock","token","CashuDataT","hashtagBlock","tag","HashtagDataT","linkBlock","LinkPreviewDataT","nostrBlock","bech32","fullText","decoded","nip19","type","relays","author","kind","d","NostrDataT","patterns","match","allMatches","pattern","start","end","block","a","b","filteredMatches","existing","lastIndex","processedBlocks","mediaGroup","isWhitespace","s","i","items","m","MediaItemT","MediaGroupDataT","fbIterable","obj","fieldName","length","value","fbArray","lengthGetter","result","v","connectWithQRCode","appName","clientKeys","generateSecretKey","clientPubkey","getPublicKey","clientSecretHex","secret","params","relay","nostrconnectUrl","manager"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../src/lib/ConnectionTracker.ts","../src/lib/ParseContent.ts","../src/utils.ts"],"sourcesContent":["import { ConnectionStatus, WorkerMessage } from 'src/generated/nostr/fb';\nimport { isConnectionStatus } from './NarrowTypes';\n\nexport class ConnectionTracker {\n\tprivate knownRelays: Map<number, ConnectionStatus> = new Map();\n\tprivate incomingCount = 0;\n\tprivate resolvedCount = 0;\n\n\t/**\n\t * Feed a new message into the tracker\n\t */\n\thandleMessage(msg: WorkerMessage) {\n\t\tconst status = isConnectionStatus(msg);\n\t\tif (!status) return; // not a connection status, ignore\n\n\t\tconst id = status.relayUrl();\n\t\tif (id && !this.knownRelays.has(id)) {\n\t\t\tthis.incomingCount++;\n\t\t\tthis.knownRelays.set(id, status);\n\t\t}\n\t\tif (this.isResolved(status)) {\n\t\t\tthis.resolvedCount++;\n\t\t}\n\t}\n\n\t/**\n\t * Define what counts as a \"resolved\" connection.\n\t * Adjust based on your real ConnectionStatus enum/shape.\n\t */\n\tprivate isResolved(status: ConnectionStatus): boolean {\n\t\treturn status.status()?.toString() === 'EOSE';\n\t}\n\n\t/** Total connection attempts processed */\n\tget totalIncoming(): number {\n\t\treturn this.incomingCount;\n\t}\n\n\t/** How many actually resolved */\n\tget totalResolved(): number {\n\t\treturn this.resolvedCount;\n\t}\n\n\t/** Quick ratio (0...1) of resolved vs incoming */\n\tget resolutionRate(): number {\n\t\treturn this.incomingCount === 0 ? 0 : this.resolvedCount / this.incomingCount;\n\t}\n}\n","import { nip19 } from 'nostr-tools';\n\nimport { ContentBlockT } from 'src/generated/nostr/fb/content-block';\nimport { ContentData } from 'src/generated/nostr/fb/content-data';\nimport { CodeDataT } from 'src/generated/nostr/fb/code-data';\nimport { CashuDataT } from 'src/generated/nostr/fb/cashu-data';\nimport { HashtagDataT } from 'src/generated/nostr/fb/hashtag-data';\nimport { ImageDataT } from 'src/generated/nostr/fb/image-data';\nimport { VideoDataT } from 'src/generated/nostr/fb/video-data';\nimport { MediaGroupDataT } from 'src/generated/nostr/fb/media-group-data';\nimport { MediaItemT } from 'src/generated/nostr/fb/media-item';\nimport { LinkPreviewDataT } from 'src/generated/nostr/fb/link-preview-data';\nimport { NostrDataT } from 'src/generated/nostr/fb/nostr-data';\n\ntype MatchProcessor = (match: RegExpExecArray) => ContentBlockT | Promise<ContentBlockT>;\n\nconst textEncoder = new TextEncoder();\n\nexport async function parseContent(content: string): Promise<ContentBlockT[]> {\n\tconst blocks: ContentBlockT[] = [];\n\n\t// Helpers\n\tconst textBlock = (text: string): ContentBlockT =>\n\t\tnew ContentBlockT(textEncoder.encode('text'), textEncoder.encode(text), ContentData.NONE, null);\n\n\tconst imageBlock = (url: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('image'),\n\t\t\ttextEncoder.encode(url),\n\t\t\tContentData.ImageData,\n\t\t\tnew ImageDataT(textEncoder.encode(url), null)\n\t\t);\n\n\tconst videoBlock = (url: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('video'),\n\t\t\ttextEncoder.encode(url),\n\t\t\tContentData.VideoData,\n\t\t\tnew VideoDataT(textEncoder.encode(url), null)\n\t\t);\n\n\tconst codeBlock = (raw: string, full: string): ContentBlockT => {\n\t\t// Try to extract optional language from first line of fenced code\n\t\t// Supports patterns like ```lang\\ncode\\n```\n\t\tconst nl = raw.indexOf('\\n');\n\t\tlet language: string | null = null;\n\t\tlet code = raw;\n\t\tif (nl !== -1) {\n\t\t\tconst firstLine = raw.slice(0, nl).trim();\n\t\t\tconst rest = raw.slice(nl + 1);\n\t\t\tif (firstLine && /^[a-zA-Z0-9+#\\.\\-_]+$/.test(firstLine)) {\n\t\t\t\tlanguage = firstLine;\n\t\t\t\tcode = rest;\n\t\t\t}\n\t\t}\n\n\t\treturn new ContentBlockT(\n\t\t\ttextEncoder.encode('code'),\n\t\t\ttextEncoder.encode(full),\n\t\t\tContentData.CodeData,\n\t\t\tnew CodeDataT(textEncoder.encode(language || ''), textEncoder.encode(code))\n\t\t);\n\t};\n\n\tconst cashuBlock = (token: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('cashu'),\n\t\t\ttextEncoder.encode(token),\n\t\t\tContentData.CashuData,\n\t\t\tnew CashuDataT(textEncoder.encode(token))\n\t\t);\n\n\tconst hashtagBlock = (tag: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('hashtag'),\n\t\t\ttextEncoder.encode(`#${tag}`),\n\t\t\tContentData.HashtagData,\n\t\t\tnew HashtagDataT(textEncoder.encode(tag))\n\t\t);\n\n\tconst linkBlock = (url: string): ContentBlockT =>\n\t\tnew ContentBlockT(\n\t\t\ttextEncoder.encode('link'),\n\t\t\ttextEncoder.encode(url),\n\t\t\tContentData.LinkPreviewData,\n\t\t\tnew LinkPreviewDataT(textEncoder.encode(url), null, null, null)\n\t\t);\n\n\tconst nostrBlock = (bech32: string, fullText: string): ContentBlockT => {\n\t\ttry {\n\t\t\tconst decoded = nip19.decode(bech32);\n\t\t\tconst type = decoded.type as 'npub' | 'nprofile' | 'note' | 'nevent' | 'naddr';\n\n\t\t\tlet id: string | null = null;\n\t\t\tlet relays: string[] = [];\n\t\t\tlet author: string | null = null;\n\t\t\tlet kind: bigint = BigInt(0);\n\n\t\t\tconst d = decoded.data as any;\n\n\t\t\tswitch (type) {\n\t\t\t\tcase 'npub':\n\t\t\t\t\t// data: hex pubkey\n\t\t\t\t\tid = d as string;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'nprofile':\n\t\t\t\t\t// data: { pubkey, relays? }\n\t\t\t\t\tid = d.pubkey;\n\t\t\t\t\trelays = Array.isArray(d.relays) ? d.relays : [];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'note':\n\t\t\t\t\t// data: hex event id\n\t\t\t\t\tid = d as string;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'nevent':\n\t\t\t\t\t// data: { id, relays?, author?, kind? }\n\t\t\t\t\tid = d.id;\n\t\t\t\t\trelays = Array.isArray(d.relays) ? d.relays : [];\n\t\t\t\t\tauthor = typeof d.author === 'string' ? d.author : null;\n\t\t\t\t\tif (typeof d.kind === 'number') kind = BigInt(d.kind);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'naddr':\n\t\t\t\t\t// data: { identifier, pubkey, kind, relays? }\n\t\t\t\t\t// Build a stable id\n\t\t\t\t\tid = `${d.kind}:${d.pubkey}:${d.identifier}`;\n\t\t\t\t\trelays = Array.isArray(d.relays) ? d.relays : [];\n\t\t\t\t\tif (typeof d.kind === 'number') kind = BigInt(d.kind);\n\t\t\t\t\tauthor = typeof d.pubkey === 'string' ? d.pubkey : null;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Ensure required fields for NostrDataT: id and entity are required\n\t\t\tif (!id) {\n\t\t\t\tid = bech32;\n\t\t\t}\n\n\t\t\treturn new ContentBlockT(\n\t\t\t\ttextEncoder.encode(type),\n\t\t\t\ttextEncoder.encode(fullText),\n\t\t\t\tContentData.NostrData,\n\t\t\t\tnew NostrDataT(\n\t\t\t\t\ttextEncoder.encode(id),\n\t\t\t\t\ttextEncoder.encode(bech32),\n\t\t\t\t\trelays,\n\t\t\t\t\ttextEncoder.encode(author || ''),\n\t\t\t\t\tkind\n\t\t\t\t)\n\t\t\t);\n\t\t} catch {\n\t\t\t// Fallback to plain text block when decode fails\n\t\t\treturn textBlock(fullText);\n\t\t}\n\t};\n\n\t// Define all the patterns we want to match\n\tconst patterns: Array<{\n\t\ttype: string;\n\t\tregex: RegExp;\n\t\tprocessMatch: MatchProcessor;\n\t}> = [\n\t\t{\n\t\t\ttype: 'code',\n\t\t\tregex: /```([\\s\\S]*?)```/g,\n\t\t\tprocessMatch: (match) => codeBlock(match[1] || '', match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'cashu',\n\t\t\tregex: /(cashuA[A-Za-z0-9_-]+)/g,\n\t\t\tprocessMatch: (match) => cashuBlock(match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'hashtag',\n\t\t\t// Match hashtags that are not part of a URL\n\t\t\tregex: /(?<![^\\s\"'(])(#[a-zA-Z0-9_]+)(?![a-zA-Z0-9_])/g,\n\t\t\tprocessMatch: (match) => hashtagBlock(match[0].substring(1))\n\t\t},\n\t\t{\n\t\t\ttype: 'image',\n\t\t\tregex: /(https?:\\/\\/\\S+\\.(?:jpg|jpeg|png|gif|webp|svg|ico)(?:\\?\\S*)?)/gi,\n\t\t\tprocessMatch: (match) => imageBlock(match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'video',\n\t\t\tregex: /(https?:\\/\\/\\S+\\.(?:mp4|mov|avi|mkv|webm|m4v)(?:\\?\\S*)?)/gi,\n\t\t\tprocessMatch: (match) => videoBlock(match[0])\n\t\t},\n\t\t{\n\t\t\ttype: 'nostr',\n\t\t\tregex: /nostr:([a-z0-9]+)/gi,\n\t\t\tprocessMatch: (match) => {\n\t\t\t\tconst bech32 = match[1];\n\t\t\t\treturn nostrBlock(bech32 || '', match[0]);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\ttype: 'link',\n\t\t\tregex: /(https?:\\/\\/\\S+)(?![\\)])/gi,\n\t\t\tprocessMatch: async (match) => linkBlock(match[0])\n\t\t}\n\t];\n\n\t// Find all matches with their positions\n\tconst allMatches: Array<{\n\t\tstart: number;\n\t\tend: number;\n\t\tblock: ContentBlockT;\n\t}> = [];\n\n\t// First, find all matches for all patterns\n\tfor (const pattern of patterns) {\n\t\tlet match: RegExpExecArray | null;\n\t\tpattern.regex.lastIndex = 0;\n\n\t\twhile ((match = pattern.regex.exec(content)) !== null) {\n\t\t\tconst start = match.index;\n\t\t\tconst end = start + match[0].length;\n\t\t\tconst block = await pattern.processMatch(match);\n\n\t\t\tallMatches.push({ start, end, block });\n\t\t}\n\t}\n\n\t// Sort matches by start position\n\tallMatches.sort((a, b) => a.start - b.start);\n\n\t// Remove overlapping matches (prioritize earlier patterns in the array)\n\tconst filteredMatches: typeof allMatches = [];\n\n\tfor (const match of allMatches) {\n\t\tconst overlaps = filteredMatches.some(\n\t\t\t(existing) =>\n\t\t\t\t(match.start >= existing.start && match.start < existing.end) ||\n\t\t\t\t(match.end > existing.start && match.end <= existing.end) ||\n\t\t\t\t(match.start <= existing.start && match.end >= existing.end)\n\t\t);\n\n\t\tif (!overlaps) {\n\t\t\tfilteredMatches.push(match);\n\t\t}\n\t}\n\n\t// Re-sort filtered matches\n\tfilteredMatches.sort((a, b) => a.start - b.start);\n\n\t// Build the final result, including text between matches\n\tlet lastIndex = 0;\n\n\tfor (const { start, end, block } of filteredMatches) {\n\t\t// Add text before this match\n\t\tif (start > lastIndex) {\n\t\t\tblocks.push(textBlock(content.substring(lastIndex, start)));\n\t\t}\n\n\t\t// Add the match\n\t\tblocks.push(block);\n\n\t\tlastIndex = end;\n\t}\n\n\t// Add any remaining text after the last match\n\tif (lastIndex < content.length) {\n\t\tblocks.push(textBlock(content.substring(lastIndex)));\n\t}\n\n\t// Post-processing: group consecutive media into grids\n\tconst processedBlocks: ContentBlockT[] = [];\n\tlet mediaGroup: ContentBlockT[] = [];\n\n\tconst isWhitespace = (s: string) => /^\\s+$/.test(s);\n\n\tfor (let i = 0; i < blocks.length; i++) {\n\t\tconst block = blocks[i];\n\n\t\t// If this is an image or video\n\t\tif (block?.type?.toString() === 'image' || block?.type?.toString() === 'video') {\n\t\t\tmediaGroup.push(block);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If this is whitespace or newlines between media, check what follows\n\t\tif (\n\t\t\tblock?.type?.toString() === 'text' &&\n\t\t\ttypeof block?.text?.toString() === 'string' &&\n\t\t\tisWhitespace(block.text?.toString())\n\t\t) {\n\t\t\tif (\n\t\t\t\tmediaGroup.length > 0 &&\n\t\t\t\ti + 1 < blocks.length &&\n\t\t\t\t(blocks[i + 1]?.type?.toString() === 'image' || blocks[i + 1]?.type?.toString() === 'video')\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// If we have collected media and the current block breaks the sequence\n\t\tif (mediaGroup.length > 0) {\n\t\t\t// Add media group if it contains more than one item\n\t\t\tif (mediaGroup.length > 1) {\n\t\t\t\tconst items: MediaItemT[] = mediaGroup.map((m) => {\n\t\t\t\t\tif (m.dataType === ContentData.ImageData) {\n\t\t\t\t\t\tconst d = m.data as ImageDataT;\n\t\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\t\tnew ImageDataT(textEncoder.encode(d.url ?? (m.text as string)), null),\n\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (m.dataType === ContentData.VideoData) {\n\t\t\t\t\t\tconst d = m.data as VideoDataT;\n\t\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\tnew VideoDataT(textEncoder.encode(d.url ?? (m.text as string)), null)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// Fallback — shouldn't occur because we only collect image/video\n\t\t\t\t\treturn new MediaItemT(null, null);\n\t\t\t\t});\n\n\t\t\t\tconst text = mediaGroup.map((m) => String(m.text ?? '')).join('\\n');\n\t\t\t\tprocessedBlocks.push(\n\t\t\t\t\tnew ContentBlockT(\n\t\t\t\t\t\ttextEncoder.encode('mediaGrid'),\n\t\t\t\t\t\ttextEncoder.encode(text),\n\t\t\t\t\t\tContentData.MediaGroupData,\n\t\t\t\t\t\tnew MediaGroupDataT(items)\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Just add the single media item\n\t\t\t\tprocessedBlocks.push(mediaGroup[0]);\n\t\t\t}\n\t\t\tmediaGroup = [];\n\t\t}\n\n\t\t// Add the current non-media block\n\t\tprocessedBlocks.push(block);\n\t}\n\n\t// Don't forget any remaining media\n\tif (mediaGroup.length > 0) {\n\t\tif (mediaGroup.length > 1) {\n\t\t\tconst items: MediaItemT[] = mediaGroup.map((m) => {\n\t\t\t\tif (m.dataType === ContentData.ImageData) {\n\t\t\t\t\tconst d = m.data as ImageDataT;\n\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\tnew ImageDataT(textEncoder.encode(d.url ?? (m.text as string)), null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t} else if (m.dataType === ContentData.VideoData) {\n\t\t\t\t\tconst d = m.data as VideoDataT;\n\t\t\t\t\treturn new MediaItemT(\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\tnew VideoDataT(textEncoder.encode(d.url ?? (m.text as string)), null)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn new MediaItemT(null, null);\n\t\t\t});\n\n\t\t\tconst text = mediaGroup.map((m) => String(m.text ?? '')).join('\\n');\n\t\t\tprocessedBlocks.push(\n\t\t\t\tnew ContentBlockT(\n\t\t\t\t\ttextEncoder.encode('mediaGrid'),\n\t\t\t\t\ttextEncoder.encode(text),\n\t\t\t\t\tContentData.MediaGroupData,\n\t\t\t\t\tnew MediaGroupDataT(items)\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\tprocessedBlocks.push(mediaGroup[0]);\n\t\t}\n\t}\n\n\treturn processedBlocks;\n}\n","import { generateSecretKey, getPublicKey } from 'nostr-tools';\nimport { getManager } from '.';\n\nexport { ConnectionTracker } from './lib/ConnectionTracker';\n\nexport * from './lib/NarrowTypes';\nexport * from './lib/ParseContent';\n\n/**\n * Extracts keys from T where the value is a `function(i: number): any`\n */\ntype FlatBufferKeys<T> = {\n\t[K in keyof T]: T[K] extends (i: number) => any ? K : never;\n}[keyof T];\n\n/**\n * Non-nullable version: Filters out null results\n */\nexport function fbIterable<T, K extends FlatBufferKeys<T>>(\n\tobj: T,\n\tfieldName: K\n): Iterable<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\tconst length = (obj as any)[`${String(fieldName)}Length`]();\n\treturn {\n\t\t[Symbol.iterator](): Iterator<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\t\t\tlet i = 0;\n\t\t\treturn {\n\t\t\t\tnext(): IteratorResult<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\t\t\t\t\twhile (i < length) {\n\t\t\t\t\t\tconst value = (obj as any)[fieldName](i);\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tif (value != null) {\n\t\t\t\t\t\t\treturn { value, done: false };\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if null → skip this index\n\t\t\t\t\t}\n\t\t\t\t\treturn { value: undefined as any, done: true };\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n}\n\n/**\n * Eager array version (non-null)\n */\nexport function fbArray<T, K extends FlatBufferKeys<T>>(\n\tobj: T,\n\tfieldName: K\n): Array<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> {\n\tif (!obj) return [];\n\tconst lengthGetter = (obj as any)[`${String(fieldName)}Length`]?.bind(obj);\n\tif (!lengthGetter) return [];\n\tconst length = lengthGetter();\n\n\tconst result: Array<NonNullable<ReturnType<Extract<T[K], (i: number) => any>>>> = [];\n\tfor (let i = 0; i < length; i++) {\n\t\tconst v = (obj as any)[fieldName](i);\n\t\tif (v != null) result.push(v);\n\t}\n\treturn result;\n}\n\n// In your frontend application\nexport async function connectWithQRCode(appName: string, relays: string[]) {\n\t// Generate a client keypair\n\tconst clientKeys = generateSecretKey();\n\tconst clientPubkey = getPublicKey(clientKeys);\n\tconst clientSecretHex = Array.from(clientKeys)\n\t\t.map((b) => b.toString(16).padStart(2, '0'))\n\t\t.join('');\n\n\t// Generate a random secret\n\tconst secret = getPublicKey(generateSecretKey());\n\n\tconst params = new URLSearchParams();\n\n\tfor (const relay of relays) {\n\t\tparams.append('relay', relay);\n\t}\n\n\tparams.set('secret', secret);\n\tparams.set('name', appName);\n\n\tconst nostrconnectUrl = `nostrconnect://${clientPubkey}?${params.toString()}`;\n\n\tconsole.log('connect url:', nostrconnectUrl);\n\n\t// Set up the NIP-46 signer with the client's pubkey and relays\n\t// Note: We don't know the remote signer's pubkey yet - that's what we're discovering\n\tgetManager().setNip46QR(nostrconnectUrl, clientSecretHex);\n\n\treturn nostrconnectUrl;\n}\n"],"names":["ConnectionTracker","msg","status","isConnectionStatus","id","textEncoder","parseContent","content","blocks","textBlock","text","ContentBlockT","ContentData","imageBlock","url","ImageDataT","videoBlock","VideoDataT","codeBlock","raw","full","nl","language","code","firstLine","rest","CodeDataT","cashuBlock","token","CashuDataT","hashtagBlock","tag","HashtagDataT","linkBlock","LinkPreviewDataT","nostrBlock","bech32","fullText","decoded","nip19","type","relays","author","kind","d","NostrDataT","patterns","match","allMatches","pattern","start","end","block","a","b","filteredMatches","existing","lastIndex","processedBlocks","mediaGroup","isWhitespace","s","i","items","m","MediaItemT","MediaGroupDataT","fbIterable","obj","fieldName","length","value","fbArray","lengthGetter","result","v","connectWithQRCode","appName","clientKeys","generateSecretKey","clientPubkey","getPublicKey","clientSecretHex","secret","params","relay","nostrconnectUrl","getManager"],"mappings":";;;;;AAGO,MAAMA,EAAkB;AAAA,EAAxB,cAAA;AACN,SAAQ,kCAAiD,IAAA,GACzD,KAAQ,gBAAgB,GACxB,KAAQ,gBAAgB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAKxB,cAAcC,GAAoB;AACjC,UAAMC,IAASC,EAAmBF,CAAG;AACrC,QAAI,CAACC,EAAQ;AAEb,UAAME,IAAKF,EAAO,SAAA;AAClB,IAAIE,KAAM,CAAC,KAAK,YAAY,IAAIA,CAAE,MACjC,KAAK,iBACL,KAAK,YAAY,IAAIA,GAAIF,CAAM,IAE5B,KAAK,WAAWA,CAAM,KACzB,KAAK;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,WAAWA,GAAmC;AACrD,WAAOA,EAAO,UAAU,SAAA,MAAe;AAAA,EACxC;AAAA;AAAA,EAGA,IAAI,gBAAwB;AAC3B,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,IAAI,gBAAwB;AAC3B,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,IAAI,iBAAyB;AAC5B,WAAO,KAAK,kBAAkB,IAAI,IAAI,KAAK,gBAAgB,KAAK;AAAA,EACjE;AACD;AC/BA,MAAMG,IAAc,IAAI,YAAA;AAExB,eAAsBC,EAAaC,GAA2C;AAC7E,QAAMC,IAA0B,CAAA,GAG1BC,IAAY,CAACC,MAClB,IAAIC,EAAcN,EAAY,OAAO,MAAM,GAAGA,EAAY,OAAOK,CAAI,GAAGE,EAAY,MAAM,IAAI,GAEzFC,IAAa,CAACC,MACnB,IAAIH;AAAA,IACHN,EAAY,OAAO,OAAO;AAAA,IAC1BA,EAAY,OAAOS,CAAG;AAAA,IACtBF,EAAY;AAAA,IACZ,IAAIG,EAAWV,EAAY,OAAOS,CAAG,GAAG,IAAI;AAAA,EAAA,GAGxCE,IAAa,CAACF,MACnB,IAAIH;AAAA,IACHN,EAAY,OAAO,OAAO;AAAA,IAC1BA,EAAY,OAAOS,CAAG;AAAA,IACtBF,EAAY;AAAA,IACZ,IAAIK,EAAWZ,EAAY,OAAOS,CAAG,GAAG,IAAI;AAAA,EAAA,GAGxCI,IAAY,CAACC,GAAaC,MAAgC;AAG/D,UAAMC,IAAKF,EAAI,QAAQ;AAAA,CAAI;AAC3B,QAAIG,IAA0B,MAC1BC,IAAOJ;AACX,QAAIE,MAAO,IAAI;AACd,YAAMG,IAAYL,EAAI,MAAM,GAAGE,CAAE,EAAE,KAAA,GAC7BI,IAAON,EAAI,MAAME,IAAK,CAAC;AAC7B,MAAIG,KAAa,wBAAwB,KAAKA,CAAS,MACtDF,IAAWE,GACXD,IAAOE;AAAA,IAET;AAEA,WAAO,IAAId;AAAA,MACVN,EAAY,OAAO,MAAM;AAAA,MACzBA,EAAY,OAAOe,CAAI;AAAA,MACvBR,EAAY;AAAA,MACZ,IAAIc,EAAUrB,EAAY,OAAOiB,KAAY,EAAE,GAAGjB,EAAY,OAAOkB,CAAI,CAAC;AAAA,IAAA;AAAA,EAE5E,GAEMI,IAAa,CAACC,MACnB,IAAIjB;AAAA,IACHN,EAAY,OAAO,OAAO;AAAA,IAC1BA,EAAY,OAAOuB,CAAK;AAAA,IACxBhB,EAAY;AAAA,IACZ,IAAIiB,EAAWxB,EAAY,OAAOuB,CAAK,CAAC;AAAA,EAAA,GAGpCE,IAAe,CAACC,MACrB,IAAIpB;AAAA,IACHN,EAAY,OAAO,SAAS;AAAA,IAC5BA,EAAY,OAAO,IAAI0B,CAAG,EAAE;AAAA,IAC5BnB,EAAY;AAAA,IACZ,IAAIoB,EAAa3B,EAAY,OAAO0B,CAAG,CAAC;AAAA,EAAA,GAGpCE,IAAY,CAACnB,MAClB,IAAIH;AAAA,IACHN,EAAY,OAAO,MAAM;AAAA,IACzBA,EAAY,OAAOS,CAAG;AAAA,IACtBF,EAAY;AAAA,IACZ,IAAIsB,EAAiB7B,EAAY,OAAOS,CAAG,GAAG,MAAM,MAAM,IAAI;AAAA,EAAA,GAG1DqB,IAAa,CAACC,GAAgBC,MAAoC;AACvE,QAAI;AACH,YAAMC,IAAUC,EAAM,OAAOH,CAAM,GAC7BI,IAAOF,EAAQ;AAErB,UAAIlC,IAAoB,MACpBqC,IAAmB,CAAA,GACnBC,IAAwB,MACxBC,IAAe,OAAO,CAAC;AAE3B,YAAMC,IAAIN,EAAQ;AAElB,cAAQE,GAAA;AAAA,QACP,KAAK;AAEJ,UAAApC,IAAKwC;AACL;AAAA,QACD,KAAK;AAEJ,UAAAxC,IAAKwC,EAAE,QACPH,IAAS,MAAM,QAAQG,EAAE,MAAM,IAAIA,EAAE,SAAS,CAAA;AAC9C;AAAA,QACD,KAAK;AAEJ,UAAAxC,IAAKwC;AACL;AAAA,QACD,KAAK;AAEJ,UAAAxC,IAAKwC,EAAE,IACPH,IAAS,MAAM,QAAQG,EAAE,MAAM,IAAIA,EAAE,SAAS,CAAA,GAC9CF,IAAS,OAAOE,EAAE,UAAW,WAAWA,EAAE,SAAS,MAC/C,OAAOA,EAAE,QAAS,aAAUD,IAAO,OAAOC,EAAE,IAAI;AACpD;AAAA,QACD,KAAK;AAGJ,UAAAxC,IAAK,GAAGwC,EAAE,IAAI,IAAIA,EAAE,MAAM,IAAIA,EAAE,UAAU,IAC1CH,IAAS,MAAM,QAAQG,EAAE,MAAM,IAAIA,EAAE,SAAS,CAAA,GAC1C,OAAOA,EAAE,QAAS,aAAUD,IAAO,OAAOC,EAAE,IAAI,IACpDF,IAAS,OAAOE,EAAE,UAAW,WAAWA,EAAE,SAAS;AACnD;AAAA,MAAA;AAIF,aAAKxC,MACJA,IAAKgC,IAGC,IAAIzB;AAAA,QACVN,EAAY,OAAOmC,CAAI;AAAA,QACvBnC,EAAY,OAAOgC,CAAQ;AAAA,QAC3BzB,EAAY;AAAA,QACZ,IAAIiC;AAAA,UACHxC,EAAY,OAAOD,CAAE;AAAA,UACrBC,EAAY,OAAO+B,CAAM;AAAA,UACzBK;AAAA,UACApC,EAAY,OAAOqC,KAAU,EAAE;AAAA,UAC/BC;AAAA,QAAA;AAAA,MACD;AAAA,IAEF,QAAQ;AAEP,aAAOlC,EAAU4B,CAAQ;AAAA,IAC1B;AAAA,EACD,GAGMS,IAID;AAAA,IACJ;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,CAACC,MAAU7B,EAAU6B,EAAM,CAAC,KAAK,IAAIA,EAAM,CAAC,CAAC;AAAA,IAAA;AAAA,IAE5D;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,CAACA,MAAUpB,EAAWoB,EAAM,CAAC,CAAC;AAAA,IAAA;AAAA,IAE7C;AAAA,MACC,MAAM;AAAA;AAAA,MAEN,OAAO;AAAA,MACP,cAAc,CAACA,MAAUjB,EAAaiB,EAAM,CAAC,EAAE,UAAU,CAAC,CAAC;AAAA,IAAA;AAAA,IAE5D;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,CAACA,MAAUlC,EAAWkC,EAAM,CAAC,CAAC;AAAA,IAAA;AAAA,IAE7C;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,CAACA,MAAU/B,EAAW+B,EAAM,CAAC,CAAC;AAAA,IAAA;AAAA,IAE7C;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,CAACA,MAAU;AACxB,cAAMX,IAASW,EAAM,CAAC;AACtB,eAAOZ,EAAWC,KAAU,IAAIW,EAAM,CAAC,CAAC;AAAA,MACzC;AAAA,IAAA;AAAA,IAED;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc,OAAOA,MAAUd,EAAUc,EAAM,CAAC,CAAC;AAAA,IAAA;AAAA,EAClD,GAIKC,IAID,CAAA;AAGL,aAAWC,KAAWH,GAAU;AAC/B,QAAIC;AAGJ,SAFAE,EAAQ,MAAM,YAAY,IAElBF,IAAQE,EAAQ,MAAM,KAAK1C,CAAO,OAAO,QAAM;AACtD,YAAM2C,IAAQH,EAAM,OACdI,IAAMD,IAAQH,EAAM,CAAC,EAAE,QACvBK,IAAQ,MAAMH,EAAQ,aAAaF,CAAK;AAE9C,MAAAC,EAAW,KAAK,EAAE,OAAAE,GAAO,KAAAC,GAAK,OAAAC,GAAO;AAAA,IACtC;AAAA,EACD;AAGA,EAAAJ,EAAW,KAAK,CAACK,GAAGC,MAAMD,EAAE,QAAQC,EAAE,KAAK;AAG3C,QAAMC,IAAqC,CAAA;AAE3C,aAAWR,KAASC;AAQnB,IAPiBO,EAAgB;AAAA,MAChC,CAACC,MACCT,EAAM,SAASS,EAAS,SAAST,EAAM,QAAQS,EAAS,OACxDT,EAAM,MAAMS,EAAS,SAAST,EAAM,OAAOS,EAAS,OACpDT,EAAM,SAASS,EAAS,SAAST,EAAM,OAAOS,EAAS;AAAA,IAAA,KAIzDD,EAAgB,KAAKR,CAAK;AAK5B,EAAAQ,EAAgB,KAAK,CAACF,GAAGC,MAAMD,EAAE,QAAQC,EAAE,KAAK;AAGhD,MAAIG,IAAY;AAEhB,aAAW,EAAE,OAAAP,GAAO,KAAAC,GAAK,OAAAC,EAAA,KAAWG;AAEnC,IAAIL,IAAQO,KACXjD,EAAO,KAAKC,EAAUF,EAAQ,UAAUkD,GAAWP,CAAK,CAAC,CAAC,GAI3D1C,EAAO,KAAK4C,CAAK,GAEjBK,IAAYN;AAIb,EAAIM,IAAYlD,EAAQ,UACvBC,EAAO,KAAKC,EAAUF,EAAQ,UAAUkD,CAAS,CAAC,CAAC;AAIpD,QAAMC,IAAmC,CAAA;AACzC,MAAIC,IAA8B,CAAA;AAElC,QAAMC,IAAe,CAACC,MAAc,QAAQ,KAAKA,CAAC;AAElD,WAASC,IAAI,GAAGA,IAAItD,EAAO,QAAQsD,KAAK;AACvC,UAAMV,IAAQ5C,EAAOsD,CAAC;AAGtB,QAAIV,GAAO,MAAM,eAAe,WAAWA,GAAO,MAAM,SAAA,MAAe,SAAS;AAC/E,MAAAO,EAAW,KAAKP,CAAK;AACrB;AAAA,IACD;AAGA,QACC,EAAAA,GAAO,MAAM,SAAA,MAAe,UAC5B,OAAOA,GAAO,MAAM,SAAA,KAAe,YACnCQ,EAAaR,EAAM,MAAM,SAAA,CAAU,KAGlCO,EAAW,SAAS,KACpBG,IAAI,IAAItD,EAAO,WACdA,EAAOsD,IAAI,CAAC,GAAG,MAAM,SAAA,MAAe,WAAWtD,EAAOsD,IAAI,CAAC,GAAG,MAAM,eAAe,WAOtF;AAAA,UAAIH,EAAW,SAAS,GAAG;AAE1B,YAAIA,EAAW,SAAS,GAAG;AAC1B,gBAAMI,IAAsBJ,EAAW,IAAI,CAACK,MAAM;AACjD,gBAAIA,EAAE,aAAapD,EAAY,WAAW;AACzC,oBAAMgC,IAAIoB,EAAE;AACZ,qBAAO,IAAIC;AAAA,gBACV,IAAIlD,EAAWV,EAAY,OAAOuC,EAAE,OAAQoB,EAAE,IAAe,GAAG,IAAI;AAAA,gBACpE;AAAA,cAAA;AAAA,YAEF,WAAWA,EAAE,aAAapD,EAAY,WAAW;AAChD,oBAAMgC,IAAIoB,EAAE;AACZ,qBAAO,IAAIC;AAAA,gBACV;AAAA,gBACA,IAAIhD,EAAWZ,EAAY,OAAOuC,EAAE,OAAQoB,EAAE,IAAe,GAAG,IAAI;AAAA,cAAA;AAAA,YAEtE;AAEA,mBAAO,IAAIC,EAAW,MAAM,IAAI;AAAA,UACjC,CAAC,GAEKvD,IAAOiD,EAAW,IAAI,CAACK,MAAM,OAAOA,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK;AAAA,CAAI;AAClE,UAAAN,EAAgB;AAAA,YACf,IAAI/C;AAAA,cACHN,EAAY,OAAO,WAAW;AAAA,cAC9BA,EAAY,OAAOK,CAAI;AAAA,cACvBE,EAAY;AAAA,cACZ,IAAIsD,EAAgBH,CAAK;AAAA,YAAA;AAAA,UAC1B;AAAA,QAEF;AAEC,UAAAL,EAAgB,KAAKC,EAAW,CAAC,CAAC;AAEnC,QAAAA,IAAa,CAAA;AAAA,MACd;AAGA,MAAAD,EAAgB,KAAKN,CAAK;AAAA;AAAA,EAC3B;AAGA,MAAIO,EAAW,SAAS;AACvB,QAAIA,EAAW,SAAS,GAAG;AAC1B,YAAMI,IAAsBJ,EAAW,IAAI,CAACK,MAAM;AACjD,YAAIA,EAAE,aAAapD,EAAY,WAAW;AACzC,gBAAMgC,IAAIoB,EAAE;AACZ,iBAAO,IAAIC;AAAA,YACV,IAAIlD,EAAWV,EAAY,OAAOuC,EAAE,OAAQoB,EAAE,IAAe,GAAG,IAAI;AAAA,YACpE;AAAA,UAAA;AAAA,QAEF,WAAWA,EAAE,aAAapD,EAAY,WAAW;AAChD,gBAAMgC,IAAIoB,EAAE;AACZ,iBAAO,IAAIC;AAAA,YACV;AAAA,YACA,IAAIhD,EAAWZ,EAAY,OAAOuC,EAAE,OAAQoB,EAAE,IAAe,GAAG,IAAI;AAAA,UAAA;AAAA,QAEtE;AACA,eAAO,IAAIC,EAAW,MAAM,IAAI;AAAA,MACjC,CAAC,GAEKvD,IAAOiD,EAAW,IAAI,CAACK,MAAM,OAAOA,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK;AAAA,CAAI;AAClE,MAAAN,EAAgB;AAAA,QACf,IAAI/C;AAAA,UACHN,EAAY,OAAO,WAAW;AAAA,UAC9BA,EAAY,OAAOK,CAAI;AAAA,UACvBE,EAAY;AAAA,UACZ,IAAIsD,EAAgBH,CAAK;AAAA,QAAA;AAAA,MAC1B;AAAA,IAEF;AACC,MAAAL,EAAgB,KAAKC,EAAW,CAAC,CAAC;AAIpC,SAAOD;AACR;ACjWO,SAASS,EACfC,GACAC,GACuE;AACvE,QAAMC,IAAUF,EAAY,GAAG,OAAOC,CAAS,CAAC,QAAQ,EAAA;AACxD,SAAO;AAAA,IACN,CAAC,OAAO,QAAQ,IAA0E;AACzF,UAAIP,IAAI;AACR,aAAO;AAAA,QACN,OAAmF;AAClF,iBAAOA,IAAIQ,KAAQ;AAClB,kBAAMC,IAASH,EAAYC,CAAS,EAAEP,CAAC;AAEvC,gBADAA,KACIS,KAAS;AACZ,qBAAO,EAAE,OAAAA,GAAO,MAAM,GAAA;AAAA,UAGxB;AACA,iBAAO,EAAE,OAAO,QAAkB,MAAM,GAAA;AAAA,QACzC;AAAA,MAAA;AAAA,IAEF;AAAA,EAAA;AAEF;AAKO,SAASC,EACfJ,GACAC,GACoE;AACpE,MAAI,CAACD,EAAK,QAAO,CAAA;AACjB,QAAMK,IAAgBL,EAAY,GAAG,OAAOC,CAAS,CAAC,QAAQ,GAAG,KAAKD,CAAG;AACzE,MAAI,CAACK,EAAc,QAAO,CAAA;AAC1B,QAAMH,IAASG,EAAA,GAETC,IAA4E,CAAA;AAClF,WAASZ,IAAI,GAAGA,IAAIQ,GAAQR,KAAK;AAChC,UAAMa,IAAKP,EAAYC,CAAS,EAAEP,CAAC;AACnC,IAAIa,KAAK,QAAMD,EAAO,KAAKC,CAAC;AAAA,EAC7B;AACA,SAAOD;AACR;AAGA,eAAsBE,EAAkBC,GAAiBpC,GAAkB;AAE1E,QAAMqC,IAAaC,EAAA,GACbC,IAAeC,EAAaH,CAAU,GACtCI,IAAkB,MAAM,KAAKJ,CAAU,EAC3C,IAAI,CAACxB,MAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE,GAGH6B,IAASF,EAAaF,GAAmB,GAEzCK,IAAS,IAAI,gBAAA;AAEnB,aAAWC,KAAS5C;AACnB,IAAA2C,EAAO,OAAO,SAASC,CAAK;AAG7B,EAAAD,EAAO,IAAI,UAAUD,CAAM,GAC3BC,EAAO,IAAI,QAAQP,CAAO;AAE1B,QAAMS,IAAkB,kBAAkBN,CAAY,IAAII,EAAO,UAAU;AAE3E,iBAAQ,IAAI,gBAAgBE,CAAe,GAI3CC,IAAa,WAAWD,GAAiBJ,CAAe,GAEjDI;AACR;"}