@aguacerowx/react-native 0.0.52 → 0.0.54

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 (265) hide show
  1. package/LICENSE +21 -0
  2. package/android/src/main/cpp/satellite_ktx_jni.cpp +6 -1
  3. package/android/src/main/java/com/aguacerowx/reactnative/NexradRadarLayerView.java +14 -2
  4. package/android/src/main/java/com/aguacerowx/reactnative/SatelliteLayer.java +121 -1
  5. package/android/src/main/java/com/aguacerowx/reactnative/SatelliteLayerView.java +556 -392
  6. package/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +77 -0
  7. package/index.js +1 -1
  8. package/ios/SatelliteLayerView.swift +517 -517
  9. package/ios/WeatherFrameProcessorModule.m +19 -15
  10. package/ios/WeatherFrameProcessorModule.swift +65 -0
  11. package/lib/commonjs/AguaceroContext.js +0 -4
  12. package/lib/commonjs/AguaceroContext.js.map +1 -1
  13. package/lib/commonjs/GridRenderLayer.js +62 -76
  14. package/lib/commonjs/GridRenderLayer.js.map +1 -1
  15. package/lib/commonjs/MapManager.js +110 -224
  16. package/lib/commonjs/MapManager.js.map +1 -1
  17. package/lib/commonjs/MapRegistry.js +21 -33
  18. package/lib/commonjs/MapRegistry.js.map +1 -1
  19. package/lib/commonjs/NexradRadarLayer.android.js +28 -100
  20. package/lib/commonjs/NexradRadarLayer.android.js.map +1 -1
  21. package/lib/commonjs/NexradRadarLayer.ios.js +26 -97
  22. package/lib/commonjs/NexradRadarLayer.ios.js.map +1 -1
  23. package/lib/commonjs/NexradSitesMapLayer.js +41 -61
  24. package/lib/commonjs/NexradSitesMapLayer.js.map +1 -1
  25. package/lib/commonjs/SatelliteLayer.android.js +26 -38
  26. package/lib/commonjs/SatelliteLayer.android.js.map +1 -1
  27. package/lib/commonjs/SatelliteLayer.ios.js +30 -42
  28. package/lib/commonjs/SatelliteLayer.ios.js.map +1 -1
  29. package/lib/commonjs/StyleApplicator.js +129 -175
  30. package/lib/commonjs/StyleApplicator.js.map +1 -1
  31. package/lib/commonjs/WeatherLayerManager.js +996 -1627
  32. package/lib/commonjs/WeatherLayerManager.js.map +1 -1
  33. package/lib/commonjs/aguaceroCoreDebugHooks.js +58 -130
  34. package/lib/commonjs/aguaceroCoreDebugHooks.js.map +1 -1
  35. package/lib/commonjs/aguaceroRnDebug.js +147 -287
  36. package/lib/commonjs/aguaceroRnDebug.js.map +1 -1
  37. package/lib/commonjs/cdnAuthenticatedFetch.js +104 -0
  38. package/lib/commonjs/cdnAuthenticatedFetch.js.map +1 -0
  39. package/lib/commonjs/dispatchViewManagerCommandCompat.js +51 -88
  40. package/lib/commonjs/dispatchViewManagerCommandCompat.js.map +1 -1
  41. package/lib/commonjs/gridCdnAuth.js +41 -50
  42. package/lib/commonjs/gridCdnAuth.js.map +1 -1
  43. package/lib/commonjs/index.js +51 -0
  44. package/lib/commonjs/index.js.map +1 -1
  45. package/lib/commonjs/nexrad/nexradAndroidController.js +851 -863
  46. package/lib/commonjs/nexrad/nexradAndroidController.js.map +1 -1
  47. package/lib/commonjs/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +62 -85
  48. package/lib/commonjs/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js.map +1 -1
  49. package/lib/commonjs/nexrad/nexradDiag.js +32 -148
  50. package/lib/commonjs/nexrad/nexradDiag.js.map +1 -1
  51. package/lib/commonjs/nexrad/nexradLevel2Keys.js +261 -0
  52. package/lib/commonjs/nexrad/nexradLevel2Keys.js.map +1 -0
  53. package/lib/commonjs/nexrad/nexradLutBuild.js +64 -111
  54. package/lib/commonjs/nexrad/nexradLutBuild.js.map +1 -1
  55. package/lib/commonjs/nexrad/nexradMapboxFrameOpts.bundled.js +136 -164
  56. package/lib/commonjs/nexrad/nexradMapboxFrameOpts.bundled.js.map +1 -1
  57. package/lib/commonjs/nexrad/nexradSdkImports.js +51 -0
  58. package/lib/commonjs/nexrad/nexradSdkImports.js.map +1 -0
  59. package/lib/commonjs/nexrad/radarArchiveCore.bundled.js +2848 -4455
  60. package/lib/commonjs/nexrad/radarArchiveCore.bundled.js.map +1 -1
  61. package/lib/commonjs/nexrad/radarDecode.worker.bundled.js +445 -648
  62. package/lib/commonjs/nexrad/radarDecode.worker.bundled.js.map +1 -1
  63. package/lib/commonjs/nexrad/radarFrameGpuMatch.bundled.js +52 -68
  64. package/lib/commonjs/nexrad/radarFrameGpuMatch.bundled.js.map +1 -1
  65. package/lib/commonjs/nexradNativeCommandIds.js +24 -0
  66. package/lib/commonjs/nexradNativeCommandIds.js.map +1 -0
  67. package/lib/commonjs/nws/NwsAlertsOverlay.android.js.map +1 -1
  68. package/lib/commonjs/nws/NwsAlertsOverlay.ios.js.map +1 -1
  69. package/lib/commonjs/nws/NwsAlertsOverlay.js +3 -3
  70. package/lib/commonjs/nws/NwsAlertsOverlay.js.map +1 -1
  71. package/lib/commonjs/nws/NwsAlertsOverlay.native.js +235 -361
  72. package/lib/commonjs/nws/NwsAlertsOverlay.native.js.map +1 -1
  73. package/lib/commonjs/nws/eventSourceRnPolyfill.js +92 -146
  74. package/lib/commonjs/nws/eventSourceRnPolyfill.js.map +1 -1
  75. package/lib/commonjs/nws/nwsAndroidConstants.js +2 -8
  76. package/lib/commonjs/nws/nwsAndroidConstants.js.map +1 -1
  77. package/lib/commonjs/satellite/satelliteAndroidController.js +122 -199
  78. package/lib/commonjs/satellite/satelliteAndroidController.js.map +1 -1
  79. package/lib/commonjs/satelliteBridgeDiag.js +3 -13
  80. package/lib/commonjs/satelliteBridgeDiag.js.map +1 -1
  81. package/lib/commonjs/satelliteRnDebug.js +160 -0
  82. package/lib/commonjs/satelliteRnDebug.js.map +1 -0
  83. package/lib/module/AguaceroContext.js +2 -7
  84. package/lib/module/AguaceroContext.js.map +1 -1
  85. package/lib/module/GridRenderLayer.js +66 -80
  86. package/lib/module/GridRenderLayer.js.map +1 -1
  87. package/lib/module/MapManager.js +125 -239
  88. package/lib/module/MapManager.js.map +1 -1
  89. package/lib/module/MapRegistry.js +21 -33
  90. package/lib/module/MapRegistry.js.map +1 -1
  91. package/lib/module/NexradRadarLayer.android.js +32 -104
  92. package/lib/module/NexradRadarLayer.android.js.map +1 -1
  93. package/lib/module/NexradRadarLayer.ios.js +30 -101
  94. package/lib/module/NexradRadarLayer.ios.js.map +1 -1
  95. package/lib/module/NexradSitesMapLayer.js +44 -63
  96. package/lib/module/NexradSitesMapLayer.js.map +1 -1
  97. package/lib/module/SatelliteLayer.android.js +32 -44
  98. package/lib/module/SatelliteLayer.android.js.map +1 -1
  99. package/lib/module/SatelliteLayer.ios.js +36 -48
  100. package/lib/module/SatelliteLayer.ios.js.map +1 -1
  101. package/lib/module/StyleApplicator.js +144 -191
  102. package/lib/module/StyleApplicator.js.map +1 -1
  103. package/lib/module/WeatherLayerManager.js +1024 -1655
  104. package/lib/module/WeatherLayerManager.js.map +1 -1
  105. package/lib/module/aguaceroCoreDebugHooks.js +59 -130
  106. package/lib/module/aguaceroCoreDebugHooks.js.map +1 -1
  107. package/lib/module/aguaceroRnDebug.js +151 -291
  108. package/lib/module/aguaceroRnDebug.js.map +1 -1
  109. package/lib/module/cdnAuthenticatedFetch.js +97 -0
  110. package/lib/module/cdnAuthenticatedFetch.js.map +1 -0
  111. package/lib/module/dispatchViewManagerCommandCompat.js +52 -90
  112. package/lib/module/dispatchViewManagerCommandCompat.js.map +1 -1
  113. package/lib/module/gridCdnAuth.js +38 -50
  114. package/lib/module/gridCdnAuth.js.map +1 -1
  115. package/lib/module/index.js +9 -6
  116. package/lib/module/index.js.map +1 -1
  117. package/lib/module/nexrad/nexradAndroidController.js +865 -876
  118. package/lib/module/nexrad/nexradAndroidController.js.map +1 -1
  119. package/lib/module/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +62 -85
  120. package/lib/module/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js.map +1 -1
  121. package/lib/module/nexrad/nexradDiag.js +31 -145
  122. package/lib/module/nexrad/nexradDiag.js.map +1 -1
  123. package/lib/module/nexrad/nexradLevel2Keys.js +245 -0
  124. package/lib/module/nexrad/nexradLevel2Keys.js.map +1 -0
  125. package/lib/module/nexrad/nexradLutBuild.js +64 -110
  126. package/lib/module/nexrad/nexradLutBuild.js.map +1 -1
  127. package/lib/module/nexrad/nexradMapboxFrameOpts.bundled.js +136 -163
  128. package/lib/module/nexrad/nexradMapboxFrameOpts.bundled.js.map +1 -1
  129. package/lib/module/nexrad/nexradSdkImports.js +4 -0
  130. package/lib/module/nexrad/nexradSdkImports.js.map +1 -0
  131. package/lib/module/nexrad/radarArchiveCore.bundled.js +2839 -4448
  132. package/lib/module/nexrad/radarArchiveCore.bundled.js.map +1 -1
  133. package/lib/module/nexrad/radarDecode.worker.bundled.js +445 -648
  134. package/lib/module/nexrad/radarDecode.worker.bundled.js.map +1 -1
  135. package/lib/module/nexrad/radarFrameGpuMatch.bundled.js +50 -66
  136. package/lib/module/nexrad/radarFrameGpuMatch.bundled.js.map +1 -1
  137. package/lib/module/nexradNativeCommandIds.js +18 -0
  138. package/lib/module/nexradNativeCommandIds.js.map +1 -0
  139. package/lib/module/nws/NwsAlertsOverlay.android.js +1 -1
  140. package/lib/module/nws/NwsAlertsOverlay.android.js.map +1 -1
  141. package/lib/module/nws/NwsAlertsOverlay.ios.js +1 -1
  142. package/lib/module/nws/NwsAlertsOverlay.ios.js.map +1 -1
  143. package/lib/module/nws/NwsAlertsOverlay.js +5 -5
  144. package/lib/module/nws/NwsAlertsOverlay.js.map +1 -1
  145. package/lib/module/nws/NwsAlertsOverlay.native.js +248 -373
  146. package/lib/module/nws/NwsAlertsOverlay.native.js.map +1 -1
  147. package/lib/module/nws/eventSourceRnPolyfill.js +92 -146
  148. package/lib/module/nws/eventSourceRnPolyfill.js.map +1 -1
  149. package/lib/module/nws/nwsAndroidConstants.js +2 -8
  150. package/lib/module/nws/nwsAndroidConstants.js.map +1 -1
  151. package/lib/module/satellite/satelliteAndroidController.js +125 -202
  152. package/lib/module/satellite/satelliteAndroidController.js.map +1 -1
  153. package/lib/module/satelliteBridgeDiag.js +3 -13
  154. package/lib/module/satelliteBridgeDiag.js.map +1 -1
  155. package/lib/module/satelliteRnDebug.js +148 -0
  156. package/lib/module/satelliteRnDebug.js.map +1 -0
  157. package/lib/typescript/AguaceroContext.d.ts +0 -4
  158. package/lib/typescript/AguaceroContext.d.ts.map +1 -1
  159. package/lib/typescript/GridRenderLayer.d.ts.map +1 -1
  160. package/lib/typescript/MapManager.d.ts +0 -12
  161. package/lib/typescript/MapManager.d.ts.map +1 -1
  162. package/lib/typescript/MapRegistry.d.ts +10 -12
  163. package/lib/typescript/MapRegistry.d.ts.map +1 -1
  164. package/lib/typescript/NexradRadarLayer.android.d.ts.map +1 -1
  165. package/lib/typescript/NexradRadarLayer.ios.d.ts.map +1 -1
  166. package/lib/typescript/NexradSitesMapLayer.d.ts +4 -10
  167. package/lib/typescript/NexradSitesMapLayer.d.ts.map +1 -1
  168. package/lib/typescript/SatelliteLayer.android.d.ts.map +1 -1
  169. package/lib/typescript/SatelliteLayer.ios.d.ts.map +1 -1
  170. package/lib/typescript/StyleApplicator.d.ts +1 -1
  171. package/lib/typescript/StyleApplicator.d.ts.map +1 -1
  172. package/lib/typescript/WeatherLayerManager.d.ts.map +1 -1
  173. package/lib/typescript/aguaceroCoreDebugHooks.d.ts +2 -9
  174. package/lib/typescript/aguaceroCoreDebugHooks.d.ts.map +1 -1
  175. package/lib/typescript/aguaceroRnDebug.d.ts +47 -66
  176. package/lib/typescript/aguaceroRnDebug.d.ts.map +1 -1
  177. package/lib/typescript/cdnAuthenticatedFetch.d.ts +10 -0
  178. package/lib/typescript/cdnAuthenticatedFetch.d.ts.map +1 -0
  179. package/lib/typescript/dispatchViewManagerCommandCompat.d.ts +1 -17
  180. package/lib/typescript/dispatchViewManagerCommandCompat.d.ts.map +1 -1
  181. package/lib/typescript/gridCdnAuth.d.ts +16 -21
  182. package/lib/typescript/gridCdnAuth.d.ts.map +1 -1
  183. package/lib/typescript/index.d.ts +2 -0
  184. package/lib/typescript/nexrad/nexradAndroidController.d.ts +39 -89
  185. package/lib/typescript/nexrad/nexradAndroidController.d.ts.map +1 -1
  186. package/lib/typescript/nexrad/nexradCrossSectionSampleAtLatLon.bundled.d.ts +2 -1
  187. package/lib/typescript/nexrad/nexradCrossSectionSampleAtLatLon.bundled.d.ts.map +1 -1
  188. package/lib/typescript/nexrad/nexradDiag.d.ts +13 -101
  189. package/lib/typescript/nexrad/nexradDiag.d.ts.map +1 -1
  190. package/lib/typescript/nexrad/nexradLevel2Keys.d.ts +36 -0
  191. package/lib/typescript/nexrad/nexradLevel2Keys.d.ts.map +1 -0
  192. package/lib/typescript/nexrad/nexradLutBuild.d.ts +3 -10
  193. package/lib/typescript/nexrad/nexradLutBuild.d.ts.map +1 -1
  194. package/lib/typescript/nexrad/nexradMapboxFrameOpts.bundled.d.ts +4 -3
  195. package/lib/typescript/nexrad/nexradMapboxFrameOpts.bundled.d.ts.map +1 -1
  196. package/lib/typescript/nexrad/nexradSdkImports.d.ts +2 -0
  197. package/lib/typescript/nexrad/nexradSdkImports.d.ts.map +1 -0
  198. package/lib/typescript/nexrad/radarArchiveCore.bundled.d.ts +12 -7
  199. package/lib/typescript/nexrad/radarArchiveCore.bundled.d.ts.map +1 -1
  200. package/lib/typescript/nexrad/radarDecode.worker.bundled.d.ts +20 -20
  201. package/lib/typescript/nexrad/radarDecode.worker.bundled.d.ts.map +1 -1
  202. package/lib/typescript/nexrad/radarFrameGpuMatch.bundled.d.ts +4 -3
  203. package/lib/typescript/nexrad/radarFrameGpuMatch.bundled.d.ts.map +1 -1
  204. package/lib/typescript/nexradNativeCommandIds.d.ts +2 -0
  205. package/lib/typescript/nexradNativeCommandIds.d.ts.map +1 -0
  206. package/lib/typescript/nws/NwsAlertsOverlay.native.d.ts +6 -17
  207. package/lib/typescript/nws/NwsAlertsOverlay.native.d.ts.map +1 -1
  208. package/lib/typescript/nws/eventSourceRnPolyfill.d.ts +0 -3
  209. package/lib/typescript/nws/eventSourceRnPolyfill.d.ts.map +1 -1
  210. package/lib/typescript/nws/nwsAndroidConstants.d.ts +0 -5
  211. package/lib/typescript/nws/nwsAndroidConstants.d.ts.map +1 -1
  212. package/lib/typescript/satellite/satelliteAndroidController.d.ts +9 -47
  213. package/lib/typescript/satellite/satelliteAndroidController.d.ts.map +1 -1
  214. package/lib/typescript/satelliteBridgeDiag.d.ts +1 -5
  215. package/lib/typescript/satelliteBridgeDiag.d.ts.map +1 -1
  216. package/lib/typescript/satelliteRnDebug.d.ts +75 -0
  217. package/lib/typescript/satelliteRnDebug.d.ts.map +1 -0
  218. package/package.json +75 -74
  219. package/src/AguaceroContext.js +1 -7
  220. package/src/GridRenderLayer.js +1 -128
  221. package/src/MapManager.js +1 -277
  222. package/src/MapRegistry.js +1 -56
  223. package/src/NexradRadarLayer.android.js +1 -121
  224. package/src/NexradRadarLayer.ios.js +1 -115
  225. package/src/NexradSitesMapLayer.js +1 -75
  226. package/src/SatelliteLayer.android.js +1 -63
  227. package/src/SatelliteLayer.ios.js +1 -70
  228. package/src/StyleApplicator.js +1 -241
  229. package/src/WeatherLayerManager.js +1 -2025
  230. package/src/aguaceroCoreDebugHooks.js +1 -142
  231. package/src/aguaceroRnDebug.js +1 -335
  232. package/src/cdnAuthenticatedFetch.js +1 -0
  233. package/src/dispatchViewManagerCommandCompat.js +1 -100
  234. package/src/gridCdnAuth.js +1 -56
  235. package/src/index.js +1 -19
  236. package/src/nexrad/nexradAndroidController.js +1 -1078
  237. package/src/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +1 -91
  238. package/src/nexrad/nexradDiag.js +1 -150
  239. package/src/nexrad/nexradLevel2Keys.js +1 -0
  240. package/src/nexrad/nexradLutBuild.js +1 -126
  241. package/src/nexrad/nexradMapboxFrameOpts.bundled.js +1 -245
  242. package/src/nexrad/nexradSdkImports.js +1 -0
  243. package/src/nexrad/radarArchiveCore.bundled.js +1 -7085
  244. package/src/nexrad/radarDecode.worker.bundled.js +1 -813
  245. package/src/nexrad/radarFrameGpuMatch.bundled.js +1 -79
  246. package/src/nexradNativeCommandIds.js +1 -0
  247. package/src/nws/NwsAlertsOverlay.android.js +1 -1
  248. package/src/nws/NwsAlertsOverlay.ios.js +1 -1
  249. package/src/nws/NwsAlertsOverlay.js +1 -7
  250. package/src/nws/NwsAlertsOverlay.native.js +1 -463
  251. package/src/nws/eventSourceRnPolyfill.js +7 -193
  252. package/src/nws/nwsAndroidConstants.js +1 -8
  253. package/src/satellite/satelliteAndroidController.js +1 -245
  254. package/src/satelliteBridgeDiag.js +1 -15
  255. package/src/satelliteRnDebug.js +1 -0
  256. package/lib/commonjs/nexrad/nexradNativeCommandIds.js +0 -51
  257. package/lib/commonjs/nexrad/nexradNativeCommandIds.js.map +0 -1
  258. package/lib/module/nexrad/nexradNativeCommandIds.js +0 -44
  259. package/lib/module/nexrad/nexradNativeCommandIds.js.map +0 -1
  260. package/lib/typescript/nexrad/nexradNativeCommandIds.d.ts +0 -9
  261. package/lib/typescript/nexrad/nexradNativeCommandIds.d.ts.map +0 -1
  262. package/src/nexrad/nexradNativeCommandIds.js +0 -44
  263. /package/lib/commonjs/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
  264. /package/lib/module/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
  265. /package/src/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
