@opengeoweb/soundings 19.4.0 → 19.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -212,8 +212,27 @@ var dTdp = function dTdp(pressure, temperature) {
212
212
  var dTdp2 = dTdp1 / (1.0 + Rs / (7.0 * EPSILON) + Math.pow(Lv / temperature, 2) * Rs * EPSILON / (R_AIR * HEATCP));
213
213
  return dTdp2;
214
214
  };
215
+ var MAX_THETA_CACHE_SIZE = 50000;
216
+ var thetaFromPressTempCache = new Map();
217
+ var buildThetaCacheKey = function buildThetaCacheKey(pressure, temperature, basePressure) {
218
+ return pressure.toFixed(6) + "|" + temperature.toFixed(6) + "|" + basePressure.toFixed(6);
219
+ };
220
+ var setThetaCacheValue = function setThetaCacheValue(key, value) {
221
+ if (thetaFromPressTempCache.size >= MAX_THETA_CACHE_SIZE) {
222
+ var oldestKey = thetaFromPressTempCache.keys().next().value;
223
+ if (oldestKey !== undefined) {
224
+ thetaFromPressTempCache["delete"](oldestKey);
225
+ }
226
+ }
227
+ thetaFromPressTempCache.set(key, value);
228
+ };
215
229
  var calculateThetaFromPressTemp = function calculateThetaFromPressTemp(pressure, temperature, basePressure) {
216
230
  var base = basePressure || REFERENCE_PRESSURE;
231
+ var cacheKey = buildThetaCacheKey(pressure, temperature, base);
232
+ var cachedValue = thetaFromPressTempCache.get(cacheKey);
233
+ if (cachedValue !== undefined) {
234
+ return cachedValue;
235
+ }
217
236
  var dpPascal = pressure > base ? pressToPascal(-10) : pressToPascal(10); // hPa steps to Pa steps
218
237
  var numberOfSteps = Math.round((base - pressure) / dpPascal) < 1 ? 1 : Math.round((base - pressure) / dpPascal);
219
238
  var pstep = (base - pressure) / numberOfSteps;
@@ -227,6 +246,7 @@ var calculateThetaFromPressTemp = function calculateThetaFromPressTemp(pressure,
227
246
  tempN += k1 / 6.0 + k2 / 3.0 + k3 / 3.0 + k4 / 6.0;
228
247
  pressureN += pstep;
229
248
  }
249
+ setThetaCacheValue(cacheKey, tempN);
230
250
  return tempN;
231
251
  };
232
252
 
@@ -1202,6 +1222,25 @@ var soundingsQueryOptions = {
1202
1222
  }(),
1203
1223
  refetchInterval: 5 * 60 * 1000
1204
1224
  });
1225
+ },
1226
+ getCollectionDetails: function getCollectionDetails$1(collectionId, url) {
1227
+ return queryOptions({
1228
+ queryKey: ['edr-soundings-collection-details', collectionId, url],
1229
+ queryFn: function () {
1230
+ var _queryFn2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
1231
+ return _regenerator().w(function (_context2) {
1232
+ while (1) switch (_context2.n) {
1233
+ case 0:
1234
+ return _context2.a(2, getCollectionDetails(collectionId, url));
1235
+ }
1236
+ }, _callee2);
1237
+ }));
1238
+ function queryFn() {
1239
+ return _queryFn2.apply(this, arguments);
1240
+ }
1241
+ return queryFn;
1242
+ }()
1243
+ });
1205
1244
  }
1206
1245
  };
1207
1246
 
@@ -1791,7 +1830,7 @@ var useTimesteps = function useTimesteps(sourceSelections) {
1791
1830
  return _context3.a(2, instanceData);
1792
1831
  case 3:
1793
1832
  _context3.n = 4;
1794
- return getCollectionDetails(collectionId, url);
1833
+ return queryClient.fetchQuery(soundingsQueryOptions.getCollectionDetails(collectionId, url));
1795
1834
  case 4:
1796
1835
  collectionData = _context3.v;
1797
1836
  return _context3.a(2, collectionData);
@@ -1857,29 +1896,9 @@ var useGetCollectionsInstances = function useGetCollectionsInstances(collections
1857
1896
  return collectionIds.map(function (_ref4) {
1858
1897
  var id = _ref4.id,
1859
1898
  url = _ref4.url;
1860
- return {
1861
- queryKey: ['edr-soundings-collection-details', id, url],
1862
- queryFn: function () {
1863
- var _queryFn4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
1864
- var data;
1865
- return _regenerator().w(function (_context4) {
1866
- while (1) switch (_context4.n) {
1867
- case 0:
1868
- _context4.n = 1;
1869
- return getCollectionDetails(id, url);
1870
- case 1:
1871
- data = _context4.v;
1872
- return _context4.a(2, data);
1873
- }
1874
- }, _callee4);
1875
- }));
1876
- function queryFn() {
1877
- return _queryFn4.apply(this, arguments);
1878
- }
1879
- return queryFn;
1880
- }(),
1899
+ return Object.assign({}, soundingsQueryOptions.getCollectionDetails(id, url), {
1881
1900
  enabled: isDialogOpen
1882
- };
1901
+ });
1883
1902
  });
1884
1903
  }, [collectionIds, isDialogOpen]);
