prismcast 1.10.2 → 1.11.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 (693) hide show
  1. package/dist/app.d.ts +6 -3
  2. package/dist/app.d.ts.map +1 -0
  3. package/dist/app.js +140 -86
  4. package/dist/app.js.map +1 -1
  5. package/dist/browser/blockedPage.d.ts +80 -0
  6. package/dist/browser/blockedPage.d.ts.map +1 -0
  7. package/dist/browser/blockedPage.js +209 -0
  8. package/dist/browser/blockedPage.js.map +1 -0
  9. package/dist/browser/browserSupervisor.d.ts +80 -0
  10. package/dist/browser/browserSupervisor.d.ts.map +1 -0
  11. package/dist/browser/browserSupervisor.js +186 -0
  12. package/dist/browser/browserSupervisor.js.map +1 -0
  13. package/dist/browser/cdp.d.ts +1 -0
  14. package/dist/browser/cdp.d.ts.map +1 -0
  15. package/dist/browser/cdp.js +6 -5
  16. package/dist/browser/cdp.js.map +1 -1
  17. package/dist/browser/channelSelection.d.ts +45 -14
  18. package/dist/browser/channelSelection.d.ts.map +1 -0
  19. package/dist/browser/channelSelection.js +81 -18
  20. package/dist/browser/channelSelection.js.map +1 -1
  21. package/dist/browser/consent.d.ts +152 -0
  22. package/dist/browser/consent.d.ts.map +1 -0
  23. package/dist/browser/consent.js +418 -0
  24. package/dist/browser/consent.js.map +1 -0
  25. package/dist/browser/display.d.ts +1 -0
  26. package/dist/browser/display.d.ts.map +1 -0
  27. package/dist/browser/hlsPlaylistObserver.d.ts +55 -0
  28. package/dist/browser/hlsPlaylistObserver.d.ts.map +1 -0
  29. package/dist/browser/hlsPlaylistObserver.js +132 -0
  30. package/dist/browser/hlsPlaylistObserver.js.map +1 -0
  31. package/dist/browser/index.d.ts +67 -40
  32. package/dist/browser/index.d.ts.map +1 -0
  33. package/dist/browser/index.js +508 -300
  34. package/dist/browser/index.js.map +1 -1
  35. package/dist/browser/launchGovernor.d.ts +89 -0
  36. package/dist/browser/launchGovernor.d.ts.map +1 -0
  37. package/dist/browser/launchGovernor.js +96 -0
  38. package/dist/browser/launchGovernor.js.map +1 -0
  39. package/dist/browser/login.d.ts +10 -2
  40. package/dist/browser/login.d.ts.map +1 -0
  41. package/dist/browser/login.js +36 -5
  42. package/dist/browser/login.js.map +1 -1
  43. package/dist/browser/manifestInterceptor.d.ts +102 -49
  44. package/dist/browser/manifestInterceptor.d.ts.map +1 -0
  45. package/dist/browser/manifestInterceptor.js +219 -237
  46. package/dist/browser/manifestInterceptor.js.map +1 -1
  47. package/dist/browser/pageStaleness.d.ts +30 -0
  48. package/dist/browser/pageStaleness.d.ts.map +1 -0
  49. package/dist/browser/pageStaleness.js +76 -0
  50. package/dist/browser/pageStaleness.js.map +1 -0
  51. package/dist/browser/precaching.d.ts +95 -3
  52. package/dist/browser/precaching.d.ts.map +1 -0
  53. package/dist/browser/precaching.js +499 -65
  54. package/dist/browser/precaching.js.map +1 -1
  55. package/dist/browser/tabNetworkObserver.d.ts +49 -0
  56. package/dist/browser/tabNetworkObserver.d.ts.map +1 -0
  57. package/dist/browser/tabNetworkObserver.js +144 -0
  58. package/dist/browser/tabNetworkObserver.js.map +1 -0
  59. package/dist/browser/tuning/cache.d.ts +61 -0
  60. package/dist/browser/tuning/cache.d.ts.map +1 -0
  61. package/dist/browser/tuning/cache.js +62 -0
  62. package/dist/browser/tuning/cache.js.map +1 -0
  63. package/dist/browser/tuning/comcastPolymer.d.ts +3 -2
  64. package/dist/browser/tuning/comcastPolymer.d.ts.map +1 -0
  65. package/dist/browser/tuning/comcastPolymer.js +79 -102
  66. package/dist/browser/tuning/comcastPolymer.js.map +1 -1
  67. package/dist/browser/tuning/cox.d.ts +1 -0
  68. package/dist/browser/tuning/cox.d.ts.map +1 -0
  69. package/dist/browser/tuning/directv.d.ts +1 -0
  70. package/dist/browser/tuning/directv.d.ts.map +1 -0
  71. package/dist/browser/tuning/directv.js +52 -46
  72. package/dist/browser/tuning/directv.js.map +1 -1
  73. package/dist/browser/tuning/fox.d.ts +1 -0
  74. package/dist/browser/tuning/fox.d.ts.map +1 -0
  75. package/dist/browser/tuning/fox.js +13 -12
  76. package/dist/browser/tuning/fox.js.map +1 -1
  77. package/dist/browser/tuning/gridSearch.d.ts +68 -0
  78. package/dist/browser/tuning/gridSearch.d.ts.map +1 -0
  79. package/dist/browser/tuning/gridSearch.js +85 -0
  80. package/dist/browser/tuning/gridSearch.js.map +1 -0
  81. package/dist/browser/tuning/hbo.d.ts +1 -0
  82. package/dist/browser/tuning/hbo.d.ts.map +1 -0
  83. package/dist/browser/tuning/hbo.js +73 -45
  84. package/dist/browser/tuning/hbo.js.map +1 -1
  85. package/dist/browser/tuning/hulu.d.ts +1 -0
  86. package/dist/browser/tuning/hulu.d.ts.map +1 -0
  87. package/dist/browser/tuning/hulu.js +128 -173
  88. package/dist/browser/tuning/hulu.js.map +1 -1
  89. package/dist/browser/tuning/shared.d.ts +75 -5
  90. package/dist/browser/tuning/shared.d.ts.map +1 -0
  91. package/dist/browser/tuning/shared.js +216 -6
  92. package/dist/browser/tuning/shared.js.map +1 -1
  93. package/dist/browser/tuning/sling.d.ts +1 -0
  94. package/dist/browser/tuning/sling.d.ts.map +1 -0
  95. package/dist/browser/tuning/sling.js +105 -126
  96. package/dist/browser/tuning/sling.js.map +1 -1
  97. package/dist/browser/tuning/spectrum.d.ts +1 -0
  98. package/dist/browser/tuning/spectrum.d.ts.map +1 -0
  99. package/dist/browser/tuning/spectrum.js +80 -125
  100. package/dist/browser/tuning/spectrum.js.map +1 -1
  101. package/dist/browser/tuning/thumbnailRow.d.ts +1 -0
  102. package/dist/browser/tuning/thumbnailRow.d.ts.map +1 -0
  103. package/dist/browser/tuning/thumbnailRow.js +8 -2
  104. package/dist/browser/tuning/thumbnailRow.js.map +1 -1
  105. package/dist/browser/tuning/tileClick.d.ts +1 -0
  106. package/dist/browser/tuning/tileClick.d.ts.map +1 -0
  107. package/dist/browser/tuning/tileClick.js +3 -2
  108. package/dist/browser/tuning/tileClick.js.map +1 -1
  109. package/dist/browser/tuning/xfinity.d.ts +1 -0
  110. package/dist/browser/tuning/xfinity.d.ts.map +1 -0
  111. package/dist/browser/tuning/youtubeTv.d.ts +1 -0
  112. package/dist/browser/tuning/youtubeTv.d.ts.map +1 -0
  113. package/dist/browser/tuning/youtubeTv.js +74 -127
  114. package/dist/browser/tuning/youtubeTv.js.map +1 -1
  115. package/dist/browser/video.d.ts +54 -14
  116. package/dist/browser/video.d.ts.map +1 -0
  117. package/dist/browser/video.js +296 -138
  118. package/dist/browser/video.js.map +1 -1
  119. package/dist/channels/index.d.ts +1 -0
  120. package/dist/channels/index.d.ts.map +1 -0
  121. package/dist/channels/index.js +12 -9
  122. package/dist/channels/index.js.map +1 -1
  123. package/dist/config/channelForm.d.ts +15 -1
  124. package/dist/config/channelForm.d.ts.map +1 -0
  125. package/dist/config/channelForm.js +28 -12
  126. package/dist/config/channelForm.js.map +1 -1
  127. package/dist/config/consistencyProbe.d.ts +1 -0
  128. package/dist/config/consistencyProbe.d.ts.map +1 -0
  129. package/dist/config/consistencyProbe.js +27 -21
  130. package/dist/config/consistencyProbe.js.map +1 -1
  131. package/dist/config/health.d.ts +41 -8
  132. package/dist/config/health.d.ts.map +1 -0
  133. package/dist/config/health.js +189 -38
  134. package/dist/config/health.js.map +1 -1
  135. package/dist/config/index.d.ts +55 -3
  136. package/dist/config/index.d.ts.map +1 -0
  137. package/dist/config/index.js +320 -69
  138. package/dist/config/index.js.map +1 -1
  139. package/dist/config/paths.d.ts +10 -9
  140. package/dist/config/paths.d.ts.map +1 -0
  141. package/dist/config/paths.js +11 -11
  142. package/dist/config/paths.js.map +1 -1
  143. package/dist/config/persistence.context.d.ts +1 -0
  144. package/dist/config/persistence.context.d.ts.map +1 -0
  145. package/dist/config/persistence.d.ts +13 -10
  146. package/dist/config/persistence.d.ts.map +1 -0
  147. package/dist/config/persistence.js +40 -21
  148. package/dist/config/persistence.js.map +1 -1
  149. package/dist/config/presets.d.ts +1 -0
  150. package/dist/config/presets.d.ts.map +1 -0
  151. package/dist/config/profiles.d.ts +22 -15
  152. package/dist/config/profiles.d.ts.map +1 -0
  153. package/dist/config/profiles.js +81 -47
  154. package/dist/config/profiles.js.map +1 -1
  155. package/dist/config/providerLineups.d.ts +47 -0
  156. package/dist/config/providerLineups.d.ts.map +1 -0
  157. package/dist/config/providerLineups.js +137 -0
  158. package/dist/config/providerLineups.js.map +1 -0
  159. package/dist/config/reactivity.d.ts +84 -0
  160. package/dist/config/reactivity.d.ts.map +1 -0
  161. package/dist/config/reactivity.js +226 -0
  162. package/dist/config/reactivity.js.map +1 -0
  163. package/dist/config/servicePacks.d.ts +18 -2
  164. package/dist/config/servicePacks.d.ts.map +1 -0
  165. package/dist/config/servicePacks.js +53 -11
  166. package/dist/config/servicePacks.js.map +1 -1
  167. package/dist/config/services.d.ts +21 -15
  168. package/dist/config/services.d.ts.map +1 -0
  169. package/dist/config/services.js +35 -24
  170. package/dist/config/services.js.map +1 -1
  171. package/dist/config/sites.d.ts +6 -4
  172. package/dist/config/sites.d.ts.map +1 -0
  173. package/dist/config/sites.js +15 -11
  174. package/dist/config/sites.js.map +1 -1
  175. package/dist/config/userChannels.d.ts +129 -30
  176. package/dist/config/userChannels.d.ts.map +1 -0
  177. package/dist/config/userChannels.js +333 -68
  178. package/dist/config/userChannels.js.map +1 -1
  179. package/dist/config/userConfig.d.ts +14 -9
  180. package/dist/config/userConfig.d.ts.map +1 -0
  181. package/dist/config/userConfig.js +87 -25
  182. package/dist/config/userConfig.js.map +1 -1
  183. package/dist/config/userProfiles.d.ts +10 -6
  184. package/dist/config/userProfiles.d.ts.map +1 -0
  185. package/dist/config/userProfiles.js +64 -39
  186. package/dist/config/userProfiles.js.map +1 -1
  187. package/dist/hdhr/channelMap.d.ts +1 -0
  188. package/dist/hdhr/channelMap.d.ts.map +1 -0
  189. package/dist/hdhr/deviceId.d.ts +1 -0
  190. package/dist/hdhr/deviceId.d.ts.map +1 -0
  191. package/dist/hdhr/discover.d.ts +1 -0
  192. package/dist/hdhr/discover.d.ts.map +1 -0
  193. package/dist/hdhr/discover.js +48 -47
  194. package/dist/hdhr/discover.js.map +1 -1
  195. package/dist/hdhr/getHandlers.d.ts +29 -0
  196. package/dist/hdhr/getHandlers.d.ts.map +1 -0
  197. package/dist/hdhr/getHandlers.js +196 -0
  198. package/dist/hdhr/getHandlers.js.map +1 -0
  199. package/dist/hdhr/identity.d.ts +36 -0
  200. package/dist/hdhr/identity.d.ts.map +1 -0
  201. package/dist/hdhr/identity.js +51 -0
  202. package/dist/hdhr/identity.js.map +1 -0
  203. package/dist/hdhr/index.d.ts +22 -4
  204. package/dist/hdhr/index.d.ts.map +1 -0
  205. package/dist/hdhr/index.js +229 -54
  206. package/dist/hdhr/index.js.map +1 -1
  207. package/dist/hdhr/protocol.d.ts +75 -0
  208. package/dist/hdhr/protocol.d.ts.map +1 -0
  209. package/dist/hdhr/protocol.js +264 -0
  210. package/dist/hdhr/protocol.js.map +1 -0
  211. package/dist/hdhr/tunerState.d.ts +24 -0
  212. package/dist/hdhr/tunerState.d.ts.map +1 -0
  213. package/dist/hdhr/tunerState.js +67 -0
  214. package/dist/hdhr/tunerState.js.map +1 -0
  215. package/dist/hdhr/udp.d.ts +43 -0
  216. package/dist/hdhr/udp.d.ts.map +1 -0
  217. package/dist/hdhr/udp.js +277 -0
  218. package/dist/hdhr/udp.js.map +1 -0
  219. package/dist/identity.d.ts +1 -0
  220. package/dist/identity.d.ts.map +1 -0
  221. package/dist/identity.js +13 -11
  222. package/dist/identity.js.map +1 -1
  223. package/dist/index.d.ts +1 -0
  224. package/dist/index.d.ts.map +1 -0
  225. package/dist/index.js +11 -12
  226. package/dist/index.js.map +1 -1
  227. package/dist/native/codecInference.d.ts +1 -0
  228. package/dist/native/codecInference.d.ts.map +1 -0
  229. package/dist/native/codecInference.js +50 -5
  230. package/dist/native/codecInference.js.map +1 -1
  231. package/dist/native/decrypt.d.ts +6 -2
  232. package/dist/native/decrypt.d.ts.map +1 -0
  233. package/dist/native/decrypt.js +15 -8
  234. package/dist/native/decrypt.js.map +1 -1
  235. package/dist/native/index.d.ts +40 -17
  236. package/dist/native/index.d.ts.map +1 -0
  237. package/dist/native/index.js +281 -120
  238. package/dist/native/index.js.map +1 -1
  239. package/dist/native/probe.d.ts +114 -18
  240. package/dist/native/probe.d.ts.map +1 -0
  241. package/dist/native/probe.js +452 -115
  242. package/dist/native/probe.js.map +1 -1
  243. package/dist/native/proxy.d.ts +57 -5
  244. package/dist/native/proxy.d.ts.map +1 -0
  245. package/dist/native/proxy.js +604 -170
  246. package/dist/native/proxy.js.map +1 -1
  247. package/dist/native/tokenExpiry.d.ts +1 -0
  248. package/dist/native/tokenExpiry.d.ts.map +1 -0
  249. package/dist/native/tokenExpiry.js +1 -1
  250. package/dist/routes/assets.d.ts +1 -0
  251. package/dist/routes/assets.d.ts.map +1 -0
  252. package/dist/routes/assets.js +4 -2
  253. package/dist/routes/assets.js.map +1 -1
  254. package/dist/routes/auth.d.ts +1 -0
  255. package/dist/routes/auth.d.ts.map +1 -0
  256. package/dist/routes/auth.js +0 -1
  257. package/dist/routes/auth.js.map +1 -1
  258. package/dist/routes/cdp.d.ts +5 -5
  259. package/dist/routes/cdp.d.ts.map +1 -0
  260. package/dist/routes/cdp.js +59 -20
  261. package/dist/routes/cdp.js.map +1 -1
  262. package/dist/routes/channels.d.ts +1 -0
  263. package/dist/routes/channels.d.ts.map +1 -0
  264. package/dist/routes/channels.js +2 -1
  265. package/dist/routes/channels.js.map +1 -1
  266. package/dist/routes/clientActions.d.ts +98 -0
  267. package/dist/routes/clientActions.d.ts.map +1 -0
  268. package/dist/routes/clientActions.js +113 -0
  269. package/dist/routes/clientActions.js.map +1 -0
  270. package/dist/routes/components.d.ts +5 -3
  271. package/dist/routes/components.d.ts.map +1 -0
  272. package/dist/routes/components.js +36 -39
  273. package/dist/routes/components.js.map +1 -1
  274. package/dist/routes/config/channels/endpoints/browse.d.ts +1 -0
  275. package/dist/routes/config/channels/endpoints/browse.d.ts.map +1 -0
  276. package/dist/routes/config/channels/endpoints/browse.js +23 -10
  277. package/dist/routes/config/channels/endpoints/browse.js.map +1 -1
  278. package/dist/routes/config/channels/endpoints/bulk.d.ts +1 -0
  279. package/dist/routes/config/channels/endpoints/bulk.d.ts.map +1 -0
  280. package/dist/routes/config/channels/endpoints/bulk.js +5 -3
  281. package/dist/routes/config/channels/endpoints/bulk.js.map +1 -1
  282. package/dist/routes/config/channels/endpoints/crud.d.ts +1 -0
  283. package/dist/routes/config/channels/endpoints/crud.d.ts.map +1 -0
  284. package/dist/routes/config/channels/endpoints/crud.js +85 -93
  285. package/dist/routes/config/channels/endpoints/crud.js.map +1 -1
  286. package/dist/routes/config/channels/endpoints/importExport.d.ts +1 -0
  287. package/dist/routes/config/channels/endpoints/importExport.d.ts.map +1 -0
  288. package/dist/routes/config/channels/endpoints/importExport.js +6 -3
  289. package/dist/routes/config/channels/endpoints/importExport.js.map +1 -1
  290. package/dist/routes/config/channels/endpoints/predefined.d.ts +1 -0
  291. package/dist/routes/config/channels/endpoints/predefined.d.ts.map +1 -0
  292. package/dist/routes/config/channels/endpoints/prefs.d.ts +1 -0
  293. package/dist/routes/config/channels/endpoints/prefs.d.ts.map +1 -0
  294. package/dist/routes/config/channels/endpoints/prefs.js +2 -1
  295. package/dist/routes/config/channels/endpoints/prefs.js.map +1 -1
  296. package/dist/routes/config/channels/endpoints/service.d.ts +2 -1
  297. package/dist/routes/config/channels/endpoints/service.d.ts.map +1 -0
  298. package/dist/routes/config/channels/endpoints/service.js +3 -1
  299. package/dist/routes/config/channels/endpoints/service.js.map +1 -1
  300. package/dist/routes/config/channels/endpoints/tags.d.ts +1 -0
  301. package/dist/routes/config/channels/endpoints/tags.d.ts.map +1 -0
  302. package/dist/routes/config/channels/endpoints/tags.js +13 -7
  303. package/dist/routes/config/channels/endpoints/tags.js.map +1 -1
  304. package/dist/routes/config/channels/healthBridge.d.ts +24 -0
  305. package/dist/routes/config/channels/healthBridge.d.ts.map +1 -0
  306. package/dist/routes/config/channels/healthBridge.js +71 -0
  307. package/dist/routes/config/channels/healthBridge.js.map +1 -0
  308. package/dist/routes/config/channels/http/handler.d.ts +1 -0
  309. package/dist/routes/config/channels/http/handler.d.ts.map +1 -0
  310. package/dist/routes/config/channels/http/playlistHint.d.ts +2 -1
  311. package/dist/routes/config/channels/http/playlistHint.d.ts.map +1 -0
  312. package/dist/routes/config/channels/http/playlistHint.js +16 -2
  313. package/dist/routes/config/channels/http/playlistHint.js.map +1 -1
  314. package/dist/routes/config/channels/http/serviceWarning.d.ts +4 -2
  315. package/dist/routes/config/channels/http/serviceWarning.d.ts.map +1 -0
  316. package/dist/routes/config/channels/http/serviceWarning.js +3 -2
  317. package/dist/routes/config/channels/http/serviceWarning.js.map +1 -1
  318. package/dist/routes/config/channels/index.d.ts +1 -0
  319. package/dist/routes/config/channels/index.d.ts.map +1 -0
  320. package/dist/routes/config/channels/setup.d.ts +1 -0
  321. package/dist/routes/config/channels/setup.d.ts.map +1 -0
  322. package/dist/routes/config/channels/table.d.ts +3 -3
  323. package/dist/routes/config/channels/table.d.ts.map +1 -0
  324. package/dist/routes/config/channels/table.js +148 -107
  325. package/dist/routes/config/channels/table.js.map +1 -1
  326. package/dist/routes/config/http/envelope.d.ts +1 -0
  327. package/dist/routes/config/http/envelope.d.ts.map +1 -0
  328. package/dist/routes/config/index.d.ts +35 -3
  329. package/dist/routes/config/index.d.ts.map +1 -0
  330. package/dist/routes/config/index.js +51 -2
  331. package/dist/routes/config/index.js.map +1 -1
  332. package/dist/routes/config/services.d.ts +5 -4
  333. package/dist/routes/config/services.d.ts.map +1 -0
  334. package/dist/routes/config/services.js +57 -43
  335. package/dist/routes/config/services.js.map +1 -1
  336. package/dist/routes/config/settings.d.ts +1 -0
  337. package/dist/routes/config/settings.d.ts.map +1 -0
  338. package/dist/routes/config/settings.js +98 -49
  339. package/dist/routes/config/settings.js.map +1 -1
  340. package/dist/routes/debug.d.ts +1 -0
  341. package/dist/routes/debug.d.ts.map +1 -0
  342. package/dist/routes/debug.js +277 -139
  343. package/dist/routes/debug.js.map +1 -1
  344. package/dist/routes/health.d.ts +39 -1
  345. package/dist/routes/health.d.ts.map +1 -0
  346. package/dist/routes/health.js +33 -27
  347. package/dist/routes/health.js.map +1 -1
  348. package/dist/routes/hls.d.ts +1 -0
  349. package/dist/routes/hls.d.ts.map +1 -0
  350. package/dist/routes/icons.d.ts +1 -0
  351. package/dist/routes/icons.d.ts.map +1 -0
  352. package/dist/routes/icons.js +1 -1
  353. package/dist/routes/index.d.ts +1 -0
  354. package/dist/routes/index.d.ts.map +1 -0
  355. package/dist/routes/logs.d.ts +1 -0
  356. package/dist/routes/logs.d.ts.map +1 -0
  357. package/dist/routes/logs.js +14 -4
  358. package/dist/routes/logs.js.map +1 -1
  359. package/dist/routes/mpegts.d.ts +1 -0
  360. package/dist/routes/mpegts.d.ts.map +1 -0
  361. package/dist/routes/play.d.ts +1 -0
  362. package/dist/routes/play.d.ts.map +1 -0
  363. package/dist/routes/playlist.d.ts +1 -0
  364. package/dist/routes/playlist.d.ts.map +1 -0
  365. package/dist/routes/playlist.js +7 -2
  366. package/dist/routes/playlist.js.map +1 -1
  367. package/dist/routes/root/content.d.ts +8 -5
  368. package/dist/routes/root/content.d.ts.map +1 -0
  369. package/dist/routes/root/content.js +29 -26
  370. package/dist/routes/root/content.js.map +1 -1
  371. package/dist/routes/root/index.d.ts +2 -1
  372. package/dist/routes/root/index.d.ts.map +1 -0
  373. package/dist/routes/root/index.js +26 -21
  374. package/dist/routes/root/index.js.map +1 -1
  375. package/dist/routes/root/scripts/channels.d.ts +6 -0
  376. package/dist/routes/root/scripts/channels.d.ts.map +1 -0
  377. package/dist/routes/root/scripts/channels.js +197 -118
  378. package/dist/routes/root/scripts/channels.js.map +1 -1
  379. package/dist/routes/root/scripts/clientEscape.d.ts +22 -0
  380. package/dist/routes/root/scripts/clientEscape.d.ts.map +1 -0
  381. package/dist/routes/root/scripts/clientEscape.js +41 -0
  382. package/dist/routes/root/scripts/clientEscape.js.map +1 -0
  383. package/dist/routes/root/scripts/clientUrl.d.ts +23 -0
  384. package/dist/routes/root/scripts/clientUrl.d.ts.map +1 -0
  385. package/dist/routes/root/scripts/clientUrl.js +44 -0
  386. package/dist/routes/root/scripts/clientUrl.js.map +1 -0
  387. package/dist/routes/root/scripts/config.d.ts +6 -0
  388. package/dist/routes/root/scripts/config.d.ts.map +1 -0
  389. package/dist/routes/root/scripts/config.js +110 -24
  390. package/dist/routes/root/scripts/config.js.map +1 -1
  391. package/dist/routes/root/scripts/index.d.ts +1 -0
  392. package/dist/routes/root/scripts/index.d.ts.map +1 -0
  393. package/dist/routes/root/scripts/shared.d.ts +1 -0
  394. package/dist/routes/root/scripts/shared.d.ts.map +1 -0
  395. package/dist/routes/root/scripts/shared.js +112 -26
  396. package/dist/routes/root/scripts/shared.js.map +1 -1
  397. package/dist/routes/root/scripts/status.d.ts +1 -0
  398. package/dist/routes/root/scripts/status.d.ts.map +1 -0
  399. package/dist/routes/root/scripts/status.handlers.d.ts +23 -33
  400. package/dist/routes/root/scripts/status.handlers.d.ts.map +1 -0
  401. package/dist/routes/root/scripts/status.handlers.js +46 -92
  402. package/dist/routes/root/scripts/status.handlers.js.map +1 -1
  403. package/dist/routes/root/scripts/status.js +21 -8
  404. package/dist/routes/root/scripts/status.js.map +1 -1
  405. package/dist/routes/root/styles.d.ts +1 -0
  406. package/dist/routes/root/styles.d.ts.map +1 -0
  407. package/dist/routes/root/styles.js +7 -4
  408. package/dist/routes/root/styles.js.map +1 -1
  409. package/dist/routes/services.d.ts +13 -1
  410. package/dist/routes/services.d.ts.map +1 -0
  411. package/dist/routes/services.js +81 -68
  412. package/dist/routes/services.js.map +1 -1
  413. package/dist/routes/sse.d.ts +1 -0
  414. package/dist/routes/sse.d.ts.map +1 -0
  415. package/dist/routes/sse.js +1 -1
  416. package/dist/routes/sse.js.map +1 -1
  417. package/dist/routes/streams.d.ts +2 -1
  418. package/dist/routes/streams.d.ts.map +1 -0
  419. package/dist/routes/streams.js +6 -4
  420. package/dist/routes/streams.js.map +1 -1
  421. package/dist/routes/theme.d.ts +3 -2
  422. package/dist/routes/theme.d.ts.map +1 -0
  423. package/dist/routes/theme.js +6 -5
  424. package/dist/routes/theme.js.map +1 -1
  425. package/dist/routes/ui.d.ts +3 -1
  426. package/dist/routes/ui.d.ts.map +1 -0
  427. package/dist/routes/ui.js +16 -4
  428. package/dist/routes/ui.js.map +1 -1
  429. package/dist/routes/upgrade.d.ts +1 -0
  430. package/dist/routes/upgrade.d.ts.map +1 -0
  431. package/dist/routes/upgrade.js +6 -2
  432. package/dist/routes/upgrade.js.map +1 -1
  433. package/dist/service/commands.context.d.ts +1 -0
  434. package/dist/service/commands.context.d.ts.map +1 -0
  435. package/dist/service/commands.context.js +4 -3
  436. package/dist/service/commands.context.js.map +1 -1
  437. package/dist/service/commands.d.ts +1 -0
  438. package/dist/service/commands.d.ts.map +1 -0
  439. package/dist/service/commands.js +10 -13
  440. package/dist/service/commands.js.map +1 -1
  441. package/dist/service/generators.context.d.ts +1 -0
  442. package/dist/service/generators.context.d.ts.map +1 -0
  443. package/dist/service/generators.context.js +1 -1
  444. package/dist/service/generators.context.js.map +1 -1
  445. package/dist/service/generators.d.ts +4 -3
  446. package/dist/service/generators.d.ts.map +1 -0
  447. package/dist/service/generators.js +111 -31
  448. package/dist/service/generators.js.map +1 -1
  449. package/dist/service/index.d.ts +1 -0
  450. package/dist/service/index.d.ts.map +1 -0
  451. package/dist/streaming/captureLock.d.ts +44 -0
  452. package/dist/streaming/captureLock.d.ts.map +1 -0
  453. package/dist/streaming/captureLock.js +95 -0
  454. package/dist/streaming/captureLock.js.map +1 -0
  455. package/dist/streaming/captureSession.d.ts +31 -0
  456. package/dist/streaming/captureSession.d.ts.map +1 -0
  457. package/dist/streaming/captureSession.js +54 -0
  458. package/dist/streaming/captureSession.js.map +1 -0
  459. package/dist/streaming/clients.d.ts +1 -0
  460. package/dist/streaming/clients.d.ts.map +1 -0
  461. package/dist/streaming/codec.d.ts +1 -0
  462. package/dist/streaming/codec.d.ts.map +1 -0
  463. package/dist/streaming/fmp4Segmenter.d.ts +29 -2
  464. package/dist/streaming/fmp4Segmenter.d.ts.map +1 -0
  465. package/dist/streaming/fmp4Segmenter.js +79 -26
  466. package/dist/streaming/fmp4Segmenter.js.map +1 -1
  467. package/dist/streaming/hls.d.ts +18 -7
  468. package/dist/streaming/hls.d.ts.map +1 -0
  469. package/dist/streaming/hls.js +220 -120
  470. package/dist/streaming/hls.js.map +1 -1
  471. package/dist/streaming/hlsResume.d.ts +1 -0
  472. package/dist/streaming/hlsResume.d.ts.map +1 -0
  473. package/dist/streaming/hlsResume.js +1 -1
  474. package/dist/streaming/hlsResume.js.map +1 -1
  475. package/dist/streaming/hlsSegments.d.ts +59 -2
  476. package/dist/streaming/hlsSegments.d.ts.map +1 -0
  477. package/dist/streaming/hlsSegments.js +147 -17
  478. package/dist/streaming/hlsSegments.js.map +1 -1
  479. package/dist/streaming/lifecycle.d.ts +4 -1
  480. package/dist/streaming/lifecycle.d.ts.map +1 -0
  481. package/dist/streaming/lifecycle.js +65 -85
  482. package/dist/streaming/lifecycle.js.map +1 -1
  483. package/dist/streaming/monitor.d.ts +6 -4
  484. package/dist/streaming/monitor.d.ts.map +1 -0
  485. package/dist/streaming/monitor.js +343 -145
  486. package/dist/streaming/monitor.js.map +1 -1
  487. package/dist/streaming/mp4Parser.d.ts +5 -4
  488. package/dist/streaming/mp4Parser.d.ts.map +1 -0
  489. package/dist/streaming/mp4Parser.js +36 -13
  490. package/dist/streaming/mp4Parser.js.map +1 -1
  491. package/dist/streaming/mpegts.d.ts +16 -0
  492. package/dist/streaming/mpegts.d.ts.map +1 -0
  493. package/dist/streaming/mpegts.js +61 -17
  494. package/dist/streaming/mpegts.js.map +1 -1
  495. package/dist/streaming/playlistBuilder.d.ts +1 -0
  496. package/dist/streaming/playlistBuilder.d.ts.map +1 -0
  497. package/dist/streaming/preroll.d.ts +32 -5
  498. package/dist/streaming/preroll.d.ts.map +1 -0
  499. package/dist/streaming/preroll.js +70 -32
  500. package/dist/streaming/preroll.js.map +1 -1
  501. package/dist/streaming/pretune.d.ts +26 -1
  502. package/dist/streaming/pretune.d.ts.map +1 -0
  503. package/dist/streaming/pretune.js +22 -24
  504. package/dist/streaming/pretune.js.map +1 -1
  505. package/dist/streaming/pretuneTimers.d.ts +24 -0
  506. package/dist/streaming/pretuneTimers.d.ts.map +1 -0
  507. package/dist/streaming/pretuneTimers.js +56 -0
  508. package/dist/streaming/pretuneTimers.js.map +1 -0
  509. package/dist/streaming/recovery.d.ts +139 -5
  510. package/dist/streaming/recovery.d.ts.map +1 -0
  511. package/dist/streaming/recovery.js +160 -16
  512. package/dist/streaming/recovery.js.map +1 -1
  513. package/dist/streaming/registry.d.ts +27 -9
  514. package/dist/streaming/registry.d.ts.map +1 -0
  515. package/dist/streaming/registry.js +21 -3
  516. package/dist/streaming/registry.js.map +1 -1
  517. package/dist/streaming/setup.d.ts +157 -29
  518. package/dist/streaming/setup.d.ts.map +1 -0
  519. package/dist/streaming/setup.js +1034 -458
  520. package/dist/streaming/setup.js.map +1 -1
  521. package/dist/streaming/showInfo.d.ts +21 -1
  522. package/dist/streaming/showInfo.d.ts.map +1 -0
  523. package/dist/streaming/showInfo.js +31 -16
  524. package/dist/streaming/showInfo.js.map +1 -1
  525. package/dist/streaming/statusEmitter.d.ts +10 -10
  526. package/dist/streaming/statusEmitter.d.ts.map +1 -0
  527. package/dist/streaming/statusEmitter.js +5 -8
  528. package/dist/streaming/statusEmitter.js.map +1 -1
  529. package/dist/types/channels.d.ts +16 -4
  530. package/dist/types/channels.d.ts.map +1 -0
  531. package/dist/types/channels.js +4 -2
  532. package/dist/types/channels.js.map +1 -1
  533. package/dist/types/config.d.ts +16 -5
  534. package/dist/types/config.d.ts.map +1 -0
  535. package/dist/types/index.d.ts +3 -2
  536. package/dist/types/index.d.ts.map +1 -0
  537. package/dist/types/profiles.d.ts +6 -4
  538. package/dist/types/profiles.d.ts.map +1 -0
  539. package/dist/types/selection.d.ts +31 -3
  540. package/dist/types/selection.d.ts.map +1 -0
  541. package/dist/types/selection.js +4 -2
  542. package/dist/types/selection.js.map +1 -1
  543. package/dist/types/shared.d.ts +1 -0
  544. package/dist/types/shared.d.ts.map +1 -0
  545. package/dist/types/streaming.d.ts +8 -0
  546. package/dist/types/streaming.d.ts.map +1 -0
  547. package/dist/upgrade/commands.context.d.ts +1 -0
  548. package/dist/upgrade/commands.context.d.ts.map +1 -0
  549. package/dist/upgrade/commands.context.js +14 -10
  550. package/dist/upgrade/commands.context.js.map +1 -1
  551. package/dist/upgrade/commands.d.ts +8 -15
  552. package/dist/upgrade/commands.d.ts.map +1 -0
  553. package/dist/upgrade/commands.js +27 -28
  554. package/dist/upgrade/commands.js.map +1 -1
  555. package/dist/upgrade/detection.context.d.ts +1 -0
  556. package/dist/upgrade/detection.context.d.ts.map +1 -0
  557. package/dist/upgrade/detection.context.js +4 -1
  558. package/dist/upgrade/detection.context.js.map +1 -1
  559. package/dist/upgrade/detection.d.ts +9 -7
  560. package/dist/upgrade/detection.d.ts.map +1 -0
  561. package/dist/upgrade/detection.js +23 -54
  562. package/dist/upgrade/detection.js.map +1 -1
  563. package/dist/upgrade/index.d.ts +2 -0
  564. package/dist/upgrade/index.d.ts.map +1 -0
  565. package/dist/upgrade/index.js +1 -0
  566. package/dist/upgrade/index.js.map +1 -1
  567. package/dist/upgrade/lifecycle.context.d.ts +20 -0
  568. package/dist/upgrade/lifecycle.context.d.ts.map +1 -0
  569. package/dist/upgrade/lifecycle.context.js +47 -0
  570. package/dist/upgrade/lifecycle.context.js.map +1 -0
  571. package/dist/upgrade/lifecycle.d.ts +72 -0
  572. package/dist/upgrade/lifecycle.d.ts.map +1 -0
  573. package/dist/upgrade/lifecycle.js +175 -0
  574. package/dist/upgrade/lifecycle.js.map +1 -0
  575. package/dist/upgrade/pathHandle.d.ts +30 -0
  576. package/dist/upgrade/pathHandle.d.ts.map +1 -0
  577. package/dist/upgrade/pathHandle.js +102 -0
  578. package/dist/upgrade/pathHandle.js.map +1 -0
  579. package/dist/utils/bootSession.context.d.ts +16 -0
  580. package/dist/utils/bootSession.context.d.ts.map +1 -0
  581. package/dist/utils/bootSession.context.js +60 -0
  582. package/dist/utils/bootSession.context.js.map +1 -0
  583. package/dist/utils/bootSession.d.ts +17 -0
  584. package/dist/utils/bootSession.d.ts.map +1 -0
  585. package/dist/utils/bootSession.js +20 -0
  586. package/dist/utils/bootSession.js.map +1 -0
  587. package/dist/utils/chromeFetch.d.ts +1 -0
  588. package/dist/utils/chromeFetch.d.ts.map +1 -0
  589. package/dist/utils/cliOutput.d.ts +1 -0
  590. package/dist/utils/cliOutput.d.ts.map +1 -0
  591. package/dist/utils/clock.d.ts +5 -4
  592. package/dist/utils/clock.d.ts.map +1 -0
  593. package/dist/utils/clock.js +19 -16
  594. package/dist/utils/clock.js.map +1 -1
  595. package/dist/utils/debugFilter.d.ts +9 -1
  596. package/dist/utils/debugFilter.d.ts.map +1 -0
  597. package/dist/utils/debugFilter.js +60 -33
  598. package/dist/utils/debugFilter.js.map +1 -1
  599. package/dist/utils/delay.d.ts +48 -15
  600. package/dist/utils/delay.d.ts.map +1 -0
  601. package/dist/utils/delay.js +73 -20
  602. package/dist/utils/delay.js.map +1 -1
  603. package/dist/utils/errors.d.ts +32 -0
  604. package/dist/utils/errors.d.ts.map +1 -0
  605. package/dist/utils/errors.js +45 -4
  606. package/dist/utils/errors.js.map +1 -1
  607. package/dist/utils/evaluate.d.ts +1 -0
  608. package/dist/utils/evaluate.d.ts.map +1 -0
  609. package/dist/utils/evaluate.js +29 -23
  610. package/dist/utils/evaluate.js.map +1 -1
  611. package/dist/utils/ffmpeg.context.d.ts +1 -0
  612. package/dist/utils/ffmpeg.context.d.ts.map +1 -0
  613. package/dist/utils/ffmpeg.context.js.map +1 -1
  614. package/dist/utils/ffmpeg.d.ts +29 -7
  615. package/dist/utils/ffmpeg.d.ts.map +1 -0
  616. package/dist/utils/ffmpeg.js +32 -14
  617. package/dist/utils/ffmpeg.js.map +1 -1
  618. package/dist/utils/fileLogger.d.ts +3 -1
  619. package/dist/utils/fileLogger.d.ts.map +1 -0
  620. package/dist/utils/fileLogger.js +64 -29
  621. package/dist/utils/fileLogger.js.map +1 -1
  622. package/dist/utils/format.d.ts +14 -1
  623. package/dist/utils/format.d.ts.map +1 -0
  624. package/dist/utils/format.js +19 -5
  625. package/dist/utils/format.js.map +1 -1
  626. package/dist/utils/index.d.ts +4 -0
  627. package/dist/utils/index.d.ts.map +1 -0
  628. package/dist/utils/index.js +3 -0
  629. package/dist/utils/index.js.map +1 -1
  630. package/dist/utils/logEmitter.d.ts +1 -0
  631. package/dist/utils/logEmitter.d.ts.map +1 -0
  632. package/dist/utils/logger.d.ts +1 -0
  633. package/dist/utils/logger.d.ts.map +1 -0
  634. package/dist/utils/logger.js +10 -6
  635. package/dist/utils/logger.js.map +1 -1
  636. package/dist/utils/m3u.d.ts +3 -2
  637. package/dist/utils/m3u.d.ts.map +1 -0
  638. package/dist/utils/m3u.js +4 -3
  639. package/dist/utils/m3u.js.map +1 -1
  640. package/dist/utils/markup.d.ts +13 -1
  641. package/dist/utils/markup.d.ts.map +1 -0
  642. package/dist/utils/markup.js +28 -4
  643. package/dist/utils/markup.js.map +1 -1
  644. package/dist/utils/memo.d.ts +3 -2
  645. package/dist/utils/memo.d.ts.map +1 -0
  646. package/dist/utils/memo.js +3 -3
  647. package/dist/utils/morganStream.d.ts +1 -0
  648. package/dist/utils/morganStream.d.ts.map +1 -0
  649. package/dist/utils/network.d.ts +1 -0
  650. package/dist/utils/network.d.ts.map +1 -0
  651. package/dist/utils/network.js +2 -2
  652. package/dist/utils/pid.d.ts +3 -25
  653. package/dist/utils/pid.d.ts.map +1 -0
  654. package/dist/utils/pid.js +10 -49
  655. package/dist/utils/pid.js.map +1 -1
  656. package/dist/utils/platform.d.ts +3 -1
  657. package/dist/utils/platform.d.ts.map +1 -0
  658. package/dist/utils/platform.js +2 -1
  659. package/dist/utils/platform.js.map +1 -1
  660. package/dist/utils/processInspector.context.d.ts +8 -0
  661. package/dist/utils/processInspector.context.d.ts.map +1 -0
  662. package/dist/utils/processInspector.context.js +106 -0
  663. package/dist/utils/processInspector.context.js.map +1 -0
  664. package/dist/utils/processInspector.d.ts +55 -0
  665. package/dist/utils/processInspector.d.ts.map +1 -0
  666. package/dist/utils/processInspector.js +127 -0
  667. package/dist/utils/processInspector.js.map +1 -0
  668. package/dist/utils/retry.d.ts +25 -2
  669. package/dist/utils/retry.d.ts.map +1 -0
  670. package/dist/utils/retry.js +33 -6
  671. package/dist/utils/retry.js.map +1 -1
  672. package/dist/utils/runtimeIdentity.context.d.ts +7 -0
  673. package/dist/utils/runtimeIdentity.context.d.ts.map +1 -0
  674. package/dist/utils/runtimeIdentity.context.js +43 -0
  675. package/dist/utils/runtimeIdentity.context.js.map +1 -0
  676. package/dist/utils/runtimeIdentity.d.ts +98 -0
  677. package/dist/utils/runtimeIdentity.d.ts.map +1 -0
  678. package/dist/utils/runtimeIdentity.js +181 -0
  679. package/dist/utils/runtimeIdentity.js.map +1 -0
  680. package/dist/utils/sanitize.d.ts +1 -0
  681. package/dist/utils/sanitize.d.ts.map +1 -0
  682. package/dist/utils/streamContext.d.ts +2 -1
  683. package/dist/utils/streamContext.d.ts.map +1 -0
  684. package/dist/utils/streamContext.js +1 -1
  685. package/dist/utils/timing.d.ts +2 -1
  686. package/dist/utils/timing.d.ts.map +1 -0
  687. package/dist/utils/timing.js +0 -5
  688. package/dist/utils/timing.js.map +1 -1
  689. package/dist/utils/version.d.ts +1 -0
  690. package/dist/utils/version.d.ts.map +1 -0
  691. package/dist/utils/version.js +47 -13
  692. package/dist/utils/version.js.map +1 -1
  693. package/package.json +26 -20