@@ -1,1815 +1,1184 @@
1
- // packages/react-native/src/WeatherLayerManager.js
2
-
3
- import { AguaceroCore, DICTIONARIES, formatTimelineDurationValue, getUnitConversionFunction, parseTimelineDurationHours } from '@aguacerowx/javascript-sdk';
4
- import { fromByteArray } from 'base64-js';
5
- import React, { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
6
- import { NativeModules, Platform, UIManager } from 'react-native';
7
- import { AguaceroContext } from './AguaceroContext';
8
- import { GridRenderLayer } from './GridRenderLayer';
9
- import NexradRadarLayer from './NexradRadarLayer';
10
- import SatelliteLayer from './SatelliteLayer';
11
- import { NexradSitesMapLayer } from './NexradSitesMapLayer';
12
- import { NexradAndroidController } from './nexrad/nexradAndroidController';
13
- import { SatelliteAndroidController } from './satellite/satelliteAndroidController';
14
- import NwsAlertsOverlay from './nws/NwsAlertsOverlay';
15
- import { mapRegistry } from './MapRegistry';
16
- import { satBridgeWarn } from './satelliteBridgeDiag';
17
- import { augmentProcessFrameOptionsForDebug, aguaceroDebugWarn, configureAguaceroRnDebug, getAguaceroAuthDiagnosticSnapshot, isAguaceroRnDebugEnabled } from './aguaceroRnDebug';
18
- import { installAguaceroCoreDebugHooks, logProcessFrameAuthMismatch } from './aguaceroCoreDebugHooks';
19
- import { resolveGridRequestSiteOrigin } from './gridCdnAuth';
20
- const NEXRAD_NATIVE = Platform.OS === 'android' || Platform.OS === 'ios';
21
- const SATELLITE_NATIVE = Platform.OS === 'android' || Platform.OS === 'ios';
22
- satBridgeWarn('SDK fingerprint', {
23
- platform: Platform.OS,
24
- SATELLITE_NATIVE,
25
- note: 'If you never see sat-bridge logs, the app bundle is not loading this WeatherLayerManager build.'
1
+ import { AguaceroCore as je, DICTIONARIES as Be, formatTimelineDurationValue as ct, getUnitConversionFunction as ve, parseTimelineDurationHours as xt } from "@aguacerowx/javascript-sdk";
2
+ import { fromByteArray as ze } from "base64-js";
3
+ import be, { forwardRef as Tt, useCallback as we, useContext as Ct, useEffect as j, useImperativeHandle as Mt, useMemo as ut, useRef as V, useState as Je } from "react";
4
+ import { NativeModules as vt, Platform as se, UIManager as mt } from "react-native";
5
+ import { AguaceroContext as $t } from "./AguaceroContext";
6
+ import { GridRenderLayer as _t } from "./GridRenderLayer";
7
+ import Nt from "./NexradRadarLayer";
8
+ import Dt from "./SatelliteLayer";
9
+ import { NexradSitesMapLayer as It } from "./NexradSitesMapLayer";
10
+ import { SatelliteAndroidController as Rt } from "./satellite/satelliteAndroidController";
11
+ import { NexradAndroidController as Ft } from "./nexrad/nexradAndroidController";
12
+ import { createNexradCloudFrontFetch as At } from "./cdnAuthenticatedFetch";
13
+ import { setNexradLevel2CloudFrontFetch as dt } from "./nexrad/radarArchiveCore.bundled.js";
14
+ import Pt from "./nws/NwsAlertsOverlay";
15
+ import { mapRegistry as Ue } from "./MapRegistry";
16
+ import { satBridgeWarn as Ee } from "./satelliteBridgeDiag";
17
+ import { augmentProcessFrameOptionsForDebug as Xe, aguaceroDebugWarn as Ye, configureAguaceroRnDebug as Lt, getAguaceroAuthDiagnosticSnapshot as ft, isAguaceroRnDebugEnabled as Ke } from "./aguaceroRnDebug";
18
+ import { installAguaceroCoreDebugHooks as Vt, logProcessFrameAuthMismatch as Qe } from "./aguaceroCoreDebugHooks";
19
+ import { buildNativeCloudFrontFetchOptions as Ot, resolveGridRequestSiteOrigin as wt } from "./gridCdnAuth";
20
+ import { auditSatelliteIntegration as Ut, installSatelliteDiagnosticListener as Et } from "./satelliteRnDebug";
21
+ const Q = se.OS === "android" || se.OS === "ios",
22
+ ie = se.OS === "android" || se.OS === "ios";
23
+ Ee("SDK fingerprint", {
24
+ platform: se.OS,
25
+ SATELLITE_NATIVE: ie,
26
+ note: "If you never see sat-bridge logs, the app bundle is not loading this WeatherLayerManager build."
26
27
  });
27
-
28
- /**
29
- * Same filtering as {@link AguaceroCore#_getFilteredMrmsTimestampsForVariable} for older cores
30
- * where that helper (or {@code setMRMSDurationValue}) is missing from the prototype chain.
31
- */
32
- function getFilteredMrmsTimestampsCompat(core, variable) {
33
- const raw = core.mrmsStatus?.[variable];
34
- if (!raw || !raw.length) return [];
35
- const hours = parseTimelineDurationHours(core.state.mrmsDurationValue);
36
- let list = [...raw].map(t => Number(t)).filter(t => !Number.isNaN(t)).sort((a, b) => a - b);
37
- if (hours > 0 && list.length > 0) {
38
- const latest = list[list.length - 1];
39
- const cutoff = latest - hours * 3600;
40
- list = list.filter(t => t >= cutoff);
28
+ function Kt(m, x) {
29
+ const g = m.mrmsStatus?.[x];
30
+ if (!g || !g.length) return [];
31
+ const I = xt(m.state.mrmsDurationValue);
32
+ let v = [...g].map(O => Number(O)).filter(O => !Number.isNaN(O)).sort((O, _) => O - _);
33
+ if (I > 0 && v.length > 0) {
34
+ const O = v[v.length - 1] - I * 3600;
35
+ v = v.filter(_ => _ >= O);
41
36
  }
42
- return list;
37
+ return v;
43
38
  }
44
-
45
- /**
46
- * Older npm installs may resolve an {@link AguaceroCore} without {@code setMRMSDurationValue} /
47
- * {@code setNexradDurationValue}; mirror those methods here using the same logic as the SDK.
48
- */
49
- async function applyMrmsDurationValue(core, value) {
50
- if (typeof core.setMRMSDurationValue === 'function') {
51
- await core.setMRMSDurationValue(value);
39
+ async function qt(m, x) {
40
+ if (typeof m.setMRMSDurationValue == "function") {
41
+ await m.setMRMSDurationValue(x);
52
42
  return;
53
43
  }
54
- const v = formatTimelineDurationValue(value);
55
- await core.setState({
56
- mrmsDurationValue: v
57
- });
58
- if (!core.state.isMRMS || !core.state.variable) return;
59
- const filtered = typeof core._getFilteredMrmsTimestampsForVariable === 'function' ? core._getFilteredMrmsTimestampsForVariable(core.state.variable) : getFilteredMrmsTimestampsCompat(core, core.state.variable);
60
- if (!filtered || filtered.length === 0) return;
61
- const curN = core.state.mrmsTimestamp == null ? null : Number(core.state.mrmsTimestamp);
62
- if (curN == null || !filtered.includes(curN)) {
63
- await core.setState({
64
- mrmsTimestamp: filtered[filtered.length - 1]
65
- });
66
- }
67
- }
68
- async function applyNexradDurationValue(core, value) {
69
- if (typeof core.setNexradDurationValue === 'function') {
70
- await core.setNexradDurationValue(value);
71
- return;
72
- }
73
- const v = formatTimelineDurationValue(value);
74
- await core.setState({
75
- nexradDurationValue: v
76
- });
77
- if (!core.state.isNexrad || !core.state.nexradSite) return;
78
- if (typeof core.refreshNexradTimes === 'function') {
79
- await core.refreshNexradTimes();
80
- }
81
- const nk = typeof core._nexradTimesCacheKey === 'function' ? core._nexradTimesCacheKey() : null;
82
- const raw = nk ? core.nexradTimesByStation?.[nk]?.unixTimes || [] : [];
83
- const filtered = typeof core._getFilteredNexradTimestampsForVariable === 'function' ? core._getFilteredNexradTimestampsForVariable(raw) : [...raw].map(t => Number(t)).filter(t => !Number.isNaN(t)).sort((a, b) => a - b);
84
- if (!filtered || filtered.length === 0) return;
85
- const curN = core.state.nexradTimestamp == null ? null : Number(core.state.nexradTimestamp);
86
- if (curN == null || !filtered.includes(curN)) {
87
- await core.setState({
88
- nexradTimestamp: filtered[filtered.length - 1]
89
- });
90
- }
44
+ const g = ct(x);
45
+ if (await m.setState({
46
+ mrmsDurationValue: g
47
+ }), !m.state.isMRMS || !m.state.variable) return;
48
+ const I = typeof m._getFilteredMrmsTimestampsForVariable == "function" ? m._getFilteredMrmsTimestampsForVariable(m.state.variable) : Kt(m, m.state.variable);
49
+ if (!I || I.length === 0) return;
50
+ const v = m.state.mrmsTimestamp == null ? null : Number(m.state.mrmsTimestamp);
51
+ (v == null || !I.includes(v)) && (await m.setState({
52
+ mrmsTimestamp: I[I.length - 1]
53
+ }));
91
54
  }
92
- function findLatestModelRun(modelsData, modelName) {
93
- const model = modelsData?.[modelName];
94
- if (!model) return null;
95
- const availableDates = Object.keys(model).sort((a, b) => b.localeCompare(a));
96
- for (const date of availableDates) {
97
- const runs = model[date];
98
- if (!runs) continue;
99
- const availableRuns = Object.keys(runs).sort((a, b) => b.localeCompare(a));
100
- if (availableRuns.length > 0) return {
101
- date: date,
102
- run: availableRuns[0]
55
+ function Gt(m, x) {
56
+ const g = m?.[x];
57
+ if (!g) return null;
58
+ const I = Object.keys(g).sort((v, O) => O.localeCompare(v));
59
+ for (const v of I) {
60
+ const O = g[v];
61
+ if (!O) continue;
62
+ const _ = Object.keys(O).sort((ee, B) => B.localeCompare(ee));
63
+ if (_.length > 0) return {
64
+ date: v,
65
+ run: _[0]
103
66
  };
104
67
  }
105
68
  return null;
106
69
  }
107
70
  const {
108
- WeatherFrameProcessorModule,
109
- InspectorModule
110
- } = NativeModules;
111
-
112
- /**
113
- * `state:change` payloads can briefly have {@code isNexrad} before {@code nexradSite} / {@code nexradTimestamp}
114
- * are populated; {@code core.state} is updated first. Merge so readouts match the active radar.
115
- *
116
- * @param {object | null} emitted
117
- * @param {object | null} coreState
118
- */
119
- function mergeNexradEmittedWithCore(emitted, coreState) {
120
- if (!emitted || !coreState) return null;
121
- return {
122
- ...emitted,
123
- nexradSite: coreState.nexradSite ?? emitted.nexradSite,
124
- nexradTimestamp: coreState.nexradTimestamp ?? emitted.nexradTimestamp,
125
- nexradProduct: coreState.nexradProduct ?? emitted.nexradProduct,
126
- nexradTilt: coreState.nexradTilt ?? emitted.nexradTilt,
127
- nexradDataSource: coreState.nexradDataSource ?? emitted.nexradDataSource,
128
- nexradStormRelative: coreState.nexradStormRelative ?? emitted.nexradStormRelative
129
- };
71
+ WeatherFrameProcessorModule: qe,
72
+ InspectorModule: kt
73
+ } = vt;
74
+ function ue(m) {
75
+ const x = Object.keys(m?.satelliteTimeToFileMap || {}).map(Number).filter(g => Number.isFinite(g)).sort((g, I) => g - I);
76
+ return x.length ? `${x.length}:${x[0]}:${x[x.length - 1]}` : "0";
130
77
  }
131
-
132
- /**
133
- * Compact timeline identity for deduping {@code state:change}: extending the NEXRAD/satellite window
134
- * often keeps the same selected unix — without this, {@link WeatherLayerManager} short-circuits and
135
- * never calls native {@code sync} / preload with the expanded frame list.
136
- */
137
- function nexradObsTimelineSig(state) {
138
- const arr = [...(state?.availableNexradTimestamps || [])].map(Number).filter(t => Number.isFinite(t)).sort((a, b) => a - b);
139
- if (!arr.length) return '0';
140
- return `${arr.length}:${arr[0]}:${arr[arr.length - 1]}`;
141
- }
142
- function satelliteObsTimelineSig(state) {
143
- const keys = Object.keys(state?.satelliteTimeToFileMap || {}).map(Number).filter(t => Number.isFinite(t)).sort((a, b) => a - b);
144
- if (!keys.length) return '0';
145
- return `${keys.length}:${keys[0]}:${keys[keys.length - 1]}`;
146
- }
147
-
148
- /** True when {@link WeatherLayerManager} `debug` / {@link configureAguaceroRnDebug}, or legacy `__AGUACERO_WX_GRID_DEBUG__`. */
149
- function wxGridDebugEnabled() {
150
- if (isAguaceroRnDebugEnabled()) return true;
78
+ function pt() {
79
+ if (Ke()) return !0;
151
80
  try {
152
- if (typeof __DEV__ !== 'undefined' && __DEV__) return true;
153
- return Boolean(typeof globalThis !== 'undefined' && globalThis.__AGUACERO_WX_GRID_DEBUG__);
81
+ return typeof __DEV__ < "u" && __DEV__ ? !0 : !!(typeof globalThis < "u" && globalThis.__AGUACERO_WX_GRID_DEBUG__);
154
82
  } catch {
155
- return false;
83
+ return !1;
156
84
  }
157
85
  }
158
- function wxGridVerbose(tag, detail) {
159
- if (!wxGridDebugEnabled()) return;
160
- if (detail !== undefined) {
161
- console.log(`[AguaceroWX][grid][${tag}]`, detail);
162
- } else {
163
- console.log(`[AguaceroWX][grid][${tag}]`);
164
- }
86
+ function z(m, x) {
87
+ pt() && (x !== void 0 ? console.log(`[AguaceroWX][grid][${m}]`, x) : console.log(`[AguaceroWX][grid][${m}]`));
165
88
  }
166
-
167
- /** Always logs (Metro / device logs) use for failures and unusual early exits. */
168
- function wxGridWarn(tag, detail) {
169
- if (detail !== undefined) {
170
- console.warn(`[AguaceroWX][grid][${tag}]`, detail);
171
- } else {
172
- console.warn(`[AguaceroWX][grid][${tag}]`);
173
- }
89
+ function Z(m, x) {
90
+ x !== void 0 ? console.warn(`[AguaceroWX][grid][${m}]`, x) : console.warn(`[AguaceroWX][grid][${m}]`);
174
91
  }
175
-
176
- /**
177
- * Native {@code processFrame} must mirror browser/AguaceroCore grid auth: encoded {@code apiKey}
178
- * in the query string and optional {@code Origin} / {@code Referer} (many CloudFront setups require them).
179
- *
180
- * @param {string} baseGridUrl
181
- * @param {string} resourcePath
182
- * @param {string} apiKey
183
- * @param {string | null | undefined} bundleId
184
- * @param {string | undefined} gridRequestSiteOrigin - prop or core origin (see {@link resolveGridRequestSiteOrigin})
185
- * @param {import('@aguacerowx/javascript-sdk').AguaceroCore | null | undefined} core
186
- */
187
- function buildGridFrameProcessOptions(baseGridUrl, resourcePath, apiKey, bundleId, gridRequestSiteOrigin, core) {
188
- const trimmedKey = typeof apiKey === 'string' ? apiKey.trim() : apiKey;
189
- const url = `${baseGridUrl}${resourcePath}?apiKey=${encodeURIComponent(trimmedKey || '')}`;
190
- const options = {
191
- url,
192
- apiKey: trimmedKey,
193
- bundleId
194
- };
195
- const origin = resolveGridRequestSiteOrigin(gridRequestSiteOrigin, core);
196
- if (origin) {
197
- options.gridRequestSiteOrigin = origin;
198
- }
199
- return options;
92
+ function Ze(m, x, g, I, v, O) {
93
+ const _ = `${m}${x}`;
94
+ return Ot({
95
+ url: _,
96
+ apiKey: g,
97
+ bundleId: I,
98
+ gridRequestSiteOrigin: v,
99
+ core: O
100
+ });
200
101
  }
201
-
202
- /**
203
- * A helper function to generate the raw RGBA byte buffer for the colormap texture.
204
- */
205
- const _generateColormapBytes = colormap => {
206
- const width = 256;
207
- const data = new Uint8Array(width * 4);
208
- const stops = colormap.reduce((acc, _, i) => i % 2 === 0 ? [...acc, {
209
- value: colormap[i],
210
- color: colormap[i + 1]
211
- }] : acc, []);
212
- if (stops.length === 0) return data;
213
- const minVal = stops[0].value;
214
- const maxVal = stops[stops.length - 1].value;
215
- const hexToRgb = hex => {
216
- const r = parseInt(hex.slice(1, 3), 16);
217
- const g = parseInt(hex.slice(3, 5), 16);
218
- const b = parseInt(hex.slice(5, 7), 16);
219
- return [r, g, b];
220
- };
221
- for (let i = 0; i < width; i++) {
222
- const val = minVal + i / (width - 1) * (maxVal - minVal);
223
- let lower = stops[0];
224
- let upper = stops[stops.length - 1];
225
- for (let j = 0; j < stops.length - 1; j++) {
226
- if (val >= stops[j].value && val <= stops[j + 1].value) {
227
- lower = stops[j];
228
- upper = stops[j + 1];
229
- break;
230
- }
102
+ const et = m => {
103
+ const x = new Uint8Array(1024),
104
+ g = m.reduce((_, ee, B) => B % 2 === 0 ? [..._, {
105
+ value: m[B],
106
+ color: m[B + 1]
107
+ }] : _, []);
108
+ if (g.length === 0) return x;
109
+ const I = g[0].value,
110
+ v = g[g.length - 1].value,
111
+ O = _ => {
112
+ const ee = parseInt(_.slice(1, 3), 16),
113
+ B = parseInt(_.slice(3, 5), 16),
114
+ fe = parseInt(_.slice(5, 7), 16);
115
+ return [ee, B, fe];
116
+ };
117
+ for (let _ = 0; _ < 256; _++) {
118
+ const ee = I + _ / 255 * (v - I);
119
+ let B = g[0],
120
+ fe = g[g.length - 1];
121
+ for (let J = 0; J < g.length - 1; J++) if (ee >= g[J].value && ee <= g[J + 1].value) {
122
+ B = g[J], fe = g[J + 1];
123
+ break;
231
124
  }
232
- const t = (val - lower.value) / (upper.value - lower.value || 1);
233
- const lowerRgb = hexToRgb(lower.color);
234
- const upperRgb = hexToRgb(upper.color);
235
- const rgb = lowerRgb.map((c, idx) => c * (1 - t) + upperRgb[idx] * t);
236
- const offset = i * 4;
237
- data[offset + 0] = Math.round(rgb[0]);
238
- data[offset + 1] = Math.round(rgb[1]);
239
- data[offset + 2] = Math.round(rgb[2]);
240
- data[offset + 3] = 255;
125
+ const Ae = (ee - B.value) / (fe.value - B.value || 1),
126
+ Pe = O(B.color),
127
+ xe = O(fe.color),
128
+ $e = Pe.map((J, Ge) => J * (1 - Ae) + xe[Ge] * Ae),
129
+ Te = _ * 4;
130
+ x[Te + 0] = Math.round($e[0]), x[Te + 1] = Math.round($e[1]), x[Te + 2] = Math.round($e[2]), x[Te + 3] = 255;
241
131
  }
242
- return data;
132
+ return x;
243
133
  };
244
- AguaceroCore.prototype.setMapCenter = function (center) {
245
- this.emit('map:move', center);
134
+ je.prototype.setMapCenter = function (m) {
135
+ this.emit("map:move", m);
246
136
  };
247
- export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
137
+ export const WeatherLayerManager = /*#__PURE__*/Tt((m, x) => {
248
138
  const {
249
- inspectorEnabled,
250
- onInspect,
251
- apiKey,
252
- customColormaps,
253
- initialMode,
254
- initialVariable,
255
- autoRefresh,
256
- autoRefreshInterval,
257
- initialModel,
258
- belowID: belowIDFromProps,
259
- interpolateNexradColormap = true,
260
- nexradGateSmoothing = false,
261
- watchesWarnings: watchesWarningsProp,
262
- onNwsAlertClick,
263
- /** Same semantics as mapsgl / AguaceroCore: Origin + Referer for grid CDN (required by many CloudFront rules). */
264
- gridRequestSiteOrigin,
265
- /** When true, logs auth/HTTP diagnostics under `[AguaceroRN][debug]` (Metro / Logcat / Xcode). */
266
- debug = false,
267
- ...restProps
268
- } = props;
269
- useEffect(() => {
270
- configureAguaceroRnDebug({
271
- enabled: Boolean(debug)
272
- });
273
- }, [debug]);
274
- const context = useContext(AguaceroContext);
275
-
276
- // Create the core here instead of getting it from context
277
- const core = useMemo(() => new AguaceroCore({
278
- apiKey: apiKey,
279
- customColormaps: customColormaps,
280
- gridRequestSiteOrigin: gridRequestSiteOrigin,
281
- layerOptions: {
282
- mode: initialMode,
283
- variable: initialVariable,
284
- model: initialModel
285
- },
286
- autoRefresh: false // <-- add this
287
- }), [apiKey, gridRequestSiteOrigin]);
288
- useEffect(() => {
289
- if (!core) return;
290
- installAguaceroCoreDebugHooks(core, {
291
- gridRequestSiteOriginProp: gridRequestSiteOrigin ?? null,
292
- debugProp: Boolean(debug)
139
+ inspectorEnabled: g,
140
+ onInspect: I,
141
+ apiKey: v,
142
+ customColormaps: O,
143
+ initialMode: _,
144
+ initialVariable: ee,
145
+ initialSatelliteId: B,
146
+ initialSatelliteSector: fe,
147
+ initialSatelliteProduct: Ae,
148
+ autoRefresh: Pe,
149
+ autoRefreshInterval: xe,
150
+ initialModel: $e,
151
+ belowID: Te,
152
+ watchesWarnings: J,
153
+ onNwsAlertClick: Ge,
154
+ gridRequestSiteOrigin: te,
155
+ debug: Ce = !1,
156
+ ...Ht
157
+ } = m;
158
+ j(() => {
159
+ Lt({
160
+ enabled: !!Ce
293
161
  });
294
- if (isAguaceroRnDebugEnabled() && !apiKey) {
295
- aguaceroDebugWarn('WeatherLayerManager.missingApiKey', {
296
- hint: 'apiKey prop is empty — all CDN requests will fail or return 403'
297
- });
298
- }
299
- if (isAguaceroRnDebugEnabled() && apiKey && !gridRequestSiteOrigin) {
300
- aguaceroDebugWarn('WeatherLayerManager.missingGridOrigin', {
301
- hint: 'gridRequestSiteOrigin is not set — CloudFront often returns 403 without Origin/Referer on React Native',
302
- snapshot: getAguaceroAuthDiagnosticSnapshot(core)
303
- });
304
- }
305
- }, [core, debug, gridRequestSiteOrigin, apiKey]);
306
- const [watchesWarningsOptions, setWatchesWarningsOptions] = useState(() => ({
307
- alertInteractionEnabled: true,
308
- ...(watchesWarningsProp ?? {})
162
+ }, [Ce]), j(() => {
163
+ if (Ce) return Ut({
164
+ core: t,
165
+ satelliteLayerRef: Ne
166
+ }), Et();
167
+ }, [Ce, t]);
168
+ const _e = Ct($t),
169
+ t = ut(() => new je({
170
+ apiKey: v,
171
+ customColormaps: O,
172
+ gridRequestSiteOrigin: te,
173
+ layerOptions: {
174
+ mode: _,
175
+ variable: ee,
176
+ model: $e,
177
+ ...(_ === "satellite" ? {
178
+ satelliteId: B,
179
+ sector: fe,
180
+ satelliteProduct: Ae ?? ee
181
+ } : {})
182
+ },
183
+ autoRefresh: !1
184
+ }), [v, te]);
185
+ j(() => {
186
+ t && (Vt(t, {
187
+ gridRequestSiteOriginProp: te ?? null,
188
+ debugProp: !!Ce
189
+ }), Ke() && !v && Ye("WeatherLayerManager.missingApiKey", {
190
+ hint: "apiKey prop is empty \u2014 all CDN requests will fail or return 403"
191
+ }), Ke() && v && !te && Ye("WeatherLayerManager.missingGridOrigin", {
192
+ hint: "gridRequestSiteOrigin is not set \u2014 CloudFront often returns 403 without Origin/Referer on React Native",
193
+ snapshot: ft(t)
194
+ }));
195
+ }, [t, Ce, te, v]);
196
+ const [gt, tt] = Je(() => ({
197
+ alertInteractionEnabled: !0,
198
+ ...(J ?? {})
309
199
  }));
310
- useEffect(() => {
311
- setWatchesWarningsOptions(prev => ({
312
- ...prev,
313
- ...(watchesWarningsProp ?? {})
200
+ j(() => {
201
+ tt(r => ({
202
+ ...r,
203
+ ...(J ?? {})
314
204
  }));
315
- }, [watchesWarningsProp]);
316
- useEffect(() => {
317
- setNexradSitesMapVisible(Boolean(core.state.isNexrad && core.state.nexradShowSitesPicker !== false));
318
- }, [core]);
319
- const gridLayerRef = useRef(null);
320
- const nexradLayerRef = useRef(null);
321
- const nexradControllerRef = useRef(null);
322
- /** Latest {@code state:change} payload (includes {@code colormap}, NEXRAD maps) — required for readouts; {@code core.state} omits those. */
323
- const lastEmittedStateForInspectRef = useRef(null);
324
- const satelliteLayerRef = useRef(null);
325
- const satelliteControllerRef = useRef(null);
326
- /** @type {React.MutableRefObject<{ cancel?: () => void } | null>} */
327
- const nexradPreloadInteractionRef = useRef(null);
328
- const currentGridDataRef = useRef(null);
329
- const autoRefreshIntervalId = useRef(null);
330
- const ensureNexradController = useCallback(() => {
331
- if (!NEXRAD_NATIVE) return null;
332
- if (!nexradControllerRef.current) {
333
- nexradControllerRef.current = new NexradAndroidController(core, nexradLayerRef, {
334
- interpolateNexradColormap,
335
- nexradGateSmoothing
336
- });
337
- }
338
- return nexradControllerRef.current;
339
- }, [core, interpolateNexradColormap, nexradGateSmoothing]);
340
-
341
- /** Synchronous NEXRAD readout (mapsgl-style); no await — avoids jank on map move. */
342
- const getNexradInspectPayloadAt = useCallback((lng, lat) => {
343
- if (!NEXRAD_NATIVE || !core?.state?.isNexrad) return null;
344
- const ctl = ensureNexradController();
345
- if (!ctl) {
346
- return null;
347
- }
348
- const emitted = lastEmittedStateForInspectRef.current;
349
- if (!emitted) {
350
- return null;
351
- }
352
- const st = mergeNexradEmittedWithCore(emitted, core.state);
353
- if (!st?.nexradSite || st.nexradTimestamp == null) {
354
- return null;
355
- }
356
- return ctl.getInspectPayload(lng, lat, st) ?? null;
357
- }, [core, ensureNexradController]);
358
- const ensureSatelliteController = useCallback(() => {
359
- if (!SATELLITE_NATIVE) return null;
360
- if (!satelliteControllerRef.current) {
361
- satelliteControllerRef.current = new SatelliteAndroidController(core, satelliteLayerRef);
362
- }
363
- return satelliteControllerRef.current;
364
- }, [core]);
365
- useEffect(() => {
366
- if (!SATELLITE_NATIVE) return;
367
- let gridCmdKeys = [];
368
- let satCmdKeys = [];
205
+ }, [J]), j(() => {
206
+ st(!!(t.state.isNexrad && t.state.nexradShowSitesPicker !== !1));
207
+ }, [t]);
208
+ const p = V(null),
209
+ rt = V(null),
210
+ X = V(null),
211
+ Ne = V(null),
212
+ re = V(null),
213
+ De = V(null),
214
+ me = V(null),
215
+ at = we(() => ie ? (re.current || (re.current = new Rt(t, Ne)), re.current) : null, [t]),
216
+ nt = we(() => !Q || !t ? null : (X.current || (X.current = new Ft(t, rt, {
217
+ interpolateNexradColormap: t.state?.shaderSmoothingEnabled !== !1
218
+ })), X.current), [t]),
219
+ ht = we(r => {
220
+ const {
221
+ colormap: a,
222
+ baseUnit: e
223
+ } = t._getColormapForVariable(r.variable),
224
+ o = t._getTargetUnit(e, r.units);
225
+ return {
226
+ ...r,
227
+ colormap: t._convertColormapUnits(a, e, o),
228
+ colormapBaseUnit: o
229
+ };
230
+ }, [t]),
231
+ Ie = we(r => {
232
+ if (!Q || !r?.isNexrad) return;
233
+ const a = nt();
234
+ a && (ae.current = !0, a.preloadAllAvailable(r), a.sync(r));
235
+ }, [nt]);
236
+ j(() => {
237
+ if (!Q || !t) return;
238
+ const r = wt(te, t),
239
+ a = At(() => ({
240
+ apiKey: t.apiKey,
241
+ bundleId: t.bundleId,
242
+ gridRequestSiteOrigin: r
243
+ }));
244
+ return dt(a), () => dt(null);
245
+ }, [t, te]), j(() => {
246
+ if (!ie) return;
247
+ let r = [],
248
+ a = [];
369
249
  try {
370
- gridCmdKeys = Object.keys(UIManager.getViewManagerConfig?.('GridRenderLayer')?.Commands ?? {});
250
+ r = Object.keys(mt.getViewManagerConfig?.("GridRenderLayer")?.Commands ?? {});
371
251
  } catch {
372
- gridCmdKeys = ['error'];
252
+ r = ["error"];
373
253
  }
374
254
  try {
375
- satCmdKeys = Object.keys(UIManager.getViewManagerConfig?.('SatelliteLayer')?.Commands ?? {});
255
+ a = Object.keys(mt.getViewManagerConfig?.("SatelliteLayer")?.Commands ?? {});
376
256
  } catch {
377
- satCmdKeys = ['error'];
257
+ a = ["error"];
378
258
  }
379
- satBridgeWarn('mount UIManager command registration', {
380
- GridRenderLayerCommands: gridCmdKeys,
381
- SatelliteLayerCommands: satCmdKeys,
382
- satelliteMissing: satCmdKeys.length === 0
259
+ Ee("mount UIManager command registration", {
260
+ GridRenderLayerCommands: r,
261
+ SatelliteLayerCommands: a,
262
+ satelliteMissing: a.length === 0
383
263
  });
384
264
  }, []);
385
- useEffect(() => {
386
- const ctl = nexradControllerRef.current;
387
- if (NEXRAD_NATIVE && ctl) {
388
- ctl.updateStyleOptions({
389
- interpolateNexradColormap,
390
- nexradGateSmoothing
391
- });
392
- if (core?.state?.isNexrad) {
393
- ctl.applyStyleFromState(core.state);
265
+ const W = V(new Map()),
266
+ pe = V(null),
267
+ ge = V(null),
268
+ ke = V([0, 1]),
269
+ ae = V(!1),
270
+ ne = V(!1),
271
+ Le = V(0),
272
+ He = V(null),
273
+ l = V(null),
274
+ [Ve, Me] = Je({
275
+ opacity: 1,
276
+ dataRange: [0, 1]
277
+ }),
278
+ [St, st] = Je(!1);
279
+ Mt(x, () => ({
280
+ play: () => {
281
+ t.play();
282
+ },
283
+ pause: () => {
284
+ t.pause();
285
+ },
286
+ togglePlay: () => {
287
+ t.togglePlay();
288
+ },
289
+ step: r => {
290
+ t.step(r);
291
+ },
292
+ setPlaybackSpeed: r => {
293
+ r > 0 && (t.playbackSpeed = r, t.isPlaying && (t.pause(), t.play()));
294
+ },
295
+ setOpacity: r => t.setOpacity(r),
296
+ setUnits: r => t.setUnits(r),
297
+ switchMode: r => t.switchMode(r),
298
+ getAvailableVariables: r => t.getAvailableVariables(r),
299
+ getVariableDisplayName: r => t.getVariableDisplayName(r),
300
+ setRun: r => t.setState({
301
+ run: r.split(":")[1]
302
+ }),
303
+ setState: r => t.setState(r),
304
+ setMRMSTimestamp: r => t.setMRMSTimestamp(r),
305
+ setMRMSDurationValue: r => qt(t, r),
306
+ setNexradSite: r => t.setNexradSite(r),
307
+ setNexradProduct: r => t.setNexradProduct(r),
308
+ setNexradTilt: r => t.setNexradTilt(r),
309
+ setNexradStormRelative: r => t.setNexradStormRelative(r),
310
+ setNexradTimestamp: r => t.setNexradTimestamp(r),
311
+ setNexradDurationValue: r => typeof t.setNexradDurationValue == "function" ? t.setNexradDurationValue(r) : t.setState({
312
+ nexradDurationValue: ct(r)
313
+ }),
314
+ setSatelliteTimestamp: r => t.setSatelliteTimestamp(r),
315
+ setSatelliteDurationValue: r => t.setSatelliteDurationValue(r),
316
+ setSatelliteSelection: r => t.setSatelliteSelection(r),
317
+ setShaderSmoothing: async r => {
318
+ await t.setShaderSmoothing(r), p.current && p.current.setSmoothing(r);
319
+ },
320
+ setSmoothing: r => {
321
+ p.current && p.current.setSmoothing(r);
322
+ },
323
+ setAutoRefresh: (r, a) => {
324
+ if (me.current && (clearInterval(me.current), me.current = null), r) {
325
+ const e = (a || xe || 30) * 1e3;
326
+ Se(), me.current = setInterval(Se, e);
394
327
  }
328
+ },
329
+ refreshData: () => {
330
+ Se();
331
+ },
332
+ configureWatchesWarnings: r => {
333
+ tt(a => ({
334
+ ...a,
335
+ ...r
336
+ }));
395
337
  }
396
- }, [interpolateNexradColormap, nexradGateSmoothing, core]);
397
-
398
- // Cache for preloaded grid data - stores the processed data ready for GPU upload
399
- const preloadedDataCache = useRef(new Map());
400
-
401
- // Store geometry and colormap that don't change with forecast hour
402
- const cachedGeometry = useRef(null);
403
- const cachedColormap = useRef(null);
404
- const cachedDataRange = useRef([0, 1]);
405
-
406
- // Track if we've done the initial load
407
- const hasInitialLoad = useRef(false);
408
- const hasPreloadedRef = useRef(false);
409
- /** Bumped on {@code cancelAllFrames} / full reload so stale {@code processFrame} results are ignored. */
410
- const preloadGenerationRef = useRef(0);
411
-
412
- // Track the last state we processed to avoid redundant updates
413
- const lastProcessedState = useRef(null);
414
- const previousStateRef = useRef(null);
415
- const [renderProps, setRenderProps] = useState({
416
- opacity: 1,
417
- dataRange: [0, 1]
418
- });
419
- /** Drives {@link NexradSitesMapLayer}; must re-render when core NEXRAD / picker flags change. */
420
- const [nexradSitesMapVisible, setNexradSitesMapVisible] = useState(false);
421
- useImperativeHandle(ref, () => {
422
- const setAutoRefresh = (enabled, intervalSeconds) => {
423
- if (autoRefreshIntervalId.current) {
424
- clearInterval(autoRefreshIntervalId.current);
425
- autoRefreshIntervalId.current = null;
426
- }
427
- if (enabled) {
428
- const effectiveInterval = (intervalSeconds || autoRefreshInterval || 30) * 1000;
429
- // Run once immediately, then start the interval
430
- _checkForUpdates();
431
- autoRefreshIntervalId.current = setInterval(_checkForUpdates, effectiveInterval);
432
- }
433
- };
434
- return {
435
- play: () => {
436
- core.play();
437
- },
438
- pause: () => {
439
- core.pause();
440
- },
441
- togglePlay: () => {
442
- core.togglePlay();
443
- },
444
- step: direction => {
445
- core.step(direction);
446
- },
447
- setPlaybackSpeed: speed => {
448
- if (speed > 0) {
449
- core.playbackSpeed = speed;
450
- if (core.isPlaying) {
451
- core.pause();
452
- core.play();
453
- }
454
- }
455
- },
456
- setOpacity: opacity => core.setOpacity(opacity),
457
- setUnits: units => core.setUnits(units),
458
- switchMode: options => core.switchMode(options),
459
- getAvailableVariables: model => core.getAvailableVariables(model),
460
- getVariableDisplayName: code => core.getVariableDisplayName(code),
461
- setRun: runString => core.setState({
462
- run: runString.split(':')[1]
463
- }),
464
- setState: newState => core.setState(newState),
465
- setMRMSTimestamp: timestamp => core.setMRMSTimestamp(timestamp),
466
- setMRMSDurationValue: value => applyMrmsDurationValue(core, value),
467
- setNexradSite: siteId => core.setNexradSite(siteId),
468
- setNexradProduct: product => core.setNexradProduct(product),
469
- setNexradTilt: tilt => core.setNexradTilt(tilt),
470
- setNexradStormRelative: enabled => core.setNexradStormRelative(enabled),
471
- setNexradTimestamp: ts => core.setNexradTimestamp(ts),
472
- setNexradDurationValue: value => applyNexradDurationValue(core, value),
473
- setSatelliteTimestamp: timestamp => core.setSatelliteTimestamp(timestamp),
474
- setSatelliteDurationValue: value => core.setSatelliteDurationValue(value),
475
- setSatelliteSelection: opts => core.setSatelliteSelection(opts),
476
- setShaderSmoothing: async enabled => {
477
- await core.setShaderSmoothing(enabled);
478
- if (gridLayerRef.current) {
479
- gridLayerRef.current.setSmoothing(enabled);
480
- }
481
- },
482
- setSmoothing: enabled => {
483
- if (gridLayerRef.current) {
484
- gridLayerRef.current.setSmoothing(enabled);
485
- }
486
- },
487
- setAutoRefresh,
488
- refreshData: () => {
489
- _checkForUpdates();
490
- },
491
- /**
492
- * NWS watches/warnings (native map, iOS + Android): same options as mapsgl {@link WeatherLayerManager#configureWatchesWarnings}.
493
- * @param {object} partial
494
- */
495
- configureWatchesWarnings: partial => {
496
- setWatchesWarningsOptions(prev => ({
497
- ...prev,
498
- ...partial
499
- }));
500
- }
501
- };
502
- }, [core, autoRefreshInterval, _checkForUpdates]);
503
- const preloadAllFramesToDisk = async state => {
504
- if (state.isNexrad || state.isSatellite) {
505
- hasPreloadedRef.current = false;
506
- wxGridVerbose('preloadSkip', {
507
- reason: 'nexrad_or_satellite'
338
+ }), [t, xe, Se]);
339
+ const it = async r => {
340
+ if (r.isNexrad || r.isSatellite) {
341
+ ne.current = !1, z("preloadSkip", {
342
+ reason: "nexrad_or_satellite"
508
343
  });
509
344
  return;
510
345
  }
511
- if (hasPreloadedRef.current) {
512
- wxGridVerbose('preloadSkip', {
513
- reason: 'hasPreloadedRef_gate',
514
- isMRMS: state.isMRMS,
515
- variable: state.variable
346
+ if (ne.current) {
347
+ z("preloadSkip", {
348
+ reason: "hasPreloadedRef_gate",
349
+ isMRMS: r.isMRMS,
350
+ variable: r.variable
516
351
  });
517
352
  return;
518
353
  }
519
354
  const {
520
- isMRMS,
521
- model,
522
- date,
523
- run,
524
- variable,
525
- units,
526
- availableHours,
527
- availableTimestamps,
528
- forecastHour,
529
- mrmsTimestamp
530
- } = state;
531
-
532
- // CRITICAL: Don't start preloading if we don't have a valid current frame
533
- if (isMRMS && (mrmsTimestamp == null || !availableTimestamps || availableTimestamps.length === 0)) {
534
- hasPreloadedRef.current = false;
535
- wxGridWarn('preloadAbort', {
536
- reason: 'mrms_missing_frame_or_timestamps',
537
- mrmsTimestamp,
538
- timestampCount: availableTimestamps?.length ?? 0,
539
- variable
355
+ isMRMS: a,
356
+ model: e,
357
+ date: o,
358
+ run: F,
359
+ variable: s,
360
+ units: w,
361
+ availableHours: N,
362
+ availableTimestamps: c,
363
+ forecastHour: i,
364
+ mrmsTimestamp: u
365
+ } = r;
366
+ if (a && (u == null || !c || c.length === 0)) {
367
+ ne.current = !1, Z("preloadAbort", {
368
+ reason: "mrms_missing_frame_or_timestamps",
369
+ mrmsTimestamp: u,
370
+ timestampCount: c?.length ?? 0,
371
+ variable: s
540
372
  });
541
373
  return;
542
374
  }
543
- if (!isMRMS && (forecastHour == null || !availableHours || availableHours.length === 0)) {
544
- hasPreloadedRef.current = false;
545
- wxGridWarn('preloadAbort', {
546
- reason: 'model_missing_hour_or_hours',
547
- forecastHour,
548
- hourCount: availableHours?.length ?? 0,
549
- model,
550
- variable
375
+ if (!a && (i == null || !N || N.length === 0)) {
376
+ ne.current = !1, Z("preloadAbort", {
377
+ reason: "model_missing_hour_or_hours",
378
+ forecastHour: i,
379
+ hourCount: N?.length ?? 0,
380
+ model: e,
381
+ variable: s
551
382
  });
552
383
  return;
553
384
  }
554
-
555
- // Only mark as "has preloaded" after validation passes
556
- hasPreloadedRef.current = true;
557
- const generation = preloadGenerationRef.current;
558
- const isStaleGeneration = () => generation !== preloadGenerationRef.current;
559
- wxGridVerbose('preloadStart', {
560
- isMRMS,
561
- model,
562
- date,
563
- run,
564
- variable,
565
- mrmsTimestamp: isMRMS ? mrmsTimestamp : undefined,
566
- forecastHour: !isMRMS ? forecastHour : undefined,
567
- baseGridUrl: core?.baseGridUrl,
568
- hasApiKey: Boolean(core?.apiKey),
569
- bundleId: core?.bundleId ?? null,
570
- gridRequestSiteOrigin: gridRequestSiteOrigin || null
385
+ ne.current = !0;
386
+ const A = Le.current,
387
+ y = () => A !== Le.current;
388
+ z("preloadStart", {
389
+ isMRMS: a,
390
+ model: e,
391
+ date: o,
392
+ run: F,
393
+ variable: s,
394
+ mrmsTimestamp: a ? u : void 0,
395
+ forecastHour: a ? void 0 : i,
396
+ baseGridUrl: t?.baseGridUrl,
397
+ hasApiKey: !!t?.apiKey,
398
+ bundleId: t?.bundleId ?? null,
399
+ gridRequestSiteOrigin: te || null
571
400
  });
572
-
573
- // Fix the current forecast hour if it's invalid for this variable/model combo
574
- let effectiveForecastHour = forecastHour;
575
- if (!isMRMS && variable === 'ptypeRefl' && model === 'hrrr' && forecastHour === 0) {
576
- const validHours = availableHours.filter(hour => hour !== 0);
577
- effectiveForecastHour = validHours.length > 0 ? validHours[0] : 0;
401
+ let M = i;
402
+ if (!a && s === "ptypeRefl" && e === "hrrr" && i === 0) {
403
+ const d = N.filter(G => G !== 0);
404
+ M = d.length > 0 ? d[0] : 0;
578
405
  }
579
- if (!cachedGeometry.current || !cachedColormap.current) {
580
- const gridModel = isMRMS ? 'mrms' : model;
581
- const {
582
- corners,
583
- gridDef
584
- } = core._getGridCornersAndDef(gridModel);
585
- gridLayerRef.current.updateGeometry(corners, gridDef);
586
- cachedGeometry.current = {
587
- model: gridModel,
588
- variable
589
- };
590
- wxGridVerbose('geometryColormapInit', {
591
- gridModel,
592
- variable,
593
- nx: gridDef?.grid_params?.nx,
594
- ny: gridDef?.grid_params?.ny
406
+ if (!pe.current || !ge.current) {
407
+ const d = a ? "mrms" : e,
408
+ {
409
+ corners: G,
410
+ gridDef: n
411
+ } = t._getGridCornersAndDef(d);
412
+ p.current.updateGeometry(G, n), pe.current = {
413
+ model: d,
414
+ variable: s
415
+ }, z("geometryColormapInit", {
416
+ gridModel: d,
417
+ variable: s,
418
+ nx: n?.grid_params?.nx,
419
+ ny: n?.grid_params?.ny
595
420
  });
596
421
  const {
597
- colormap,
598
- baseUnit
599
- } = core._getColormapForVariable(variable);
600
- const toUnit = core._getTargetUnit(baseUnit, units);
601
- const finalColormap = core._convertColormapUnits(colormap, baseUnit, toUnit);
602
- let dataRange;
603
- if (variable === 'ptypeRefl' || variable === 'ptypeRate') {
604
- dataRange = isMRMS ? [5, 380] : [5, 380];
605
- } else {
606
- dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
607
- }
608
- const colormapBytes = _generateColormapBytes(finalColormap);
609
- const colormapAsBase64 = fromByteArray(colormapBytes);
610
- gridLayerRef.current.updateColormapTexture(colormapAsBase64);
611
- cachedColormap.current = {
612
- key: `${variable}-${units}`
613
- };
614
- cachedDataRange.current = dataRange;
615
- setRenderProps({
616
- opacity: state.opacity,
617
- dataRange: dataRange
618
- });
619
- hasInitialLoad.current = true;
422
+ colormap: R,
423
+ baseUnit: h
424
+ } = t._getColormapForVariable(s),
425
+ k = t._getTargetUnit(h, w),
426
+ P = t._convertColormapUnits(R, h, k);
427
+ let f;
428
+ s === "ptypeRefl" || s === "ptypeRate" ? f = a ? [5, 380] : [5, 380] : f = [P[0], P[P.length - 2]];
429
+ const C = et(P),
430
+ b = ze(C);
431
+ p.current.updateColormapTexture(b), ge.current = {
432
+ key: `${s}-${w}`
433
+ }, ke.current = f, Me({
434
+ opacity: r.opacity,
435
+ dataRange: f
436
+ }), ae.current = !0;
620
437
  }
621
-
622
- // Apply the same filtering logic as in AguaceroCore._emitStateChange
623
- let filteredHours = availableHours;
624
- if (!isMRMS && variable === 'ptypeRefl' && model === 'hrrr' && availableHours && availableHours.length > 0) {
625
- filteredHours = availableHours.filter(hour => hour !== 0);
626
- }
627
- const allFrames = isMRMS ? availableTimestamps : filteredHours;
628
- if (!allFrames || allFrames.length === 0) {
629
- hasPreloadedRef.current = false;
630
- wxGridWarn('preloadAbort', {
631
- reason: 'no_frames_after_filter',
632
- isMRMS,
633
- variable
438
+ let U = N;
439
+ !a && s === "ptypeRefl" && e === "hrrr" && N && N.length > 0 && (U = N.filter(d => d !== 0));
440
+ const E = a ? c : U;
441
+ if (!E || E.length === 0) {
442
+ ne.current = !1, Z("preloadAbort", {
443
+ reason: "no_frames_after_filter",
444
+ isMRMS: a,
445
+ variable: s
634
446
  });
635
447
  return;
636
448
  }
637
- const currentFrame = isMRMS ? mrmsTimestamp : effectiveForecastHour;
638
-
639
- // Double-check currentFrame is valid
640
- if (currentFrame == null) {
641
- hasPreloadedRef.current = false;
642
- wxGridWarn('preloadAbort', {
643
- reason: 'currentFrame_null',
644
- isMRMS,
645
- variable
449
+ const K = a ? u : M;
450
+ if (K == null) {
451
+ ne.current = !1, Z("preloadAbort", {
452
+ reason: "currentFrame_null",
453
+ isMRMS: a,
454
+ variable: s
646
455
  });
647
456
  return;
648
457
  }
649
-
650
- // Reverse the frame order to load from last to first
651
- const reversedFrames = [...allFrames].reverse();
652
- const framesToPreload = reversedFrames.filter(frame => frame !== currentFrame);
653
- const {
654
- corners,
655
- gridDef
656
- } = core._getGridCornersAndDef(isMRMS ? 'mrms' : model);
657
- const {
658
- nx,
659
- ny
660
- } = gridDef.grid_params;
661
-
662
- // Load the current frame FIRST and WAIT for it before continuing
663
- const currentCacheKey = isMRMS ? `mrms-${currentFrame}-${variable}` : `${model}-${date}-${run}-${currentFrame}-${variable}`;
664
- if (!preloadedDataCache.current.has(currentCacheKey)) {
665
- let resourcePath;
666
- if (isMRMS) {
667
- const frameDate = new Date(currentFrame * 1000);
668
- const y = frameDate.getUTCFullYear();
669
- const m = (frameDate.getUTCMonth() + 1).toString().padStart(2, '0');
670
- const d = frameDate.getUTCDate().toString().padStart(2, '0');
671
- resourcePath = `/grids/mrms/${y}${m}${d}/${currentFrame}/0/${variable}/0`;
672
- } else {
673
- resourcePath = `/grids/${model}/${date}/${run}/${currentFrame}/${variable}/0`;
674
- }
675
- const options = augmentProcessFrameOptionsForDebug(buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin, core), core);
676
- logProcessFrameAuthMismatch(core, options, {
677
- phase: 'preloadCurrent',
678
- currentCacheKey
458
+ const Y = [...E].reverse().filter(d => d !== K),
459
+ {
460
+ corners: D,
461
+ gridDef: q
462
+ } = t._getGridCornersAndDef(a ? "mrms" : e),
463
+ {
464
+ nx: de,
465
+ ny: ye
466
+ } = q.grid_params,
467
+ $ = a ? `mrms-${K}-${s}` : `${e}-${o}-${F}-${K}-${s}`;
468
+ if (!W.current.has($)) {
469
+ let d;
470
+ if (a) {
471
+ const n = new Date(K * 1e3),
472
+ R = n.getUTCFullYear(),
473
+ h = (n.getUTCMonth() + 1).toString().padStart(2, "0"),
474
+ k = n.getUTCDate().toString().padStart(2, "0");
475
+ d = `/grids/mrms/${R}${h}${k}/${K}/0/${s}/0`;
476
+ } else d = `/grids/${e}/${o}/${F}/${K}/${s}/0`;
477
+ const G = Xe(Ze(t.baseGridUrl, d, t.apiKey, t.bundleId, te, t), t);
478
+ Qe(t, G, {
479
+ phase: "preloadCurrent",
480
+ currentCacheKey: $
679
481
  });
680
482
  try {
681
- wxGridVerbose('processFrameRequest', {
682
- currentCacheKey,
683
- resourcePath,
684
- frame: currentFrame
483
+ z("processFrameRequest", {
484
+ currentCacheKey: $,
485
+ resourcePath: d,
486
+ frame: K
685
487
  });
686
- const result = await WeatherFrameProcessorModule.processFrame(options);
687
- if (isStaleGeneration()) {
688
- wxGridVerbose('preloadCurrentFrameStale', {
689
- currentCacheKey,
690
- generation
488
+ const n = await qe.processFrame(G);
489
+ if (y()) {
490
+ z("preloadCurrentFrameStale", {
491
+ currentCacheKey: $,
492
+ generation: A
691
493
  });
692
494
  return;
693
495
  }
694
- if (!result || !result.filePath) {
695
- hasPreloadedRef.current = false;
696
- wxGridWarn('preloadAbort', {
697
- reason: 'processFrame_empty_result',
698
- currentCacheKey,
699
- resultKeys: result ? Object.keys(result) : []
496
+ if (!n || !n.filePath) {
497
+ ne.current = !1, Z("preloadAbort", {
498
+ reason: "processFrame_empty_result",
499
+ currentCacheKey: $,
500
+ resultKeys: n ? Object.keys(n) : []
700
501
  });
701
502
  return;
702
503
  }
703
504
  const {
704
- baseUnit
705
- } = core._getColormapForVariable(variable);
706
- const toUnit = core._getTargetUnit(baseUnit, units);
707
- const fieldInfo = DICTIONARIES?.fld?.[variable] || {};
708
- const serverDataUnit = fieldInfo.defaultUnit || baseUnit;
709
- let dataScale = result.scale;
710
- let dataOffset = result.offset;
711
- let convertedScale = dataScale;
712
- let convertedOffset = dataOffset;
713
- if (serverDataUnit !== baseUnit) {
714
- const conversionFunc = getUnitConversionFunction(serverDataUnit, baseUnit);
715
- if (conversionFunc) {
716
- if (result.scaleType === 'sqrt') {
717
- const physicalAtOffset = dataOffset * dataOffset;
718
- const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
719
- const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
720
- const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
721
- convertedOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
722
- const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
723
- convertedScale = newOffsetPlusScale - convertedOffset;
724
- } else {
725
- convertedOffset = conversionFunc(dataOffset);
726
- const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
727
- convertedScale = convertedOffsetPlusScale - convertedOffset;
728
- }
729
- dataScale = convertedScale;
730
- dataOffset = convertedOffset;
505
+ baseUnit: R
506
+ } = t._getColormapForVariable(s),
507
+ h = t._getTargetUnit(R, w),
508
+ k = (Be?.fld?.[s] || {}).defaultUnit || R;
509
+ let P = n.scale,
510
+ f = n.offset,
511
+ C = P,
512
+ b = f;
513
+ if (k !== R) {
514
+ const T = ve(k, R);
515
+ if (T) {
516
+ if (n.scaleType === "sqrt") {
517
+ const L = f * f,
518
+ H = (f + P) * (f + P),
519
+ oe = T(L),
520
+ ce = T(H);
521
+ b = Math.sqrt(Math.abs(oe)) * Math.sign(oe), C = Math.sqrt(Math.abs(ce)) * Math.sign(ce) - b;
522
+ } else b = T(f), C = T(f + P) - b;
523
+ P = C, f = b;
731
524
  }
732
525
  }
733
- if (baseUnit !== toUnit) {
734
- const conversionFunc = getUnitConversionFunction(baseUnit, toUnit);
735
- if (conversionFunc) {
736
- if (result.scaleType === 'sqrt') {
737
- const physicalAtOffset = dataOffset * dataOffset;
738
- const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
739
- const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
740
- const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
741
- convertedOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
742
- const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
743
- convertedScale = newOffsetPlusScale - convertedOffset;
744
- } else {
745
- convertedOffset = conversionFunc(dataOffset);
746
- const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
747
- convertedScale = convertedOffsetPlusScale - convertedOffset;
748
- }
749
- }
526
+ if (R !== h) {
527
+ const T = ve(R, h);
528
+ if (T) if (n.scaleType === "sqrt") {
529
+ const L = f * f,
530
+ H = (f + P) * (f + P),
531
+ oe = T(L),
532
+ ce = T(H);
533
+ b = Math.sqrt(Math.abs(oe)) * Math.sign(oe), C = Math.sqrt(Math.abs(ce)) * Math.sign(ce) - b;
534
+ } else b = T(f), C = T(f + P) - b;
750
535
  }
751
- const frameData = {
752
- filePath: result.filePath,
753
- nx,
754
- ny,
755
- scale: convertedScale,
756
- offset: convertedOffset,
757
- missing: result.missing,
758
- corners,
759
- gridDef,
760
- scaleType: result.scaleType,
761
- originalScale: result.scale,
762
- originalOffset: result.offset
763
- };
764
- preloadedDataCache.current.set(currentCacheKey, frameData);
765
-
766
- // Update the GPU with the current frame
767
- gridLayerRef.current.updateDataTextureFromFile(frameData.filePath, frameData.nx, frameData.ny, frameData.scale, frameData.offset, frameData.missing, frameData.scaleType);
768
- currentGridDataRef.current = {
769
- nx: frameData.nx,
770
- ny: frameData.ny,
771
- scale: frameData.scale,
772
- offset: frameData.offset,
773
- missing: frameData.missing,
774
- gridDef: frameData.gridDef,
775
- variable: variable,
776
- units: units,
777
- scaleType: frameData.scaleType
536
+ const S = {
537
+ filePath: n.filePath,
538
+ nx: de,
539
+ ny: ye,
540
+ scale: C,
541
+ offset: b,
542
+ missing: n.missing,
543
+ corners: D,
544
+ gridDef: q,
545
+ scaleType: n.scaleType,
546
+ originalScale: n.scale,
547
+ originalOffset: n.offset
778
548
  };
779
- wxGridVerbose('preloadCurrentFrameOk', {
780
- currentCacheKey,
781
- nx: frameData.nx,
782
- ny: frameData.ny,
783
- scale: frameData.scale,
784
- offset: frameData.offset,
785
- filePathSuffix: String(frameData.filePath).split('/').pop()
549
+ W.current.set($, S), p.current.updateDataTextureFromFile(S.filePath, S.nx, S.ny, S.scale, S.offset, S.missing, S.scaleType), De.current = {
550
+ nx: S.nx,
551
+ ny: S.ny,
552
+ scale: S.scale,
553
+ offset: S.offset,
554
+ missing: S.missing,
555
+ gridDef: S.gridDef,
556
+ variable: s,
557
+ units: w,
558
+ scaleType: S.scaleType
559
+ }, z("preloadCurrentFrameOk", {
560
+ currentCacheKey: $,
561
+ nx: S.nx,
562
+ ny: S.ny,
563
+ scale: S.scale,
564
+ offset: S.offset,
565
+ filePathSuffix: String(S.filePath).split("/").pop()
786
566
  });
787
- } catch (e) {
788
- const cancelled = e && (e.code === 'E_CANCELLED' || e?.userInfo?.code === 'E_CANCELLED' || typeof e?.message === 'string' && e.message.includes('superseded'));
789
- if (!cancelled) {
790
- hasPreloadedRef.current = false;
791
- const errDetail = {
792
- currentCacheKey,
793
- code: e?.code,
794
- message: e?.message,
795
- userInfo: e?.userInfo
567
+ } catch (n) {
568
+ if (n && (n.code === "E_CANCELLED" || n?.userInfo?.code === "E_CANCELLED" || typeof n?.message == "string" && n.message.includes("superseded"))) z("preloadProcessFrameCancelled", {
569
+ currentCacheKey: $
570
+ });else {
571
+ ne.current = !1;
572
+ const R = {
573
+ currentCacheKey: $,
574
+ code: n?.code,
575
+ message: n?.message,
576
+ userInfo: n?.userInfo
796
577
  };
797
- wxGridWarn('preloadProcessFrameError', errDetail);
798
- if (isAguaceroRnDebugEnabled()) {
799
- aguaceroDebugWarn('preloadProcessFrameError', {
800
- ...errDetail,
801
- auth: getAguaceroAuthDiagnosticSnapshot(core),
802
- is403: e?.code === 'HTTP_ERROR' && typeof e?.message === 'string' && e.message.includes('403')
803
- });
804
- }
805
- } else {
806
- wxGridVerbose('preloadProcessFrameCancelled', {
807
- currentCacheKey
578
+ Z("preloadProcessFrameError", R), Ke() && Ye("preloadProcessFrameError", {
579
+ ...R,
580
+ auth: ft(t),
581
+ is403: n?.code === "HTTP_ERROR" && typeof n?.message == "string" && n.message.includes("403")
808
582
  });
809
583
  }
810
584
  }
811
585
  }
812
-
813
- // NOW preload the rest of the frames asynchronously
814
- framesToPreload.forEach(frame => {
815
- const cacheKey = isMRMS ? `mrms-${frame}-${variable}` : `${model}-${date}-${run}-${frame}-${variable}`;
816
- if (preloadedDataCache.current.has(cacheKey)) {
817
- return;
818
- }
819
- let resourcePath;
820
- if (isMRMS) {
821
- const frameDate = new Date(frame * 1000);
822
- const y = frameDate.getUTCFullYear();
823
- const m = (frameDate.getUTCMonth() + 1).toString().padStart(2, '0');
824
- const d = frameDate.getUTCDate().toString().padStart(2, '0');
825
- resourcePath = `/grids/mrms/${y}${m}${d}/${frame}/0/${variable}/0`;
826
- } else {
827
- resourcePath = `/grids/${model}/${date}/${run}/${frame}/${variable}/0`;
828
- }
829
- const options = augmentProcessFrameOptionsForDebug(buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin, core), core);
830
- logProcessFrameAuthMismatch(core, options, {
831
- phase: 'preloadBackground',
832
- cacheKey
833
- });
834
- WeatherFrameProcessorModule.processFrame(options).then(result => {
835
- if (isStaleGeneration()) {
836
- return;
837
- }
838
- if (!result || !result.filePath) {
839
- return;
840
- }
841
-
842
- // ADD: Same two-step conversion as the current frame
586
+ Y.forEach(d => {
587
+ const G = a ? `mrms-${d}-${s}` : `${e}-${o}-${F}-${d}-${s}`;
588
+ if (W.current.has(G)) return;
589
+ let n;
590
+ if (a) {
591
+ const h = new Date(d * 1e3),
592
+ k = h.getUTCFullYear(),
593
+ P = (h.getUTCMonth() + 1).toString().padStart(2, "0"),
594
+ f = h.getUTCDate().toString().padStart(2, "0");
595
+ n = `/grids/mrms/${k}${P}${f}/${d}/0/${s}/0`;
596
+ } else n = `/grids/${e}/${o}/${F}/${d}/${s}/0`;
597
+ const R = Xe(Ze(t.baseGridUrl, n, t.apiKey, t.bundleId, te, t), t);
598
+ Qe(t, R, {
599
+ phase: "preloadBackground",
600
+ cacheKey: G
601
+ }), qe.processFrame(R).then(h => {
602
+ if (y() || !h || !h.filePath) return;
843
603
  const {
844
- baseUnit
845
- } = core._getColormapForVariable(variable);
846
- const toUnit = core._getTargetUnit(baseUnit, units);
847
- const fieldInfo = DICTIONARIES?.fld?.[variable] || {};
848
- const serverDataUnit = fieldInfo.defaultUnit || baseUnit;
849
- let dataScale = result.scale;
850
- let dataOffset = result.offset;
851
- let convertedScale = dataScale;
852
- let convertedOffset = dataOffset;
853
-
854
- // Step 1: Convert from server unit to colormap base unit
855
- if (serverDataUnit !== baseUnit) {
856
- const conversionFunc = getUnitConversionFunction(serverDataUnit, baseUnit);
857
- if (conversionFunc) {
858
- if (result.scaleType === 'sqrt') {
859
- const physicalAtOffset = dataOffset * dataOffset;
860
- const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
861
- const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
862
- const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
863
- convertedOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
864
- const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
865
- convertedScale = newOffsetPlusScale - convertedOffset;
866
- } else {
867
- convertedOffset = conversionFunc(dataOffset);
868
- const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
869
- convertedScale = convertedOffsetPlusScale - convertedOffset;
870
- }
871
- dataScale = convertedScale;
872
- dataOffset = convertedOffset;
604
+ baseUnit: k
605
+ } = t._getColormapForVariable(s),
606
+ P = t._getTargetUnit(k, w),
607
+ f = (Be?.fld?.[s] || {}).defaultUnit || k;
608
+ let C = h.scale,
609
+ b = h.offset,
610
+ S = C,
611
+ T = b;
612
+ if (f !== k) {
613
+ const H = ve(f, k);
614
+ if (H) {
615
+ if (h.scaleType === "sqrt") {
616
+ const oe = b * b,
617
+ ce = (b + C) * (b + C),
618
+ Re = H(oe),
619
+ Fe = H(ce);
620
+ T = Math.sqrt(Math.abs(Re)) * Math.sign(Re), S = Math.sqrt(Math.abs(Fe)) * Math.sign(Fe) - T;
621
+ } else T = H(b), S = H(b + C) - T;
622
+ C = S, b = T;
873
623
  }
874
624
  }
875
-
876
- // Step 2: Convert from colormap base unit to target display unit
877
- if (baseUnit !== toUnit) {
878
- const conversionFunc = getUnitConversionFunction(baseUnit, toUnit);
879
- if (conversionFunc) {
880
- if (result.scaleType === 'sqrt') {
881
- const physicalAtOffset = dataOffset * dataOffset;
882
- const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
883
- const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
884
- const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
885
- convertedOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
886
- const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
887
- convertedScale = newOffsetPlusScale - convertedOffset;
888
- } else {
889
- convertedOffset = conversionFunc(dataOffset);
890
- const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
891
- convertedScale = convertedOffsetPlusScale - convertedOffset;
892
- }
893
- }
625
+ if (k !== P) {
626
+ const H = ve(k, P);
627
+ if (H) if (h.scaleType === "sqrt") {
628
+ const oe = b * b,
629
+ ce = (b + C) * (b + C),
630
+ Re = H(oe),
631
+ Fe = H(ce);
632
+ T = Math.sqrt(Math.abs(Re)) * Math.sign(Re), S = Math.sqrt(Math.abs(Fe)) * Math.sign(Fe) - T;
633
+ } else T = H(b), S = H(b + C) - T;
894
634
  }
895
- const frameData = {
896
- filePath: result.filePath,
897
- nx,
898
- ny,
899
- scale: convertedScale,
900
- offset: convertedOffset,
901
- missing: result.missing,
902
- corners,
903
- gridDef,
904
- scaleType: result.scaleType,
905
- originalScale: result.scale,
906
- originalOffset: result.offset
635
+ const L = {
636
+ filePath: h.filePath,
637
+ nx: de,
638
+ ny: ye,
639
+ scale: S,
640
+ offset: T,
641
+ missing: h.missing,
642
+ corners: D,
643
+ gridDef: q,
644
+ scaleType: h.scaleType,
645
+ originalScale: h.scale,
646
+ originalOffset: h.offset
907
647
  };
908
- preloadedDataCache.current.set(cacheKey, frameData);
909
- if (Platform.OS === 'ios' && gridLayerRef.current.primeGpuCache) {
910
- const frameInfoForGpu = {
911
- [cacheKey]: {
912
- filePath: frameData.filePath,
913
- nx: frameData.nx,
914
- ny: frameData.ny,
915
- scale: frameData.scale,
916
- offset: frameData.offset,
917
- missing: frameData.missing,
918
- scaleType: frameData.scaleType || 'linear',
919
- originalScale: frameData.originalScale,
920
- originalOffset: frameData.originalOffset
648
+ if (W.current.set(G, L), se.OS === "ios" && p.current.primeGpuCache) {
649
+ const H = {
650
+ [G]: {
651
+ filePath: L.filePath,
652
+ nx: L.nx,
653
+ ny: L.ny,
654
+ scale: L.scale,
655
+ offset: L.offset,
656
+ missing: L.missing,
657
+ scaleType: L.scaleType || "linear",
658
+ originalScale: L.originalScale,
659
+ originalOffset: L.originalOffset
921
660
  }
922
661
  };
923
- gridLayerRef.current.primeGpuCache(frameInfoForGpu);
924
- }
925
- }).catch(e => {
926
- const cancelled = e && (e.code === 'E_CANCELLED' || e?.userInfo?.code === 'E_CANCELLED' || typeof e?.message === 'string' && e.message.includes('superseded'));
927
- if (!cancelled) {
928
- wxGridWarn('backgroundFrameError', {
929
- cacheKey,
930
- code: e?.code,
931
- message: e?.message
932
- });
662
+ p.current.primeGpuCache(H);
933
663
  }
664
+ }).catch(h => {
665
+ h && (h.code === "E_CANCELLED" || h?.userInfo?.code === "E_CANCELLED" || typeof h?.message == "string" && h.message.includes("superseded")) || Z("backgroundFrameError", {
666
+ cacheKey: G,
667
+ code: h?.code,
668
+ message: h?.message
669
+ });
934
670
  });
935
671
  });
936
672
  };
937
- useEffect(() => {
938
- // This effect manages the auto-refresh based on props
939
- if (autoRefresh) {
940
- const interval = (autoRefreshInterval || 30) * 1000;
941
- _checkForUpdates(); // Run immediately on enable
942
- autoRefreshIntervalId.current = setInterval(_checkForUpdates, interval);
673
+ j(() => {
674
+ if (Pe) {
675
+ const r = (xe || 30) * 1e3;
676
+ Se(), me.current = setInterval(Se, r);
943
677
  }
944
-
945
- // Cleanup function: this runs when the component unmounts or props change
946
678
  return () => {
947
- if (autoRefreshIntervalId.current) {
948
- clearInterval(autoRefreshIntervalId.current);
949
- autoRefreshIntervalId.current = null;
950
- }
679
+ me.current && (clearInterval(me.current), me.current = null);
951
680
  };
952
- }, [autoRefresh, autoRefreshInterval, _checkForUpdates]);
953
- const updateGPUWithCachedData = state => {
954
- const {
955
- model,
956
- date,
957
- run,
958
- forecastHour,
959
- variable,
960
- units,
961
- isMRMS,
962
- mrmsTimestamp
963
- } = state;
964
- const cacheKey = isMRMS ? `mrms-${mrmsTimestamp}-${variable}` : `${model}-${date}-${run}-${forecastHour}-${variable}`;
965
- if (Platform.OS === 'ios' && gridLayerRef.current.setActiveFrame) {
966
- // Get the cached data BEFORE calling setActiveFrame
967
- const cachedData = preloadedDataCache.current.get(cacheKey);
968
- if (cachedData) {
969
- currentGridDataRef.current = {
970
- nx: cachedData.nx,
971
- ny: cachedData.ny,
972
- scale: cachedData.scale,
973
- offset: cachedData.offset,
974
- missing: cachedData.missing,
975
- gridDef: cachedData.gridDef,
976
- variable: variable,
977
- units: units,
978
- scaleType: cachedData.scaleType
979
- };
980
- } else {
981
- wxGridVerbose('gpuIOS_setActiveFrame_no_row', {
982
- cacheKey,
983
- cacheSize: preloadedDataCache.current.size
984
- });
985
- }
986
- gridLayerRef.current.setActiveFrame(cacheKey);
987
- wxGridVerbose('gpuIOS_setActiveFrame', {
988
- cacheKey,
989
- hadCachedRow: Boolean(cachedData)
990
- });
991
- return true;
992
- }
993
- const cachedData = preloadedDataCache.current.get(cacheKey);
994
- if (!cachedData) {
995
- wxGridWarn('updateGPUNoCache', {
996
- cacheKey,
997
- cacheSize: preloadedDataCache.current.size,
998
- sampleKeys: Array.from(preloadedDataCache.current.keys()).slice(0, 5)
999
- });
1000
- return false;
1001
- }
1002
- if (!gridLayerRef.current) {
1003
- wxGridWarn('updateGPUNoGridLayerRef', {
1004
- cacheKey
1005
- });
1006
- return false;
1007
- }
1008
- if (!cachedGeometry.current || cachedGeometry.current.model !== (isMRMS ? 'mrms' : model) || cachedGeometry.current.variable !== variable) {
1009
- gridLayerRef.current.updateGeometry(cachedData.corners, cachedData.gridDef);
1010
- cachedGeometry.current = {
1011
- model: isMRMS ? 'mrms' : model,
1012
- variable
1013
- };
1014
- }
1015
- const colormapKey = `${variable}-${units}`;
1016
- if (!cachedColormap.current || cachedColormap.current.key !== colormapKey) {
681
+ }, [Pe, xe, Se]);
682
+ const yt = r => {
1017
683
  const {
1018
- colormap,
1019
- baseUnit
1020
- } = core._getColormapForVariable(variable);
1021
- const toUnit = core._getTargetUnit(baseUnit, units);
1022
- const finalColormap = core._convertColormapUnits(colormap, baseUnit, toUnit);
1023
- let dataRange;
1024
- if (variable === 'ptypeRefl' || variable === 'ptypeRate') {
1025
- if (isMRMS) {
1026
- dataRange = [5, 380];
1027
- } else {
1028
- dataRange = [5, 380];
1029
- }
1030
- } else {
1031
- dataRange = [finalColormap[0], finalColormap[finalColormap.length - 2]];
684
+ model: a,
685
+ date: e,
686
+ run: o,
687
+ forecastHour: F,
688
+ variable: s,
689
+ units: w,
690
+ isMRMS: N,
691
+ mrmsTimestamp: c
692
+ } = r,
693
+ i = N ? `mrms-${c}-${s}` : `${a}-${e}-${o}-${F}-${s}`;
694
+ if (se.OS === "ios" && p.current.setActiveFrame) {
695
+ const y = W.current.get(i);
696
+ return y ? De.current = {
697
+ nx: y.nx,
698
+ ny: y.ny,
699
+ scale: y.scale,
700
+ offset: y.offset,
701
+ missing: y.missing,
702
+ gridDef: y.gridDef,
703
+ variable: s,
704
+ units: w,
705
+ scaleType: y.scaleType
706
+ } : z("gpuIOS_setActiveFrame_no_row", {
707
+ cacheKey: i,
708
+ cacheSize: W.current.size
709
+ }), p.current.setActiveFrame(i), z("gpuIOS_setActiveFrame", {
710
+ cacheKey: i,
711
+ hadCachedRow: !!y
712
+ }), !0;
1032
713
  }
1033
- const colormapBytes = _generateColormapBytes(finalColormap);
1034
- const colormapAsBase64 = fromByteArray(colormapBytes);
1035
- gridLayerRef.current.updateColormapTexture(colormapAsBase64);
1036
- cachedColormap.current = {
1037
- key: colormapKey
1038
- };
1039
- cachedDataRange.current = dataRange;
1040
- setRenderProps(prev => ({
1041
- ...prev,
1042
- dataRange
1043
- }));
1044
- }
1045
- if (cachedData.filePath) {
1046
- gridLayerRef.current.updateDataTextureFromFile(cachedData.filePath, cachedData.nx, cachedData.ny, cachedData.scale, cachedData.offset, cachedData.missing, cachedData.scaleType);
1047
- currentGridDataRef.current = {
1048
- nx: cachedData.nx,
1049
- ny: cachedData.ny,
1050
- scale: cachedData.scale,
1051
- offset: cachedData.offset,
1052
- missing: cachedData.missing,
1053
- gridDef: cachedData.gridDef,
1054
- variable: variable,
1055
- units: units,
1056
- scaleType: cachedData.scaleType
1057
- };
1058
- wxGridVerbose('gpuUploadFromFile', {
1059
- cacheKey,
1060
- nx: cachedData.nx,
1061
- ny: cachedData.ny,
1062
- filePathSuffix: String(cachedData.filePath).split('/').pop()
1063
- });
1064
- } else {
1065
- wxGridWarn('updateGPUNoFilePath', {
1066
- cacheKey
714
+ const u = W.current.get(i);
715
+ if (!u) return Z("updateGPUNoCache", {
716
+ cacheKey: i,
717
+ cacheSize: W.current.size,
718
+ sampleKeys: Array.from(W.current.keys()).slice(0, 5)
719
+ }), !1;
720
+ if (!p.current) return Z("updateGPUNoGridLayerRef", {
721
+ cacheKey: i
722
+ }), !1;
723
+ (!pe.current || pe.current.model !== (N ? "mrms" : a) || pe.current.variable !== s) && (p.current.updateGeometry(u.corners, u.gridDef), pe.current = {
724
+ model: N ? "mrms" : a,
725
+ variable: s
1067
726
  });
1068
- return false;
1069
- }
1070
-
1071
- // Update inspector parameters for file-based data too
1072
- if (gridLayerRef.current && gridLayerRef.current.updateDataParameters) {
1073
- gridLayerRef.current.updateDataParameters(cachedData.scale, cachedData.offset, cachedData.missing);
1074
- }
1075
- return true;
1076
- };
1077
- const handleStateChangeRef = useRef(null);
1078
- const debounceTimeoutRef = useRef(null);
1079
- useEffect(() => {
1080
- if (core && props.customColormaps) {
1081
- core.customColormaps = props.customColormaps;
1082
- // Trigger a re-render if we already have data loaded
1083
- if (hasInitialLoad.current) {
1084
- core._emitStateChange();
1085
- }
1086
- }
1087
- }, [core, props.customColormaps]);
1088
- const getValueAtPoint = async (lng, lat) => {
1089
- if (!core) {
1090
- return null;
1091
- }
1092
- if (NEXRAD_NATIVE && core.state?.isNexrad) {
1093
- return getNexradInspectPayloadAt(lng, lat);
1094
- }
1095
-
1096
- // ADD THIS: Check if we have valid data before attempting inspection
1097
- if (!currentGridDataRef.current) {
1098
- return null;
1099
- }
1100
- try {
1101
- const gridIndices = core._getGridIndexFromLngLat(lng, lat);
1102
- if (!gridIndices) return null;
1103
- const {
1104
- i,
1105
- j
1106
- } = gridIndices;
1107
- const value = await InspectorModule.getValueAtGridIndex(i, j);
1108
- if (value === null) {
1109
- return null;
1110
- }
1111
- const {
1112
- colormap,
1113
- baseUnit
1114
- } = core._getColormapForVariable(core.state.variable);
1115
- const displayUnit = core._getTargetUnit(baseUnit, core.state.units);
1116
- const finalColormap = core._convertColormapUnits(colormap, baseUnit, displayUnit);
1117
- const minThreshold = finalColormap[0];
1118
- if (value < minThreshold) {
1119
- return null;
727
+ const A = `${s}-${w}`;
728
+ if (!ge.current || ge.current.key !== A) {
729
+ const {
730
+ colormap: y,
731
+ baseUnit: M
732
+ } = t._getColormapForVariable(s),
733
+ U = t._getTargetUnit(M, w),
734
+ E = t._convertColormapUnits(y, M, U);
735
+ let K;
736
+ s === "ptypeRefl" || s === "ptypeRate" ? N ? K = [5, 380] : K = [5, 380] : K = [E[0], E[E.length - 2]];
737
+ const Y = et(E),
738
+ D = ze(Y);
739
+ p.current.updateColormapTexture(D), ge.current = {
740
+ key: A
741
+ }, ke.current = K, Me(q => ({
742
+ ...q,
743
+ dataRange: K
744
+ }));
1120
745
  }
1121
-
1122
- // Filter out values below the minimum threshold (matching shader behavior)
1123
- if (value < minThreshold) {
1124
- return null;
746
+ if (u.filePath) p.current.updateDataTextureFromFile(u.filePath, u.nx, u.ny, u.scale, u.offset, u.missing, u.scaleType), De.current = {
747
+ nx: u.nx,
748
+ ny: u.ny,
749
+ scale: u.scale,
750
+ offset: u.offset,
751
+ missing: u.missing,
752
+ gridDef: u.gridDef,
753
+ variable: s,
754
+ units: w,
755
+ scaleType: u.scaleType
756
+ }, z("gpuUploadFromFile", {
757
+ cacheKey: i,
758
+ nx: u.nx,
759
+ ny: u.ny,
760
+ filePathSuffix: String(u.filePath).split("/").pop()
761
+ });else return Z("updateGPUNoFilePath", {
762
+ cacheKey: i
763
+ }), !1;
764
+ return p.current && p.current.updateDataParameters && p.current.updateDataParameters(u.scale, u.offset, u.missing), !0;
765
+ },
766
+ he = V(null),
767
+ le = V(null);
768
+ j(() => {
769
+ t && m.customColormaps && (t.customColormaps = m.customColormaps, ae.current && t._emitStateChange());
770
+ }, [t, m.customColormaps]);
771
+ const lt = async (r, a) => {
772
+ if (!t) return null;
773
+ if (t.state?.isNexrad) {
774
+ const e = X.current;
775
+ return e ? e.getInspectPayload(r, a, ht(t.state)) : null;
1125
776
  }
1126
-
1127
- // Also check if value is NaN or effectively missing
1128
- if (!isFinite(value)) {
777
+ if (!De.current) return null;
778
+ try {
779
+ const e = t._getGridIndexFromLngLat(r, a);
780
+ if (!e) return null;
781
+ const {
782
+ i: o,
783
+ j: F
784
+ } = e,
785
+ s = await kt.getValueAtGridIndex(o, F);
786
+ if (s === null) return null;
787
+ const {
788
+ colormap: w,
789
+ baseUnit: N
790
+ } = t._getColormapForVariable(t.state.variable),
791
+ c = t._getTargetUnit(N, t.state.units),
792
+ i = t._convertColormapUnits(w, N, c)[0];
793
+ return s < i || s < i || !isFinite(s) ? null : {
794
+ value: s,
795
+ unit: c,
796
+ variable: {
797
+ code: t.state.variable,
798
+ name: t.getVariableDisplayName(t.state.variable)
799
+ },
800
+ lngLat: {
801
+ lng: r,
802
+ lat: a
803
+ }
804
+ };
805
+ } catch {
1129
806
  return null;
1130
807
  }
1131
- return {
1132
- value: value,
1133
- unit: displayUnit,
1134
- variable: {
1135
- code: core.state.variable,
1136
- name: core.getVariableDisplayName(core.state.variable)
1137
- },
1138
- lngLat: {
1139
- lng,
1140
- lat
1141
- }
1142
- };
1143
- } catch {
1144
- return null;
1145
- }
1146
- };
1147
- const getValueAtPointRef = useRef(getValueAtPoint);
1148
- getValueAtPointRef.current = getValueAtPoint;
1149
- const getNexradInspectPayloadAtRef = useRef(getNexradInspectPayloadAt);
1150
- getNexradInspectPayloadAtRef.current = getNexradInspectPayloadAt;
1151
- const _checkForUpdates = useMemo(() => async () => {
1152
- if (!core) return;
1153
- const s = core.state;
1154
- const {
1155
- isMRMS,
1156
- isSatellite,
1157
- isNexrad,
1158
- model: currentModel,
1159
- variable: currentVariable,
1160
- date,
1161
- run
1162
- } = s;
1163
- if (isSatellite) {
1164
- const prevTimeline = core._computeSatelliteTimeline();
1165
- const prevTimes = [...(prevTimeline.unixTimes || [])].map(t => Number(t)).filter(t => !Number.isNaN(t)).sort((a, b) => a - b);
1166
- const prevMax = prevTimes.length ? prevTimes[prevTimes.length - 1] : null;
1167
- const curSat = s.satelliteTimestamp == null ? null : Number(s.satelliteTimestamp);
1168
- await core.fetchSatelliteListing(true);
1169
- core._emitStateChange();
1170
- const nextTimeline = core._computeSatelliteTimeline();
1171
- const nextTimes = [...(nextTimeline.unixTimes || [])].map(t => Number(t)).filter(t => !Number.isNaN(t)).sort((a, b) => a - b);
1172
- const newMax = nextTimes.length ? nextTimes[nextTimes.length - 1] : null;
1173
- if (prevMax != null && curSat != null && curSat === prevMax && newMax != null && newMax > prevMax) {
1174
- await core.setSatelliteTimestamp(newMax);
1175
- } else if (curSat != null && newMax != null && nextTimes.length && !nextTimes.includes(curSat)) {
1176
- await core.setSatelliteTimestamp(newMax);
1177
- }
808
+ },
809
+ We = V(lt);
810
+ We.current = lt;
811
+ const Se = ut(() => async () => {
812
+ if (!t) return;
813
+ const r = t.state,
814
+ {
815
+ isMRMS: a,
816
+ isSatellite: e,
817
+ isNexrad: o,
818
+ model: F,
819
+ variable: s,
820
+ date: w,
821
+ run: N
822
+ } = r;
823
+ if (e) {
824
+ const c = [...(t._computeSatelliteTimeline().unixTimes || [])].map(M => Number(M)).filter(M => !Number.isNaN(M)).sort((M, U) => M - U),
825
+ i = c.length ? c[c.length - 1] : null,
826
+ u = r.satelliteTimestamp == null ? null : Number(r.satelliteTimestamp);
827
+ await t.fetchSatelliteListing(!0), t._emitStateChange();
828
+ const A = [...(t._computeSatelliteTimeline().unixTimes || [])].map(M => Number(M)).filter(M => !Number.isNaN(M)).sort((M, U) => M - U),
829
+ y = A.length ? A[A.length - 1] : null;
830
+ i != null && u != null && u === i && y != null && y > i ? await t.setSatelliteTimestamp(y) : u != null && y != null && A.length && !A.includes(u) && (await t.setSatelliteTimestamp(y));
1178
831
  return;
1179
832
  }
1180
- if (isNexrad && s.nexradSite) {
1181
- const nk = core._nexradTimesCacheKey();
1182
- const rawBefore = nk ? core.nexradTimesByStation[nk]?.unixTimes : [];
1183
- const filteredBefore = core._getFilteredNexradTimestampsForVariable(rawBefore || []);
1184
- const prevMax = filteredBefore.length ? filteredBefore[filteredBefore.length - 1] : null;
1185
- const curNx = s.nexradTimestamp == null ? null : Number(s.nexradTimestamp);
1186
- await core.refreshNexradTimes();
1187
- const rawAfter = nk ? core.nexradTimesByStation[nk]?.unixTimes : [];
1188
- const filteredAfter = core._getFilteredNexradTimestampsForVariable(rawAfter || []);
1189
- const newMax = filteredAfter.length ? filteredAfter[filteredAfter.length - 1] : null;
1190
- if (prevMax != null && curNx != null && curNx === prevMax && newMax != null && newMax > prevMax) {
1191
- await core.setNexradTimestamp(newMax);
1192
- } else if (curNx != null && newMax != null && filteredAfter.length && !filteredAfter.includes(curNx)) {
1193
- await core.setNexradTimestamp(newMax);
1194
- }
833
+ if (o && r.nexradSite) {
834
+ const c = t._nexradTimesCacheKey(),
835
+ i = c ? t.nexradTimesByStation[c]?.unixTimes : [],
836
+ u = t._getFilteredNexradTimestampsForVariable(i || []),
837
+ A = u.length ? u[u.length - 1] : null,
838
+ y = r.nexradTimestamp == null ? null : Number(r.nexradTimestamp);
839
+ await t.refreshNexradTimes(), t._emitStateChange();
840
+ const M = c ? t.nexradTimesByStation[c]?.unixTimes : [],
841
+ U = t._getFilteredNexradTimestampsForVariable(M || []),
842
+ E = U.length ? U[U.length - 1] : null;
843
+ A != null && y != null && y === A && E != null && E > A ? await t.setNexradTimestamp(E) : y != null && E != null && U.length && !U.includes(y) && (await t.setNexradTimestamp(E));
1195
844
  return;
1196
845
  }
1197
- if (isMRMS) {
1198
- // --- MRMS LOGIC (Keep existing logic) ---
1199
- const oldTimestamps = new Set(core.mrmsStatus?.[currentVariable] || []);
1200
- const mrmsStatus = await core.fetchMRMSStatus(true);
1201
- const newTimestamps = mrmsStatus?.[currentVariable] || [];
1202
- if (newTimestamps.length === 0) return;
1203
- const newTimestampsToPreload = newTimestamps.filter(ts => !oldTimestamps.has(ts));
1204
- if (newTimestampsToPreload.length > 0) {
1205
- core.mrmsStatus = mrmsStatus;
1206
- core._emitStateChange(); // Update UI slider without changing selection
1207
-
1208
- // ... (Keep your existing preloading logic here) ...
1209
- const {
1210
- corners,
1211
- gridDef
1212
- } = core._getGridCornersAndDef('mrms');
846
+ if (a) {
847
+ const c = new Set(t.mrmsStatus?.[s] || []),
848
+ i = await t.fetchMRMSStatus(!0),
849
+ u = i?.[s] || [];
850
+ if (u.length === 0) return;
851
+ const A = u.filter(y => !c.has(y));
852
+ if (A.length > 0) {
853
+ t.mrmsStatus = i, t._emitStateChange();
1213
854
  const {
1214
- nx,
1215
- ny
1216
- } = gridDef.grid_params;
1217
- newTimestampsToPreload.forEach(frame => {
1218
- const cacheKey = `mrms-${frame}-${currentVariable}`;
1219
- if (preloadedDataCache.current.has(cacheKey)) return;
1220
- const frameDate = new Date(frame * 1000);
1221
- const y = frameDate.getUTCFullYear(),
1222
- m = (frameDate.getUTCMonth() + 1).toString().padStart(2, '0'),
1223
- d = frameDate.getUTCDate().toString().padStart(2, '0');
1224
- const resourcePath = `/grids/mrms/${y}${m}${d}/${frame}/0/${currentVariable}/0`;
1225
- const options = augmentProcessFrameOptionsForDebug(buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin, core), core);
1226
- logProcessFrameAuthMismatch(core, options, {
1227
- phase: 'mrmsRefresh',
1228
- cacheKey
1229
- });
1230
- WeatherFrameProcessorModule.processFrame(options).then(result => {
1231
- if (!result || !result.filePath) return;
1232
- const frameData = {
1233
- filePath: result.filePath,
1234
- nx,
1235
- ny,
1236
- scale: result.scale,
1237
- offset: result.offset,
1238
- missing: result.missing,
1239
- corners,
1240
- gridDef,
1241
- scaleType: result.scaleType,
1242
- originalScale: result.scale,
1243
- originalOffset: result.offset
855
+ corners: y,
856
+ gridDef: M
857
+ } = t._getGridCornersAndDef("mrms"),
858
+ {
859
+ nx: U,
860
+ ny: E
861
+ } = M.grid_params;
862
+ A.forEach(Y => {
863
+ const D = `mrms-${Y}-${s}`;
864
+ if (W.current.has(D)) return;
865
+ const q = new Date(Y * 1e3),
866
+ de = q.getUTCFullYear(),
867
+ ye = (q.getUTCMonth() + 1).toString().padStart(2, "0"),
868
+ $ = q.getUTCDate().toString().padStart(2, "0"),
869
+ d = `/grids/mrms/${de}${ye}${$}/${Y}/0/${s}/0`,
870
+ G = Xe(Ze(t.baseGridUrl, d, t.apiKey, t.bundleId, te, t), t);
871
+ Qe(t, G, {
872
+ phase: "mrmsRefresh",
873
+ cacheKey: D
874
+ }), qe.processFrame(G).then(n => {
875
+ if (!n || !n.filePath) return;
876
+ const R = {
877
+ filePath: n.filePath,
878
+ nx: U,
879
+ ny: E,
880
+ scale: n.scale,
881
+ offset: n.offset,
882
+ missing: n.missing,
883
+ corners: y,
884
+ gridDef: M,
885
+ scaleType: n.scaleType,
886
+ originalScale: n.scale,
887
+ originalOffset: n.offset
1244
888
  };
1245
- preloadedDataCache.current.set(cacheKey, frameData);
1246
- if (Platform.OS === 'ios' && gridLayerRef.current?.primeGpuCache) {
1247
- gridLayerRef.current.primeGpuCache({
1248
- [cacheKey]: frameData
1249
- });
1250
- }
1251
- }).catch(e => {
1252
- const cancelled = e && (e.code === 'E_CANCELLED' || e?.userInfo?.code === 'E_CANCELLED' || typeof e?.message === 'string' && e.message.includes('superseded'));
1253
- if (!cancelled) {
1254
- wxGridWarn('mrmsRefreshFrameError', {
1255
- cacheKey,
1256
- code: e?.code,
1257
- message: e?.message
1258
- });
1259
- }
889
+ W.current.set(D, R), se.OS === "ios" && p.current?.primeGpuCache && p.current.primeGpuCache({
890
+ [D]: R
891
+ });
892
+ }).catch(n => {
893
+ n && (n.code === "E_CANCELLED" || n?.userInfo?.code === "E_CANCELLED" || typeof n?.message == "string" && n.message.includes("superseded")) || Z("mrmsRefreshFrameError", {
894
+ cacheKey: D,
895
+ code: n?.code,
896
+ message: n?.message
897
+ });
1260
898
  });
1261
899
  });
1262
- const newTimestampsSet = new Set(newTimestamps);
1263
- oldTimestamps.forEach(oldTs => {
1264
- if (!newTimestampsSet.has(oldTs)) {
1265
- const cacheKey = `mrms-${oldTs}-${currentVariable}`;
1266
- preloadedDataCache.current.delete(cacheKey);
900
+ const K = new Set(u);
901
+ c.forEach(Y => {
902
+ if (!K.has(Y)) {
903
+ const D = `mrms-${Y}-${s}`;
904
+ W.current.delete(D);
1267
905
  }
1268
906
  });
1269
907
  }
1270
908
  } else {
1271
- const previousStatus = core.modelStatus;
1272
- const modelStatus = await core.fetchModelStatus(true);
1273
- const statusChanged = JSON.stringify(previousStatus) !== JSON.stringify(modelStatus);
1274
- if (statusChanged) {
1275
- core._emitStateChange();
1276
- }
1277
- const latestRun = findLatestModelRun(modelStatus, currentModel);
1278
- if (!latestRun) return;
1279
- }
1280
- }, [core]);
1281
- useEffect(() => {
1282
- if (!core) {
1283
- return;
909
+ const c = t.modelStatus,
910
+ i = await t.fetchModelStatus(!0);
911
+ if (JSON.stringify(c) !== JSON.stringify(i) && t._emitStateChange(), !Gt(i, F)) return;
1284
912
  }
1285
- const handleStateChange = newState => {
1286
- if (!previousStateRef.current) {
1287
- previousStateRef.current = core.state;
1288
- }
1289
- const variableChanged = !previousStateRef.current || newState.variable !== previousStateRef.current.variable;
1290
- if (variableChanged && gridLayerRef.current?.setVariable) {
1291
- gridLayerRef.current.setVariable(newState.variable);
1292
- }
1293
- const stateKey = newState.isNexrad ? `nx-${newState.nexradSite}-${newState.nexradProduct}-${newState.nexradDataSource}-${newState.nexradTimestamp}-${newState.nexradTilt}-${newState.units}-${newState.model}-${newState.variable}-${newState.mrmsTimestamp}-${newState.forecastHour}-dur:${newState.nexradDurationValue ?? ''}-tl:${nexradObsTimelineSig(newState)}` : newState.isSatellite ? `sat-${newState.satelliteInstrumentId}-${newState.satelliteSectorLabel}-${newState.satelliteChannel}-${newState.satelliteTimestamp}-${newState.variable}-${newState.units}-${newState.opacity}-dur:${newState.satelliteDurationValue ?? ''}-tl:${satelliteObsTimelineSig(newState)}` : `${newState.model}-${newState.variable}-${newState.date}-${newState.run}-${newState.forecastHour}-${newState.units}-${newState.mrmsTimestamp}`;
1294
- const sameTimeline = newState.isNexrad ? newState.nexradTimestamp === previousStateRef.current?.nexradTimestamp && newState.nexradSite === previousStateRef.current?.nexradSite && newState.nexradProduct === previousStateRef.current?.nexradProduct && Number(newState.nexradTilt) === Number(previousStateRef.current?.nexradTilt) && newState.nexradDurationValue === previousStateRef.current?.nexradDurationValue && nexradObsTimelineSig(newState) === nexradObsTimelineSig(previousStateRef.current) : newState.isSatellite ? newState.satelliteTimestamp === previousStateRef.current?.satelliteTimestamp && newState.satelliteInstrumentId === previousStateRef.current?.satelliteInstrumentId && newState.satelliteSectorLabel === previousStateRef.current?.satelliteSectorLabel && newState.satelliteChannel === previousStateRef.current?.satelliteChannel && newState.satelliteDurationValue === previousStateRef.current?.satelliteDurationValue && satelliteObsTimelineSig(newState) === satelliteObsTimelineSig(previousStateRef.current) : newState.forecastHour === previousStateRef.current?.forecastHour && newState.mrmsTimestamp === previousStateRef.current?.mrmsTimestamp;
1295
- const sameModeAnchor = newState.isSatellite ? newState.satelliteInstrumentId === previousStateRef.current?.satelliteInstrumentId && newState.satelliteSectorLabel === previousStateRef.current?.satelliteSectorLabel && newState.satelliteChannel === previousStateRef.current?.satelliteChannel : newState.model === previousStateRef.current?.model && newState.isMRMS === previousStateRef.current?.isMRMS;
1296
- const isOpacityOnlyChange = hasInitialLoad.current && newState.opacity !== renderProps.opacity && newState.variable === previousStateRef.current?.variable && sameTimeline && sameModeAnchor && newState.units === previousStateRef.current?.units;
1297
- const isPlayStateOnlyChange = hasInitialLoad.current && newState.isPlaying !== previousStateRef.current?.isPlaying && newState.variable === previousStateRef.current?.variable && sameTimeline && sameModeAnchor && newState.units === previousStateRef.current?.units && newState.opacity === previousStateRef.current?.opacity;
1298
- if (!isOpacityOnlyChange && !isPlayStateOnlyChange && lastProcessedState.current === stateKey) {
1299
- previousStateRef.current = newState;
913
+ }, [t]);
914
+ j(() => {
915
+ if (!t) return;
916
+ const r = e => {
917
+ l.current || (l.current = t.state), (!l.current || e.variable !== l.current.variable) && p.current?.setVariable && p.current.setVariable(e.variable);
918
+ const o = e.isNexrad ? `nx-${e.nexradSite}-${e.nexradProduct}-${e.nexradDataSource}-${e.nexradTimestamp}-${e.nexradTilt}-${e.opacity}` : e.isSatellite ? `sat-${e.satelliteInstrumentId}-${e.satelliteSectorLabel}-${e.satelliteChannel}-${e.satelliteTimestamp}-${e.variable}-${e.units}-${e.opacity}-dur:${e.satelliteDurationValue ?? ""}-tl:${ue(e)}` : `${e.model}-${e.variable}-${e.date}-${e.run}-${e.forecastHour}-${e.units}-${e.mrmsTimestamp}`,
919
+ F = e.isNexrad ? e.nexradTimestamp === l.current?.nexradTimestamp && e.nexradSite === l.current?.nexradSite && e.nexradProduct === l.current?.nexradProduct && Number(e.nexradTilt) === Number(l.current?.nexradTilt) : e.isSatellite ? e.satelliteTimestamp === l.current?.satelliteTimestamp && e.satelliteInstrumentId === l.current?.satelliteInstrumentId && e.satelliteSectorLabel === l.current?.satelliteSectorLabel && e.satelliteChannel === l.current?.satelliteChannel && e.satelliteDurationValue === l.current?.satelliteDurationValue && ue(e) === ue(l.current) : e.forecastHour === l.current?.forecastHour && e.mrmsTimestamp === l.current?.mrmsTimestamp,
920
+ s = e.isSatellite ? e.satelliteInstrumentId === l.current?.satelliteInstrumentId && e.satelliteSectorLabel === l.current?.satelliteSectorLabel && e.satelliteChannel === l.current?.satelliteChannel : e.model === l.current?.model && e.isMRMS === l.current?.isMRMS,
921
+ w = ae.current && e.opacity !== Ve.opacity && e.variable === l.current?.variable && F && s && e.units === l.current?.units,
922
+ N = ae.current && e.isPlaying !== l.current?.isPlaying && e.variable === l.current?.variable && F && s && e.units === l.current?.units && e.opacity === l.current?.opacity;
923
+ if (!w && !N && He.current === o) {
924
+ l.current = e;
1300
925
  return;
1301
926
  }
1302
- if (wxGridDebugEnabled() && Platform.OS === 'ios' && (newState.isNexrad && previousStateRef.current?.isNexrad || newState.isSatellite && previousStateRef.current?.isSatellite)) {
1303
- const prev = previousStateRef.current;
1304
- if (newState.isNexrad && prev?.isNexrad) {
1305
- if (newState.nexradDurationValue !== prev.nexradDurationValue || nexradObsTimelineSig(newState) !== nexradObsTimelineSig(prev)) {
1306
- wxGridVerbose('iosNexradTimelineWindowChanged', {
1307
- duration: {
1308
- from: prev.nexradDurationValue,
1309
- to: newState.nexradDurationValue
1310
- },
1311
- timelineSig: {
1312
- from: nexradObsTimelineSig(prev),
1313
- to: nexradObsTimelineSig(newState)
1314
- },
1315
- willSyncNative: true
1316
- });
1317
- }
1318
- }
1319
- if (newState.isSatellite && prev?.isSatellite) {
1320
- if (newState.satelliteDurationValue !== prev.satelliteDurationValue || satelliteObsTimelineSig(newState) !== satelliteObsTimelineSig(prev)) {
1321
- wxGridVerbose('iosSatelliteTimelineWindowChanged', {
1322
- duration: {
1323
- from: prev.satelliteDurationValue,
1324
- to: newState.satelliteDurationValue
1325
- },
1326
- timelineSig: {
1327
- from: satelliteObsTimelineSig(prev),
1328
- to: satelliteObsTimelineSig(newState)
1329
- },
1330
- willSyncNative: true
1331
- });
1332
- }
1333
- }
1334
- }
1335
- if (!isOpacityOnlyChange && !isPlayStateOnlyChange) {
1336
- lastProcessedState.current = stateKey;
927
+ if (pt() && se.OS === "ios" && e.isSatellite && l.current?.isSatellite) {
928
+ const i = l.current;
929
+ e.isSatellite && i?.isSatellite && (e.satelliteDurationValue !== i.satelliteDurationValue || ue(e) !== ue(i)) && z("iosSatelliteTimelineWindowChanged", {
930
+ duration: {
931
+ from: i.satelliteDurationValue,
932
+ to: e.satelliteDurationValue
933
+ },
934
+ timelineSig: {
935
+ from: ue(i),
936
+ to: ue(e)
937
+ },
938
+ willSyncNative: !0
939
+ });
1337
940
  }
1338
- if (isOpacityOnlyChange) {
1339
- setRenderProps(prev => ({
1340
- ...prev,
1341
- opacity: newState.opacity
1342
- }));
1343
- if (NEXRAD_NATIVE && newState.isNexrad) {
1344
- nexradControllerRef.current?.applyStyleFromState?.(newState);
1345
- }
1346
- if (SATELLITE_NATIVE && newState.isSatellite) {
1347
- satelliteLayerRef.current?.updateSatelliteStyle?.(JSON.stringify({
1348
- visible: newState.visible !== false,
1349
- opacity: newState.opacity ?? 1,
1350
- fillSmoothing: 0
1351
- }));
1352
- }
1353
- previousStateRef.current = newState;
941
+ if (!w && !N && (He.current = o), w) {
942
+ Me(i => ({
943
+ ...i,
944
+ opacity: e.opacity
945
+ })), ie && e.isSatellite && Ne.current?.updateSatelliteStyle?.(JSON.stringify({
946
+ visible: e.visible !== !1,
947
+ opacity: e.opacity ?? 1,
948
+ fillSmoothing: 0
949
+ })), Q && e.isNexrad && Ie(e), l.current = e;
1354
950
  return;
1355
951
  }
1356
- if (isPlayStateOnlyChange) {
1357
- previousStateRef.current = newState;
952
+ if (N) {
953
+ l.current = e;
1358
954
  return;
1359
955
  }
1360
- const isUnitsOnlyChange = hasInitialLoad.current && newState.model === previousStateRef.current.model && newState.isMRMS === previousStateRef.current.isMRMS && newState.variable === previousStateRef.current.variable && newState.date === previousStateRef.current.date && newState.run === previousStateRef.current.run && (newState.isNexrad ? newState.nexradTimestamp === previousStateRef.current.nexradTimestamp && newState.nexradSite === previousStateRef.current.nexradSite && newState.nexradProduct === previousStateRef.current.nexradProduct : newState.forecastHour === previousStateRef.current.forecastHour && newState.mrmsTimestamp === previousStateRef.current.mrmsTimestamp) && newState.units !== previousStateRef.current.units;
1361
- if (isUnitsOnlyChange) {
1362
- if (NEXRAD_NATIVE && newState.isNexrad) {
1363
- setRenderProps(prev => ({
1364
- ...prev,
1365
- opacity: newState.opacity
1366
- }));
1367
- nexradControllerRef.current?.applyStyleFromState?.(newState);
1368
- previousStateRef.current = newState;
956
+ if (ae.current && e.model === l.current.model && e.isMRMS === l.current.isMRMS && e.variable === l.current.variable && e.date === l.current.date && e.run === l.current.run && (e.isNexrad ? e.nexradTimestamp === l.current.nexradTimestamp && e.nexradSite === l.current.nexradSite && e.nexradProduct === l.current.nexradProduct : e.forecastHour === l.current.forecastHour && e.mrmsTimestamp === l.current.mrmsTimestamp) && e.units !== l.current.units) {
957
+ if (Q && e.isNexrad) {
958
+ Me(q => ({
959
+ ...q,
960
+ opacity: e.opacity
961
+ })), Ie(e), l.current = e;
1369
962
  return;
1370
963
  }
1371
964
  const {
1372
- variable,
1373
- units,
1374
- isMRMS,
1375
- mrmsTimestamp,
1376
- model,
1377
- date,
1378
- run,
1379
- forecastHour
1380
- } = newState;
1381
- const oldCacheKey = isMRMS ? `mrms-${mrmsTimestamp}-${variable}` : `${model}-${date}-${run}-${forecastHour}-${variable}`;
1382
- const cachedData = preloadedDataCache.current.get(oldCacheKey);
1383
- if (cachedData && cachedData.originalScale !== undefined && cachedData.originalOffset !== undefined) {
965
+ variable: i,
966
+ units: u,
967
+ isMRMS: A,
968
+ mrmsTimestamp: y,
969
+ model: M,
970
+ date: U,
971
+ run: E,
972
+ forecastHour: K
973
+ } = e,
974
+ Y = A ? `mrms-${y}-${i}` : `${M}-${U}-${E}-${K}-${i}`,
975
+ D = W.current.get(Y);
976
+ if (D && D.originalScale !== void 0 && D.originalOffset !== void 0) {
1384
977
  const {
1385
- baseUnit
1386
- } = core._getColormapForVariable(variable);
1387
- const toUnit = core._getTargetUnit(baseUnit, units);
1388
- const fieldInfo = DICTIONARIES?.fld?.[variable] || {};
1389
- const serverDataUnit = fieldInfo.defaultUnit || baseUnit;
1390
- let dataScale = cachedData.originalScale;
1391
- let dataOffset = cachedData.originalOffset;
1392
- if (serverDataUnit !== baseUnit) {
1393
- const conversionFunc = getUnitConversionFunction(serverDataUnit, baseUnit);
1394
- if (conversionFunc) {
1395
- if (cachedData.scaleType === 'sqrt') {
1396
- const physicalAtOffset = dataOffset * dataOffset;
1397
- const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
1398
- const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
1399
- const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
1400
- const newOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
1401
- const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
1402
- dataScale = newOffsetPlusScale - newOffset;
1403
- dataOffset = newOffset;
1404
- } else {
1405
- const convertedOffset = conversionFunc(dataOffset);
1406
- const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
1407
- dataScale = convertedOffsetPlusScale - convertedOffset;
1408
- dataOffset = convertedOffset;
1409
- }
978
+ baseUnit: q
979
+ } = t._getColormapForVariable(i),
980
+ de = t._getTargetUnit(q, u),
981
+ ye = (Be?.fld?.[i] || {}).defaultUnit || q;
982
+ let $ = D.originalScale,
983
+ d = D.originalOffset;
984
+ if (ye !== q) {
985
+ const f = ve(ye, q);
986
+ if (f) if (D.scaleType === "sqrt") {
987
+ const C = d * d,
988
+ b = (d + $) * (d + $),
989
+ S = f(C),
990
+ T = f(b),
991
+ L = Math.sqrt(Math.abs(S)) * Math.sign(S);
992
+ $ = Math.sqrt(Math.abs(T)) * Math.sign(T) - L, d = L;
993
+ } else {
994
+ const C = f(d);
995
+ $ = f(d + $) - C, d = C;
1410
996
  }
1411
997
  }
1412
- if (baseUnit !== toUnit) {
1413
- const conversionFunc = getUnitConversionFunction(baseUnit, toUnit);
1414
- if (conversionFunc) {
1415
- if (cachedData.scaleType === 'sqrt') {
1416
- const physicalAtOffset = dataOffset * dataOffset;
1417
- const physicalAtOffsetPlusScale = (dataOffset + dataScale) * (dataOffset + dataScale);
1418
- const convertedPhysicalAtOffset = conversionFunc(physicalAtOffset);
1419
- const convertedPhysicalAtOffsetPlusScale = conversionFunc(physicalAtOffsetPlusScale);
1420
- const newOffset = Math.sqrt(Math.abs(convertedPhysicalAtOffset)) * Math.sign(convertedPhysicalAtOffset);
1421
- const newOffsetPlusScale = Math.sqrt(Math.abs(convertedPhysicalAtOffsetPlusScale)) * Math.sign(convertedPhysicalAtOffsetPlusScale);
1422
- dataScale = newOffsetPlusScale - newOffset;
1423
- dataOffset = newOffset;
1424
- } else {
1425
- const convertedOffset = conversionFunc(dataOffset);
1426
- const convertedOffsetPlusScale = conversionFunc(dataOffset + dataScale);
1427
- dataScale = convertedOffsetPlusScale - convertedOffset;
1428
- dataOffset = convertedOffset;
1429
- }
998
+ if (q !== de) {
999
+ const f = ve(q, de);
1000
+ if (f) if (D.scaleType === "sqrt") {
1001
+ const C = d * d,
1002
+ b = (d + $) * (d + $),
1003
+ S = f(C),
1004
+ T = f(b),
1005
+ L = Math.sqrt(Math.abs(S)) * Math.sign(S);
1006
+ $ = Math.sqrt(Math.abs(T)) * Math.sign(T) - L, d = L;
1007
+ } else {
1008
+ const C = f(d);
1009
+ $ = f(d + $) - C, d = C;
1430
1010
  }
1431
1011
  }
1432
1012
  const {
1433
- colormap
1434
- } = core._getColormapForVariable(variable);
1435
- const finalColormap = core._convertColormapUnits(colormap, baseUnit, toUnit);
1436
- let dataRange = variable === 'ptypeRefl' || variable === 'ptypeRate' ? [5, 380] : [finalColormap[0], finalColormap[finalColormap.length - 2]];
1437
- const colormapBytes = _generateColormapBytes(finalColormap);
1438
- const colormapAsBase64 = fromByteArray(colormapBytes);
1439
- gridLayerRef.current.updateColormapTexture(colormapAsBase64);
1440
- cachedColormap.current = {
1441
- key: `${variable}-${units}`
1442
- };
1443
- cachedDataRange.current = dataRange;
1444
- setRenderProps(prev => ({
1445
- ...prev,
1446
- dataRange,
1447
- opacity: newState.opacity
1448
- }));
1449
- if (gridLayerRef.current && gridLayerRef.current.updateDataParameters) {
1450
- const scaleTypeValue = cachedData.scaleType === 'sqrt' ? 1 : 0;
1451
- gridLayerRef.current.updateDataParameters(dataScale, dataOffset, cachedData.missing, scaleTypeValue);
1013
+ colormap: G
1014
+ } = t._getColormapForVariable(i),
1015
+ n = t._convertColormapUnits(G, q, de);
1016
+ let R = i === "ptypeRefl" || i === "ptypeRate" ? [5, 380] : [n[0], n[n.length - 2]];
1017
+ const h = et(n),
1018
+ k = ze(h);
1019
+ if (p.current.updateColormapTexture(k), ge.current = {
1020
+ key: `${i}-${u}`
1021
+ }, ke.current = R, Me(f => ({
1022
+ ...f,
1023
+ dataRange: R,
1024
+ opacity: e.opacity
1025
+ })), p.current && p.current.updateDataParameters) {
1026
+ const f = D.scaleType === "sqrt" ? 1 : 0;
1027
+ p.current.updateDataParameters($, d, D.missing, f);
1452
1028
  }
1453
- const newCacheKey = isMRMS ? `mrms-${mrmsTimestamp}-${variable}` : `${model}-${date}-${run}-${forecastHour}-${variable}`;
1454
- preloadedDataCache.current.set(newCacheKey, {
1455
- ...cachedData,
1456
- scale: dataScale,
1457
- offset: dataOffset
1029
+ const P = A ? `mrms-${y}-${i}` : `${M}-${U}-${E}-${K}-${i}`;
1030
+ W.current.set(P, {
1031
+ ...D,
1032
+ scale: $,
1033
+ offset: d
1458
1034
  });
1459
1035
  }
1460
- previousStateRef.current = newState;
1036
+ l.current = e;
1461
1037
  return;
1462
1038
  }
1463
- const prev = previousStateRef.current;
1464
- const needsFullLoad = !hasInitialLoad.current || newState.isNexrad !== prev?.isNexrad || newState.isSatellite !== prev?.isSatellite || newState.isNexrad && prev?.isNexrad && (newState.nexradSite !== prev.nexradSite || newState.nexradDataSource !== prev.nexradDataSource || newState.nexradProduct !== prev.nexradProduct) || newState.isSatellite && prev?.isSatellite && (newState.satelliteInstrumentId !== prev.satelliteInstrumentId || newState.satelliteSectorLabel !== prev.satelliteSectorLabel || newState.satelliteChannel !== prev.satelliteChannel) || !newState.isNexrad && !newState.isSatellite && (newState.model !== prev?.model || newState.isMRMS !== prev?.isMRMS || newState.variable !== prev?.variable || newState.date !== prev?.date || newState.run !== prev?.run);
1465
- if (needsFullLoad) {
1466
- wxGridVerbose('needsFullLoad', {
1467
- variable: newState.variable,
1468
- isMRMS: newState.isMRMS,
1469
- model: newState.model,
1470
- isInitial: !hasInitialLoad.current,
1471
- prevVariable: prev?.variable,
1472
- prevModel: prev?.model
1473
- });
1474
- const nexradIdentityChange = NEXRAD_NATIVE && (newState.isNexrad !== prev?.isNexrad || newState.isNexrad && prev?.isNexrad && (newState.nexradSite !== prev.nexradSite || newState.nexradDataSource !== prev.nexradDataSource || newState.nexradProduct !== prev.nexradProduct));
1475
- const satelliteIdentityChange = SATELLITE_NATIVE && (newState.isSatellite !== prev?.isSatellite || newState.isSatellite && prev?.isSatellite && (newState.satelliteInstrumentId !== prev.satelliteInstrumentId || newState.satelliteSectorLabel !== prev.satelliteSectorLabel || newState.satelliteChannel !== prev.satelliteChannel));
1476
- if (nexradIdentityChange) {
1477
- nexradPreloadInteractionRef.current?.cancel?.();
1478
- nexradPreloadInteractionRef.current = null;
1479
- nexradControllerRef.current?.destroy();
1480
- nexradControllerRef.current = null;
1481
- }
1482
- if (satelliteIdentityChange) {
1483
- satelliteControllerRef.current?.destroy();
1484
- satelliteControllerRef.current = null;
1485
- }
1486
- if (gridLayerRef.current) {
1487
- gridLayerRef.current.setVariable(newState.variable);
1488
- gridLayerRef.current.clear();
1489
- if (Platform.OS === 'ios' && gridLayerRef.current.clearGpuCache) {
1490
- gridLayerRef.current.clearGpuCache();
1491
- }
1492
- }
1493
- hasPreloadedRef.current = false;
1494
- preloadGenerationRef.current += 1;
1495
- preloadedDataCache.current.clear();
1496
- cachedGeometry.current = null;
1497
- cachedColormap.current = null;
1498
- currentGridDataRef.current = null;
1499
- WeatherFrameProcessorModule.cancelAllFrames();
1500
- wxGridVerbose('cancelAllFrames', {
1501
- reason: 'needsFullLoad',
1502
- variable: newState.variable,
1503
- generation: preloadGenerationRef.current
1039
+ const c = l.current;
1040
+ if (!ae.current || e.isNexrad !== c?.isNexrad || e.isSatellite !== c?.isSatellite || e.isNexrad && c?.isNexrad && (e.nexradSite !== c.nexradSite || e.nexradDataSource !== c.nexradDataSource || e.nexradProduct !== c.nexradProduct) || e.isSatellite && c?.isSatellite && (e.satelliteInstrumentId !== c.satelliteInstrumentId || e.satelliteSectorLabel !== c.satelliteSectorLabel || e.satelliteChannel !== c.satelliteChannel) || !e.isNexrad && !e.isSatellite && (e.model !== c?.model || e.isMRMS !== c?.isMRMS || e.variable !== c?.variable || e.date !== c?.date || e.run !== c?.run)) {
1041
+ z("needsFullLoad", {
1042
+ variable: e.variable,
1043
+ isMRMS: e.isMRMS,
1044
+ model: e.model,
1045
+ isInitial: !ae.current,
1046
+ prevVariable: c?.variable,
1047
+ prevModel: c?.model
1504
1048
  });
1505
- if (!newState.variable) {
1506
- previousStateRef.current = newState;
1049
+ const i = Q && (e.isNexrad !== c?.isNexrad || e.isNexrad && c?.isNexrad && (e.nexradSite !== c.nexradSite || e.nexradDataSource !== c.nexradDataSource || e.nexradProduct !== c.nexradProduct)),
1050
+ u = ie && (e.isSatellite !== c?.isSatellite || e.isSatellite && c?.isSatellite && (e.satelliteInstrumentId !== c.satelliteInstrumentId || e.satelliteSectorLabel !== c.satelliteSectorLabel || e.satelliteChannel !== c.satelliteChannel));
1051
+ if (i && (X.current?.destroy(), X.current = null), u && (re.current?.destroy(), re.current = null), p.current && (p.current.setVariable(e.variable), p.current.clear(), se.OS === "ios" && p.current.clearGpuCache && p.current.clearGpuCache()), ne.current = !1, Le.current += 1, W.current.clear(), pe.current = null, ge.current = null, De.current = null, qe.cancelAllFrames(), z("cancelAllFrames", {
1052
+ reason: "needsFullLoad",
1053
+ variable: e.variable,
1054
+ generation: Le.current
1055
+ }), !e.variable) {
1056
+ l.current = e;
1507
1057
  return;
1508
1058
  }
1509
- if (!newState.isNexrad && !newState.isSatellite) {
1510
- preloadAllFramesToDisk(newState);
1511
- } else if (NEXRAD_NATIVE && newState.isNexrad) {
1512
- hasInitialLoad.current = true;
1513
- } else if (SATELLITE_NATIVE && newState.isSatellite) {
1514
- hasInitialLoad.current = true;
1515
- }
1516
- } else if (!newState.isNexrad && (newState.forecastHour !== previousStateRef.current.forecastHour || newState.isMRMS && newState.mrmsTimestamp !== previousStateRef.current.mrmsTimestamp)) {
1517
- const success = updateGPUWithCachedData(newState);
1518
- if (!success) {
1519
- wxGridWarn('timelineGpuUpdateMiss', {
1520
- isMRMS: newState.isMRMS,
1521
- variable: newState.variable,
1522
- mrmsTimestamp: newState.mrmsTimestamp,
1523
- forecastHour: newState.forecastHour
1524
- });
1525
- hasPreloadedRef.current = false;
1526
- void preloadAllFramesToDisk(newState);
1527
- }
1528
- if (success && newState.opacity !== renderProps.opacity) {
1529
- setRenderProps(prev => ({
1530
- ...prev,
1531
- opacity: newState.opacity
1532
- }));
1533
- }
1534
- }
1535
- if (NEXRAD_NATIVE && newState.isNexrad && newState.nexradSite && newState.nexradTimestamp != null) {
1536
- const ctl = ensureNexradController();
1537
- if (ctl) {
1538
- hasInitialLoad.current = true;
1539
- void ctl.sync(newState);
1540
- nexradPreloadInteractionRef.current?.cancel?.();
1541
- const preloadCancelled = {
1542
- v: false
1543
- };
1544
- nexradPreloadInteractionRef.current = {
1545
- cancel: () => {
1546
- preloadCancelled.v = true;
1547
- }
1548
- };
1549
- const nexradTimelineSnapshot = Array.isArray(newState.availableNexradTimestamps) ? newState.availableNexradTimestamps : [];
1550
- const kickPreload = () => {
1551
- nexradPreloadInteractionRef.current = null;
1552
- if (preloadCancelled.v) {
1553
- return;
1554
- }
1555
- const cur = nexradControllerRef.current;
1556
- if (!cur) {
1557
- return;
1558
- }
1559
- const s = core.state;
1560
- if (!s.isNexrad || !s.nexradSite || s.nexradTimestamp == null) {
1561
- return;
1562
- }
1563
- const coreTs = Array.isArray(s.availableNexradTimestamps) ? s.availableNexradTimestamps : [];
1564
- const mergedTimestamps = coreTs.length > 0 ? coreTs : nexradTimelineSnapshot.length > 0 ? nexradTimelineSnapshot : [];
1565
- const preloadState = {
1566
- ...s,
1567
- availableNexradTimestamps: mergedTimestamps
1568
- };
1569
- cur.preloadAllAvailable(preloadState);
1570
- };
1571
- if (typeof queueMicrotask === 'function') {
1572
- queueMicrotask(kickPreload);
1573
- } else {
1574
- setTimeout(kickPreload, 0);
1575
- }
1576
- }
1577
- } else if (NEXRAD_NATIVE && (!newState.isNexrad || !newState.nexradSite)) {
1578
- nexradPreloadInteractionRef.current?.cancel?.();
1579
- nexradPreloadInteractionRef.current = null;
1580
- nexradControllerRef.current?.destroy();
1581
- nexradControllerRef.current = null;
1059
+ !e.isNexrad && !e.isSatellite ? it(e) : Q && e.isNexrad ? Ie(e) : ie && e.isSatellite && (ae.current = !0);
1060
+ } else if (!e.isNexrad && (e.forecastHour !== l.current.forecastHour || e.isMRMS && e.mrmsTimestamp !== l.current.mrmsTimestamp)) {
1061
+ const i = yt(e);
1062
+ i || (Z("timelineGpuUpdateMiss", {
1063
+ isMRMS: e.isMRMS,
1064
+ variable: e.variable,
1065
+ mrmsTimestamp: e.mrmsTimestamp,
1066
+ forecastHour: e.forecastHour
1067
+ }), ne.current = !1, it(e)), i && e.opacity !== Ve.opacity && Me(u => ({
1068
+ ...u,
1069
+ opacity: e.opacity
1070
+ }));
1582
1071
  }
1583
- if (SATELLITE_NATIVE && newState.isSatellite) {
1584
- satBridgeWarn('handleStateChange satellite', {
1585
- satelliteInstrumentId: newState.satelliteInstrumentId ?? null,
1586
- satelliteSectorLabel: newState.satelliteSectorLabel ?? null,
1587
- satelliteChannel: newState.satelliteChannel ?? null,
1588
- timelineKeys: Object.keys(newState.satelliteTimeToFileMap || {}).length,
1589
- refHasSync: Boolean(satelliteLayerRef.current?.syncSatellite)
1072
+ if (Q && e.isNexrad ? Ie(e) : Q && !e.isNexrad && (X.current?.destroy(), X.current = null), ie && e.isSatellite) {
1073
+ Ee("handleStateChange \u2192 satellite", {
1074
+ satelliteInstrumentId: e.satelliteInstrumentId ?? null,
1075
+ satelliteSectorLabel: e.satelliteSectorLabel ?? null,
1076
+ satelliteChannel: e.satelliteChannel ?? null,
1077
+ timelineKeys: Object.keys(e.satelliteTimeToFileMap || {}).length,
1078
+ refHasSync: !!Ne.current?.syncSatellite
1590
1079
  });
1591
- const satCtl = ensureSatelliteController();
1592
- if (satCtl) {
1593
- hasInitialLoad.current = true;
1594
- void satCtl.sync(newState);
1595
- } else {
1596
- satBridgeWarn('handleStateChange satellite: ensureSatelliteController returned null', {});
1597
- }
1598
- if (!newState.satelliteInstrumentId && typeof __DEV__ !== 'undefined' && __DEV__) {
1599
- console.warn('[AguaceroWX][satellite] isSatellite is true but satelliteInstrumentId is missing — native sync still runs; timeline may be empty until core sets instrument.');
1600
- }
1601
- } else if (SATELLITE_NATIVE && !newState.isSatellite) {
1602
- satelliteControllerRef.current?.destroy();
1603
- satelliteControllerRef.current = null;
1604
- }
1605
- previousStateRef.current = newState;
1080
+ const i = at();
1081
+ i ? (ae.current = !0, i.sync(e)) : Ee("handleStateChange satellite: ensureSatelliteController returned null", {}), !e.satelliteInstrumentId && typeof __DEV__ < "u" && __DEV__ && console.warn("[AguaceroWX][satellite] isSatellite is true but satelliteInstrumentId is missing \u2014 native sync still runs; timeline may be empty until core sets instrument.");
1082
+ } else ie && !e.isSatellite && (re.current?.destroy(), re.current = null);
1083
+ l.current = e;
1606
1084
  };
1607
- handleStateChangeRef.current = handleStateChange;
1608
- const stableHandler = newState => {
1609
- lastEmittedStateForInspectRef.current = newState;
1610
- setNexradSitesMapVisible(Boolean(newState.isNexrad && newState.nexradShowSitesPicker !== false));
1611
- // OPTIMIZATION: If playing (high speed), prioritize MAP update and skip debounce
1612
- if (newState.isPlaying) {
1613
- // 1. Update Map FIRST (Native Enqueue)
1614
- if (handleStateChangeRef.current) {
1615
- handleStateChangeRef.current(newState);
1616
- }
1617
-
1618
- // 2. Update UI Slider SECOND
1619
- // This ensures the heavy map frame is processing while React reconciles the slider
1620
- props.onStateChange?.(newState);
1621
- if (debounceTimeoutRef.current) {
1622
- clearTimeout(debounceTimeoutRef.current);
1623
- debounceTimeoutRef.current = null;
1624
- }
1085
+ he.current = r;
1086
+ const a = e => {
1087
+ if (st(!!(e.isNexrad && e.nexradShowSitesPicker !== !1)), e.isPlaying) {
1088
+ he.current && he.current(e), m.onStateChange?.(e), le.current && (clearTimeout(le.current), le.current = null);
1625
1089
  return;
1626
1090
  }
1627
-
1628
- // --- Existing Logic for scrubbing/paused ---
1629
-
1630
- // 1. Immediate Slider Update for responsiveness
1631
- props.onStateChange?.(newState);
1632
- if (debounceTimeoutRef.current) {
1633
- clearTimeout(debounceTimeoutRef.current);
1634
- }
1635
- const prevStable = previousStateRef.current;
1636
- const sameTimelineStable = prevStable && (prevStable.isNexrad ? newState.nexradTimestamp === prevStable.nexradTimestamp && newState.nexradSite === prevStable.nexradSite && newState.nexradProduct === prevStable.nexradProduct && Number(newState.nexradTilt) === Number(prevStable.nexradTilt) && newState.nexradDurationValue === prevStable.nexradDurationValue && nexradObsTimelineSig(newState) === nexradObsTimelineSig(prevStable) : prevStable.isSatellite ? newState.satelliteTimestamp === prevStable.satelliteTimestamp && newState.satelliteInstrumentId === prevStable.satelliteInstrumentId && newState.satelliteSectorLabel === prevStable.satelliteSectorLabel && newState.satelliteChannel === prevStable.satelliteChannel && newState.satelliteDurationValue === prevStable.satelliteDurationValue && satelliteObsTimelineSig(newState) === satelliteObsTimelineSig(prevStable) : newState.forecastHour === prevStable.forecastHour && newState.mrmsTimestamp === prevStable.mrmsTimestamp);
1637
- const sameModeStable = prevStable && (newState.isSatellite ? newState.satelliteInstrumentId === prevStable.satelliteInstrumentId && newState.satelliteSectorLabel === prevStable.satelliteSectorLabel && newState.satelliteChannel === prevStable.satelliteChannel : newState.model === prevStable.model && newState.isMRMS === prevStable.isMRMS);
1638
-
1639
- // Opacity and Play state changes should be immediate for the native layer too
1640
- const isOpacityOnlyChange = prevStable && sameTimelineStable && sameModeStable && newState.opacity !== prevStable.opacity && newState.variable === prevStable.variable && newState.units === prevStable.units;
1641
- const isPlayStateOnlyChange = prevStable && sameTimelineStable && sameModeStable && newState.isPlaying !== prevStable.isPlaying && newState.variable === prevStable.variable && newState.units === prevStable.units && newState.opacity === prevStable.opacity;
1642
- if (isOpacityOnlyChange || isPlayStateOnlyChange || !previousStateRef.current) {
1643
- if (handleStateChangeRef.current) {
1644
- handleStateChangeRef.current(newState);
1645
- }
1091
+ m.onStateChange?.(e), le.current && clearTimeout(le.current);
1092
+ const o = l.current,
1093
+ F = o && (o.isNexrad ? e.nexradTimestamp === o.nexradTimestamp && e.nexradSite === o.nexradSite && e.nexradProduct === o.nexradProduct && Number(e.nexradTilt) === Number(o.nexradTilt) : o.isSatellite ? e.satelliteTimestamp === o.satelliteTimestamp && e.satelliteInstrumentId === o.satelliteInstrumentId && e.satelliteSectorLabel === o.satelliteSectorLabel && e.satelliteChannel === o.satelliteChannel && e.satelliteDurationValue === o.satelliteDurationValue && ue(e) === ue(o) : e.forecastHour === o.forecastHour && e.mrmsTimestamp === o.mrmsTimestamp),
1094
+ s = o && (e.isSatellite ? e.satelliteInstrumentId === o.satelliteInstrumentId && e.satelliteSectorLabel === o.satelliteSectorLabel && e.satelliteChannel === o.satelliteChannel : e.model === o.model && e.isMRMS === o.isMRMS),
1095
+ w = o && F && s && e.opacity !== o.opacity && e.variable === o.variable && e.units === o.units,
1096
+ N = o && F && s && e.isPlaying !== o.isPlaying && e.variable === o.variable && e.units === o.units && e.opacity === o.opacity;
1097
+ if (w || N || !l.current) {
1098
+ he.current && he.current(e);
1646
1099
  return;
1647
1100
  }
1648
- debounceTimeoutRef.current = setTimeout(() => {
1649
- if (handleStateChangeRef.current) {
1650
- handleStateChangeRef.current(newState);
1651
- }
1652
- debounceTimeoutRef.current = null;
1653
- }, 16); // ~60fps map updates
1101
+ le.current = setTimeout(() => {
1102
+ he.current && he.current(e), le.current = null;
1103
+ }, 16);
1654
1104
  };
1655
- core.on('state:change', stableHandler);
1656
- return () => {
1657
- core.off('state:change', stableHandler);
1658
- if (debounceTimeoutRef.current) {
1659
- clearTimeout(debounceTimeoutRef.current);
1660
- }
1661
- if (NEXRAD_NATIVE) {
1662
- nexradPreloadInteractionRef.current?.cancel?.();
1663
- nexradPreloadInteractionRef.current = null;
1664
- nexradControllerRef.current?.destroy();
1665
- nexradControllerRef.current = null;
1666
- }
1667
- if (SATELLITE_NATIVE) {
1668
- satelliteControllerRef.current?.destroy();
1669
- satelliteControllerRef.current = null;
1670
- }
1671
- };
1672
- }, [core, ensureNexradController, ensureSatelliteController]);
1673
- useEffect(() => {
1674
- return () => {
1675
- preloadedDataCache.current.clear(); // This drops JS references
1676
- hasInitialLoad.current = false;
1677
- lastProcessedState.current = null;
1678
- // Native cleanup
1679
- if (gridLayerRef.current && Platform.OS === 'ios') {
1680
- gridLayerRef.current.clearGpuCache();
1681
- }
1682
- if (NEXRAD_NATIVE) {
1683
- nexradPreloadInteractionRef.current?.cancel?.();
1684
- nexradPreloadInteractionRef.current = null;
1685
- nexradControllerRef.current?.destroy();
1686
- nexradControllerRef.current = null;
1687
- }
1688
- if (SATELLITE_NATIVE) {
1689
- satelliteControllerRef.current?.destroy();
1690
- satelliteControllerRef.current = null;
1691
- }
1105
+ return t.on("state:change", a), () => {
1106
+ t.off("state:change", a), le.current && clearTimeout(le.current), Q && (X.current?.destroy(), X.current = null), ie && (re.current?.destroy(), re.current = null);
1692
1107
  };
1108
+ }, [t, at, Ie]), j(() => () => {
1109
+ W.current.clear(), ae.current = !1, He.current = null, p.current && se.OS === "ios" && p.current.clearGpuCache(), Q && (X.current?.destroy(), X.current = null), ie && (re.current?.destroy(), re.current = null);
1693
1110
  }, []);
1694
- const lastInspectorUpdateRef = useRef(0);
1695
- const INSPECTOR_THROTTLE_MS = 50;
1696
- useEffect(() => {
1697
- if (!core || !inspectorEnabled) {
1698
- return;
1699
- }
1700
- const handleMapMove = center => {
1701
- if (!center || !Array.isArray(center) || center.length !== 2) {
1702
- return;
1703
- }
1704
-
1705
- // Throttle updates
1706
- const now = Date.now();
1707
- if (now - lastInspectorUpdateRef.current < INSPECTOR_THROTTLE_MS) {
1708
- return;
1709
- }
1710
- lastInspectorUpdateRef.current = now;
1711
- const [longitude, latitude] = center;
1712
- if (NEXRAD_NATIVE && core.state?.isNexrad) {
1713
- onInspect?.(getNexradInspectPayloadAtRef.current(longitude, latitude));
1714
- return;
1715
- }
1716
- void getValueAtPointRef.current(longitude, latitude).then(payload => {
1717
- onInspect?.(payload);
1111
+ const ot = V(0),
1112
+ bt = 50;
1113
+ j(() => {
1114
+ if (!t || !g) return;
1115
+ const r = a => {
1116
+ if (!a || !Array.isArray(a) || a.length !== 2) return;
1117
+ const e = Date.now();
1118
+ if (e - ot.current < bt) return;
1119
+ ot.current = e;
1120
+ const [o, F] = a;
1121
+ We.current(o, F).then(s => {
1122
+ I?.(s);
1718
1123
  });
1719
1124
  };
1720
- core.on('map:move', handleMapMove);
1721
- if (context && context.getCenter) {
1722
- const center = context.getCenter();
1723
- if (center) {
1724
- handleMapMove(center);
1725
- }
1125
+ if (t.on("map:move", r), _e && _e.getCenter) {
1126
+ const a = _e.getCenter();
1127
+ a && r(a);
1726
1128
  }
1727
1129
  return () => {
1728
- core.off('map:move', handleMapMove);
1729
- };
1730
- }, [inspectorEnabled, onInspect, core, context]);
1731
- useEffect(() => {
1732
- if (!core || !inspectorEnabled) {
1733
- return;
1734
- }
1735
- const triggerReinspection = () => {
1736
- const mapRef = mapRegistry.getMap();
1737
- const center = mapRef?._currentCenter;
1738
- if (center && Array.isArray(center) && center.length === 2) {
1739
- const [longitude, latitude] = center;
1740
- if (NEXRAD_NATIVE && core?.state?.isNexrad) {
1741
- onInspect?.(getNexradInspectPayloadAtRef.current(longitude, latitude));
1742
- } else {
1743
- getValueAtPointRef.current(longitude, latitude).then(payload => {
1744
- onInspect?.(payload);
1745
- });
1746
- }
1747
- }
1130
+ t.off("map:move", r);
1748
1131
  };
1749
-
1750
- // Small delay to ensure data is loaded before re-inspecting
1751
- const timer = setTimeout(triggerReinspection, 100);
1752
- return () => clearTimeout(timer);
1753
- }, [core?.state?.nexradTimestamp, core?.state?.isNexrad, core?.state?.nexradSite, core?.state?.nexradProduct, core?.state?.nexradTilt, core?.state?.nexradDataSource, core?.state?.nexradStormRelative, core?.state?.variable, core?.state?.model, core?.state?.forecastHour, core?.state?.mrmsTimestamp, core?.state?.units, core?.state?.opacity, inspectorEnabled, onInspect]);
1754
- useEffect(() => {
1755
- if (!core) {
1756
- return;
1757
- }
1758
- const handleCameraChange = center => {
1759
- if (core && center) {
1760
- core.setMapCenter(center);
1132
+ }, [g, I, t, _e]), j(() => {
1133
+ if (!t || !g) return;
1134
+ const r = setTimeout(() => {
1135
+ const a = Ue.getMap()?._currentCenter;
1136
+ if (a && Array.isArray(a) && a.length === 2) {
1137
+ const [e, o] = a;
1138
+ We.current(e, o).then(F => {
1139
+ I?.(F);
1140
+ });
1761
1141
  }
1142
+ }, 100);
1143
+ return () => clearTimeout(r);
1144
+ }, [t?.state?.nexradTimestamp, t?.state?.isNexrad, t?.state?.nexradSite, t?.state?.nexradProduct, t?.state?.nexradTilt, t?.state?.nexradDataSource, t?.state?.nexradStormRelative, t?.state?.variable, t?.state?.model, t?.state?.forecastHour, t?.state?.mrmsTimestamp, t?.state?.units, t?.state?.opacity, g, I]), j(() => {
1145
+ if (!t) return;
1146
+ const r = e => {
1147
+ t && e && t.setMapCenter(e);
1762
1148
  };
1763
-
1764
- // Register with the global registry
1765
- mapRegistry.addCameraListener(handleCameraChange);
1766
-
1767
- // Try to get initial center
1768
- const mapRef = mapRegistry.getMap();
1769
- if (mapRef?._currentCenter) {
1770
- handleCameraChange(mapRef._currentCenter);
1771
- }
1772
- return () => {
1773
- mapRegistry.removeCameraListener(handleCameraChange);
1774
- };
1775
- }, [core]);
1776
- useEffect(() => {
1777
- core.initialize({
1778
- autoRefresh: false
1779
- }); // <-- add the argument
1780
- return () => {
1781
- core.destroy();
1149
+ Ue.addCameraListener(r);
1150
+ const a = Ue.getMap();
1151
+ return a?._currentCenter && r(a._currentCenter), () => {
1152
+ Ue.removeCameraListener(r);
1782
1153
  };
1783
- }, [core]);
1784
- const gridBelowId = belowIDFromProps ?? context?.weatherBeforeLayerId ?? 'AML_-_terrain';
1785
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(GridRenderLayer, {
1786
- ref: gridLayerRef,
1787
- opacity: renderProps.opacity,
1788
- dataRange: renderProps.dataRange,
1789
- belowID: gridBelowId
1790
- }), NEXRAD_NATIVE ? /*#__PURE__*/React.createElement(NexradRadarLayer, {
1791
- ref: nexradLayerRef,
1792
- belowID: gridBelowId
1793
- }) : null, SATELLITE_NATIVE ? /*#__PURE__*/React.createElement(SatelliteLayer, {
1794
- ref: satelliteLayerRef,
1795
- belowID: gridBelowId
1796
- }) : null, /*#__PURE__*/React.createElement(NwsAlertsOverlay, {
1797
- core: core,
1798
- watchesWarnings: watchesWarningsOptions,
1799
- onNwsAlertClick: onNwsAlertClick
1800
- }), nexradSitesMapVisible ? /*#__PURE__*/React.createElement(NexradSitesMapLayer, {
1801
- visible: true,
1802
- belowLayerID: gridBelowId,
1803
- onSelectSite: siteId => void core.setNexradSite(siteId)
1154
+ }, [t]), j(() => (t.initialize({
1155
+ autoRefresh: !1
1156
+ }), () => {
1157
+ t.destroy();
1158
+ }), [t]);
1159
+ const Oe = Te ?? _e?.weatherBeforeLayerId ?? "AML_-_terrain";
1160
+ return /*#__PURE__*/be.createElement(be.Fragment, null, /*#__PURE__*/be.createElement(_t, {
1161
+ ref: p,
1162
+ opacity: Ve.opacity,
1163
+ dataRange: Ve.dataRange,
1164
+ belowID: Oe
1165
+ }), Q ? /*#__PURE__*/be.createElement(Nt, {
1166
+ ref: rt,
1167
+ belowID: Oe
1168
+ }) : null, ie ? /*#__PURE__*/be.createElement(Dt, {
1169
+ ref: Ne,
1170
+ belowID: Oe
1171
+ }) : null, /*#__PURE__*/be.createElement(Pt, {
1172
+ core: t,
1173
+ watchesWarnings: gt,
1174
+ onNwsAlertClick: Ge
1175
+ }), St ? /*#__PURE__*/be.createElement(It, {
1176
+ visible: !0,
1177
+ belowLayerID: Oe,
1178
+ onSelectSite: r => void t.setNexradSite(r)
1804
1179
  }) : null);
1805
1180
  });
1806
- WeatherLayerManager.getAvailableVariables = options => {
1807
- if (!options || !options.apiKey) {
1808
- return [];
1809
- }
1810
- const core = new AguaceroCore({
1811
- apiKey: options.apiKey
1812
- });
1813
- return core.getAvailableVariables('mrms');
1814
- };
1181
+ WeatherLayerManager.getAvailableVariables = m => !m || !m.apiKey ? [] : new je({
1182
+ apiKey: m.apiKey
1183
+ }).getAvailableVariables("mrms");
1815
1184
  //# sourceMappingURL=WeatherLayerManager.js.map