1885
1904
  var resultsCollection = useQueries({
@@ -1965,61 +1984,61 @@ var useGetLocations = function useGetLocations(collections, enabled) {
1965
1984
  return {
1966
1985
  queryKey: ['edr-locations', collection.id, collection.url, (_collection$instanceI = collection.instanceId) != null ? _collection$instanceI : ''],
1967
1986
  queryFn: function () {
1968
- var _queryFn5 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
1987
+ var _queryFn4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
1969
1988
  var resolvedInstanceId, instances, resolved, locationsExplicitlyUnsupported, _locations, locations;
1970
- return _regenerator().w(function (_context5) {
1971
- while (1) switch (_context5.p = _context5.n) {
1989
+ return _regenerator().w(function (_context4) {
1990
+ while (1) switch (_context4.p = _context4.n) {
1972
1991
  case 0:
1973
1992
  resolvedInstanceId = collection.instanceId;
1974
1993
  if (!(resolvedInstanceId && referenceTimeUtils.isRelativeReferenceTime(resolvedInstanceId))) {
1975
- _context5.n = 4;
1994
+ _context4.n = 4;
1976
1995
  break;
1977
1996
  }
1978
- _context5.p = 1;
1979
- _context5.n = 2;
1997
+ _context4.p = 1;
1998
+ _context4.n = 2;
1980
1999
  return queryClient.fetchQuery(soundingsQueryOptions.getCollectionInstances(collection.id, collection.url));
1981
2000
  case 2:
1982
- instances = _context5.v;
2001
+ instances = _context4.v;
1983
2002
  resolved = referenceTimeUtils.resolveReferenceTimeInstance(instances.instances, resolvedInstanceId); // Skip instance-level only when data_queries is present but explicitly excludes locations — if data_queries is absent, try instance-level anyway
1984
2003
  locationsExplicitlyUnsupported = (resolved == null ? void 0 : resolved.data_queries) !== undefined && !resolved.data_queries.locations;
1985
2004
  resolvedInstanceId = locationsExplicitlyUnsupported ? undefined : resolved == null ? void 0 : resolved.id;
1986
- _context5.n = 4;
2005
+ _context4.n = 4;
1987
2006
  break;
1988
2007
  case 3:
1989
- _context5.p = 3;
1990
- _context5.v;
2008
+ _context4.p = 3;
2009
+ _context4.v;
1991
2010
  resolvedInstanceId = undefined;
1992
2011
  case 4:
1993
2012
  if (!resolvedInstanceId) {
1994
- _context5.n = 8;
2013
+ _context4.n = 8;
1995
2014
  break;
1996
2015
  }
1997
- _context5.p = 5;
1998
- _context5.n = 6;
2016
+ _context4.p = 5;
2017
+ _context4.n = 6;
1999
2018
  return getInstanceLocations(collection.id, resolvedInstanceId, collection.url);
2000
2019
  case 6:
2001
- _locations = _context5.v;
2002
- return _context5.a(2, Object.assign({}, _locations, {
2020
+ _locations = _context4.v;
2021
+ return _context4.a(2, Object.assign({}, _locations, {
2003
2022
  id: collection.id,
2004
2023
  name: collection.name
2005
2024
  }));
2006
2025
  case 7:
2007
- _context5.p = 7;
2008
- _context5.v;
2026
+ _context4.p = 7;
2027
+ _context4.v;
2009
2028
  case 8:
2010
- _context5.n = 9;
2029
+ _context4.n = 9;
2011
2030
  return getCollectionLocations(collection.id, collection.url);
2012
2031
  case 9:
2013
- locations = _context5.v;
2014
- return _context5.a(2, Object.assign({}, locations, {
2032
+ locations = _context4.v;
2033
+ return _context4.a(2, Object.assign({}, locations, {
2015
2034
  id: collection.id,
2016
2035
  name: collection.name
2017
2036
  }));
2018
2037
  }
2019
- }, _callee5, null, [[5, 7], [1, 3]]);
2038
+ }, _callee4, null, [[5, 7], [1, 3]]);
2020
2039
  }));
2021
2040
  function queryFn() {
2022
- return _queryFn5.apply(this, arguments);
2041
+ return _queryFn4.apply(this, arguments);
2023
2042
  }
2024
2043
  return queryFn;
2025
2044
  }(),
@@ -2069,48 +2088,48 @@ var useCheckPositionQuerySupportBySource = function useCheckPositionQuerySupport
2069
2088
  return {
2070
2089
  queryKey: ['edr-position-support', collectionId, instanceId || ''],
2071
2090
  queryFn: function () {
2072
- var _queryFn6 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
2091
+ var _queryFn5 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
2073
2092
  var _details$data_queries, _instance$data_querie, instances, instance, details;
2074
- return _regenerator().w(function (_context6) {
2075
- while (1) switch (_context6.p = _context6.n) {
2093
+ return _regenerator().w(function (_context5) {
2094
+ while (1) switch (_context5.p = _context5.n) {
2076
2095
  case 0:
2077
- _context6.p = 0;
2096
+ _context5.p = 0;
2078
2097
  if (!instanceId) {
2079
- _context6.n = 2;
2098
+ _context5.n = 2;
2080
2099
  break;
2081
2100
  }
2082
- _context6.n = 1;
2101
+ _context5.n = 1;
2083
2102
  return queryClient.fetchQuery(soundingsQueryOptions.getCollectionInstances(collectionId, url));
2084
2103
  case 1:
2085
- instances = _context6.v;
2104
+ instances = _context5.v;
2086
2105
  instance = instances.instances.find(function (i) {
2087
2106
  return i.id === instanceId;
2088
2107
  });
2089
- return _context6.a(2, {
2108
+ return _context5.a(2, {
2090
2109
  collectionId: collectionId,
2091
2110
  supported: !!(instance != null && (_instance$data_querie = instance.data_queries) != null && _instance$data_querie.position)
2092
2111
  });
2093
2112
  case 2:
2094
- _context6.n = 3;
2095
- return getCollectionDetails(collectionId, url);
2113
+ _context5.n = 3;
2114
+ return queryClient.fetchQuery(soundingsQueryOptions.getCollectionDetails(collectionId, url));
2096
2115
  case 3:
2097
- details = _context6.v;
2098
- return _context6.a(2, {
2116
+ details = _context5.v;
2117
+ return _context5.a(2, {
2099
2118
  collectionId: collectionId,
2100
2119
  supported: !!(details != null && (_details$data_queries = details.data_queries) != null && _details$data_queries.position)
2101
2120
  });
2102
2121
  case 4:
2103
- _context6.p = 4;
2104
- _context6.v;
2105
- return _context6.a(2, {
2122
+ _context5.p = 4;
2123
+ _context5.v;
2124
+ return _context5.a(2, {
2106
2125
  collectionId: collectionId,
2107
2126
  supported: false
2108
2127
  });
2109
2128
  }
2110
- }, _callee6, null, [[0, 4]]);
2129
+ }, _callee5, null, [[0, 4]]);
2111
2130
  }));
2112
2131
  function queryFn() {
2113
- return _queryFn6.apply(this, arguments);
2132
+ return _queryFn5.apply(this, arguments);
2114
2133
  }
2115
2134
  return queryFn;
2116
2135
  }(),
@@ -2166,48 +2185,48 @@ var useCheckRadiusQuerySupportBySource = function useCheckRadiusQuerySupportBySo
2166
2185
  return {
2167
2186
  queryKey: ['edr-radius-support', collectionId, instanceId || ''],
2168
2187
  queryFn: function () {
2169
- var _queryFn7 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
2188
+ var _queryFn6 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
2170
2189
  var _details$data_queries2, _instance$data_querie2, instances, instance, details;
2171
- return _regenerator().w(function (_context7) {
2172
- while (1) switch (_context7.p = _context7.n) {
2190
+ return _regenerator().w(function (_context6) {
2191
+ while (1) switch (_context6.p = _context6.n) {
2173
2192
  case 0:
2174
- _context7.p = 0;
2193
+ _context6.p = 0;
2175
2194
  if (!instanceId) {
2176
- _context7.n = 2;
2195
+ _context6.n = 2;
2177
2196
  break;
2178
2197
  }
2179
- _context7.n = 1;
2198
+ _context6.n = 1;
2180
2199
  return queryClient.fetchQuery(soundingsQueryOptions.getCollectionInstances(collectionId, url));
2181
2200
  case 1:
2182
- instances = _context7.v;
2201
+ instances = _context6.v;
2183
2202
  instance = instances.instances.find(function (i) {
2184
2203
  return i.id === instanceId;
2185
2204
  });
2186
- return _context7.a(2, {
2205
+ return _context6.a(2, {
2187
2206
  collectionId: collectionId,
2188
2207
  supported: !!(instance != null && (_instance$data_querie2 = instance.data_queries) != null && _instance$data_querie2.radius)
2189
2208
  });
2190
2209
  case 2:
2191
- _context7.n = 3;
2192
- return getCollectionDetails(collectionId, url);
2210
+ _context6.n = 3;
2211
+ return queryClient.fetchQuery(soundingsQueryOptions.getCollectionDetails(collectionId, url));
2193
2212
  case 3:
2194
- details = _context7.v;
2195
- return _context7.a(2, {
2213
+ details = _context6.v;
2214
+ return _context6.a(2, {
2196
2215
  collectionId: collectionId,
2197
2216
  supported: !!(details != null && (_details$data_queries2 = details.data_queries) != null && _details$data_queries2.radius)
2198
2217
  });
2199
2218
  case 4:
2200
- _context7.p = 4;
2201
- _context7.v;
2202
- return _context7.a(2, {
2219
+ _context6.p = 4;
2220
+ _context6.v;
2221
+ return _context6.a(2, {
2203
2222
  collectionId: collectionId,
2204
2223
  supported: false
2205
2224
  });
2206
2225
  }
2207
- }, _callee7, null, [[0, 4]]);
2226
+ }, _callee6, null, [[0, 4]]);
2208
2227
  }));
2209
2228
  function queryFn() {
2210
- return _queryFn7.apply(this, arguments);
2229
+ return _queryFn6.apply(this, arguments);
2211
2230
  }
2212
2231
  return queryFn;
2213
2232
  }(),
@@ -2269,20 +2288,20 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
2269
2288
  return {
2270
2289
  queryKey: ['edr-grid-points-disabled', collectionId],
2271
2290
  queryFn: function () {
2272
- var _queryFn8 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
2273
- return _regenerator().w(function (_context8) {
2274
- while (1) switch (_context8.n) {
2291
+ var _queryFn7 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
2292
+ return _regenerator().w(function (_context7) {
2293
+ while (1) switch (_context7.n) {
2275
2294
  case 0:
2276
- return _context8.a(2, {
2295
+ return _context7.a(2, {
2277
2296
  sourceId: collectionId,
2278
2297
  gridPoint: undefined,
2279
2298
  allGridPoints: []
2280
2299
  });
2281
2300
  }
2282
- }, _callee8);
2301
+ }, _callee7);
2283
2302
  }));
2284
2303
  function queryFn() {
2285
- return _queryFn8.apply(this, arguments);
2304
+ return _queryFn7.apply(this, arguments);
2286
2305
  }
2287
2306
  return queryFn;
2288
2307
  }(),
@@ -2307,22 +2326,22 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
2307
2326
  return {
2308
2327
  queryKey: ['edr-grid-points-radius', collectionId, instanceId || '', centerCoordinates.join(','), radiusKm.toString(), datetime],
2309
2328
  queryFn: function () {
2310
- var _queryFn9 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9() {
2329
+ var _queryFn8 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
2311
2330
  var minimalParameters, minimalVerticalRange, rawData, allGridPoints, nearestPoint, minSquaredDistance;
2312
- return _regenerator().w(function (_context9) {
2313
- while (1) switch (_context9.p = _context9.n) {
2331
+ return _regenerator().w(function (_context8) {
2332
+ while (1) switch (_context8.p = _context8.n) {
2314
2333
  case 0:
2315
2334
  if (supportsRadius) {
2316
- _context9.n = 1;
2335
+ _context8.n = 1;
2317
2336
  break;
2318
2337
  }
2319
- return _context9.a(2, {
2338
+ return _context8.a(2, {
2320
2339
  sourceId: collectionId,
2321
2340
  gridPoint: undefined,
2322
2341
  allGridPoints: []
2323
2342
  });
2324
2343
  case 1:
2325
- _context9.p = 1;
2344
+ _context8.p = 1;
2326
2345
  // Optimization: Only request a single parameter to minimize data transfer
2327
2346
  // We only need the grid point coordinates, not the actual sounding data
2328
2347
  minimalParameters = parameters.slice(0, 1); // Just one parameter
@@ -2330,10 +2349,10 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
2330
2349
  // (Don't hardcode '1000' as that only works for pressure-level sources,
2331
2350
  // not for hybrid/model-level sources which use levels 1-65)
2332
2351
  minimalVerticalRange = '';
2333
- _context9.n = 2;
2352
+ _context8.n = 2;
2334
2353
  return getEdrCollectionForRadius(collectionId, url, instanceId, centerCoordinates, radiusKm, minimalParameters, datetime, minimalVerticalRange);
2335
2354
  case 2:
2336
- rawData = _context9.v;
2355
+ rawData = _context8.v;
2337
2356
  allGridPoints = extractGridPointsFromCoverage(rawData); // Find the nearest grid point to the center coordinates
2338
2357
  minSquaredDistance = Infinity;
2339
2358
  allGridPoints.forEach(function (point) {
@@ -2348,24 +2367,24 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
2348
2367
  nearestPoint = point;
2349
2368
  }
2350
2369
  });
2351
- return _context9.a(2, {
2370
+ return _context8.a(2, {
2352
2371
  sourceId: collectionId,
2353
2372
  gridPoint: nearestPoint,
2354
2373
  allGridPoints: allGridPoints
2355
2374
  });
2356
2375
  case 3:
2357
- _context9.p = 3;
2358
- _context9.v;
2359
- return _context9.a(2, {
2376
+ _context8.p = 3;
2377
+ _context8.v;
2378
+ return _context8.a(2, {
2360
2379
  sourceId: collectionId,
2361
2380
  gridPoint: undefined,
2362
2381
  allGridPoints: []
2363
2382
  });
2364
2383
  }
2365
- }, _callee9, null, [[1, 3]]);
2384
+ }, _callee8, null, [[1, 3]]);
2366
2385
  }));
2367
2386
  function queryFn() {
2368
- return _queryFn9.apply(this, arguments);
2387
+ return _queryFn8.apply(this, arguments);
2369
2388
  }
2370
2389
  return queryFn;
2371
2390
  }(),
@@ -2767,6 +2786,9 @@ var slice = createSlice({
2767
2786
  panel.isTimeSliderVisible = (_preset$isTimeSliderV = preset.isTimeSliderVisible) != null ? _preset$isTimeSliderV : true;
2768
2787
  panel.isLegendVisible = (_preset$isLegendVisib = preset.isLegendVisible) != null ? _preset$isLegendVisib : true;
2769
2788
  panel.profileDataPreferences = (_preset$profileDataPr = preset.profileDataPreferences) != null ? _preset$profileDataPr : DEFAULT_PROFILE_DATA_PREFERENCES;
2789
+ panel.locationMenuSize = preset.locationMenuSize;
2790
+ panel.locationMenuPosition = preset.locationMenuPosition;
2791
+ panel.isLocationsDialogOpen = preset.isLocationsDialogOpen;
2770
2792
  }
2771
2793
  },
2772
2794
  setSoundingsCollections: function setSoundingsCollections(draft, payloadAction) {
@@ -2897,6 +2919,23 @@ var slice = createSlice({
2897
2919
  customWidth: customWidth
2898
2920
  });
2899
2921
  },
2922
+ setLocationMenuSizeAndPosition: function setLocationMenuSizeAndPosition(draft, payloadAction) {
2923
+ var panel = resolveSoundingsView(draft, payloadAction);
2924
+ if (!panel) {
2925
+ return;
2926
+ }
2927
+ panel.locationMenuSize = payloadAction.payload.size;
2928
+ if (payloadAction.payload.position !== undefined) {
2929
+ panel.locationMenuPosition = payloadAction.payload.position;
2930
+ }
2931
+ },
2932
+ setLocationsMenuOpen: function setLocationsMenuOpen(draft, payloadAction) {
2933
+ var panel = resolveSoundingsView(draft, payloadAction);
2934
+ if (!panel) {
2935
+ return;
2936
+ }
2937
+ panel.isLocationsDialogOpen = payloadAction.payload.isLocationsDialogOpen;
2938
+ },
2900
2939
  notifyViewClosed: function notifyViewClosed(draft) {
2901
2940
  var _draft$resizeOnViewCl;
2902
2941
  draft.resizeOnViewCloseSignal = ((_draft$resizeOnViewCl = draft.resizeOnViewCloseSignal) != null ? _draft$resizeOnViewCl : 0) + 1;
@@ -3046,6 +3085,12 @@ var getSelectedSourcesIds = createSelector(getSelectedSources, function (activeS
3046
3085
  return source.collectionId;
3047
3086
  });
3048
3087
  }, selectorMemoizationOptions);
3088
+ var getLocationMenuSize = createSelector(getSoundingsViewState, function (store) {
3089
+ return store.locationMenuSize;
3090
+ }, selectorMemoizationOptions);
3091
+ var getLocationMenuPosition = createSelector(getSoundingsViewState, function (store) {
3092
+ return store.locationMenuPosition;
3093
+ }, selectorMemoizationOptions);
3049
3094
  var getSoundingsPreset = createSelector(getSoundingsViewState, function (soundingsStore) {
3050
3095
  return Object.assign({}, soundingsStore);
3051
3096
  }, selectorMemoizationOptions);
@@ -3069,6 +3114,8 @@ var selectors = /*#__PURE__*/Object.freeze({
3069
3114
  getDiagramType: getDiagramType,
3070
3115
  getIsLegendVisible: getIsLegendVisible,
3071
3116
  getIsTimeSliderVisible: getIsTimeSliderVisible,
3117
+ getLocationMenuPosition: getLocationMenuPosition,
3118
+ getLocationMenuSize: getLocationMenuSize,
3072
3119
  getLocationSelections: getLocationSelections,
3073
3120
  getPanelCustomWidth: getPanelCustomWidth,
3074
3121
  getPanelIsOpen: getPanelIsOpen,
@@ -3417,13 +3464,21 @@ var MenuBarConnect = function MenuBarConnect(_ref) {
3417
3464
  dispatchActiveMapId(uiTypes.DialogTypes.SoundingsSources, isSourcesOpenInStore, currentActiveMapIdSources);
3418
3465
  break;
3419
3466
  case MenuOptions.locations:
3420
- dispatchActiveMapId(uiTypes.DialogTypes.SoundingsLocations, isLocationsOpenInStore, currentActiveMapIdLocations);
3421
- break;
3467
+ {
3468
+ var newIsLocationsOpen = currentActiveMapIdLocations !== viewId ? true : !isLocationsOpenInStore;
3469
+ dispatchActiveMapId(uiTypes.DialogTypes.SoundingsLocations, isLocationsOpenInStore, currentActiveMapIdLocations);
3470
+ dispatch(soundingsActions.setLocationsMenuOpen({
3471
+ viewId: viewId,
3472
+ isLocationsDialogOpen: newIsLocationsOpen,
3473
+ origin: SoundingsActionOrigin.soundingsComponent
3474
+ }));
3475
+ break;
3476
+ }
3422
3477
  case MenuOptions.profileData:
3423
3478
  dispatchActiveMapId(uiTypes.DialogTypes.SoundingsProfileData, isProfileDataOpenInStore, currentActiveMapIdProfileData);
3424
3479
  break;
3425
3480
  }
3426
- }, [dispatchActiveMapId, isSoundingsManagerOpenInStore, currentActiveMapIdsoundingsManager, isSourcesOpenInStore, currentActiveMapIdSources, isLocationsOpenInStore, currentActiveMapIdLocations, isProfileDataOpenInStore, currentActiveMapIdProfileData]);
3481
+ }, [dispatch, dispatchActiveMapId, viewId, isSoundingsManagerOpenInStore, currentActiveMapIdsoundingsManager, isSourcesOpenInStore, currentActiveMapIdSources, isLocationsOpenInStore, currentActiveMapIdLocations, isProfileDataOpenInStore, currentActiveMapIdProfileData]);
3427
3482
  var isOpen = (_isOpen = {}, _isOpen[MenuOptions.sources] = currentActiveMapIdSources === viewId && isSourcesOpenInStore, _isOpen[MenuOptions.locations] = currentActiveMapIdLocations === viewId && isLocationsOpenInStore, _isOpen[MenuOptions.soundingsManager] = currentActiveMapIdsoundingsManager === viewId && isSoundingsManagerOpenInStore, _isOpen[MenuOptions.profileData] = currentActiveMapIdProfileData === viewId && isProfileDataOpenInStore, _isOpen);
3428
3483
  return jsx(SoundingsMenuBar, {
3429
3484
  handleClick: handleClick,
@@ -4502,6 +4557,7 @@ var drawDryAdiabatsBijvoet = function drawDryAdiabatsBijvoet(_ref2) {
4502
4557
  yScale = _ref2.yScale,
4503
4558
  svg = _ref2.svg,
4504
4559
  d3GraphId = _ref2.d3GraphId;
4560
+ var lineGenerator = d3.line();
4505
4561
  for (var Tbase = -20; Tbase < 40; Tbase += 5) {
4506
4562
  var Px = [];
4507
4563
  var tempKelvin = tempToKelvin(Tbase);
@@ -4515,7 +4571,6 @@ var drawDryAdiabatsBijvoet = function drawDryAdiabatsBijvoet(_ref2) {
4515
4571
  var Tpx = xScale(theta);
4516
4572
  Px.push([Tpx, Ppx]);
4517
4573
  }
4518
- var lineGenerator = d3.line();
4519
4574
  var daPathString = lineGenerator(Px);
4520
4575
  var strID = Tbase + "-dryadiabat";
4521
4576
  svg.append('path').attr('id', strID).attr('d', daPathString).style('fill', 'none').style('stroke-width', 1).style('stroke', 'green').style('opacity', 0.3).attr('clip-path', "url(#clip-" + d3GraphId + "-BIJVOETd3)");
@@ -4617,6 +4672,7 @@ var drawIsothermsBijvoet = function drawIsothermsBijvoet(_ref2) {
4617
4672
  labelSvg = _ref2.labelSvg,
4618
4673
  height = _ref2.height,
4619
4674
  d3GraphId = _ref2.d3GraphId;
4675
+ var lineGenerator = d3.line();
4620
4676
  // lines of constant temperature (2 degree interval from -150...+40C)
4621
4677
  for (var temp = -150; temp <= 40; temp += 2) {
4622
4678
  var _points$;
@@ -4627,7 +4683,6 @@ var drawIsothermsBijvoet = function drawIsothermsBijvoet(_ref2) {
4627
4683
  var theta = calculateThetaFromPressTemp(pressToPascal(pressure), Tiso, REFERENCE_PRESSURE);
4628
4684
  points.push([xScale(theta), yScale(pressure)]);
4629
4685
  }
4630
- var lineGenerator = d3.line();
4631
4686
  var pathString = lineGenerator(points);
4632
4687
  var strID = temp + "-isotherm-BIJVOET";
4633
4688
  svg.append('path').attr('id', strID).attr('d', pathString).style('fill', 'none').style('stroke-width', temp % 10 === 0 ? 2 : 1).style('stroke', temp === 0 ? '#D27D2D' : 'orange').style('stroke-opacity', 0.5).attr('clip-path', "url(#clip-" + d3GraphId + "-BIJVOETd3)");
@@ -4865,113 +4920,472 @@ var drawStaticLines = function drawStaticLines(_ref) {
4865
4920
  }
4866
4921
  };
4867
4922
 
4868
- var shadow$1 = '0 1px 5px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.14)';
4869
- var soundingsStyle$1 = {
4870
- tooltip: {
4871
- display: 'block',
4872
- position: 'absolute',
4873
- borderRadius: '1.5px',
4874
- backgroundColor: 'geowebColors.soundings.tooltip.background',
4875
- boxShadow: shadow$1,
4876
- padding: '2px 4px',
4877
- pointerEvents: 'none',
4878
- zIndex: 500
4879
- },
4880
- pressure: {
4881
- fontSize: '10px'
4882
- },
4883
- temperature: {
4884
- fontSize: '12px',
4885
- fontWeight: 'bold'
4886
- },
4887
- dewPoint: {
4888
- fontSize: '12px',
4889
- fontWeight: 'bold'
4890
- }};
4891
- var updateTransformToViewport = function updateTransformToViewport(transform, width, height) {
4892
- var minX = width * (1 - transform.k);
4893
- var minY = height * (1 - transform.k);
4894
- return d3.zoomIdentity.translate(Math.min(0, Math.max(minX, transform.x)), Math.min(0, Math.max(minY, transform.y))).scale(transform.k);
4923
+ /* *
4924
+ * Licensed under the Apache License, Version 2.0 (the "License");
4925
+ * you may not use this file except in compliance with the License.
4926
+ * You may obtain a copy of the License at
4927
+ *
4928
+ * http://www.apache.org/licenses/LICENSE-2.0
4929
+ *
4930
+ * Unless required by applicable law or agreed to in writing, software
4931
+ * distributed under the License is distributed on an "AS IS" BASIS,
4932
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4933
+ * See the License for the specific language governing permissions and
4934
+ * limitations under the License.
4935
+ *
4936
+ * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
4937
+ * Copyright 2025 - Finnish Meteorological Institute (FMI)
4938
+ * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
4939
+ * */
4940
+ var windSymbolDefinitions = {
4941
+ calm: "<svg width=\"50\" height=\"50\" viewBox=\"0 0 50 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M25 45C36.0456 45 45 36.0456 45 25C45 13.9543 36.0456 5 25 5C13.9543 5 5 13.9543 5 25C5 36.0456 13.9543 45 25 45Z\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
4942
+ lightAir: "<svg width=\"14\" height=\"48\" viewBox=\"0 0 14 48\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M7.22656 4.89307V48.0001M7.22656 43.0262V44.6842\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
4943
+ fiveKnots: "<svg width=\"15\" height=\"49\" viewBox=\"0 0 15 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M8.26953 5.57324V48.608M8.26953 40.5757L0.269531 42.2309\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4944
+ tenKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17.0781 4.64502V44.9031L1.07812 47.9999\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4945
+ fifteenKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.4727 5.55469V45.8128L0.472656 48.9095M16.4727 38.0708L9.61551 39.6192\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
4946
+ twentyKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.8555 4.71924V44.9773L0.855469 48.0741M16.8555 38.4093L0.855469 41.5061\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4947
+ twentyFiveKnots: "<svg width=\"23\" height=\"51\" viewBox=\"0 0 23 51\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.2383 4.94434V46.1541L0.238281 49.3241M16.2383 40.3787L0.238281 43.5486M16.2383 33.9801L9.38114 35.5651\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4948
+ thirtyKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.1914 5.64502V45.9031L0.191406 48.9999M16.1914 40.3459L0.191406 43.4427M16.1914 34.9407L0.191406 38.0375\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4949
+ thirtyFiveKnots: "<svg width=\"19\" height=\"50\" viewBox=\"0 0 19 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M12.0028 4.96729V45.2253L1.16406 48.3221M12.0028 39.6443L1.16406 42.7411M12.0028 34.4793L1.16406 37.576M12.0028 29.2735L7.35761 30.8219\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4950
+ fortyKnots: "<svg width=\"24\" height=\"50\" viewBox=\"0 0 24 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.5391 5.40311V45.6612L0.539062 48.7579M16.5391 40.4525L0.539062 43.5493M16.5391 35.0449L0.539062 38.1417M16.5391 30.2009L0.539062 33.2976\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4951
+ fortyFiveKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.4492 5.4043V45.6624L0.449219 48.7591M16.4492 40.1513L0.449219 43.2481M16.4492 34.7124L0.449219 37.8091M16.4492 29.2013L0.449219 32.2981M16.4492 24.3066L9.59208 25.855\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4952
+ fiftyKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.9062 5.27002V45.5281L0.90625 48.6249L16.9062 37.7861\" fill=\"black\"/>\n<path d=\"M16.9053 5.27002V45.5281L4.35132 47.2337L16.9053 37.7861\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
4953
+ fiftyFiveKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.728 5.55371V45.8118L0.894531 48.9085L16.728 38.0698\" fill=\"black\"/>\n<path d=\"M16.73 5.55371V45.8118L4.33984 47.5245L16.73 38.0698\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.7292 32.7358C13.6376 33.3406 8.8125 34.2842 8.8125 34.2842\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4954
+ sixtyKnots: "<svg width=\"23\" height=\"49\" viewBox=\"0 0 23 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.2891 5.27051V45.5286L0.289062 48.6253L16.2891 37.7866\" fill=\"black\"/>\n<path d=\"M16.2897 5.27051V45.5286L3.7422 47.2478L16.2897 37.7866\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.2891 34.6899L0.289062 37.7867\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4955
+ sixtyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L9.5 28.5\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4956
+ seventyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
4957
+ seventyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 22C13.8251 22.6048 9 23.5484 9 23.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4958
+ eightyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4959
+ eightyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 17C13.8251 17.6048 9 18.5484 9 18.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
4960
+ ninetyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
4961
+ ninetyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 12C13.8251 12.6048 9 13.5484 9 13.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4962
+ hundredKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
4963
+ hundredFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 25C13.8251 25.6048 9 26.5484 9 26.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
4964
+ hundredTenKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4965
+ hundredFifteenKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 21C13.8251 21.6048 9 22.5484 9 22.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4966
+ hundredTwentyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4967
+ hundredTwentyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 17C13.8251 17.6048 9 18.5484 9 18.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
4968
+ hundredThirtyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4969
+ hundredThirtyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 13C13.8251 13.6048 9 14.5484 9 14.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4970
+ hundredFortyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 13C10.7518 14.1718 1 16 1 16\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4971
+ hundredFortyFiveKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 5.26807V25.3971V45.5261L1 48.6229L17 37.7842\" fill=\"black\"/>\n<path d=\"M16.9984 5.26807V30M16.9984 37.7842L4.35938 47.2985L16.9984 45.5261V37.5M16.9984 30C16.9984 30 5.67406 37.7842 4 39M16.9984 30V31.5M4 39C9.07621 38.4142 16.9984 37.5 16.9984 37.5M4 39C9.07621 36.0711 16.9984 31.5 16.9984 31.5M4 39C9.07682 36.6569 17 33 17 33M4 39C9.07621 37.2426 16.9984 34.5 16.9984 34.5M4 39C9.07621 37.8284 16.9984 36 16.9984 36M16.9984 37.5V36M16.9984 31.5V34.5M16.9984 34.5V36\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 12C13.8251 12.6048 9 13.5484 9 13.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 27C10.7518 28.1718 1 30 1 30\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 23C10.7518 24.1718 1 26 1 26\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 19C10.7518 20.1718 1 22 1 22\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 15C10.7518 16.1718 1 18 1 18\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
4972
+ hundredFiftyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V19M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M16.9984 28V26.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34M16.9984 19C16.9984 19 8 25.5 4 29M16.9984 19V20.5M4 29C9.07621 28.0237 16.9984 26.5 16.9984 26.5M4 29C9.07621 25.6805 16.9984 20.5 16.9984 20.5M4 29C9.07621 26.4616 16.9984 22.5 16.9984 22.5M4 29C9.07621 27.0474 16.9984 24 16.9984 24M4 29C9.07621 27.5355 16.9984 25.25 16.9984 25.25M16.9984 26.5V25.25M16.9984 20.5V22.5M16.9984 22.5V24M16.9984 24V25.25\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>"
4895
4973
  };
4896
- var Soundings = function Soundings(_ref) {
4897
- var d3GraphId = _ref.d3GraphId,
4898
- data = _ref.data,
4899
- svgDimensions = _ref.svgDimensions,
4900
- _ref$showTooltip = _ref.showTooltip,
4901
- showTooltip = _ref$showTooltip === void 0 ? true : _ref$showTooltip,
4902
- _ref$diagramType = _ref.diagramType,
4903
- diagramType = _ref$diagramType === void 0 ? 'SKEWT' : _ref$diagramType;
4904
- var instanceId = useId().replace(/:/g, '_');
4905
- var scopedGraphId = d3GraphId + "-" + instanceId;
4906
- var svgRef = useRef(null);
4907
- var canvasRef = useRef(null);
4908
- var pressureRef = useRef(null);
4909
- var tempRef = useRef(null);
4910
- var dewpointRef = useRef(null);
4911
- // Refs to store current scale/data for shared mouse effect
4912
- var yScaleRef = useRef(null);
4913
- var marginRef = useRef(null);
4914
- var widthRef = useRef(0);
4915
- var svgRectRef = useRef(null);
4916
- var tooltipDataRef = useRef(null);
4917
- var zoomBehaviorRef = useRef(null);
4918
- // Keep zoom target on the inner translated <g>; Soundings and WindBarbs must
4919
- // transform the same coordinate space to stay aligned.
4920
- var zoomTargetRef = useRef(null);
4921
- var isApplyingSharedZoomRef = useRef(false);
4922
- // Keep the last applied d3 zoom transform across SVG redraws.
4923
- // Width/height changes recreate the chart, so this ref prevents zoom snapping
4924
- // back to identity when panels are closed/resized.
4925
- var persistedZoomTransformRef = useRef(d3.zoomIdentity);
4926
- var previousDiagramTypeRef = useRef(null);
4927
- var _useSharedMouseY = useSharedMouseY(),
4928
- clientY = _useSharedMouseY.clientY,
4929
- publishVerticalZoom = _useSharedMouseY.publishVerticalZoom,
4930
- verticalZoom = _useSharedMouseY.verticalZoom,
4931
- resetVerticalZoom = _useSharedMouseY.resetVerticalZoom;
4932
- // Set SVG dimensions (required props; no optional chaining needed)
4933
- var baseWidth = svgDimensions.width,
4934
- baseHeight = svgDimensions.height,
4935
- margin = svgDimensions.margin;
4936
- var width = baseWidth - (margin.left + margin.right);
4937
- var height = baseHeight - (margin.top + margin.bottom);
4938
- useEffect(function () {
4939
- if (!svgRef.current || width <= 0 || height <= 0) {
4940
- return;
4941
- }
4942
- var isDiagramTypeChange = previousDiagramTypeRef.current !== null && previousDiagramTypeRef.current !== diagramType;
4943
- if (isDiagramTypeChange) {
4944
- persistedZoomTransformRef.current = d3.zoomIdentity;
4945
- resetVerticalZoom(scopedGraphId);
4946
- }
4947
- var root = d3.select(svgRef.current);
4948
- root.selectAll('*').remove();
4949
- var svg = initializeSvg$1({
4950
- svgRef: svgRef,
4951
- width: width,
4952
- height: height,
4953
- margin: margin,
4954
- diagramType: diagramType,
4955
- d3GraphId: scopedGraphId
4956
- });
4957
- // Create a separate layer for axes so they can stay visible above the zoomed content.
4958
- var axisLayer = svg.append('g').attr('data-layer', 'axis-layer');
4959
- // Keep a static viewport group for clipping, and transform only the inner
4960
- // content group during zoom so the visible area stays fixed.
4961
- var zoomViewport = svg.append('g').attr('data-layer', 'zoom-viewport').attr('clip-path', "url(#clip-" + scopedGraphId + "-" + diagramType + "d3)");
4962
- var zoomContent = zoomViewport.append('g').attr('data-layer', 'zoom-content');
4963
- var bijvoetLabelLayer = svg.append('g').attr('data-layer', 'bijvoet-label-layer').style('pointer-events', 'none');
4964
- var svgRectangle = svgRef.current.getBoundingClientRect();
4965
- svgRectRef.current = svgRectangle;
4966
- marginRef.current = margin;
4967
- widthRef.current = width;
4968
- var minT = diagramType === 'EMAGRAM' ? minEmagramTemperature : minTemperature;
4969
- var maxT = maxTemperature;
4970
- var _createScales = createScales$1(diagramType, width, height, minPressure, maxPressure, minT, maxT),
4971
- xScale = _createScales[0],
4972
- yScale = _createScales[1];
4973
- yScaleRef.current = yScale;
4974
- var applyAxisClips = function applyAxisClips() {
4974
+ var windSpeedRanges = [{
4975
+ min: 0,
4976
+ max: 1,
4977
+ symbol: windSymbolDefinitions.calm
4978
+ }, {
4979
+ min: 1,
4980
+ max: 4.5,
4981
+ symbol: windSymbolDefinitions.lightAir
4982
+ }, {
4983
+ min: 4.5,
4984
+ max: 7.5,
4985
+ symbol: windSymbolDefinitions.fiveKnots
4986
+ }, {
4987
+ min: 7.5,
4988
+ max: 12.5,
4989
+ symbol: windSymbolDefinitions.tenKnots
4990
+ }, {
4991
+ min: 12.5,
4992
+ max: 17.5,
4993
+ symbol: windSymbolDefinitions.fifteenKnots
4994
+ }, {
4995
+ min: 17.5,
4996
+ max: 22.5,
4997
+ symbol: windSymbolDefinitions.twentyKnots
4998
+ }, {
4999
+ min: 22.5,
5000
+ max: 27.5,
5001
+ symbol: windSymbolDefinitions.twentyFiveKnots
5002
+ }, {
5003
+ min: 27.5,
5004
+ max: 32.5,
5005
+ symbol: windSymbolDefinitions.thirtyKnots
5006
+ }, {
5007
+ min: 32.5,
5008
+ max: 37.5,
5009
+ symbol: windSymbolDefinitions.thirtyFiveKnots
5010
+ }, {
5011
+ min: 37.5,
5012
+ max: 42.5,
5013
+ symbol: windSymbolDefinitions.fortyKnots
5014
+ }, {
5015
+ min: 42.5,
5016
+ max: 47.5,
5017
+ symbol: windSymbolDefinitions.fortyFiveKnots
5018
+ }, {
5019
+ min: 47.5,
5020
+ max: 52.5,
5021
+ symbol: windSymbolDefinitions.fiftyKnots
5022
+ }, {
5023
+ min: 52.5,
5024
+ max: 57.5,
5025
+ symbol: windSymbolDefinitions.fiftyFiveKnots
5026
+ }, {
5027
+ min: 57.5,
5028
+ max: 62.5,
5029
+ symbol: windSymbolDefinitions.sixtyKnots
5030
+ }, {
5031
+ min: 62.5,
5032
+ max: 67.5,
5033
+ symbol: windSymbolDefinitions.sixtyFiveKnots
5034
+ }, {
5035
+ min: 67.5,
5036
+ max: 72.5,
5037
+ symbol: windSymbolDefinitions.seventyKnots
5038
+ }, {
5039
+ min: 72.5,
5040
+ max: 77.5,
5041
+ symbol: windSymbolDefinitions.seventyFiveKnots
5042
+ }, {
5043
+ min: 77.5,
5044
+ max: 82.5,
5045
+ symbol: windSymbolDefinitions.eightyKnots
5046
+ }, {
5047
+ min: 82.5,
5048
+ max: 87.5,
5049
+ symbol: windSymbolDefinitions.eightyFiveKnots
5050
+ }, {
5051
+ min: 87.5,
5052
+ max: 92.5,
5053
+ symbol: windSymbolDefinitions.ninetyKnots
5054
+ }, {
5055
+ min: 92.5,
5056
+ max: 97.5,
5057
+ symbol: windSymbolDefinitions.ninetyFiveKnots
5058
+ }, {
5059
+ min: 97.5,
5060
+ max: 102.5,
5061
+ symbol: windSymbolDefinitions.hundredKnots
5062
+ }, {
5063
+ min: 102.5,
5064
+ max: 107.5,
5065
+ symbol: windSymbolDefinitions.hundredFiveKnots
5066
+ }, {
5067
+ min: 107.5,
5068
+ max: 112.5,
5069
+ symbol: windSymbolDefinitions.hundredTenKnots
5070
+ }, {
5071
+ min: 112.5,
5072
+ max: 117.5,
5073
+ symbol: windSymbolDefinitions.hundredFifteenKnots
5074
+ }, {
5075
+ min: 117.5,
5076
+ max: 122.5,
5077
+ symbol: windSymbolDefinitions.hundredTwentyKnots
5078
+ }, {
5079
+ min: 122.5,
5080
+ max: 127.5,
5081
+ symbol: windSymbolDefinitions.hundredTwentyFiveKnots
5082
+ }, {
5083
+ min: 127.5,
5084
+ max: 132.5,
5085
+ symbol: windSymbolDefinitions.hundredThirtyKnots
5086
+ }, {
5087
+ min: 132.5,
5088
+ max: 137.5,
5089
+ symbol: windSymbolDefinitions.hundredThirtyFiveKnots
5090
+ }, {
5091
+ min: 137.5,
5092
+ max: 142.5,
5093
+ symbol: windSymbolDefinitions.hundredFortyKnots
5094
+ }, {
5095
+ min: 142.5,
5096
+ max: 147.5,
5097
+ symbol: windSymbolDefinitions.hundredFortyFiveKnots
5098
+ }, {
5099
+ min: 147.5,
5100
+ max: 152,
5101
+ symbol: windSymbolDefinitions.hundredFiftyKnots
5102
+ }];
5103
+
5104
+ /* *
5105
+ * Licensed under the Apache License, Version 2.0 (the "License");
5106
+ * you may not use this file except in compliance with the License.
5107
+ * You may obtain a copy of the License at
5108
+ *
5109
+ * http://www.apache.org/licenses/LICENSE-2.0
5110
+ *
5111
+ * Unless required by applicable law or agreed to in writing, software
5112
+ * distributed under the License is distributed on an "AS IS" BASIS,
5113
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5114
+ * See the License for the specific language governing permissions and
5115
+ * limitations under the License.
5116
+ *
5117
+ * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
5118
+ * Copyright 2025 - Finnish Meteorological Institute (FMI)
5119
+ * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
5120
+ * */
5121
+ var MIN_VERTICAL_SCALE = 1;
5122
+ var MAX_VERTICAL_SCALE = 7;
5123
+ var DEFAULT_THINNING_BASE = 1.15;
5124
+ var MIN_THINNING_BASE = 1.08;
5125
+ var EXTRA_REVEAL_EXPONENT = 0.5; // Decrease this number to reveal more barbs earlier as you zoom in
5126
+ var extendIsoBar = function extendIsoBar(path, horizontalBarbMargin) {
5127
+ var match = /^M([\d.-]+),([\d.-]+)\s*L([\d.-]+),([\d.-]+)/.exec(path);
5128
+ if (match) {
5129
+ var startX = parseFloat(match[1]);
5130
+ var startY = parseFloat(match[2]);
5131
+ var endX = parseFloat(match[3]);
5132
+ var endY = parseFloat(match[4]);
5133
+ return "M" + startX + "," + startY + "L" + (endX + horizontalBarbMargin * 3) + "," + endY;
5134
+ }
5135
+ return path;
5136
+ };
5137
+ var extendXAxis = function extendXAxis(path, horizontalBarbMargin) {
5138
+ var match = /^M([\d.-]+),([\d.-]+)H([\d.-]+)/.exec(path);
5139
+ if (match) {
5140
+ var endX = parseFloat(match[3]);
5141
+ return path.replace(/H[\d.-]+/, "H" + (endX + horizontalBarbMargin * 3));
5142
+ }
5143
+ return path;
5144
+ };
5145
+ var drawWindBarbs = function drawWindBarbs(_ref) {
5146
+ var _rootSvg$node;
5147
+ var svgRef = _ref.svgRef,
5148
+ plotGroup = _ref.plotGroup,
5149
+ yScale = _ref.yScale,
5150
+ data = _ref.data,
5151
+ width = _ref.width,
5152
+ margin = _ref.margin,
5153
+ _ref$barbColor = _ref.barbColor,
5154
+ barbColor = _ref$barbColor === void 0 ? 'black' : _ref$barbColor,
5155
+ _ref$columnOffsetX = _ref.columnOffsetX,
5156
+ columnOffsetX = _ref$columnOffsetX === void 0 ? 0 : _ref$columnOffsetX,
5157
+ _ref$verticalScale = _ref.verticalScale,
5158
+ verticalScale = _ref$verticalScale === void 0 ? 1 : _ref$verticalScale;
5159
+ var barbsSize = 40;
5160
+ var scalingFactor = 0.5;
5161
+ var horizontalBarbMargin = barbsSize * scalingFactor + 5;
5162
+ var visibleItems = getVisibleWindItemsForVerticalScale(data, verticalScale).filter(function (item) {
5163
+ return item.pressure >= 150;
5164
+ });
5165
+ // Measure width and height and make extra room for one column
5166
+ // of windbarbs
5167
+ var rootSvg = d3.select(svgRef.current);
5168
+ var currentWidth = (_rootSvg$node = rootSvg.node()) == null ? void 0 : _rootSvg$node.getBoundingClientRect().width;
5169
+ if (!currentWidth) {
5170
+ return;
5171
+ }
5172
+ // Add extra width to isobars in this SVG only.
5173
+ rootSvg.selectAll('path[type="isobar"]').each(function (_d, i, nodes) {
5174
+ var path = d3.select(nodes[i]).attr('d');
5175
+ var newD = extendIsoBar(path, horizontalBarbMargin);
5176
+ d3.select(nodes[i]).attr('d', newD).attr('clip-path', null);
5177
+ });
5178
+ // Add extra width to x-axis in this SVG only.
5179
+ rootSvg.select('g[type="x-axis"] path.domain').each(function (_d, i, nodes) {
5180
+ var path = d3.select(nodes[i]).attr('d');
5181
+ var newD = extendXAxis(path, horizontalBarbMargin);
5182
+ d3.select(nodes[i]).attr('d', newD);
5183
+ });
5184
+ // Expand root SVG width to make room for barbs column at the right
5185
+ rootSvg.attr('width', currentWidth + margin.left + horizontalBarbMargin);
5186
+ // Place the barbs just to the right of the plotting area.
5187
+ // plotGroup's origin is already translated to (margin.left, margin.top),
5188
+ // and its width equals `width`.
5189
+ var windBarbColumnX = width + 5 + columnOffsetX + horizontalBarbMargin;
5190
+ var barbGroup = plotGroup.append('g').attr('class', 'wind-group').attr('transform', // Apply translation and counter-scale to maintain aspect ratio during vertical zoom.
5191
+ // The counter-scale (1, 1/verticalScale) undoes the parent's vertical scaling.
5192
+ "translate(" + windBarbColumnX + ", 0) scale(1, " + 1 / verticalScale + ")");
5193
+ barbGroup.selectAll('g').data(visibleItems).enter().append('g').attr('id', 'wind-barb').each(function handleBarb(data) {
5194
+ var group = d3.select(this);
5195
+ var windSymbol = getWindSymbol(data.windSpeed);
5196
+ if (windSymbol) {
5197
+ var _innerGroup$node;
5198
+ // Inner group will have rotation and scaling applied to it
5199
+ var innerGroup = group.append('g');
5200
+ (_innerGroup$node = innerGroup.node()) == null || _innerGroup$node.appendChild(windSymbol);
5201
+ // Update stroke color
5202
+ innerGroup.selectAll('*').attr('stroke', barbColor);
5203
+ // Only update the fill for the paths that already used a fill
5204
+ // in their original svg form.
5205
+ innerGroup.selectAll('*').each(function (_d, i, nodes) {
5206
+ var el = d3.select(nodes[i]);
5207
+ var currentFill = el.attr('fill');
5208
+ if (currentFill && currentFill !== 'none') {
5209
+ el.attr('fill', barbColor);
5210
+ }
5211
+ });
5212
+ var bbox = windSymbol.getBBox();
5213
+ // Central point
5214
+ var cx = bbox.x + bbox.width / 2;
5215
+ var cy = bbox.y + bbox.height / 2;
5216
+ var rotation = 180 + data.windDirection;
5217
+ var y = yScale(data.pressure);
5218
+ // Place items in the correct vertical position.
5219
+ // Apply verticalScale to compensate for the parent's counter-scale,
5220
+ // ensuring barbs appear at the correct zoomed Y position.
5221
+ group.attr('transform', "translate(0, " + (y - barbsSize * scalingFactor / 8) * verticalScale + ")");
5222
+ // Rotate accordingly, and scale
5223
+ innerGroup.attr('transform', "rotate(" + rotation + ") scale(" + scalingFactor + ") translate(" + -cx + ", " + -cy + ")");
5224
+ }
5225
+ });
5226
+ };
5227
+ var removeItemsExponential = function removeItemsExponential(array, base) {
5228
+ if (base === void 0) {
5229
+ base = DEFAULT_THINNING_BASE;
5230
+ }
5231
+ var indicesToKeep = [];
5232
+ var i = 0;
5233
+ var nextIndex = 0;
5234
+ while (nextIndex < array.length) {
5235
+ nextIndex = Math.floor(Math.pow(base, i));
5236
+ indicesToKeep.push(nextIndex);
5237
+ i += 1;
5238
+ }
5239
+ return array.filter(function (_, index) {
5240
+ return indicesToKeep.includes(index);
5241
+ });
5242
+ };
5243
+ var getVisibleWindItemsForVerticalScale = function getVisibleWindItemsForVerticalScale(data, verticalScale) {
5244
+ var reversedData = [].concat(data).reverse();
5245
+ var baselineItems = removeItemsExponential(reversedData);
5246
+ var maxDetailItems = removeItemsExponential(reversedData, MIN_THINNING_BASE);
5247
+ var baselineSet = new Set(baselineItems);
5248
+ var maxDetailSet = new Set(maxDetailItems);
5249
+ // Candidate additions are fixed and ordered; zooming in reveals a prefix only.
5250
+ var extraCandidates = reversedData.filter(function (item) {
5251
+ return maxDetailSet.has(item) && !baselineSet.has(item);
5252
+ });
5253
+ var clampedScale = Math.max(MIN_VERTICAL_SCALE, Math.min(MAX_VERTICAL_SCALE, verticalScale));
5254
+ var normalizedScale = (clampedScale - MIN_VERTICAL_SCALE) / (MAX_VERTICAL_SCALE - MIN_VERTICAL_SCALE);
5255
+ // Use a front-loaded curve so extra barbs appear earlier when zooming in,
5256
+ // while still keeping zoom level 1 unchanged and monotonic.
5257
+ var revealProgress = Math.pow(normalizedScale, EXTRA_REVEAL_EXPONENT);
5258
+ var extraCount = Math.floor(revealProgress * extraCandidates.length);
5259
+ var extraSet = new Set(extraCandidates.slice(0, extraCount));
5260
+ return reversedData.filter(function (item) {
5261
+ return baselineSet.has(item) || extraSet.has(item);
5262
+ });
5263
+ };
5264
+ var getWindSymbol = function getWindSymbol(value) {
5265
+ var matchedRange = windSpeedRanges.find(function (_ref2) {
5266
+ var min = _ref2.min,
5267
+ max = _ref2.max;
5268
+ return value >= min && value < max;
5269
+ });
5270
+ // Out of range
5271
+ if (!matchedRange) {
5272
+ return null;
5273
+ }
5274
+ // SVG string to actual SVG element
5275
+ var parser = new DOMParser();
5276
+ var svgDoc = parser.parseFromString(matchedRange.symbol, 'image/svg+xml');
5277
+ var svgNode = svgDoc.documentElement;
5278
+ // Return the parsed SVG node
5279
+ return svgNode;
5280
+ };
5281
+
5282
+ var shadow$1 = '0 1px 5px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.14)';
5283
+ var soundingsStyle$1 = {
5284
+ tooltip: {
5285
+ display: 'block',
5286
+ position: 'absolute',
5287
+ borderRadius: '1.5px',
5288
+ backgroundColor: 'geowebColors.soundings.tooltip.background',
5289
+ boxShadow: shadow$1,
5290
+ padding: '2px 4px',
5291
+ pointerEvents: 'none',
5292
+ zIndex: 500
5293
+ },
5294
+ pressure: {
5295
+ fontSize: '10px'
5296
+ },
5297
+ temperature: {
5298
+ fontSize: '12px',
5299
+ fontWeight: 'bold'
5300
+ },
5301
+ dewPoint: {
5302
+ fontSize: '12px',
5303
+ fontWeight: 'bold'
5304
+ }};
5305
+ var updateTransformToViewport = function updateTransformToViewport(transform, width, height) {
5306
+ var minX = width * (1 - transform.k);
5307
+ var minY = height * (1 - transform.k);
5308
+ return d3.zoomIdentity.translate(Math.min(0, Math.max(minX, transform.x)), Math.min(0, Math.max(minY, transform.y))).scale(transform.k);
5309
+ };
5310
+ var Soundings = function Soundings(_ref) {
5311
+ var d3GraphId = _ref.d3GraphId,
5312
+ data = _ref.data,
5313
+ svgDimensions = _ref.svgDimensions,
5314
+ _ref$showTooltip = _ref.showTooltip,
5315
+ showTooltip = _ref$showTooltip === void 0 ? true : _ref$showTooltip,
5316
+ _ref$diagramType = _ref.diagramType,
5317
+ diagramType = _ref$diagramType === void 0 ? 'SKEWT' : _ref$diagramType;
5318
+ var instanceId = useId().replace(/:/g, '_');
5319
+ var scopedGraphId = d3GraphId + "-" + instanceId;
5320
+ var svgRef = useRef(null);
5321
+ var canvasRef = useRef(null);
5322
+ var pressureRef = useRef(null);
5323
+ var tempRef = useRef(null);
5324
+ var dewpointRef = useRef(null);
5325
+ // Refs to store current scale/data for shared mouse effect
5326
+ var yScaleRef = useRef(null);
5327
+ var marginRef = useRef(null);
5328
+ var widthRef = useRef(0);
5329
+ var svgRectRef = useRef(null);
5330
+ var tooltipDataRef = useRef(null);
5331
+ var zoomBehaviorRef = useRef(null);
5332
+ // Keep zoom target on the inner translated <g>; Soundings and WindBarbs must
5333
+ // transform the same coordinate space to stay aligned.
5334
+ var zoomTargetRef = useRef(null);
5335
+ var isApplyingSharedZoomRef = useRef(false);
5336
+ // Keep the last applied d3 zoom transform across SVG redraws.
5337
+ // Width/height changes recreate the chart, so this ref prevents zoom snapping
5338
+ // back to identity when panels are closed/resized.
5339
+ var persistedZoomTransformRef = useRef(d3.zoomIdentity);
5340
+ var previousDiagramTypeRef = useRef(null);
5341
+ var _useSharedMouseY = useSharedMouseY(),
5342
+ clientY = _useSharedMouseY.clientY,
5343
+ publishVerticalZoom = _useSharedMouseY.publishVerticalZoom,
5344
+ verticalZoom = _useSharedMouseY.verticalZoom,
5345
+ resetVerticalZoom = _useSharedMouseY.resetVerticalZoom;
5346
+ // Set SVG dimensions (required props; no optional chaining needed)
5347
+ var baseWidth = svgDimensions.width,
5348
+ baseHeight = svgDimensions.height,
5349
+ margin = svgDimensions.margin;
5350
+ var width = baseWidth - (margin.left + margin.right);
5351
+ var height = baseHeight - (margin.top + margin.bottom);
5352
+ useEffect(function () {
5353
+ if (!svgRef.current || width <= 0 || height <= 0) {
5354
+ return;
5355
+ }
5356
+ var isDiagramTypeChange = previousDiagramTypeRef.current !== null && previousDiagramTypeRef.current !== diagramType;
5357
+ if (isDiagramTypeChange) {
5358
+ persistedZoomTransformRef.current = d3.zoomIdentity;
5359
+ resetVerticalZoom(scopedGraphId);
5360
+ }
5361
+ var root = d3.select(svgRef.current);
5362
+ root.selectAll('*').remove();
5363
+ var svg = initializeSvg$1({
5364
+ svgRef: svgRef,
5365
+ width: width,
5366
+ height: height,
5367
+ margin: margin,
5368
+ diagramType: diagramType,
5369
+ d3GraphId: scopedGraphId
5370
+ });
5371
+ // Create a separate layer for axes so they can stay visible above the zoomed content.
5372
+ var axisLayer = svg.append('g').attr('data-layer', 'axis-layer');
5373
+ // Keep a static viewport group for clipping, and transform only the inner
5374
+ // content group during zoom so the visible area stays fixed.
5375
+ var zoomViewport = svg.append('g').attr('data-layer', 'zoom-viewport').attr('clip-path', "url(#clip-" + scopedGraphId + "-" + diagramType + "d3)");
5376
+ var zoomContent = zoomViewport.append('g').attr('data-layer', 'zoom-content');
5377
+ var bijvoetLabelLayer = svg.append('g').attr('data-layer', 'bijvoet-label-layer').style('pointer-events', 'none');
5378
+ var svgRectangle = svgRef.current.getBoundingClientRect();
5379
+ svgRectRef.current = svgRectangle;
5380
+ marginRef.current = margin;
5381
+ widthRef.current = width;
5382
+ var minT = diagramType === 'EMAGRAM' ? minEmagramTemperature : minTemperature;
5383
+ var maxT = maxTemperature;
5384
+ var _createScales = createScales$1(diagramType, width, height, minPressure, maxPressure, minT, maxT),
5385
+ xScale = _createScales[0],
5386
+ yScale = _createScales[1];
5387
+ yScaleRef.current = yScale;
5388
+ var applyAxisClips = function applyAxisClips() {
4975
5389
  axisLayer.select('g[type="x-axis"] path.domain').attr('d', "M0.5,0.5H" + (width + 0.5));
4976
5390
  axisLayer.select('g[type="x-axis"]').attr('clip-path', "url(#clip-" + scopedGraphId + "-" + diagramType + "x-axis)");
4977
5391
  axisLayer.select('g[type="y-axis"]').attr('clip-path', "url(#clip-" + scopedGraphId + "-" + diagramType + "y-axis)");
@@ -5051,7 +5465,7 @@ var Soundings = function Soundings(_ref) {
5051
5465
  d3.select(bijvoetLabelTarget).attr('transform', transform.toString());
5052
5466
  };
5053
5467
  // Allow zooming and panning
5054
- var zoomBehavior = d3.zoom().scaleExtent([1, 7]).extent([[0, 0], [width, height]]).translateExtent([[0, 0], [width, height]]).on('zoom', function (event) {
5468
+ var zoomBehavior = d3.zoom().scaleExtent([MIN_VERTICAL_SCALE, MAX_VERTICAL_SCALE]).extent([[0, 0], [width, height]]).translateExtent([[0, 0], [width, height]]).on('zoom', function (event) {
5055
5469
  // Persist every interactive zoom/pan event so the transform can be
5056
5470
  // restored after dimension-driven rerenders.
5057
5471
  persistedZoomTransformRef.current = event.transform;
@@ -5208,401 +5622,148 @@ var useMaxLabelCount = function useMaxLabelCount(ref) {
5208
5622
  var maxLabelCount = Math.max(1, Math.floor(width / LABEL_MIN_WIDTH));
5209
5623
  return maxLabelCount;
5210
5624
  };
5211
- var shouldHideLabel = function shouldHideLabel(nItems, index, maxLabelCount) {
5212
- var nthLabelsToShow = Math.ceil(nItems / maxLabelCount);
5213
- return nItems > maxLabelCount &&
5214
- // hide labels if too many items
5215
- index !== nItems - 1 && (
5216
- // not last item (always shown)
5217
- // only show every nth label, skip label within last n/2 items so end doesn't get cluttered
5218
- index % nthLabelsToShow !== 0 || nItems - 1 - index < nthLabelsToShow / 2);
5219
- };
5220
- var SoundingsTimeSlider = function SoundingsTimeSlider(_ref) {
5221
- var timesteps = _ref.timesteps,
5222
- selectedTime = _ref.selectedTime,
5223
- updateSelectedTime = _ref.updateSelectedTime;
5224
- var sliderRef = React.useRef(null);
5225
- var maxLabelCount = useMaxLabelCount(sliderRef);
5226
- var _useSoundingsTranslat = useSoundingsTranslation(),
5227
- i18n = _useSoundingsTranslat.i18n;
5228
- var marks = timesteps.filter(function (date) {
5229
- return dateUtils.isValidIsoDateString(date);
5230
- }).map(function (date, index, arr) {
5231
- return {
5232
- value: dateUtils.unix(dateUtils.getUtcFromString(date)),
5233
- label: shouldHideLabel(arr.length, index, maxLabelCount) ? '' : dateUtils.dateToString(dateUtils.getUtcFromString(date), 'iii d. HH:mm', true, i18n.language)
5234
- };
5235
- });
5236
- var currentTimeIndex = React.useMemo(function () {
5237
- if (timesteps.length === 0) {
5238
- return -1;
5239
- }
5240
- var selectedUtc = dateUtils.getUtcFromString(selectedTime);
5241
- if (!selectedUtc) {
5242
- return 0;
5243
- }
5244
- var selectedUnix = dateUtils.unix(selectedUtc);
5245
- var indexByExactTimestamp = timesteps.findIndex(function (time) {
5246
- var utcTime = dateUtils.getUtcFromString(time);
5247
- if (!utcTime) {
5248
- return false;
5249
- }
5250
- return dateUtils.unix(utcTime) === selectedUnix;
5251
- });
5252
- if (indexByExactTimestamp !== -1) {
5253
- return indexByExactTimestamp;
5254
- }
5255
- var indexByExactString = timesteps.findIndex(function (time) {
5256
- return time === selectedTime;
5257
- });
5258
- if (indexByExactString !== -1) {
5259
- return indexByExactString;
5260
- }
5261
- // If selected time is not a sounding timestep, anchor on the nearest timestep
5262
- // so forward/backward navigation continues from the expected point in time.
5263
- return timesteps.reduce(function (nearestIndex, time, index) {
5264
- var utcTime = dateUtils.getUtcFromString(time);
5265
- if (!utcTime) {
5266
- return nearestIndex;
5267
- }
5268
- var currentDiff = Math.abs(dateUtils.unix(utcTime) - selectedUnix);
5269
- var nearestUtc = dateUtils.getUtcFromString(timesteps[nearestIndex]);
5270
- if (!nearestUtc) {
5271
- return index;
5272
- }
5273
- var nearestDiff = Math.abs(dateUtils.unix(nearestUtc) - selectedUnix);
5274
- return currentDiff < nearestDiff ? index : nearestIndex;
5275
- }, 0);
5276
- }, [selectedTime, timesteps]);
5277
- var onStepBackward = React.useCallback(function () {
5278
- var precedingIndex = Math.max(currentTimeIndex - 1, 0);
5279
- updateSelectedTime(timesteps[precedingIndex]);
5280
- }, [currentTimeIndex, updateSelectedTime, timesteps]);
5281
- var onStepForward = React.useCallback(function () {
5282
- var followingIndex = Math.min(currentTimeIndex + 1, timesteps.length - 1);
5283
- updateSelectedTime(timesteps[followingIndex]);
5284
- }, [currentTimeIndex, updateSelectedTime, timesteps]);
5285
- return jsxs("div", {
5286
- ref: sliderRef,
5287
- style: {
5288
- display: 'flex',
5289
- paddingTop: '32px',
5290
- marginRight: '80px',
5291
- marginLeft: '24px',
5292
- height: TIMESLIDER_HEIGHT + "px"
5293
- },
5294
- children: [jsxs("div", {
5295
- style: {
5296
- minWidth: '60px',
5297
- marginTop: '2px',
5298
- display: 'flex',
5299
- gap: '4px'
5300
- },
5301
- children: [jsx(BackwardForwardStepButton, {
5302
- isDisabled: marks.length === 0,
5303
- isForwardStep: false,
5304
- onClickBFButton: onStepBackward
5305
- }), jsx(BackwardForwardStepButton, {
5306
- isDisabled: marks.length === 0,
5307
- isForwardStep: true,
5308
- onClickBFButton: onStepForward
5309
- })]
5310
- }), marks.length === 0 ? jsx(CustomSlider, {
5311
- disabled: true,
5312
- max: 1,
5313
- min: 0,
5314
- orientation: "horizontal",
5315
- value: 0.5
5316
- }) : jsx(CustomSlider, {
5317
- extraStyles: {
5318
- margin: '0px 20px 0px 20px',
5319
- '.MuiSlider-markLabel': {
5320
- transform: 'translate(-90%, 20px) rotate(-45deg)',
5321
- transformOrigin: 'top center'
5322
- }
5323
- },
5324
- marks: marks,
5325
- max: marks[marks.length - 1].value,
5326
- min: marks[0].value,
5327
- onChange: function onChange(_, value) {
5328
- updateSelectedTime(dateUtils.fromUnix(value).toISOString());
5329
- },
5330
- orientation: "horizontal",
5331
- slotProps: {
5332
- // Workaround for MUI bug where labels are just draggable area and clicking on one
5333
- // does not necessarily select the described timestep
5334
- markLabel: {
5335
- onPointerDown: function onPointerDown(event) {
5336
- event.preventDefault();
5337
- var markIndex = event.currentTarget.getAttribute('data-index');
5338
- var mark = marks[Number(markIndex)];
5339
- var value = mark.value;
5340
- updateSelectedTime(dateUtils.fromUnix(value).toISOString());
5341
- }
5342
- }
5343
- },
5344
- step: null,
5345
- value: dateUtils.unix(dateUtils.getUtcFromString(selectedTime)),
5346
- valueLabelDisplay: "on",
5347
- valueLabelFormat: function valueLabelFormat(value) {
5348
- return dateUtils.dateToString(dateUtils.fromUnix(value), "yyyy iii dd MMM HH:mm 'UTC'", true, i18n.language);
5349
- }
5350
- })]
5351
- });
5352
- };
5353
-
5354
- /* *
5355
- * Licensed under the Apache License, Version 2.0 (the "License");
5356
- * you may not use this file except in compliance with the License.
5357
- * You may obtain a copy of the License at
5358
- *
5359
- * http://www.apache.org/licenses/LICENSE-2.0
5360
- *
5361
- * Unless required by applicable law or agreed to in writing, software
5362
- * distributed under the License is distributed on an "AS IS" BASIS,
5363
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5364
- * See the License for the specific language governing permissions and
5365
- * limitations under the License.
5366
- *
5367
- * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
5368
- * Copyright 2025 - Finnish Meteorological Institute (FMI)
5369
- * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
5370
- * */
5371
- var OFFSET_HEIGHT = 100; // Space reserved in layout
5372
- var useSoundingsDiagramSize = function useSoundingsDiagramSize(ref, useWidth) {
5373
- if (useWidth === void 0) {
5374
- useWidth = true;
5375
- }
5376
- var _React$useState = React.useState(0),
5377
- size = _React$useState[0],
5378
- setSize = _React$useState[1];
5379
- React.useLayoutEffect(function () {
5380
- var container = ref.current;
5381
- if (!container) {
5382
- return undefined;
5383
- }
5384
- var resizeObserver = new ResizeObserver(function (entries) {
5385
- if (!entries.length) {
5386
- return;
5387
- }
5388
- var _entries$0$contentRec = entries[0].contentRect,
5389
- width = _entries$0$contentRec.width,
5390
- height = _entries$0$contentRec.height;
5391
- var availableHeight = height - TIMESLIDER_HEIGHT + OFFSET_HEIGHT;
5392
- var nextSize = useWidth ? Math.floor(Math.min(width, availableHeight)) : Math.floor(availableHeight);
5393
- setSize(nextSize > 0 ? nextSize : 0);
5394
- });
5395
- resizeObserver.observe(container);
5396
- return function () {
5397
- resizeObserver.disconnect();
5398
- };
5399
- }, [ref, useWidth]);
5400
- return size;
5401
- };
5402
-
5403
- /* *
5404
- * Licensed under the Apache License, Version 2.0 (the "License");
5405
- * you may not use this file except in compliance with the License.
5406
- * You may obtain a copy of the License at
5407
- *
5408
- * http://www.apache.org/licenses/LICENSE-2.0
5409
- *
5410
- * Unless required by applicable law or agreed to in writing, software
5411
- * distributed under the License is distributed on an "AS IS" BASIS,
5412
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5413
- * See the License for the specific language governing permissions and
5414
- * limitations under the License.
5415
- *
5416
- * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
5417
- * Copyright 2025 - Finnish Meteorological Institute (FMI)
5418
- * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
5419
- * */
5420
- var animateResizeTransform = function animateResizeTransform(svg, marginLocal, innerHeight, prevInnerHeightRef) {
5421
- var prevInnerHeight = typeof prevInnerHeightRef.current === 'number' ? prevInnerHeightRef.current : 0;
5422
- var scaleYStart = prevInnerHeight > 0 && innerHeight > 0 ? prevInnerHeight / innerHeight : 0;
5423
- svg.attr('transform', "translate(" + marginLocal.left + "," + marginLocal.top + ") scale(1," + scaleYStart + ")").transition().duration(300).attr('transform', "translate(" + marginLocal.left + "," + marginLocal.top + ") scale(1,1)");
5424
- };
5425
-
5426
- /* *
5427
- * Licensed under the Apache License, Version 2.0 (the "License");
5428
- * you may not use this file except in compliance with the License.
5429
- * You may obtain a copy of the License at
5430
- *
5431
- * http://www.apache.org/licenses/LICENSE-2.0
5432
- *
5433
- * Unless required by applicable law or agreed to in writing, software
5434
- * distributed under the License is distributed on an "AS IS" BASIS,
5435
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5436
- * See the License for the specific language governing permissions and
5437
- * limitations under the License.
5438
- *
5439
- * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
5440
- * Copyright 2025 - Finnish Meteorological Institute (FMI)
5441
- * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
5442
- * */
5443
- var windSymbolDefinitions = {
5444
- calm: "<svg width=\"50\" height=\"50\" viewBox=\"0 0 50 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M25 45C36.0456 45 45 36.0456 45 25C45 13.9543 36.0456 5 25 5C13.9543 5 5 13.9543 5 25C5 36.0456 13.9543 45 25 45Z\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
5445
- lightAir: "<svg width=\"14\" height=\"48\" viewBox=\"0 0 14 48\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M7.22656 4.89307V48.0001M7.22656 43.0262V44.6842\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
5446
- fiveKnots: "<svg width=\"15\" height=\"49\" viewBox=\"0 0 15 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M8.26953 5.57324V48.608M8.26953 40.5757L0.269531 42.2309\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5447
- tenKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17.0781 4.64502V44.9031L1.07812 47.9999\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5448
- fifteenKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.4727 5.55469V45.8128L0.472656 48.9095M16.4727 38.0708L9.61551 39.6192\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
5449
- twentyKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.8555 4.71924V44.9773L0.855469 48.0741M16.8555 38.4093L0.855469 41.5061\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5450
- twentyFiveKnots: "<svg width=\"23\" height=\"51\" viewBox=\"0 0 23 51\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.2383 4.94434V46.1541L0.238281 49.3241M16.2383 40.3787L0.238281 43.5486M16.2383 33.9801L9.38114 35.5651\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5451
- thirtyKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.1914 5.64502V45.9031L0.191406 48.9999M16.1914 40.3459L0.191406 43.4427M16.1914 34.9407L0.191406 38.0375\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5452
- thirtyFiveKnots: "<svg width=\"19\" height=\"50\" viewBox=\"0 0 19 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M12.0028 4.96729V45.2253L1.16406 48.3221M12.0028 39.6443L1.16406 42.7411M12.0028 34.4793L1.16406 37.576M12.0028 29.2735L7.35761 30.8219\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5453
- fortyKnots: "<svg width=\"24\" height=\"50\" viewBox=\"0 0 24 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.5391 5.40311V45.6612L0.539062 48.7579M16.5391 40.4525L0.539062 43.5493M16.5391 35.0449L0.539062 38.1417M16.5391 30.2009L0.539062 33.2976\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5454
- fortyFiveKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.4492 5.4043V45.6624L0.449219 48.7591M16.4492 40.1513L0.449219 43.2481M16.4492 34.7124L0.449219 37.8091M16.4492 29.2013L0.449219 32.2981M16.4492 24.3066L9.59208 25.855\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5455
- fiftyKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.9062 5.27002V45.5281L0.90625 48.6249L16.9062 37.7861\" fill=\"black\"/>\n<path d=\"M16.9053 5.27002V45.5281L4.35132 47.2337L16.9053 37.7861\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
5456
- fiftyFiveKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.728 5.55371V45.8118L0.894531 48.9085L16.728 38.0698\" fill=\"black\"/>\n<path d=\"M16.73 5.55371V45.8118L4.33984 47.5245L16.73 38.0698\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.7292 32.7358C13.6376 33.3406 8.8125 34.2842 8.8125 34.2842\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5457
- sixtyKnots: "<svg width=\"23\" height=\"49\" viewBox=\"0 0 23 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.2891 5.27051V45.5286L0.289062 48.6253L16.2891 37.7866\" fill=\"black\"/>\n<path d=\"M16.2897 5.27051V45.5286L3.7422 47.2478L16.2897 37.7866\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.2891 34.6899L0.289062 37.7867\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5458
- sixtyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L9.5 28.5\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5459
- seventyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
5460
- seventyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 22C13.8251 22.6048 9 23.5484 9 23.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5461
- eightyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5462
- eightyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 17C13.8251 17.6048 9 18.5484 9 18.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
5463
- ninetyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
5464
- ninetyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 12C13.8251 12.6048 9 13.5484 9 13.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5465
- hundredKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
5466
- hundredFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 25C13.8251 25.6048 9 26.5484 9 26.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
5467
- hundredTenKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5468
- hundredFifteenKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 21C13.8251 21.6048 9 22.5484 9 22.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5469
- hundredTwentyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5470
- hundredTwentyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 17C13.8251 17.6048 9 18.5484 9 18.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
5471
- hundredThirtyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5472
- hundredThirtyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 13C13.8251 13.6048 9 14.5484 9 14.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5473
- hundredFortyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 13C10.7518 14.1718 1 16 1 16\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5474
- hundredFortyFiveKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 5.26807V25.3971V45.5261L1 48.6229L17 37.7842\" fill=\"black\"/>\n<path d=\"M16.9984 5.26807V30M16.9984 37.7842L4.35938 47.2985L16.9984 45.5261V37.5M16.9984 30C16.9984 30 5.67406 37.7842 4 39M16.9984 30V31.5M4 39C9.07621 38.4142 16.9984 37.5 16.9984 37.5M4 39C9.07621 36.0711 16.9984 31.5 16.9984 31.5M4 39C9.07682 36.6569 17 33 17 33M4 39C9.07621 37.2426 16.9984 34.5 16.9984 34.5M4 39C9.07621 37.8284 16.9984 36 16.9984 36M16.9984 37.5V36M16.9984 31.5V34.5M16.9984 34.5V36\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 12C13.8251 12.6048 9 13.5484 9 13.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 27C10.7518 28.1718 1 30 1 30\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 23C10.7518 24.1718 1 26 1 26\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 19C10.7518 20.1718 1 22 1 22\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 15C10.7518 16.1718 1 18 1 18\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
5475
- hundredFiftyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V19M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M16.9984 28V26.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34M16.9984 19C16.9984 19 8 25.5 4 29M16.9984 19V20.5M4 29C9.07621 28.0237 16.9984 26.5 16.9984 26.5M4 29C9.07621 25.6805 16.9984 20.5 16.9984 20.5M4 29C9.07621 26.4616 16.9984 22.5 16.9984 22.5M4 29C9.07621 27.0474 16.9984 24 16.9984 24M4 29C9.07621 27.5355 16.9984 25.25 16.9984 25.25M16.9984 26.5V25.25M16.9984 20.5V22.5M16.9984 22.5V24M16.9984 24V25.25\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>"
5625
+ var shouldHideLabel = function shouldHideLabel(nItems, index, maxLabelCount) {
5626
+ var nthLabelsToShow = Math.ceil(nItems / maxLabelCount);
5627
+ return nItems > maxLabelCount &&
5628
+ // hide labels if too many items
5629
+ index !== nItems - 1 && (
5630
+ // not last item (always shown)
5631
+ // only show every nth label, skip label within last n/2 items so end doesn't get cluttered
5632
+ index % nthLabelsToShow !== 0 || nItems - 1 - index < nthLabelsToShow / 2);
5633
+ };
5634
+ var SoundingsTimeSlider = function SoundingsTimeSlider(_ref) {
5635
+ var timesteps = _ref.timesteps,
5636
+ selectedTime = _ref.selectedTime,
5637
+ updateSelectedTime = _ref.updateSelectedTime;
5638
+ var sliderRef = React.useRef(null);
5639
+ var maxLabelCount = useMaxLabelCount(sliderRef);
5640
+ var _useSoundingsTranslat = useSoundingsTranslation(),
5641
+ i18n = _useSoundingsTranslat.i18n;
5642
+ var marks = timesteps.filter(function (date) {
5643
+ return dateUtils.isValidIsoDateString(date);
5644
+ }).map(function (date, index, arr) {
5645
+ return {
5646
+ value: dateUtils.unix(dateUtils.getUtcFromString(date)),
5647
+ label: shouldHideLabel(arr.length, index, maxLabelCount) ? '' : dateUtils.dateToString(dateUtils.getUtcFromString(date), 'iii d. HH:mm', true, i18n.language)
5648
+ };
5649
+ });
5650
+ var currentTimeIndex = React.useMemo(function () {
5651
+ if (timesteps.length === 0) {
5652
+ return -1;
5653
+ }
5654
+ var selectedUtc = dateUtils.getUtcFromString(selectedTime);
5655
+ if (!selectedUtc) {
5656
+ return 0;
5657
+ }
5658
+ var selectedUnix = dateUtils.unix(selectedUtc);
5659
+ var indexByExactTimestamp = timesteps.findIndex(function (time) {
5660
+ var utcTime = dateUtils.getUtcFromString(time);
5661
+ if (!utcTime) {
5662
+ return false;
5663
+ }
5664
+ return dateUtils.unix(utcTime) === selectedUnix;
5665
+ });
5666
+ if (indexByExactTimestamp !== -1) {
5667
+ return indexByExactTimestamp;
5668
+ }
5669
+ var indexByExactString = timesteps.findIndex(function (time) {
5670
+ return time === selectedTime;
5671
+ });
5672
+ if (indexByExactString !== -1) {
5673
+ return indexByExactString;
5674
+ }
5675
+ // If selected time is not a sounding timestep, anchor on the nearest timestep
5676
+ // so forward/backward navigation continues from the expected point in time.
5677
+ return timesteps.reduce(function (nearestIndex, time, index) {
5678
+ var utcTime = dateUtils.getUtcFromString(time);
5679
+ if (!utcTime) {
5680
+ return nearestIndex;
5681
+ }
5682
+ var currentDiff = Math.abs(dateUtils.unix(utcTime) - selectedUnix);
5683
+ var nearestUtc = dateUtils.getUtcFromString(timesteps[nearestIndex]);
5684
+ if (!nearestUtc) {
5685
+ return index;
5686
+ }
5687
+ var nearestDiff = Math.abs(dateUtils.unix(nearestUtc) - selectedUnix);
5688
+ return currentDiff < nearestDiff ? index : nearestIndex;
5689
+ }, 0);
5690
+ }, [selectedTime, timesteps]);
5691
+ var onStepBackward = React.useCallback(function () {
5692
+ var precedingIndex = Math.max(currentTimeIndex - 1, 0);
5693
+ updateSelectedTime(timesteps[precedingIndex]);
5694
+ }, [currentTimeIndex, updateSelectedTime, timesteps]);
5695
+ var onStepForward = React.useCallback(function () {
5696
+ var followingIndex = Math.min(currentTimeIndex + 1, timesteps.length - 1);
5697
+ updateSelectedTime(timesteps[followingIndex]);
5698
+ }, [currentTimeIndex, updateSelectedTime, timesteps]);
5699
+ return jsxs("div", {
5700
+ ref: sliderRef,
5701
+ style: {
5702
+ display: 'flex',
5703
+ paddingTop: '32px',
5704
+ marginRight: '80px',
5705
+ marginLeft: '24px',
5706
+ height: TIMESLIDER_HEIGHT + "px"
5707
+ },
5708
+ children: [jsxs("div", {
5709
+ style: {
5710
+ minWidth: '60px',
5711
+ marginTop: '2px',
5712
+ display: 'flex',
5713
+ gap: '4px'
5714
+ },
5715
+ children: [jsx(BackwardForwardStepButton, {
5716
+ isDisabled: marks.length === 0,
5717
+ isForwardStep: false,
5718
+ onClickBFButton: onStepBackward
5719
+ }), jsx(BackwardForwardStepButton, {
5720
+ isDisabled: marks.length === 0,
5721
+ isForwardStep: true,
5722
+ onClickBFButton: onStepForward
5723
+ })]
5724
+ }), marks.length === 0 ? jsx(CustomSlider, {
5725
+ disabled: true,
5726
+ max: 1,
5727
+ min: 0,
5728
+ orientation: "horizontal",
5729
+ value: 0.5
5730
+ }) : jsx(CustomSlider, {
5731
+ extraStyles: {
5732
+ margin: '0px 20px 0px 20px',
5733
+ '.MuiSlider-markLabel': {
5734
+ transform: 'translate(-90%, 20px) rotate(-45deg)',
5735
+ transformOrigin: 'top center'
5736
+ }
5737
+ },
5738
+ marks: marks,
5739
+ max: marks[marks.length - 1].value,
5740
+ min: marks[0].value,
5741
+ onChange: function onChange(_, value) {
5742
+ updateSelectedTime(dateUtils.fromUnix(value).toISOString());
5743
+ },
5744
+ orientation: "horizontal",
5745
+ slotProps: {
5746
+ // Workaround for MUI bug where labels are just draggable area and clicking on one
5747
+ // does not necessarily select the described timestep
5748
+ markLabel: {
5749
+ onPointerDown: function onPointerDown(event) {
5750
+ event.preventDefault();
5751
+ var markIndex = event.currentTarget.getAttribute('data-index');
5752
+ var mark = marks[Number(markIndex)];
5753
+ var value = mark.value;
5754
+ updateSelectedTime(dateUtils.fromUnix(value).toISOString());
5755
+ }
5756
+ }
5757
+ },
5758
+ step: null,
5759
+ value: dateUtils.unix(dateUtils.getUtcFromString(selectedTime)),
5760
+ valueLabelDisplay: "on",
5761
+ valueLabelFormat: function valueLabelFormat(value) {
5762
+ return dateUtils.dateToString(dateUtils.fromUnix(value), "yyyy iii dd MMM HH:mm 'UTC'", true, i18n.language);
5763
+ }
5764
+ })]
5765
+ });
5476
5766
  };
5477
- var windSpeedRanges = [{
5478
- min: 0,
5479
- max: 1,
5480
- symbol: windSymbolDefinitions.calm
5481
- }, {
5482
- min: 1,
5483
- max: 4.5,
5484
- symbol: windSymbolDefinitions.lightAir
5485
- }, {
5486
- min: 4.5,
5487
- max: 7.5,
5488
- symbol: windSymbolDefinitions.fiveKnots
5489
- }, {
5490
- min: 7.5,
5491
- max: 12.5,
5492
- symbol: windSymbolDefinitions.tenKnots
5493
- }, {
5494
- min: 12.5,
5495
- max: 17.5,
5496
- symbol: windSymbolDefinitions.fifteenKnots
5497
- }, {
5498
- min: 17.5,
5499
- max: 22.5,
5500
- symbol: windSymbolDefinitions.twentyKnots
5501
- }, {
5502
- min: 22.5,
5503
- max: 27.5,
5504
- symbol: windSymbolDefinitions.twentyFiveKnots
5505
- }, {
5506
- min: 27.5,
5507
- max: 32.5,
5508
- symbol: windSymbolDefinitions.thirtyKnots
5509
- }, {
5510
- min: 32.5,
5511
- max: 37.5,
5512
- symbol: windSymbolDefinitions.thirtyFiveKnots
5513
- }, {
5514
- min: 37.5,
5515
- max: 42.5,
5516
- symbol: windSymbolDefinitions.fortyKnots
5517
- }, {
5518
- min: 42.5,
5519
- max: 47.5,
5520
- symbol: windSymbolDefinitions.fortyFiveKnots
5521
- }, {
5522
- min: 47.5,
5523
- max: 52.5,
5524
- symbol: windSymbolDefinitions.fiftyKnots
5525
- }, {
5526
- min: 52.5,
5527
- max: 57.5,
5528
- symbol: windSymbolDefinitions.fiftyFiveKnots
5529
- }, {
5530
- min: 57.5,
5531
- max: 62.5,
5532
- symbol: windSymbolDefinitions.sixtyKnots
5533
- }, {
5534
- min: 62.5,
5535
- max: 67.5,
5536
- symbol: windSymbolDefinitions.sixtyFiveKnots
5537
- }, {
5538
- min: 67.5,
5539
- max: 72.5,
5540
- symbol: windSymbolDefinitions.seventyKnots
5541
- }, {
5542
- min: 72.5,
5543
- max: 77.5,
5544
- symbol: windSymbolDefinitions.seventyFiveKnots
5545
- }, {
5546
- min: 77.5,
5547
- max: 82.5,
5548
- symbol: windSymbolDefinitions.eightyKnots
5549
- }, {
5550
- min: 82.5,
5551
- max: 87.5,
5552
- symbol: windSymbolDefinitions.eightyFiveKnots
5553
- }, {
5554
- min: 87.5,
5555
- max: 92.5,
5556
- symbol: windSymbolDefinitions.ninetyKnots
5557
- }, {
5558
- min: 92.5,
5559
- max: 97.5,
5560
- symbol: windSymbolDefinitions.ninetyFiveKnots
5561
- }, {
5562
- min: 97.5,
5563
- max: 102.5,
5564
- symbol: windSymbolDefinitions.hundredKnots
5565
- }, {
5566
- min: 102.5,
5567
- max: 107.5,
5568
- symbol: windSymbolDefinitions.hundredFiveKnots
5569
- }, {
5570
- min: 107.5,
5571
- max: 112.5,
5572
- symbol: windSymbolDefinitions.hundredTenKnots
5573
- }, {
5574
- min: 112.5,
5575
- max: 117.5,
5576
- symbol: windSymbolDefinitions.hundredFifteenKnots
5577
- }, {
5578
- min: 117.5,
5579
- max: 122.5,
5580
- symbol: windSymbolDefinitions.hundredTwentyKnots
5581
- }, {
5582
- min: 122.5,
5583
- max: 127.5,
5584
- symbol: windSymbolDefinitions.hundredTwentyFiveKnots
5585
- }, {
5586
- min: 127.5,
5587
- max: 132.5,
5588
- symbol: windSymbolDefinitions.hundredThirtyKnots
5589
- }, {
5590
- min: 132.5,
5591
- max: 137.5,
5592
- symbol: windSymbolDefinitions.hundredThirtyFiveKnots
5593
- }, {
5594
- min: 137.5,
5595
- max: 142.5,
5596
- symbol: windSymbolDefinitions.hundredFortyKnots
5597
- }, {
5598
- min: 142.5,
5599
- max: 147.5,
5600
- symbol: windSymbolDefinitions.hundredFortyFiveKnots
5601
- }, {
5602
- min: 147.5,
5603
- max: 152,
5604
- symbol: windSymbolDefinitions.hundredFiftyKnots
5605
- }];
5606
5767
 
5607
5768
  /* *
5608
5769
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -5621,137 +5782,59 @@ var windSpeedRanges = [{
5621
5782
  * Copyright 2025 - Finnish Meteorological Institute (FMI)
5622
5783
  * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
5623
5784
  * */
5624
- var extendIsoBar = function extendIsoBar(path, horizontalBarbMargin) {
5625
- var match = /^M([\d.-]+),([\d.-]+)\s*L([\d.-]+),([\d.-]+)/.exec(path);
5626
- if (match) {
5627
- var startX = parseFloat(match[1]);
5628
- var startY = parseFloat(match[2]);
5629
- var endX = parseFloat(match[3]);
5630
- var endY = parseFloat(match[4]);
5631
- return "M" + startX + "," + startY + "L" + (endX + horizontalBarbMargin * 3) + "," + endY;
5632
- }
5633
- return path;
5634
- };
5635
- var extendXAxis = function extendXAxis(path, horizontalBarbMargin) {
5636
- var match = /^M([\d.-]+),([\d.-]+)H([\d.-]+)/.exec(path);
5637
- if (match) {
5638
- var endX = parseFloat(match[3]);
5639
- return path.replace(/H[\d.-]+/, "H" + (endX + horizontalBarbMargin * 3));
5640
- }
5641
- return path;
5642
- };
5643
- var drawWindBarbs = function drawWindBarbs(_ref) {
5644
- var _rootSvg$node;
5645
- var svgRef = _ref.svgRef,
5646
- plotGroup = _ref.plotGroup,
5647
- yScale = _ref.yScale,
5648
- data = _ref.data,
5649
- width = _ref.width,
5650
- margin = _ref.margin,
5651
- _ref$barbColor = _ref.barbColor,
5652
- barbColor = _ref$barbColor === void 0 ? 'black' : _ref$barbColor,
5653
- _ref$columnOffsetX = _ref.columnOffsetX,
5654
- columnOffsetX = _ref$columnOffsetX === void 0 ? 0 : _ref$columnOffsetX,
5655
- _ref$verticalScale = _ref.verticalScale,
5656
- verticalScale = _ref$verticalScale === void 0 ? 1 : _ref$verticalScale;
5657
- var barbsSize = 40;
5658
- var scalingFactor = 0.5;
5659
- var horizontalBarbMargin = barbsSize * scalingFactor + 5;
5660
- var visibleItems = removeItemsExponential(data.reverse()).filter(function (item) {
5661
- return item.pressure >= 150;
5662
- });
5663
- // Measure width and height and make extra room for one column
5664
- // of windbarbs
5665
- var rootSvg = d3.select(svgRef.current);
5666
- var currentWidth = (_rootSvg$node = rootSvg.node()) == null ? void 0 : _rootSvg$node.getBoundingClientRect().width;
5667
- if (!currentWidth) {
5668
- return;
5785
+ var OFFSET_HEIGHT = 100; // Space reserved in layout
5786
+ var useSoundingsDiagramSize = function useSoundingsDiagramSize(ref, useWidth) {
5787
+ if (useWidth === void 0) {
5788
+ useWidth = true;
5669
5789
  }
5670
- // Add extra width to isobars in this SVG only.
5671
- rootSvg.selectAll('path[type="isobar"]').each(function (_d, i, nodes) {
5672
- var path = d3.select(nodes[i]).attr('d');
5673
- var newD = extendIsoBar(path, horizontalBarbMargin);
5674
- d3.select(nodes[i]).attr('d', newD).attr('clip-path', null);
5675
- });
5676
- // Add extra width to x-axis in this SVG only.
5677
- rootSvg.select('g[type="x-axis"] path.domain').each(function (_d, i, nodes) {
5678
- var path = d3.select(nodes[i]).attr('d');
5679
- var newD = extendXAxis(path, horizontalBarbMargin);
5680
- d3.select(nodes[i]).attr('d', newD);
5681
- });
5682
- // Expand root SVG width to make room for barbs column at the right
5683
- rootSvg.attr('width', currentWidth + margin.left + horizontalBarbMargin);
5684
- // Place the barbs just to the right of the plotting area.
5685
- // plotGroup's origin is already translated to (margin.left, margin.top),
5686
- // and its width equals `width`.
5687
- var windBarbColumnX = width + 5 + columnOffsetX + horizontalBarbMargin;
5688
- var barbGroup = plotGroup.append('g').attr('class', 'wind-group').attr('transform', // Apply translation and counter-scale to maintain aspect ratio during vertical zoom.
5689
- // The counter-scale (1, 1/verticalScale) undoes the parent's vertical scaling.
5690
- "translate(" + windBarbColumnX + ", 0) scale(1, " + 1 / verticalScale + ")");
5691
- barbGroup.selectAll('g').data(visibleItems).enter().append('g').attr('id', 'wind-barb').each(function handleBarb(data) {
5692
- var group = d3.select(this);
5693
- var windSymbol = getWindSymbol(data.windSpeed);
5694
- if (windSymbol) {
5695
- var _innerGroup$node;
5696
- // Inner group will have rotation and scaling applied to it
5697
- var innerGroup = group.append('g');
5698
- (_innerGroup$node = innerGroup.node()) == null || _innerGroup$node.appendChild(windSymbol);
5699
- // Update stroke color
5700
- innerGroup.selectAll('*').attr('stroke', barbColor);
5701
- // Only update the fill for the paths that already used a fill
5702
- // in their original svg form.
5703
- innerGroup.selectAll('*').each(function (_d, i, nodes) {
5704
- var el = d3.select(nodes[i]);
5705
- var currentFill = el.attr('fill');
5706
- if (currentFill && currentFill !== 'none') {
5707
- el.attr('fill', barbColor);
5708
- }
5709
- });
5710
- var bbox = windSymbol.getBBox();
5711
- // Central point
5712
- var cx = bbox.x + bbox.width / 2;
5713
- var cy = bbox.y + bbox.height / 2;
5714
- var rotation = 180 + data.windDirection;
5715
- var y = yScale(data.pressure);
5716
- // Place items in the correct vertical position.
5717
- // Apply verticalScale to compensate for the parent's counter-scale,
5718
- // ensuring barbs appear at the correct zoomed Y position.
5719
- group.attr('transform', "translate(0, " + (y - barbsSize * scalingFactor / 8) * verticalScale + ")");
5720
- // Rotate accordingly, and scale
5721
- innerGroup.attr('transform', "rotate(" + rotation + ") scale(" + scalingFactor + ") translate(" + -cx + ", " + -cy + ")");
5790
+ var _React$useState = React.useState(0),
5791
+ size = _React$useState[0],
5792
+ setSize = _React$useState[1];
5793
+ React.useLayoutEffect(function () {
5794
+ var container = ref.current;
5795
+ if (!container) {
5796
+ return undefined;
5722
5797
  }
5723
- });
5724
- };
5725
- var removeItemsExponential = function removeItemsExponential(array) {
5726
- var base = 1.15;
5727
- var indicesToKeep = [];
5728
- var i = 0;
5729
- var nextIndex = 0;
5730
- while (nextIndex < array.length) {
5731
- nextIndex = Math.floor(Math.pow(base, i));
5732
- indicesToKeep.push(nextIndex);
5733
- i += 1;
5734
- }
5735
- return array.filter(function (_, index) {
5736
- return indicesToKeep.includes(index);
5737
- });
5798
+ var resizeObserver = new ResizeObserver(function (entries) {
5799
+ if (!entries.length) {
5800
+ return;
5801
+ }
5802
+ var _entries$0$contentRec = entries[0].contentRect,
5803
+ width = _entries$0$contentRec.width,
5804
+ height = _entries$0$contentRec.height;
5805
+ var availableHeight = height - TIMESLIDER_HEIGHT + OFFSET_HEIGHT;
5806
+ var nextSize = useWidth ? Math.floor(Math.min(width, availableHeight)) : Math.floor(availableHeight);
5807
+ setSize(nextSize > 0 ? nextSize : 0);
5808
+ });
5809
+ resizeObserver.observe(container);
5810
+ return function () {
5811
+ resizeObserver.disconnect();
5812
+ };
5813
+ }, [ref, useWidth]);
5814
+ return size;
5738
5815
  };
5739
- var getWindSymbol = function getWindSymbol(value) {
5740
- var matchedRange = windSpeedRanges.find(function (_ref2) {
5741
- var min = _ref2.min,
5742
- max = _ref2.max;
5743
- return value >= min && value < max;
5744
- });
5745
- // Out of range
5746
- if (!matchedRange) {
5747
- return null;
5748
- }
5749
- // SVG string to actual SVG element
5750
- var parser = new DOMParser();
5751
- var svgDoc = parser.parseFromString(matchedRange.symbol, 'image/svg+xml');
5752
- var svgNode = svgDoc.documentElement;
5753
- // Return the parsed SVG node
5754
- return svgNode;
5816
+
5817
+ /* *
5818
+ * Licensed under the Apache License, Version 2.0 (the "License");
5819
+ * you may not use this file except in compliance with the License.
5820
+ * You may obtain a copy of the License at
5821
+ *
5822
+ * http://www.apache.org/licenses/LICENSE-2.0
5823
+ *
5824
+ * Unless required by applicable law or agreed to in writing, software
5825
+ * distributed under the License is distributed on an "AS IS" BASIS,
5826
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5827
+ * See the License for the specific language governing permissions and
5828
+ * limitations under the License.
5829
+ *
5830
+ * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
5831
+ * Copyright 2025 - Finnish Meteorological Institute (FMI)
5832
+ * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
5833
+ * */
5834
+ var animateResizeTransform = function animateResizeTransform(svg, marginLocal, innerHeight, prevInnerHeightRef) {
5835
+ var prevInnerHeight = typeof prevInnerHeightRef.current === 'number' ? prevInnerHeightRef.current : 0;
5836
+ var scaleYStart = prevInnerHeight > 0 && innerHeight > 0 ? prevInnerHeight / innerHeight : 0;
5837
+ svg.attr('transform', "translate(" + marginLocal.left + "," + marginLocal.top + ") scale(1," + scaleYStart + ")").transition().duration(300).attr('transform', "translate(" + marginLocal.left + "," + marginLocal.top + ") scale(1,1)");
5755
5838
  };
5756
5839
 
5757
5840
  var shadow = '0 1px 5px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.14)';
@@ -6496,6 +6579,7 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
6496
6579
  // Skip re-registering if the incoming preset already matches the current
6497
6580
  // soundings store state (e.g. workspace initialProps updated after a save)
6498
6581
  if (!isEqual(soundingsPreset, currentSoundingsPreset)) {
6582
+ var _soundingsPreset$isLo;
6499
6583
  presetJustLoadedRef.current = true;
6500
6584
  initialLocationsRef.current = soundingsPreset.selectedLocations || {};
6501
6585
  previousLocationsRef.current = {};
@@ -6503,6 +6587,11 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
6503
6587
  viewId: viewId,
6504
6588
  preset: soundingsPreset
6505
6589
  }));
6590
+ dispatch(uiActions.setActiveMapIdForDialog({
6591
+ type: uiTypes.DialogTypes.SoundingsLocations,
6592
+ mapId: viewId,
6593
+ setOpen: (_soundingsPreset$isLo = soundingsPreset.isLocationsDialogOpen) != null ? _soundingsPreset$isLo : false
6594
+ }));
6506
6595
  setTimeout(function () {
6507
6596
  presetJustLoadedRef.current = false;
6508
6597
  initialLocationsRef.current = {};
@@ -7624,7 +7713,10 @@ var LocationsMenu = function LocationsMenu(_ref2) {
7624
7713
  _ref2$order = _ref2.order,
7625
7714
  order = _ref2$order === void 0 ? 0 : _ref2$order,
7626
7715
  isLoading = _ref2.isLoading,
7627
- error = _ref2.error;
7716
+ error = _ref2.error,
7717
+ locationMenuSize = _ref2.locationMenuSize,
7718
+ onSizeChange = _ref2.onSizeChange,
7719
+ locationMenuPosition = _ref2.locationMenuPosition;
7628
7720
  var _useState = useState(''),
7629
7721
  searchFilter = _useState[0],
7630
7722
  setSearchFilter = _useState[1];
@@ -7651,13 +7743,26 @@ var LocationsMenu = function LocationsMenu(_ref2) {
7651
7743
  isOpen: isOpen,
7652
7744
  minWidth: 264,
7653
7745
  onClose: onClose,
7746
+ onDragEnd: function onDragEnd(position, size) {
7747
+ if (typeof size.width === 'number' && typeof size.height === 'number') {
7748
+ onSizeChange == null || onSizeChange({
7749
+ width: size.width,
7750
+ height: size.height
7751
+ }, position);
7752
+ }
7753
+ },
7654
7754
  onMouseDown: onMouseDown,
7655
7755
  order: order,
7756
+ resetPositionOnOpen: true,
7757
+ startDraggablePosition: locationMenuPosition != null ? locationMenuPosition : {
7758
+ x: 0,
7759
+ y: 0
7760
+ },
7656
7761
  startPosition: {
7657
7762
  top: 60,
7658
7763
  left: 200
7659
7764
  },
7660
- startSize: {
7765
+ startSize: locationMenuSize != null ? locationMenuSize : {
7661
7766
  width: 320,
7662
7767
  height: 500
7663
7768
  },
@@ -7773,6 +7878,12 @@ var LocationsMenuConnect = function LocationsMenuConnect(_ref) {
7773
7878
  dispatch(soundingsActions.setSoundingsCollections(soundingsCollections));
7774
7879
  }
7775
7880
  }, [dispatch, soundingsCollections]);
7881
+ var locationMenuSize = useSelector(function (state) {
7882
+ return getLocationMenuSize(state, viewId);
7883
+ });
7884
+ var locationMenuPosition = useSelector(function (state) {
7885
+ return getLocationMenuPosition(state, viewId);
7886
+ });
7776
7887
  var _useGetLocations = useGetLocations(collections, isDialogOpen),
7777
7888
  data = _useGetLocations.data,
7778
7889
  isPending = _useGetLocations.isPending,
@@ -7846,12 +7957,31 @@ var LocationsMenuConnect = function LocationsMenuConnect(_ref) {
7846
7957
  }
7847
7958
  }
7848
7959
  }, [dispatch, viewId, services, selectedSourceIds, locationSelections, selectedMapIds, ownedFeatureLayerIds]);
7960
+ var handleSizeChange = useCallback(function (size, position) {
7961
+ dispatch(soundingsActions.setLocationMenuSizeAndPosition({
7962
+ size: size,
7963
+ position: position,
7964
+ viewId: viewId,
7965
+ origin: SoundingsActionOrigin.soundingsComponent
7966
+ }));
7967
+ }, [dispatch, viewId]);
7968
+ var handleClose = useCallback(function () {
7969
+ onCloseDialog();
7970
+ dispatch(soundingsActions.setLocationsMenuOpen({
7971
+ viewId: viewId,
7972
+ isLocationsDialogOpen: false,
7973
+ origin: SoundingsActionOrigin.soundingsComponent
7974
+ }));
7975
+ }, [dispatch, onCloseDialog, viewId]);
7849
7976
  return jsx(LocationsMenu, {
7850
7977
  error: error,
7851
7978
  isLoading: isPending,
7852
7979
  isOpen: isDialogOpen,
7853
- onClose: onCloseDialog,
7980
+ locationMenuPosition: locationMenuPosition,
7981
+ locationMenuSize: locationMenuSize,
7982
+ onClose: handleClose,
7854
7983
  onMouseDown: setDialogOrder,
7984
+ onSizeChange: handleSizeChange,
7855
7985
  order: dialogOrder,
7856
7986
  selectedLocations: locationSelections,
7857
7987
  selectedSourcesAmount: sourcesAmount,