@mentra/engine 0.1.0-beta.0 → 0.1.0-dev.1

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 (355) hide show
  1. package/README.md +42 -1
  2. package/build/engine.d.ts +11 -3
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +7 -2
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts.map +1 -1
  7. package/build/facades/dev.js +9 -5
  8. package/build/facades/dev.js.map +1 -1
  9. package/build/facades/gallery.js +1 -1
  10. package/build/facades/gallery.js.map +1 -1
  11. package/build/facades/glasses.d.ts +1 -0
  12. package/build/facades/glasses.d.ts.map +1 -1
  13. package/build/facades/glasses.js +19 -4
  14. package/build/facades/glasses.js.map +1 -1
  15. package/build/facades/glassesSettings.d.ts.map +1 -1
  16. package/build/facades/glassesSettings.js +1 -0
  17. package/build/facades/glassesSettings.js.map +1 -1
  18. package/build/facades/miniapps.d.ts +4 -0
  19. package/build/facades/miniapps.d.ts.map +1 -1
  20. package/build/facades/miniapps.js +5 -0
  21. package/build/facades/miniapps.js.map +1 -1
  22. package/build/facades/ota.d.ts +11 -2
  23. package/build/facades/ota.d.ts.map +1 -1
  24. package/build/facades/ota.js +19 -4
  25. package/build/facades/ota.js.map +1 -1
  26. package/build/facades/pairing.d.ts +4 -0
  27. package/build/facades/pairing.d.ts.map +1 -1
  28. package/build/facades/pairing.js +10 -8
  29. package/build/facades/pairing.js.map +1 -1
  30. package/build/facades/phoneNotifications.d.ts +0 -4
  31. package/build/facades/phoneNotifications.d.ts.map +1 -1
  32. package/build/facades/phoneNotifications.js +4 -14
  33. package/build/facades/phoneNotifications.js.map +1 -1
  34. package/build/index.d.ts +6 -3
  35. package/build/index.d.ts.map +1 -1
  36. package/build/index.js +4 -2
  37. package/build/index.js.map +1 -1
  38. package/build/internal.d.ts +2 -2
  39. package/build/internal.d.ts.map +1 -1
  40. package/build/internal.js +1 -1
  41. package/build/internal.js.map +1 -1
  42. package/build/react/MentraLiveOtaFlow.d.ts +38 -0
  43. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  44. package/build/react/MentraLiveOtaFlow.js +528 -0
  45. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  46. package/build/react/index.d.ts +2 -0
  47. package/build/react/index.d.ts.map +1 -0
  48. package/build/react/index.js +2 -0
  49. package/build/react/index.js.map +1 -0
  50. package/build/react/useEngineSnapshot.d.ts +2 -0
  51. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  52. package/build/react/useEngineSnapshot.js +14 -0
  53. package/build/react/useEngineSnapshot.js.map +1 -0
  54. package/build/runtime/bootstrap.d.ts +24 -1
  55. package/build/runtime/bootstrap.d.ts.map +1 -1
  56. package/build/runtime/bootstrap.js +17 -0
  57. package/build/runtime/bootstrap.js.map +1 -1
  58. package/build/runtime/scanQrSeam.d.ts +7 -0
  59. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  60. package/build/runtime/scanQrSeam.js +16 -0
  61. package/build/runtime/scanQrSeam.js.map +1 -0
  62. package/build/services/AppRegistry.d.ts +18 -8
  63. package/build/services/AppRegistry.d.ts.map +1 -1
  64. package/build/services/AppRegistry.js +44 -45
  65. package/build/services/AppRegistry.js.map +1 -1
  66. package/build/services/AudioCloudUplink.d.ts +9 -3
  67. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  68. package/build/services/AudioCloudUplink.js +9 -3
  69. package/build/services/AudioCloudUplink.js.map +1 -1
  70. package/build/services/AudioPlaybackService.d.ts +9 -1
  71. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  72. package/build/services/AudioPlaybackService.js +77 -32
  73. package/build/services/AudioPlaybackService.js.map +1 -1
  74. package/build/services/BlobStore.d.ts +2 -1
  75. package/build/services/BlobStore.d.ts.map +1 -1
  76. package/build/services/BlobStore.js +17 -9
  77. package/build/services/BlobStore.js.map +1 -1
  78. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  79. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  80. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  81. package/build/services/CloudClientService.d.ts +15 -0
  82. package/build/services/CloudClientService.d.ts.map +1 -1
  83. package/build/services/CloudClientService.js +75 -0
  84. package/build/services/CloudClientService.js.map +1 -1
  85. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  86. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  87. package/build/services/ForegroundLocationPermission.js +12 -0
  88. package/build/services/ForegroundLocationPermission.js.map +1 -0
  89. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  90. package/build/services/GlassesSettingsSync.js +9 -3
  91. package/build/services/GlassesSettingsSync.js.map +1 -1
  92. package/build/services/GlassesStatusProjection.d.ts +2 -1
  93. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  94. package/build/services/GlassesStatusProjection.js +15 -8
  95. package/build/services/GlassesStatusProjection.js.map +1 -1
  96. package/build/services/HotspotOtaTransport.d.ts +29 -0
  97. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  98. package/build/services/HotspotOtaTransport.js +146 -0
  99. package/build/services/HotspotOtaTransport.js.map +1 -0
  100. package/build/services/HotspotShutdown.d.ts +17 -0
  101. package/build/services/HotspotShutdown.d.ts.map +1 -0
  102. package/build/services/HotspotShutdown.js +29 -0
  103. package/build/services/HotspotShutdown.js.map +1 -0
  104. package/build/services/LocalDisplayManager.d.ts +15 -0
  105. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  106. package/build/services/LocalDisplayManager.js +106 -20
  107. package/build/services/LocalDisplayManager.js.map +1 -1
  108. package/build/services/LocalMiniappRuntime.d.ts +67 -1
  109. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  110. package/build/services/LocalMiniappRuntime.js +486 -126
  111. package/build/services/LocalMiniappRuntime.js.map +1 -1
  112. package/build/services/LocalMiniappStorage.d.ts +32 -0
  113. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  114. package/build/services/LocalMiniappStorage.js +66 -0
  115. package/build/services/LocalMiniappStorage.js.map +1 -0
  116. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  117. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  118. package/build/services/LocalMiniappUserIdentity.js +43 -0
  119. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  120. package/build/services/MicStateCoordinator.d.ts +42 -1
  121. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  122. package/build/services/MicStateCoordinator.js +141 -3
  123. package/build/services/MicStateCoordinator.js.map +1 -1
  124. package/build/services/MiniappLauncher.d.ts.map +1 -1
  125. package/build/services/MiniappLauncher.js +23 -3
  126. package/build/services/MiniappLauncher.js.map +1 -1
  127. package/build/services/MiniappLiveness.d.ts +12 -0
  128. package/build/services/MiniappLiveness.d.ts.map +1 -0
  129. package/build/services/MiniappLiveness.js +16 -0
  130. package/build/services/MiniappLiveness.js.map +1 -0
  131. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  132. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  133. package/build/services/OtaArtifactDownloader.js +226 -0
  134. package/build/services/OtaArtifactDownloader.js.map +1 -0
  135. package/build/services/OtaAutoChain.d.ts +34 -0
  136. package/build/services/OtaAutoChain.d.ts.map +1 -0
  137. package/build/services/OtaAutoChain.js +83 -0
  138. package/build/services/OtaAutoChain.js.map +1 -0
  139. package/build/services/OtaErrorMapping.d.ts +18 -0
  140. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  141. package/build/services/OtaErrorMapping.js +63 -0
  142. package/build/services/OtaErrorMapping.js.map +1 -0
  143. package/build/services/OtaInstallCoordinator.d.ts +94 -14
  144. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  145. package/build/services/OtaInstallCoordinator.js +574 -130
  146. package/build/services/OtaInstallCoordinator.js.map +1 -1
  147. package/build/services/OtaService.d.ts.map +1 -1
  148. package/build/services/OtaService.js +8 -1
  149. package/build/services/OtaService.js.map +1 -1
  150. package/build/services/OtaUpdateCheckService.d.ts +38 -3
  151. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  152. package/build/services/OtaUpdateCheckService.js +142 -22
  153. package/build/services/OtaUpdateCheckService.js.map +1 -1
  154. package/build/services/PhoneCalendarService.d.ts.map +1 -1
  155. package/build/services/PhoneCalendarService.js +22 -1
  156. package/build/services/PhoneCalendarService.js.map +1 -1
  157. package/build/services/PhoneCameraFovCoordinator.d.ts +2 -0
  158. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  159. package/build/services/PhoneCameraFovCoordinator.js +14 -0
  160. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  161. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  162. package/build/services/PhoneNotificationsSync.js +12 -10
  163. package/build/services/PhoneNotificationsSync.js.map +1 -1
  164. package/build/services/PhonePhotoCoordinator.d.ts +10 -3
  165. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  166. package/build/services/PhonePhotoCoordinator.js +21 -3
  167. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  168. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  169. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  170. package/build/services/PhoneStreamCoordinator.js +125 -13
  171. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  172. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  173. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  174. package/build/services/PhoneVideoCoordinator.js +10 -0
  175. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  176. package/build/services/SceneRenderer.d.ts.map +1 -1
  177. package/build/services/SceneRenderer.js +15 -0
  178. package/build/services/SceneRenderer.js.map +1 -1
  179. package/build/services/SupportProfileSync.d.ts +22 -0
  180. package/build/services/SupportProfileSync.d.ts.map +1 -0
  181. package/build/services/SupportProfileSync.js +213 -0
  182. package/build/services/SupportProfileSync.js.map +1 -0
  183. package/build/services/TtsTextSanitizer.d.ts +5 -0
  184. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  185. package/build/services/TtsTextSanitizer.js +61 -0
  186. package/build/services/TtsTextSanitizer.js.map +1 -0
  187. package/build/services/WifiAdbRequest.d.ts +17 -0
  188. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  189. package/build/services/WifiAdbRequest.js +35 -0
  190. package/build/services/WifiAdbRequest.js.map +1 -0
  191. package/build/services/asg/asgCameraApi.d.ts +3 -0
  192. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  193. package/build/services/asg/asgCameraApi.js +72 -2
  194. package/build/services/asg/asgCameraApi.js.map +1 -1
  195. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  196. package/build/services/asg/gallerySyncService.js +26 -14
  197. package/build/services/asg/gallerySyncService.js.map +1 -1
  198. package/build/services/asg/localNetworkTransport.d.ts +2 -2
  199. package/build/services/asg/localNetworkTransport.d.ts.map +1 -1
  200. package/build/services/asg/localNetworkTransport.js +6 -6
  201. package/build/services/asg/localNetworkTransport.js.map +1 -1
  202. package/build/services/audioPlaybackAssets.d.ts +8 -0
  203. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  204. package/build/services/audioPlaybackAssets.js +7 -0
  205. package/build/services/audioPlaybackAssets.js.map +1 -0
  206. package/build/services/glassesClockSync.js +2 -2
  207. package/build/services/glassesClockSync.js.map +1 -1
  208. package/build/services/manifestActions.d.ts +7 -0
  209. package/build/services/manifestActions.d.ts.map +1 -0
  210. package/build/services/manifestActions.js +25 -0
  211. package/build/services/manifestActions.js.map +1 -0
  212. package/build/services/otaDisplayState.d.ts +22 -11
  213. package/build/services/otaDisplayState.d.ts.map +1 -1
  214. package/build/services/otaDisplayState.js +36 -14
  215. package/build/services/otaDisplayState.js.map +1 -1
  216. package/build/services/otaInstallPolicy.d.ts +15 -3
  217. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  218. package/build/services/otaInstallPolicy.js +24 -3
  219. package/build/services/otaInstallPolicy.js.map +1 -1
  220. package/build/services/otaManifestUrl.d.ts +2 -0
  221. package/build/services/otaManifestUrl.d.ts.map +1 -0
  222. package/build/services/{asgOtaVersionUrl.js → otaManifestUrl.js} +15 -5
  223. package/build/services/otaManifestUrl.js.map +1 -0
  224. package/build/services/slimStreamStatus.d.ts +11 -0
  225. package/build/services/slimStreamStatus.d.ts.map +1 -1
  226. package/build/services/slimStreamStatus.js +14 -4
  227. package/build/services/slimStreamStatus.js.map +1 -1
  228. package/build/stores/apps.d.ts.map +1 -1
  229. package/build/stores/apps.js +11 -0
  230. package/build/stores/apps.js.map +1 -1
  231. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  232. package/build/stores/bluetoothSettingKeys.js +2 -0
  233. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  234. package/build/stores/gallerySync.d.ts +2 -0
  235. package/build/stores/gallerySync.d.ts.map +1 -1
  236. package/build/stores/gallerySync.js +2 -0
  237. package/build/stores/gallerySync.js.map +1 -1
  238. package/build/stores/glasses.d.ts.map +1 -1
  239. package/build/stores/glasses.js +3 -0
  240. package/build/stores/glasses.js.map +1 -1
  241. package/build/stores/settings.d.ts +17 -0
  242. package/build/stores/settings.d.ts.map +1 -1
  243. package/build/stores/settings.js +152 -19
  244. package/build/stores/settings.js.map +1 -1
  245. package/build/types/applet.d.ts +2 -0
  246. package/build/types/applet.d.ts.map +1 -1
  247. package/build/types/applet.js.map +1 -1
  248. package/build/types/enums.d.ts +1 -0
  249. package/build/types/enums.d.ts.map +1 -1
  250. package/build/types/enums.js +1 -0
  251. package/build/types/enums.js.map +1 -1
  252. package/build/types/hardware.d.ts +1 -0
  253. package/build/types/hardware.d.ts.map +1 -1
  254. package/build/types/hardware.js +14 -0
  255. package/build/types/hardware.js.map +1 -1
  256. package/build/utils/configuredDevHost.d.ts +6 -0
  257. package/build/utils/configuredDevHost.d.ts.map +1 -0
  258. package/build/utils/configuredDevHost.js +19 -0
  259. package/build/utils/configuredDevHost.js.map +1 -0
  260. package/build/utils/devMiniappLaunch.d.ts +19 -8
  261. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  262. package/build/utils/devMiniappLaunch.js +144 -21
  263. package/build/utils/devMiniappLaunch.js.map +1 -1
  264. package/build/utils/diagnosticContext.d.ts.map +1 -1
  265. package/build/utils/diagnosticContext.js +15 -17
  266. package/build/utils/diagnosticContext.js.map +1 -1
  267. package/build/utils/hardware/hardware.d.ts.map +1 -1
  268. package/build/utils/hardware/hardware.js +7 -3
  269. package/build/utils/hardware/hardware.js.map +1 -1
  270. package/build/utils/miniappDiagnostics.d.ts +64 -0
  271. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  272. package/build/utils/miniappDiagnostics.js +173 -0
  273. package/build/utils/miniappDiagnostics.js.map +1 -0
  274. package/build/utils/timers/timers.d.ts.map +1 -1
  275. package/build/utils/timers/timers.js +55 -18
  276. package/build/utils/timers/timers.js.map +1 -1
  277. package/package.json +27 -18
  278. package/src/assets/silence.wav +0 -0
  279. package/src/engine.ts +7 -2
  280. package/src/facades/dev.ts +9 -5
  281. package/src/facades/gallery.ts +1 -1
  282. package/src/facades/glasses.ts +17 -4
  283. package/src/facades/glassesSettings.ts +5 -0
  284. package/src/facades/miniapps.ts +7 -0
  285. package/src/facades/ota.ts +19 -4
  286. package/src/facades/pairing.ts +11 -7
  287. package/src/facades/phoneNotifications.ts +4 -13
  288. package/src/index.ts +26 -2
  289. package/src/internal.ts +2 -1
  290. package/src/react/MentraLiveOtaFlow.tsx +856 -0
  291. package/src/react/index.ts +7 -0
  292. package/src/react/useEngineSnapshot.ts +16 -0
  293. package/src/runtime/bootstrap.ts +33 -1
  294. package/src/runtime/scanQrSeam.ts +20 -0
  295. package/src/services/AppRegistry.ts +72 -48
  296. package/src/services/AudioCloudUplink.ts +9 -3
  297. package/src/services/AudioPlaybackService.ts +94 -34
  298. package/src/services/BlobStore.ts +22 -9
  299. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  300. package/src/services/CloudClientService.ts +74 -0
  301. package/src/services/ForegroundLocationPermission.ts +24 -0
  302. package/src/services/GlassesSettingsSync.ts +9 -3
  303. package/src/services/GlassesStatusProjection.ts +16 -8
  304. package/src/services/HotspotOtaTransport.ts +184 -0
  305. package/src/services/HotspotShutdown.ts +41 -0
  306. package/src/services/LocalDisplayManager.ts +112 -21
  307. package/src/services/LocalMiniappRuntime.ts +576 -130
  308. package/src/services/LocalMiniappStorage.ts +82 -0
  309. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  310. package/src/services/MicStateCoordinator.ts +169 -4
  311. package/src/services/MiniappLauncher.ts +30 -3
  312. package/src/services/MiniappLiveness.ts +24 -0
  313. package/src/services/OtaArtifactDownloader.ts +312 -0
  314. package/src/services/OtaAutoChain.ts +106 -0
  315. package/src/services/OtaErrorMapping.ts +80 -0
  316. package/src/services/OtaInstallCoordinator.ts +645 -143
  317. package/src/services/OtaService.ts +11 -5
  318. package/src/services/OtaUpdateCheckService.ts +180 -20
  319. package/src/services/PhoneCalendarService.ts +27 -4
  320. package/src/services/PhoneCameraFovCoordinator.ts +15 -0
  321. package/src/services/PhoneNotificationsSync.ts +12 -10
  322. package/src/services/PhonePhotoCoordinator.ts +33 -7
  323. package/src/services/PhoneStreamCoordinator.ts +139 -25
  324. package/src/services/PhoneVideoCoordinator.ts +11 -0
  325. package/src/services/SceneRenderer.ts +16 -0
  326. package/src/services/SupportProfileSync.ts +218 -0
  327. package/src/services/TtsTextSanitizer.ts +66 -0
  328. package/src/services/WifiAdbRequest.ts +53 -0
  329. package/src/services/asg/asgCameraApi.ts +99 -8
  330. package/src/services/asg/gallerySyncService.ts +28 -19
  331. package/src/services/asg/localNetworkTransport.ts +7 -11
  332. package/src/services/audioPlaybackAssets.ts +8 -0
  333. package/src/services/glassesClockSync.ts +2 -2
  334. package/src/services/manifestActions.ts +30 -0
  335. package/src/services/otaDisplayState.ts +57 -16
  336. package/src/services/otaInstallPolicy.ts +29 -3
  337. package/src/services/{asgOtaVersionUrl.ts → otaManifestUrl.ts} +16 -4
  338. package/src/services/slimStreamStatus.ts +16 -5
  339. package/src/stores/apps.ts +12 -0
  340. package/src/stores/bluetoothSettingKeys.ts +2 -0
  341. package/src/stores/gallerySync.ts +4 -0
  342. package/src/stores/glasses.ts +3 -0
  343. package/src/stores/settings.ts +174 -21
  344. package/src/types/applet.ts +2 -0
  345. package/src/types/enums.ts +2 -1
  346. package/src/types/hardware.ts +17 -0
  347. package/src/utils/configuredDevHost.ts +17 -0
  348. package/src/utils/devMiniappLaunch.ts +151 -23
  349. package/src/utils/diagnosticContext.ts +17 -17
  350. package/src/utils/hardware/hardware.ts +7 -9
  351. package/src/utils/miniappDiagnostics.ts +226 -0
  352. package/src/utils/timers/timers.ts +57 -21
  353. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  354. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  355. package/build/services/asgOtaVersionUrl.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"gallerySyncService.js","sourceRoot":"","sources":["../../../src/services/asg/gallerySyncService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,6BAA6B,CAAA;AACnD,OAAO,OAAO,MAAM,iCAAiC,CAAA;AACrD,OAAO,YAAY,MAAM,gCAAgC,CAAA;AACzD,OAAO,WAAW,MAAM,eAAe,CAAA;AACvC,OAAO,EAAC,QAAQ,EAAkB,QAAQ,EAAC,MAAM,cAAc,CAAA;AAC/D,OAAO,UAAU,MAAM,0BAA0B,CAAA;AACjD,OAAO,WAAW,MAAM,0BAA0B,CAAA;AAElD,OAAO,EAAC,mBAAmB,EAAc,MAAM,0BAA0B,CAAA;AACzE,OAAO,EAAC,sBAAsB,EAAE,eAAe,EAAC,MAAM,sBAAsB,CAAA;AAC5E,OAAO,EAAC,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAC,QAAQ,EAAE,gBAAgB,EAAC,MAAM,uBAAuB,CAAA;AAEhE,OAAO,kBAAkB,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAC,uBAAuB,EAAC,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAC,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAC,uBAAuB,EAAC,MAAM,iDAAiD,CAAA;AACvF,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,2BAA2B,CAAA;AAEzE,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAA;AACnE,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAC,kCAAkC,EAAC,MAAM,0BAA0B,CAAA;AAC3E,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAC,2BAA2B,EAAC,MAAM,+BAA+B,CAAA;AAEzE,mBAAmB;AACnB,MAAM,MAAM,GAAG;IACb,wBAAwB,EAAE,IAAI,EAAE,kFAAkF;IAClH,0BAA0B,EAAE,KAAK,EAAE,wCAAwC;IAC3E,0BAA0B,EAAE,KAAK;IACjC,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,6DAA6D;IAC9F,+EAA+E;IAC/E,uBAAuB,EAAE,IAAI,EAAE,4CAA4C;IAC3E,oBAAoB,EAAE,CAAC,EAAE,mDAAmD;IAC5E,mGAAmG;IACnG,gBAAgB,EAAE,IAAI,EAAE,4EAA4E;IACpG,uFAAuF;IACvF,0EAA0E;IAC1E,kCAAkC,EAAE,IAAI;CAChC,CAAA;AAaV,MAAM,kBAAkB;IACd,MAAM,CAAC,QAAQ,CAAoB;IACnC,yBAAyB,GAAG,KAAK,CAAA;IACjC,wBAAwB,GAAkB,IAAI,CAAA;IAC9C,qBAAqB,GAAkB,IAAI,CAAA;IAC3C,eAAe,GAA2B,IAAI,CAAA;IAC9C,aAAa,GAAG,KAAK,CAAA;IACrB,uBAAuB,GAAwB,IAAI,CAAA;IACnD,oBAAoB,GAAwD,IAAI,CAAA;IAChF,mBAAmB,GAAG,KAAK,CAAA;IACnC,kFAAkF;IAClF,mFAAmF;IACnF,+EAA+E;IACvE,oBAAoB,GAAkB,IAAI,CAAA;IAC1C,oBAAoB,GAAkB,IAAI,CAAA,CAAC,gDAAgD;IAC3F,gBAAgB,GAAyB,IAAI,CAAA;IAC7C,YAAY,GAAG,KAAK,CAAA;IAE5B,gBAAuB,CAAC;IAExB,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC;YACjC,kBAAkB,CAAC,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAA;QACxD,CAAC;QACD,OAAO,kBAAkB,CAAC,QAAQ,CAAA;IACpC,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,IAAI,CAAC,aAAa;YAAE,OAAM;QAE9B,oCAAoC;QACpC,kBAAkB,CAAC,WAAW,CAAC,uBAAuB,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAA;QACvF,kBAAkB,CAAC,WAAW,CAAC,eAAe,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;QACxE,kBAAkB,CAAC,WAAW,CAAC,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAA;QAE1E,iEAAiE;QACjE,IAAI,CAAC,uBAAuB,GAAG,eAAe,CAAC,SAAS,CAAC,sBAAsB,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE;YAC5G,gEAAgE;YAChE,IAAI,aAAa,IAAI,CAAC,SAAS,EAAE,CAAC;gBAChC,IAAI,CAAC,yBAAyB,EAAE,CAAA;YAClC,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,0EAA0E;QAC1E,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAA;QAE1F,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAA;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QAEzB,KAAK,2BAA2B,CAAC,UAAU,EAAE,CAAA;QAE7C,kDAAkD;QAElD,sCAAsC;QACtC,IAAI,CAAC,qBAAqB,EAAE,CAAA;IAC9B,CAAC;IAED;;OAEG;IACH,OAAO;QACL,KAAK,qBAAqB,CAAC,UAAU,EAAE,CAAA;QACvC,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACnC,kBAAkB,CAAC,cAAc,CAAC,uBAAuB,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAA;YAC1F,kBAAkB,CAAC,cAAc,CAAC,eAAe,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;YAC3E,kBAAkB,CAAC,cAAc,CAAC,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAA;YAC7E,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAA;QACxC,CAAC;QAED,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACjC,IAAI,CAAC,uBAAuB,EAAE,CAAA;YAC9B,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAA;QACrC,CAAC;QAED,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9B,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAA;YAClC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAA;QAClC,CAAC;QACD,2BAA2B,CAAC,OAAO,EAAE,CAAA;QAErC,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAClC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAyB,CAAC,CAAA;YACpD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAA;QACtC,CAAC;QAED,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,qBAAsB,CAAC,CAAA;YACjD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAA;QACnC,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAA;QAC5B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;QAC1B,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAA;IAChD,CAAC;IAED;;OAEG;IACK,yBAAyB,GAAG,GAAS,EAAE;QAC7C,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAE5C,+FAA+F;QAC/F,IAAI,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAA;YAC3F,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;YACxB,OAAM;QACR,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAA;QACjF,KAAK,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAA;QAE1C,0BAA0B;QAC1B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;YAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;QAC7B,CAAC;QAED,iBAAiB;QACjB,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAClC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAyB,CAAC,CAAA;YACpD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAA;QACtC,CAAC;QACD,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,qBAAsB,CAAC,CAAA;YACjD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAA;QACnC,CAAC;QAED,wBAAwB,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAA;QAC9D,KAAK,qBAAqB,CAAC,UAAU,EAAE,CAAA;IACzC,CAAC,CAAA;IAED;;OAEG;IACK,oBAAoB,GAAG,KAAK,EAAE,YAA4B,EAAiB,EAAE;QACnF,2CAA2C;QAC3C,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAM;QACR,CAAC;QAED,qFAAqF;QACrF,KAAK,2BAA2B,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAEzD,8CAA8C;QAC9C,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,OAAM;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,+EAA+E,CAAC,CAAA;QAE5F,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;QAC/C,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;QAEpE,uCAAuC;QACvC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;YAC5E,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAA;YAChC,OAAM;QACR,CAAC;QAED,8CAA8C;QAC9C,oFAAoF;QACpF,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,WAAW,GAAG,CAAC,CAAA;YACrB,MAAM,cAAc,GAAG,IAAI,CAAA,CAAC,4BAA4B;YAExD,OAAO,CAAC,GAAG,CAAC,2FAA2F,CAAC,CAAA;YAExG,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;gBACxD,IAAI,CAAC;oBACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC,CAAA;oBAEzF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;oBACtC,OAAO,CAAC,GAAG,CACT,2CAA2C,OAAO,IAAI,WAAW,aAAa,QAAQ,CAAC,aAAa,EAAE,CACvG,CAAA;oBAED,IAAI,QAAQ,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;wBACpC,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAA;wBAC9E,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAA;wBAChC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAA,CAAC,2BAA2B;wBAC5D,6BAA6B;wBAC7B,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;wBAC1B,kBAAkB;wBAClB,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;wBACtB,OAAM;oBACR,CAAC;oBAED,gDAAgD;oBAChD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;wBAC5B,OAAO,CAAC,GAAG,CACT,mGAAmG,CACpG,CAAA;wBACD,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAA;wBAChC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAA,CAAC,2BAA2B;oBAC9D,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,+DAA+D,OAAO,GAAG,EAAE,KAAK,CAAC,CAAA;oBAC9F,yBAAyB;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED;;OAEG;IACK,mBAAmB,GAAG,CAAC,IAAS,EAAQ,EAAE;QAChD,OAAO,CAAC,GAAG,CAAC,+CAA+C,EAAE,IAAI,CAAC,CAAA;QAElE,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,KAAK,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,CAAA;IAC/G,CAAC,CAAA;IAED;;OAEG;IACK,yBAAyB,GAAG,KAAK,EAAE,SAAc,EAAiB,EAAE;QAC1E,OAAO,CAAC,GAAG,CAAC,8CAA8C,EAAE,SAAS,CAAC,CAAA;QAEtE,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAE5C,8CAA8C;QAC9C,IAAI,KAAK,CAAC,SAAS,KAAK,oBAAoB,IAAI,KAAK,CAAC,SAAS,KAAK,iBAAiB,EAAE,CAAC;YACtF,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;YACpF,OAAM;QACR,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;YACzD,OAAM;QACR,CAAC;QAED,4DAA4D;QAC5D,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,qBAAsB,CAAC,CAAA;YACjD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAA;QACnC,CAAC;QAED,0GAA0G;QAC1G,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,2FAA2F,CAAC,CAAA;YACxG,KAAK,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAA;YAC1C,wBAAwB,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAA;YAC9D,OAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAgB;YAC/B,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,EAAE,EAAE,SAAS,CAAC,QAAQ;SACvB,CAAA;QAED,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;QAEjC,0CAA0C;QAC1C,OAAO,CAAC,GAAG,CACT,iDAAiD,MAAM,CAAC,wBAAwB,oCAAoC,CACrH,CAAA;QACD,OAAO,CAAC,GAAG,CAAC,+EAA+E,CAAC,CAAA;QAE5F,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAClC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAyB,CAAC,CAAA;QACtD,CAAC;QAED,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;YACtD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAA;YACpC,8DAA8D;YAC9D,MAAM,cAAc,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,CAAA;YAChF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAA;gBACzG,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;gBACnD,YAAY,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAA;gBACjD,wBAAwB,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAA;gBAC9D,OAAM;YACR,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAA;YAC/F,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAA;QACxC,CAAC,EAAE,MAAM,CAAC,wBAAwB,CAAC,CAAA;IACrC,CAAC,CAAA;IAED;;OAEG;IACK,kBAAkB,GAAG,CAAC,SAAc,EAAQ,EAAE;QACpD,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,SAAS,CAAC,CAAA;QAE/D,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAE5C,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAClC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAyB,CAAC,CAAA;YACpD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAA;QACtC,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,aAAa,IAAI,yBAAyB,CAAC,CAAA;QACxE,wBAAwB,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAA;IACnE,CAAC,CAAA;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAA;YAC/F,OAAO,IAAI,CAAC,gBAAgB,CAAA;QAC9B,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YACvD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAA;QAC9B,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAC,gBAAgB,CAAA;IAC9B,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,yBAAyB;QACrC,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;gBACxB,WAAW,CAAC,yBAAyB,EAAE;gBACvC,IAAI,OAAO,CAAU,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CACjC,UAAU,CACR,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,EAC5D,MAAM,CAAC,kCAAkC,CAC1C,CACF;aACF,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,wDAAwD,EAAE,KAAK,CAAC,CAAA;YAC9E,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAClE,OAAO,CAAC,IAAI,CAAC,+FAA+F,CAAC,CAAA;gBAC7G,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,yBAAyB;QACrC,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,KAAK,CAAC,EAAC,SAAS,EAAE,KAAK,EAAC,CAAC,CAAA;YAC1C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,CAAA;gBAC3C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,OAAO,KAAK,KAAK,IAAI,CAAA;gBACvB,CAAC;gBACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;YACzD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,mFAAmF,CAAC,CAAA;YACjG,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sDAAsD,EAAE,KAAK,CAAC,CAAA;YAC5E,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAEO,oBAAoB;QAC1B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;YACzB,OAAO,IAAI,CAAA;QACb,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,iFAAiF;QACjF,+EAA+E;QAC/E,mEAAmE;QACnE,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;QAEzB,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;QAC3D,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAE5E,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;QAC/C,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;QACpE,MAAM,cAAc,GAClB,YAAY,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS;YACtC,CAAC,CAAC;gBACE,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI;gBAC/B,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,QAAQ;gBACvC,EAAE,EAAE,YAAY,CAAC,OAAO,CAAC,OAAO;aACjC;YACH,CAAC,CAAC,IAAI,CAAA;QAEV,oFAAoF;QACpF,IACE,KAAK,CAAC,SAAS,KAAK,SAAS;YAC7B,KAAK,CAAC,SAAS,KAAK,iBAAiB;YACrC,KAAK,CAAC,SAAS,KAAK,oBAAoB,EACxC,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,mDAAmD,KAAK,CAAC,SAAS,2BAA2B,CAAC,CAAA;YAC1G,OAAM;QACR,CAAC;QAED,8EAA8E;QAC9E,6EAA6E;QAC7E,0DAA0D;QAC1D,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;YACzE,KAAK,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAA;YAC3C,iBAAiB,CAAC,EAAC,IAAI,EAAE,sBAAsB,EAAC,CAAC,CAAA;YACjD,OAAM;QACR,CAAC;QAED,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,yBAAyB,EAAE,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;YACzE,KAAK,CAAC,YAAY,CAAC,qDAAqD,CAAC,CAAA;YACzE,iBAAiB,CAAC,EAAC,IAAI,EAAE,eAAe,EAAC,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,gFAAgF,CAAC,CAAA;QAC7F,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE;YACnD,SAAS,EAAE,gBAAgB;YAC3B,cAAc,EAAE,cAAc,KAAK,IAAI;SACxC,CAAC,CAAA;QAEF,iFAAiF;QACjF,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAA;QAE1E,4DAA4D;QAC5D,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAA;QAC9E,MAAM,wBAAwB,CAAC,kBAAkB,EAAE,CAAA;QACnD,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;YACpF,OAAM;QACR,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAA;QAEvE,+EAA+E;QAC/E,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAA;QACxE,MAAM,qBAAqB,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;QAClF,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAA;YACxF,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;YACtE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAA;gBACrG,uFAAuF;YACzF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAA;YACrE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAA;QAC7E,CAAC;QACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;YAChF,OAAM;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAA;YAC1E,MAAM,sBAAsB,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAA;YACrF,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAA;gBACxE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,KAAK,CAAC,YAAY,CAAC,oDAAoD,CAAC,CAAA;oBACxE,MAAM,wBAAwB,CAAC,aAAa,CAAC,8CAA8C,CAAC,CAAA;oBAC5F,OAAM;gBACR,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAA;gBAClF,OAAM;YACR,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,uBAAuB,EAAE,CAAA;QAC7E,OAAO,CAAC,GAAG,CAAC,uDAAuD,cAAc,EAAE,CAAC,CAAA;QACpF,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAA;YAC3E,MAAM,aAAa,GAAG,MAAM,uBAAuB,CAAC,eAAe,EAAE,CAAA;YACrE,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAA;gBAC3F,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,iBAAiB,EAAE,CAAA;gBACjE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CAAC,yFAAyF,CAAC,CAAA;oBACvG,KAAK,CAAC,YAAY,CAAC,mEAAmE,CAAC,CAAA;oBACvF,iBAAiB,CAAC,EAAC,IAAI,EAAE,iCAAiC,EAAC,CAAC,CAAA;oBAC5D,OAAM;gBACR,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAA;gBACxE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAA;YAChF,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAA;YACnF,OAAM;QACR,CAAC;QAED,2DAA2D;QAC3D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;YACrC,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;YACpD,OAAO,CAAC,GAAG,CAAC,8CAA8C,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YACtF,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;gBACzC,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAA;gBAC1E,iBAAiB,CAAC,EAAC,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,EAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAC,EAAC,CAAC,CAAA;gBAC/F,KAAK,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAA;gBAChD,OAAM;YACR,CAAC;QACH,CAAC;QAAC,OAAO,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,uDAAuD,EAAE,OAAO,CAAC,CAAA;YAC9E,6CAA6C;QAC/C,CAAC;QACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAA;YAC7E,OAAM;QACR,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAE5C,mFAAmF;QACnF,kFAAkF;QAClF,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3D,MAAM,uBAAuB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAA;YACtE,MAAM,iBAAiB,GAAG,MAAM,CAAC,gBAAgB,GAAG,uBAAuB,CAAA;YAE3E,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CACT,8CAA8C,IAAI,CAAC,KAAK,CACtD,iBAAiB,GAAG,IAAI,CACzB,qCAAqC,CACvC,CAAA;gBAED,iBAAiB,CAAC,EAAC,IAAI,EAAE,mBAAmB,EAAC,CAAC,CAAA;gBAC9C,OAAM;YACR,CAAC;iBAAM,CAAC;gBACN,wCAAwC;gBACxC,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;gBACpF,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAA;YAClC,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,yEAAyE;QACzE,gFAAgF;QAChF,2FAA2F;QAC3F,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAA;QACzE,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,6EAA6E;gBAC7E,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,SAAS,EAAE,CAAA;gBACjD,OAAO,CAAC,GAAG,CAAC,uDAAuD,EAAE,WAAW,CAAC,CAAA;gBAEjF,4CAA4C;gBAC5C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;gBACtC,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAA;gBACxF,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;gBACzE,OAAO,CAAC,GAAG,CAAC,+CAA+C,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA;gBAE1F,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAA;oBAExE,+EAA+E;oBAC/E,8EAA8E;oBAC9E,4EAA4E;oBAC5E,gFAAgF;oBAChF,kFAAkF;oBAClF,iFAAiF;oBACjF,6CAA6C;oBAC7C,iBAAiB,CAAC;wBAChB,IAAI,EAAE,UAAU;wBAChB,GAAG,EAAE,GAAG,EAAE;4BACR,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAA;4BAC/B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;wBACxC,CAAC;qBACF,CAAC,CAAA;oBACF,KAAK,CAAC,YAAY,CAAC,2CAA2C,CAAC,CAAA;oBAE/D,0CAA0C;oBAC1C,OAAM;gBACR,CAAC;qBAAM,CAAC;oBACN,iDAAiD;oBACjD,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;oBACpE,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAA;gBAClC,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,wDAAwD,EAAE,KAAK,CAAC,CAAA;gBAC7E,0DAA0D;YAC5D,CAAC;YACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAA;gBACvE,OAAM;YACR,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAA;QACxE,CAAC;QAED,sFAAsF;QACtF,qFAAqF;QACrF,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAA;YAC7E,IAAI,CAAC;gBACH,MAAM,uBAAuB,GAAG,MAAM,IAAI,CAAC,yBAAyB,EAAE,CAAA;gBACtE,OAAO,CAAC,GAAG,CAAC,sDAAsD,EAAE,uBAAuB,CAAC,CAAA;gBAE5F,IAAI,CAAC,uBAAuB,EAAE,CAAC;oBAC7B,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAA;oBAChF,OAAO,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAA;oBAEhG,+EAA+E;oBAC/E,iBAAiB,CAAC,EAAC,IAAI,EAAE,uBAAuB,EAAC,CAAC,CAAA;oBAClD,KAAK,CAAC,YAAY,CAAC,+DAA+D,CAAC,CAAA;oBAEnF,0CAA0C;oBAC1C,OAAM;gBACR,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAA;gBACnF,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,qEAAqE,EAAE,KAAK,CAAC,CAAA;gBAC1F,0DAA0D;YAC5D,CAAC;YACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;gBACpF,OAAM;YACR,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,wFAAwF;QACxF,6FAA6F;QAC7F,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAA;QAEtF,2FAA2F;QAC3F,uEAAuE;QACvE,MAAM,uBAAuB,GAAG,kBAAkB,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,CAAA;QACzF,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,wFAAwF,CAAC,CAAA;YACrG,OAAM;QACR,CAAC;QACD,MAAM,mBAAmB,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;QACtD,MAAM,qBAAqB,GACzB,mBAAmB,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS;YAC7C,CAAC,CAAC;gBACE,IAAI,EAAE,mBAAmB,CAAC,OAAO,CAAC,IAAI;gBACtC,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC,QAAQ;gBAC9C,EAAE,EAAE,mBAAmB,CAAC,OAAO,CAAC,OAAO;aACxC;YACH,CAAC,CAAC,IAAI,CAAA;QAEV,IAAI,kBAAkB,GAAG,KAAK,CAAA;QAC9B,IAAI,qBAAqB,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;YAChE,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;YACxD,OAAO,CAAC,GAAG,CAAC,qCAAqC,qBAAqB,CAAC,IAAI,EAAE,CAAC,CAAA;YAC9E,OAAO,CAAC,GAAG,CAAC,mCAAmC,qBAAqB,CAAC,EAAE,EAAE,CAAC,CAAA;YAE1E,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,kBAAkB,EAAE,CAAA;gBAC1D,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;oBAChC,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAA;oBACvE,OAAM;gBACR,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,uDAAuD,WAAW,GAAG,CAAC,CAAA;gBAClF,OAAO,CAAC,GAAG,CAAC,mEAAmE,qBAAqB,CAAC,IAAI,GAAG,CAAC,CAAA;gBAE7G,kBAAkB,GAAG,WAAW,KAAK,qBAAqB,CAAC,IAAI,CAAA;gBAC/D,IAAI,kBAAkB,EAAE,CAAC;oBACvB,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAA;gBACxF,CAAC;qBAAM,IAAI,WAAW,EAAE,CAAC;oBACvB,OAAO,CAAC,GAAG,CAAC,4DAA4D,WAAW,GAAG,CAAC,CAAA;oBACvF,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAA;gBAC1E,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;gBAClF,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,+DAA+D,EAAE,KAAK,CAAC,CAAA;gBACpF,qEAAqE;gBACrE,kBAAkB,GAAG,KAAK,CAAA;YAC5B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAA;YAC9E,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAA;QAC1E,CAAC;QAED,oFAAoF;QACpF,mFAAmF;QACnF,oBAAoB,CAAC,KAAK,EAAE,CAAA;QAE5B,IAAI,kBAAkB,IAAI,qBAAqB,EAAE,CAAC;YAChD,MAAM,WAAW,GAAgB,qBAAqB,CAAA;YACtD,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;YACjC,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAA;YACrC,IAAI,qBAAqB,CAAC,wBAAwB,EAAE,IAAI,CAAC,qBAAqB,CAAC,wBAAwB,EAAE,EAAE,CAAC;gBAC1G,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAA;gBACjG,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAA;YAC9C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;gBACpF,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;YAC3C,CAAC;YACD,OAAM;QACR,CAAC;QAED,kBAAkB;QAClB,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAA;QACnF,KAAK,CAAC,oBAAoB,EAAE,CAAA;QAC5B,KAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAA;QAEvC,gFAAgF;QAChF,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;YACnD,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;YACnD,IAAI,YAAY,CAAC,SAAS,KAAK,oBAAoB,EAAE,CAAC;gBACpD,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAA;gBAC/D,YAAY,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAA;gBACtD,YAAY,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAA;gBAC/C,wBAAwB,CAAC,aAAa,CAAC,4CAA4C,CAAC,CAAA;YACtF,CAAC;YACD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAA;QACnC,CAAC,EAAE,MAAM,CAAC,0BAA0B,CAAC,CAAA;QAErC,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAA;YACrF,MAAM,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;YACxC,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAA;QACpE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,oDAAoD;YACpD,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC/B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,qBAAsB,CAAC,CAAA;gBACjD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAA;YACnC,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,qDAAqD,EAAE,KAAK,CAAC,CAAA;YAC3E,KAAK,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAA;YAC7C,KAAK,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,uBAAuB,CAAC,IAAY;QAChD,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QACjD,MAAM,kBAAkB,GAAG,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAA;QAExF,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;YACpF,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAA;QAE9E,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;YACtC,MAAM,OAAO,GAAG,GAAG,EAAE;gBACnB,4CAA4C;gBAC5C,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;gBAC1E,OAAO,CAAC,IAAI,CAAC,CAAA;YACf,CAAC,CAAA;YACD,uFAAuF;YACvF,sFAAsF;YACtF,gFAAgF;YAChF,MAAM,SAAS,GAAG,iBAAiB,CAAC;gBAClC,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAC;gBACnC,GAAG,EAAE,OAAO;aACb,CAAC,CAAA;YACF,oFAAoF;YACpF,IAAI,SAAS,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAA;QAChC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,oBAAoB,CAAC,WAAwB;QACzD,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAE5C,+EAA+E;QAC/E,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAA;YACtF,KAAK,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAA;YAC1C,wBAAwB,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAA;YAC9D,OAAM;QACR,CAAC;QAED,kFAAkF;QAClF,MAAM,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QAEpD,IAAI,SAAS,GAAQ,IAAI,CAAA;QACzB,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEvC,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAA;QAC5D,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,wCAAwC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAA;QACvE,OAAO,CAAC,GAAG,CAAC,4CAA4C,WAAW,CAAC,QAAQ,CAAC,MAAM,QAAQ,CAAC,CAAA;QAC5F,OAAO,CAAC,GAAG,CAAC,uCAAuC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAA;QACpE,OAAO,CAAC,GAAG,CAAC,qCAAqC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;QAC/D,OAAO,CAAC,GAAG,CAAC,+CAA+C,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAA;QACzF,OAAO,CAAC,GAAG,CAAC,wCAAwC,MAAM,CAAC,uBAAuB,IAAI,CAAC,CAAA;QAEvF,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAA;QAErC,qDAAqD;QACrD,IAAI,eAAe,GAAG,KAAK,CAAA;QAC3B,IAAI,iBAAiB,GAAkB,IAAI,CAAA;QAC3C,MAAM,eAAe,GAAG,CAAC,YAA4B,EAAE,EAAE;YACvD,IAAI,YAAY,KAAK,YAAY,EAAE,CAAC;gBAClC,eAAe,GAAG,IAAI,CAAA;gBACtB,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAC9B,OAAO,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAA;gBACnF,OAAO,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAA;gBACxF,OAAO,CAAC,IAAI,CACV,0DAA0D,EAC1D,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,EACjC,IAAI,CACL,CAAA;YACH,CAAC;iBAAM,IAAI,YAAY,KAAK,QAAQ,IAAI,eAAe,EAAE,CAAC;gBACxD,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;gBAChE,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,iBAAiB,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;YAC/G,CAAC;QACH,CAAC,CAAA;QAED,MAAM,oBAAoB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAA;QACjF,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;QAEpE,qFAAqF;QACrF,IAAI,CAAC;YACH,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,oBAAoB,EAAE,OAAO,EAAE,EAAE,CAAC;gBACxE,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAEnC,qBAAqB;gBACrB,IAAI,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;oBACzC,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;oBACpF,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAA;oBACpC,OAAM;gBACR,CAAC;gBAED,IAAI,CAAC;oBACH,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;oBAC5E,OAAO,CAAC,GAAG,CACT,mCAAmC,OAAO,IAAI,MAAM,CAAC,oBAAoB,6BAA6B,CACvG,CAAA;oBACD,OAAO,CAAC,GAAG,CAAC,0DAA0D,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,IAAI,CAAC,CAAA;oBAC5G,OAAO,CAAC,GAAG,CAAC,+DAA+D,eAAe,EAAE,CAAC,CAAA;oBAE7F,wDAAwD;oBACxD,IAAI,cAAc,GAAG,SAAS,CAAA;oBAC9B,IAAI,CAAC;wBACH,cAAc,GAAG,MAAM,WAAW,CAAC,kBAAkB,EAAE,CAAA;wBACvD,OAAO,CAAC,GAAG,CAAC,+CAA+C,cAAc,GAAG,CAAC,CAAA;wBAE7E,oEAAoE;wBACpE,IAAI,CAAC,qBAAqB,CAAC,wBAAwB,EAAE,IAAI,cAAc,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;4BAC7F,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAA;4BAC/F,oBAAoB,CAAC,MAAM,EAAE,CAAA;4BAE7B,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,CAAA;4BAC3D,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;4BAC5E,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAA;4BAClF,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;4BAC5E,OAAO,CAAC,GAAG,CAAC,sDAAsD,iBAAiB,IAAI,CAAC,CAAA;4BACxF,OAAO,CAAC,GAAG,CAAC,4DAA4D,WAAW,CAAC,EAAE,OAAO,CAAC,CAAA;4BAE9F,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;4BACzC,OAAM,CAAC,6BAA6B;wBACtC,CAAC;oBACH,CAAC;oBAAC,OAAO,QAAa,EAAE,CAAC;wBACvB,OAAO,CAAC,IAAI,CAAC,uDAAuD,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;wBACxF,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;oBACrE,CAAC;oBAED,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;oBAChF,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAA;oBAClD,OAAO,CAAC,GAAG,CAAC,oCAAoC,WAAW,CAAC,IAAI,GAAG,CAAC,CAAA;oBACpE,OAAO,CAAC,GAAG,CAAC,uCAAuC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;oBAC7F,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;oBACxD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;oBAExD,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;oBACvC,eAAe,GAAG,KAAK,CAAA,CAAC,8BAA8B;oBACtD,iBAAiB,GAAG,IAAI,CAAA;oBAExB,MAAM,qBAAqB,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;oBAE3E,MAAM,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,CAAA;oBAC7D,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAA;oBACpF,OAAO,CAAC,GAAG,CAAC,kDAAkD,mBAAmB,IAAI,CAAC,CAAA;oBACtF,OAAO,CAAC,GAAG,CAAC,6DAA6D,eAAe,EAAE,CAAC,CAAA;oBAC3F,IAAI,eAAe,IAAI,iBAAiB,EAAE,CAAC;wBACzC,OAAO,CAAC,GAAG,CACT,qDAAqD,iBAAiB,GAAG,oBAAoB,IAAI,CAClG,CAAA;oBACH,CAAC;oBACD,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAA;oBAE/F,8DAA8D;oBAC9D,2FAA2F;oBAC3F,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;wBAC1B,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAA;wBAC/E,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAA;wBAE1F,MAAM,iBAAiB,GAAG,EAAE,CAAA,CAAC,0BAA0B;wBACvD,IAAI,SAAS,GAAG,KAAK,CAAA;wBACrB,IAAI,YAAY,GAAG,SAAS,CAAA;wBAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,iBAAiB,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC3C,IAAI,CAAC;gCACH,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,kBAAkB,EAAE,CAAA;gCAC1D,YAAY,GAAG,WAAW,IAAI,MAAM,CAAA;gCAEpC,OAAO,CAAC,GAAG,CACT,uCACE,CAAC,GAAG,CACN,IAAI,iBAAiB,cAAc,WAAW,cAAc,WAAW,CAAC,IAAI,GAAG,CAChF,CAAA;gCAED,IAAI,WAAW,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;oCACrC,OAAO,CAAC,GAAG,CACT,qFACE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GACZ,IAAI,CACL,CAAA;oCACD,SAAS,GAAG,IAAI,CAAA;oCAChB,MAAK;gCACP,CAAC;qCAAM,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;oCACnD,OAAO,CAAC,GAAG,CACT,6FAA6F,CAC9F,CAAA;gCACH,CAAC;4BACH,CAAC;4BAAC,OAAO,SAAc,EAAE,CAAC;gCACxB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,GAAG,CAAC,2BAA2B,SAAS,EAAE,OAAO,EAAE,CAAC,CAAA;gCACpG,YAAY,GAAG,OAAO,CAAA;4BACxB,CAAC;4BAED,gCAAgC;4BAChC,IAAI,CAAC,GAAG,iBAAiB,GAAG,CAAC,EAAE,CAAC;gCAC9B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;4BAChF,CAAC;wBACH,CAAC;wBAED,IAAI,CAAC,SAAS,EAAE,CAAC;4BACf,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAA;4BAC/E,OAAO,CAAC,KAAK,CAAC,4CAA4C,YAAY,GAAG,CAAC,CAAA;4BAC1E,OAAO,CAAC,KAAK,CAAC,2CAA2C,WAAW,CAAC,IAAI,GAAG,CAAC,CAAA;4BAC7E,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;4BACzD,OAAO,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAA;4BACxF,OAAO,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAA;4BAC3F,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAA;4BAC5E,MAAM,IAAI,KAAK,CACb,4CAA4C,YAAY,gBAAgB,WAAW,CAAC,IAAI,GAAG,CAC5F,CAAA;wBACH,CAAC;oBACH,CAAC;oBAED,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAA;oBACrD,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;oBACjE,OAAO,CAAC,GAAG,CAAC,mDAAmD,eAAe,IAAI,CAAC,CAAA;oBACnF,OAAO,CAAC,GAAG,CAAC,qCAAqC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;oBAE/D,4BAA4B;oBAC5B,oBAAoB,CAAC,MAAM,EAAE,CAAA;oBAC7B,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;oBAEjE,wEAAwE;oBACxE,IAAI,CAAC;wBACH,MAAM,SAAS,GAAG,qBAAqB,CAAC,wBAAwB,EAAE;4BAChE,CAAC,CAAC,WAAW,CAAC,IAAI;4BAClB,CAAC,CAAC,MAAM,WAAW,CAAC,kBAAkB,EAAE,CAAA;wBAC1C,OAAO,CAAC,GAAG,CAAC,8DAA8D,SAAS,GAAG,CAAC,CAAA;wBACvF,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;4BAC9B,mFAAmF;4BACnF,CAAC;4BAAC,YAAoB,CAAC,uBAAuB,EAAE,EAAE,CAAA;wBACpD,CAAC;wBACD,IAAI,SAAS,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;4BACnC,OAAO,CAAC,KAAK,CACX,4DAA4D,WAAW,CAAC,IAAI,WAAW,SAAS,GAAG,CACpG,CAAA;4BACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,SAAS,iBAAiB,WAAW,CAAC,IAAI,GAAG,CAAC,CAAA;wBACtG,CAAC;oBACH,CAAC;oBAAC,OAAO,UAAe,EAAE,CAAC;wBACzB,OAAO,CAAC,IAAI,CAAC,+DAA+D,UAAU,EAAE,OAAO,EAAE,CAAC,CAAA;wBAClG,kDAAkD;oBACpD,CAAC;oBAED,gEAAgE;oBAChE,2EAA2E;oBAC3E,iEAAiE;oBACjE,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;wBAC1B,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAA;wBACtF,OAAO,CAAC,GAAG,CAAC,6CAA6C,WAAW,CAAC,EAAE,kBAAkB,CAAC,CAAA;wBAE1F,MAAM,gBAAgB,GAAG,EAAE,CAAA,CAAC,uCAAuC;wBACnE,IAAI,YAAY,GAAG,KAAK,CAAA;wBAExB,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,IAAI,gBAAgB,EAAE,QAAQ,EAAE,EAAE,CAAC;4BAChE,IAAI,CAAC;gCACH,OAAO,CAAC,GAAG,CAAC,8CAA8C,QAAQ,IAAI,gBAAgB,KAAK,CAAC,CAAA;gCAE5F,gEAAgE;gCAChE,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;gCAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA,CAAC,6BAA6B;gCAE1G,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gCACjC,MAAM,aAAa,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,UAAU,WAAW,CAAC,EAAE,kBAAkB,EAAE;oCAClG,MAAM,EAAE,KAAK;oCACb,MAAM,EAAE,eAAe,CAAC,MAAM;iCAC/B,CAAC,CAAA;gCACF,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAA;gCAElC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAA;gCACjD,OAAO,CAAC,GAAG,CACT,iCAAiC,QAAQ,mBAAmB,aAAa,CAAC,MAAM,KAAK,aAAa,KAAK,CACxG,CAAA;gCAED,IAAI,aAAa,CAAC,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oCACjE,6EAA6E;oCAC7E,kCAAkC;oCAClC,OAAO,CAAC,GAAG,CAAC,iEAAiE,QAAQ,UAAU,CAAC,CAAA;oCAChG,YAAY,GAAG,IAAI,CAAA;oCACnB,MAAK;gCACP,CAAC;4BACH,CAAC;4BAAC,OAAO,UAAe,EAAE,CAAC;gCACzB,MAAM,QAAQ,GAAG,UAAU,EAAE,OAAO,IAAI,SAAS,CAAA;gCACjD,OAAO,CAAC,GAAG,CACT,iCAAiC,QAAQ,YAAY,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAC5E,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EACjC,EAAE,CACH,CAAA;gCACD,yBAAyB;4BAC3B,CAAC;4BAED,kEAAkE;4BAClE,IAAI,QAAQ,GAAG,gBAAgB,EAAE,CAAC;gCAChC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;4BAChF,CAAC;wBACH,CAAC;wBAED,IAAI,CAAC,YAAY,EAAE,CAAC;4BAClB,OAAO,CAAC,KAAK,CACX,qEAAqE,gBAAgB,WAAW,CACjG,CAAA;4BACD,OAAO,CAAC,KAAK,CAAC,mEAAmE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAA;4BAClG,MAAM,IAAI,KAAK,CACb,2CAA2C,WAAW,CAAC,EAAE,eAAe,gBAAgB,WAAW,CACpG,CAAA;wBACH,CAAC;oBACH,CAAC;oBAED,4BAA4B;oBAC5B,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,CAAA;oBAC3D,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;oBAC5E,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;oBAC9D,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;oBAC5E,OAAO,CAAC,GAAG,CAAC,sDAAsD,iBAAiB,IAAI,CAAC,CAAA;oBACxF,OAAO,CAAC,GAAG,CAAC,0CAA0C,OAAO,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAA;oBAC/F,OAAO,CAAC,GAAG,CAAC,4DAA4D,WAAW,CAAC,EAAE,OAAO,CAAC,CAAA;oBAE9F,MAAM,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;oBACzC,OAAM,CAAC,gCAAgC;gBACzC,CAAC;gBAAC,OAAO,KAAU,EAAE,CAAC;oBACpB,SAAS,GAAG,KAAK,CAAA;oBACjB,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAA;oBAErD,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAA;oBAChF,OAAO,CAAC,KAAK,CAAC,uCAAuC,OAAO,SAAS,CAAC,CAAA;oBACtE,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAA;oBAChF,OAAO,CAAC,KAAK,CAAC,yCAAyC,KAAK,EAAE,OAAO,IAAI,YAAY,EAAE,CAAC,CAAA;oBACxF,OAAO,CAAC,KAAK,CAAC,sCAAsC,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,CAAC,CAAA;oBAC/E,OAAO,CAAC,KAAK,CAAC,sCAAsC,KAAK,EAAE,IAAI,IAAI,OAAO,KAAK,EAAE,CAAC,CAAA;oBAClF,OAAO,CAAC,KAAK,CAAC,oCAAoC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;oBAChE,OAAO,CAAC,KAAK,CAAC,4CAA4C,eAAe,IAAI,CAAC,CAAA;oBAC9E,OAAO,CAAC,KAAK,CAAC,gDAAgD,eAAe,EAAE,CAAC,CAAA;oBAChF,IAAI,eAAe,IAAI,iBAAiB,EAAE,CAAC;wBACzC,OAAO,CAAC,KAAK,CAAC,8CAA8C,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,IAAI,CAAC,CAAA;oBACjG,CAAC;oBACD,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;oBAE1F,yCAAyC;oBACzC,IAAI,KAAK,EAAE,IAAI,KAAK,YAAY,IAAI,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACvE,OAAO,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAA;wBACjF,oBAAoB,CAAC,MAAM,EAAE,CAAA;wBAC7B,KAAK,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAA;wBAC/C,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;4BACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;wBAC3B,CAAC;wBACD,OAAM;oBACR,CAAC;oBAED,iEAAiE;oBACjE,IAAI,KAAK,EAAE,IAAI,KAAK,mBAAmB,EAAE,CAAC;wBACxC,OAAO,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAA;wBAC7F,OAAO,CAAC,IAAI,CACV,yCAAyC,MAAM,CAAC,uBAAuB,eAAe,OAAO,IAAI,MAAM,CAAC,oBAAoB,GAAG,CAChI,CAAA;oBACH,CAAC;oBAED,mFAAmF;oBACnF,IAAI,KAAK,EAAE,IAAI,KAAK,iBAAiB,EAAE,CAAC;wBACtC,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAA;wBACxE,OAAO,CAAC,KAAK,CAAC,gDAAgD,eAAe,EAAE,CAAC,CAAA;wBAChF,IAAI,eAAe,IAAI,iBAAiB,EAAE,CAAC;4BACzC,OAAO,CAAC,KAAK,CAAC,8CAA8C,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,IAAI,CAAC,CAAA;4BAC/F,OAAO,CAAC,KAAK,CAAC,0FAA0F,CAAC,CAAA;wBAC3G,CAAC;wBACD,OAAO,CAAC,IAAI,CACV,yCAAyC,MAAM,CAAC,uBAAuB,eAAe,OAAO,IAAI,MAAM,CAAC,oBAAoB,GAAG,CAChI,CAAA;oBACH,CAAC;oBAED,8FAA8F;oBAC9F,uFAAuF;oBACvF,8EAA8E;oBAC9E,EAAE;oBACF,+EAA+E;oBAC/E,oCAAoC;oBACpC,EAAE;oBACF,2GAA2G;oBAC3G,QAAQ;oBACR,wBAAwB;oBACxB,yBAAyB;oBACzB,yBAAyB;oBACzB,2CAA2C;oBAC3C,2CAA2C;oBAC3C,0EAA0E;oBAC1E,gDAAgD;oBAChD,gCAAgC;oBAChC,YAAY;oBACZ,WAAW;oBACX,SAAS;oBACT,QAAQ;oBACR,+BAA+B;oBAC/B,+BAA+B;oBAC/B,2EAA2E;oBAC3E,iDAAiD;oBACjD,2DAA2D;oBAC3D,+DAA+D;oBAC/D,gDAAgD;oBAChD,sCAAsC;oBACtC,YAAY;oBACZ,WAAW;oBACX,SAAS;oBACT,OAAO;oBACP,WAAW;oBACX,IAAI;oBAEJ,uDAAuD;oBACvD,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;wBAClF,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAA;wBACvF,oBAAoB,CAAC,MAAM,EAAE,CAAA;wBAC7B,KAAK,CAAC,YAAY,CAAC,2CAA2C,CAAC,CAAA;wBAC/D,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;4BACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;wBAC3B,CAAC;wBACD,OAAM;oBACR,CAAC;oBAED,4DAA4D;oBAC5D,sDAAsD;oBACtD,yEAAyE;oBACzE,IAAI,OAAO,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAC;wBAC1C,MAAM,MAAM,GACV,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,mCAAmC,CAAA;wBAClG,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;wBAC5E,OAAO,CAAC,GAAG,CAAC,2CAA2C,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAA;wBACpG,OAAO,CAAC,GAAG,CAAC,mCAAmC,MAAM,CAAC,uBAAuB,OAAO,MAAM,GAAG,CAAC,CAAA;wBAC9F,OAAO,CAAC,GAAG,CAAC,0CAA0C,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAA;wBAC9E,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAA;wBACzG,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAA;oBACvE,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAA;oBAC3E,CAAC;gBACH,CAAC;YACH,CAAC;YAED,wBAAwB;YACxB,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,oBAAoB,CAAA;YAE3D,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAA;YAChF,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAA;YACtF,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAA;YAChF,OAAO,CAAC,KAAK,CAAC,oCAAoC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;YAChE,OAAO,CAAC,KAAK,CAAC,0CAA0C,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAA;YACtF,OAAO,CAAC,KAAK,CAAC,0CAA0C,iBAAiB,IAAI,CAAC,CAAA;YAC9E,OAAO,CAAC,KAAK,CAAC,8DAA8D,eAAe,EAAE,CAAC,CAAA;YAC9F,OAAO,CAAC,KAAK,CAAC,8CAA8C,SAAS,EAAE,OAAO,IAAI,YAAY,EAAE,CAAC,CAAA;YACjG,OAAO,CAAC,KAAK,CAAC,2CAA2C,SAAS,EAAE,IAAI,IAAI,SAAS,EAAE,CAAC,CAAA;YACxF,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAA;YAEhF,0DAA0D;YAC1D,IAAI,gBAAgB,GAAG,SAAS,EAAE,OAAO,IAAI,mCAAmC,CAAA;YAEhF,IAAI,SAAS,EAAE,IAAI,KAAK,iBAAiB,IAAI,eAAe,EAAE,CAAC;gBAC7D,gBAAgB;oBACd,0IAA0I,CAAA;YAC9I,CAAC;iBAAM,IAAI,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC1D,gBAAgB;oBACd,8FAA8F,CAAA;YAClG,CAAC;YAED,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAA;YAEpC,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;gBACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;YAC3B,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,qFAAqF;YACrF,mFAAmF;YACnF,MAAM,qBAAqB,CAAC,UAAU,EAAE,CAAA;YACxC,wFAAwF;YACxF,oBAAoB,CAAC,MAAM,EAAE,CAAA;QAC/B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,YAAoB;QACpE,MAAM,EAAE,GAAG,OAAO,YAAY,CAAC,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;QACvG,IAAI,EAAE,EAAE,CAAC;YACP,MAAM,eAAe,GAAG,MAAM,mBAAmB,CAAC,kBAAkB,EAAE,CAAA;YACtE,MAAM,mBAAmB,CAAC,uBAAuB,CAC/C,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAChD,eAAe,CAChB,CAAA;YACD,OAAO;gBACL,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,QAAQ;gBACnB,uFAAuF;gBACvF,wFAAwF;gBACxF,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAC1B,CAAC,OAAO,EAAE,EAAE,CACV,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CACxG;gBACD,aAAa,EAAE,EAAE;gBACjB,aAAa,EAAE,EAAE;gBACjB,WAAW,EAAE,EAAE,CAAC,WAAW;gBAC3B,aAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM;gBACjC,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;aAClF,CAAA;QACH,CAAC;QACD,2FAA2F;QAC3F,qEAAqE;QACrE,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC,CAAA;QACrF,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,YAAY,CAAqB,CAAA;QACpE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAA;QAClH,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,CACpD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,qBAAqB,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CACnE,CAAA;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAC/B,QAAgB,EAChB,YAAoB;QAEpB,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,IAAI,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QACnE,IAAI,UAAU,GAAG,KAAK,CAAA;QAEtB,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;QACnF,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvB,UAAU,GAAG,MAAM,uBAAuB,CAAC,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;YAC9E,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAA;gBACjG,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;YACtD,CAAC;QACH,CAAC;QAED,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,IAAI,YAAY,KAAK,CAAC,EAAC,CAAA;QACnE,CAAC;QAED,4FAA4F;QAC5F,4FAA4F;QAC5F,yFAAyF;QACzF,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,YAAY,EAAE,CAAA;QAC9C,MAAM,8BAA8B,GAAG,IAAI,CAAC,oBAAoB,KAAK,QAAQ,CAAA;QAC7E,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,iBAAiB,IAAI,YAAY,KAAK,CAAC,IAAI,CAAC,8BAA8B,EAAE,CAAC;YACpG,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAA;YACpC,OAAO,CAAC,GAAG,CAAC,kGAAkG,CAAC,CAAA;YAC/G,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;YACpD,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAC,CAAA;YACvC,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,iBAAiB,IAAI,YAAY,KAAK,CAAC,IAAI,8BAA8B,EAAE,CAAC;YAC1G,OAAO,CAAC,IAAI,CACV,iJAAiJ,CAClJ,CAAA;QACH,CAAC;QAED,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAA;YAC/F,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAC,CAAA;IACxC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAAC,WAAwB;QACtD,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAE5C,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAA;QAC7E,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,qCAAqC,WAAW,CAAC,EAAE,OAAO,CAAC,CAAA;QAEvE,IAAI,CAAC;YACH,wBAAwB;YACxB,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;YAC5C,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAA;YAE7D,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,YAAY,EAAE,CAAA;YAC1D,IAAI,QAAQ,CAAC,OAAO,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,OAAO,CAAC,GAAG,CACT,uCAAuC,QAAQ,CAAC,OAAO,eAAe,QAAQ,CAAC,MAAM,gBAAgB,CACtG,CAAA;YACH,CAAC;YAED,uCAAuC;YACvC,sFAAsF;YACtF,wFAAwF;YACxF,6EAA6E;YAC7E,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAA;YAClF,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,CAAA;YAC1D,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE;gBACnD,SAAS,EAAE,SAAS,CAAC,SAAS;gBAC9B,cAAc,EAAE,SAAS,CAAC,cAAc;gBACxC,cAAc,EAAE,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,OAAO;gBACzG,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;gBAC5C,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;aACpE,CAAC,CAAA;YAEF,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAA;YACtE,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC,CAAA;YAC9F,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAA;YAChD,OAAO,CAAC,GAAG,CAAC,mDAAmD,aAAa,IAAI,CAAC,CAAA;YAEjF,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,gBAAgB,GAAG,oCAAoC,CAAA;gBAC7D,KAAK,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAA;gBACpC,MAAM,wBAAwB,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAA;gBAC9D,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;oBACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;gBAC3B,CAAC;gBACD,OAAM;YACR,CAAC;YAED,MAAM,EAAC,QAAQ,EAAC,GAAG,QAAQ,CAAA;YAE3B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;YAChE,OAAO,CAAC,GAAG,CAAC,4CAA4C,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;YAC/E,OAAO,CAAC,GAAG,CAAC,8CAA8C,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAA;YAChG,OAAO,CAAC,GAAG,CAAC,yCAAyC,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAA;YAEtF,IAAI,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAA;gBAClF,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,EAAE,CAAC;oBAC/C,KAAK,CAAC,YAAY,CAAC,+CAA+C,CAAC,CAAA;gBACrE,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,eAAe,EAAE,CAAA;gBACzB,CAAC;gBACD,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;gBAC/B,OAAM;YACR,CAAC;YAED,4DAA4D;YAC5D,MAAM,WAAW,GAAG,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;YAEzG,IAAI,WAAW,EAAE,CAAC;gBAChB,8BAA8B;gBAC9B,MAAM,QAAQ,GAAmB,QAAQ,CAAC,QAAS,CAAA;gBACnD,OAAO,CAAC,GAAG,CACT,mCAAmC,QAAQ,CAAC,MAAM,sCAAsC,QAAQ,CAAC,WAAW,GAAG,CAChH,CAAA;gBAED,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAe,EAAE,GAAW,EAAE,EAAE;oBAC5D,OAAO,CAAC,GAAG,CACT,6BAA6B,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAC5F,CAAC,CAAC,UAAU,GAAG,IAAI,CACpB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CACnB,CAAA;gBACH,CAAC,CAAC,CAAA;gBACF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,OAAO,CAAC,GAAG,CAAC,qCAAqC,QAAQ,CAAC,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAA;gBACvF,CAAC;gBAED,+EAA+E;gBAC/E,MAAM,iBAAiB,GAAgB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBACxD,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;oBAC3E,OAAO;wBACL,IAAI,EAAE,CAAC,CAAC,UAAU;wBAClB,GAAG,EAAE,mBAAmB,kBAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;wBAC9D,QAAQ,EAAE,sBAAsB,kBAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;wBACtE,IAAI,EAAE,CAAC,CAAC,UAAU;wBAClB,QAAQ,EAAE,CAAC,CAAC,SAAS;wBACrB,QAAQ,EAAE,CAAC,CAAC,IAAI,KAAK,OAAO;wBAC5B,cAAc,EAAE,CAAC,CAAC,cAAc;wBAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ;qBACrB,CAAA;gBACH,CAAC,CAAC,CAAA;gBAEF,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;gBAEnC,MAAM,mBAAmB,CAAC,aAAa,CAAC;oBACtC,KAAK,EAAE,iBAAiB;oBACxB,YAAY,EAAE,CAAC;oBACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,WAAW;iBACZ,CAAC,CAAA;gBAEF,MAAM,wBAAwB,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;gBAE/D,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;gBAChF,MAAM,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;YACnE,CAAC;iBAAM,CAAC;gBACN,6BAA6B;gBAC7B,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAA;gBAC1C,8EAA8E;gBAC9E,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,CACzC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,CAAC,CACxF,CAAC,MAAM,CAAA;gBACR,OAAO,CAAC,GAAG,CACT,mCAAmC,WAAW,CAAC,MAAM,uBAAuB,gBAAgB,6BAA6B,CAC1H,CAAA;gBAED,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAA;gBACvD,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAU,EAAE,IAAY,EAAE,EAAE;oBAC3D,OAAO,CAAC,GAAG,CACT,6BAA6B,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,CAC9F,KAAK,CAAC,IAAI,GAAG,IAAI,CAClB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CACnB,CAAA;gBACH,CAAC,CAAC,CAAA;gBACF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,qCAAqC,WAAW,CAAC,MAAM,GAAG,CAAC,aAAa,CAAC,CAAA;gBACvF,CAAC;gBAED,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;gBAE7B,MAAM,mBAAmB,CAAC,aAAa,CAAC;oBACtC,KAAK,EAAE,WAAW;oBAClB,YAAY,EAAE,CAAC;oBACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,WAAW;iBACZ,CAAC,CAAA;gBAEF,MAAM,wBAAwB,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAA;gBAEhE,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAA;gBACjF,MAAM,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;YAC/D,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,KAAK,CAAC,CAAA;YACtE,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,IAAI,0BAA0B,CAAC,CAAA;YAChE,MAAM,wBAAwB,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAA;YAExE,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;gBACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,eAAe,CAAC,KAAkB,EAAE,UAAkB;QAClE,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACpC,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;QACjE,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,gDAAgD,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;QAE3E,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QACjD,MAAM,eAAe,GAAG,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAE/E,IAAI,eAAe,GAAG,CAAC,CAAA;QACvB,IAAI,WAAW,GAAG,CAAC,CAAA;QAEnB,iGAAiG;QACjG,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,uBAAuB,EAAE,CAAA;QAC7E,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;QACtG,OAAO,CAAC,GAAG,CAAC,uDAAuD,cAAc,EAAE,CAAC,CAAA;QACpF,OAAO,CAAC,GAAG,CAAC,+CAA+C,mBAAmB,EAAE,CAAC,CAAA;QAEjF,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,MAAM,YAAY,CAAC,cAAc,CACtD,KAAK,EACL,IAAI,EACJ,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE;gBACzD,0CAA0C;gBAC1C,0EAA0E;gBAC1E,kFAAkF;gBAElF,wEAAwE;gBACxE,IAAI,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;oBACzC,OAAM;gBACR,CAAC;gBAED,eAAe;gBACf,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;gBAEnD,IAAI,YAAY,KAAK,CAAC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;oBACrD,8EAA8E;oBAC9E,0DAA0D;oBAC1D,4EAA4E;oBAC5E,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,KAAK,QAAQ,CAAA;oBAEvD,IAAI,SAAS,EAAE,CAAC;wBACd,qDAAqD;wBACrD,IAAI,OAAO,GAAG,CAAC,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;4BAC5C,YAAY,CAAC,cAAc,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;4BACrD,kEAAkE;4BAClE,mBAAmB,CAAC,oBAAoB,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gCAClE,OAAO,CAAC,KAAK,CAAC,qDAAqD,EAAE,GAAG,CAAC,CAAA;4BAC3E,CAAC,CAAC,CAAA;wBACJ,CAAC;wBACD,+BAA+B;wBAC/B,YAAY,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;oBAC1C,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,YAAY,CAAC,cAAc,CAAC,QAAQ,EAAE,YAAY,IAAI,CAAC,CAAC,CAAA;gBAC1D,CAAC;gBAED,2EAA2E;gBAC3E,IAAI,YAAY,KAAK,GAAG,IAAI,cAAc,EAAE,CAAC;oBAC3C,sEAAsE;oBACtE,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ;wBAC1C,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;4BAC7C,CAAC,CAAC,cAAc,CAAC,QAAQ;4BACzB,CAAC,CAAC,UAAU,cAAc,CAAC,QAAQ,EAAE;wBACvC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAA;oBAEtB,MAAM,iBAAiB,GAAG,cAAc,CAAC,aAAa;wBACpD,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC;4BAClD,CAAC,CAAC,cAAc,CAAC,aAAa;4BAC9B,CAAC,CAAC,UAAU,cAAc,CAAC,aAAa,EAAE;wBAC5C,CAAC,CAAC,SAAS,CAAA;oBAEb,MAAM,WAAW,GAAG;wBAClB,GAAG,cAAc;wBACjB,GAAG,EAAE,YAAY,EAAE,iDAAiD;wBACpE,QAAQ,EAAE,YAAY,EAAE,iCAAiC;wBACzD,QAAQ,EAAE,cAAc,CAAC,QAAQ;wBACjC,aAAa,EAAE,iBAAiB;qBACjC,CAAA;oBACD,YAAY,CAAC,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;oBAErD,0DAA0D;oBAC1D,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;wBAC5B,sDAAsD;wBACtD,IAAI,WAA+B,CAAA;wBACnC,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;4BAC5B,WAAW;gCACT,OAAO,cAAc,CAAC,QAAQ,KAAK,QAAQ;oCACzC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,CAAC;oCACvC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAA;4BAC7B,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;gCACvB,OAAO,CAAC,IAAI,CACV,uDAAuD,cAAc,CAAC,IAAI,GAAG,EAC7E,cAAc,CAAC,QAAQ,CACxB,CAAA;gCACD,WAAW,GAAG,SAAS,CAAA;4BACzB,CAAC;wBACH,CAAC;wBAED,mDAAmD;wBACnD,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;wBAC3D,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC;4BAC7C,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;4BACzE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAA;wBACvB,MAAM,YAAY,GAAG,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,CAAA;wBAChD,MAAM,YAAY,GAAG,IAAI,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAA;wBAErD,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;4BAC9D,MAAM,cAAc,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;4BAC/E,oBAAoB,CAAC,OAAO,CAAC;gCAC3B,EAAE,EAAE,cAAc,CAAC,IAAI;gCACvB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;gCACjC,WAAW,EAAE,cAAc,CAAC,QAAQ;gCACpC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;gCACjD,SAAS,EAAE,WAAW;gCACtB,SAAS,EAAE,cAAc,CAAC,IAAI;gCAC9B,QAAQ,EAAE,cAAc,CAAC,QAAQ;gCACjC,YAAY,EAAE,eAAe;gCAC7B,aAAa,EAAE,CAAC,CAAC,mBAAmB;gCACpC,cAAc,EAAE,CAAC,CAAC,cAAc;gCAChC,aAAa,EAAE,cAAc,CAAC,aAAa;gCAC3C,iBAAiB,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC;gCACxC,eAAe,EAAE,CAAC;6BACnB,CAAC,CAAA;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,sBAAsB;gBACtB,wBAAwB,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,IAAI,CAAC,CAAC,CAAA;YACtF,CAAC,EACD,IAAI,CAAC,eAAe,EAAE,MAAM,CAC7B,CAAA;YAED,eAAe,GAAG,cAAc,CAAC,UAAU,CAAC,MAAM,CAAA;YAClD,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAA;YAE1C,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,CAAA;YACvD,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;YAC5E,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;YACjE,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;YAC5E,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAA;YACjD,OAAO,CAAC,GAAG,CAAC,2CAA2C,eAAe,EAAE,CAAC,CAAA;YACzE,OAAO,CAAC,GAAG,CAAC,uCAAuC,WAAW,EAAE,CAAC,CAAA;YACjE,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;YAC7F,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,cAAc,CAAC,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;YACjH,IAAI,gBAAgB,GAAG,CAAC,IAAI,cAAc,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;gBAC1D,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;gBACtF,OAAO,CAAC,GAAG,CAAC,0CAA0C,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;YACrF,CAAC;YAED,gEAAgE;YAChE,IAAI,cAAc,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzC,MAAM,YAAY,GAAG,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAA;gBAC1F,IAAI,YAAY,EAAE,CAAC;oBACjB,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;oBACnD,YAAY,CAAC,cAAc,CAAC,YAAY,CAAC,CAAA;gBAC3C,CAAC;YACH,CAAC;YAED,uCAAuC;YACvC,MAAM,mBAAmB,CAAC,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAE5D,6BAA6B;YAC7B,KAAK,MAAM,cAAc,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;gBACnD,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;gBACnD,YAAY,CAAC,YAAY,CAAC,cAAc,CAAC,CAAA;YAC3C,CAAC;YAED,8DAA8D;YAC9D,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;YAChF,MAAM,oBAAoB,CAAC,gBAAgB,EAAE,CAAA;YAC7C,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;YAEhE,iFAAiF;YACjF,0FAA0F;YAC1F,yFAAyF;YACzF,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAA;YAC9E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpF,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACvC,CAAC;YACH,CAAC;YACD,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAA;YAE1C,uEAAuE;YACvE,uEAAuE;YACvE,IAAI,aAAa,GAAG,UAAU,CAAA;YAC9B,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,CAAA;gBACjE,aAAa,GAAG,gBAAgB,CAAC,cAAc,CAAA;gBAC/C,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAA;YACzF,CAAC;iBAAM,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBAChD,IAAI,YAAY,GAAG,QAAQ,CAAA;gBAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;oBACtB,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC1B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;wBACzF,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,YAAY;4BAAE,YAAY,GAAG,EAAE,CAAA;oBACxD,CAAC;gBACH,CAAC;gBACD,IAAI,YAAY,GAAG,QAAQ,EAAE,CAAC;oBAC5B,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,CAAA;oBAC7C,OAAO,CAAC,GAAG,CACT,6BAA6B,cAAc,CAAC,MAAM,CAAC,MAAM,yCAAyC,aAAa,eAAe,UAAU,EAAE,CAC3I,CAAA;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,WAAW,GAAG,CAAC,CAAA;gBACnB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBAChD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;oBACtB,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;wBAAE,SAAQ;oBACnC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;oBACzF,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;wBAAE,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;gBACzD,CAAC;gBACD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;oBACpB,aAAa,GAAG,WAAW,CAAA;gBAC7B,CAAC;YACH,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;YAChF,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,CAAA;YACjE,qFAAqF;YACrF,kFAAkF;YAClF,yEAAyE;YACzE,IAAI,eAAe,GAAG,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5D,MAAM,mBAAmB,CAAC,eAAe,CAAC;oBACxC,cAAc,EAAE,aAAa;oBAC7B,gBAAgB,EAAE,gBAAgB,CAAC,gBAAgB,GAAG,eAAe;oBACrE,UAAU,EAAE,gBAAgB,CAAC,UAAU,GAAG,cAAc,CAAC,UAAU;iBACpE,CAAC,CAAA;YACJ,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;YAC3D,OAAO,CAAC,GAAG,CACT,mDAAmD,aAAa,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,GAAG,CAC9G,CAAA;YACD,OAAO,CAAC,GAAG,CACT,2DACE,gBAAgB,CAAC,gBAAgB,GAAG,eACtC,EAAE,CACH,CAAA;YACD,OAAO,CAAC,GAAG,CACT,sDAAsD,CACpD,CAAC,gBAAgB,CAAC,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC;gBACzD,IAAI;gBACJ,IAAI,CACL,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAClB,CAAA;YAED,IAAI,WAAW,GAAG,CAAC,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,EAAE,CAAC;gBAClE,KAAK,CAAC,YAAY,CAAC,GAAG,WAAW,IAAI,MAAM,2BAA2B,CAAC,CAAA;YACzE,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,eAAe,EAAE,CAAA;YACzB,CAAC;YACD,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,WAAW,CAAC,CAAA;QACzD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,oBAAoB,CAAC,KAAK,EAAE,CAAA;YAC5B,IAAI,KAAK,EAAE,OAAO,KAAK,gBAAgB,EAAE,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;gBACtD,KAAK,CAAC,gBAAgB,EAAE,CAAA;gBACxB,MAAM,wBAAwB,CAAC,iBAAiB,EAAE,CAAA;YACpD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;gBAC7D,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,IAAI,iBAAiB,CAAC,CAAA;gBACvD,MAAM,wBAAwB,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,IAAI,iBAAiB,CAAC,CAAA;YACnF,CAAC;YAED,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;gBACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,sBAAsB,CAAC,QAAwB,EAAE,UAAkB;QAC/E,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACpC,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAA;QACzE,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,mDAAmD,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAEjF,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QACjD,MAAM,eAAe,GAAG,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAE/E,IAAI,eAAe,GAAG,CAAC,CAAA;QACvB,IAAI,WAAW,GAAG,CAAC,CAAA;QACnB,IAAI,mBAAmB,GAAG,CAAC,CAAA;QAC3B,IAAI,qBAAqB,GAAG,QAAQ,CAAA,CAAC,2BAA2B;QAChE,IAAI,sBAAsB,GAAG,CAAC,CAAA;QAE9B,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,uBAAuB,EAAE,CAAA;QAC7E,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;QAEtG,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;gBAE3B,qBAAqB;gBACrB,IAAI,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;oBACzC,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAA;gBACnC,CAAC;gBAED,wBAAwB;gBACxB,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;gBACnD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBACV,oCAAoC;oBACpC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;oBACvD,MAAM,mBAAmB,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAA;gBACnD,CAAC;gBACD,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;gBAElD,IAAI,CAAC;oBACH,OAAO,CAAC,GAAG,CACT,iDAAiD,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,UAAU,KAC9F,OAAO,CAAC,KAAK,CAAC,MAChB,SAAS,CACV,CAAA;oBAED,kCAAkC,CAAC,OAAO,CAAC,CAAA;oBAE3C,qCAAqC;oBACrC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,eAAe,CAC/C,OAAO,EACP,CAAC,eAAe,EAAE,UAAU,EAAE,EAAE;wBAC9B,sEAAsE;wBACtE,IAAI,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO;4BAAE,OAAM;wBAChD,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,eAAe,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;wBACtF,MAAM,EAAE,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;wBACzC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;wBAC7D,wBAAwB,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;oBAC/F,CAAC,EACD,IAAI,CAAC,eAAe,EAAE,MAAM,CAC7B,CAAA;oBAED,qBAAqB;oBACrB,MAAM,GAAG,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;oBAC1C,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;oBAE3C,mBAAmB,IAAI,OAAO,CAAC,UAAU,CAAA;oBACzC,eAAe,EAAE,CAAA;oBACjB,IAAI,OAAO,CAAC,SAAS,GAAG,sBAAsB,EAAE,CAAC;wBAC/C,sBAAsB,GAAG,OAAO,CAAC,SAAS,CAAA;oBAC5C,CAAC;oBAED,gEAAgE;oBAChE,qFAAqF;oBACrF,oBAAoB,CAAC,OAAO,CAAC;wBAC3B,EAAE,EAAE,OAAO,CAAC,UAAU;wBACtB,IAAI,EAAE,OAAO,CAAC,IAAI;wBAClB,WAAW,EAAE,MAAM,CAAC,WAAW;wBAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;wBACjC,WAAW,EAAE,MAAM,CAAC,WAAW;wBAC/B,aAAa,EAAE,OAAO,CAAC,cAAc;wBACrC,UAAU,EAAE,MAAM,CAAC,UAAU;wBAC7B,SAAS,EAAE,OAAO,CAAC,SAAS;wBAC5B,SAAS,EAAE,OAAO,CAAC,UAAU;wBAC7B,QAAQ,EAAE,OAAO,CAAC,QAAQ;wBAC1B,YAAY,EAAE,eAAe;wBAC7B,aAAa,EAAE,CAAC,CAAC,mBAAmB;wBACpC,cAAc,EAAE,CAAC,CAAC,cAAc;wBAChC,iBAAiB,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;wBACvC,eAAe,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;qBACnE,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,YAAiB,EAAE,CAAC;oBAC3B,IAAI,YAAY,EAAE,OAAO,KAAK,gBAAgB;wBAAE,MAAM,YAAY,CAAA;oBAClE,MAAM,MAAM,GAAG,YAAY,EAAE,OAAO,IAAI,YAAY,EAAE,QAAQ,EAAE,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;oBAClG,OAAO,CAAC,KAAK,CAAC,uDAAuD,OAAO,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC,CAAA;oBACrG,WAAW,EAAE,CAAA;oBACb,iEAAiE;oBACjE,IAAI,OAAO,CAAC,SAAS,GAAG,qBAAqB,EAAE,CAAC;wBAC9C,qBAAqB,GAAG,OAAO,CAAC,SAAS,CAAA;oBAC3C,CAAC;oBACD,MAAM,EAAE,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;oBACzC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC;YAED,gCAAgC;YAChC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;gBACjD,MAAM,EAAE,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;gBACzC,EAAE,CAAC,cAAc,CAAC,WAAW,CAAC,UAAU,CAAC,CAAA;YAC3C,CAAC;YAED,MAAM,mBAAmB,CAAC,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YAE/D,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,CAAA;YACvD,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;YAC5E,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAA;YACzE,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;YAC5E,OAAO,CAAC,GAAG,CAAC,yCAAyC,eAAe,aAAa,WAAW,EAAE,CAAC,CAAA;YAC/F,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;YAE3F,8DAA8D;YAC9D,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;YAChF,MAAM,oBAAoB,CAAC,gBAAgB,EAAE,CAAA;YAC7C,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;YAEhE,4EAA4E;YAC5E,wEAAwE;YACxE,6EAA6E;YAC7E,4EAA4E;YAC5E,oEAAoE;YACpE,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAkB,CAAA;YACtD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;oBACpC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,CAAA;gBACrD,CAAC;YACH,CAAC;YACD,MAAM,cAAc,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAA;YACjE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS,cAAc,CAAC,CAAA;YACxD,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;gBACxC,MAAM,EAAE,GAAG,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;gBAC7C,IAAI,EAAE,KAAK,SAAS;oBAAE,SAAQ,CAAC,yDAAyD;gBACxF,IAAI,EAAE,GAAG,qBAAqB,EAAE,CAAC;oBAC/B,qBAAqB,GAAG,EAAE,CAAA;gBAC5B,CAAC;YACH,CAAC;YACD,+EAA+E;YAC/E,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAA;YAC7F,IAAI,mBAAmB,GAAG,WAAW,EAAE,CAAC;gBACtC,WAAW,GAAG,mBAAmB,CAAA;YACnC,CAAC;YAED,4EAA4E;YAC5E,IAAI,aAAa,GAAG,UAAU,CAAA;YAC9B,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,CAAA;YACjE,IAAI,WAAW,GAAG,CAAC,IAAI,qBAAqB,GAAG,QAAQ,EAAE,CAAC;gBACxD,mFAAmF;gBACnF,6EAA6E;gBAC7E,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAC,CAAA;gBACtD,OAAO,CAAC,GAAG,CACT,6BAA6B,WAAW,4CAA4C,aAAa,eAAe,UAAU,0BAA0B,CACrJ,CAAA;YACH,CAAC;iBAAM,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;gBACjC,aAAa,GAAG,gBAAgB,CAAC,cAAc,CAAA;gBAC/C,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAA;YAC5F,CAAC;iBAAM,IAAI,sBAAsB,GAAG,CAAC,EAAE,CAAC;gBACtC,aAAa,GAAG,sBAAsB,CAAA;YACxC,CAAC;YACD,oFAAoF;YACpF,+EAA+E;YAC/E,IAAI,eAAe,GAAG,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,qBAAqB,GAAG,QAAQ,CAAC,EAAE,CAAC;gBACjF,MAAM,mBAAmB,CAAC,eAAe,CAAC;oBACxC,cAAc,EAAE,aAAa;oBAC7B,gBAAgB,EAAE,gBAAgB,CAAC,gBAAgB,GAAG,eAAe;oBACrE,UAAU,EAAE,gBAAgB,CAAC,UAAU,GAAG,mBAAmB;iBAC9D,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,WAAW,GAAG,CAAC,IAAI,qBAAqB,CAAC,kBAAkB,EAAE,EAAE,CAAC;gBAClE,KAAK,CAAC,YAAY,CAAC,GAAG,WAAW,IAAI,MAAM,2BAA2B,CAAC,CAAA;YACzE,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,eAAe,EAAE,CAAA;YACzB,CAAC;YACD,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,WAAW,CAAC,CAAA;QACzD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,oBAAoB,CAAC,KAAK,EAAE,CAAA;YAC5B,IAAI,KAAK,EAAE,OAAO,KAAK,gBAAgB,EAAE,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;gBACtD,KAAK,CAAC,gBAAgB,EAAE,CAAA;gBACxB,MAAM,wBAAwB,CAAC,iBAAiB,EAAE,CAAA;YACpD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAA;gBACrE,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,IAAI,iBAAiB,CAAC,CAAA;gBACvD,MAAM,wBAAwB,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,IAAI,iBAAiB,CAAC,CAAA;YACnF,CAAC;YAED,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;gBACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,eAAuB,EAAE,WAAmB;QACvE,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;QAChE,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAA;QACvD,OAAO,CAAC,GAAG,CAAC,2CAA2C,eAAe,EAAE,CAAC,CAAA;QACzE,OAAO,CAAC,GAAG,CAAC,uCAAuC,WAAW,EAAE,CAAC,CAAA;QACjE,OAAO,CAAC,GAAG,CACT,6CACE,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,eAAe,GAAG,WAAW,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACjG,GAAG,CACJ,CAAA;QAED,mEAAmE;QACnE,QAAQ;QACR,0EAA0E;QAC1E,kDAAkD;QAClD,2GAA2G;QAC3G,+DAA+D;QAC/D,cAAc;QACd,wBAAwB;QACxB,wCAAwC;QACxC,wCAAwC;QACxC,8EAA8E;QAC9E,SAAS;QACT,oBAAoB;QACpB,oCAAoC;QACpC,8CAA8C;QAC9C,kEAAkE;QAClE,wEAAwE;QACxE,qBAAqB;QACrB,oHAAoH;QACpH,UAAU;QACV,SAAS;QACT,iCAAiC;QACjC,wFAAwF;QACxF,MAAM;QACN,oBAAoB;QACpB,oFAAoF;QACpF,IAAI;QAEJ,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,kBAAkB,EAAE,CAAA;QACrE,IAAI,CAAC,kBAAkB,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAA;YACzE,MAAM,mBAAmB,CAAC,cAAc,EAAE,CAAA;QAC5C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAA;QAChG,CAAC;QAED,IAAI,kBAAkB,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAA;YAC/E,MAAM,wBAAwB,CAAC,aAAa,CAC1C,WAAW,GAAG,CAAC;gBACb,CAAC,CAAC,GAAG,WAAW,gBAAgB,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,kBAAkB;gBAC9E,CAAC,CAAC,mDAAmD,CACxD,CAAA;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAA;YAC3E,MAAM,wBAAwB,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,CAAC,CAAA;QACrE,CAAC;QAED,gCAAgC;QAChC,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAA;YAC/E,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;QAC3B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAA;QACjG,CAAC;QAED,gEAAgE;QAChE,qDAAqD;QACrD,6EAA6E;QAC7E,IAAI,CAAC,kBAAkB,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAA;YAC1F,KAAK,CAAC,yBAAyB,EAAE,CAAA;QACnC,CAAC;QAED,wEAAwE;QACxE,gEAAgE;QAChE,4EAA4E;QAC5E,8EAA8E;QAC9E,sEAAsE;QACtE,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAA;QACtF,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAC5B,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;YACnD,IAAI,YAAY,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;gBAC1C,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAA;gBAC1E,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;YACnC,CAAC;YACD,qEAAqE;YACrE,4DAA4D;YAC5D,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAA;YACzF,MAAM,IAAI,CAAC,yBAAyB,EAAE,CAAA;QACxC,CAAC,EAAE,IAAI,CAAC,CAAA;QAER,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;QAC5E,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;QACzD,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAA;IAC9E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;QAEtD,8BAA8B;QAC9B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;YAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;QAC7B,CAAC;QAED,gBAAgB;QAChB,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAClC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAyB,CAAC,CAAA;YACpD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAA;QACtC,CAAC;QAED,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAE5C,gCAAgC;QAChC,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;QAC3B,CAAC;QAED,eAAe;QACf,KAAK,CAAC,gBAAgB,EAAE,CAAA;QAExB,cAAc;QACd,MAAM,mBAAmB,CAAC,cAAc,EAAE,CAAA;QAE1C,uBAAuB;QACvB,MAAM,wBAAwB,CAAC,iBAAiB,EAAE,CAAA;IACpD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY;QACxB,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAE5C,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;YACtD,MAAM,qBAAqB,CAAC,UAAU,EAAE,CAAA;YACxC,MAAM,YAAY,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;YACzC,KAAK,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAA;YACxC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;YAC1B,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAA;QACvE,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB;QACzB,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,qBAAqB,EAAE,CAAA;QAEtE,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;YAC9D,sCAAsC;YACtC,gEAAgE;QAClE,CAAC;QAED,OAAO,YAAY,CAAA;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,CAAA;QAEtD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAA;YACtD,MAAM,mBAAmB,CAAC,cAAc,EAAE,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,6EAA6E;QAC7E,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAA;QAC7C,IAAI,QAAQ,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,uCAAuC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,2BAA2B,CAAC,CAAA;YAC1G,MAAM,mBAAmB,CAAC,cAAc,EAAE,CAAA;YAC1C,uEAAuE;YACvE,OAAM;QACR,CAAC;QAED,0EAA0E;QAC1E,2EAA2E;QAC3E,wEAAwE;QACxE,OAAO,CAAC,GAAG,CAAC,gDAAgD,KAAK,CAAC,YAAY,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;QAC3G,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAA;QACjF,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,yBAAyB;QAC7B,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,kBAAkB,EAAE,CAAA;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sDAAsD,EAAE,KAAK,CAAC,CAAA;QAC9E,CAAC;IACH,CAAC;IAED,yFAAyF;IACzF,cAAc;QACZ,OAAO,IAAI,CAAC,gBAAgB,KAAK,IAAI,CAAA;IACvC,CAAC;IAED;;;OAGG;IACH,SAAS;QACP,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAA;QAC5C,OAAO,CACL,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,iBAAiB,IAAI,KAAK,CAAC,SAAS,KAAK,oBAAoB,CACnH,CAAA;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,WAAW,EAAE,CAAA","sourcesContent":["/**\n * Gallery Sync Service\n * Orchestrates gallery sync independently of UI lifecycle\n */\n\nimport * as RNFS from \"@dr.pogodin/react-native-fs\"\nimport NetInfo from \"@react-native-community/netinfo\"\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport CrustModule from \"@mentra/crust\"\nimport {AppState, AppStateStatus, Platform} from \"react-native\"\nimport BleManager from \"react-native-ble-manager\"\nimport WifiManager from \"react-native-wifi-reborn\"\n\nimport {useGallerySyncStore, HotspotInfo} from \"../../stores/gallerySync\"\nimport {selectGlassesConnected, useGlassesStore} from \"../../stores/glasses\"\nimport {isGlassesConnected} from \"../GlassesReadiness\"\nimport {SETTINGS, useSettingsStore} from \"../../stores/settings\"\nimport {PhotoInfo, CaptureGroup} from \"../../types/asg\"\nimport GlobalEventEmitter from \"../../utils/GlobalEventEmitter\"\nimport {BgTimer} from \"../../utils/timers\"\nimport {fixGlassesClockIfSkewed} from \"../glassesClockSync\"\nimport {detectClockSkew, isSyncManifestEmpty} from \"../gallerySyncClock\"\nimport {MediaLibraryPermissions} from \"../../utils/permissions/MediaLibraryPermissions\"\nimport {permissions, PermissionFeatures} from \"../../facades/permissions\"\n\nimport {asgCameraApi} from \"./asgCameraApi\"\nimport {gallerySettingsService} from \"./gallerySettingsService\"\nimport {gallerySyncNotifications} from \"./gallerySyncNotifications\"\nimport {localNetworkTransport} from \"./localNetworkTransport\"\nimport {localStorageService} from \"./localStorageService\"\nimport {mediaProcessingQueue} from \"./mediaProcessingQueue\"\nimport {validateCaptureMetadataForDownload} from \"./galleryMediaValidation\"\nimport {emitGalleryNotice} from \"./galleryNotices\"\nimport {galleryTransferLedger} from \"./galleryTransferLedger\"\nimport {cameraRollExportCoordinator} from \"./cameraRollExportCoordinator\"\n\n// Timing constants\nconst TIMING = {\n HOTSPOT_CONNECT_DELAY_MS: 3000, // Increased from 1000ms - hotspot needs time to broadcast and become discoverable\n HOTSPOT_REQUEST_TIMEOUT_MS: 30000, // Timeout waiting for hotspot to enable\n WIFI_CONNECTION_TIMEOUT_MS: 30000,\n RETRY_DELAY_MS: 2000,\n MAX_QUEUE_AGE_MS: 2 * 60 * 1000, // 2 min - glasses hotspot auto-disables after 40s inactivity\n // iOS WiFi connection timing - the system shows a dialog that user must accept\n IOS_WIFI_RETRY_DELAY_MS: 3000, // Wait for user to interact with iOS dialog\n IOS_WIFI_MAX_RETRIES: 5, // Retry multiple times to give user time to accept\n // WiFi initialization cooldown - prevents repeated \"enable WiFi\" alerts while WiFi is initializing\n WIFI_COOLDOWN_MS: 3000, // Wait 3 seconds after user visits WiFi settings before showing alert again\n // Cap the native location-services (GPS) check so a hung CrustModule call can't freeze\n // the sync pre-flight (mirrors the host's former PermissionsUtils guard).\n LOCATION_SERVICES_CHECK_TIMEOUT_MS: 5000,\n} as const\n\ntype SyncManifestData = {\n api_version?: number\n client_id: string\n captures?: CaptureGroup[]\n changed_files: PhotoInfo[]\n deleted_files?: string[]\n server_time: number\n total_changed?: number\n total_size?: number\n}\n\nclass GallerySyncService {\n private static instance: GallerySyncService\n private hotspotListenerRegistered = false\n private hotspotConnectionTimeout: number | null = null\n private hotspotRequestTimeout: number | null = null\n private abortController: AbortController | null = null\n private isInitialized = false\n private glassesStoreUnsubscribe: (() => void) | null = null\n private appStateSubscription: ReturnType<typeof AppState.addEventListener> | null = null\n private waitingForWifiRetry = false\n // Guards full-sync recovery so we don't re-download the entire gallery every sync\n // when glasses retain leftover files (e.g. a previous delete-from-glasses failed).\n // Keyed by `${client_id}:${last_sync_time}` — same pair = already tried, skip.\n private lastFullSyncRetryKey: string | null = null\n private wifiSettingsOpenedAt: number | null = null // Timestamp when user was sent to WiFi settings\n private syncStartPromise: Promise<void> | null = null\n private startAborted = false\n\n private constructor() {}\n\n static getInstance(): GallerySyncService {\n if (!GallerySyncService.instance) {\n GallerySyncService.instance = new GallerySyncService()\n }\n return GallerySyncService.instance\n }\n\n /**\n * Initialize the service - register event listeners\n */\n initialize(): void {\n if (this.isInitialized) return\n\n // Listen for hotspot status changes\n GlobalEventEmitter.addListener(\"hotspot_status_change\", this.handleHotspotStatusChange)\n GlobalEventEmitter.addListener(\"hotspot_error\", this.handleHotspotError)\n GlobalEventEmitter.addListener(\"gallery_status\", this.handleGalleryStatus)\n\n // Subscribe to glasses store to detect disconnection during sync\n this.glassesStoreUnsubscribe = useGlassesStore.subscribe(selectGlassesConnected, (connected, prevConnected) => {\n // Only trigger on disconnect (was connected, now not connected)\n if (prevConnected && !connected) {\n this.handleGlassesDisconnected()\n }\n })\n\n // Listen for app state changes to auto-retry sync after user enables WiFi\n this.appStateSubscription = AppState.addEventListener(\"change\", this.handleAppStateChange)\n\n this.hotspotListenerRegistered = true\n this.isInitialized = true\n\n void cameraRollExportCoordinator.initialize()\n\n // console.log(\"[GallerySyncService] Initialized\")\n\n // Check for resumable sync on startup\n this.checkForResumableSync()\n }\n\n /**\n * Cleanup - remove event listeners\n */\n cleanup(): void {\n void localNetworkTransport.disconnect()\n if (this.hotspotListenerRegistered) {\n GlobalEventEmitter.removeListener(\"hotspot_status_change\", this.handleHotspotStatusChange)\n GlobalEventEmitter.removeListener(\"hotspot_error\", this.handleHotspotError)\n GlobalEventEmitter.removeListener(\"gallery_status\", this.handleGalleryStatus)\n this.hotspotListenerRegistered = false\n }\n\n if (this.glassesStoreUnsubscribe) {\n this.glassesStoreUnsubscribe()\n this.glassesStoreUnsubscribe = null\n }\n\n if (this.appStateSubscription) {\n this.appStateSubscription.remove()\n this.appStateSubscription = null\n }\n cameraRollExportCoordinator.cleanup()\n\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n\n this.syncStartPromise = null\n this.isInitialized = false\n console.log(\"[GallerySyncService] Cleaned up\")\n }\n\n /**\n * Handle glasses disconnection during sync\n */\n private handleGlassesDisconnected = (): void => {\n const store = useGallerySyncStore.getState()\n\n // Pre-flight has no sync state yet — abort quietly; runStartSync checks this flag after awaits\n if (this.syncStartPromise && !this.isSyncing()) {\n console.log(\"[GallerySyncService] Glasses disconnected during pre-flight — aborting start\")\n this.startAborted = true\n return\n }\n\n // Only handle if we're actively syncing\n if (!this.isSyncing()) {\n return\n }\n\n console.log(\"[GallerySyncService] Glasses disconnected during sync - cancelling\")\n store.setSyncError(\"Glasses disconnected\")\n\n // Abort ongoing downloads\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n\n // Clear timeouts\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n void localNetworkTransport.disconnect()\n }\n\n /**\n * Handle app state changes to auto-retry sync when user returns from settings\n */\n private handleAppStateChange = async (nextAppState: AppStateStatus): Promise<void> => {\n // Only handle when app comes to foreground\n if (nextAppState !== \"active\") {\n return\n }\n\n // Camera-roll backfill is phone-local and must resume independently of glasses/WiFi.\n void cameraRollExportCoordinator.resume(\"app foreground\")\n\n // Only auto-retry if we were waiting for WiFi\n if (!this.waitingForWifiRetry) {\n return\n }\n\n console.log(\"[GallerySyncService] App returned to foreground - checking if WiFi is enabled\")\n\n const store = useGallerySyncStore.getState()\n const glassesStore = useGlassesStore.getState()\n const glassesConnected = isGlassesConnected(glassesStore.connection)\n\n // Check if glasses are still connected\n if (!glassesConnected) {\n console.log(\"[GallerySyncService] Glasses disconnected - not retrying sync\")\n this.waitingForWifiRetry = false\n return\n }\n\n // Check if WiFi is now enabled (Android only)\n // Use retry logic because WiFi status takes time to propagate after user enables it\n if (Platform.OS === \"android\") {\n const MAX_RETRIES = 5\n const RETRY_DELAY_MS = 1000 // Wait 500ms between checks\n\n console.log(\"[GallerySyncService] Waiting for WiFi to initialize (may take a moment after enabling)...\")\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n try {\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), RETRY_DELAY_MS))\n\n const netState = await NetInfo.fetch()\n console.log(\n `[GallerySyncService] WiFi check attempt ${attempt}/${MAX_RETRIES}: enabled=${netState.isWifiEnabled}`,\n )\n\n if (netState.isWifiEnabled === true) {\n console.log(\"[GallerySyncService] ✅ WiFi is now enabled - auto-retrying sync\")\n this.waitingForWifiRetry = false\n this.wifiSettingsOpenedAt = null // Clear cooldown timestamp\n // Clear previous error state\n store.setSyncState(\"idle\")\n // Auto-retry sync\n await this.startSync()\n return\n }\n\n // If this was the last attempt, log and give up\n if (attempt === MAX_RETRIES) {\n console.log(\n \"[GallerySyncService] ❌ WiFi still disabled after all retries - user may need to tap sync manually\",\n )\n this.waitingForWifiRetry = false\n this.wifiSettingsOpenedAt = null // Clear cooldown timestamp\n }\n } catch (error) {\n console.warn(`[GallerySyncService] Failed to check WiFi status on attempt ${attempt}:`, error)\n // Continue to next retry\n }\n }\n }\n }\n\n /**\n * Handle gallery status from glasses\n */\n private handleGalleryStatus = (data: any): void => {\n console.log(\"[GallerySyncService] Received gallery_status:\", data)\n\n const store = useGallerySyncStore.getState()\n store.setGlassesGalleryStatus(data.photos || 0, data.videos || 0, data.total || 0, data.has_content || false)\n }\n\n /**\n * Handle hotspot status change event\n */\n private handleHotspotStatusChange = async (eventData: any): Promise<void> => {\n console.log(\"[GallerySyncService] Hotspot status changed:\", eventData)\n\n const store = useGallerySyncStore.getState()\n\n // Only process if we're in a connecting state\n if (store.syncState !== \"requesting_hotspot\" && store.syncState !== \"connecting_wifi\") {\n console.log(\"[GallerySyncService] Ignoring hotspot event - not in connecting state\")\n return\n }\n\n if (!eventData.enabled || !eventData.ssid || !eventData.password) {\n console.log(\"[GallerySyncService] Hotspot not ready yet\")\n return\n }\n\n // Clear the hotspot request timeout since we got a response\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n\n // Pre-flight: do not start the wait if already disconnected (e.g. BT dropped right after hotspot enabled)\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\"[GallerySyncService] ❌ Glasses disconnected on hotspot_status_change - aborting (no wait)\")\n store.setSyncError(\"Glasses disconnected\")\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n return\n }\n\n const hotspotInfo: HotspotInfo = {\n ssid: eventData.ssid,\n password: eventData.password,\n ip: eventData.local_ip,\n }\n\n store.setHotspotInfo(hotspotInfo)\n\n // Wait for hotspot to become discoverable\n console.log(\n `[GallerySyncService] Hotspot enabled, waiting ${TIMING.HOTSPOT_CONNECT_DELAY_MS}ms for broadcast initialization...`,\n )\n console.log(\"[GallerySyncService] 📡 Glasses need time to start WiFi AP and broadcast SSID\")\n\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n }\n\n this.hotspotConnectionTimeout = BgTimer.setTimeout(() => {\n this.hotspotConnectionTimeout = null\n // Pre-flight: abort if Bluetooth disconnected during the wait\n const stillConnected = isGlassesConnected(useGlassesStore.getState().connection)\n if (!stillConnected) {\n console.log(\"[GallerySyncService] ❌ Glasses disconnected during hotspot wait - skipping WiFi connection\")\n const currentStore = useGallerySyncStore.getState()\n currentStore.setSyncError(\"Glasses disconnected\")\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n return\n }\n console.log(\"[GallerySyncService] ✅ Hotspot broadcast window complete - attempting connection\")\n this.connectToHotspotWifi(hotspotInfo)\n }, TIMING.HOTSPOT_CONNECT_DELAY_MS)\n }\n\n /**\n * Handle hotspot error event\n */\n private handleHotspotError = (eventData: any): void => {\n console.error(\"[GallerySyncService] Hotspot error:\", eventData)\n\n const store = useGallerySyncStore.getState()\n\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n\n store.setSyncError(eventData.error_message || \"Failed to start hotspot\")\n gallerySyncNotifications.showSyncError(\"Failed to start hotspot\")\n }\n\n /**\n * Start the sync process\n */\n async startSync(): Promise<void> {\n if (this.syncStartPromise) {\n console.log(\"[GallerySyncService] ⚠️ Sync start already in progress, joining existing attempt\")\n return this.syncStartPromise\n }\n\n this.syncStartPromise = this.runStartSync().finally(() => {\n this.syncStartPromise = null\n })\n return this.syncStartPromise\n }\n\n /**\n * Native location-services (GPS on/off) check, raced against a timeout so a hung\n * CrustModule call can't freeze the sync pre-flight. Mirrors the host's former\n * PermissionsUtils.isLocationServicesEnabled exactly: on timeout assume enabled\n * (proceed); on any other native error assume disabled (block + prompt). Android-only\n * callers; iOS doesn't need location for BLE since iOS 13.\n */\n private async isLocationServicesEnabled(): Promise<boolean> {\n try {\n return await Promise.race([\n CrustModule.isLocationServicesEnabled(),\n new Promise<boolean>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"Location services check timed out\")),\n TIMING.LOCATION_SERVICES_CHECK_TIMEOUT_MS,\n ),\n ),\n ])\n } catch (error) {\n console.error(\"[GallerySyncService] Error checking location services:\", error)\n if (error instanceof Error && error.message.includes(\"timed out\")) {\n console.warn(\"[GallerySyncService] Location services check timed out — assuming enabled so sync can proceed\")\n return true\n }\n return false\n }\n }\n\n /**\n * Mirrors the host's old PermissionsUtils.isBluetoothEnabled exactly: poll\n * BleManager for up to 500ms while the adapter reports \"unknown\"; assume\n * enabled on a timeout (a slow adapter must not block the sync) and disabled\n * on a check error.\n */\n private async isBluetoothAdapterEnabled(): Promise<boolean> {\n try {\n await BleManager.start({showAlert: false})\n for (let attempt = 0; attempt < 10; attempt++) {\n const state = await BleManager.checkState()\n if (state !== \"unknown\") {\n return state === \"on\"\n }\n await new Promise((resolve) => setTimeout(resolve, 50))\n }\n console.warn(\"[GallerySyncService] Bluetooth state still unknown after 500ms - assuming enabled\")\n return true\n } catch (error) {\n console.error(\"[GallerySyncService] Error checking Bluetooth state:\", error)\n return false\n }\n }\n\n private shouldAbortPreFlight(): boolean {\n if (this.startAborted) {\n this.startAborted = false\n return true\n }\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n return true\n }\n return false\n }\n\n private async runStartSync(): Promise<void> {\n // Clear stale abort flag — it can persist when a prior pre-flight exited through\n // a non-shouldAbortPreFlight path (e.g. connectivity failed, disk full), which\n // would otherwise cause the next sync attempt to abort spuriously.\n this.startAborted = false\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 🚀 SYNC START INITIATED\")\n console.log(\"[GallerySyncService] ========================================\")\n\n const store = useGallerySyncStore.getState()\n const glassesStore = useGlassesStore.getState()\n const glassesConnected = isGlassesConnected(glassesStore.connection)\n const glassesHotspot =\n glassesStore.hotspot.state === \"enabled\"\n ? {\n ssid: glassesStore.hotspot.ssid,\n password: glassesStore.hotspot.password,\n ip: glassesStore.hotspot.localIp,\n }\n : null\n\n // R1: Check if already syncing (including requesting_hotspot to prevent double-tap)\n if (\n store.syncState === \"syncing\" ||\n store.syncState === \"connecting_wifi\" ||\n store.syncState === \"requesting_hotspot\"\n ) {\n console.log(`[GallerySyncService] ⚠️ Already syncing (state: ${store.syncState}), ignoring start request`)\n return\n }\n\n // Engine-owned pre-flight: glasses reachable + bluetooth adapter on. The host\n // renders the alerts off the structured notices; Android location permission\n // and services are handled in the permission steps below.\n if (!glassesConnected) {\n console.warn(\"[GallerySyncService] Sync aborted - Glasses not connected\")\n store.setSyncError(\"Glasses not connected\")\n emitGalleryNotice({code: \"glasses_disconnected\"})\n return\n }\n\n if (!(await this.isBluetoothAdapterEnabled())) {\n console.warn(\"[GallerySyncService] Sync aborted - Bluetooth is disabled\")\n store.setSyncError(\"Bluetooth disabled - enable Bluetooth and try again\")\n emitGalleryNotice({code: \"bluetooth_off\"})\n return\n }\n\n console.log(\"[GallerySyncService] ✅ Pre-flight check passed - BT enabled, Glasses connected\")\n console.log(\"[GallerySyncService] 📊 Glasses info:\", {\n connected: glassesConnected,\n hotspotEnabled: glassesHotspot !== null,\n })\n\n // Request all permissions upfront so user isn't interrupted during WiFi/download\n console.log(\"[GallerySyncService] 🔐 Step 1/6: Requesting permissions...\")\n\n // 1. Notification permission (for background sync progress)\n console.log(\"[GallerySyncService] 📱 Requesting notification permission...\")\n await gallerySyncNotifications.requestPermissions()\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after notification permission\")\n return\n }\n console.log(\"[GallerySyncService] ✅ Notification permission handled\")\n\n // 2. Location permission (required to read WiFi SSID for hotspot verification)\n console.log(\"[GallerySyncService] 📍 Checking location permission...\")\n const hasLocationPermission = await permissions.check(PermissionFeatures.LOCATION)\n if (!hasLocationPermission) {\n console.log(\"[GallerySyncService] ⚠️ Location permission not granted - requesting...\")\n const granted = await permissions.request(PermissionFeatures.LOCATION)\n if (!granted) {\n console.warn(\"[GallerySyncService] ❌ Location permission denied - WiFi SSID verification may fail\")\n // Don't block sync - we'll try anyway and fall back to IP-based verification if needed\n } else {\n console.log(\"[GallerySyncService] ✅ Location permission granted\")\n }\n } else {\n console.log(\"[GallerySyncService] ✅ Location permission already granted\")\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after location permission\")\n return\n }\n\n if (Platform.OS === \"android\") {\n console.log(\"[GallerySyncService] 📡 Checking local WiFi permission...\")\n const hasLocalWifiPermission = await permissions.check(PermissionFeatures.LOCAL_WIFI)\n if (!hasLocalWifiPermission) {\n const granted = await permissions.request(PermissionFeatures.LOCAL_WIFI)\n if (!granted) {\n store.setSyncError(\"Local WiFi permission is required for gallery sync\")\n await gallerySyncNotifications.showSyncError(\"Allow WiFi access to connect to your glasses\")\n return\n }\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after local WiFi permission\")\n return\n }\n }\n\n // 3. Camera roll permission (if auto-save is enabled)\n const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll()\n console.log(`[GallerySyncService] 📸 Auto-save to camera roll: ${shouldAutoSave}`)\n if (shouldAutoSave) {\n console.log(\"[GallerySyncService] 📸 Checking camera roll permission...\")\n const hasPermission = await MediaLibraryPermissions.checkPermission()\n if (!hasPermission) {\n console.log(\"[GallerySyncService] ⚠️ Camera roll permission not granted - requesting...\")\n const granted = await MediaLibraryPermissions.requestPermission()\n if (!granted) {\n console.warn(\"[GallerySyncService] ❌ Camera roll permission denied - auto-save sync cannot continue\")\n store.setSyncError(\"Camera-roll permission required while automatic saving is enabled\")\n emitGalleryNotice({code: \"camera_roll_permission_required\"})\n return\n } else {\n console.log(\"[GallerySyncService] ✅ Camera roll permission granted\")\n }\n } else {\n console.log(\"[GallerySyncService] ✅ Camera roll permission already granted\")\n }\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after camera roll permission\")\n return\n }\n\n // S1: Disk space check — abort early if insufficient space\n try {\n const fsInfo = await RNFS.getFSInfo()\n const freeSpaceMB = fsInfo.freeSpace / (1024 * 1024)\n console.log(`[GallerySyncService] 💾 Free disk space: ${freeSpaceMB.toFixed(0)} MB`)\n if (fsInfo.freeSpace < 500 * 1024 * 1024) {\n console.error(\"[GallerySyncService] ❌ Insufficient disk space (<500MB)\")\n emitGalleryNotice({code: \"insufficient_storage\", data: {freeSpaceMB: Math.round(freeSpaceMB)}})\n store.setSyncError(\"Insufficient storage space\")\n return\n }\n } catch (fsError) {\n console.warn(\"[GallerySyncService] ⚠️ Could not check disk space:\", fsError)\n // Continue — don't block sync if check fails\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after disk space check\")\n return\n }\n\n // Reset abort controller\n this.abortController = new AbortController()\n\n // COOLDOWN CHECK: If user just went to WiFi settings, show a \"please wait\" message\n // This prevents showing \"enable WiFi\" alert repeatedly while WiFi is initializing\n if (Platform.OS === \"android\" && this.wifiSettingsOpenedAt) {\n const timeSinceSettingsOpened = Date.now() - this.wifiSettingsOpenedAt\n const cooldownRemaining = TIMING.WIFI_COOLDOWN_MS - timeSinceSettingsOpened\n\n if (cooldownRemaining > 0) {\n console.log(\n `[GallerySyncService] WiFi cooldown active (${Math.round(\n cooldownRemaining / 1000,\n )}s remaining) - showing wait message`,\n )\n\n emitGalleryNotice({code: \"wifi_initializing\"})\n return\n } else {\n // Cooldown expired, clear the timestamp\n console.log(\"[GallerySyncService] WiFi cooldown expired - resuming normal behavior\")\n this.wifiSettingsOpenedAt = null\n }\n }\n\n // Pre-flight WiFi check on Android BEFORE any connection attempts\n // This prevents sync failures even when we think we're already connected\n // NOTE: We use WifiManager.isEnabled() instead of NetInfo.isWifiEnabled because\n // NetInfo can return stale/cached data that reports WiFi as enabled when it's actually OFF\n console.log(\"[GallerySyncService] 📡 Step 2/6: WiFi pre-flight check...\")\n if (Platform.OS === \"android\") {\n try {\n // Use WifiManager.isEnabled() for accurate WiFi state (NetInfo can be stale)\n const wifiEnabled = await WifiManager.isEnabled()\n console.log(\"[GallerySyncService] 📡 WiFi enabled (WifiManager):\", wifiEnabled)\n\n // Also log NetInfo for debugging comparison\n const netState = await NetInfo.fetch()\n console.log(\"[GallerySyncService] 📡 WiFi enabled (NetInfo):\", netState.isWifiEnabled)\n console.log(\"[GallerySyncService] 📡 Connected:\", netState.isConnected)\n console.log(\"[GallerySyncService] 📡 Internet reachable:\", netState.isInternetReachable)\n\n if (!wifiEnabled) {\n console.error(\"[GallerySyncService] ❌ WiFi is disabled - cannot sync\")\n\n // Don't arm the auto-retry / \"WiFi initializing\" cooldown yet — whether to arm\n // them depends on the user's choice in the host's prompt, which only the host\n // learns. The host renders an \"enable WiFi → open settings\" alert from this\n // notice and calls ack() ONLY when the user opts to open settings; on Cancel it\n // does nothing, so a declined prompt leaves no pending retry or phantom cooldown.\n // The engine still owns what arming MEANS (this closure) — the host only reports\n // that the user took the affirmative action.\n emitGalleryNotice({\n code: \"wifi_off\",\n ack: () => {\n this.waitingForWifiRetry = true\n this.wifiSettingsOpenedAt = Date.now()\n },\n })\n store.setSyncError(\"WiFi disabled - enable WiFi and try again\")\n\n // Return early - do NOT proceed with sync\n return\n } else {\n // WiFi is enabled - clear any cooldown timestamp\n console.log(\"[GallerySyncService] ✅ WiFi is enabled - proceeding\")\n this.wifiSettingsOpenedAt = null\n }\n } catch (error) {\n console.warn(\"[GallerySyncService] ⚠️ Failed to check WiFi status:\", error)\n // Continue with sync attempt - don't block if check fails\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after WiFi check\")\n return\n }\n } else {\n console.log(\"[GallerySyncService] ℹ️ iOS - WiFi check not required\")\n }\n\n // Check if Location Services is enabled (Android only - required for WiFi operations)\n // This must be checked BEFORE attempting any WiFi connection to avoid cryptic errors\n if (Platform.OS === \"android\") {\n console.log(\"[GallerySyncService] 📍 Checking Location Services status...\")\n try {\n const locationServicesEnabled = await this.isLocationServicesEnabled()\n console.log(\"[GallerySyncService] 📍 Location Services enabled:\", locationServicesEnabled)\n\n if (!locationServicesEnabled) {\n console.error(\"[GallerySyncService] ❌ Location Services is OFF - cannot sync\")\n console.error(\"[GallerySyncService] ❌ Android requires Location Services for WiFi operations\")\n\n // Emit a notice; the host shows the \"enable Location Services\" alert + dialog.\n emitGalleryNotice({code: \"location_services_off\"})\n store.setSyncError(\"Location Services disabled - enable in Settings and try again\")\n\n // Return early - do NOT proceed with sync\n return\n } else {\n console.log(\"[GallerySyncService] ✅ Location Services is enabled - proceeding\")\n }\n } catch (error) {\n console.warn(\"[GallerySyncService] ⚠️ Failed to check Location Services status:\", error)\n // Continue with sync attempt - don't block if check fails\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after location services check\")\n return\n }\n }\n\n // Check if already connected to hotspot\n // IMPORTANT: We must verify the phone's WiFi is actually connected to the hotspot SSID,\n // not just that the glasses reported hotspot is enabled (which persists across app restarts)\n console.log(\"[GallerySyncService] 🔌 Step 3/6: Checking hotspot connection status...\")\n\n // Re-read current glasses state from the store — the snapshot from the top of the function\n // may be stale if glasses disconnected during one of the above awaits.\n const currentGlassesConnected = isGlassesConnected(useGlassesStore.getState().connection)\n if (!currentGlassesConnected) {\n console.log(\"[GallerySyncService] Pre-flight aborted — glasses no longer connected at hotspot check\")\n return\n }\n const currentGlassesStore = useGlassesStore.getState()\n const currentGlassesHotspot =\n currentGlassesStore.hotspot.state === \"enabled\"\n ? {\n ssid: currentGlassesStore.hotspot.ssid,\n password: currentGlassesStore.hotspot.password,\n ip: currentGlassesStore.hotspot.localIp,\n }\n : null\n\n let isAlreadyConnected = false\n if (currentGlassesHotspot) {\n console.log(\"[GallerySyncService] 📊 Glasses hotspot status:\")\n console.log(\"[GallerySyncService] - Enabled: true\")\n console.log(`[GallerySyncService] - SSID: ${currentGlassesHotspot.ssid}`)\n console.log(`[GallerySyncService] - IP: ${currentGlassesHotspot.ip}`)\n\n try {\n const currentSSID = await WifiManager.getCurrentWifiSSID()\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after SSID check\")\n return\n }\n console.log(`[GallerySyncService] 📱 Phone current WiFi SSID: \"${currentSSID}\"`)\n console.log(`[GallerySyncService] 🔍 Comparing with glasses hotspot SSID: \"${currentGlassesHotspot.ssid}\"`)\n\n isAlreadyConnected = currentSSID === currentGlassesHotspot.ssid\n if (isAlreadyConnected) {\n console.log(\"[GallerySyncService] ✅ Phone is already connected to glasses hotspot!\")\n } else if (currentSSID) {\n console.log(`[GallerySyncService] ⚠️ Phone is on different network (${currentSSID})`)\n console.log(\"[GallerySyncService] ➡️ Will request hotspot connection\")\n } else {\n console.log(\"[GallerySyncService] ⚠️ Phone not connected to any WiFi network\")\n }\n } catch (error) {\n console.warn(\"[GallerySyncService] ⚠️ Could not verify current WiFi SSID:\", error)\n // If we can't verify, don't assume we're connected - request hotspot\n isAlreadyConnected = false\n }\n } else {\n console.log(\"[GallerySyncService] ℹ️ Glasses hotspot not currently enabled\")\n console.log(\"[GallerySyncService] ➡️ Will request hotspot activation\")\n }\n\n // Every fallible pre-flight gate has passed. It is now safe to replace the previous\n // in-memory queue; startFileDownload immediately recovers its durable ledger work.\n mediaProcessingQueue.reset()\n\n if (isAlreadyConnected && currentGlassesHotspot) {\n const hotspotInfo: HotspotInfo = currentGlassesHotspot\n store.setHotspotInfo(hotspotInfo)\n store.setSyncState(\"connecting_wifi\")\n if (localNetworkTransport.supportsScopedConnection() && !localNetworkTransport.isScopedConnectionActive()) {\n console.log(\"[GallerySyncService] 📡 System SSID matches; establishing scoped glasses transport\")\n await this.connectToHotspotWifi(hotspotInfo)\n } else {\n console.log(\"[GallerySyncService] 🚀 Skipping hotspot request - already connected!\")\n await this.startFileDownload(hotspotInfo)\n }\n return\n }\n\n // Request hotspot\n console.log(\"[GallerySyncService] 📡 Step 4/6: Requesting hotspot from glasses...\")\n store.setRequestingHotspot()\n store.setSyncServiceOpenedHotspot(true)\n\n // Set timeout for hotspot request - if we don't get a response, fail gracefully\n this.hotspotRequestTimeout = BgTimer.setTimeout(() => {\n const currentStore = useGallerySyncStore.getState()\n if (currentStore.syncState === \"requesting_hotspot\") {\n console.error(\"[GallerySyncService] Hotspot request timed out\")\n currentStore.setSyncError(\"Hotspot request timed out\")\n currentStore.setSyncServiceOpenedHotspot(false)\n gallerySyncNotifications.showSyncError(\"Could not start hotspot - please try again\")\n }\n this.hotspotRequestTimeout = null\n }, TIMING.HOTSPOT_REQUEST_TIMEOUT_MS)\n\n try {\n console.log(\"[GallerySyncService] 📤 Sending hotspot enable command to glasses...\")\n await BluetoothSdk.setHotspotState(true)\n console.log(\"[GallerySyncService] ✅ Hotspot enabled by glasses\")\n } catch (error) {\n // Clear the timeout since we got an immediate error\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n console.error(\"[GallerySyncService] ❌ Failed to request hotspot:\", error)\n store.setSyncError(\"Failed to start hotspot\")\n store.setSyncServiceOpenedHotspot(false)\n }\n }\n\n /**\n * Show explanation dialog before WiFi connection (first time only)\n * Returns true if user wants to proceed, false if cancelled\n */\n private async showWifiJoinExplanation(ssid: string): Promise<boolean> {\n const settingsStore = useSettingsStore.getState()\n const hasSeenExplanation = settingsStore.getSetting(SETTINGS.gallery_sync_explained.key)\n\n if (hasSeenExplanation) {\n console.log(\"[GallerySyncService] User has seen WiFi explanation before - skipping\")\n return true\n }\n\n console.log(\"[GallerySyncService] First sync - showing WiFi join explanation\")\n\n return new Promise<boolean>((resolve) => {\n const proceed = () => {\n // Mark as explained so we don't show again.\n settingsStore.setSetting(SETTINGS.gallery_sync_explained.key, true, false)\n resolve(true)\n }\n // Emit the one-time wifi-join explanation as a notice the host renders + acknowledges.\n // The host owns the alert + its dismiss timing (Android's native WiFi connect freezes\n // the UI thread, so it should let the dialog fully dismiss before calling ack).\n const delivered = emitGalleryNotice({\n code: \"connect_to_glasses\",\n data: {ssid, platform: Platform.OS},\n ack: proceed,\n })\n // No host listening (e.g. an OEM that hasn't wired onNotice) — don't hang the sync.\n if (delivered === 0) proceed()\n })\n }\n\n /**\n * Connect to hotspot WiFi with retry logic (unified for both platforms)\n * Both iOS and Android benefit from retries:\n * - iOS: Library throws \"internal error\" before user responds to system dialog\n * - Android: Hotspot needs time to initialize, especially when glasses WiFi was cold\n */\n private async connectToHotspotWifi(hotspotInfo: HotspotInfo): Promise<void> {\n const store = useGallerySyncStore.getState()\n\n // Pre-flight: do not attempt WiFi connection if Bluetooth already disconnected\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\"[GallerySyncService] ❌ Glasses not connected - aborting WiFi connection\")\n store.setSyncError(\"Glasses disconnected\")\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n return\n }\n\n // Show explanation dialog on first sync (user must acknowledge before proceeding)\n await this.showWifiJoinExplanation(hotspotInfo.ssid)\n\n let lastError: any = null\n const wifiConnectStartTime = Date.now()\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📡 WIFI CONNECTION PHASE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 🎯 Target SSID: ${hotspotInfo.ssid}`)\n console.log(`[GallerySyncService] 🔑 Password length: ${hotspotInfo.password.length} chars`)\n console.log(`[GallerySyncService] 🌐 Gateway IP: ${hotspotInfo.ip}`)\n console.log(`[GallerySyncService] 📱 Platform: ${Platform.OS}`)\n console.log(`[GallerySyncService] 🔄 Max retry attempts: ${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.log(`[GallerySyncService] ⏱️ Retry delay: ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms`)\n\n store.setSyncState(\"connecting_wifi\")\n\n // Setup app state monitoring to detect backgrounding\n let appBackgrounded = false\n let appBackgroundTime: number | null = null\n const appStateHandler = (nextAppState: AppStateStatus) => {\n if (nextAppState === \"background\") {\n appBackgrounded = true\n appBackgroundTime = Date.now()\n console.warn(\"[GallerySyncService] ⚠️ 🚨 APP BACKGROUNDED during WiFi connection!\")\n console.warn(\"[GallerySyncService] ⚠️ This may indicate Android system dialog appeared\")\n console.warn(\n \"[GallerySyncService] ⚠️ Time since WiFi connect started:\",\n Date.now() - wifiConnectStartTime,\n \"ms\",\n )\n } else if (nextAppState === \"active\" && appBackgrounded) {\n console.log(\"[GallerySyncService] ✅ App returned to foreground\")\n console.log(\"[GallerySyncService] ⏱️ Time spent in background:\", Date.now() - (appBackgroundTime || 0), \"ms\")\n }\n }\n\n const appStateSubscription = AppState.addEventListener(\"change\", appStateHandler)\n console.log(\"[GallerySyncService] 👂 App state listener registered\")\n\n // L2: Wrap retry loop in try/finally to guarantee listener cleanup on all exit paths\n try {\n for (let attempt = 1; attempt <= TIMING.IOS_WIFI_MAX_RETRIES; attempt++) {\n const attemptStartTime = Date.now()\n\n // Check if cancelled\n if (this.abortController?.signal.aborted) {\n console.log(\"[GallerySyncService] 🛑 Sync was cancelled - aborting WiFi connection\")\n store.setSyncError(\"Sync cancelled\")\n return\n }\n\n try {\n console.log(\"[GallerySyncService] ----------------------------------------\")\n console.log(\n `[GallerySyncService] 📡 ATTEMPT ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES} - Starting WiFi connection`,\n )\n console.log(`[GallerySyncService] ⏱️ Time since WiFi phase started: ${Date.now() - wifiConnectStartTime}ms`)\n console.log(`[GallerySyncService] 📱 App backgrounded during connection: ${appBackgrounded}`)\n\n // Check current WiFi state before attempting connection\n let preConnectSSID = \"unknown\"\n try {\n preConnectSSID = await WifiManager.getCurrentWifiSSID()\n console.log(`[GallerySyncService] 📡 Current WiFi SSID: \"${preConnectSSID}\"`)\n\n // Check if already connected (shouldn't happen, but good to verify)\n if (!localNetworkTransport.supportsScopedConnection() && preConnectSSID === hotspotInfo.ssid) {\n console.log(\"[GallerySyncService] ✅ Already connected to target SSID! Proceeding to download.\")\n appStateSubscription.remove()\n\n const totalWifiDuration = Date.now() - wifiConnectStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ WIFI CONNECTION COMPLETE (already connected)\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] ⏱️ Total WiFi phase duration: ${totalWifiDuration}ms`)\n console.log(`[GallerySyncService] 🚀 Proceeding to file download from ${hotspotInfo.ip}:8089`)\n\n await this.startFileDownload(hotspotInfo)\n return // Exit function successfully\n }\n } catch (preError: any) {\n console.warn(`[GallerySyncService] ⚠️ Could not get current SSID: ${preError?.message}`)\n console.warn(\"[GallerySyncService] ⚠️ Error code:\", preError?.code)\n }\n\n console.log(`[GallerySyncService] 🔌 Connecting the glasses-local transport...`)\n console.log(`[GallerySyncService] 🔌 Parameters:`)\n console.log(`[GallerySyncService] - SSID: \"${hotspotInfo.ssid}\"`)\n console.log(`[GallerySyncService] - Password: ${\"*\".repeat(hotspotInfo.password.length)}`)\n console.log(`[GallerySyncService] - joinOnce: false`)\n console.log(`[GallerySyncService] - isHidden: false`)\n\n const connectCallStartTime = Date.now()\n appBackgrounded = false // Reset flag for this attempt\n appBackgroundTime = null\n\n await localNetworkTransport.connect(hotspotInfo.ssid, hotspotInfo.password)\n\n const connectCallDuration = Date.now() - connectCallStartTime\n console.log(`[GallerySyncService] ✅ Glasses-local transport connected successfully`)\n console.log(`[GallerySyncService] ⏱️ Library call duration: ${connectCallDuration}ms`)\n console.log(`[GallerySyncService] 📱 App was backgrounded during call: ${appBackgrounded}`)\n if (appBackgrounded && appBackgroundTime) {\n console.log(\n `[GallerySyncService] ⏱️ Time until backgrounding: ${appBackgroundTime - connectCallStartTime}ms`,\n )\n }\n console.log(`[GallerySyncService] 📝 Note: On iOS, this does NOT guarantee actual connection!`)\n\n // iOS-specific: Verify actual WiFi connection by polling SSID\n // The library promise resolves when iOS ACCEPTS the request, not when connection completes\n if (Platform.OS === \"ios\") {\n console.log(`[GallerySyncService] 🍎 iOS: Starting connection verification...`)\n console.log(`[GallerySyncService] 🍎 Will poll getCurrentWifiSSID() for up to 15 seconds`)\n\n const maxVerifyAttempts = 30 // 30 × 500ms = 15 seconds\n let connected = false\n let lastSeenSSID = \"unknown\"\n\n for (let i = 0; i < maxVerifyAttempts; i++) {\n try {\n const currentSSID = await WifiManager.getCurrentWifiSSID()\n lastSeenSSID = currentSSID || \"null\"\n\n console.log(\n `[GallerySyncService] 🍎 Verify poll ${\n i + 1\n }/${maxVerifyAttempts}: Current=\"${currentSSID}\", Target=\"${hotspotInfo.ssid}\"`,\n )\n\n if (currentSSID === hotspotInfo.ssid) {\n console.log(\n `[GallerySyncService] 🍎 ✅ VERIFICATION SUCCESS! Connected to target network after ${\n (i + 1) * 500\n }ms`,\n )\n connected = true\n break\n } else if (i === 0 && currentSSID === lastSeenSSID) {\n console.log(\n `[GallerySyncService] 🍎 ⚠️ Still on original network - iOS dialog may not have appeared yet`,\n )\n }\n } catch (ssidError: any) {\n console.log(`[GallerySyncService] 🍎 ⚠️ Poll ${i + 1}: Could not check SSID: ${ssidError?.message}`)\n lastSeenSSID = \"error\"\n }\n\n // Don't wait after last attempt\n if (i < maxVerifyAttempts - 1) {\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), 500))\n }\n }\n\n if (!connected) {\n console.error(`[GallerySyncService] 🍎 ❌ VERIFICATION FAILED after 15 seconds`)\n console.error(`[GallerySyncService] 🍎 Last seen SSID: \"${lastSeenSSID}\"`)\n console.error(`[GallerySyncService] 🍎 Expected SSID: \"${hotspotInfo.ssid}\"`)\n console.error(`[GallerySyncService] 🍎 Possible causes:`)\n console.error(`[GallerySyncService] 🍎 1. User did not tap \"Join\" on iOS WiFi dialog`)\n console.error(`[GallerySyncService] 🍎 2. iOS dialog did not appear (permission issue?)`)\n console.error(`[GallerySyncService] 🍎 3. iOS refused to switch networks`)\n throw new Error(\n `iOS WiFi verification failed - still on \"${lastSeenSSID}\", expected \"${hotspotInfo.ssid}\"`,\n )\n }\n }\n\n const attemptDuration = Date.now() - attemptStartTime\n console.log(`[GallerySyncService] ✅ WiFi connection successful!`)\n console.log(`[GallerySyncService] ⏱️ Total attempt duration: ${attemptDuration}ms`)\n console.log(`[GallerySyncService] 🎉 Platform: ${Platform.OS}`)\n\n // Remove app state listener\n appStateSubscription.remove()\n console.log(\"[GallerySyncService] 👂 App state listener removed\")\n\n // Final verification: Check SSID one more time before starting download\n try {\n const finalSSID = localNetworkTransport.isScopedConnectionActive()\n ? hotspotInfo.ssid\n : await WifiManager.getCurrentWifiSSID()\n console.log(`[GallerySyncService] 📶 Final SSID check before download: \"${finalSSID}\"`)\n if (Platform.OS === \"android\") {\n // Some local builds can have stale generated typings for the Bluetooth SDK module.\n ;(BluetoothSdk as any).logCurrentWifiFrequency?.()\n }\n if (finalSSID !== hotspotInfo.ssid) {\n console.error(\n `[GallerySyncService] ❌ SSID mismatch detected! Expected \"${hotspotInfo.ssid}\", got \"${finalSSID}\"`,\n )\n throw new Error(`WiFi SSID mismatch - connected to \"${finalSSID}\" instead of \"${hotspotInfo.ssid}\"`)\n }\n } catch (finalError: any) {\n console.warn(`[GallerySyncService] ⚠️ Could not perform final SSID check: ${finalError?.message}`)\n // Continue anyway - we've done our best to verify\n }\n\n // iOS-specific: Wait for actual network connectivity to glasses\n // Even though SSID is correct, iOS needs time for routing tables to update\n // We actively probe the glasses HTTP server until it's reachable\n if (Platform.OS === \"ios\") {\n console.log(`[GallerySyncService] 🍎 Waiting for iOS network routes to glasses IP...`)\n console.log(`[GallerySyncService] 🍎 Will probe http://${hotspotInfo.ip}:8089/api/health`)\n\n const maxProbeAttempts = 20 // 20 attempts × 500ms = 10 seconds max\n let networkReady = false\n\n for (let probeNum = 1; probeNum <= maxProbeAttempts; probeNum++) {\n try {\n console.log(`[GallerySyncService] 🍎 Connectivity probe ${probeNum}/${maxProbeAttempts}...`)\n\n // Try to reach the glasses health endpoint with a short timeout\n const probeController = new AbortController()\n const probeTimeout = BgTimer.setTimeout(() => probeController.abort(), 1000) // 1 second timeout per probe\n\n const probeStartTime = Date.now()\n const probeResponse = await localNetworkTransport.fetch(`http://${hotspotInfo.ip}:8089/api/health`, {\n method: \"GET\",\n signal: probeController.signal,\n })\n BgTimer.clearTimeout(probeTimeout)\n\n const probeDuration = Date.now() - probeStartTime\n console.log(\n `[GallerySyncService] 🍎 Probe ${probeNum} response: HTTP ${probeResponse.status} (${probeDuration}ms)`,\n )\n\n if (probeResponse.status === 200 || probeResponse.status === 404) {\n // 200 = health endpoint exists, 404 = glasses responded (no health endpoint)\n // Either way, network is working!\n console.log(`[GallerySyncService] 🍎 ✅ Network connectivity verified after ${probeNum} probes!`)\n networkReady = true\n break\n }\n } catch (probeError: any) {\n const errorMsg = probeError?.message || \"unknown\"\n console.log(\n `[GallerySyncService] 🍎 Probe ${probeNum} failed: ${errorMsg.substring(0, 50)}${\n errorMsg.length > 50 ? \"...\" : \"\"\n }`,\n )\n // Continue to next probe\n }\n\n // Wait 500ms before next probe (unless this was the last attempt)\n if (probeNum < maxProbeAttempts) {\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), 500))\n }\n }\n\n if (!networkReady) {\n console.error(\n `[GallerySyncService] 🍎 ❌ Network connectivity probe failed after ${maxProbeAttempts} attempts`,\n )\n console.error(`[GallerySyncService] 🍎 iOS routing tables may not be ready for ${hotspotInfo.ip}`)\n throw new Error(\n `iOS network not ready - could not reach ${hotspotInfo.ip}:8089 after ${maxProbeAttempts} attempts`,\n )\n }\n }\n\n // Start the actual download\n const totalWifiDuration = Date.now() - wifiConnectStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ WIFI CONNECTION COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] ⏱️ Total WiFi phase duration: ${totalWifiDuration}ms`)\n console.log(`[GallerySyncService] 🎯 Attempts used: ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.log(`[GallerySyncService] 🚀 Proceeding to file download from ${hotspotInfo.ip}:8089`)\n\n await this.startFileDownload(hotspotInfo)\n return // Success - exit the retry loop\n } catch (error: any) {\n lastError = error\n const attemptDuration = Date.now() - attemptStartTime\n\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(`[GallerySyncService] ❌ WiFi ATTEMPT ${attempt} FAILED`)\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(`[GallerySyncService] ❌ Error message: ${error?.message || \"No message\"}`)\n console.error(`[GallerySyncService] ❌ Error code: ${error?.code || \"No code\"}`)\n console.error(`[GallerySyncService] ❌ Error type: ${error?.name || typeof error}`)\n console.error(`[GallerySyncService] ❌ Platform: ${Platform.OS}`)\n console.error(`[GallerySyncService] ❌ Attempt duration: ${attemptDuration}ms`)\n console.error(`[GallerySyncService] ❌ App was backgrounded: ${appBackgrounded}`)\n if (appBackgrounded && appBackgroundTime) {\n console.error(`[GallerySyncService] ❌ Time in background: ${Date.now() - appBackgroundTime}ms`)\n }\n console.error(`[GallerySyncService] ❌ Full error object:`, JSON.stringify(error, null, 2))\n\n // If user explicitly denied, don't retry\n if (error?.code === \"userDenied\" || error?.message?.includes(\"cancel\")) {\n console.warn(\"[GallerySyncService] 🚫 User cancelled WiFi connection - aborting\")\n appStateSubscription.remove()\n store.setSyncError(\"WiFi connection cancelled\")\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n return\n }\n\n // Handle \"didNotFindNetwork\" - hotspot may still be initializing\n if (error?.code === \"didNotFindNetwork\") {\n console.warn(\"[GallerySyncService] 🔍 Network not found - hotspot may still be initializing\")\n console.warn(\n `[GallerySyncService] 🔍 Will retry in ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms (attempt ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES})`,\n )\n }\n\n // Handle \"timeoutOccurred\" - likely caused by app backgrounding during WiFi dialog\n if (error?.code === \"timeoutOccurred\") {\n console.error(\"[GallerySyncService] ⏰ WiFi connection timeout occurred\")\n console.error(`[GallerySyncService] ⏰ App was backgrounded: ${appBackgrounded}`)\n if (appBackgrounded && appBackgroundTime) {\n console.error(`[GallerySyncService] ⏰ Time in background: ${Date.now() - appBackgroundTime}ms`)\n console.error(\"[GallerySyncService] ⏰ Android may have shown WiFi dialog that user didn't interact with\")\n }\n console.warn(\n `[GallerySyncService] 🔍 Will retry in ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms (attempt ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES})`,\n )\n }\n\n // DISABLED: Check if WiFi was disabled during connection attempt (Android 10+ specific error)\n // if (Platform.OS === \"android\" && error?.message?.includes(\"enable wifi manually\")) {\n // console.error(\"[GallerySyncService] WiFi was disabled during connection\")\n //\n // // Mark that we're waiting for WiFi so we can auto-retry when user returns\n // this.waitingForWifiRetry = true\n //\n // showAlert(\"WiFi Required\", \"WiFi must be enabled to sync photos. Please enable WiFi and try again.\", [\n // {\n // text: \"Cancel\",\n // style: \"cancel\",\n // onPress: () => {\n // this.waitingForWifiRetry = false\n // this.wifiSettingsOpenedAt = null\n // store.setSyncError(\"WiFi disabled - enable WiFi and try again\")\n // if (store.syncServiceOpenedHotspot) {\n // this.closeHotspot()\n // }\n // },\n // },\n // {\n // text: \"Open Settings\",\n // onPress: async () => {\n // // Set timestamp so we can enforce cooldown on next sync attempt\n // this.wifiSettingsOpenedAt = Date.now()\n // await SettingsNavigationUtils.openWifiSettings()\n // store.setSyncError(\"Enable WiFi and try sync again\")\n // if (store.syncServiceOpenedHotspot) {\n // await this.closeHotspot()\n // }\n // },\n // },\n // ])\n // return\n // }\n\n // Let connection fail naturally and show generic error\n if (Platform.OS === \"android\" && error?.message?.includes(\"enable wifi manually\")) {\n console.error(\"[GallerySyncService] 🚫 WiFi was disabled during connection - aborting\")\n appStateSubscription.remove()\n store.setSyncError(\"Could not connect - check WiFi is enabled\")\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n return\n }\n\n // For \"internal error\" or \"unableToConnect\", wait and retry\n // iOS: Gives user time to interact with system dialog\n // Android: Gives hotspot time to fully initialize and start broadcasting\n if (attempt < TIMING.IOS_WIFI_MAX_RETRIES) {\n const reason =\n Platform.OS === \"ios\" ? \"user may be seeing system dialog\" : \"hotspot may still be initializing\"\n console.log(\"[GallerySyncService] ----------------------------------------\")\n console.log(`[GallerySyncService] 🔄 Preparing retry ${attempt + 1}/${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.log(`[GallerySyncService] ⏱️ Waiting ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms (${reason})`)\n console.log(`[GallerySyncService] 📱 App currently: ${AppState.currentState}`)\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), TIMING.IOS_WIFI_RETRY_DELAY_MS))\n console.log(`[GallerySyncService] ⏱️ Wait complete - starting retry`)\n } else {\n console.error(\"[GallerySyncService] 🚫 No more retry attempts available\")\n }\n }\n }\n\n // All retries exhausted\n const totalWifiDuration = Date.now() - wifiConnectStartTime\n\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(\"[GallerySyncService] ❌ WIFI CONNECTION FAILED - ALL RETRIES EXHAUSTED\")\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(`[GallerySyncService] ❌ Platform: ${Platform.OS}`)\n console.error(`[GallerySyncService] ❌ Total attempts: ${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.error(`[GallerySyncService] ❌ Total duration: ${totalWifiDuration}ms`)\n console.error(`[GallerySyncService] ❌ App was backgrounded at some point: ${appBackgrounded}`)\n console.error(`[GallerySyncService] ❌ Last error message: ${lastError?.message || \"No message\"}`)\n console.error(`[GallerySyncService] ❌ Last error code: ${lastError?.code || \"No code\"}`)\n console.error(\"[GallerySyncService] ❌ ========================================\")\n\n // Provide user-friendly error message based on error type\n let userErrorMessage = lastError?.message || \"Failed to connect to glasses WiFi\"\n\n if (lastError?.code === \"timeoutOccurred\" && appBackgrounded) {\n userErrorMessage =\n \"WiFi connection timed out. Android may be blocking automatic WiFi switching. Please manually connect to the glasses hotspot in Settings.\"\n } else if (lastError?.message?.includes(\"internal error\")) {\n userErrorMessage =\n \"Could not connect to glasses WiFi. Please ensure you accept the WiFi prompt when it appears.\"\n }\n\n store.setSyncError(userErrorMessage)\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n } finally {\n // Release the scoped Android Network on every terminal path. This is idempotent with\n // closeHotspot(), and intentionally leaves Android 9/iOS legacy routing unchanged.\n await localNetworkTransport.disconnect()\n // L2: Guarantee listener cleanup on all exit paths (cancel, success, error, exhaustion)\n appStateSubscription.remove()\n }\n }\n\n private async fetchSyncManifest(clientId: string, lastSyncTime: number): Promise<SyncManifestData> {\n const v3 = typeof asgCameraApi.getV3Manifest === \"function\" ? await asgCameraApi.getV3Manifest() : null\n if (v3) {\n const downloadedFiles = await localStorageService.getDownloadedFiles()\n await localStorageService.reconcileRemoteCaptures(\n v3.captures.map((capture) => capture.capture_id),\n downloadedFiles,\n )\n return {\n api_version: 3,\n client_id: clientId,\n // The ledger is a crash-recovery journal, not proof that app-private media survived an\n // Android restore or reinstall. Suppress a remote capture only when both records agree.\n captures: v3.captures.filter(\n (capture) =>\n !downloadedFiles[capture.capture_id] || !galleryTransferLedger.isLocallyCommitted(capture.capture_id),\n ),\n changed_files: [],\n deleted_files: [],\n server_time: v3.server_time,\n total_changed: v3.captures.length,\n total_size: v3.captures.reduce((total, capture) => total + capture.total_size, 0),\n }\n }\n // Old firmware remains on the exact v2 endpoint/schema. Avoid expensive inline thumbnails;\n // the UI can request them lazily after the primary transfer is safe.\n const syncResponse = await asgCameraApi.syncWithServer(clientId, lastSyncTime, false)\n const data = (syncResponse.data || syncResponse) as SyncManifestData\n if (data.captures) {\n data.captures = data.captures.filter((capture) => !galleryTransferLedger.isLocallyCommitted(capture.capture_id))\n }\n data.changed_files = (data.changed_files || []).filter(\n (file) => !galleryTransferLedger.isFileLocallyCommitted(file.name),\n )\n return data\n }\n\n /**\n * Resolve sync manifest: detect skew, optionally fix clock, retry full sync when needed.\n */\n private async resolveSyncManifest(\n clientId: string,\n lastSyncTime: number,\n ): Promise<{syncData: SyncManifestData; usedFullSync: boolean} | null> {\n const store = useGallerySyncStore.getState()\n let syncData = await this.fetchSyncManifest(clientId, lastSyncTime)\n let clockFixed = false\n\n const skewOnFirst = detectClockSkew(Date.now(), syncData.server_time, lastSyncTime)\n if (skewOnFirst.skewed) {\n clockFixed = await fixGlassesClockIfSkewed(syncData.server_time, lastSyncTime)\n if (clockFixed) {\n console.log(\"[GallerySyncService] 🔄 Retrying /api/sync with last_sync_time=0 after clock fix\")\n syncData = await this.fetchSyncManifest(clientId, 0)\n }\n }\n\n if (!isSyncManifestEmpty(syncData)) {\n return {syncData, usedFullSync: clockFixed || lastSyncTime === 0}\n }\n\n // Guard against re-firing the full-sync retry every sync when glasses retain leftover files\n // from a failed delete-from-glasses: at most one retry per (client_id, last_sync_time) pair\n // per process lifetime. Without this, we'd re-download the entire gallery on every sync.\n const retryKey = `${clientId}:${lastSyncTime}`\n const alreadyRetriedForThisWatermark = this.lastFullSyncRetryKey === retryKey\n if (!clockFixed && store.glassesHasContent && lastSyncTime !== 0 && !alreadyRetriedForThisWatermark) {\n this.lastFullSyncRetryKey = retryKey\n console.log(\"[GallerySyncService] 🔄 Empty sync but glasses report content — retrying with last_sync_time=0\")\n syncData = await this.fetchSyncManifest(clientId, 0)\n if (!isSyncManifestEmpty(syncData)) {\n return {syncData, usedFullSync: true}\n }\n } else if (!clockFixed && store.glassesHasContent && lastSyncTime !== 0 && alreadyRetriedForThisWatermark) {\n console.warn(\n \"[GallerySyncService] ⚠️ Glasses still report content but /api/sync empty — already retried this watermark, skipping to avoid re-download loop\",\n )\n }\n\n if (store.glassesHasContent) {\n console.warn(\"[GallerySyncService] ⚠️ Empty sync while glasses still report gallery content\")\n return null\n }\n\n return {syncData, usedFullSync: false}\n }\n\n /**\n * Start downloading files\n */\n private async startFileDownload(hotspotInfo: HotspotInfo): Promise<void> {\n const store = useGallerySyncStore.getState()\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📥 Step 5/6: Starting file download phase\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 🌐 Server: ${hotspotInfo.ip}:8089`)\n\n try {\n // Set up the API client\n asgCameraApi.setServer(hotspotInfo.ip, 8089)\n console.log(\"[GallerySyncService] ✅ API client configured\")\n\n const recovery = await mediaProcessingQueue.retryPending()\n if (recovery.retried > 0 || recovery.failed > 0) {\n console.log(\n `[GallerySyncService] ♻️ Recovery: ${recovery.retried} completed, ${recovery.failed} still pending`,\n )\n }\n\n // Get sync state and files to download\n // IMPORTANT: This creates a SNAPSHOT of files at this moment based on last_sync_time.\n // Any photos taken AFTER this call (during the sync) will NOT be included in this sync.\n // They will be detected in the next sync when we query gallery status again.\n console.log(\"[GallerySyncService] 📊 Fetching sync state from local storage...\")\n const syncState = await localStorageService.getSyncState()\n console.log(\"[GallerySyncService] 📊 Sync state:\", {\n client_id: syncState.client_id,\n last_sync_time: syncState.last_sync_time,\n last_sync_date: syncState.last_sync_time > 0 ? new Date(syncState.last_sync_time).toISOString() : \"Never\",\n total_downloaded: syncState.total_downloaded,\n total_size: `${(syncState.total_size / 1024 / 1024).toFixed(2)} MB`,\n })\n\n console.log(\"[GallerySyncService] 📡 Calling /api/sync endpoint...\")\n const syncStartTime = Date.now()\n const resolved = await this.resolveSyncManifest(syncState.client_id, syncState.last_sync_time)\n const _syncDuration = Date.now() - syncStartTime\n console.log(`[GallerySyncService] ✅ /api/sync completed in ${_syncDuration}ms`)\n\n if (!resolved) {\n const syncErrorMessage = \"Could not sync gallery — try again\"\n store.setSyncError(syncErrorMessage)\n await gallerySyncNotifications.showSyncError(syncErrorMessage)\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n return\n }\n\n const {syncData} = resolved\n\n console.log(\"[GallerySyncService] 📋 Sync response received:\")\n console.log(`[GallerySyncService] - Server time: ${syncData.server_time}`)\n console.log(`[GallerySyncService] - Changed files: ${syncData.changed_files?.length || 0}`)\n console.log(`[GallerySyncService] - Captures: ${syncData.captures?.length || 0}`)\n\n if (isSyncManifestEmpty(syncData)) {\n console.log(\"[GallerySyncService] ✅ No new files to sync - already up to date!\")\n if (galleryTransferLedger.hasPendingRecovery()) {\n store.setSyncError(\"Gallery export or acknowledgement needs retry\")\n } else {\n store.setSyncComplete()\n }\n await this.onSyncComplete(0, 0)\n return\n }\n\n // Detect API version and route to appropriate download path\n const useCaptures = (syncData.api_version || 0) >= 2 && syncData.captures && syncData.captures.length > 0\n\n if (useCaptures) {\n // New capture-aware sync path\n const captures: CaptureGroup[] = syncData.captures!\n console.log(\n `[GallerySyncService] 📊 Found ${captures.length} captures to download (api_version=${syncData.api_version})`,\n )\n\n captures.slice(0, 5).forEach((c: CaptureGroup, idx: number) => {\n console.log(\n `[GallerySyncService] ${idx + 1}. ${c.capture_id} (${c.type}, ${c.files.length} files, ${(\n c.total_size / 1024\n ).toFixed(1)} KB)`,\n )\n })\n if (captures.length > 5) {\n console.log(`[GallerySyncService] ... and ${captures.length - 5} more captures`)\n }\n\n // Build a PhotoInfo[] for the store (one per capture, using primary file info)\n const capturePhotoInfos: PhotoInfo[] = captures.map((c) => {\n const primaryFile = c.files.find((f) => f.role === \"primary\") || c.files[0]\n return {\n name: c.capture_id,\n url: `/api/photo?file=${encodeURIComponent(primaryFile.name)}`,\n download: `/api/download?file=${encodeURIComponent(primaryFile.name)}`,\n size: c.total_size,\n modified: c.timestamp,\n is_video: c.type === \"video\",\n thumbnail_data: c.thumbnail_data,\n duration: c.duration,\n }\n })\n\n store.setSyncing(capturePhotoInfos)\n\n await localStorageService.saveSyncQueue({\n files: capturePhotoInfos,\n currentIndex: 0,\n startedAt: Date.now(),\n hotspotInfo,\n })\n\n await gallerySyncNotifications.showSyncStarted(captures.length)\n\n console.log(\"[GallerySyncService] 🚀 Beginning capture download execution...\")\n await this.executeCaptureDownload(captures, syncData.server_time)\n } else {\n // Legacy flat file sync path\n const filesToSync = syncData.changed_files\n // Count only user-visible media files (exclude HDR brackets and IMU sidecars)\n const userVisibleCount = filesToSync.filter(\n (f: any) => !f.name?.match(/_ev-?\\d+\\.(jpg|jpeg)$/i) && !f.name?.match(/\\.imu\\.json$/i),\n ).length\n console.log(\n `[GallerySyncService] 📊 Found ${filesToSync.length} files to download (${userVisibleCount} media items, legacy path):`,\n )\n\n console.log(\"[GallerySyncService] 📋 First 5 files:\")\n filesToSync.slice(0, 5).forEach((_file: any, _idx: number) => {\n console.log(\n `[GallerySyncService] ${_idx + 1}. ${_file.name} (${_file.is_video ? \"video\" : \"photo\"}, ${(\n _file.size / 1024\n ).toFixed(1)} KB)`,\n )\n })\n if (filesToSync.length > 5) {\n console.log(`[GallerySyncService] ... and ${filesToSync.length - 5} more files`)\n }\n\n store.setSyncing(filesToSync)\n\n await localStorageService.saveSyncQueue({\n files: filesToSync,\n currentIndex: 0,\n startedAt: Date.now(),\n hotspotInfo,\n })\n\n await gallerySyncNotifications.showSyncStarted(userVisibleCount)\n\n console.log(\"[GallerySyncService] 🚀 Beginning download execution (legacy)...\")\n await this.executeDownload(filesToSync, syncData.server_time)\n }\n } catch (error: any) {\n console.error(\"[GallerySyncService] Failed to start download:\", error)\n store.setSyncError(error?.message || \"Failed to start download\")\n await gallerySyncNotifications.showSyncError(\"Failed to start download\")\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n }\n }\n\n /**\n * Execute the actual file download.\n * Used for old asg_client firmware that doesn't send api_version=2 / captures.\n * NOTE: The sidecar/bracket filtering within is likely dead code — old firmware\n * only produces flat photos/videos with no sidecars or HDR brackets.\n */\n private async executeDownload(files: PhotoInfo[], serverTime: number): Promise<void> {\n const downloadStartTime = Date.now()\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ⬇️ DOWNLOAD EXECUTION STARTED\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 📊 Files to download: ${files.length}`)\n\n const store = useGallerySyncStore.getState()\n const settingsStore = useSettingsStore.getState()\n const defaultWearable = settingsStore.getSetting(SETTINGS.default_wearable.key)\n\n let downloadedCount = 0\n let failedCount = 0\n\n // Check if auto-save to camera roll is enabled (we'll save each file immediately after download)\n const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll()\n const shouldProcessImages = useSettingsStore.getState().getSetting(SETTINGS.media_post_processing.key)\n console.log(`[GallerySyncService] 📸 Auto-save to camera roll: ${shouldAutoSave}`)\n console.log(`[GallerySyncService] 🎨 Image processing: ${shouldProcessImages}`)\n\n try {\n const downloadResult = await asgCameraApi.batchSyncFiles(\n files,\n true,\n (current, total, fileName, fileProgress, downloadedFile) => {\n // CRITICAL: This callback MUST NOT throw!\n // RNFS progress callbacks run inside native bridge — throwing here causes\n // EXC_BAD_ACCESS. Cancellation is handled via AbortSignal → the active transport.\n\n // Check if cancelled — just return, abort signal will stop the download\n if (this.abortController?.signal.aborted) {\n return\n }\n\n // Update store\n const currentStore = useGallerySyncStore.getState()\n\n if (fileProgress === 0 || fileProgress === undefined) {\n // Starting a new file - but only mark previous complete if this is a NEW file\n // (not just another 0% progress report for the same file)\n // This prevents double-counting when both batchSyncFiles and RNFS report 0%\n const isNewFile = currentStore.currentFile !== fileName\n\n if (isNewFile) {\n // Mark previous file as complete when moving to next\n if (current > 1 && currentStore.currentFile) {\n currentStore.onFileComplete(currentStore.currentFile)\n // Persist queue index so we can resume from here if app is killed\n localStorageService.updateSyncQueueIndex(current - 1).catch((err) => {\n console.error(\"[GallerySyncService] Failed to persist queue index:\", err)\n })\n }\n // Now set the new current file\n currentStore.setCurrentFile(fileName, 0)\n }\n } else {\n currentStore.onFileProgress(fileName, fileProgress || 0)\n }\n\n // When file completes (100%), update it in the queue with downloaded paths\n if (fileProgress === 100 && downloadedFile) {\n // Update file with local paths and URLs for immediate preview display\n const localFileUrl = downloadedFile.filePath\n ? downloadedFile.filePath.startsWith(\"file://\")\n ? downloadedFile.filePath\n : `file://${downloadedFile.filePath}`\n : downloadedFile.url\n\n const localThumbnailUrl = downloadedFile.thumbnailPath\n ? downloadedFile.thumbnailPath.startsWith(\"file://\")\n ? downloadedFile.thumbnailPath\n : `file://${downloadedFile.thumbnailPath}`\n : undefined\n\n const updatedFile = {\n ...downloadedFile,\n url: localFileUrl, // Update URL to local file for immediate preview\n download: localFileUrl, // Update download URL for videos\n filePath: downloadedFile.filePath,\n thumbnailPath: localThumbnailUrl,\n }\n currentStore.updateFileInQueue(fileName, updatedFile)\n\n // 🎯 IMMEDIATELY process + save to camera roll if enabled\n if (downloadedFile.filePath) {\n // Parse the capture timestamp from the photo metadata\n let captureTime: number | undefined\n if (downloadedFile.modified) {\n captureTime =\n typeof downloadedFile.modified === \"string\"\n ? parseInt(downloadedFile.modified, 10)\n : downloadedFile.modified\n if (isNaN(captureTime)) {\n console.warn(\n `[GallerySyncService] Invalid modified timestamp for ${downloadedFile.name}:`,\n downloadedFile.modified,\n )\n captureTime = undefined\n }\n }\n\n // Enqueue for background processing (non-blocking)\n const isVideo = downloadedFile.name?.match(/\\.(mp4|mov)$/i)\n const leaf = downloadedFile.name?.includes(\"/\")\n ? downloadedFile.name.substring(downloadedFile.name.lastIndexOf(\"/\") + 1)\n : downloadedFile.name\n const isImuSidecar = leaf?.match(/^imu\\.json$/i)\n const isHdrBracket = leaf?.match(/^ev-?\\d+\\.jpe?g$/i)\n\n if (!isImuSidecar && !isHdrBracket && downloadedFile.filePath) {\n const imuSidecarPath = downloadedFile.filePath.replace(/\\.[^.]+$/, \".imu.json\")\n mediaProcessingQueue.enqueue({\n id: downloadedFile.name,\n type: isVideo ? \"video\" : \"photo\",\n primaryPath: downloadedFile.filePath,\n sidecarPath: isVideo ? imuSidecarPath : undefined,\n timestamp: captureTime,\n totalSize: downloadedFile.size,\n duration: downloadedFile.duration,\n glassesModel: defaultWearable,\n shouldProcess: !!shouldProcessImages,\n shouldAutoSave: !!shouldAutoSave,\n thumbnailPath: downloadedFile.thumbnailPath,\n deleteFromGlasses: [downloadedFile.name],\n protocolVersion: 1,\n })\n }\n }\n }\n\n // Update notification\n gallerySyncNotifications.updateProgress(current, total, fileName, fileProgress || 0)\n },\n this.abortController?.signal,\n )\n\n downloadedCount = downloadResult.downloaded.length\n failedCount = downloadResult.failed.length\n\n const downloadDuration = Date.now() - downloadStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ DOWNLOAD EXECUTION COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📊 Results:\")\n console.log(`[GallerySyncService] - Downloaded: ${downloadedCount}`)\n console.log(`[GallerySyncService] - Failed: ${failedCount}`)\n console.log(`[GallerySyncService] - Duration: ${(downloadDuration / 1000).toFixed(1)}s`)\n console.log(`[GallerySyncService] - Total size: ${(downloadResult.total_size / 1024 / 1024).toFixed(2)} MB`)\n if (downloadDuration > 0 && downloadResult.total_size > 0) {\n const _speedMbps = downloadResult.total_size / 1024 / 1024 / (downloadDuration / 1000)\n console.log(`[GallerySyncService] - Avg speed: ${_speedMbps.toFixed(2)} MB/s`)\n }\n\n // Mark the last file as complete (if any files were downloaded)\n if (downloadResult.downloaded.length > 0) {\n const lastFileName = downloadResult.downloaded[downloadResult.downloaded.length - 1]?.name\n if (lastFileName) {\n const currentStore = useGallerySyncStore.getState()\n currentStore.onFileComplete(lastFileName)\n }\n }\n\n // Update queue index to final position\n await localStorageService.updateSyncQueueIndex(files.length)\n\n // Mark failed files in store\n for (const failedFileName of downloadResult.failed) {\n const currentStore = useGallerySyncStore.getState()\n currentStore.onFileFailed(failedFileName)\n }\n\n // Wait for processing queue to finish before marking complete\n console.log(\"[GallerySyncService] ⏳ Waiting for processing queue to drain...\")\n await mediaProcessingQueue.waitUntilDrained()\n console.log(\"[GallerySyncService] ✅ Processing queue drained\")\n\n // Download success is not destination success. Export, validation, metadata, and\n // acknowledgement failures are reported asynchronously by the processing queue; fold them\n // back into the legacy result so its timestamp watermark cannot skip the source forever.\n const processingFailures = new Set(useGallerySyncStore.getState().failedFiles)\n for (const file of files) {\n if (processingFailures.has(file.name) && !downloadResult.failed.includes(file.name)) {\n downloadResult.failed.push(file.name)\n }\n }\n failedCount = downloadResult.failed.length\n\n // Update sync state — only advance watermark if files were downloaded.\n // If any failed, set it before the oldest failure so they get retried.\n let syncWatermark = serverTime\n if (downloadedCount === 0) {\n const currentSyncState = await localStorageService.getSyncState()\n syncWatermark = currentSyncState.last_sync_time\n console.log(\"[GallerySyncService] ℹ️ No files downloaded — last_sync_time unchanged\")\n } else if (downloadResult.failed.length > 0) {\n const failedSet = new Set(downloadResult.failed)\n let oldestFailed = Infinity\n for (const f of files) {\n if (failedSet.has(f.name)) {\n const ts = typeof f.modified === \"number\" ? f.modified : parseInt(String(f.modified), 10)\n if (!isNaN(ts) && ts < oldestFailed) oldestFailed = ts\n }\n }\n if (oldestFailed < Infinity) {\n syncWatermark = Math.max(0, oldestFailed - 1)\n console.log(\n `[GallerySyncService] ⚠️ ${downloadResult.failed.length} files failed — sync watermark set to ${syncWatermark} instead of ${serverTime}`,\n )\n }\n } else {\n let maxModified = 0\n const failedSet = new Set(downloadResult.failed)\n for (const f of files) {\n if (failedSet.has(f.name)) continue\n const ts = typeof f.modified === \"number\" ? f.modified : parseInt(String(f.modified), 10)\n if (!isNaN(ts)) maxModified = Math.max(maxModified, ts)\n }\n if (maxModified > 0) {\n syncWatermark = maxModified\n }\n }\n console.log(\"[GallerySyncService] 💾 Updating sync state in local storage...\")\n const currentSyncState = await localStorageService.getSyncState()\n // Persist if we downloaded anything OR if a failure needs the watermark rolled back.\n // (Otherwise a clock-skew-triggered full sync where every legacy file fails would\n // leave the stale future watermark on disk and never retry those files.)\n if (downloadedCount > 0 || downloadResult.failed.length > 0) {\n await localStorageService.updateSyncState({\n last_sync_time: syncWatermark,\n total_downloaded: currentSyncState.total_downloaded + downloadedCount,\n total_size: currentSyncState.total_size + downloadResult.total_size,\n })\n }\n console.log(\"[GallerySyncService] ✅ Sync state updated:\")\n console.log(\n `[GallerySyncService] - New last_sync_time: ${syncWatermark} (${new Date(syncWatermark).toISOString()})`,\n )\n console.log(\n `[GallerySyncService] - Total downloads (lifetime): ${\n currentSyncState.total_downloaded + downloadedCount\n }`,\n )\n console.log(\n `[GallerySyncService] - Total data (lifetime): ${(\n (currentSyncState.total_size + downloadResult.total_size) /\n 1024 /\n 1024\n ).toFixed(2)} MB`,\n )\n\n if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {\n store.setSyncError(`${failedCount || \"Some\"} gallery items need retry`)\n } else {\n store.setSyncComplete()\n }\n await this.onSyncComplete(downloadedCount, failedCount)\n } catch (error: any) {\n mediaProcessingQueue.abort()\n if (error?.message === \"Sync cancelled\") {\n console.log(\"[GallerySyncService] Sync was cancelled\")\n store.setSyncCancelled()\n await gallerySyncNotifications.showSyncCancelled()\n } else {\n console.error(\"[GallerySyncService] Download failed:\", error)\n store.setSyncError(error?.message || \"Download failed\")\n await gallerySyncNotifications.showSyncError(error?.message || \"Download failed\")\n }\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n }\n }\n\n /**\n * Execute capture-aware download (api_version=2).\n * Downloads captures as groups, runs HDR merge, saves single metadata entry per capture.\n */\n private async executeCaptureDownload(captures: CaptureGroup[], serverTime: number): Promise<void> {\n const downloadStartTime = Date.now()\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ⬇️ CAPTURE DOWNLOAD EXECUTION STARTED\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 📊 Captures to download: ${captures.length}`)\n\n const store = useGallerySyncStore.getState()\n const settingsStore = useSettingsStore.getState()\n const defaultWearable = settingsStore.getSetting(SETTINGS.default_wearable.key)\n\n let downloadedCount = 0\n let failedCount = 0\n let totalSizeDownloaded = 0\n let oldestFailedTimestamp = Infinity // Track for sync watermark\n let maxSuccessfulTimestamp = 0\n\n const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll()\n const shouldProcessImages = useSettingsStore.getState().getSetting(SETTINGS.media_post_processing.key)\n\n try {\n for (let i = 0; i < captures.length; i++) {\n const capture = captures[i]\n\n // Check cancellation\n if (this.abortController?.signal.aborted) {\n throw new Error(\"Sync cancelled\")\n }\n\n // Update store progress\n const currentStore = useGallerySyncStore.getState()\n if (i > 0) {\n // Mark previous capture as complete\n currentStore.onFileComplete(captures[i - 1].capture_id)\n await localStorageService.updateSyncQueueIndex(i)\n }\n currentStore.setCurrentFile(capture.capture_id, 0)\n\n try {\n console.log(\n `[GallerySyncService] 📦 Downloading capture ${i + 1}/${captures.length}: ${capture.capture_id} (${\n capture.files.length\n } files)`,\n )\n\n validateCaptureMetadataForDownload(capture)\n\n // Download all files in this capture\n const result = await asgCameraApi.downloadCapture(\n capture,\n (bytesDownloaded, totalBytes) => {\n // Don't throw in progress callbacks — abort signal stops the download\n if (this.abortController?.signal.aborted) return\n const progress = totalBytes > 0 ? Math.round((bytesDownloaded / totalBytes) * 100) : 0\n const cs = useGallerySyncStore.getState()\n cs.onFileProgress(capture.capture_id, Math.min(progress, 99))\n gallerySyncNotifications.updateProgress(i + 1, captures.length, capture.capture_id, progress)\n },\n this.abortController?.signal,\n )\n\n // Mark 100% progress\n const cs2 = useGallerySyncStore.getState()\n cs2.onFileProgress(capture.capture_id, 100)\n\n totalSizeDownloaded += capture.total_size\n downloadedCount++\n if (capture.timestamp > maxSuccessfulTimestamp) {\n maxSuccessfulTimestamp = capture.timestamp\n }\n\n // Enqueue for processing (runs concurrently with next download)\n // Delete from glasses happens after processing completes to avoid data loss on crash\n mediaProcessingQueue.enqueue({\n id: capture.capture_id,\n type: capture.type,\n primaryPath: result.primaryPath,\n bracketPaths: result.bracketPaths,\n sidecarPath: result.sidecarPath,\n thumbnailData: capture.thumbnail_data,\n captureDir: result.captureDir,\n timestamp: capture.timestamp,\n totalSize: capture.total_size,\n duration: capture.duration,\n glassesModel: defaultWearable,\n shouldProcess: !!shouldProcessImages,\n shouldAutoSave: !!shouldAutoSave,\n deleteFromGlasses: [capture.capture_id],\n protocolVersion: capture.files.some((file) => !!file.etag) ? 3 : 2,\n })\n } catch (captureError: any) {\n if (captureError?.message === \"Sync cancelled\") throw captureError\n const errMsg = captureError?.message || captureError?.toString?.() || JSON.stringify(captureError)\n console.error(`[GallerySyncService] ❌ Failed to download capture ${capture.capture_id}: ${errMsg}`)\n failedCount++\n // Track oldest failed timestamp so we don't advance sync past it\n if (capture.timestamp < oldestFailedTimestamp) {\n oldestFailedTimestamp = capture.timestamp\n }\n const cs = useGallerySyncStore.getState()\n cs.onFileFailed(capture.capture_id)\n }\n }\n\n // Mark last capture as complete\n if (captures.length > 0) {\n const lastCapture = captures[captures.length - 1]\n const cs = useGallerySyncStore.getState()\n cs.onFileComplete(lastCapture.capture_id)\n }\n\n await localStorageService.updateSyncQueueIndex(captures.length)\n\n const downloadDuration = Date.now() - downloadStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ CAPTURE DOWNLOAD EXECUTION COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 📊 Downloaded: ${downloadedCount}, Failed: ${failedCount}`)\n console.log(`[GallerySyncService] ⏱️ Duration: ${(downloadDuration / 1000).toFixed(1)}s`)\n\n // Wait for processing queue to finish before marking complete\n console.log(\"[GallerySyncService] ⏳ Waiting for processing queue to drain...\")\n await mediaProcessingQueue.waitUntilDrained()\n console.log(\"[GallerySyncService] ✅ Processing queue drained\")\n\n // Reconcile failures from the processing queue. validateDownloadedMediaFile\n // (post-download validation in mediaProcessingQueue) runs AFTER enqueue\n // returns, so a failure there doesn't reach the per-capture catch above. The\n // gallerySync store collects those failures via onFileFailed — pull them in\n // here so the watermark holds them back for retry on the next sync.\n const captureTimestampById = new Map<string, number>()\n for (const c of captures) {\n if (typeof c.timestamp === \"number\") {\n captureTimestampById.set(c.capture_id, c.timestamp)\n }\n }\n const failedSnapshot = useGallerySyncStore.getState().failedFiles\n const observedFailures = new Set<string>(failedSnapshot)\n for (const failedId of observedFailures) {\n const ts = captureTimestampById.get(failedId)\n if (ts === undefined) continue // failure from a different scope (e.g. file-level), skip\n if (ts < oldestFailedTimestamp) {\n oldestFailedTimestamp = ts\n }\n }\n // failedCount should reflect the total set of failed captures from THIS batch.\n const failedFromThisBatch = captures.filter((c) => observedFailures.has(c.capture_id)).length\n if (failedFromThisBatch > failedCount) {\n failedCount = failedFromThisBatch\n }\n\n // Update sync state — only advance watermark when captures were downloaded.\n let syncWatermark = serverTime\n const currentSyncState = await localStorageService.getSyncState()\n if (failedCount > 0 && oldestFailedTimestamp < Infinity) {\n // Failures take priority — roll the watermark back before the oldest failure so it\n // gets retried, regardless of whether anything else succeeded in this batch.\n syncWatermark = Math.max(0, oldestFailedTimestamp - 1)\n console.log(\n `[GallerySyncService] ⚠️ ${failedCount} captures failed — sync watermark set to ${syncWatermark} instead of ${serverTime} so they will be retried`,\n )\n } else if (downloadedCount === 0) {\n syncWatermark = currentSyncState.last_sync_time\n console.log(\"[GallerySyncService] ℹ️ No captures downloaded — last_sync_time unchanged\")\n } else if (maxSuccessfulTimestamp > 0) {\n syncWatermark = maxSuccessfulTimestamp\n }\n // Persist if we downloaded anything OR if a failure needs the watermark rolled back\n // (zero-byte / validation failures otherwise leave a stale watermark on disk).\n if (downloadedCount > 0 || (failedCount > 0 && oldestFailedTimestamp < Infinity)) {\n await localStorageService.updateSyncState({\n last_sync_time: syncWatermark,\n total_downloaded: currentSyncState.total_downloaded + downloadedCount,\n total_size: currentSyncState.total_size + totalSizeDownloaded,\n })\n }\n\n if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {\n store.setSyncError(`${failedCount || \"Some\"} gallery items need retry`)\n } else {\n store.setSyncComplete()\n }\n await this.onSyncComplete(downloadedCount, failedCount)\n } catch (error: any) {\n mediaProcessingQueue.abort()\n if (error?.message === \"Sync cancelled\") {\n console.log(\"[GallerySyncService] Sync was cancelled\")\n store.setSyncCancelled()\n await gallerySyncNotifications.showSyncCancelled()\n } else {\n console.error(\"[GallerySyncService] Capture download failed:\", error)\n store.setSyncError(error?.message || \"Download failed\")\n await gallerySyncNotifications.showSyncError(error?.message || \"Download failed\")\n }\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n }\n }\n\n /**\n * Handle sync completion\n */\n private async onSyncComplete(downloadedCount: number, failedCount: number): Promise<void> {\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 🎉 Step 6/6: Sync completion\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📊 Final results:\")\n console.log(`[GallerySyncService] - Downloaded: ${downloadedCount}`)\n console.log(`[GallerySyncService] - Failed: ${failedCount}`)\n console.log(\n `[GallerySyncService] - Success rate: ${\n downloadedCount > 0 ? ((downloadedCount / (downloadedCount + failedCount)) * 100).toFixed(1) : 0\n }%`,\n )\n\n // 🔍 DIAGNOSTIC: Show all pictures currently in storage after sync\n // try {\n // const allStoredFiles = await localStorageService.getDownloadedFiles()\n // const fileNames = Object.keys(allStoredFiles)\n // console.log(`[GallerySyncService] 📸 POST-SYNC INVENTORY: ${fileNames.length} total files in storage`)\n // console.log(`[GallerySyncService] 📋 Complete file list:`)\n // fileNames\n // .sort((a, b) => {\n // const fileA = allStoredFiles[a]\n // const fileB = allStoredFiles[b]\n // return fileB.downloaded_at - fileA.downloaded_at // Most recent first\n // })\n // .slice(0, 20)\n // .forEach((fileName, idx) => {\n // const file = allStoredFiles[fileName]\n // const captureDate = new Date(file.modified).toISOString()\n // const downloadDate = new Date(file.downloaded_at).toISOString()\n // console.log(\n // `[GallerySyncService] ${idx + 1}. ${fileName} - captured: ${captureDate}, downloaded: ${downloadDate}`,\n // )\n // })\n // if (fileNames.length > 20) {\n // console.log(`[GallerySyncService] ... and ${fileNames.length - 20} more files`)\n // }\n // } catch (error) {\n // console.error(`[GallerySyncService] Failed to get post-sync inventory:`, error)\n // }\n\n const hasPendingRecovery = galleryTransferLedger.hasPendingRecovery()\n if (!hasPendingRecovery && failedCount === 0) {\n console.log(\"[GallerySyncService] 🧹 Clearing completed sync queue...\")\n await localStorageService.clearSyncQueue()\n } else {\n console.log(\"[GallerySyncService] ♻️ Keeping recovery state for unfinished export/ack work\")\n }\n\n if (hasPendingRecovery || failedCount > 0) {\n console.log(\"[GallerySyncService] 📱 Showing retry-required notification...\")\n await gallerySyncNotifications.showSyncError(\n failedCount > 0\n ? `${failedCount} gallery item${failedCount === 1 ? \"\" : \"s\"} will be retried`\n : \"Gallery export or acknowledgement will be retried\",\n )\n } else {\n console.log(\"[GallerySyncService] 📱 Showing completion notification...\")\n await gallerySyncNotifications.showSyncComplete(downloadedCount, 0)\n }\n\n // Close hotspot if we opened it\n const store = useGallerySyncStore.getState()\n if (store.syncServiceOpenedHotspot) {\n console.log(\"[GallerySyncService] 📡 Closing hotspot (service opened it)...\")\n await this.closeHotspot()\n } else {\n console.log(\"[GallerySyncService] ℹ️ Hotspot was not opened by service - leaving it enabled\")\n }\n\n // Clear glasses gallery count immediately after successful sync\n // This ensures UI shows 0 items remaining right away\n // The subsequent query will update this if new photos were taken during sync\n if (!hasPendingRecovery && failedCount === 0) {\n console.log(\"[GallerySyncService] 🔄 Clearing glasses gallery count (synced all items)\")\n store.clearGlassesGalleryStatus()\n }\n\n // Auto-reset to idle after 4 seconds to clear \"Sync complete!\" message,\n // then query glasses for any new content taken during the sync.\n // The query MUST happen after the reset — otherwise setGlassesGalleryStatus\n // sees syncState=\"complete\" + hasContent=true and immediately resets to idle,\n // making it look like sync accomplished nothing (circular sync loop).\n console.log(\"[GallerySyncService] ⏲️ Scheduling auto-reset to idle in 4 seconds...\")\n BgTimer.setTimeout(async () => {\n const currentStore = useGallerySyncStore.getState()\n if (currentStore.syncState === \"complete\") {\n console.log(\"[GallerySyncService] 🔄 Auto-resetting sync state to idle\")\n currentStore.setSyncState(\"idle\")\n }\n // Now query glasses — any content reported will show the sync button\n // naturally without preempting the \"Sync complete!\" message\n console.log(\"[GallerySyncService] 🔍 Querying glasses for post-sync gallery status...\")\n await this.queryGlassesGalleryStatus()\n }, 4000)\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ SYNC FULLY COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n }\n\n /**\n * Cancel the current sync\n */\n async cancelSync(): Promise<void> {\n console.log(\"[GallerySyncService] Cancelling sync...\")\n\n // Abort any ongoing downloads\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n\n // Clear timeout\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n\n const store = useGallerySyncStore.getState()\n\n // Close hotspot if we opened it\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n\n // Update store\n store.setSyncCancelled()\n\n // Clear queue\n await localStorageService.clearSyncQueue()\n\n // Dismiss notification\n await gallerySyncNotifications.showSyncCancelled()\n }\n\n /**\n * Close the hotspot\n */\n private async closeHotspot(): Promise<void> {\n const store = useGallerySyncStore.getState()\n\n try {\n console.log(\"[GallerySyncService] Closing hotspot...\")\n await localNetworkTransport.disconnect()\n await BluetoothSdk.setHotspotState(false)\n store.setSyncServiceOpenedHotspot(false)\n store.setHotspotInfo(null)\n console.log(\"[GallerySyncService] Hotspot closed\")\n } catch (error) {\n console.error(\"[GallerySyncService] Failed to close hotspot:\", error)\n }\n }\n\n /**\n * Check for resumable sync on app start\n */\n async checkForResumableSync(): Promise<boolean> {\n const hasResumable = await localStorageService.hasResumableSyncQueue()\n\n if (hasResumable) {\n console.log(\"[GallerySyncService] Found resumable sync queue\")\n // Don't auto-resume - let user decide\n // Could emit an event here for UI to show \"Resume sync?\" prompt\n }\n\n return hasResumable\n }\n\n /**\n * Resume a previously interrupted sync\n */\n async resumeSync(): Promise<void> {\n const queue = await localStorageService.getSyncQueue()\n\n if (!queue || queue.currentIndex >= queue.files.length) {\n console.log(\"[GallerySyncService] No queue to resume\")\n await localStorageService.clearSyncQueue()\n return\n }\n\n // Check if queue is too old - hotspot auto-disables after 40s of inactivity,\n // so stale queues can't be resumed (hotspot credentials are no longer valid)\n const queueAge = Date.now() - queue.startedAt\n if (queueAge > TIMING.MAX_QUEUE_AGE_MS) {\n console.log(`[GallerySyncService] Queue too old (${Math.round(queueAge / 1000)}s) - clearing stale queue`)\n await localStorageService.clearSyncQueue()\n // Don't auto-start - let user tap sync button if they want to continue\n return\n }\n\n // R5: Resume by going through full startSync() flow to re-request hotspot\n // (stale hotspot credentials are unreliable). The saved queue will be used\n // to skip already-downloaded files when startFileDownload detects them.\n console.log(`[GallerySyncService] Resuming sync from file ${queue.currentIndex + 1}/${queue.files.length}`)\n console.log(\"[GallerySyncService] Re-requesting hotspot via full startSync flow\")\n await this.startSync()\n }\n\n /**\n * Query glasses for gallery status\n */\n async queryGlassesGalleryStatus(): Promise<void> {\n try {\n await BluetoothSdk.queryGalleryStatus()\n } catch (error) {\n console.error(\"[GallerySyncService] Failed to query gallery status:\", error)\n }\n }\n\n /** True while pre-flight startSync work is in flight (before sync state transitions). */\n isSyncStarting(): boolean {\n return this.syncStartPromise !== null\n }\n\n /**\n * Check if sync is currently in progress (hotspot/WiFi/download phases).\n * Does not include pre-flight — use isSyncStarting() for that.\n */\n isSyncing(): boolean {\n const store = useGallerySyncStore.getState()\n return (\n store.syncState === \"syncing\" || store.syncState === \"connecting_wifi\" || store.syncState === \"requesting_hotspot\"\n )\n }\n}\n\nexport const gallerySyncService = GallerySyncService.getInstance()\n"]}