@@ -0,0 +1,264 @@
1
+ import { crc32 } from "node:zlib";
2
+ // Packet type codes from libhdhomerun's hdhomerun_pkt.h. The protocol uses a single GETSET_REQ code (0x0004) for both Get and Set requests; the two are
3
+ // distinguished by the presence or absence of a value TLV in the payload, not by a separate packet code. Discover/Get are the request-reply pairs PrismCast
4
+ // actually answers; Upgrade requests fall through to the transport layer's unsupported handler. The PACKET_UPGRADE_REPLY code is included for completeness
5
+ // even though PrismCast never receives nor emits upgrade replies.
6
+ export const PACKET_DISCOVER_REQUEST = 0x0002;
7
+ export const PACKET_DISCOVER_REPLY = 0x0003;
8
+ export const PACKET_GET_REQUEST = 0x0004;
9
+ export const PACKET_GET_REPLY = 0x0005;
10
+ export const PACKET_UPGRADE_REQUEST = 0x0006;
11
+ export const PACKET_UPGRADE_REPLY = 0x0007;
12
+ // TLV tag identifiers. The numeric values are part of the wire protocol; do not renumber. Discover packets carry the device-class TLVs (0x01, 0x02, 0x10, 0x2A);
13
+ // Get/Set packets carry the name/value/error TLVs (0x03, 0x04, 0x05). The tags match the canonical values published in libhdhomerun's hdhomerun_pkt.h - there
14
+ // is no standard tag for a discrete lineup URL, so clients derive it by appending "/lineup.json" to the base URL.
15
+ export const TLV_DEVICE_TYPE = 0x01;
16
+ export const TLV_DEVICE_ID = 0x02;
17
+ export const TLV_GETSET_NAME = 0x03;
18
+ export const TLV_GETSET_VALUE = 0x04;
19
+ export const TLV_ERROR = 0x05;
20
+ export const TLV_TUNER_COUNT = 0x10;
21
+ export const TLV_BASE_URL = 0x2A;
22
+ // Wildcard sentinel for Discover requests. Clients that want any device send these to filter neither by type nor by id.
23
+ export const HDHR_WILDCARD = 0xFFFFFFFF;
24
+ /**
25
+ * Parses an incoming packet. Returns null when the packet is structurally malformed (too short, length mismatch, bad CRC). Otherwise returns the discriminated
26
+ * record describing the packet's intent. Unknown TLVs within a known packet type are silently skipped - the protocol allows extension TLVs that PrismCast does
27
+ * not understand.
28
+ * @param buf - The raw datagram bytes.
29
+ * @returns The parsed packet or null on malformed input.
30
+ */
31
+ export function parsePacket(buf) {
32
+ // Minimum packet size is the 4-byte header plus the 4-byte CRC. A datagram smaller than that cannot encode a valid packet.
33
+ if (buf.length < 8) {
34
+ return null;
35
+ }
36
+ const packetType = buf.readUInt16BE(0);
37
+ const payloadLength = buf.readUInt16BE(2);
38
+ const expectedSize = 4 + payloadLength + 4;
39
+ // A packet whose declared length does not match the datagram size is corrupt - either fragmentation or a malformed sender.
40
+ if (buf.length !== expectedSize) {
41
+ return null;
42
+ }
43
+ // The CRC covers the header and payload but not the CRC field itself. We compute over slice(0, header + payload) and compare to the trailing little-endian u32.
44
+ const computedCrc = crc32(buf.subarray(0, 4 + payloadLength));
45
+ const declaredCrc = buf.readUInt32LE(4 + payloadLength);
46
+ if (computedCrc !== declaredCrc) {
47
+ return null;
48
+ }
49
+ const payload = buf.subarray(4, 4 + payloadLength);
50
+ const tlvs = decodeTlvs(payload);
51
+ if (tlvs === null) {
52
+ return null;
53
+ }
54
+ switch (packetType) {
55
+ case PACKET_DISCOVER_REQUEST: {
56
+ // Discover requests may include device-type and device-id filters. Both default to wildcard when missing so a request with no filters matches everything.
57
+ const requestedDeviceType = readU32Tlv(tlvs, TLV_DEVICE_TYPE) ?? HDHR_WILDCARD;
58
+ const requestedDeviceId = readU32Tlv(tlvs, TLV_DEVICE_ID) ?? HDHR_WILDCARD;
59
+ return { requestedDeviceId, requestedDeviceType, type: "discover" };
60
+ }
61
+ case PACKET_GET_REQUEST: {
62
+ const name = readStringTlv(tlvs, TLV_GETSET_NAME);
63
+ if (name === null) {
64
+ return null;
65
+ }
66
+ const value = readStringTlv(tlvs, TLV_GETSET_VALUE);
67
+ // Get requests carry only a name; Set requests carry both a name and a value. The protocol uses the same 0x0004 packet type for both - the presence of
68
+ // the value TLV distinguishes them. This is unusual but documented in libhdhomerun's source.
69
+ if (value !== null) {
70
+ return { name, type: "set", value };
71
+ }
72
+ return { name, type: "get" };
73
+ }
74
+ default: {
75
+ return { packetType, type: "unsupported" };
76
+ }
77
+ }
78
+ }
79
+ /**
80
+ * Builds a Discover reply packet. The reply is short enough to fit in a single datagram even with all fields populated; the largest contributor is the base
81
+ * URL string which is typically under 50 bytes.
82
+ * @param fields - The device-identity values to serialize.
83
+ * @returns A complete wire-formatted packet ready to send via socket.send.
84
+ */
85
+ export function buildDiscoverReply(fields) {
86
+ // Pre-compute each TLV so we can compose them in tag order. The wire order is conventional but not strictly required by the protocol - listing tags in
87
+ // ascending tag order matches real HDHomeRun reply traces and avoids client implementations that assume a specific order. TunerCount is encoded as an 8-bit
88
+ // value because real HDHR devices report it that way (real-world tuner counts fit in a byte; the wire format reflects that).
89
+ const tlvs = [
90
+ encodeU32Tlv(TLV_DEVICE_TYPE, fields.deviceType),
91
+ encodeU32Tlv(TLV_DEVICE_ID, fields.deviceId),
92
+ encodeU8Tlv(TLV_TUNER_COUNT, fields.tunerCount),
93
+ encodeStringTlv(TLV_BASE_URL, fields.baseUrl)
94
+ ];
95
+ return buildPacket(PACKET_DISCOVER_REPLY, Buffer.concat(tlvs));
96
+ }
97
+ /**
98
+ * Builds a Get reply packet carrying a name/value pair. Used when answering a known Get key with a real value.
99
+ * @param name - The Get key being answered (echoed back in the reply).
100
+ * @param value - The value returned for that key.
101
+ * @returns A complete wire-formatted packet.
102
+ */
103
+ export function buildGetReply(name, value) {
104
+ const payload = Buffer.concat([
105
+ encodeStringTlv(TLV_GETSET_NAME, name),
106
+ encodeStringTlv(TLV_GETSET_VALUE, value)
107
+ ]);
108
+ return buildPacket(PACKET_GET_REPLY, payload);
109
+ }
110
+ /**
111
+ * Builds a Get reply packet carrying an error string. Used when answering a Get for an unknown key or rejecting a Set or Upgrade request. Real HDHomeRun
112
+ * firmware uses "ERROR: ..." prose for the error TLV; we follow the same convention so client error messages remain familiar to operators.
113
+ * @param name - The key being answered (echoed back).
114
+ * @param error - The error string. Should begin with "ERROR: " per HDHR convention.
115
+ * @returns A complete wire-formatted packet.
116
+ */
117
+ export function buildErrorReply(name, error) {
118
+ const payload = Buffer.concat([
119
+ encodeStringTlv(TLV_GETSET_NAME, name),
120
+ encodeStringTlv(TLV_ERROR, error)
121
+ ]);
122
+ return buildPacket(PACKET_GET_REPLY, payload);
123
+ }
124
+ /**
125
+ * Composes a complete packet: 4-byte header, payload, 4-byte little-endian CRC of header + payload. The CRC is computed last so the packet body is valid bytes
126
+ * before sealing.
127
+ * @param packetType - The packet type code.
128
+ * @param payload - The TLV-encoded payload bytes.
129
+ * @returns The complete packet.
130
+ */
131
+ function buildPacket(packetType, payload) {
132
+ const header = Buffer.alloc(4);
133
+ header.writeUInt16BE(packetType, 0);
134
+ header.writeUInt16BE(payload.length, 2);
135
+ const body = Buffer.concat([header, payload]);
136
+ const checksum = Buffer.alloc(4);
137
+ checksum.writeUInt32LE(crc32(body), 0);
138
+ return Buffer.concat([body, checksum]);
139
+ }
140
+ /**
141
+ * Encodes a 32-bit unsigned integer TLV. The four-byte value is written big-endian to match the wire protocol.
142
+ * @param tag - The TLV tag.
143
+ * @param value - The unsigned 32-bit value.
144
+ * @returns The TLV bytes (tag + length + value).
145
+ */
146
+ function encodeU32Tlv(tag, value) {
147
+ const buf = Buffer.alloc(6);
148
+ buf.writeUInt8(tag, 0);
149
+ buf.writeUInt8(4, 1);
150
+ buf.writeUInt32BE(value >>> 0, 2);
151
+ return buf;
152
+ }
153
+ /**
154
+ * Encodes an 8-bit unsigned integer TLV. Used for fields like tuner count whose values fit in a single byte and are documented as one-byte on the wire.
155
+ * @param tag - The TLV tag.
156
+ * @param value - The unsigned 8-bit value.
157
+ * @returns The TLV bytes (tag + length + value).
158
+ */
159
+ function encodeU8Tlv(tag, value) {
160
+ const buf = Buffer.alloc(3);
161
+ buf.writeUInt8(tag, 0);
162
+ buf.writeUInt8(1, 1);
163
+ buf.writeUInt8(value & 0xFF, 2);
164
+ return buf;
165
+ }
166
+ /**
167
+ * Encodes a string TLV. The string is serialized as UTF-8 with a trailing NUL byte (HDHomeRun convention), so a 10-character string occupies 11 bytes of value.
168
+ * Values longer than 127 bytes use the two-byte length encoding; PrismCast never emits values that long, but the encoder remains correct if a future field
169
+ * exceeds the threshold.
170
+ * @param tag - The TLV tag.
171
+ * @param value - The string value.
172
+ * @returns The TLV bytes (tag + length + UTF-8 bytes + NUL).
173
+ */
174
+ function encodeStringTlv(tag, value) {
175
+ const bodyBytes = Buffer.from(value + "\0", "utf8");
176
+ const length = bodyBytes.length;
177
+ // Length under 128 fits in the single-byte form. The two-byte form is included for correctness even though our outgoing values never need it.
178
+ if (length < 128) {
179
+ const buf = Buffer.alloc(2 + length);
180
+ buf.writeUInt8(tag, 0);
181
+ buf.writeUInt8(length, 1);
182
+ bodyBytes.copy(buf, 2);
183
+ return buf;
184
+ }
185
+ // Two-byte length form: first byte has high bit set carrying low 7 bits of length; second byte carries the high 8 bits. Little-endian.
186
+ const buf = Buffer.alloc(3 + length);
187
+ buf.writeUInt8(tag, 0);
188
+ buf.writeUInt8((length & 0x7F) | 0x80, 1);
189
+ buf.writeUInt8((length >>> 7) & 0xFF, 2);
190
+ bodyBytes.copy(buf, 3);
191
+ return buf;
192
+ }
193
+ /**
194
+ * Decodes a TLV-encoded payload into a list of records. Returns null when the payload is structurally malformed (a length field that overruns the remaining
195
+ * bytes). Unknown tags pass through; the caller decides whether to use them.
196
+ * @param payload - The raw payload bytes (header and CRC already stripped).
197
+ * @returns The decoded TLVs or null on malformed input.
198
+ */
199
+ function decodeTlvs(payload) {
200
+ const tlvs = [];
201
+ let offset = 0;
202
+ while (offset < payload.length) {
203
+ // Need at least tag + first length byte to make progress; anything shorter is truncation.
204
+ if ((offset + 2) > payload.length) {
205
+ return null;
206
+ }
207
+ const tag = payload.readUInt8(offset);
208
+ const lengthByte = payload.readUInt8(offset + 1);
209
+ let length;
210
+ let headerSize;
211
+ // High bit set on the length byte signals the two-byte length form; clear means single-byte length 0-127.
212
+ if ((lengthByte & 0x80) !== 0) {
213
+ if ((offset + 3) > payload.length) {
214
+ return null;
215
+ }
216
+ length = (lengthByte & 0x7F) | (payload.readUInt8(offset + 2) << 7);
217
+ headerSize = 3;
218
+ }
219
+ else {
220
+ length = lengthByte;
221
+ headerSize = 2;
222
+ }
223
+ const valueStart = offset + headerSize;
224
+ const valueEnd = valueStart + length;
225
+ if (valueEnd > payload.length) {
226
+ return null;
227
+ }
228
+ tlvs.push({ tag, value: payload.subarray(valueStart, valueEnd) });
229
+ offset = valueEnd;
230
+ }
231
+ return tlvs;
232
+ }
233
+ /**
234
+ * Looks up a 32-bit unsigned integer TLV by tag. Returns null when the tag is missing or its value is not exactly four bytes. The big-endian read matches the
235
+ * wire format.
236
+ * @param tlvs - The decoded TLV list.
237
+ * @param tag - The tag to look up.
238
+ * @returns The 32-bit value or null.
239
+ */
240
+ function readU32Tlv(tlvs, tag) {
241
+ const entry = tlvs.find((t) => (t.tag === tag));
242
+ if (entry?.value.length !== 4) {
243
+ return null;
244
+ }
245
+ return entry.value.readUInt32BE(0);
246
+ }
247
+ /**
248
+ * Looks up a string TLV by tag. Returns null when the tag is missing. The trailing NUL byte (HDHomeRun convention) is stripped before decoding so callers
249
+ * receive the bare string.
250
+ * @param tlvs - The decoded TLV list.
251
+ * @param tag - The tag to look up.
252
+ * @returns The string value or null.
253
+ */
254
+ function readStringTlv(tlvs, tag) {
255
+ const entry = tlvs.find((t) => (t.tag === tag));
256
+ if (!entry) {
257
+ return null;
258
+ }
259
+ // Strip a single trailing NUL if present; senders that omit the NUL still produce a valid string. .at(-1) returns undefined on an empty buffer, so the zero-
260
+ // length case is handled by the strict-equality check without a separate length guard.
261
+ const trimmed = (entry.value.at(-1) === 0) ? entry.value.subarray(0, -1) : entry.value;
262
+ return trimmed.toString("utf8");
263
+ }
264
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/hdhr/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Nullable } from "../types/index.ts";
2
+ /**
3
+ * Slot-indexed projection of stream state. Every configured tuner slot produces one entry; active slots carry channel and client info while idle slots carry
4
+ * only the resource name. Wire-format conversion (to JSON for HTTP, to plain strings or space-delimited key=value strings for UDP Get replies) happens in
5
+ * the consumer.
6
+ */
7
+ export interface TunerState {
8
+ readonly active: boolean;
9
+ readonly channelName: Nullable<string>;
10
+ readonly channelNumber: Nullable<number>;
11
+ readonly clientAddress: Nullable<string>;
12
+ readonly resource: string;
13
+ readonly slot: number;
14
+ }
15
+ /**
16
+ * Returns the current slot-indexed projection of stream state. Active streams (sorted by stream id) take the first N slots; remaining slots through the
17
+ * configured maxConcurrentStreams are returned as idle entries. The array length is max(maxConcurrentStreams, activeStreams): in the normal case it equals
18
+ * maxConcurrentStreams, but if the active stream count exceeds the configured limit - reachable by lowering maxConcurrentStreams while streams are running,
19
+ * since live streams are not terminated by a limit change - every active stream is still reported and there are simply no idle entries. We never drop an
20
+ * active tuner and never report fewer slots than there are active streams, because a real HDHomeRun cannot have fewer tuners than it has active recordings.
21
+ * @returns Slot-indexed array of TunerState records.
22
+ */
23
+ export declare function getTunerStates(): readonly TunerState[];
24
+ //# sourceMappingURL=tunerState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunerState.d.ts","sourceRoot":"","sources":["../../src/hdhr/tunerState.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAKlD;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAGzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAIzB,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAGvC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAGzC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAGzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAG1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,SAAS,UAAU,EAAE,CA+CtD"}
@@ -0,0 +1,67 @@
1
+ /* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * tunerState.ts: HDHomeRun tuner-slot state for PrismCast.
4
+ *
5
+ * Real HDHomeRun devices expose a fixed number of "tuner" slots indexed from zero. PrismCast does not have RF tuners but emulates the model: the configured
6
+ * maxConcurrentStreams becomes the slot count, and each active stream binds to the next free slot in stream-ID order. Two HDHR consumers need the same slot-
7
+ * indexed view of current state:
8
+ *
9
+ * 1. The HTTP /status.json endpoint serves it to monitoring dashboards (Home Assistant, Homepage) as a JSON array of HDHR-shaped tuner entries.
10
+ * 2. The UDP control plane on port 65001 serves it to clients that issue Get requests for /tuner<N>/channel, /tuner<N>/status, /tuner<N>/target, etc.
11
+ *
12
+ * This module is the single source of truth for the slot-indexed projection. It returns format-neutral TunerState records; each consumer formats them into the
13
+ * wire shape its protocol expects (JSON keys for HTTP, plain strings and space-delimited key=value pairs for UDP). Keeping the projection here means the
14
+ * channel-map merge logic, the fallback-to-stream-name handling, and the client-address normalization live in one place, so an HDHR feature gap or a
15
+ * refactor of the underlying registry surfaces in exactly one location.
16
+ */
17
+ import { CONFIG } from "../config/index.js";
18
+ import { buildChannelMap } from "./channelMap.js";
19
+ import { getAllStreams } from "../streaming/registry.js";
20
+ import { normalizeClientAddress } from "../utils/index.js";
21
+ /**
22
+ * Returns the current slot-indexed projection of stream state. Active streams (sorted by stream id) take the first N slots; remaining slots through the
23
+ * configured maxConcurrentStreams are returned as idle entries. The array length is max(maxConcurrentStreams, activeStreams): in the normal case it equals
24
+ * maxConcurrentStreams, but if the active stream count exceeds the configured limit - reachable by lowering maxConcurrentStreams while streams are running,
25
+ * since live streams are not terminated by a limit change - every active stream is still reported and there are simply no idle entries. We never drop an
26
+ * active tuner and never report fewer slots than there are active streams, because a real HDHomeRun cannot have fewer tuners than it has active recordings.
27
+ * @returns Slot-indexed array of TunerState records.
28
+ */
29
+ export function getTunerStates() {
30
+ const channelMap = buildChannelMap();
31
+ const channelByKey = new Map(channelMap.map((entry) => [entry.key, entry]));
32
+ const streams = getAllStreams().toSorted((a, b) => a.id - b.id);
33
+ // Slot count is the larger of the configured limit and the live active-stream count. Clamping to the configured limit would drop real active tuners from the
34
+ // projection when the operator lowers maxConcurrentStreams mid-stream; taking the max keeps every active stream visible and lets the idle-fill loop below be
35
+ // a no-op in the oversubscribed case rather than producing a negative range.
36
+ const tunerCount = Math.max(CONFIG.streaming.maxConcurrentStreams, streams.length);
37
+ const states = [];
38
+ // Active slots: one entry per running stream, in stream-id order. Channel info merges from the lineup with a fallback to stream.channelName.
39
+ for (const [slot, stream] of streams.entries()) {
40
+ const channelEntry = channelByKey.get(stream.info.storeKey);
41
+ const channelName = channelEntry?.name ?? stream.channelName ?? null;
42
+ const channelNumber = channelEntry ? channelEntry.number : null;
43
+ const clientAddress = stream.clientAddress ? normalizeClientAddress(stream.clientAddress) : null;
44
+ states.push({
45
+ active: true,
46
+ channelName,
47
+ channelNumber,
48
+ clientAddress,
49
+ resource: "tuner" + String(slot),
50
+ slot
51
+ });
52
+ }
53
+ // Idle slots fill the remaining capacity up to tunerCount. When oversubscribed (active streams exceed the configured limit) tunerCount equals the active
54
+ // count, so this loop runs zero times and the array is all-active - never a negative range, never a dropped tuner.
55
+ for (let slot = streams.length; slot < tunerCount; slot++) {
56
+ states.push({
57
+ active: false,
58
+ channelName: null,
59
+ channelNumber: null,
60
+ clientAddress: null,
61
+ resource: "tuner" + String(slot),
62
+ slot
63
+ });
64
+ }
65
+ return states;
66
+ }
67
+ //# sourceMappingURL=tunerState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunerState.js","sourceRoot":"","sources":["../../src/hdhr/tunerState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AA6B3D;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc;IAE5B,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAEhE,6JAA6J;IAC7J,6JAA6J;IAC7J,6EAA6E;IAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnF,MAAM,MAAM,GAAiB,EAAE,CAAC;IAEhC,6IAA6I;IAC7I,KAAI,MAAM,CAAE,IAAI,EAAE,MAAM,CAAE,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAEhD,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,YAAY,EAAE,IAAI,IAAI,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;QACrE,MAAM,aAAa,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAChE,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAEjG,MAAM,CAAC,IAAI,CAAC;YAEV,MAAM,EAAE,IAAI;YACZ,WAAW;YACX,aAAa;YACb,aAAa;YACb,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;YAChC,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,yJAAyJ;IACzJ,mHAAmH;IACnH,KAAI,IAAI,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,GAAG,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;QAEzD,MAAM,CAAC,IAAI,CAAC;YAEV,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,IAAI;YACnB,aAAa,EAAE,IAAI;YACnB,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;YAChC,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { NetworkInterfaceInfo } from "node:os";
2
+ import type { Nullable } from "../types/index.ts";
3
+ export declare const HDHR_DISCOVERY_PORT = 65001;
4
+ /**
5
+ * Options for UdpSurface.ensureUp. Tests pass an ephemeral port (0) so the kernel picks a free port; production passes the httpPortProvider so Discover replies
6
+ * advertise the real bound HTTP port.
7
+ */
8
+ export interface UdpSurfaceOptions {
9
+ readonly bindAddress?: string;
10
+ readonly httpPortProvider?: () => Nullable<number>;
11
+ readonly port?: number;
12
+ }
13
+ /**
14
+ * A self-disposing HDHomeRun UDP discovery surface. The node owns exactly one responder socket and the captured HTTP-port provider, cycling the socket up and
15
+ * down via ensureUp/ensureDown as the controller reconciles CONFIG.hdhr. ensureDown is exposed as [Symbol.asyncDispose] so the surface composes with the rest of
16
+ * the resource-ownership tree; disposal closes the current socket but leaves the node reusable (a later ensureUp rebinds), because this is owner-bounded, not
17
+ * scope-bounded, disposal.
18
+ */
19
+ export interface UdpSurface extends AsyncDisposable {
20
+ readonly boundPort: Nullable<number>;
21
+ ensureDown(): Promise<void>;
22
+ ensureUp(options?: UdpSurfaceOptions): Promise<boolean>;
23
+ }
24
+ /**
25
+ * Creates an HDHomeRun UDP discovery surface node. The returned object fully owns its socket; nothing outside the closure touches it. ensureUp/ensureDown are the
26
+ * cycling verbs the controller drives; [Symbol.asyncDispose] aliases ensureDown so the surface is a well-formed async-disposable resource.
27
+ * @returns A UdpSurface node.
28
+ */
29
+ export declare function createUdpSurface(): UdpSurface;
30
+ /**
31
+ * Selects the local IPv4 address that is reachable from the requester's subnet. Walks os.networkInterfaces, computes each interface's network address via its
32
+ * netmask, and returns the matching interface's address. Falls back to the first non-loopback IPv4 address when no subnet matches (typical on hosts whose
33
+ * routing crosses a layer-3 boundary). Returns "127.0.0.1" as the last resort - clients reaching us on loopback will use it; clients on the LAN that hit this
34
+ * branch will fail to reach back, but that scenario implies a misconfigured host where LAN advertising would not help anyway.
35
+ *
36
+ * Exposed (and parameterized over network interfaces) primarily for tests; the production call site uses os.networkInterfaces() directly via the default
37
+ * parameter.
38
+ * @param targetAddress - The requester's IPv4 address (from dgram rinfo).
39
+ * @param interfaces - Map of interface name to NetworkInterfaceInfo array (defaults to os.networkInterfaces()).
40
+ * @returns The selected local IPv4 address.
41
+ */
42
+ export declare function selectLanAddress(targetAddress: string, interfaces?: NodeJS.Dict<NetworkInterfaceInfo[]>): string;
43
+ //# sourceMappingURL=udp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/hdhr/udp.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,oBAAoB,EAA4B,MAAM,SAAS,CAAC;AAI9E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAUlD,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAGhC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAG9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;IAGnD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAW,SAAQ,eAAe;IAIjD,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAGrC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAI5B,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CA2H7C;AAgGD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAuB,GAAG,MAAM,CAiDrI"}