1
+ {"version":3,"file":"gallerySyncService.js","sourceRoot":"","sources":["../../../src/services/asg/gallerySyncService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Gallery Sync Service\n * Orchestrates gallery sync independently of UI lifecycle\n */\n\nimport * as RNFS from \"@dr.pogodin/react-native-fs\"\nimport NetInfo from \"@react-native-community/netinfo\"\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport CrustModule from \"@mentra/crust\"\nimport {AppState, AppStateStatus, Platform} from \"react-native\"\nimport BleManager from \"react-native-ble-manager\"\nimport WifiManager from \"react-native-wifi-reborn\"\n\nimport {useGallerySyncStore, HotspotInfo} from \"../../stores/gallerySync\"\nimport {selectGlassesConnected, useGlassesStore} from \"../../stores/glasses\"\nimport {isGlassesConnected} from \"../GlassesReadiness\"\nimport {SETTINGS, useSettingsStore} from \"../../stores/settings\"\nimport {PhotoInfo, CaptureGroup} from \"../../types/asg\"\nimport GlobalEventEmitter from \"../../utils/GlobalEventEmitter\"\nimport {BgTimer} from \"../../utils/timers\"\nimport {fixGlassesClockIfSkewed} from \"../glassesClockSync\"\nimport {detectClockSkew, isSyncManifestEmpty} from \"../gallerySyncClock\"\nimport {MediaLibraryPermissions} from \"../../utils/permissions/MediaLibraryPermissions\"\nimport {permissions, PermissionFeatures} from \"../../facades/permissions\"\n\nimport {asgCameraApi} from \"./asgCameraApi\"\nimport {gallerySettingsService} from \"./gallerySettingsService\"\nimport {gallerySyncNotifications} from \"./gallerySyncNotifications\"\nimport {localNetworkTransport} from \"./localNetworkTransport\"\nimport {localStorageService} from \"./localStorageService\"\nimport {mediaProcessingQueue} from \"./mediaProcessingQueue\"\nimport {validateCaptureMetadataForDownload} from \"./galleryMediaValidation\"\nimport {emitGalleryNotice} from \"./galleryNotices\"\nimport {galleryTransferLedger} from \"./galleryTransferLedger\"\nimport {cameraRollExportCoordinator} from \"./cameraRollExportCoordinator\"\n\n// Timing constants\nconst TIMING = {\n HOTSPOT_CONNECT_DELAY_MS: 3000, // Increased from 1000ms - hotspot needs time to broadcast and become discoverable\n HOTSPOT_REQUEST_TIMEOUT_MS: 30000, // Timeout waiting for hotspot to enable\n WIFI_CONNECTION_TIMEOUT_MS: 30000,\n RETRY_DELAY_MS: 2000,\n MAX_QUEUE_AGE_MS: 2 * 60 * 1000, // 2 min - glasses hotspot auto-disables after 40s inactivity\n // iOS WiFi connection timing - the system shows a dialog that user must accept\n IOS_WIFI_RETRY_DELAY_MS: 3000, // Wait for user to interact with iOS dialog\n IOS_WIFI_MAX_RETRIES: 5, // Retry multiple times to give user time to accept\n // WiFi initialization cooldown - prevents repeated \"enable WiFi\" alerts while WiFi is initializing\n WIFI_COOLDOWN_MS: 3000, // Wait 3 seconds after user visits WiFi settings before showing alert again\n // Cap the native location-services (GPS) check so a hung CrustModule call can't freeze\n // the sync pre-flight (mirrors the host's former PermissionsUtils guard).\n LOCATION_SERVICES_CHECK_TIMEOUT_MS: 5000,\n} as const\n\ntype SyncManifestData = {\n api_version?: number\n client_id: string\n captures?: CaptureGroup[]\n changed_files: PhotoInfo[]\n deleted_files?: string[]\n server_time: number\n total_changed?: number\n total_size?: number\n}\n\nclass GallerySyncService {\n private static instance: GallerySyncService\n private hotspotListenerRegistered = false\n private hotspotConnectionTimeout: number | null = null\n private hotspotRequestTimeout: number | null = null\n private abortController: AbortController | null = null\n private isInitialized = false\n private glassesStoreUnsubscribe: (() => void) | null = null\n private appStateSubscription: ReturnType<typeof AppState.addEventListener> | null = null\n private waitingForWifiRetry = false\n // Guards full-sync recovery so we don't re-download the entire gallery every sync\n // when glasses retain leftover files (e.g. a previous delete-from-glasses failed).\n // Keyed by `${client_id}:${last_sync_time}` — same pair = already tried, skip.\n private lastFullSyncRetryKey: string | null = null\n private wifiSettingsOpenedAt: number | null = null // Timestamp when user was sent to WiFi settings\n private syncStartPromise: Promise<void> | null = null\n private startAborted = false\n\n private constructor() {}\n\n static getInstance(): GallerySyncService {\n if (!GallerySyncService.instance) {\n GallerySyncService.instance = new GallerySyncService()\n }\n return GallerySyncService.instance\n }\n\n /**\n * Initialize the service - register event listeners\n */\n initialize(): void {\n if (this.isInitialized) return\n\n // Listen for hotspot status changes\n GlobalEventEmitter.addListener(\"hotspot_status_change\", this.handleHotspotStatusChange)\n GlobalEventEmitter.addListener(\"hotspot_error\", this.handleHotspotError)\n GlobalEventEmitter.addListener(\"gallery_status\", this.handleGalleryStatus)\n\n // Subscribe to glasses store to detect disconnection during sync\n this.glassesStoreUnsubscribe = useGlassesStore.subscribe(selectGlassesConnected, (connected, prevConnected) => {\n // Only trigger on disconnect (was connected, now not connected)\n if (prevConnected && !connected) {\n this.handleGlassesDisconnected()\n }\n })\n\n // Listen for app state changes to auto-retry sync after user enables WiFi\n this.appStateSubscription = AppState.addEventListener(\"change\", this.handleAppStateChange)\n\n this.hotspotListenerRegistered = true\n this.isInitialized = true\n\n void cameraRollExportCoordinator.initialize()\n\n // console.log(\"[GallerySyncService] Initialized\")\n\n // Check for resumable sync on startup\n this.checkForResumableSync()\n }\n\n /**\n * Cleanup - remove event listeners\n */\n cleanup(): void {\n void localNetworkTransport.disconnect()\n if (this.hotspotListenerRegistered) {\n GlobalEventEmitter.removeListener(\"hotspot_status_change\", this.handleHotspotStatusChange)\n GlobalEventEmitter.removeListener(\"hotspot_error\", this.handleHotspotError)\n GlobalEventEmitter.removeListener(\"gallery_status\", this.handleGalleryStatus)\n this.hotspotListenerRegistered = false\n }\n\n if (this.glassesStoreUnsubscribe) {\n this.glassesStoreUnsubscribe()\n this.glassesStoreUnsubscribe = null\n }\n\n if (this.appStateSubscription) {\n this.appStateSubscription.remove()\n this.appStateSubscription = null\n }\n cameraRollExportCoordinator.cleanup()\n\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n\n this.syncStartPromise = null\n useGallerySyncStore.getState().setSyncStarting(false)\n this.waitingForWifiRetry = false\n this.wifiSettingsOpenedAt = null\n this.startAborted = false\n this.isInitialized = false\n console.log(\"[GallerySyncService] Cleaned up\")\n }\n\n /**\n * Handle glasses disconnection during sync\n */\n private handleGlassesDisconnected = (): void => {\n const store = useGallerySyncStore.getState()\n\n // Pre-flight has no sync state yet — abort quietly; runStartSync checks this flag after awaits\n if (this.syncStartPromise && !this.isSyncing()) {\n console.log(\"[GallerySyncService] Glasses disconnected during pre-flight — aborting start\")\n this.startAborted = true\n return\n }\n\n // Only handle if we're actively syncing\n if (!this.isSyncing()) {\n return\n }\n\n console.log(\"[GallerySyncService] Glasses disconnected during sync - cancelling\")\n store.setSyncError(\"Glasses disconnected\")\n\n // Abort ongoing downloads\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n\n // Clear timeouts\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n void localNetworkTransport.disconnect()\n }\n\n /**\n * Handle app state changes to auto-retry sync when user returns from settings\n */\n private handleAppStateChange = async (nextAppState: AppStateStatus): Promise<void> => {\n // Only handle when app comes to foreground\n if (nextAppState !== \"active\") {\n return\n }\n\n // Camera-roll backfill is phone-local and must resume independently of glasses/WiFi.\n void cameraRollExportCoordinator.resume(\"app foreground\")\n\n // Only auto-retry if we were waiting for WiFi\n if (!this.waitingForWifiRetry) {\n return\n }\n\n console.log(\"[GallerySyncService] App returned to foreground - checking if WiFi is enabled\")\n\n const store = useGallerySyncStore.getState()\n const glassesStore = useGlassesStore.getState()\n const glassesConnected = isGlassesConnected(glassesStore.connection)\n\n // Check if glasses are still connected\n if (!glassesConnected) {\n console.log(\"[GallerySyncService] Glasses disconnected - not retrying sync\")\n this.waitingForWifiRetry = false\n this.wifiSettingsOpenedAt = null\n return\n }\n\n // The user has returned from the WiFi settings prompt, so the previous\n // \"Sync failed\" state is no longer actionable. Make the button available\n // immediately while the native WiFi state catches up; a successful check\n // below will start the sync automatically.\n if (store.syncState === \"error\" && store.lastError?.startsWith(\"WiFi disabled\")) {\n store.setSyncState(\"idle\")\n }\n\n // Check if WiFi is now enabled (Android only)\n // Use retry logic because WiFi status takes time to propagate after user enables it\n if (Platform.OS === \"android\") {\n const MAX_RETRIES = 5\n const RETRY_DELAY_MS = 1000\n\n console.log(\"[GallerySyncService] Waiting for WiFi to initialize (may take a moment after enabling)...\")\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n try {\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), RETRY_DELAY_MS))\n\n // NetInfo can remain stale after Android's WiFi settings close. Use\n // the same native source as the normal sync preflight.\n const wifiEnabled = await WifiManager.isEnabled()\n console.log(`[GallerySyncService] WiFi check attempt ${attempt}/${MAX_RETRIES}: enabled=${wifiEnabled}`)\n\n if (wifiEnabled) {\n console.log(\"[GallerySyncService] ✅ WiFi is now enabled - auto-retrying sync\")\n this.waitingForWifiRetry = false\n this.wifiSettingsOpenedAt = null // Clear cooldown timestamp\n // Auto-retry sync\n await this.startSync()\n return\n }\n } catch (error) {\n console.warn(`[GallerySyncService] Failed to check WiFi status on attempt ${attempt}:`, error)\n // Continue to next retry\n }\n }\n\n console.log(\"[GallerySyncService] WiFi not detected after retries - leaving sync available for manual retry\")\n this.waitingForWifiRetry = false\n this.wifiSettingsOpenedAt = null\n }\n }\n\n /**\n * Handle gallery status from glasses\n */\n private handleGalleryStatus = (data: any): void => {\n console.log(\"[GallerySyncService] Received gallery_status:\", data)\n\n const store = useGallerySyncStore.getState()\n store.setGlassesGalleryStatus(data.photos || 0, data.videos || 0, data.total || 0, data.has_content || false)\n }\n\n /**\n * Handle hotspot status change event\n */\n private handleHotspotStatusChange = async (eventData: any): Promise<void> => {\n console.log(\"[GallerySyncService] Hotspot status changed:\", eventData)\n\n const store = useGallerySyncStore.getState()\n\n // Only process if we're in a connecting state\n if (store.syncState !== \"requesting_hotspot\" && store.syncState !== \"connecting_wifi\") {\n console.log(\"[GallerySyncService] Ignoring hotspot event - not in connecting state\")\n return\n }\n\n if (!eventData.enabled || !eventData.ssid || !eventData.password) {\n console.log(\"[GallerySyncService] Hotspot not ready yet\")\n return\n }\n\n // Clear the hotspot request timeout since we got a response\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n\n // Pre-flight: do not start the wait if already disconnected (e.g. BT dropped right after hotspot enabled)\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\"[GallerySyncService] ❌ Glasses disconnected on hotspot_status_change - aborting (no wait)\")\n store.setSyncError(\"Glasses disconnected\")\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n return\n }\n\n const hotspotInfo: HotspotInfo = {\n ssid: eventData.ssid,\n password: eventData.password,\n ip: eventData.local_ip,\n }\n\n store.setHotspotInfo(hotspotInfo)\n\n // Wait for hotspot to become discoverable\n console.log(\n `[GallerySyncService] Hotspot enabled, waiting ${TIMING.HOTSPOT_CONNECT_DELAY_MS}ms for broadcast initialization...`,\n )\n console.log(\"[GallerySyncService] 📡 Glasses need time to start WiFi AP and broadcast SSID\")\n\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n }\n\n this.hotspotConnectionTimeout = BgTimer.setTimeout(() => {\n this.hotspotConnectionTimeout = null\n // Pre-flight: abort if Bluetooth disconnected during the wait\n const stillConnected = isGlassesConnected(useGlassesStore.getState().connection)\n if (!stillConnected) {\n console.log(\"[GallerySyncService] ❌ Glasses disconnected during hotspot wait - skipping WiFi connection\")\n const currentStore = useGallerySyncStore.getState()\n currentStore.setSyncError(\"Glasses disconnected\")\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n return\n }\n console.log(\"[GallerySyncService] ✅ Hotspot broadcast window complete - attempting connection\")\n this.connectToHotspotWifi(hotspotInfo)\n }, TIMING.HOTSPOT_CONNECT_DELAY_MS)\n }\n\n /**\n * Handle hotspot error event\n */\n private handleHotspotError = (eventData: any): void => {\n console.error(\"[GallerySyncService] Hotspot error:\", eventData)\n\n const store = useGallerySyncStore.getState()\n\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n\n store.setSyncError(eventData.error_message || \"Failed to start hotspot\")\n gallerySyncNotifications.showSyncError(\"Failed to start hotspot\")\n }\n\n /**\n * Start the sync process\n */\n async startSync(): Promise<void> {\n if (this.syncStartPromise) {\n console.log(\"[GallerySyncService] ⚠️ Sync start already in progress, joining existing attempt\")\n return this.syncStartPromise\n }\n\n useGallerySyncStore.getState().setSyncStarting(true)\n this.syncStartPromise = this.runStartSync().finally(() => {\n this.syncStartPromise = null\n useGallerySyncStore.getState().setSyncStarting(false)\n })\n return this.syncStartPromise\n }\n\n /**\n * Native location-services (GPS on/off) check, raced against a timeout so a hung\n * CrustModule call can't freeze the sync pre-flight. Mirrors the host's former\n * PermissionsUtils.isLocationServicesEnabled exactly: on timeout assume enabled\n * (proceed); on any other native error assume disabled (block + prompt). Android-only\n * callers; iOS doesn't need location for BLE since iOS 13.\n */\n private async isLocationServicesEnabled(): Promise<boolean> {\n try {\n return await Promise.race([\n CrustModule.isLocationServicesEnabled(),\n new Promise<boolean>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"Location services check timed out\")),\n TIMING.LOCATION_SERVICES_CHECK_TIMEOUT_MS,\n ),\n ),\n ])\n } catch (error) {\n console.error(\"[GallerySyncService] Error checking location services:\", error)\n if (error instanceof Error && error.message.includes(\"timed out\")) {\n console.warn(\"[GallerySyncService] Location services check timed out — assuming enabled so sync can proceed\")\n return true\n }\n return false\n }\n }\n\n /**\n * Mirrors the host's old PermissionsUtils.isBluetoothEnabled exactly: poll\n * BleManager for up to 500ms while the adapter reports \"unknown\"; assume\n * enabled on a timeout (a slow adapter must not block the sync) and disabled\n * on a check error.\n */\n private async isBluetoothAdapterEnabled(): Promise<boolean> {\n try {\n await BleManager.start({showAlert: false})\n for (let attempt = 0; attempt < 10; attempt++) {\n const state = await BleManager.checkState()\n if (state !== \"unknown\") {\n return state === \"on\"\n }\n await new Promise((resolve) => setTimeout(resolve, 50))\n }\n console.warn(\"[GallerySyncService] Bluetooth state still unknown after 500ms - assuming enabled\")\n return true\n } catch (error) {\n console.error(\"[GallerySyncService] Error checking Bluetooth state:\", error)\n return false\n }\n }\n\n private shouldAbortPreFlight(): boolean {\n if (this.startAborted) {\n this.startAborted = false\n return true\n }\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n return true\n }\n return false\n }\n\n private async runStartSync(): Promise<void> {\n // Clear stale abort flag — it can persist when a prior pre-flight exited through\n // a non-shouldAbortPreFlight path (e.g. connectivity failed, disk full), which\n // would otherwise cause the next sync attempt to abort spuriously.\n this.startAborted = false\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 🚀 SYNC START INITIATED\")\n console.log(\"[GallerySyncService] ========================================\")\n\n const store = useGallerySyncStore.getState()\n const glassesStore = useGlassesStore.getState()\n const glassesConnected = isGlassesConnected(glassesStore.connection)\n const glassesHotspot =\n glassesStore.hotspot.state === \"enabled\"\n ? {\n ssid: glassesStore.hotspot.ssid,\n password: glassesStore.hotspot.password,\n ip: glassesStore.hotspot.localIp,\n }\n : null\n\n // R1: Check if already syncing (including requesting_hotspot to prevent double-tap)\n if (\n store.syncState === \"syncing\" ||\n store.syncState === \"connecting_wifi\" ||\n store.syncState === \"requesting_hotspot\"\n ) {\n console.log(`[GallerySyncService] ⚠️ Already syncing (state: ${store.syncState}), ignoring start request`)\n return\n }\n\n // Engine-owned pre-flight: glasses reachable + bluetooth adapter on. The host\n // renders the alerts off the structured notices; Android location permission\n // and services are handled in the permission steps below.\n if (!glassesConnected) {\n console.warn(\"[GallerySyncService] Sync aborted - Glasses not connected\")\n store.setSyncError(\"Glasses not connected\")\n emitGalleryNotice({code: \"glasses_disconnected\"})\n return\n }\n\n if (!(await this.isBluetoothAdapterEnabled())) {\n console.warn(\"[GallerySyncService] Sync aborted - Bluetooth is disabled\")\n store.setSyncError(\"Bluetooth disabled - enable Bluetooth and try again\")\n emitGalleryNotice({code: \"bluetooth_off\"})\n return\n }\n\n console.log(\"[GallerySyncService] ✅ Pre-flight check passed - BT enabled, Glasses connected\")\n console.log(\"[GallerySyncService] 📊 Glasses info:\", {\n connected: glassesConnected,\n hotspotEnabled: glassesHotspot !== null,\n })\n\n // Request all permissions upfront so user isn't interrupted during WiFi/download\n console.log(\"[GallerySyncService] 🔐 Step 1/6: Requesting permissions...\")\n\n // 1. Notification permission (for background sync progress)\n console.log(\"[GallerySyncService] 📱 Requesting notification permission...\")\n await gallerySyncNotifications.requestPermissions()\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after notification permission\")\n return\n }\n console.log(\"[GallerySyncService] ✅ Notification permission handled\")\n\n // 2. Location permission (required to read WiFi SSID for hotspot verification)\n console.log(\"[GallerySyncService] 📍 Checking location permission...\")\n const hasLocationPermission = await permissions.check(PermissionFeatures.LOCATION)\n if (!hasLocationPermission) {\n console.log(\"[GallerySyncService] ⚠️ Location permission not granted - requesting...\")\n const granted = await permissions.request(PermissionFeatures.LOCATION)\n if (!granted) {\n console.warn(\"[GallerySyncService] ❌ Location permission denied - WiFi SSID verification may fail\")\n // Don't block sync - we'll try anyway and fall back to IP-based verification if needed\n } else {\n console.log(\"[GallerySyncService] ✅ Location permission granted\")\n }\n } else {\n console.log(\"[GallerySyncService] ✅ Location permission already granted\")\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after location permission\")\n return\n }\n\n if (Platform.OS === \"android\") {\n console.log(\"[GallerySyncService] 📡 Checking local WiFi permission...\")\n const hasLocalWifiPermission = await permissions.check(PermissionFeatures.LOCAL_WIFI)\n if (!hasLocalWifiPermission) {\n const granted = await permissions.request(PermissionFeatures.LOCAL_WIFI)\n if (!granted) {\n store.setSyncError(\"Local WiFi permission is required for gallery sync\")\n await gallerySyncNotifications.showSyncError(\"Allow WiFi access to connect to your glasses\")\n return\n }\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after local WiFi permission\")\n return\n }\n }\n\n // 3. Camera roll permission (if auto-save is enabled)\n const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll()\n console.log(`[GallerySyncService] 📸 Auto-save to camera roll: ${shouldAutoSave}`)\n if (shouldAutoSave) {\n console.log(\"[GallerySyncService] 📸 Checking camera roll permission...\")\n const hasPermission = await MediaLibraryPermissions.checkPermission()\n if (!hasPermission) {\n console.log(\"[GallerySyncService] ⚠️ Camera roll permission not granted - requesting...\")\n const granted = await MediaLibraryPermissions.requestPermission()\n if (!granted) {\n console.warn(\"[GallerySyncService] ❌ Camera roll permission denied - auto-save sync cannot continue\")\n store.setSyncError(\"Camera-roll permission required while automatic saving is enabled\")\n emitGalleryNotice({code: \"camera_roll_permission_required\"})\n return\n } else {\n console.log(\"[GallerySyncService] ✅ Camera roll permission granted\")\n }\n } else {\n console.log(\"[GallerySyncService] ✅ Camera roll permission already granted\")\n }\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after camera roll permission\")\n return\n }\n\n // S1: Disk space check — abort early if insufficient space\n try {\n const fsInfo = await RNFS.getFSInfo()\n const freeSpaceMB = fsInfo.freeSpace / (1024 * 1024)\n console.log(`[GallerySyncService] 💾 Free disk space: ${freeSpaceMB.toFixed(0)} MB`)\n if (fsInfo.freeSpace < 500 * 1024 * 1024) {\n console.error(\"[GallerySyncService] ❌ Insufficient disk space (<500MB)\")\n emitGalleryNotice({code: \"insufficient_storage\", data: {freeSpaceMB: Math.round(freeSpaceMB)}})\n store.setSyncError(\"Insufficient storage space\")\n return\n }\n } catch (fsError) {\n console.warn(\"[GallerySyncService] ⚠️ Could not check disk space:\", fsError)\n // Continue — don't block sync if check fails\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after disk space check\")\n return\n }\n\n // Reset abort controller\n this.abortController = new AbortController()\n\n // COOLDOWN CHECK: If user just went to WiFi settings, show a \"please wait\" message\n // This prevents showing \"enable WiFi\" alert repeatedly while WiFi is initializing\n if (Platform.OS === \"android\" && this.wifiSettingsOpenedAt) {\n const timeSinceSettingsOpened = Date.now() - this.wifiSettingsOpenedAt\n const cooldownRemaining = TIMING.WIFI_COOLDOWN_MS - timeSinceSettingsOpened\n\n if (cooldownRemaining > 0) {\n console.log(\n `[GallerySyncService] WiFi cooldown active (${Math.round(\n cooldownRemaining / 1000,\n )}s remaining) - showing wait message`,\n )\n\n emitGalleryNotice({code: \"wifi_initializing\"})\n return\n } else {\n // Cooldown expired, clear the timestamp\n console.log(\"[GallerySyncService] WiFi cooldown expired - resuming normal behavior\")\n this.wifiSettingsOpenedAt = null\n }\n }\n\n // Pre-flight WiFi check on Android BEFORE any connection attempts\n // This prevents sync failures even when we think we're already connected\n // NOTE: We use WifiManager.isEnabled() instead of NetInfo.isWifiEnabled because\n // NetInfo can return stale/cached data that reports WiFi as enabled when it's actually OFF\n console.log(\"[GallerySyncService] 📡 Step 2/6: WiFi pre-flight check...\")\n if (Platform.OS === \"android\") {\n try {\n // Use WifiManager.isEnabled() for accurate WiFi state (NetInfo can be stale)\n const wifiEnabled = await WifiManager.isEnabled()\n console.log(\"[GallerySyncService] 📡 WiFi enabled (WifiManager):\", wifiEnabled)\n\n // Also log NetInfo for debugging comparison\n const netState = await NetInfo.fetch()\n console.log(\"[GallerySyncService] 📡 WiFi enabled (NetInfo):\", netState.isWifiEnabled)\n console.log(\"[GallerySyncService] 📡 Connected:\", netState.isConnected)\n console.log(\"[GallerySyncService] 📡 Internet reachable:\", netState.isInternetReachable)\n\n if (!wifiEnabled) {\n console.error(\"[GallerySyncService] ❌ WiFi is disabled - cannot sync\")\n\n // Don't arm the auto-retry / \"WiFi initializing\" cooldown yet — whether to arm\n // them depends on the user's choice in the host's prompt, which only the host\n // learns. The host renders an \"enable WiFi → open settings\" alert from this\n // notice and calls ack() ONLY when the user opts to open settings; on Cancel it\n // does nothing, so a declined prompt leaves no pending retry or phantom cooldown.\n // The engine still owns what arming MEANS (this closure) — the host only reports\n // that the user took the affirmative action.\n emitGalleryNotice({\n code: \"wifi_off\",\n ack: () => {\n this.waitingForWifiRetry = true\n this.wifiSettingsOpenedAt = Date.now()\n },\n })\n store.setSyncError(\"WiFi disabled - enable WiFi and try again\")\n\n // Return early - do NOT proceed with sync\n return\n } else {\n // WiFi is enabled - clear any cooldown timestamp\n console.log(\"[GallerySyncService] ✅ WiFi is enabled - proceeding\")\n this.wifiSettingsOpenedAt = null\n }\n } catch (error) {\n console.warn(\"[GallerySyncService] ⚠️ Failed to check WiFi status:\", error)\n // Continue with sync attempt - don't block if check fails\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after WiFi check\")\n return\n }\n } else {\n console.log(\"[GallerySyncService] ℹ️ iOS - WiFi check not required\")\n }\n\n // Check if Location Services is enabled (Android only - required for WiFi operations)\n // This must be checked BEFORE attempting any WiFi connection to avoid cryptic errors\n if (Platform.OS === \"android\") {\n console.log(\"[GallerySyncService] 📍 Checking Location Services status...\")\n try {\n const locationServicesEnabled = await this.isLocationServicesEnabled()\n console.log(\"[GallerySyncService] 📍 Location Services enabled:\", locationServicesEnabled)\n\n if (!locationServicesEnabled) {\n console.error(\"[GallerySyncService] ❌ Location Services is OFF - cannot sync\")\n console.error(\"[GallerySyncService] ❌ Android requires Location Services for WiFi operations\")\n\n // Emit a notice; the host shows the \"enable Location Services\" alert + dialog.\n emitGalleryNotice({code: \"location_services_off\"})\n store.setSyncError(\"Location Services disabled - enable in Settings and try again\")\n\n // Return early - do NOT proceed with sync\n return\n } else {\n console.log(\"[GallerySyncService] ✅ Location Services is enabled - proceeding\")\n }\n } catch (error) {\n console.warn(\"[GallerySyncService] ⚠️ Failed to check Location Services status:\", error)\n // Continue with sync attempt - don't block if check fails\n }\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after location services check\")\n return\n }\n }\n\n // Check if already connected to hotspot\n // IMPORTANT: We must verify the phone's WiFi is actually connected to the hotspot SSID,\n // not just that the glasses reported hotspot is enabled (which persists across app restarts)\n console.log(\"[GallerySyncService] 🔌 Step 3/6: Checking hotspot connection status...\")\n\n // Re-read current glasses state from the store — the snapshot from the top of the function\n // may be stale if glasses disconnected during one of the above awaits.\n const currentGlassesConnected = isGlassesConnected(useGlassesStore.getState().connection)\n if (!currentGlassesConnected) {\n console.log(\"[GallerySyncService] Pre-flight aborted — glasses no longer connected at hotspot check\")\n return\n }\n const currentGlassesStore = useGlassesStore.getState()\n const currentGlassesHotspot =\n currentGlassesStore.hotspot.state === \"enabled\"\n ? {\n ssid: currentGlassesStore.hotspot.ssid,\n password: currentGlassesStore.hotspot.password,\n ip: currentGlassesStore.hotspot.localIp,\n }\n : null\n\n let isAlreadyConnected = false\n if (currentGlassesHotspot) {\n console.log(\"[GallerySyncService] 📊 Glasses hotspot status:\")\n console.log(\"[GallerySyncService] - Enabled: true\")\n console.log(`[GallerySyncService] - SSID: ${currentGlassesHotspot.ssid}`)\n console.log(`[GallerySyncService] - IP: ${currentGlassesHotspot.ip}`)\n\n try {\n const currentSSID = await WifiManager.getCurrentWifiSSID()\n if (this.shouldAbortPreFlight()) {\n console.log(\"[GallerySyncService] Pre-flight aborted after SSID check\")\n return\n }\n console.log(`[GallerySyncService] 📱 Phone current WiFi SSID: \"${currentSSID}\"`)\n console.log(`[GallerySyncService] 🔍 Comparing with glasses hotspot SSID: \"${currentGlassesHotspot.ssid}\"`)\n\n isAlreadyConnected = currentSSID === currentGlassesHotspot.ssid\n if (isAlreadyConnected) {\n console.log(\"[GallerySyncService] ✅ Phone is already connected to glasses hotspot!\")\n } else if (currentSSID) {\n console.log(`[GallerySyncService] ⚠️ Phone is on different network (${currentSSID})`)\n console.log(\"[GallerySyncService] ➡️ Will request hotspot connection\")\n } else {\n console.log(\"[GallerySyncService] ⚠️ Phone not connected to any WiFi network\")\n }\n } catch (error) {\n console.warn(\"[GallerySyncService] ⚠️ Could not verify current WiFi SSID:\", error)\n // If we can't verify, don't assume we're connected - request hotspot\n isAlreadyConnected = false\n }\n } else {\n console.log(\"[GallerySyncService] ℹ️ Glasses hotspot not currently enabled\")\n console.log(\"[GallerySyncService] ➡️ Will request hotspot activation\")\n }\n\n // Every fallible pre-flight gate has passed. It is now safe to replace the previous\n // in-memory queue; startFileDownload immediately recovers its durable ledger work.\n mediaProcessingQueue.reset()\n\n if (isAlreadyConnected && currentGlassesHotspot) {\n const hotspotInfo: HotspotInfo = currentGlassesHotspot\n store.setHotspotInfo(hotspotInfo)\n store.setSyncState(\"connecting_wifi\")\n if (localNetworkTransport.supportsScopedConnection() && !localNetworkTransport.isScopedConnectionActive()) {\n console.log(\"[GallerySyncService] 📡 System SSID matches; establishing scoped glasses transport\")\n await this.connectToHotspotWifi(hotspotInfo)\n } else {\n console.log(\"[GallerySyncService] 🚀 Skipping hotspot request - already connected!\")\n await this.startFileDownload(hotspotInfo)\n }\n return\n }\n\n // Request hotspot\n console.log(\"[GallerySyncService] 📡 Step 4/6: Requesting hotspot from glasses...\")\n store.setRequestingHotspot()\n store.setSyncServiceOpenedHotspot(true)\n\n // Set timeout for hotspot request - if we don't get a response, fail gracefully\n this.hotspotRequestTimeout = BgTimer.setTimeout(() => {\n const currentStore = useGallerySyncStore.getState()\n if (currentStore.syncState === \"requesting_hotspot\") {\n console.error(\"[GallerySyncService] Hotspot request timed out\")\n currentStore.setSyncError(\"Hotspot request timed out\")\n currentStore.setSyncServiceOpenedHotspot(false)\n gallerySyncNotifications.showSyncError(\"Could not start hotspot - please try again\")\n }\n this.hotspotRequestTimeout = null\n }, TIMING.HOTSPOT_REQUEST_TIMEOUT_MS)\n\n try {\n console.log(\"[GallerySyncService] 📤 Sending hotspot enable command to glasses...\")\n await BluetoothSdk.setHotspotState(true)\n console.log(\"[GallerySyncService] ✅ Hotspot enabled by glasses\")\n } catch (error) {\n // Clear the timeout since we got an immediate error\n if (this.hotspotRequestTimeout) {\n BgTimer.clearTimeout(this.hotspotRequestTimeout!)\n this.hotspotRequestTimeout = null\n }\n console.error(\"[GallerySyncService] ❌ Failed to request hotspot:\", error)\n store.setSyncError(\"Failed to start hotspot\")\n store.setSyncServiceOpenedHotspot(false)\n }\n }\n\n /**\n * Show explanation dialog before WiFi connection (first time only)\n * Returns true if user wants to proceed, false if cancelled\n */\n private async showWifiJoinExplanation(ssid: string): Promise<boolean> {\n const settingsStore = useSettingsStore.getState()\n const hasSeenExplanation = settingsStore.getSetting(SETTINGS.gallery_sync_explained.key)\n\n if (hasSeenExplanation) {\n console.log(\"[GallerySyncService] User has seen WiFi explanation before - skipping\")\n return true\n }\n\n console.log(\"[GallerySyncService] First sync - showing WiFi join explanation\")\n\n return new Promise<boolean>((resolve) => {\n const proceed = () => {\n // Mark as explained so we don't show again.\n settingsStore.setSetting(SETTINGS.gallery_sync_explained.key, true, false)\n resolve(true)\n }\n // Emit the one-time wifi-join explanation as a notice the host renders + acknowledges.\n // The host owns the alert + its dismiss timing (Android's native WiFi connect freezes\n // the UI thread, so it should let the dialog fully dismiss before calling ack).\n const delivered = emitGalleryNotice({\n code: \"connect_to_glasses\",\n data: {ssid, platform: Platform.OS},\n ack: proceed,\n })\n // No host listening (e.g. an OEM that hasn't wired onNotice) — don't hang the sync.\n if (delivered === 0) proceed()\n })\n }\n\n /**\n * Connect to hotspot WiFi with retry logic (unified for both platforms)\n * Both iOS and Android benefit from retries:\n * - iOS: Library throws \"internal error\" before user responds to system dialog\n * - Android: Hotspot needs time to initialize, especially when glasses WiFi was cold\n */\n private async connectToHotspotWifi(hotspotInfo: HotspotInfo): Promise<void> {\n const store = useGallerySyncStore.getState()\n\n // Pre-flight: do not attempt WiFi connection if Bluetooth already disconnected\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\"[GallerySyncService] ❌ Glasses not connected - aborting WiFi connection\")\n store.setSyncError(\"Glasses disconnected\")\n gallerySyncNotifications.showSyncError(\"Glasses disconnected\")\n return\n }\n\n // Show explanation dialog on first sync (user must acknowledge before proceeding)\n await this.showWifiJoinExplanation(hotspotInfo.ssid)\n\n let lastError: any = null\n const wifiConnectStartTime = Date.now()\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📡 WIFI CONNECTION PHASE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 🎯 Target SSID: ${hotspotInfo.ssid}`)\n console.log(`[GallerySyncService] 🔑 Password length: ${hotspotInfo.password.length} chars`)\n console.log(`[GallerySyncService] 🌐 Gateway IP: ${hotspotInfo.ip}`)\n console.log(`[GallerySyncService] 📱 Platform: ${Platform.OS}`)\n console.log(`[GallerySyncService] 🔄 Max retry attempts: ${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.log(`[GallerySyncService] ⏱️ Retry delay: ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms`)\n\n store.setSyncState(\"connecting_wifi\")\n\n // Setup app state monitoring to detect backgrounding\n let appBackgrounded = false\n let appBackgroundTime: number | null = null\n const appStateHandler = (nextAppState: AppStateStatus) => {\n if (nextAppState === \"background\") {\n appBackgrounded = true\n appBackgroundTime = Date.now()\n console.warn(\"[GallerySyncService] ⚠️ 🚨 APP BACKGROUNDED during WiFi connection!\")\n console.warn(\"[GallerySyncService] ⚠️ This may indicate Android system dialog appeared\")\n console.warn(\n \"[GallerySyncService] ⚠️ Time since WiFi connect started:\",\n Date.now() - wifiConnectStartTime,\n \"ms\",\n )\n } else if (nextAppState === \"active\" && appBackgrounded) {\n console.log(\"[GallerySyncService] ✅ App returned to foreground\")\n console.log(\"[GallerySyncService] ⏱️ Time spent in background:\", Date.now() - (appBackgroundTime || 0), \"ms\")\n }\n }\n\n const appStateSubscription = AppState.addEventListener(\"change\", appStateHandler)\n console.log(\"[GallerySyncService] 👂 App state listener registered\")\n\n // L2: Wrap retry loop in try/finally to guarantee listener cleanup on all exit paths\n try {\n for (let attempt = 1; attempt <= TIMING.IOS_WIFI_MAX_RETRIES; attempt++) {\n const attemptStartTime = Date.now()\n\n // Check if cancelled\n if (this.abortController?.signal.aborted) {\n console.log(\"[GallerySyncService] 🛑 Sync was cancelled - aborting WiFi connection\")\n store.setSyncError(\"Sync cancelled\")\n return\n }\n\n try {\n console.log(\"[GallerySyncService] ----------------------------------------\")\n console.log(\n `[GallerySyncService] 📡 ATTEMPT ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES} - Starting WiFi connection`,\n )\n console.log(`[GallerySyncService] ⏱️ Time since WiFi phase started: ${Date.now() - wifiConnectStartTime}ms`)\n console.log(`[GallerySyncService] 📱 App backgrounded during connection: ${appBackgrounded}`)\n\n // Check current WiFi state before attempting connection\n let preConnectSSID = \"unknown\"\n try {\n preConnectSSID = await WifiManager.getCurrentWifiSSID()\n console.log(`[GallerySyncService] 📡 Current WiFi SSID: \"${preConnectSSID}\"`)\n\n // Check if already connected (shouldn't happen, but good to verify)\n if (!localNetworkTransport.supportsScopedConnection() && preConnectSSID === hotspotInfo.ssid) {\n console.log(\"[GallerySyncService] ✅ Already connected to target SSID! Proceeding to download.\")\n appStateSubscription.remove()\n\n const totalWifiDuration = Date.now() - wifiConnectStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ WIFI CONNECTION COMPLETE (already connected)\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] ⏱️ Total WiFi phase duration: ${totalWifiDuration}ms`)\n console.log(`[GallerySyncService] 🚀 Proceeding to file download from ${hotspotInfo.ip}:8089`)\n\n await this.startFileDownload(hotspotInfo)\n return // Exit function successfully\n }\n } catch (preError: any) {\n console.warn(`[GallerySyncService] ⚠️ Could not get current SSID: ${preError?.message}`)\n console.warn(\"[GallerySyncService] ⚠️ Error code:\", preError?.code)\n }\n\n console.log(`[GallerySyncService] 🔌 Connecting the glasses-local transport...`)\n console.log(`[GallerySyncService] 🔌 Parameters:`)\n console.log(`[GallerySyncService] - SSID: \"${hotspotInfo.ssid}\"`)\n console.log(`[GallerySyncService] - Password: ${\"*\".repeat(hotspotInfo.password.length)}`)\n console.log(`[GallerySyncService] - joinOnce: false`)\n console.log(`[GallerySyncService] - isHidden: false`)\n\n const connectCallStartTime = Date.now()\n appBackgrounded = false // Reset flag for this attempt\n appBackgroundTime = null\n\n await localNetworkTransport.connect(hotspotInfo.ssid, hotspotInfo.password)\n\n const connectCallDuration = Date.now() - connectCallStartTime\n console.log(`[GallerySyncService] ✅ Glasses-local transport connected successfully`)\n console.log(`[GallerySyncService] ⏱️ Library call duration: ${connectCallDuration}ms`)\n console.log(`[GallerySyncService] 📱 App was backgrounded during call: ${appBackgrounded}`)\n if (appBackgrounded && appBackgroundTime) {\n console.log(\n `[GallerySyncService] ⏱️ Time until backgrounding: ${appBackgroundTime - connectCallStartTime}ms`,\n )\n }\n console.log(`[GallerySyncService] 📝 Note: On iOS, this does NOT guarantee actual connection!`)\n\n // iOS-specific: Verify actual WiFi connection by polling SSID\n // The library promise resolves when iOS ACCEPTS the request, not when connection completes\n if (Platform.OS === \"ios\") {\n console.log(`[GallerySyncService] 🍎 iOS: Starting connection verification...`)\n console.log(`[GallerySyncService] 🍎 Will poll getCurrentWifiSSID() for up to 15 seconds`)\n\n const maxVerifyAttempts = 30 // 30 × 500ms = 15 seconds\n let connected = false\n let lastSeenSSID = \"unknown\"\n\n for (let i = 0; i < maxVerifyAttempts; i++) {\n try {\n const currentSSID = await WifiManager.getCurrentWifiSSID()\n lastSeenSSID = currentSSID || \"null\"\n\n console.log(\n `[GallerySyncService] 🍎 Verify poll ${\n i + 1\n }/${maxVerifyAttempts}: Current=\"${currentSSID}\", Target=\"${hotspotInfo.ssid}\"`,\n )\n\n if (currentSSID === hotspotInfo.ssid) {\n console.log(\n `[GallerySyncService] 🍎 ✅ VERIFICATION SUCCESS! Connected to target network after ${\n (i + 1) * 500\n }ms`,\n )\n connected = true\n break\n } else if (i === 0 && currentSSID === lastSeenSSID) {\n console.log(\n `[GallerySyncService] 🍎 ⚠️ Still on original network - iOS dialog may not have appeared yet`,\n )\n }\n } catch (ssidError: any) {\n console.log(`[GallerySyncService] 🍎 ⚠️ Poll ${i + 1}: Could not check SSID: ${ssidError?.message}`)\n lastSeenSSID = \"error\"\n }\n\n // Don't wait after last attempt\n if (i < maxVerifyAttempts - 1) {\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), 500))\n }\n }\n\n if (!connected) {\n console.error(`[GallerySyncService] 🍎 ❌ VERIFICATION FAILED after 15 seconds`)\n console.error(`[GallerySyncService] 🍎 Last seen SSID: \"${lastSeenSSID}\"`)\n console.error(`[GallerySyncService] 🍎 Expected SSID: \"${hotspotInfo.ssid}\"`)\n console.error(`[GallerySyncService] 🍎 Possible causes:`)\n console.error(`[GallerySyncService] 🍎 1. User did not tap \"Join\" on iOS WiFi dialog`)\n console.error(`[GallerySyncService] 🍎 2. iOS dialog did not appear (permission issue?)`)\n console.error(`[GallerySyncService] 🍎 3. iOS refused to switch networks`)\n throw new Error(\n `iOS WiFi verification failed - still on \"${lastSeenSSID}\", expected \"${hotspotInfo.ssid}\"`,\n )\n }\n }\n\n const attemptDuration = Date.now() - attemptStartTime\n console.log(`[GallerySyncService] ✅ WiFi connection successful!`)\n console.log(`[GallerySyncService] ⏱️ Total attempt duration: ${attemptDuration}ms`)\n console.log(`[GallerySyncService] 🎉 Platform: ${Platform.OS}`)\n\n // Remove app state listener\n appStateSubscription.remove()\n console.log(\"[GallerySyncService] 👂 App state listener removed\")\n\n // Final verification: Check SSID one more time before starting download\n try {\n const finalSSID = localNetworkTransport.isScopedConnectionActive()\n ? hotspotInfo.ssid\n : await WifiManager.getCurrentWifiSSID()\n console.log(`[GallerySyncService] 📶 Final SSID check before download: \"${finalSSID}\"`)\n if (Platform.OS === \"android\") {\n // Some local builds can have stale generated typings for the Bluetooth SDK module.\n ;(BluetoothSdk as any).logCurrentWifiFrequency?.()\n }\n if (finalSSID !== hotspotInfo.ssid) {\n console.error(\n `[GallerySyncService] ❌ SSID mismatch detected! Expected \"${hotspotInfo.ssid}\", got \"${finalSSID}\"`,\n )\n throw new Error(`WiFi SSID mismatch - connected to \"${finalSSID}\" instead of \"${hotspotInfo.ssid}\"`)\n }\n } catch (finalError: any) {\n console.warn(`[GallerySyncService] ⚠️ Could not perform final SSID check: ${finalError?.message}`)\n // Continue anyway - we've done our best to verify\n }\n\n // iOS-specific: Wait for actual network connectivity to glasses\n // Even though SSID is correct, iOS needs time for routing tables to update\n // We actively probe the glasses HTTP server until it's reachable\n if (Platform.OS === \"ios\") {\n console.log(`[GallerySyncService] 🍎 Waiting for iOS network routes to glasses IP...`)\n console.log(`[GallerySyncService] 🍎 Will probe http://${hotspotInfo.ip}:8089/api/health`)\n\n const maxProbeAttempts = 20 // 20 attempts × 500ms = 10 seconds max\n let networkReady = false\n\n for (let probeNum = 1; probeNum <= maxProbeAttempts; probeNum++) {\n try {\n console.log(`[GallerySyncService] 🍎 Connectivity probe ${probeNum}/${maxProbeAttempts}...`)\n\n // Try to reach the glasses health endpoint with a short timeout\n const probeController = new AbortController()\n const probeTimeout = BgTimer.setTimeout(() => probeController.abort(), 1000) // 1 second timeout per probe\n\n const probeStartTime = Date.now()\n const probeResponse = await localNetworkTransport.fetch(`http://${hotspotInfo.ip}:8089/api/health`, {\n method: \"GET\",\n signal: probeController.signal,\n })\n BgTimer.clearTimeout(probeTimeout)\n\n const probeDuration = Date.now() - probeStartTime\n console.log(\n `[GallerySyncService] 🍎 Probe ${probeNum} response: HTTP ${probeResponse.status} (${probeDuration}ms)`,\n )\n\n if (probeResponse.status === 200 || probeResponse.status === 404) {\n // 200 = health endpoint exists, 404 = glasses responded (no health endpoint)\n // Either way, network is working!\n console.log(`[GallerySyncService] 🍎 ✅ Network connectivity verified after ${probeNum} probes!`)\n networkReady = true\n break\n }\n } catch (probeError: any) {\n const errorMsg = probeError?.message || \"unknown\"\n console.log(\n `[GallerySyncService] 🍎 Probe ${probeNum} failed: ${errorMsg.substring(0, 50)}${\n errorMsg.length > 50 ? \"...\" : \"\"\n }`,\n )\n // Continue to next probe\n }\n\n // Wait 500ms before next probe (unless this was the last attempt)\n if (probeNum < maxProbeAttempts) {\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), 500))\n }\n }\n\n if (!networkReady) {\n console.error(\n `[GallerySyncService] 🍎 ❌ Network connectivity probe failed after ${maxProbeAttempts} attempts`,\n )\n console.error(`[GallerySyncService] 🍎 iOS routing tables may not be ready for ${hotspotInfo.ip}`)\n throw new Error(\n `iOS network not ready - could not reach ${hotspotInfo.ip}:8089 after ${maxProbeAttempts} attempts`,\n )\n }\n }\n\n // Start the actual download\n const totalWifiDuration = Date.now() - wifiConnectStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ WIFI CONNECTION COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] ⏱️ Total WiFi phase duration: ${totalWifiDuration}ms`)\n console.log(`[GallerySyncService] 🎯 Attempts used: ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.log(`[GallerySyncService] 🚀 Proceeding to file download from ${hotspotInfo.ip}:8089`)\n\n await this.startFileDownload(hotspotInfo)\n return // Success - exit the retry loop\n } catch (error: any) {\n lastError = error\n const attemptDuration = Date.now() - attemptStartTime\n\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(`[GallerySyncService] ❌ WiFi ATTEMPT ${attempt} FAILED`)\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(`[GallerySyncService] ❌ Error message: ${error?.message || \"No message\"}`)\n console.error(`[GallerySyncService] ❌ Error code: ${error?.code || \"No code\"}`)\n console.error(`[GallerySyncService] ❌ Error type: ${error?.name || typeof error}`)\n console.error(`[GallerySyncService] ❌ Platform: ${Platform.OS}`)\n console.error(`[GallerySyncService] ❌ Attempt duration: ${attemptDuration}ms`)\n console.error(`[GallerySyncService] ❌ App was backgrounded: ${appBackgrounded}`)\n if (appBackgrounded && appBackgroundTime) {\n console.error(`[GallerySyncService] ❌ Time in background: ${Date.now() - appBackgroundTime}ms`)\n }\n console.error(`[GallerySyncService] ❌ Full error object:`, JSON.stringify(error, null, 2))\n\n // If user explicitly denied, don't retry\n if (error?.code === \"userDenied\" || error?.message?.includes(\"cancel\")) {\n console.warn(\"[GallerySyncService] 🚫 User cancelled WiFi connection - aborting\")\n appStateSubscription.remove()\n store.setSyncError(\"WiFi connection cancelled\")\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n return\n }\n\n // Handle \"didNotFindNetwork\" - hotspot may still be initializing\n if (error?.code === \"didNotFindNetwork\") {\n console.warn(\"[GallerySyncService] 🔍 Network not found - hotspot may still be initializing\")\n console.warn(\n `[GallerySyncService] 🔍 Will retry in ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms (attempt ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES})`,\n )\n }\n\n // Handle \"timeoutOccurred\" - likely caused by app backgrounding during WiFi dialog\n if (error?.code === \"timeoutOccurred\") {\n console.error(\"[GallerySyncService] ⏰ WiFi connection timeout occurred\")\n console.error(`[GallerySyncService] ⏰ App was backgrounded: ${appBackgrounded}`)\n if (appBackgrounded && appBackgroundTime) {\n console.error(`[GallerySyncService] ⏰ Time in background: ${Date.now() - appBackgroundTime}ms`)\n console.error(\"[GallerySyncService] ⏰ Android may have shown WiFi dialog that user didn't interact with\")\n }\n console.warn(\n `[GallerySyncService] 🔍 Will retry in ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms (attempt ${attempt}/${TIMING.IOS_WIFI_MAX_RETRIES})`,\n )\n }\n\n // DISABLED: Check if WiFi was disabled during connection attempt (Android 10+ specific error)\n // if (Platform.OS === \"android\" && error?.message?.includes(\"enable wifi manually\")) {\n // console.error(\"[GallerySyncService] WiFi was disabled during connection\")\n //\n // // Mark that we're waiting for WiFi so we can auto-retry when user returns\n // this.waitingForWifiRetry = true\n //\n // showAlert(\"WiFi Required\", \"WiFi must be enabled to sync photos. Please enable WiFi and try again.\", [\n // {\n // text: \"Cancel\",\n // style: \"cancel\",\n // onPress: () => {\n // this.waitingForWifiRetry = false\n // this.wifiSettingsOpenedAt = null\n // store.setSyncError(\"WiFi disabled - enable WiFi and try again\")\n // if (store.syncServiceOpenedHotspot) {\n // this.closeHotspot()\n // }\n // },\n // },\n // {\n // text: \"Open Settings\",\n // onPress: async () => {\n // // Set timestamp so we can enforce cooldown on next sync attempt\n // this.wifiSettingsOpenedAt = Date.now()\n // await SettingsNavigationUtils.openWifiSettings()\n // store.setSyncError(\"Enable WiFi and try sync again\")\n // if (store.syncServiceOpenedHotspot) {\n // await this.closeHotspot()\n // }\n // },\n // },\n // ])\n // return\n // }\n\n // Let connection fail naturally and show generic error\n if (Platform.OS === \"android\" && error?.message?.includes(\"enable wifi manually\")) {\n console.error(\"[GallerySyncService] 🚫 WiFi was disabled during connection - aborting\")\n appStateSubscription.remove()\n store.setSyncError(\"Could not connect - check WiFi is enabled\")\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n return\n }\n\n // For \"internal error\" or \"unableToConnect\", wait and retry\n // iOS: Gives user time to interact with system dialog\n // Android: Gives hotspot time to fully initialize and start broadcasting\n if (attempt < TIMING.IOS_WIFI_MAX_RETRIES) {\n const reason =\n Platform.OS === \"ios\" ? \"user may be seeing system dialog\" : \"hotspot may still be initializing\"\n console.log(\"[GallerySyncService] ----------------------------------------\")\n console.log(`[GallerySyncService] 🔄 Preparing retry ${attempt + 1}/${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.log(`[GallerySyncService] ⏱️ Waiting ${TIMING.IOS_WIFI_RETRY_DELAY_MS}ms (${reason})`)\n console.log(`[GallerySyncService] 📱 App currently: ${AppState.currentState}`)\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), TIMING.IOS_WIFI_RETRY_DELAY_MS))\n console.log(`[GallerySyncService] ⏱️ Wait complete - starting retry`)\n } else {\n console.error(\"[GallerySyncService] 🚫 No more retry attempts available\")\n }\n }\n }\n\n // All retries exhausted\n const totalWifiDuration = Date.now() - wifiConnectStartTime\n\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(\"[GallerySyncService] ❌ WIFI CONNECTION FAILED - ALL RETRIES EXHAUSTED\")\n console.error(\"[GallerySyncService] ❌ ========================================\")\n console.error(`[GallerySyncService] ❌ Platform: ${Platform.OS}`)\n console.error(`[GallerySyncService] ❌ Total attempts: ${TIMING.IOS_WIFI_MAX_RETRIES}`)\n console.error(`[GallerySyncService] ❌ Total duration: ${totalWifiDuration}ms`)\n console.error(`[GallerySyncService] ❌ App was backgrounded at some point: ${appBackgrounded}`)\n console.error(`[GallerySyncService] ❌ Last error message: ${lastError?.message || \"No message\"}`)\n console.error(`[GallerySyncService] ❌ Last error code: ${lastError?.code || \"No code\"}`)\n console.error(\"[GallerySyncService] ❌ ========================================\")\n\n // Provide user-friendly error message based on error type\n let userErrorMessage = lastError?.message || \"Failed to connect to glasses WiFi\"\n\n if (lastError?.code === \"timeoutOccurred\" && appBackgrounded) {\n userErrorMessage =\n \"WiFi connection timed out. Android may be blocking automatic WiFi switching. Please manually connect to the glasses hotspot in Settings.\"\n } else if (lastError?.message?.includes(\"internal error\")) {\n userErrorMessage =\n \"Could not connect to glasses WiFi. Please ensure you accept the WiFi prompt when it appears.\"\n }\n\n store.setSyncError(userErrorMessage)\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n } finally {\n // Release the scoped Android Network on every terminal path. This is idempotent with\n // closeHotspot(), and intentionally leaves Android 9/iOS legacy routing unchanged.\n await localNetworkTransport.disconnect()\n // L2: Guarantee listener cleanup on all exit paths (cancel, success, error, exhaustion)\n appStateSubscription.remove()\n }\n }\n\n private async fetchSyncManifest(clientId: string, lastSyncTime: number): Promise<SyncManifestData> {\n const v3 = typeof asgCameraApi.getV3Manifest === \"function\" ? await asgCameraApi.getV3Manifest() : null\n if (v3) {\n const downloadedFiles = await localStorageService.getDownloadedFiles()\n await localStorageService.reconcileRemoteCaptures(\n v3.captures.map((capture) => capture.capture_id),\n downloadedFiles,\n )\n return {\n api_version: 3,\n client_id: clientId,\n // The ledger is a crash-recovery journal, not proof that app-private media survived an\n // Android restore or reinstall. Suppress a remote capture only when both records agree.\n captures: v3.captures.filter(\n (capture) =>\n !downloadedFiles[capture.capture_id] || !galleryTransferLedger.isLocallyCommitted(capture.capture_id),\n ),\n changed_files: [],\n deleted_files: [],\n server_time: v3.server_time,\n total_changed: v3.captures.length,\n total_size: v3.captures.reduce((total, capture) => total + capture.total_size, 0),\n }\n }\n // Old firmware remains on the exact v2 endpoint/schema. Avoid expensive inline thumbnails;\n // video thumbnails are fetched as small side downloads with their primary media.\n const syncResponse = await asgCameraApi.syncWithServer(clientId, lastSyncTime, false)\n const data = (syncResponse.data || syncResponse) as SyncManifestData\n if (data.captures) {\n data.captures = data.captures.filter((capture) => !galleryTransferLedger.isLocallyCommitted(capture.capture_id))\n }\n data.changed_files = (data.changed_files || []).filter(\n (file) => !galleryTransferLedger.isFileLocallyCommitted(file.name),\n )\n return data\n }\n\n /**\n * Resolve sync manifest: detect skew, optionally fix clock, retry full sync when needed.\n */\n private async resolveSyncManifest(\n clientId: string,\n lastSyncTime: number,\n ): Promise<{syncData: SyncManifestData; usedFullSync: boolean} | null> {\n const store = useGallerySyncStore.getState()\n let syncData = await this.fetchSyncManifest(clientId, lastSyncTime)\n let clockFixed = false\n\n const skewOnFirst = detectClockSkew(Date.now(), syncData.server_time, lastSyncTime)\n if (skewOnFirst.skewed) {\n clockFixed = await fixGlassesClockIfSkewed(syncData.server_time, lastSyncTime)\n if (clockFixed) {\n console.log(\"[GallerySyncService] 🔄 Retrying /api/sync with last_sync_time=0 after clock fix\")\n syncData = await this.fetchSyncManifest(clientId, 0)\n }\n }\n\n if (!isSyncManifestEmpty(syncData)) {\n return {syncData, usedFullSync: clockFixed || lastSyncTime === 0}\n }\n\n // Guard against re-firing the full-sync retry every sync when glasses retain leftover files\n // from a failed delete-from-glasses: at most one retry per (client_id, last_sync_time) pair\n // per process lifetime. Without this, we'd re-download the entire gallery on every sync.\n const retryKey = `${clientId}:${lastSyncTime}`\n const alreadyRetriedForThisWatermark = this.lastFullSyncRetryKey === retryKey\n if (!clockFixed && store.glassesHasContent && lastSyncTime !== 0 && !alreadyRetriedForThisWatermark) {\n this.lastFullSyncRetryKey = retryKey\n console.log(\"[GallerySyncService] 🔄 Empty sync but glasses report content — retrying with last_sync_time=0\")\n syncData = await this.fetchSyncManifest(clientId, 0)\n if (!isSyncManifestEmpty(syncData)) {\n return {syncData, usedFullSync: true}\n }\n } else if (!clockFixed && store.glassesHasContent && lastSyncTime !== 0 && alreadyRetriedForThisWatermark) {\n console.warn(\n \"[GallerySyncService] ⚠️ Glasses still report content but /api/sync empty — already retried this watermark, skipping to avoid re-download loop\",\n )\n }\n\n if (store.glassesHasContent) {\n console.warn(\"[GallerySyncService] ⚠️ Empty sync while glasses still report gallery content\")\n return null\n }\n\n return {syncData, usedFullSync: false}\n }\n\n /**\n * Start downloading files\n */\n private async startFileDownload(hotspotInfo: HotspotInfo): Promise<void> {\n const store = useGallerySyncStore.getState()\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📥 Step 5/6: Starting file download phase\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 🌐 Server: ${hotspotInfo.ip}:8089`)\n\n try {\n // Set up the API client\n asgCameraApi.setServer(hotspotInfo.ip, 8089)\n console.log(\"[GallerySyncService] ✅ API client configured\")\n\n const recovery = await mediaProcessingQueue.retryPending()\n if (recovery.retried > 0 || recovery.failed > 0) {\n console.log(\n `[GallerySyncService] ♻️ Recovery: ${recovery.retried} completed, ${recovery.failed} still pending`,\n )\n }\n\n // Get sync state and files to download\n // IMPORTANT: This creates a SNAPSHOT of files at this moment based on last_sync_time.\n // Any photos taken AFTER this call (during the sync) will NOT be included in this sync.\n // They will be detected in the next sync when we query gallery status again.\n console.log(\"[GallerySyncService] 📊 Fetching sync state from local storage...\")\n const syncState = await localStorageService.getSyncState()\n console.log(\"[GallerySyncService] 📊 Sync state:\", {\n client_id: syncState.client_id,\n last_sync_time: syncState.last_sync_time,\n last_sync_date: syncState.last_sync_time > 0 ? new Date(syncState.last_sync_time).toISOString() : \"Never\",\n total_downloaded: syncState.total_downloaded,\n total_size: `${(syncState.total_size / 1024 / 1024).toFixed(2)} MB`,\n })\n\n console.log(\"[GallerySyncService] 📡 Calling /api/sync endpoint...\")\n const syncStartTime = Date.now()\n const resolved = await this.resolveSyncManifest(syncState.client_id, syncState.last_sync_time)\n const _syncDuration = Date.now() - syncStartTime\n console.log(`[GallerySyncService] ✅ /api/sync completed in ${_syncDuration}ms`)\n\n if (!resolved) {\n const syncErrorMessage = \"Could not sync gallery — try again\"\n store.setSyncError(syncErrorMessage)\n await gallerySyncNotifications.showSyncError(syncErrorMessage)\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n return\n }\n\n const {syncData} = resolved\n\n console.log(\"[GallerySyncService] 📋 Sync response received:\")\n console.log(`[GallerySyncService] - Server time: ${syncData.server_time}`)\n console.log(`[GallerySyncService] - Changed files: ${syncData.changed_files?.length || 0}`)\n console.log(`[GallerySyncService] - Captures: ${syncData.captures?.length || 0}`)\n\n if (isSyncManifestEmpty(syncData)) {\n console.log(\"[GallerySyncService] ✅ No new files to sync - already up to date!\")\n if (galleryTransferLedger.hasPendingRecovery()) {\n store.setSyncError(\"Gallery export or acknowledgement needs retry\")\n } else {\n store.setSyncComplete()\n }\n await this.onSyncComplete(0, 0)\n return\n }\n\n // Detect API version and route to appropriate download path\n const useCaptures = (syncData.api_version || 0) >= 2 && syncData.captures && syncData.captures.length > 0\n\n if (useCaptures) {\n // New capture-aware sync path\n const captures: CaptureGroup[] = syncData.captures!\n console.log(\n `[GallerySyncService] 📊 Found ${captures.length} captures to download (api_version=${syncData.api_version})`,\n )\n\n captures.slice(0, 5).forEach((c: CaptureGroup, idx: number) => {\n console.log(\n `[GallerySyncService] ${idx + 1}. ${c.capture_id} (${c.type}, ${c.files.length} files, ${(\n c.total_size / 1024\n ).toFixed(1)} KB)`,\n )\n })\n if (captures.length > 5) {\n console.log(`[GallerySyncService] ... and ${captures.length - 5} more captures`)\n }\n\n // Build a PhotoInfo[] for the store (one per capture, using primary file info)\n const capturePhotoInfos: PhotoInfo[] = captures.map((c) => {\n const primaryFile = c.files.find((f) => f.role === \"primary\") || c.files[0]\n return {\n name: c.capture_id,\n url: `/api/photo?file=${encodeURIComponent(primaryFile.name)}`,\n download: `/api/download?file=${encodeURIComponent(primaryFile.name)}`,\n size: c.total_size,\n modified: c.timestamp,\n is_video: c.type === \"video\",\n thumbnail_data: c.thumbnail_data,\n duration: c.duration,\n }\n })\n\n store.setSyncing(capturePhotoInfos)\n\n await localStorageService.saveSyncQueue({\n files: capturePhotoInfos,\n currentIndex: 0,\n startedAt: Date.now(),\n hotspotInfo,\n })\n\n await gallerySyncNotifications.showSyncStarted(captures.length)\n\n console.log(\"[GallerySyncService] 🚀 Beginning capture download execution...\")\n await this.executeCaptureDownload(captures, syncData.server_time)\n } else {\n // Legacy flat file sync path\n const filesToSync = syncData.changed_files\n // Count only user-visible media files (exclude HDR brackets and IMU sidecars)\n const userVisibleCount = filesToSync.filter(\n (f: any) => !f.name?.match(/_ev-?\\d+\\.(jpg|jpeg)$/i) && !f.name?.match(/\\.imu\\.json$/i),\n ).length\n console.log(\n `[GallerySyncService] 📊 Found ${filesToSync.length} files to download (${userVisibleCount} media items, legacy path):`,\n )\n\n console.log(\"[GallerySyncService] 📋 First 5 files:\")\n filesToSync.slice(0, 5).forEach((_file: any, _idx: number) => {\n console.log(\n `[GallerySyncService] ${_idx + 1}. ${_file.name} (${_file.is_video ? \"video\" : \"photo\"}, ${(\n _file.size / 1024\n ).toFixed(1)} KB)`,\n )\n })\n if (filesToSync.length > 5) {\n console.log(`[GallerySyncService] ... and ${filesToSync.length - 5} more files`)\n }\n\n store.setSyncing(filesToSync)\n\n await localStorageService.saveSyncQueue({\n files: filesToSync,\n currentIndex: 0,\n startedAt: Date.now(),\n hotspotInfo,\n })\n\n await gallerySyncNotifications.showSyncStarted(userVisibleCount)\n\n console.log(\"[GallerySyncService] 🚀 Beginning download execution (legacy)...\")\n await this.executeDownload(filesToSync, syncData.server_time)\n }\n } catch (error: any) {\n console.error(\"[GallerySyncService] Failed to start download:\", error)\n store.setSyncError(error?.message || \"Failed to start download\")\n await gallerySyncNotifications.showSyncError(\"Failed to start download\")\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n }\n }\n\n /**\n * Execute the actual file download.\n * Used for old asg_client firmware that doesn't send api_version=2 / captures.\n * NOTE: The sidecar/bracket filtering within is likely dead code — old firmware\n * only produces flat photos/videos with no sidecars or HDR brackets.\n */\n private async executeDownload(files: PhotoInfo[], serverTime: number): Promise<void> {\n const downloadStartTime = Date.now()\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ⬇️ DOWNLOAD EXECUTION STARTED\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 📊 Files to download: ${files.length}`)\n\n const store = useGallerySyncStore.getState()\n const settingsStore = useSettingsStore.getState()\n const defaultWearable = settingsStore.getSetting(SETTINGS.default_wearable.key)\n\n let downloadedCount = 0\n let failedCount = 0\n\n // Check if auto-save to camera roll is enabled (we'll save each file immediately after download)\n const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll()\n const shouldProcessImages = useSettingsStore.getState().getSetting(SETTINGS.media_post_processing.key)\n console.log(`[GallerySyncService] 📸 Auto-save to camera roll: ${shouldAutoSave}`)\n console.log(`[GallerySyncService] 🎨 Image processing: ${shouldProcessImages}`)\n\n try {\n const downloadResult = await asgCameraApi.batchSyncFiles(\n files,\n true,\n (current, total, fileName, fileProgress, downloadedFile) => {\n // CRITICAL: This callback MUST NOT throw!\n // RNFS progress callbacks run inside native bridge — throwing here causes\n // EXC_BAD_ACCESS. Cancellation is handled via AbortSignal → the active transport.\n\n // Check if cancelled — just return, abort signal will stop the download\n if (this.abortController?.signal.aborted) {\n return\n }\n\n // Update store\n const currentStore = useGallerySyncStore.getState()\n\n if (fileProgress === 0 || fileProgress === undefined) {\n // Starting a new file - but only mark previous complete if this is a NEW file\n // (not just another 0% progress report for the same file)\n // This prevents double-counting when both batchSyncFiles and RNFS report 0%\n const isNewFile = currentStore.currentFile !== fileName\n\n if (isNewFile) {\n // Mark previous file as complete when moving to next\n if (current > 1 && currentStore.currentFile) {\n currentStore.onFileComplete(currentStore.currentFile)\n // Persist queue index so we can resume from here if app is killed\n localStorageService.updateSyncQueueIndex(current - 1).catch((err) => {\n console.error(\"[GallerySyncService] Failed to persist queue index:\", err)\n })\n }\n // Now set the new current file\n currentStore.setCurrentFile(fileName, 0)\n }\n } else {\n currentStore.onFileProgress(fileName, fileProgress || 0)\n }\n\n // When file completes (100%), update it in the queue with downloaded paths\n if (fileProgress === 100 && downloadedFile) {\n // Update file with local paths and URLs for immediate preview display\n const localFileUrl = downloadedFile.filePath\n ? downloadedFile.filePath.startsWith(\"file://\")\n ? downloadedFile.filePath\n : `file://${downloadedFile.filePath}`\n : downloadedFile.url\n\n const localThumbnailUrl = downloadedFile.thumbnailPath\n ? downloadedFile.thumbnailPath.startsWith(\"file://\")\n ? downloadedFile.thumbnailPath\n : `file://${downloadedFile.thumbnailPath}`\n : undefined\n\n const updatedFile = {\n ...downloadedFile,\n url: localFileUrl, // Update URL to local file for immediate preview\n download: localFileUrl, // Update download URL for videos\n filePath: downloadedFile.filePath,\n thumbnailPath: localThumbnailUrl,\n }\n currentStore.updateFileInQueue(fileName, updatedFile)\n\n // 🎯 IMMEDIATELY process + save to camera roll if enabled\n if (downloadedFile.filePath) {\n // Parse the capture timestamp from the photo metadata\n let captureTime: number | undefined\n if (downloadedFile.modified) {\n captureTime =\n typeof downloadedFile.modified === \"string\"\n ? parseInt(downloadedFile.modified, 10)\n : downloadedFile.modified\n if (isNaN(captureTime)) {\n console.warn(\n `[GallerySyncService] Invalid modified timestamp for ${downloadedFile.name}:`,\n downloadedFile.modified,\n )\n captureTime = undefined\n }\n }\n\n // Enqueue for background processing (non-blocking)\n const isVideo = downloadedFile.name?.match(/\\.(mp4|mov)$/i)\n const leaf = downloadedFile.name?.includes(\"/\")\n ? downloadedFile.name.substring(downloadedFile.name.lastIndexOf(\"/\") + 1)\n : downloadedFile.name\n const isImuSidecar = leaf?.match(/^imu\\.json$/i)\n const isHdrBracket = leaf?.match(/^ev-?\\d+\\.jpe?g$/i)\n\n if (!isImuSidecar && !isHdrBracket && downloadedFile.filePath) {\n const imuSidecarPath = downloadedFile.filePath.replace(/\\.[^.]+$/, \".imu.json\")\n mediaProcessingQueue.enqueue({\n id: downloadedFile.name,\n type: isVideo ? \"video\" : \"photo\",\n primaryPath: downloadedFile.filePath,\n sidecarPath: isVideo ? imuSidecarPath : undefined,\n timestamp: captureTime,\n totalSize: downloadedFile.size,\n duration: downloadedFile.duration,\n glassesModel: defaultWearable,\n shouldProcess: !!shouldProcessImages,\n shouldAutoSave: !!shouldAutoSave,\n thumbnailPath: downloadedFile.thumbnailPath,\n deleteFromGlasses: [downloadedFile.name],\n protocolVersion: 1,\n })\n }\n }\n }\n\n // Update notification\n gallerySyncNotifications.updateProgress(current, total, fileName, fileProgress || 0)\n },\n this.abortController?.signal,\n )\n\n downloadedCount = downloadResult.downloaded.length\n failedCount = downloadResult.failed.length\n\n const downloadDuration = Date.now() - downloadStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ DOWNLOAD EXECUTION COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📊 Results:\")\n console.log(`[GallerySyncService] - Downloaded: ${downloadedCount}`)\n console.log(`[GallerySyncService] - Failed: ${failedCount}`)\n console.log(`[GallerySyncService] - Duration: ${(downloadDuration / 1000).toFixed(1)}s`)\n console.log(`[GallerySyncService] - Total size: ${(downloadResult.total_size / 1024 / 1024).toFixed(2)} MB`)\n if (downloadDuration > 0 && downloadResult.total_size > 0) {\n const _speedMbps = downloadResult.total_size / 1024 / 1024 / (downloadDuration / 1000)\n console.log(`[GallerySyncService] - Avg speed: ${_speedMbps.toFixed(2)} MB/s`)\n }\n\n // Mark the last file as complete (if any files were downloaded)\n if (downloadResult.downloaded.length > 0) {\n const lastFileName = downloadResult.downloaded[downloadResult.downloaded.length - 1]?.name\n if (lastFileName) {\n const currentStore = useGallerySyncStore.getState()\n currentStore.onFileComplete(lastFileName)\n }\n }\n\n // Update queue index to final position\n await localStorageService.updateSyncQueueIndex(files.length)\n\n // Mark failed files in store\n for (const failedFileName of downloadResult.failed) {\n const currentStore = useGallerySyncStore.getState()\n currentStore.onFileFailed(failedFileName)\n }\n\n // Wait for processing queue to finish before marking complete\n console.log(\"[GallerySyncService] ⏳ Waiting for processing queue to drain...\")\n await mediaProcessingQueue.waitUntilDrained()\n console.log(\"[GallerySyncService] ✅ Processing queue drained\")\n\n // Download success is not destination success. Export, validation, metadata, and\n // acknowledgement failures are reported asynchronously by the processing queue; fold them\n // back into the legacy result so its timestamp watermark cannot skip the source forever.\n const processingFailures = new Set(useGallerySyncStore.getState().failedFiles)\n for (const file of files) {\n if (processingFailures.has(file.name) && !downloadResult.failed.includes(file.name)) {\n downloadResult.failed.push(file.name)\n }\n }\n failedCount = downloadResult.failed.length\n\n // Update sync state — only advance watermark if files were downloaded.\n // If any failed, set it before the oldest failure so they get retried.\n let syncWatermark = serverTime\n if (downloadedCount === 0) {\n const currentSyncState = await localStorageService.getSyncState()\n syncWatermark = currentSyncState.last_sync_time\n console.log(\"[GallerySyncService] ℹ️ No files downloaded — last_sync_time unchanged\")\n } else if (downloadResult.failed.length > 0) {\n const failedSet = new Set(downloadResult.failed)\n let oldestFailed = Infinity\n for (const f of files) {\n if (failedSet.has(f.name)) {\n const ts = typeof f.modified === \"number\" ? f.modified : parseInt(String(f.modified), 10)\n if (!isNaN(ts) && ts < oldestFailed) oldestFailed = ts\n }\n }\n if (oldestFailed < Infinity) {\n syncWatermark = Math.max(0, oldestFailed - 1)\n console.log(\n `[GallerySyncService] ⚠️ ${downloadResult.failed.length} files failed — sync watermark set to ${syncWatermark} instead of ${serverTime}`,\n )\n }\n } else {\n let maxModified = 0\n const failedSet = new Set(downloadResult.failed)\n for (const f of files) {\n if (failedSet.has(f.name)) continue\n const ts = typeof f.modified === \"number\" ? f.modified : parseInt(String(f.modified), 10)\n if (!isNaN(ts)) maxModified = Math.max(maxModified, ts)\n }\n if (maxModified > 0) {\n syncWatermark = maxModified\n }\n }\n console.log(\"[GallerySyncService] 💾 Updating sync state in local storage...\")\n const currentSyncState = await localStorageService.getSyncState()\n // Persist if we downloaded anything OR if a failure needs the watermark rolled back.\n // (Otherwise a clock-skew-triggered full sync where every legacy file fails would\n // leave the stale future watermark on disk and never retry those files.)\n if (downloadedCount > 0 || downloadResult.failed.length > 0) {\n await localStorageService.updateSyncState({\n last_sync_time: syncWatermark,\n total_downloaded: currentSyncState.total_downloaded + downloadedCount,\n total_size: currentSyncState.total_size + downloadResult.total_size,\n })\n }\n console.log(\"[GallerySyncService] ✅ Sync state updated:\")\n console.log(\n `[GallerySyncService] - New last_sync_time: ${syncWatermark} (${new Date(syncWatermark).toISOString()})`,\n )\n console.log(\n `[GallerySyncService] - Total downloads (lifetime): ${\n currentSyncState.total_downloaded + downloadedCount\n }`,\n )\n console.log(\n `[GallerySyncService] - Total data (lifetime): ${(\n (currentSyncState.total_size + downloadResult.total_size) /\n 1024 /\n 1024\n ).toFixed(2)} MB`,\n )\n\n if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {\n store.setSyncError(`${failedCount || \"Some\"} gallery items need retry`)\n } else {\n store.setSyncComplete()\n }\n await this.onSyncComplete(downloadedCount, failedCount)\n } catch (error: any) {\n mediaProcessingQueue.abort()\n if (error?.message === \"Sync cancelled\") {\n console.log(\"[GallerySyncService] Sync was cancelled\")\n store.setSyncCancelled()\n await gallerySyncNotifications.showSyncCancelled()\n } else {\n console.error(\"[GallerySyncService] Download failed:\", error)\n store.setSyncError(error?.message || \"Download failed\")\n await gallerySyncNotifications.showSyncError(error?.message || \"Download failed\")\n }\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n }\n }\n\n /**\n * Execute capture-aware download (api_version=2).\n * Downloads captures as groups, runs HDR merge, saves single metadata entry per capture.\n */\n private async executeCaptureDownload(captures: CaptureGroup[], serverTime: number): Promise<void> {\n const downloadStartTime = Date.now()\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ⬇️ CAPTURE DOWNLOAD EXECUTION STARTED\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 📊 Captures to download: ${captures.length}`)\n\n const store = useGallerySyncStore.getState()\n const settingsStore = useSettingsStore.getState()\n const defaultWearable = settingsStore.getSetting(SETTINGS.default_wearable.key)\n\n let downloadedCount = 0\n let failedCount = 0\n let totalSizeDownloaded = 0\n let oldestFailedTimestamp = Infinity // Track for sync watermark\n let maxSuccessfulTimestamp = 0\n\n const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll()\n const shouldProcessImages = useSettingsStore.getState().getSetting(SETTINGS.media_post_processing.key)\n\n try {\n for (let i = 0; i < captures.length; i++) {\n const capture = captures[i]\n\n // Check cancellation\n if (this.abortController?.signal.aborted) {\n throw new Error(\"Sync cancelled\")\n }\n\n // Update store progress\n const currentStore = useGallerySyncStore.getState()\n if (i > 0) {\n // Mark previous capture as complete\n currentStore.onFileComplete(captures[i - 1].capture_id)\n await localStorageService.updateSyncQueueIndex(i)\n }\n currentStore.setCurrentFile(capture.capture_id, 0)\n\n try {\n console.log(\n `[GallerySyncService] 📦 Downloading capture ${i + 1}/${captures.length}: ${capture.capture_id} (${\n capture.files.length\n } files)`,\n )\n\n validateCaptureMetadataForDownload(capture)\n\n // Download all files in this capture\n const result = await asgCameraApi.downloadCapture(\n capture,\n (bytesDownloaded, totalBytes) => {\n // Don't throw in progress callbacks — abort signal stops the download\n if (this.abortController?.signal.aborted) return\n const progress = totalBytes > 0 ? Math.round((bytesDownloaded / totalBytes) * 100) : 0\n const cs = useGallerySyncStore.getState()\n cs.onFileProgress(capture.capture_id, Math.min(progress, 99))\n gallerySyncNotifications.updateProgress(i + 1, captures.length, capture.capture_id, progress)\n },\n this.abortController?.signal,\n )\n\n // Mark 100% progress\n const cs2 = useGallerySyncStore.getState()\n cs2.onFileProgress(capture.capture_id, 100)\n\n totalSizeDownloaded += capture.total_size\n downloadedCount++\n if (capture.timestamp > maxSuccessfulTimestamp) {\n maxSuccessfulTimestamp = capture.timestamp\n }\n\n // Enqueue for processing (runs concurrently with next download)\n // Delete from glasses happens after processing completes to avoid data loss on crash\n mediaProcessingQueue.enqueue({\n id: capture.capture_id,\n type: capture.type,\n primaryPath: result.primaryPath,\n bracketPaths: result.bracketPaths,\n sidecarPath: result.sidecarPath,\n thumbnailData: capture.thumbnail_data,\n thumbnailPath: result.thumbnailPath,\n captureDir: result.captureDir,\n timestamp: capture.timestamp,\n totalSize: capture.total_size,\n duration: capture.duration,\n glassesModel: defaultWearable,\n shouldProcess: !!shouldProcessImages,\n shouldAutoSave: !!shouldAutoSave,\n deleteFromGlasses: [capture.capture_id],\n protocolVersion: capture.files.some((file) => !!file.etag) ? 3 : 2,\n })\n } catch (captureError: any) {\n if (captureError?.message === \"Sync cancelled\") throw captureError\n const errMsg = captureError?.message || captureError?.toString?.() || JSON.stringify(captureError)\n console.error(`[GallerySyncService] ❌ Failed to download capture ${capture.capture_id}: ${errMsg}`)\n failedCount++\n // Track oldest failed timestamp so we don't advance sync past it\n if (capture.timestamp < oldestFailedTimestamp) {\n oldestFailedTimestamp = capture.timestamp\n }\n const cs = useGallerySyncStore.getState()\n cs.onFileFailed(capture.capture_id)\n }\n }\n\n // Mark last capture as complete\n if (captures.length > 0) {\n const lastCapture = captures[captures.length - 1]\n const cs = useGallerySyncStore.getState()\n cs.onFileComplete(lastCapture.capture_id)\n }\n\n await localStorageService.updateSyncQueueIndex(captures.length)\n\n const downloadDuration = Date.now() - downloadStartTime\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ CAPTURE DOWNLOAD EXECUTION COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(`[GallerySyncService] 📊 Downloaded: ${downloadedCount}, Failed: ${failedCount}`)\n console.log(`[GallerySyncService] ⏱️ Duration: ${(downloadDuration / 1000).toFixed(1)}s`)\n\n // Wait for processing queue to finish before marking complete\n console.log(\"[GallerySyncService] ⏳ Waiting for processing queue to drain...\")\n await mediaProcessingQueue.waitUntilDrained()\n console.log(\"[GallerySyncService] ✅ Processing queue drained\")\n\n // Reconcile failures from the processing queue. validateDownloadedMediaFile\n // (post-download validation in mediaProcessingQueue) runs AFTER enqueue\n // returns, so a failure there doesn't reach the per-capture catch above. The\n // gallerySync store collects those failures via onFileFailed — pull them in\n // here so the watermark holds them back for retry on the next sync.\n const captureTimestampById = new Map<string, number>()\n for (const c of captures) {\n if (typeof c.timestamp === \"number\") {\n captureTimestampById.set(c.capture_id, c.timestamp)\n }\n }\n const failedSnapshot = useGallerySyncStore.getState().failedFiles\n const observedFailures = new Set<string>(failedSnapshot)\n for (const failedId of observedFailures) {\n const ts = captureTimestampById.get(failedId)\n if (ts === undefined) continue // failure from a different scope (e.g. file-level), skip\n if (ts < oldestFailedTimestamp) {\n oldestFailedTimestamp = ts\n }\n }\n // failedCount should reflect the total set of failed captures from THIS batch.\n const failedFromThisBatch = captures.filter((c) => observedFailures.has(c.capture_id)).length\n if (failedFromThisBatch > failedCount) {\n failedCount = failedFromThisBatch\n }\n\n // Update sync state — only advance watermark when captures were downloaded.\n let syncWatermark = serverTime\n const currentSyncState = await localStorageService.getSyncState()\n if (failedCount > 0 && oldestFailedTimestamp < Infinity) {\n // Failures take priority — roll the watermark back before the oldest failure so it\n // gets retried, regardless of whether anything else succeeded in this batch.\n syncWatermark = Math.max(0, oldestFailedTimestamp - 1)\n console.log(\n `[GallerySyncService] ⚠️ ${failedCount} captures failed — sync watermark set to ${syncWatermark} instead of ${serverTime} so they will be retried`,\n )\n } else if (downloadedCount === 0) {\n syncWatermark = currentSyncState.last_sync_time\n console.log(\"[GallerySyncService] ℹ️ No captures downloaded — last_sync_time unchanged\")\n } else if (maxSuccessfulTimestamp > 0) {\n syncWatermark = maxSuccessfulTimestamp\n }\n // Persist if we downloaded anything OR if a failure needs the watermark rolled back\n // (zero-byte / validation failures otherwise leave a stale watermark on disk).\n if (downloadedCount > 0 || (failedCount > 0 && oldestFailedTimestamp < Infinity)) {\n await localStorageService.updateSyncState({\n last_sync_time: syncWatermark,\n total_downloaded: currentSyncState.total_downloaded + downloadedCount,\n total_size: currentSyncState.total_size + totalSizeDownloaded,\n })\n }\n\n if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {\n store.setSyncError(`${failedCount || \"Some\"} gallery items need retry`)\n } else {\n store.setSyncComplete()\n }\n await this.onSyncComplete(downloadedCount, failedCount)\n } catch (error: any) {\n mediaProcessingQueue.abort()\n if (error?.message === \"Sync cancelled\") {\n console.log(\"[GallerySyncService] Sync was cancelled\")\n store.setSyncCancelled()\n await gallerySyncNotifications.showSyncCancelled()\n } else {\n console.error(\"[GallerySyncService] Capture download failed:\", error)\n store.setSyncError(error?.message || \"Download failed\")\n await gallerySyncNotifications.showSyncError(error?.message || \"Download failed\")\n }\n\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n }\n }\n\n /**\n * Handle sync completion\n */\n private async onSyncComplete(downloadedCount: number, failedCount: number): Promise<void> {\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 🎉 Step 6/6: Sync completion\")\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] 📊 Final results:\")\n console.log(`[GallerySyncService] - Downloaded: ${downloadedCount}`)\n console.log(`[GallerySyncService] - Failed: ${failedCount}`)\n console.log(\n `[GallerySyncService] - Success rate: ${\n downloadedCount > 0 ? ((downloadedCount / (downloadedCount + failedCount)) * 100).toFixed(1) : 0\n }%`,\n )\n\n // 🔍 DIAGNOSTIC: Show all pictures currently in storage after sync\n // try {\n // const allStoredFiles = await localStorageService.getDownloadedFiles()\n // const fileNames = Object.keys(allStoredFiles)\n // console.log(`[GallerySyncService] 📸 POST-SYNC INVENTORY: ${fileNames.length} total files in storage`)\n // console.log(`[GallerySyncService] 📋 Complete file list:`)\n // fileNames\n // .sort((a, b) => {\n // const fileA = allStoredFiles[a]\n // const fileB = allStoredFiles[b]\n // return fileB.downloaded_at - fileA.downloaded_at // Most recent first\n // })\n // .slice(0, 20)\n // .forEach((fileName, idx) => {\n // const file = allStoredFiles[fileName]\n // const captureDate = new Date(file.modified).toISOString()\n // const downloadDate = new Date(file.downloaded_at).toISOString()\n // console.log(\n // `[GallerySyncService] ${idx + 1}. ${fileName} - captured: ${captureDate}, downloaded: ${downloadDate}`,\n // )\n // })\n // if (fileNames.length > 20) {\n // console.log(`[GallerySyncService] ... and ${fileNames.length - 20} more files`)\n // }\n // } catch (error) {\n // console.error(`[GallerySyncService] Failed to get post-sync inventory:`, error)\n // }\n\n const hasPendingRecovery = galleryTransferLedger.hasPendingRecovery()\n if (!hasPendingRecovery && failedCount === 0) {\n console.log(\"[GallerySyncService] 🧹 Clearing completed sync queue...\")\n await localStorageService.clearSyncQueue()\n } else {\n console.log(\"[GallerySyncService] ♻️ Keeping recovery state for unfinished export/ack work\")\n }\n\n if (hasPendingRecovery || failedCount > 0) {\n console.log(\"[GallerySyncService] 📱 Showing retry-required notification...\")\n await gallerySyncNotifications.showSyncError(\n failedCount > 0\n ? `${failedCount} gallery item${failedCount === 1 ? \"\" : \"s\"} will be retried`\n : \"Gallery export or acknowledgement will be retried\",\n )\n } else {\n console.log(\"[GallerySyncService] 📱 Showing completion notification...\")\n await gallerySyncNotifications.showSyncComplete(downloadedCount, 0)\n }\n\n // Close hotspot if we opened it\n const store = useGallerySyncStore.getState()\n if (store.syncServiceOpenedHotspot) {\n console.log(\"[GallerySyncService] 📡 Closing hotspot (service opened it)...\")\n await this.closeHotspot()\n } else {\n console.log(\"[GallerySyncService] ℹ️ Hotspot was not opened by service - leaving it enabled\")\n }\n\n // Clear glasses gallery count immediately after successful sync\n // This ensures UI shows 0 items remaining right away\n // The subsequent query will update this if new photos were taken during sync\n if (!hasPendingRecovery && failedCount === 0) {\n console.log(\"[GallerySyncService] 🔄 Clearing glasses gallery count (synced all items)\")\n store.clearGlassesGalleryStatus()\n }\n\n // Auto-reset to idle after 4 seconds to clear \"Sync complete!\" message,\n // then query glasses for any new content taken during the sync.\n // The query MUST happen after the reset — otherwise setGlassesGalleryStatus\n // sees syncState=\"complete\" + hasContent=true and immediately resets to idle,\n // making it look like sync accomplished nothing (circular sync loop).\n console.log(\"[GallerySyncService] ⏲️ Scheduling auto-reset to idle in 4 seconds...\")\n BgTimer.setTimeout(async () => {\n const currentStore = useGallerySyncStore.getState()\n if (currentStore.syncState === \"complete\") {\n console.log(\"[GallerySyncService] 🔄 Auto-resetting sync state to idle\")\n currentStore.setSyncState(\"idle\")\n }\n // Now query glasses — any content reported will show the sync button\n // naturally without preempting the \"Sync complete!\" message\n console.log(\"[GallerySyncService] 🔍 Querying glasses for post-sync gallery status...\")\n await this.queryGlassesGalleryStatus()\n }, 4000)\n\n console.log(\"[GallerySyncService] ========================================\")\n console.log(\"[GallerySyncService] ✅ SYNC FULLY COMPLETE\")\n console.log(\"[GallerySyncService] ========================================\")\n }\n\n /**\n * Cancel the current sync\n */\n async cancelSync(): Promise<void> {\n console.log(\"[GallerySyncService] Cancelling sync...\")\n\n // Abort any ongoing downloads\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n\n // Clear timeout\n if (this.hotspotConnectionTimeout) {\n BgTimer.clearTimeout(this.hotspotConnectionTimeout!)\n this.hotspotConnectionTimeout = null\n }\n\n const store = useGallerySyncStore.getState()\n\n // Close hotspot if we opened it\n if (store.syncServiceOpenedHotspot) {\n await this.closeHotspot()\n }\n\n // Update store\n store.setSyncCancelled()\n\n // Clear queue\n await localStorageService.clearSyncQueue()\n\n // Dismiss notification\n await gallerySyncNotifications.showSyncCancelled()\n }\n\n /**\n * Close the hotspot\n */\n private async closeHotspot(): Promise<void> {\n const store = useGallerySyncStore.getState()\n\n try {\n console.log(\"[GallerySyncService] Closing hotspot...\")\n await localNetworkTransport.disconnect()\n await BluetoothSdk.setHotspotState(false)\n store.setSyncServiceOpenedHotspot(false)\n store.setHotspotInfo(null)\n console.log(\"[GallerySyncService] Hotspot closed\")\n } catch (error) {\n console.error(\"[GallerySyncService] Failed to close hotspot:\", error)\n }\n }\n\n /**\n * Check for resumable sync on app start\n */\n async checkForResumableSync(): Promise<boolean> {\n const hasResumable = await localStorageService.hasResumableSyncQueue()\n\n if (hasResumable) {\n console.log(\"[GallerySyncService] Found resumable sync queue\")\n // Don't auto-resume - let user decide\n // Could emit an event here for UI to show \"Resume sync?\" prompt\n }\n\n return hasResumable\n }\n\n /**\n * Resume a previously interrupted sync\n */\n async resumeSync(): Promise<void> {\n const queue = await localStorageService.getSyncQueue()\n\n if (!queue || queue.currentIndex >= queue.files.length) {\n console.log(\"[GallerySyncService] No queue to resume\")\n await localStorageService.clearSyncQueue()\n return\n }\n\n // Check if queue is too old - hotspot auto-disables after 40s of inactivity,\n // so stale queues can't be resumed (hotspot credentials are no longer valid)\n const queueAge = Date.now() - queue.startedAt\n if (queueAge > TIMING.MAX_QUEUE_AGE_MS) {\n console.log(`[GallerySyncService] Queue too old (${Math.round(queueAge / 1000)}s) - clearing stale queue`)\n await localStorageService.clearSyncQueue()\n // Don't auto-start - let user tap sync button if they want to continue\n return\n }\n\n // R5: Resume by going through full startSync() flow to re-request hotspot\n // (stale hotspot credentials are unreliable). The saved queue will be used\n // to skip already-downloaded files when startFileDownload detects them.\n console.log(`[GallerySyncService] Resuming sync from file ${queue.currentIndex + 1}/${queue.files.length}`)\n console.log(\"[GallerySyncService] Re-requesting hotspot via full startSync flow\")\n await this.startSync()\n }\n\n /**\n * Query glasses for gallery status\n */\n async queryGlassesGalleryStatus(): Promise<void> {\n try {\n await BluetoothSdk.queryGalleryStatus()\n } catch (error) {\n console.error(\"[GallerySyncService] Failed to query gallery status:\", error)\n }\n }\n\n /** True while pre-flight startSync work is in flight (before sync state transitions). */\n isSyncStarting(): boolean {\n return useGallerySyncStore.getState().syncStarting\n }\n\n /**\n * Check if sync is currently in progress (hotspot/WiFi/download phases).\n * Does not include pre-flight — use isSyncStarting() for that.\n */\n isSyncing(): boolean {\n const store = useGallerySyncStore.getState()\n return (\n store.syncState === \"syncing\" || store.syncState === \"connecting_wifi\" || store.syncState === \"requesting_hotspot\"\n )\n }\n}\n\nexport const gallerySyncService = GallerySyncService.getInstance()\n"]}