@ohif/app 3.8.0-beta.63 → 3.8.0-beta.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{121.bundle.f6c25e845985d96c423c.js → 121.bundle.fda405f29003c308ce09.js} +4 -4
  2. package/dist/{155.bundle.9e3dd18c9a3961232504.js → 155.bundle.a57744809d0f46030ee0.js} +12 -7
  3. package/dist/{188.bundle.528e9ad81159c776affa.js → 188.bundle.c448aed48915741e9f97.js} +2 -2
  4. package/dist/{270.bundle.fd387adff5b064fca506.js → 270.bundle.16ac8114c5c4ce006f4a.js} +51 -28
  5. package/dist/{295.bundle.c132f53e1397ef9d432a.js → 295.bundle.57700cd41fd87e1521b4.js} +4 -4
  6. package/dist/{339.bundle.591a0a6075220b14c249.js → 339.bundle.57dac3644803cefe3e3d.js} +27 -69
  7. package/dist/{68.bundle.efc5ba2a44aa2b96ee1a.js → 41.bundle.58b85dd990fb6fac615e.js} +280 -494
  8. package/dist/{250.bundle.d8b502b7ef6afc79a87e.js → 448.bundle.d195aba3aef25ec286d1.js} +284 -388
  9. package/dist/{530.bundle.ef1ea9d98f7b377a9d3a.js → 530.bundle.72d9812f117036615a38.js} +2 -2
  10. package/dist/{544.bundle.05b543f28d0c124950ef.js → 544.bundle.c3009e245ceb1554c70a.js} +5 -17
  11. package/dist/{559.bundle.fc08eab02848a451ed34.js → 559.bundle.05bd51e94422a2cab116.js} +6 -10
  12. package/dist/{594.bundle.3a5fa2e7d5636ddccb32.js → 594.bundle.14b122ab995e4b13e652.js} +147 -188
  13. package/dist/{50.bundle.55ad62f1f656f5fd5a36.js → 638.bundle.a63003e18bed65f227bb.js} +159 -395
  14. package/dist/699.bundle.efc67171e6d212f25a24.js +774 -0
  15. package/dist/{963.bundle.874395d7b2d80f9e5831.js → 701.bundle.bc40f1a7d5d6b1a4dd38.js} +554 -215
  16. package/dist/{724.bundle.294a41af83a5af33f3cc.js → 724.bundle.3945f8d2e9c8b0b23628.js} +86 -164
  17. package/dist/{862.bundle.c8eba798644149650775.js → 862.bundle.d787dac01f4567560a42.js} +2 -2
  18. package/dist/{889.bundle.a776c87be9e3580f3437.js → 889.bundle.ffc727aa6d1a74f2138d.js} +180 -207
  19. package/dist/{704.bundle.842ada45436f1fb029aa.js → 90.bundle.abde898ebd3c74f521f9.js} +323 -334
  20. package/dist/{905.bundle.73a711d0255cb988fa6e.js → 905.bundle.6b5b42b2403e4676bb3a.js} +119 -89
  21. package/dist/{907.bundle.6932f0458b9e0143c18a.js → 907.bundle.fbd5768fa5b53f9d3f86.js} +2 -14
  22. package/dist/{961.bundle.6cf1599ed3a2871c040f.js → 961.bundle.8bb5a713fc5a3817c6a6.js} +2 -15
  23. package/dist/{987.bundle.e7c041a6dfb4ddb41813.js → 987.bundle.91d4867efedd5b4d84cb.js} +5 -1
  24. package/dist/{app.bundle.22ffa6050ebef98b2066.js → app.bundle.0c24b249dc8b631916ef.js} +2234 -980
  25. package/dist/app.bundle.css +1 -1
  26. package/dist/index.html +1 -1
  27. package/dist/{polySeg.bundle.99be036bab9b7f011b0c.js → polySeg.bundle.c1cec6312eb6c6dc3701.js} +1 -1
  28. package/dist/sw.js +1 -1
  29. package/package.json +17 -17
  30. package/dist/317.bundle.dd0879c5035c4b90fad3.js +0 -562
  31. /package/dist/{164.bundle.710b5db3fef4d536a59f.js → 164.bundle.ff12d6019a627cda2a6c.js} +0 -0
  32. /package/dist/{50.css → 638.css} +0 -0
  33. /package/dist/{963.css → 701.css} +0 -0
@@ -51,7 +51,7 @@ var useSearchParams = __webpack_require__(86669);
51
51
 
52
52
  /***/ }),
53
53
 
54
- /***/ 45573:
54
+ /***/ 68870:
55
55
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
56
56
 
57
57
  "use strict";
@@ -99,12 +99,12 @@ Compose.propTypes = {
99
99
  components: (prop_types_default()).array,
100
100
  children: (prop_types_default()).node.isRequired
101
101
  };
102
- // EXTERNAL MODULE: ../../ui/src/index.js + 489 modules
103
- var ui_src = __webpack_require__(6804);
102
+ // EXTERNAL MODULE: ../../ui/src/index.js + 497 modules
103
+ var ui_src = __webpack_require__(58046);
104
104
  // EXTERNAL MODULE: ./state/index.js + 1 modules
105
105
  var state = __webpack_require__(15575);
106
- // EXTERNAL MODULE: ../../core/src/index.ts + 66 modules
107
- var core_src = __webpack_require__(14283);
106
+ // EXTERNAL MODULE: ../../core/src/index.ts + 67 modules
107
+ var core_src = __webpack_require__(78198);
108
108
  // EXTERNAL MODULE: ../node_modules/react-router/dist/index.js
109
109
  var react_router_dist = __webpack_require__(10971);
110
110
  // EXTERNAL MODULE: ./hooks/useSearchParams.ts
@@ -993,7 +993,7 @@ function WorkList({
993
993
  }) // launch-arrow | launch-info
994
994
  ,
995
995
  onClick: () => {},
996
- "data-cy": `mode-${mode.routeName}-${studyInstanceUid}`,
996
+ dataCY: `mode-${mode.routeName}-${studyInstanceUid}`,
997
997
  className: isValidMode ? 'text-[13px]' : 'bg-[#222d44] text-[13px]'
998
998
  }, mode.displayName));
999
999
  }))),
@@ -1002,8 +1002,8 @@ function WorkList({
1002
1002
  };
1003
1003
  });
1004
1004
  const hasStudies = numOfStudies > 0;
1005
- const versionNumber = "3.8.0-beta.63";
1006
- const commitHash = "45b68e841dcb9e28a2ea991c37ee7ac4a8c5b71e";
1005
+ const versionNumber = "3.8.0-beta.65";
1006
+ const commitHash = "617043fe0da5de91fbea4ac33a27f1df16ae1ca6";
1007
1007
  const menuOptions = [{
1008
1008
  title: t('Header:About'),
1009
1009
  icon: 'info',
@@ -1533,6 +1533,7 @@ function ViewerViewportGrid(props) {
1533
1533
  numRows
1534
1534
  } = layout;
1535
1535
  const elementRef = (0,react.useRef)(null);
1536
+ const layoutHash = (0,react.useRef)(null);
1536
1537
 
1537
1538
  // TODO -> Need some way of selecting which displaySets hit the viewports.
1538
1539
  const {
@@ -1541,6 +1542,7 @@ function ViewerViewportGrid(props) {
1541
1542
  hangingProtocolService,
1542
1543
  uiNotificationService
1543
1544
  } = servicesManager.services;
1545
+ const generateLayoutHash = () => `${numCols}-${numRows}`;
1544
1546
 
1545
1547
  /**
1546
1548
  * This callback runs after the viewports structure has changed in any way.
@@ -1641,6 +1643,16 @@ function ViewerViewportGrid(props) {
1641
1643
  unsubscribe();
1642
1644
  };
1643
1645
  }, []);
1646
+
1647
+ // Check viewport readiness in useEffect
1648
+ (0,react.useEffect)(() => {
1649
+ const allReady = viewportGridService.getGridViewportsReady();
1650
+ const sameLayoutHash = layoutHash.current === generateLayoutHash();
1651
+ if (allReady && !sameLayoutHash) {
1652
+ layoutHash.current = generateLayoutHash();
1653
+ viewportGridService.publishViewportsReady();
1654
+ }
1655
+ }, [viewportGridService, generateLayoutHash]);
1644
1656
  (0,react.useEffect)(() => {
1645
1657
  const {
1646
1658
  unsubscribe
@@ -1811,7 +1823,10 @@ function ViewerViewportGrid(props) {
1811
1823
  dataSource: dataSource,
1812
1824
  viewportOptions: viewportOptions,
1813
1825
  displaySetOptions: displaySetOptions,
1814
- needsRerendering: displaySetsNeedsRerendering
1826
+ needsRerendering: displaySetsNeedsRerendering,
1827
+ onReady: () => {
1828
+ viewportGridService.setViewportIsReady(viewportId, true);
1829
+ }
1815
1830
  })));
1816
1831
  }
1817
1832
  return viewportPanes;
@@ -1876,68 +1891,6 @@ function _getViewportComponent(displaySets, viewportComponents, uiNotificationSe
1876
1891
  return components_EmptyViewport;
1877
1892
  }
1878
1893
  /* harmony default export */ const ViewportGrid = (ViewerViewportGrid);
1879
- ;// CONCATENATED MODULE: ./routes/Mode/studiesList.ts
1880
-
1881
- /**
1882
- * Compare function for sorting
1883
- *
1884
- * @param a - some simple value (string, number, timestamp)
1885
- * @param b - some simple value
1886
- * @param defaultCompare - default return value as a fallback when a===b
1887
- * @returns - compare a and b, returning 1 if a<b -1 if a>b and defaultCompare otherwise
1888
- */
1889
- const compare = (a, b, defaultCompare = 0) => {
1890
- if (a === b) {
1891
- return defaultCompare;
1892
- }
1893
- if (a < b) {
1894
- return 1;
1895
- }
1896
- return -1;
1897
- };
1898
-
1899
- /**
1900
- * The studies from display sets gets the studies in study date
1901
- * order or in study instance UID order - not very useful, but
1902
- * if not specifically specified then at least making it consistent is useful.
1903
- */
1904
- const getStudiesfromDisplaySets = displaysets => {
1905
- const studyMap = {};
1906
- const ret = displaySets.reduce((prev, curr) => {
1907
- const {
1908
- StudyInstanceUID
1909
- } = curr;
1910
- if (!studyMap[StudyInstanceUID]) {
1911
- const study = core_src.DicomMetadataStore.getStudy(StudyInstanceUID);
1912
- studyMap[StudyInstanceUID] = study;
1913
- prev.push(study);
1914
- }
1915
- return prev;
1916
- }, []);
1917
- // Return the sorted studies, first on study date and second on study instance UID
1918
- ret.sort((a, b) => {
1919
- return compare(a.StudyDate, b.StudyDate, compare(a.StudyInstanceUID, b.StudyInstanceUID));
1920
- });
1921
- return ret;
1922
- };
1923
-
1924
- /**
1925
- * The studies retrieve from the Uids is faster and gets the studies
1926
- * in the original order, as specified.
1927
- */
1928
- const getStudiesFromUIDs = studyUids => {
1929
- if (!studyUids?.length) {
1930
- return;
1931
- }
1932
- return studyUids.map(uid => core_src.DicomMetadataStore.getStudy(uid));
1933
- };
1934
-
1935
- /** Gets the array of studies */
1936
- const getStudies = (studyUids, displaySets) => {
1937
- return getStudiesFromUIDs(studyUids) || getStudiesfromDisplaySets(displaySets);
1938
- };
1939
- /* harmony default export */ const studiesList = (getStudies);
1940
-
1941
1894
  ;// CONCATENATED MODULE: ./utils/history.ts
1942
1895
  const history_history = {
1943
1896
  navigate: null
@@ -1962,15 +1915,15 @@ modes.push("@ohif/mode-microscopy");
1962
1915
  async function loadModule(module) {
1963
1916
  if (typeof module !== 'string') return module;
1964
1917
  if (module === "@ohif/extension-default") {
1965
- const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(931), __webpack_require__.e(704), __webpack_require__.e(481)]).then(__webpack_require__.bind(__webpack_require__, 49704));
1918
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(931), __webpack_require__.e(90), __webpack_require__.e(481)]).then(__webpack_require__.bind(__webpack_require__, 54090));
1966
1919
  return imported.default;
1967
1920
  }
1968
1921
  if (module === "@ohif/extension-cornerstone") {
1969
- const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(290), __webpack_require__.e(963)]).then(__webpack_require__.bind(__webpack_require__, 34963));
1922
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(290), __webpack_require__.e(701)]).then(__webpack_require__.bind(__webpack_require__, 20701));
1970
1923
  return imported.default;
1971
1924
  }
1972
1925
  if (module === "@ohif/extension-measurement-tracking") {
1973
- const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(342), __webpack_require__.e(931), __webpack_require__.e(835), __webpack_require__.e(704), __webpack_require__.e(559), __webpack_require__.e(155)]).then(__webpack_require__.bind(__webpack_require__, 63934));
1926
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(342), __webpack_require__.e(931), __webpack_require__.e(835), __webpack_require__.e(90), __webpack_require__.e(559), __webpack_require__.e(155)]).then(__webpack_require__.bind(__webpack_require__, 63934));
1974
1927
  return imported.default;
1975
1928
  }
1976
1929
  if (module === "@ohif/extension-cornerstone-dicom-sr") {
@@ -1978,7 +1931,7 @@ async function loadModule(module) {
1978
1931
  return imported.default;
1979
1932
  }
1980
1933
  if (module === "@ohif/extension-cornerstone-dicom-seg") {
1981
- const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(342), __webpack_require__.e(931), __webpack_require__.e(726), __webpack_require__.e(704), __webpack_require__.e(50)]).then(__webpack_require__.bind(__webpack_require__, 71093));
1934
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(504), __webpack_require__.e(191), __webpack_require__.e(644), __webpack_require__.e(342), __webpack_require__.e(931), __webpack_require__.e(726), __webpack_require__.e(90), __webpack_require__.e(638)]).then(__webpack_require__.bind(__webpack_require__, 92169));
1982
1935
  return imported.default;
1983
1936
  }
1984
1937
  if (module === "@ohif/extension-dicom-microscopy") {
@@ -2006,11 +1959,11 @@ async function loadModule(module) {
2006
1959
  return imported.default;
2007
1960
  }
2008
1961
  if (module === "@ohif/mode-longitudinal") {
2009
- const imported = await __webpack_require__.e(/* import() */ 68).then(__webpack_require__.bind(__webpack_require__, 76068));
1962
+ const imported = await __webpack_require__.e(/* import() */ 41).then(__webpack_require__.bind(__webpack_require__, 97041));
2010
1963
  return imported.default;
2011
1964
  }
2012
1965
  if (module === "@ohif/mode-segmentation") {
2013
- const imported = await __webpack_require__.e(/* import() */ 317).then(__webpack_require__.bind(__webpack_require__, 55317));
1966
+ const imported = await __webpack_require__.e(/* import() */ 699).then(__webpack_require__.bind(__webpack_require__, 40080));
2014
1967
  return imported.default;
2015
1968
  }
2016
1969
  if (module === "@ohif/mode-tmtv") {
@@ -2022,7 +1975,7 @@ async function loadModule(module) {
2022
1975
  return imported.default;
2023
1976
  }
2024
1977
  if (module === "@ohif/mode-test") {
2025
- const imported = await __webpack_require__.e(/* import() */ 250).then(__webpack_require__.bind(__webpack_require__, 11250));
1978
+ const imported = await __webpack_require__.e(/* import() */ 448).then(__webpack_require__.bind(__webpack_require__, 14448));
2026
1979
  return imported.default;
2027
1980
  }
2028
1981
  if (module === "@ohif/mode-basic-dev-mode") {
@@ -2038,6 +1991,68 @@ function importItems(modules) {
2038
1991
  return Promise.all(modules.map(loadModule));
2039
1992
  }
2040
1993
 
1994
+ ;// CONCATENATED MODULE: ./routes/Mode/studiesList.ts
1995
+
1996
+ /**
1997
+ * Compare function for sorting
1998
+ *
1999
+ * @param a - some simple value (string, number, timestamp)
2000
+ * @param b - some simple value
2001
+ * @param defaultCompare - default return value as a fallback when a===b
2002
+ * @returns - compare a and b, returning 1 if a<b -1 if a>b and defaultCompare otherwise
2003
+ */
2004
+ const compare = (a, b, defaultCompare = 0) => {
2005
+ if (a === b) {
2006
+ return defaultCompare;
2007
+ }
2008
+ if (a < b) {
2009
+ return 1;
2010
+ }
2011
+ return -1;
2012
+ };
2013
+
2014
+ /**
2015
+ * The studies from display sets gets the studies in study date
2016
+ * order or in study instance UID order - not very useful, but
2017
+ * if not specifically specified then at least making it consistent is useful.
2018
+ */
2019
+ const getStudiesfromDisplaySets = displaysets => {
2020
+ const studyMap = {};
2021
+ const ret = displaySets.reduce((prev, curr) => {
2022
+ const {
2023
+ StudyInstanceUID
2024
+ } = curr;
2025
+ if (!studyMap[StudyInstanceUID]) {
2026
+ const study = core_src.DicomMetadataStore.getStudy(StudyInstanceUID);
2027
+ studyMap[StudyInstanceUID] = study;
2028
+ prev.push(study);
2029
+ }
2030
+ return prev;
2031
+ }, []);
2032
+ // Return the sorted studies, first on study date and second on study instance UID
2033
+ ret.sort((a, b) => {
2034
+ return compare(a.StudyDate, b.StudyDate, compare(a.StudyInstanceUID, b.StudyInstanceUID));
2035
+ });
2036
+ return ret;
2037
+ };
2038
+
2039
+ /**
2040
+ * The studies retrieve from the Uids is faster and gets the studies
2041
+ * in the original order, as specified.
2042
+ */
2043
+ const getStudiesFromUIDs = studyUids => {
2044
+ if (!studyUids?.length) {
2045
+ return;
2046
+ }
2047
+ return studyUids.map(uid => core_src.DicomMetadataStore.getStudy(uid));
2048
+ };
2049
+
2050
+ /** Gets the array of studies */
2051
+ const getStudies = (studyUids, displaySets) => {
2052
+ return getStudiesFromUIDs(studyUids) || getStudiesfromDisplaySets(displaySets);
2053
+ };
2054
+ /* harmony default export */ const studiesList = (getStudies);
2055
+
2041
2056
  ;// CONCATENATED MODULE: ./utils/isSeriesFilterUsed.ts
2042
2057
  /**
2043
2058
  * This function is used to check if the filter is used. Its intend is to
@@ -2055,23 +2070,12 @@ function isSeriesFilterUsed(instances, filters) {
2055
2070
  }
2056
2071
  return seriesInstanceUIDs.includes(instances[0].SeriesInstanceUID);
2057
2072
  }
2058
- ;// CONCATENATED MODULE: ./routes/Mode/Mode.tsx
2059
-
2060
-
2061
-
2062
- // TODO: DicomMetadataStore should be injected?
2063
-
2064
-
2065
-
2066
-
2067
-
2068
-
2073
+ ;// CONCATENATED MODULE: ./routes/Mode/defaultRouteInit.ts
2069
2074
 
2070
2075
 
2071
2076
 
2072
2077
 
2073
2078
  const {
2074
- getSplitParam,
2075
2079
  sortingCriteria
2076
2080
  } = core_src.utils;
2077
2081
 
@@ -2190,6 +2194,55 @@ function defaultRouteInit({
2190
2194
  });
2191
2195
  return unsubscriptions;
2192
2196
  }
2197
+ ;// CONCATENATED MODULE: ./routes/Mode/updateAuthServiceAndCleanUrl.ts
2198
+ /**
2199
+ * Updates the user authentication service with the provided token and cleans the token from the URL.
2200
+ * @param token - The token to set in the user authentication service.
2201
+ * @param location - The location object from the router.
2202
+ * @param userAuthenticationService - The user authentication service instance.
2203
+ */
2204
+ function updateAuthServiceAndCleanUrl(token, location, userAuthenticationService) {
2205
+ if (!token) {
2206
+ return;
2207
+ }
2208
+
2209
+ // if a token is passed in, set the userAuthenticationService to use it
2210
+ // for the Authorization header for all requests
2211
+ userAuthenticationService.setServiceImplementation({
2212
+ getAuthorizationHeader: () => ({
2213
+ Authorization: 'Bearer ' + token
2214
+ })
2215
+ });
2216
+
2217
+ // Create a URL object with the current location
2218
+ const urlObj = new URL(window.location.origin + window.location.pathname + location.search);
2219
+
2220
+ // Remove the token from the URL object
2221
+ urlObj.searchParams.delete('token');
2222
+ const cleanUrl = urlObj.toString();
2223
+
2224
+ // Update the browser's history without the token
2225
+ if (window.history && window.history.replaceState) {
2226
+ window.history.replaceState(null, '', cleanUrl);
2227
+ }
2228
+ }
2229
+ ;// CONCATENATED MODULE: ./routes/Mode/Mode.tsx
2230
+
2231
+
2232
+
2233
+
2234
+
2235
+
2236
+
2237
+
2238
+
2239
+
2240
+
2241
+
2242
+
2243
+ const {
2244
+ getSplitParam
2245
+ } = core_src.utils;
2193
2246
  function ModeRoute({
2194
2247
  mode,
2195
2248
  dataSourceName,
@@ -2219,7 +2272,7 @@ function ModeRoute({
2219
2272
  const lowerCaseSearchParams = (0,hooks/* useSearchParams */.o)({
2220
2273
  lowerCaseKeys: true
2221
2274
  });
2222
- const [studyInstanceUIDs, setStudyInstanceUIDs] = (0,react.useState)();
2275
+ const [studyInstanceUIDs, setStudyInstanceUIDs] = (0,react.useState)(null);
2223
2276
  const [refresh, setRefresh] = (0,react.useState)(false);
2224
2277
  const [ExtensionDependenciesLoaded, setExtensionDependenciesLoaded] = (0,react.useState)(false);
2225
2278
  const layoutTemplateData = (0,react.useRef)(false);
@@ -2246,25 +2299,7 @@ function ModeRoute({
2246
2299
  const runTimeHangingProtocolId = lowerCaseSearchParams.get('hangingprotocolid');
2247
2300
  const token = lowerCaseSearchParams.get('token');
2248
2301
  if (token) {
2249
- // if a token is passed in, set the userAuthenticationService to use it
2250
- // for the Authorization header for all requests
2251
- userAuthenticationService.setServiceImplementation({
2252
- getAuthorizationHeader: () => ({
2253
- Authorization: 'Bearer ' + token
2254
- })
2255
- });
2256
-
2257
- // Create a URL object with the current location
2258
- const urlObj = new URL(window.location.origin + window.location.pathname + location.search);
2259
-
2260
- // Remove the token from the URL object
2261
- urlObj.searchParams.delete('token');
2262
- const cleanUrl = urlObj.toString();
2263
-
2264
- // Update the browser's history without the token
2265
- if (window.history && window.history.replaceState) {
2266
- window.history.replaceState(null, '', cleanUrl);
2267
- }
2302
+ updateAuthServiceAndCleanUrl(token, location, userAuthenticationService);
2268
2303
  }
2269
2304
 
2270
2305
  // Preserve the old array interface for hotkeys
@@ -2279,32 +2314,6 @@ function ModeRoute({
2279
2314
 
2280
2315
  // Only handling one route per mode for now
2281
2316
  const route = mode.routes[0];
2282
-
2283
- // For each extension, look up their context modules
2284
- // TODO: move to extension manager.
2285
- let contextModules = [];
2286
- Object.keys(extensions).forEach(extensionId => {
2287
- const allRegisteredModuleIds = Object.keys(extensionManager.modulesMap);
2288
- const moduleIds = allRegisteredModuleIds.filter(id => id.includes(`${extensionId}.contextModule.`));
2289
- if (!moduleIds || !moduleIds.length) {
2290
- return;
2291
- }
2292
- const modules = moduleIds.map(extensionManager.getModuleEntry);
2293
- contextModules = contextModules.concat(modules);
2294
- });
2295
- const contextModuleProviders = contextModules.map(a => a.provider);
2296
- const CombinedContextProvider = ({
2297
- children
2298
- }) => Compose({
2299
- components: contextModuleProviders,
2300
- children
2301
- });
2302
- function ViewportGridWithDataSource(props) {
2303
- return ViewportGrid({
2304
- ...props,
2305
- dataSource
2306
- });
2307
- }
2308
2317
  (0,react.useEffect)(() => {
2309
2318
  const loadExtensions = async () => {
2310
2319
  const loadedExtensions = await importItems(Object.keys(extensions));
@@ -2349,7 +2358,7 @@ function ModeRoute({
2349
2358
  };
2350
2359
  }, [location, ExtensionDependenciesLoaded]);
2351
2360
  (0,react.useEffect)(() => {
2352
- if (!ExtensionDependenciesLoaded) {
2361
+ if (!ExtensionDependenciesLoaded || !studyInstanceUIDs?.length) {
2353
2362
  return;
2354
2363
  }
2355
2364
  const retrieveLayoutData = async () => {
@@ -2363,7 +2372,7 @@ function ModeRoute({
2363
2372
  setRefresh(!refresh);
2364
2373
  }
2365
2374
  };
2366
- if (studyInstanceUIDs?.length && studyInstanceUIDs[0] !== undefined) {
2375
+ if (Array.isArray(studyInstanceUIDs) && studyInstanceUIDs[0]) {
2367
2376
  retrieveLayoutData();
2368
2377
  }
2369
2378
  return () => {
@@ -2371,7 +2380,7 @@ function ModeRoute({
2371
2380
  };
2372
2381
  }, [studyInstanceUIDs, ExtensionDependenciesLoaded]);
2373
2382
  (0,react.useEffect)(() => {
2374
- if (!hotkeys || !ExtensionDependenciesLoaded) {
2383
+ if (!hotkeys || !ExtensionDependenciesLoaded || !studyInstanceUIDs?.length) {
2375
2384
  return;
2376
2385
  }
2377
2386
  hotkeysManager.setDefaultHotKeys(hotkeys);
@@ -2384,9 +2393,9 @@ function ModeRoute({
2384
2393
  return () => {
2385
2394
  hotkeysManager.destroy();
2386
2395
  };
2387
- }, [ExtensionDependenciesLoaded]);
2396
+ }, [ExtensionDependenciesLoaded, hotkeys, studyInstanceUIDs]);
2388
2397
  (0,react.useEffect)(() => {
2389
- if (!layoutTemplateData.current || !ExtensionDependenciesLoaded) {
2398
+ if (!layoutTemplateData.current || !ExtensionDependenciesLoaded || !studyInstanceUIDs?.length) {
2390
2399
  return;
2391
2400
  }
2392
2401
  const setupRouteInit = async () => {
@@ -2493,20 +2502,57 @@ function ModeRoute({
2493
2502
  extensionManager.onModeExit();
2494
2503
  };
2495
2504
  }, [mode, dataSourceName, location, ExtensionDependenciesLoaded, route, servicesManager, extensionManager, hotkeysManager, studyInstanceUIDs, refresh]);
2496
- const renderLayoutData = props => {
2505
+ if (!studyInstanceUIDs || !layoutTemplateData.current || !ExtensionDependenciesLoaded) {
2506
+ return null;
2507
+ }
2508
+ const ViewportGridWithDataSource = props => {
2509
+ return ViewportGrid({
2510
+ ...props,
2511
+ dataSource
2512
+ });
2513
+ };
2514
+ const CombinedExtensionsContextProvider = createCombinedContextProvider(extensionManager, servicesManager, commandsManager);
2515
+ const getLayoutComponent = props => {
2497
2516
  const layoutTemplateModuleEntry = extensionManager.getModuleEntry(layoutTemplateData.current.id);
2498
2517
  const LayoutComponent = layoutTemplateModuleEntry.component;
2499
2518
  return /*#__PURE__*/react.createElement(LayoutComponent, props);
2500
2519
  };
2501
- return /*#__PURE__*/react.createElement(ui_src/* ImageViewerProvider */.xy
2502
- // initialState={{ StudyInstanceUIDs: StudyInstanceUIDs }}
2503
- , {
2504
- StudyInstanceUIDs: studyInstanceUIDs
2505
- // reducer={reducer}
2506
- }, /*#__PURE__*/react.createElement(CombinedContextProvider, null, /*#__PURE__*/react.createElement(ui_src/* DragAndDropProvider */.G8, null, layoutTemplateData.current && studyInstanceUIDs?.[0] !== undefined && ExtensionDependenciesLoaded && renderLayoutData({
2520
+ const LayoutComponent = getLayoutComponent({
2507
2521
  ...layoutTemplateData.current.props,
2508
2522
  ViewportGridComp: ViewportGridWithDataSource
2509
- }))));
2523
+ });
2524
+ return /*#__PURE__*/react.createElement(ui_src/* ImageViewerProvider */.xy, {
2525
+ StudyInstanceUIDs: studyInstanceUIDs
2526
+ }, CombinedExtensionsContextProvider ? /*#__PURE__*/react.createElement(CombinedExtensionsContextProvider, null, /*#__PURE__*/react.createElement(ui_src/* DragAndDropProvider */.G8, null, LayoutComponent)) : /*#__PURE__*/react.createElement(ui_src/* DragAndDropProvider */.G8, null, LayoutComponent));
2527
+ }
2528
+
2529
+ /**
2530
+ * Creates a combined context provider using the context modules from the extension manager.
2531
+ * @param {object} extensionManager - The extension manager instance.
2532
+ * @param {object} servicesManager - The services manager instance.
2533
+ * @param {object} commandsManager - The commands manager instance.
2534
+ * @returns {React.Component} - A React component that provides combined contexts to its children.
2535
+ */
2536
+ function createCombinedContextProvider(extensionManager, servicesManager, commandsManager) {
2537
+ const extensionsContextModules = extensionManager.getModulesByType(extensionManager.constructor.MODULE_TYPES.CONTEXT);
2538
+ if (!extensionsContextModules?.length) {
2539
+ return;
2540
+ }
2541
+ const contextModuleProviders = extensionsContextModules.flatMap(({
2542
+ module
2543
+ }) => {
2544
+ return module.map(aContextModule => {
2545
+ return aContextModule.provider;
2546
+ });
2547
+ });
2548
+ return ({
2549
+ children
2550
+ }) => {
2551
+ return Compose({
2552
+ components: contextModuleProviders,
2553
+ children
2554
+ });
2555
+ };
2510
2556
  }
2511
2557
  ModeRoute.propTypes = {
2512
2558
  mode: (prop_types_default()).object.isRequired,
@@ -2781,7 +2827,8 @@ async function appInit(appConfigOrFunc, defaultExtensions, defaultModes) {
2781
2827
  hotkeysManager,
2782
2828
  appConfig
2783
2829
  });
2784
- servicesManager.registerServices([core_src/* UINotificationService */.v4.REGISTRATION, core_src/* UIModalService */.zo.REGISTRATION, core_src/* UIDialogService */.u$.REGISTRATION, core_src/* UIViewportDialogService */.A$.REGISTRATION, core_src.MeasurementService.REGISTRATION, core_src/* DisplaySetService */.IO.REGISTRATION, [core_src/* CustomizationService */.V0.REGISTRATION, appConfig.customizationService], core_src/* ToolbarService */.hx.REGISTRATION, core_src/* ViewportGridService */.sI.REGISTRATION, core_src/* HangingProtocolService */.Qe.REGISTRATION, core_src/* CineService */.xx.REGISTRATION, core_src/* UserAuthenticationService */.pS.REGISTRATION, core_src/* PanelService */.Mr.REGISTRATION, core_src/* StateSyncService */.wb.REGISTRATION]);
2830
+ servicesManager.setExtensionManager(extensionManager);
2831
+ servicesManager.registerServices([core_src/* UINotificationService */.v4.REGISTRATION, core_src/* UIModalService */.zo.REGISTRATION, core_src/* UIDialogService */.u$.REGISTRATION, core_src/* UIViewportDialogService */.A$.REGISTRATION, core_src.MeasurementService.REGISTRATION, core_src/* DisplaySetService */.IO.REGISTRATION, [core_src/* CustomizationService */.V0.REGISTRATION, appConfig.customizationService], core_src.ToolbarService.REGISTRATION, core_src/* ViewportGridService */.sI.REGISTRATION, core_src/* HangingProtocolService */.Qe.REGISTRATION, core_src/* CineService */.xx.REGISTRATION, core_src/* UserAuthenticationService */.pS.REGISTRATION, core_src/* PanelService */.Mr.REGISTRATION, core_src/* StateSyncService */.wb.REGISTRATION]);
2785
2832
  core_src/* errorHandler */.r_.getHTTPErrorHandler = () => {
2786
2833
  if (typeof appConfig.httpErrorHandler === 'function') {
2787
2834
  return appConfig.httpErrorHandler;
@@ -3175,7 +3222,7 @@ function App({
3175
3222
  service: userAuthenticationService
3176
3223
  }], [es/* I18nextProvider */.xC, {
3177
3224
  i18n: src/* default */.A
3178
- }], [ui_src/* ThemeWrapper */.L$], [ui_src/* ViewportGridProvider */.ql, {
3225
+ }], [ui_src/* ThemeWrapper */.L$], [ui_src/* ToolboxProvider */.nB], [ui_src/* ViewportGridProvider */.ql, {
3179
3226
  service: viewportGridService
3180
3227
  }], [ui_src/* ViewportDialogProvider */.cm, {
3181
3228
  service: uiViewportDialogService
@@ -6486,7 +6533,7 @@ const detectionOptions = {
6486
6533
  }
6487
6534
  });
6488
6535
  ;// CONCATENATED MODULE: ../../i18n/package.json
6489
- const package_namespaceObject = /*#__PURE__*/JSON.parse('{"rE":"3.8.0-beta.62"}');
6536
+ const package_namespaceObject = /*#__PURE__*/JSON.parse('{"rE":"3.8.0-beta.64"}');
6490
6537
  ;// CONCATENATED MODULE: ../../i18n/src/utils.js
6491
6538
  const languagesMap = {
6492
6539
  ar: 'Arabic',
@@ -8969,21 +9016,46 @@ toolCapture.defaultProps = {
8969
9016
  var toolLayout = function toolLayout(props) {
8970
9017
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
8971
9018
  fill: "none",
8972
- fillRule: "evenodd",
8973
- stroke: "currentColor",
9019
+ fillRule: "evenodd"
9020
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9021
+ d: "M0 0h28v28H0z"
9022
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
9023
+ stroke: "currentColor"
9024
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9025
+ d: "M.5 9.995v7.9a2 2 0 0 0 2 2h8.862M19.695 6.357V2.5a2 2 0 0 0-2-2h-7.7 0",
9026
+ strokeWidth: "1.25",
9027
+ strokeLinecap: "round"
9028
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9029
+ d: "M10.4.5H2.5a2 2 0 0 0-2 2v7.7h0",
9030
+ strokeWidth: "1.25",
9031
+ strokeLinecap: "round"
9032
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
9033
+ opacity: ".55",
8974
9034
  strokeLinecap: "round",
8975
- strokeLinejoin: "round",
8976
9035
  strokeWidth: "1.5"
8977
9036
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
8978
- fill: "currentColor",
8979
- d: "M9.313 8.52a.793.793 0 0 1-.792.793H2.188a.792.792 0 0 1-.792-.792V2.188c0-.438.354-.792.791-.792h6.334c.437 0 .792.354.792.791v6.334z"
9037
+ d: "M10 17V3M3 10h13"
9038
+ })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
9039
+ transform: "rotate(-20 43.208 -34.372)",
9040
+ strokeLinecap: "round",
9041
+ strokeLinejoin: "round",
9042
+ strokeWidth: "1.25"
9043
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("circle", {
9044
+ cx: "5.124",
9045
+ cy: "5.767",
9046
+ r: "1.282"
8980
9047
  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
8981
- d: "M19.604 8.52a.792.792 0 0 1-.791.793h-6.334a.792.792 0 0 1-.791-.792V2.188c0-.438.354-.792.791-.792h6.334a.79.79 0 0 1 .791.791v6.334zM9.313 18.813a.792.792 0 0 1-.792.791H2.188a.791.791 0 0 1-.792-.791v-6.334a.79.79 0 0 1 .791-.791h6.334c.437 0 .792.354.792.791v6.334zm10.291 0a.79.79 0 0 1-.791.791h-6.334a.79.79 0 0 1-.791-.791v-6.334a.79.79 0 0 1 .791-.791h6.334a.79.79 0 0 1 .791.791v6.334z"
8982
- })));
9048
+ d: "m6.214.808.377 1.241a.85.85 0 0 0 1.003.582l1.259-.292a1.144 1.144 0 0 1 1.089 1.896l-.88.95a.856.856 0 0 0 0 1.16l.88.949a1.144 1.144 0 0 1-1.09 1.896l-1.258-.292a.849.849 0 0 0-1.007.586l-.377 1.241a1.138 1.138 0 0 1-2.179 0l-.374-1.241A.848.848 0 0 0 2.654 8.9l-1.258.292a1.144 1.144 0 0 1-1.09-1.896l.881-.95a.856.856 0 0 0 0-1.16l-.88-.95a1.144 1.144 0 0 1 1.089-1.895l1.258.291a.848.848 0 0 0 1.003-.581L4.035.81A1.138 1.138 0 0 1 6.214.808Z"
9049
+ })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9050
+ strokeLinejoin: "round",
9051
+ d: "m21 27.25-2.5-2.632.35-.368L21 26.513l2.15-2.263.35.368z"
9052
+ }))));
8983
9053
  };
8984
9054
  toolLayout.defaultProps = {
8985
- xmlns: "http://www.w3.org/2000/svg",
8986
- viewBox: "0 0 21 21"
9055
+ width: "28",
9056
+ height: "28",
9057
+ viewBox: "0 0 28 28",
9058
+ xmlns: "http://www.w3.org/2000/svg"
8987
9059
  };
8988
9060
  var toolMore = function toolMore(props) {
8989
9061
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
@@ -9968,19 +10040,19 @@ var iconToolBrush = function iconToolBrush(props) {
9968
10040
  fill: "none",
9969
10041
  fillRule: "evenodd"
9970
10042
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9971
- d: "M3.246 22.329a.432.432 0 0 1 .024-.79c2.056-.833 1.394-3.177 2.004-4.43a3.075 3.075 0 0 1 4.083-1.405c4.592 2.238-.874 9.117-6.11 6.625ZM21.597 3.302a1.194 1.194 0 0 0-1.635.045L9.692 13.589a5.196 5.196 0 0 1 3.129 2.646l8.92-11.298a1.194 1.194 0 0 0-.144-1.635Z",
10043
+ d: "M0 0h24v24H0z"
10044
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10045
+ d: "M3.246 21.829a.432.432 0 0 1 .024-.79c2.056-.833 1.394-3.177 2.004-4.43a3.075 3.075 0 0 1 4.083-1.405c4.592 2.238-.874 9.117-6.11 6.625ZM21.597 2.302a1.194 1.194 0 0 0-1.635.045L9.692 12.589a5.196 5.196 0 0 1 3.129 2.646l8.92-11.298a1.194 1.194 0 0 0-.144-1.635Z",
9972
10046
  stroke: "currentColor",
9973
- strokeWidth: "1.25",
10047
+ strokeWidth: "1.5",
9974
10048
  strokeLinecap: "round",
9975
10049
  strokeLinejoin: "round"
9976
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9977
- d: "M0 0h25v25H0z"
9978
10050
  })));
9979
10051
  };
9980
10052
  iconToolBrush.defaultProps = {
9981
- width: "25",
9982
- height: "25",
9983
- viewBox: "0 0 25 25",
10053
+ width: "24",
10054
+ height: "24",
10055
+ viewBox: "0 0 24 24",
9984
10056
  xmlns: "http://www.w3.org/2000/svg"
9985
10057
  };
9986
10058
  var iconToolEraser = function iconToolEraser(props) {
@@ -9988,19 +10060,19 @@ var iconToolEraser = function iconToolEraser(props) {
9988
10060
  fill: "none",
9989
10061
  fillRule: "evenodd"
9990
10062
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9991
- d: "M8.391 20.504a5.08 5.08 0 0 1-3.118-1.291l-1.982-1.984a1.832 1.832 0 0 1 0-2.583L14.404 3.533a1.832 1.832 0 0 1 2.583 0l4.721 4.721c.71.715.71 1.869 0 2.583l-8.373 8.374a5.08 5.08 0 0 1-3.118 1.293H8.391ZM10.217 7.719l7.305 7.305M2 22.328h21",
10063
+ d: "M0 0h24v24H0z"
10064
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10065
+ d: "M8.478 18.003a4.354 4.354 0 0 1-2.672-1.107l-1.7-1.7a1.57 1.57 0 0 1 0-2.214l9.526-9.525a1.57 1.57 0 0 1 2.214 0l4.047 4.047a1.57 1.57 0 0 1 0 2.214l-7.178 7.177a4.354 4.354 0 0 1-2.672 1.108H8.478ZM10.043 7.045l6.261 6.261M3 20.567h18",
9992
10066
  stroke: "currentColor",
9993
- strokeWidth: "1.25",
10067
+ strokeWidth: "1.5",
9994
10068
  strokeLinecap: "round",
9995
10069
  strokeLinejoin: "round"
9996
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
9997
- d: "M0 0h25v25H0z"
9998
10070
  })));
9999
10071
  };
10000
10072
  iconToolEraser.defaultProps = {
10001
- width: "25",
10002
- height: "25",
10003
- viewBox: "0 0 25 25",
10073
+ width: "24",
10074
+ height: "24",
10075
+ viewBox: "0 0 24 24",
10004
10076
  xmlns: "http://www.w3.org/2000/svg"
10005
10077
  };
10006
10078
  var iconToolScissor = function iconToolScissor(props) {
@@ -10040,7 +10112,13 @@ var iconToolShape = function iconToolShape(props) {
10040
10112
  fill: "none",
10041
10113
  fillRule: "evenodd"
10042
10114
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10043
- d: "M0 0h25v25H0z"
10115
+ d: "M0 0h24v24H0z"
10116
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("circle", {
10117
+ stroke: "currentColor",
10118
+ strokeWidth: "1.5",
10119
+ cx: "16",
10120
+ cy: "15",
10121
+ r: "6"
10044
10122
  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10045
10123
  stroke: "currentColor",
10046
10124
  strokeWidth: "1.5",
@@ -10048,19 +10126,13 @@ var iconToolShape = function iconToolShape(props) {
10048
10126
  y: "3",
10049
10127
  width: "13",
10050
10128
  height: "13",
10051
- rx: "1"
10052
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("circle", {
10053
- stroke: "currentColor",
10054
- strokeWidth: "1.5",
10055
- cx: "16.5",
10056
- cy: "16.5",
10057
- r: "6.5"
10129
+ rx: "2"
10058
10130
  })));
10059
10131
  };
10060
10132
  iconToolShape.defaultProps = {
10061
- width: "25",
10062
- height: "25",
10063
- viewBox: "0 0 25 25",
10133
+ width: "24",
10134
+ height: "24",
10135
+ viewBox: "0 0 24 24",
10064
10136
  xmlns: "http://www.w3.org/2000/svg"
10065
10137
  };
10066
10138
  var iconToolThreshold = function iconToolThreshold(props) {
@@ -10068,35 +10140,35 @@ var iconToolThreshold = function iconToolThreshold(props) {
10068
10140
  fill: "none",
10069
10141
  fillRule: "evenodd"
10070
10142
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10143
+ d: "M0 0h24v24H0z"
10144
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10145
+ transform: "translate(2.418 14.367)",
10071
10146
  stroke: "currentColor",
10072
- strokeWidth: "1.25",
10147
+ strokeWidth: "1.5"
10148
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10073
10149
  strokeLinecap: "round",
10074
- d: "M19.457 16.87H22.5M2.5 16.87h12.174"
10150
+ d: "M16.582 2.133h2.5M.082 2.133h12"
10075
10151
  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("circle", {
10152
+ cx: "14.224",
10153
+ cy: "2.092",
10154
+ r: "2.092"
10155
+ })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10156
+ transform: "matrix(-1 0 0 1 21.5 5.367)",
10076
10157
  stroke: "currentColor",
10077
- strokeWidth: "1.25",
10078
- cx: "16.848",
10079
- cy: "16.87",
10080
- r: "2.174"
10081
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10082
- stroke: "currentColor",
10083
- strokeWidth: "1.25",
10158
+ strokeWidth: "1.5"
10159
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10084
10160
  strokeLinecap: "round",
10085
- d: "M11.63 8.174h10.435M2.5 8.174h4.783"
10161
+ d: "M16 2.133h3.082M.082 2.133H11"
10086
10162
  }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("circle", {
10087
- stroke: "currentColor",
10088
- strokeWidth: "1.25",
10089
- cx: "9.457",
10090
- cy: "8.174",
10091
- r: "2.174"
10092
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10093
- d: "M0 0h25v25H0z"
10094
- })));
10163
+ cx: "13.224",
10164
+ cy: "2.092",
10165
+ r: "2.092"
10166
+ }))));
10095
10167
  };
10096
10168
  iconToolThreshold.defaultProps = {
10097
- width: "25",
10098
- height: "25",
10099
- viewBox: "0 0 25 25",
10169
+ width: "24",
10170
+ height: "24",
10171
+ viewBox: "0 0 24 24",
10100
10172
  xmlns: "http://www.w3.org/2000/svg"
10101
10173
  };
10102
10174
  /** Old OHIF */
@@ -10133,6 +10205,243 @@ oldStop.defaultProps = {
10133
10205
  'aria-labelledby': "title",
10134
10206
  fill: "currentColor"
10135
10207
  };
10208
+ /** LAYOUT */
10209
+ var layoutAdvanced3DFourUp = function layoutAdvanced3DFourUp(props) {
10210
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10211
+ transform: "translate(1 1)",
10212
+ stroke: "currentColor",
10213
+ fill: "none",
10214
+ fillRule: "evenodd"
10215
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10216
+ width: "27",
10217
+ height: "16.2",
10218
+ rx: "2"
10219
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10220
+ d: "M13.886 0H2a2 2 0 0 0-2 2v12.2a2 2 0 0 0 2 2h11.886V0Z"
10221
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10222
+ d: "M13.886 0H25a2 2 0 0 1 2 2v6.5H13.886V0Z",
10223
+ fill: "#263A71"
10224
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10225
+ d: "M13.886 8.486H0V14.2a2 2 0 0 0 2 2h11.886V8.486ZM13.886 8.486H27V14.2a2 2 0 0 1-2 2H13.886V8.486Z"
10226
+ })));
10227
+ };
10228
+ layoutAdvanced3DFourUp.defaultProps = {
10229
+ width: "29",
10230
+ height: "18",
10231
+ viewBox: "0 0 29 18",
10232
+ xmlns: "http://www.w3.org/2000/svg"
10233
+ };
10234
+ var layoutAdvanced3DMain = function layoutAdvanced3DMain(props) {
10235
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10236
+ transform: "translate(1 1)",
10237
+ stroke: "currentColor",
10238
+ fill: "none",
10239
+ fillRule: "evenodd"
10240
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10241
+ width: "27",
10242
+ height: "16.2",
10243
+ rx: "2"
10244
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10245
+ d: "M18 7.714h9V14.2a2 2 0 0 1-2 2h-7V7.714ZM0 7.714h9.257V16.2H2a2 2 0 0 1-2-2V7.714Z"
10246
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10247
+ d: "M25 0H2a2 2 0 0 0-2 2v6.486h27V2a2 2 0 0 0-2-2Z",
10248
+ fill: "#263A71"
10249
+ })));
10250
+ };
10251
+ layoutAdvanced3DMain.defaultProps = {
10252
+ width: "29",
10253
+ height: "18",
10254
+ viewBox: "0 0 29 18",
10255
+ xmlns: "http://www.w3.org/2000/svg"
10256
+ };
10257
+ var layoutAdvanced3DOnly = function layoutAdvanced3DOnly(props) {
10258
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10259
+ width: "27",
10260
+ height: "16.2",
10261
+ rx: "2",
10262
+ transform: "translate(1 1)",
10263
+ fill: "#263A71",
10264
+ stroke: "currentColor",
10265
+ fillRule: "evenodd"
10266
+ }));
10267
+ };
10268
+ layoutAdvanced3DOnly.defaultProps = {
10269
+ width: "29",
10270
+ height: "18",
10271
+ viewBox: "0 0 29 18",
10272
+ xmlns: "http://www.w3.org/2000/svg"
10273
+ };
10274
+ var layoutAdvanced3DPrimary = function layoutAdvanced3DPrimary(props) {
10275
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10276
+ transform: "translate(1 1)",
10277
+ stroke: "currentColor",
10278
+ fill: "none",
10279
+ fillRule: "evenodd"
10280
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10281
+ width: "27",
10282
+ height: "16.2",
10283
+ rx: "2"
10284
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10285
+ d: "M15.429 10.5H27V14a2 2 0 0 1-2 2h-9.571v-5.5ZM15.429 0H25a2 2 0 0 1 2 2v3.4H15.429V0Z"
10286
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10287
+ d: "M16.2 0H2a2 2 0 0 0-2 2v12.2a2 2 0 0 0 2 2h14.2V0Z",
10288
+ fill: "#263A71"
10289
+ })));
10290
+ };
10291
+ layoutAdvanced3DPrimary.defaultProps = {
10292
+ width: "29",
10293
+ height: "18",
10294
+ viewBox: "0 0 29 18",
10295
+ xmlns: "http://www.w3.org/2000/svg"
10296
+ };
10297
+ var layoutAdvancedAxialPrimary = function layoutAdvancedAxialPrimary(props) {
10298
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10299
+ stroke: "currentColor",
10300
+ fill: "none",
10301
+ fillRule: "evenodd"
10302
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10303
+ d: "M16.429 1H26a2 2 0 0 1 2 2v12.2a2 2 0 0 1-2 2h-9.571V1Z"
10304
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10305
+ d: "M16.429 1H26a2 2 0 0 1 2 2v6.486H16.429V1Z"
10306
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10307
+ d: "M16.7 1H3a2 2 0 0 0-2 2v12.2a2 2 0 0 0 2 2h13.7V1Z"
10308
+ })));
10309
+ };
10310
+ layoutAdvancedAxialPrimary.defaultProps = {
10311
+ width: "29",
10312
+ height: "18",
10313
+ viewBox: "0 0 29 18",
10314
+ xmlns: "http://www.w3.org/2000/svg"
10315
+ };
10316
+ var layoutAdvancedMPR = function layoutAdvancedMPR(props) {
10317
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10318
+ stroke: "currentColor",
10319
+ fill: "none",
10320
+ fillRule: "evenodd"
10321
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10322
+ d: "M18.743 1H26a2 2 0 0 1 2 2v12.2a2 2 0 0 1-2 2h-7.257V1Z"
10323
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10324
+ d: "M10 1h9v16.2h-9z"
10325
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10326
+ d: "M10.257 1H3a2 2 0 0 0-2 2v12.2a2 2 0 0 0 2 2h7.257V1Z"
10327
+ })));
10328
+ };
10329
+ layoutAdvancedMPR.defaultProps = {
10330
+ width: "29",
10331
+ height: "18",
10332
+ viewBox: "0 0 29 18",
10333
+ xmlns: "http://www.w3.org/2000/svg"
10334
+ };
10335
+ var layoutCommon1x1 = function layoutCommon1x1(props) {
10336
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10337
+ width: "26",
10338
+ height: "15.6",
10339
+ rx: "2",
10340
+ transform: "translate(1 1)",
10341
+ stroke: "currentColor",
10342
+ fill: "none",
10343
+ fillRule: "evenodd"
10344
+ }));
10345
+ };
10346
+ layoutCommon1x1.defaultProps = {
10347
+ width: "28",
10348
+ height: "18",
10349
+ viewBox: "0 0 28 18",
10350
+ xmlns: "http://www.w3.org/2000/svg"
10351
+ };
10352
+ var layoutCommon1x2 = function layoutCommon1x2(props) {
10353
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10354
+ transform: "translate(1 1)",
10355
+ stroke: "currentColor",
10356
+ fill: "none",
10357
+ fillRule: "evenodd"
10358
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10359
+ width: "26",
10360
+ height: "15.6",
10361
+ rx: "2"
10362
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10363
+ d: "M13 0H2a2 2 0 0 0-2 2v11.6a2 2 0 0 0 2 2h11V0Z"
10364
+ })));
10365
+ };
10366
+ layoutCommon1x2.defaultProps = {
10367
+ width: "28",
10368
+ height: "18",
10369
+ viewBox: "0 0 28 18",
10370
+ xmlns: "http://www.w3.org/2000/svg"
10371
+ };
10372
+ var layoutCommon2x2 = function layoutCommon2x2(props) {
10373
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10374
+ transform: "translate(1 1)",
10375
+ stroke: "currentColor",
10376
+ fill: "none",
10377
+ fillRule: "evenodd"
10378
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10379
+ width: "26",
10380
+ height: "15.6",
10381
+ rx: "2"
10382
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10383
+ d: "M13 0H2a2 2 0 0 0-2 2v11.6a2 2 0 0 0 2 2h11V0Z"
10384
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10385
+ d: "M24 0H2a2 2 0 0 0-2 2v6h26V2a2 2 0 0 0-2-2Z"
10386
+ })));
10387
+ };
10388
+ layoutCommon2x2.defaultProps = {
10389
+ width: "28",
10390
+ height: "18",
10391
+ viewBox: "0 0 28 18",
10392
+ xmlns: "http://www.w3.org/2000/svg"
10393
+ };
10394
+ var layoutCommon2x3 = function layoutCommon2x3(props) {
10395
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10396
+ transform: "translate(1 1)",
10397
+ stroke: "currentColor",
10398
+ fill: "none",
10399
+ fillRule: "evenodd"
10400
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("rect", {
10401
+ width: "26",
10402
+ height: "15.6",
10403
+ rx: "2"
10404
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10405
+ d: "M9 0H2a2 2 0 0 0-2 2v11.6a2 2 0 0 0 2 2h7V0Z"
10406
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10407
+ d: "M17 0H2a2 2 0 0 0-2 2v11.6a2 2 0 0 0 2 2h15V0Z"
10408
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10409
+ d: "M24 0H2a2 2 0 0 0-2 2v6h26V2a2 2 0 0 0-2-2Z"
10410
+ })));
10411
+ };
10412
+ layoutCommon2x3.defaultProps = {
10413
+ width: "28",
10414
+ height: "18",
10415
+ viewBox: "0 0 28 18",
10416
+ xmlns: "http://www.w3.org/2000/svg"
10417
+ };
10418
+ var iconToolRotate = function iconToolRotate(props) {
10419
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10420
+ fill: "none",
10421
+ fillRule: "evenodd"
10422
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10423
+ d: "M0 0h28v28H0z"
10424
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
10425
+ stroke: "currentColor",
10426
+ strokeLinecap: "round",
10427
+ strokeLinejoin: "round",
10428
+ strokeWidth: "1.5"
10429
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10430
+ d: "m10 24.996 2.5-1.998-2.5-2.002"
10431
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10432
+ d: "M12.5 22.998c-3.462.654-7.5-1.5-8.5-5M18 3l-2.5 1.998L18 7"
10433
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10434
+ d: "M15.5 4.998c3.462-.654 7.5 1.5 8.5 5M14 8.75l-5 2.188 5 2.187 5-2.188z"
10435
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("path", {
10436
+ d: "M9 10.938v5.937l5 2.188 5-2.188v-5.938M14 13.125v5.938"
10437
+ }))));
10438
+ };
10439
+ iconToolRotate.defaultProps = {
10440
+ width: "28",
10441
+ height: "28",
10442
+ viewBox: "0 0 28 28",
10443
+ xmlns: "http://www.w3.org/2000/svg"
10444
+ };
10136
10445
  /** New investigational use */
10137
10446
  var investigationalUse = function investigationalUse(props) {
10138
10447
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("svg", props, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement("g", {
@@ -10253,7 +10562,7 @@ const ICONS = {
10253
10562
  'tool-window-level': toolWindow,
10254
10563
  'tool-annotate': toolAnnotate,
10255
10564
  'tool-bidirectional': toolBidirectional,
10256
- 'tool-elipse': toolElipse,
10565
+ 'tool-ellipse': toolElipse,
10257
10566
  'tool-circle': toolCircle,
10258
10567
  'tool-length': toolLength,
10259
10568
  'tool-stack-scroll': toolStackScroll,
@@ -10274,6 +10583,7 @@ const ICONS = {
10274
10583
  'tool-freehand-line': toolFreehand,
10275
10584
  'tool-freehand-polygon': toolFreehandPolygon,
10276
10585
  'tool-polygon': toolPolygon,
10586
+ 'tool-3d-rotate': iconToolRotate,
10277
10587
  'edit-patient': editPatient,
10278
10588
  'icon-mpr': iconMPR,
10279
10589
  'icon-next-inactive': iconNextInactive,
@@ -10311,6 +10621,17 @@ const ICONS = {
10311
10621
  'old-trash': oldTrash,
10312
10622
  'old-play': oldPlay,
10313
10623
  'old-stop': oldStop,
10624
+ /** LAYOUT */
10625
+ 'layout-advanced-3d-four-up': layoutAdvanced3DFourUp,
10626
+ 'layout-advanced-3d-main': layoutAdvanced3DMain,
10627
+ 'layout-advanced-3d-only': layoutAdvanced3DOnly,
10628
+ 'layout-advanced-3d-primary': layoutAdvanced3DPrimary,
10629
+ 'layout-advanced-axial-primary': layoutAdvancedAxialPrimary,
10630
+ 'layout-advanced-mpr': layoutAdvancedMPR,
10631
+ 'layout-common-1x1': layoutCommon1x1,
10632
+ 'layout-common-1x2': layoutCommon1x2,
10633
+ 'layout-common-2x2': layoutCommon2x2,
10634
+ 'layout-common-2x3': layoutCommon2x3,
10314
10635
  /** New investigational use */
10315
10636
  'illustration-investigational-use': investigationalUse
10316
10637
  };
@@ -10336,43 +10657,16 @@ function getIcon(key, props) {
10336
10657
 
10337
10658
  /***/ }),
10338
10659
 
10339
- /***/ 53589:
10660
+ /***/ 1675:
10340
10661
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10341
10662
 
10342
10663
  "use strict";
10664
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10665
+ /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
10666
+ /* harmony export */ });
10667
+ /* harmony import */ var _Icon__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(66348);
10343
10668
 
10344
- // EXPORTS
10345
- __webpack_require__.d(__webpack_exports__, {
10346
- A: () => (/* binding */ components_Icon)
10347
- });
10348
-
10349
- // EXTERNAL MODULE: ../../../node_modules/react/index.js
10350
- var react = __webpack_require__(41766);
10351
- // EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
10352
- var prop_types = __webpack_require__(11374);
10353
- var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
10354
- // EXTERNAL MODULE: ../../ui/src/components/Icon/getIcon.js
10355
- var getIcon = __webpack_require__(32854);
10356
- ;// CONCATENATED MODULE: ../../ui/src/components/Icon/Icon.tsx
10357
-
10358
-
10359
-
10360
- const Icon = ({
10361
- name,
10362
- ...otherProps
10363
- }) => {
10364
- return /*#__PURE__*/react.createElement(react.Fragment, null, (0,getIcon/* default */.Ay)(name, {
10365
- ...otherProps
10366
- }));
10367
- };
10368
- Icon.propTypes = {
10369
- name: (prop_types_default()).string.isRequired,
10370
- className: (prop_types_default()).string
10371
- };
10372
- /* harmony default export */ const Icon_Icon = (Icon);
10373
- ;// CONCATENATED MODULE: ../../ui/src/components/Icon/index.js
10374
-
10375
- /* harmony default export */ const components_Icon = (Icon_Icon);
10669
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_Icon__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A);
10376
10670
 
10377
10671
  /***/ }),
10378
10672
 
@@ -10505,7 +10799,7 @@ Typography.propTypes = {
10505
10799
 
10506
10800
  /***/ }),
10507
10801
 
10508
- /***/ 6804:
10802
+ /***/ 58046:
10509
10803
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10510
10804
 
10511
10805
  "use strict";
@@ -10513,9 +10807,9 @@ Typography.propTypes = {
10513
10807
  // EXPORTS
10514
10808
  __webpack_require__.d(__webpack_exports__, {
10515
10809
  VT: () => (/* reexport */ components_AboutModal),
10516
- om: () => (/* reexport */ components_AdvancedToolbox),
10517
10810
  $n: () => (/* reexport */ components_Button),
10518
10811
  Ny: () => (/* reexport */ ButtonEnums_namespaceObject),
10812
+ e2: () => (/* reexport */ components_ButtonGroup),
10519
10813
  F0: () => (/* reexport */ components_CinePlayer),
10520
10814
  p: () => (/* reexport */ CineProvider),
10521
10815
  lG: () => (/* reexport */ components_Dialog),
@@ -10528,11 +10822,11 @@ __webpack_require__.d(__webpack_exports__, {
10528
10822
  uq: () => (/* reexport */ components_ImageScrollbar),
10529
10823
  xy: () => (/* reexport */ ImageViewerProvider),
10530
10824
  pd: () => (/* reexport */ components_Input),
10531
- Z5: () => (/* reexport */ components_InputDoubleRange),
10532
10825
  Cv: () => (/* reexport */ components_InputFilterText),
10533
10826
  Qr: () => (/* reexport */ components_InputRange),
10534
10827
  j: () => (/* reexport */ components_InvestigationalUseDialog),
10535
10828
  JU: () => (/* reexport */ components_Label),
10829
+ qu: () => (/* reexport */ components_LayoutPreset),
10536
10830
  sG: () => (/* reexport */ components_LayoutSelector),
10537
10831
  _H: () => (/* reexport */ components_LegacyButton),
10538
10832
  xA: () => (/* reexport */ components_LegacyButtonGroup),
@@ -10557,6 +10851,8 @@ __webpack_require__.d(__webpack_exports__, {
10557
10851
  u3: () => (/* reexport */ components_StudySummary),
10558
10852
  L$: () => (/* reexport */ components_ThemeWrapper),
10559
10853
  IB: () => (/* reexport */ components_ToolbarButton),
10854
+ OO: () => (/* reexport */ Toolbox_Toolbox),
10855
+ nB: () => (/* reexport */ ToolboxProvider),
10560
10856
  m_: () => (/* reexport */ components_Tooltip),
10561
10857
  ax: () => (/* reexport */ TooltipClipboard_TooltipClipboard),
10562
10858
  o5: () => (/* reexport */ Typography/* default */.A),
@@ -10579,7 +10875,7 @@ __webpack_require__.d(__webpack_exports__, {
10579
10875
  ih: () => (/* reexport */ useViewportGrid)
10580
10876
  });
10581
10877
 
10582
- // UNUSED EXPORTS: BackgroundColor, ButtonGroup, CheckBox, ContextMenu, DateRange, Dropdown, ExpandableToolbarButton, HotkeyField, HotkeysPreferences, ICONS, IconButton, ImageViewerContext, InputDateRange, InputGroup, InputLabelWrapper, InputMultiSelect, InputNumber, InputText, LegacyCinePlayer, LegacySidePanel, LegacyViewportActionBar, ListMenu, MeasurementItem, ModalComponent, ModalConsumer, NavBar, PanelSection, StudyItem, StudyListTableRow, Svg, Table, TableBody, TableCell, TableHead, TableRow, Thumbnail, ThumbnailList, ThumbnailNoImage, ThumbnailTracked, Types, UserAuthenticationContext, Viewport, ViewportGridContext, addIcon, getIcon, useDialog, useSnackbar, withDialog, withModal, withSnackbar
10878
+ // UNUSED EXPORTS: AdvancedToolbox, BackgroundColor, CheckBox, ContextMenu, DateRange, Dropdown, ExpandableToolbarButton, HotkeyField, HotkeysPreferences, ICONS, IconButton, ImageViewerContext, InputDateRange, InputDoubleRange, InputGroup, InputLabelWrapper, InputMultiSelect, InputNumber, InputText, LegacyCinePlayer, LegacySidePanel, LegacySplitButton, LegacyViewportActionBar, ListMenu, MeasurementItem, ModalComponent, ModalConsumer, NavBar, PanelSection, StudyItem, StudyListTableRow, Svg, Table, TableBody, TableCell, TableHead, TableRow, Thumbnail, ThumbnailList, ThumbnailNoImage, ThumbnailTracked, ToolSettings, Types, UserAuthenticationContext, Viewport, ViewportGridContext, addIcon, getIcon, useDialog, useSnackbar, useToolbox, withDialog, withModal, withSnackbar
10583
10879
 
10584
10880
  // NAMESPACE OBJECT: ../../../node_modules/react-dnd-html5-backend/dist/esm/NativeTypes.js
10585
10881
  var NativeTypes_namespaceObject = {};
@@ -17540,17 +17836,10 @@ ModalProvider.propTypes = {
17540
17836
  const ModalConsumer = ModalContext.Consumer;
17541
17837
  ;// CONCATENATED MODULE: ../../ui/src/contextProviders/ImageViewerProvider.tsx
17542
17838
 
17543
-
17544
- // export const IMAGE_VIEWER_DEFAULT_VALUE = {
17545
- // StudyInstanceUIDs: [],
17546
- // setImageViewer: () => {},
17547
- // };
17548
-
17549
- const ImageViewerContext = /*#__PURE__*/(0,react.createContext)();
17839
+ const ImageViewerContext = /*#__PURE__*/(0,react.createContext)(null);
17840
+ const useImageViewer = () => (0,react.useContext)(ImageViewerContext);
17550
17841
  function ImageViewerProvider({
17551
17842
  StudyInstanceUIDs,
17552
- reducer,
17553
- initialState,
17554
17843
  children
17555
17844
  }) {
17556
17845
  const value = (0,react.useMemo)(() => {
@@ -17562,7 +17851,6 @@ function ImageViewerProvider({
17562
17851
  value: value
17563
17852
  }, children);
17564
17853
  }
17565
- const useImageViewer = () => (0,react.useContext)(ImageViewerContext);
17566
17854
  ;// CONCATENATED MODULE: ../../ui/src/contextProviders/CineProvider.tsx
17567
17855
 
17568
17856
 
@@ -17657,7 +17945,7 @@ function CineProvider({
17657
17945
  const api = {
17658
17946
  getState,
17659
17947
  setCine,
17660
- setIsCineEnabled,
17948
+ setIsCineEnabled: isCineEnabled => service.setIsCineEnabled(isCineEnabled),
17661
17949
  playClip: (element, playClipOptions) => service.playClip(element, playClipOptions),
17662
17950
  stopClip: element => service.stopClip(element)
17663
17951
  };
@@ -17679,8 +17967,8 @@ const useCine = () => (0,react.useContext)(CineContext);
17679
17967
  SUCCESS: 'success',
17680
17968
  ERROR: 'error'
17681
17969
  });
17682
- // EXTERNAL MODULE: ../../ui/src/components/Icon/index.js + 1 modules
17683
- var Icon = __webpack_require__(53589);
17970
+ // EXTERNAL MODULE: ../../ui/src/components/Icon/index.js
17971
+ var Icon = __webpack_require__(1675);
17684
17972
  ;// CONCATENATED MODULE: ../../ui/src/components/Snackbar/SnackbarItem.tsx
17685
17973
 
17686
17974
 
@@ -17955,8 +18243,8 @@ ViewportDialogProvider.propTypes = {
17955
18243
  // EXTERNAL MODULE: ../../../node_modules/lodash.merge/index.js
17956
18244
  var lodash_merge = __webpack_require__(40592);
17957
18245
  var lodash_merge_default = /*#__PURE__*/__webpack_require__.n(lodash_merge);
17958
- // EXTERNAL MODULE: ../../core/src/index.ts + 66 modules
17959
- var src = __webpack_require__(14283);
18246
+ // EXTERNAL MODULE: ../../core/src/index.ts + 67 modules
18247
+ var src = __webpack_require__(78198);
17960
18248
  ;// CONCATENATED MODULE: ../../ui/src/utils/viewportLabels.ts
17961
18249
  const viewportLabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
17962
18250
  /* harmony default export */ const utils_viewportLabels = (viewportLabels);
@@ -17980,6 +18268,7 @@ const ViewportGridProvider_DEFAULT_STATE = {
17980
18268
  default: {
17981
18269
  viewportId: 'default',
17982
18270
  displaySetInstanceUIDs: [],
18271
+ isReady: false,
17983
18272
  viewportOptions: {
17984
18273
  viewportId: 'default'
17985
18274
  },
@@ -18177,6 +18466,7 @@ function ViewportGridProvider({
18177
18466
  y: yPos
18178
18467
  });
18179
18468
  viewport.viewportLabel = getViewportLabel(viewports, viewport.viewportId);
18469
+ viewport.isReady = false;
18180
18470
  if (!viewport.viewportOptions.presentationIds) {
18181
18471
  viewport.viewportOptions.presentationIds = src/* ViewportGridService */.sI.getPresentationIds(viewport, viewports);
18182
18472
  }
@@ -18207,6 +18497,26 @@ function ViewportGridProvider({
18207
18497
  ...action.payload
18208
18498
  };
18209
18499
  }
18500
+ case 'VIEWPORT_IS_READY':
18501
+ {
18502
+ const {
18503
+ viewportId,
18504
+ isReady
18505
+ } = action.payload;
18506
+ const viewports = new Map(state.viewports);
18507
+ const viewport = viewports.get(viewportId);
18508
+ if (!viewport) {
18509
+ return;
18510
+ }
18511
+ viewports.set(viewportId, {
18512
+ ...viewport,
18513
+ isReady
18514
+ });
18515
+ return {
18516
+ ...state,
18517
+ viewports
18518
+ };
18519
+ }
18210
18520
  default:
18211
18521
  return action.payload;
18212
18522
  }
@@ -18230,6 +18540,22 @@ function ViewportGridProvider({
18230
18540
  type: 'SET_DISPLAYSETS_FOR_VIEWPORTS',
18231
18541
  payload: viewports
18232
18542
  }), [dispatch]);
18543
+ const setViewportIsReady = (0,react.useCallback)((viewportId, isReady) => {
18544
+ dispatch({
18545
+ type: 'VIEWPORT_IS_READY',
18546
+ payload: {
18547
+ viewportId,
18548
+ isReady
18549
+ }
18550
+ });
18551
+ }, [dispatch, viewportGridState]);
18552
+ const getGridViewportsReady = (0,react.useCallback)(() => {
18553
+ const {
18554
+ viewports
18555
+ } = viewportGridState;
18556
+ const readyViewports = Array.from(viewports.values()).filter(viewport => viewport.isReady);
18557
+ return readyViewports.length === viewports.size;
18558
+ }, [viewportGridState]);
18233
18559
  const setLayout = (0,react.useCallback)(({
18234
18560
  layoutType,
18235
18561
  numRows,
@@ -18283,10 +18609,12 @@ function ViewportGridProvider({
18283
18609
  reset,
18284
18610
  onModeExit: reset,
18285
18611
  set,
18286
- getNumViewportPanes
18612
+ getNumViewportPanes,
18613
+ setViewportIsReady,
18614
+ getGridViewportsReady
18287
18615
  });
18288
18616
  }
18289
- }, [getState, service, setActiveViewportId, setDisplaySetsForViewports, setLayout, reset, set, getNumViewportPanes]);
18617
+ }, [getState, service, setActiveViewportId, setDisplaySetsForViewports, setLayout, reset, set, getNumViewportPanes, setViewportIsReady, getGridViewportsReady]);
18290
18618
 
18291
18619
  // run many of the calls through the service itself since we want to publish events
18292
18620
  const api = {
@@ -18299,8 +18627,11 @@ function ViewportGridProvider({
18299
18627
  set: gridLayoutState => service.setState(gridLayoutState),
18300
18628
  // run it through the service itself since we want to publish events
18301
18629
  getNumViewportPanes,
18630
+ setViewportIsReady,
18631
+ getGridViewportsReady,
18302
18632
  getActiveViewportOptionByKey,
18303
- setViewportGridSizeChanged: props => service.setViewportGridSizeChanged(props)
18633
+ setViewportGridSizeChanged: props => service.setViewportGridSizeChanged(props),
18634
+ publishViewportsReady: () => service.publishViewportsReady()
18304
18635
  };
18305
18636
  return /*#__PURE__*/react.createElement(ViewportGridContext.Provider, {
18306
18637
  value: [viewportGridState, api]
@@ -18311,6 +18642,133 @@ ViewportGridProvider.propTypes = {
18311
18642
  service: prop_types_default().instanceOf(src/* ViewportGridService */.sI).isRequired
18312
18643
  };
18313
18644
  const useViewportGrid = () => (0,react.useContext)(ViewportGridContext);
18645
+ ;// CONCATENATED MODULE: ../../ui/src/contextProviders/Toolbox/ToolboxContext.tsx
18646
+
18647
+ const ToolboxContext_initialState = {};
18648
+ const toolboxReducer = (state, action) => {
18649
+ const {
18650
+ toolbarSectionId
18651
+ } = action.payload;
18652
+ if (!state[toolbarSectionId]) {
18653
+ state[toolbarSectionId] = {
18654
+ activeTool: null,
18655
+ toolOptions: {}
18656
+ };
18657
+ }
18658
+ switch (action.type) {
18659
+ case 'SET_ACTIVE_TOOL':
18660
+ return {
18661
+ ...state,
18662
+ [toolbarSectionId]: {
18663
+ ...state[toolbarSectionId],
18664
+ activeTool: action.payload.activeTool
18665
+ }
18666
+ };
18667
+ case 'UPDATE_TOOL_OPTION':
18668
+ const {
18669
+ toolName,
18670
+ optionName,
18671
+ value
18672
+ } = action.payload;
18673
+ return {
18674
+ ...state,
18675
+ [toolbarSectionId]: {
18676
+ ...state[toolbarSectionId],
18677
+ toolOptions: {
18678
+ ...state[toolbarSectionId].toolOptions,
18679
+ [toolName]: state[toolbarSectionId].toolOptions[toolName].map(option => option.id === optionName ? {
18680
+ ...option,
18681
+ value
18682
+ } : option)
18683
+ }
18684
+ }
18685
+ };
18686
+ case 'INITIALIZE_TOOL_OPTIONS':
18687
+ // Initialize tool options for each toolbarSectionId
18688
+ return {
18689
+ ...state,
18690
+ [action.toolbarSectionId]: {
18691
+ ...state[action.toolbarSectionId],
18692
+ toolOptions: action.payload
18693
+ }
18694
+ };
18695
+ default:
18696
+ return state;
18697
+ }
18698
+ };
18699
+ const ToolboxContext = /*#__PURE__*/(0,react.createContext)();
18700
+ const ToolboxProvider = ({
18701
+ children
18702
+ }) => {
18703
+ const [state, dispatch] = (0,react.useReducer)(toolboxReducer, ToolboxContext_initialState);
18704
+ const handleToolSelect = (toolbarSectionId, toolName) => {
18705
+ dispatch({
18706
+ type: 'SET_ACTIVE_TOOL',
18707
+ payload: {
18708
+ toolbarSectionId,
18709
+ activeTool: toolName
18710
+ }
18711
+ });
18712
+ };
18713
+ const handleToolOptionChange = (toolbarSectionId, toolName, optionName, newValue) => {
18714
+ dispatch({
18715
+ type: 'UPDATE_TOOL_OPTION',
18716
+ payload: {
18717
+ toolbarSectionId,
18718
+ toolName,
18719
+ optionName,
18720
+ value: newValue
18721
+ }
18722
+ });
18723
+ };
18724
+ const initializeToolOptions = (toolbarSectionId, toolOptions) => {
18725
+ dispatch({
18726
+ type: 'INITIALIZE_TOOL_OPTIONS',
18727
+ toolbarSectionId,
18728
+ payload: toolOptions
18729
+ });
18730
+ };
18731
+ const api = {
18732
+ handleToolSelect,
18733
+ handleToolOptionChange,
18734
+ initializeToolOptions
18735
+ };
18736
+ const value = {
18737
+ state,
18738
+ api
18739
+ };
18740
+ return /*#__PURE__*/react.createElement(ToolboxContext.Provider, {
18741
+ value: value
18742
+ }, children);
18743
+ };
18744
+
18745
+ /**
18746
+ * Custom hook for accessing toolbox state and actions for a specific toolbar section.
18747
+ * You can use this hook to access the state and actions for a specific toolbar section (
18748
+ * defined by the toolbarSectionId) in your custom toolbar components. This hook
18749
+ * helps to manage the state and actions for the tools and their options in the toolbar.
18750
+ */
18751
+ const useToolbox = toolbarSectionId => {
18752
+ const context = (0,react.useContext)(ToolboxContext);
18753
+ if (context === undefined) {
18754
+ throw new Error('useToolbox must be used within a ToolboxProvider');
18755
+ }
18756
+ const {
18757
+ state,
18758
+ api
18759
+ } = context;
18760
+ return {
18761
+ state: state[toolbarSectionId] || {
18762
+ activeTool: null,
18763
+ toolOptions: {}
18764
+ },
18765
+ api: {
18766
+ handleToolSelect: toolName => api.handleToolSelect(toolbarSectionId, toolName),
18767
+ handleToolOptionChange: (toolName, optionName, value) => api.handleToolOptionChange(toolbarSectionId, toolName, optionName, value),
18768
+ initializeToolOptions: toolOptions => api.initializeToolOptions(toolbarSectionId, toolOptions)
18769
+ }
18770
+ };
18771
+ };
18314
18772
  ;// CONCATENATED MODULE: ../../ui/src/contextProviders/UserAuthenticationProvider.tsx
18315
18773
 
18316
18774
 
@@ -18432,6 +18890,7 @@ const useUserAuthentication = () => (0,react.useContext)(UserAuthenticationConte
18432
18890
 
18433
18891
 
18434
18892
 
18893
+
18435
18894
  ;// CONCATENATED MODULE: ../../../node_modules/browser-detect/dist/browser-detect.es5.js
18436
18895
  /*! *****************************************************************************
18437
18896
  Copyright (c) Microsoft Corporation. All rights reserved.
@@ -19254,6 +19713,7 @@ const arrowPositionStyle = {
19254
19713
  };
19255
19714
  const Tooltip = ({
19256
19715
  content,
19716
+ secondaryContent = null,
19257
19717
  isSticky,
19258
19718
  position,
19259
19719
  className,
@@ -19290,9 +19750,11 @@ const Tooltip = ({
19290
19750
  })
19291
19751
  }, /*#__PURE__*/react.createElement("div", {
19292
19752
  className: classnames_default()('tooltip-box bg-primary-dark border-secondary-light w-max-content relative inset-x-auto top-full rounded border text-base text-white', {
19293
- 'py-1 px-4': !tight
19753
+ 'py-[6px] px-[8px]': !tight
19294
19754
  })
19295
- }, typeof content === 'string' ? t(content) : content, /*#__PURE__*/react.createElement("svg", {
19755
+ }, /*#__PURE__*/react.createElement("div", null, typeof content === 'string' ? t(content) : content), /*#__PURE__*/react.createElement("div", {
19756
+ className: "text-aqua-pale"
19757
+ }, typeof secondaryContent === 'string' ? t(secondaryContent) : secondaryContent), /*#__PURE__*/react.createElement("svg", {
19296
19758
  className: "text-primary-dark stroke-secondary-light absolute h-4",
19297
19759
  style: arrowPositionStyle[position],
19298
19760
  xmlns: "http://www.w3.org/2000/svg",
@@ -19363,9 +19825,11 @@ const Button = ({
19363
19825
  name,
19364
19826
  className,
19365
19827
  onClick,
19828
+ dataCY,
19366
19829
  startIconTooltip = null,
19367
19830
  endIconTooltip = null
19368
19831
  }) => {
19832
+ dataCY = dataCY || `${name}-btn`;
19369
19833
  const startIcon = startIconProp && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.cloneElement(startIconProp, {
19370
19834
  className: classnames_default()('w-4 h-4 fill-current', startIconProp?.props?.className)
19371
19835
  }));
@@ -19387,7 +19851,7 @@ const Button = ({
19387
19851
  disabled: disabled,
19388
19852
  ref: buttonElement,
19389
19853
  onClick: handleOnClick,
19390
- "data-cy": `${name}-btn`
19854
+ "data-cy": dataCY
19391
19855
  }, startIconTooltip ? /*#__PURE__*/react.createElement(Tooltip_Tooltip, {
19392
19856
  content: startIconTooltip
19393
19857
  }, startIcon) : startIcon, children, endIconTooltip ? /*#__PURE__*/react.createElement(Tooltip_Tooltip, {
@@ -19422,7 +19886,9 @@ Button.propTypes = {
19422
19886
  /** Tooltip for the start icon */
19423
19887
  startIconTooltip: (prop_types_default()).node,
19424
19888
  /** Tooltip for the end icon */
19425
- endIconTooltip: (prop_types_default()).node
19889
+ endIconTooltip: (prop_types_default()).node,
19890
+ /** Data attribute for testing */
19891
+ dataCY: (prop_types_default()).string
19426
19892
  };
19427
19893
  /* harmony default export */ const Button_Button = (Button);
19428
19894
  ;// CONCATENATED MODULE: ../../ui/src/components/Button/index.js
@@ -19431,23 +19897,25 @@ Button.propTypes = {
19431
19897
 
19432
19898
  /* harmony default export */ const components_Button = (Button_Button);
19433
19899
  ;// CONCATENATED MODULE: ../../ui/src/components/ButtonGroup/ButtonGroup.tsx
19434
- function ButtonGroup_extends() { ButtonGroup_extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return ButtonGroup_extends.apply(this, arguments); }
19435
19900
 
19436
19901
 
19437
19902
 
19438
19903
 
19439
19904
  const ButtonGroup = ({
19440
- buttons,
19441
- onActiveIndexChange,
19905
+ children,
19442
19906
  className,
19443
19907
  orientation = ButtonEnums_orientation.horizontal,
19444
- defaultActiveIndex = 0
19908
+ activeIndex: defaultActiveIndex = 0,
19909
+ onActiveIndexChange,
19910
+ disabled = false
19445
19911
  }) => {
19446
19912
  const [activeIndex, setActiveIndex] = (0,react.useState)(defaultActiveIndex);
19447
- const handleButtonClick = (e, index) => {
19913
+ (0,react.useEffect)(() => {
19914
+ setActiveIndex(defaultActiveIndex);
19915
+ }, [defaultActiveIndex]);
19916
+ const handleButtonClick = index => {
19448
19917
  setActiveIndex(index);
19449
19918
  onActiveIndexChange && onActiveIndexChange(index);
19450
- buttons[index].onClick && buttons[index].onClick(e);
19451
19919
  };
19452
19920
  const orientationClasses = {
19453
19921
  horizontal: 'flex-row',
@@ -19455,24 +19923,28 @@ const ButtonGroup = ({
19455
19923
  };
19456
19924
  const wrapperClasses = classnames_default()('inline-flex', orientationClasses[orientation], className);
19457
19925
  return /*#__PURE__*/react.createElement("div", {
19458
- className: classnames_default()(wrapperClasses, 'border-secondary-light rounded-[5px] border bg-black text-[13px] ')
19459
- }, buttons.map((buttonProps, index) => {
19460
- const isActive = index === activeIndex;
19461
- return /*#__PURE__*/react.createElement("button", ButtonGroup_extends({}, buttonProps, {
19462
- key: index,
19463
- className: classnames_default()('rounded-[4px] px-2 py-1', isActive ? 'bg-customblue-40 text-white' : 'text-primary-active bg-black'),
19464
- onClick: e => handleButtonClick(e, index)
19465
- }));
19926
+ className: classnames_default()(wrapperClasses, 'border-secondary-light rounded-[5px] border bg-black text-[13px]')
19927
+ }, react.Children.map(children, (child, index) => {
19928
+ if ( /*#__PURE__*/react.isValidElement(child)) {
19929
+ return /*#__PURE__*/(0,react.cloneElement)(child, {
19930
+ key: index,
19931
+ className: classnames_default()('rounded-[4px] px-2 py-1', index === activeIndex ? 'bg-customblue-40 text-white' : 'text-primary-active bg-black', child.props.className, disabled ? 'ohif-disabled' : ''),
19932
+ onClick: e => {
19933
+ child.props.onClick && child.props.onClick(e);
19934
+ handleButtonClick(index);
19935
+ }
19936
+ });
19937
+ }
19938
+ return child;
19466
19939
  }));
19467
19940
  };
19468
19941
  ButtonGroup.propTypes = {
19469
- buttons: prop_types_default().arrayOf((prop_types_default()).object).isRequired,
19942
+ children: (prop_types_default()).node.isRequired,
19470
19943
  orientation: prop_types_default().oneOf(Object.values(ButtonEnums_orientation)),
19471
- type: prop_types_default().oneOf(Object.values(type)),
19472
- size: prop_types_default().oneOf(Object.values(size)),
19473
- defaultActiveIndex: (prop_types_default()).number,
19944
+ activeIndex: (prop_types_default()).number,
19474
19945
  onActiveIndexChange: (prop_types_default()).func,
19475
- className: (prop_types_default()).string
19946
+ className: (prop_types_default()).string,
19947
+ disabled: (prop_types_default()).bool
19476
19948
  };
19477
19949
  /* harmony default export */ const ButtonGroup_ButtonGroup = (ButtonGroup);
19478
19950
  ;// CONCATENATED MODULE: ../../ui/src/components/ButtonGroup/index.js
@@ -20492,7 +20964,7 @@ const roundedClasses = {
20492
20964
  full: 'rounded-full'
20493
20965
  };
20494
20966
  const IconButton_disabledClasses = {
20495
- true: 'cursor-not-allowed',
20967
+ true: 'ohif-disabled',
20496
20968
  false: ''
20497
20969
  };
20498
20970
  const variantClasses = {
@@ -20511,36 +20983,13 @@ const variantClasses = {
20511
20983
  black: 'border border-primary-main text-white hover:bg-primary-main focus:bg-primary-main hover:border-black focus:border-black'
20512
20984
  },
20513
20985
  contained: {
20514
- default: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
20986
+ default: 'text-common-bright hover:opacity-80 active:opacity-100 focus:opacity-80',
20515
20987
  primary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
20516
20988
  secondary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
20517
20989
  white: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
20518
20990
  black: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80'
20519
20991
  }
20520
20992
  };
20521
- const backgroundClasses = {
20522
- text: {
20523
- default: '',
20524
- primary: '',
20525
- secondary: '',
20526
- white: '',
20527
- black: ''
20528
- },
20529
- outlined: {
20530
- default: 'bg-transparent',
20531
- primary: 'bg-transparent',
20532
- secondary: 'bg-transparent',
20533
- white: 'bg-transparent',
20534
- black: 'bg-black'
20535
- },
20536
- contained: {
20537
- default: 'bg-primary-light',
20538
- primary: 'bg-primary-main',
20539
- secondary: 'bg-secondary-light',
20540
- white: 'bg-white',
20541
- black: 'bg-black'
20542
- }
20543
- };
20544
20993
  const IconButton_sizeClasses = {
20545
20994
  small: 'py-2 px-2 text-base',
20546
20995
  medium: 'py-3 px-3 text-lg',
@@ -20552,7 +21001,7 @@ const iconSizeClasses = {
20552
21001
  small: 'w-4 h-4',
20553
21002
  medium: 'w-5 h-5',
20554
21003
  large: 'w-6 h-6',
20555
- toolbar: 'w-5 h-5'
21004
+ toolbar: 'w-[24px] h-[24px]'
20556
21005
  };
20557
21006
  const fullWidthClasses = {
20558
21007
  true: 'flex w-full',
@@ -20569,9 +21018,7 @@ const IconButton = ({
20569
21018
  fullWidth,
20570
21019
  onClick,
20571
21020
  className,
20572
- name,
20573
21021
  id,
20574
- bgColor,
20575
21022
  ...rest
20576
21023
  }) => {
20577
21024
  const buttonElement = (0,react.useRef)(null);
@@ -20579,11 +21026,11 @@ const IconButton = ({
20579
21026
  buttonElement.current.blur();
20580
21027
  onClick(e);
20581
21028
  };
20582
- const bgColorToUse = bgColor ? bgColor : backgroundClasses[variant][color];
21029
+ const padding = size === 'toolbar' ? '8px' : size === 'toolbox' ? '4px' : null;
20583
21030
  return /*#__PURE__*/react.createElement("button", {
20584
- className: classnames_default()(baseClasses, variantClasses[variant][color], roundedClasses[rounded], IconButton_sizeClasses[size], fullWidthClasses[fullWidth], IconButton_disabledClasses[disabled], bgColorToUse, className),
21031
+ className: classnames_default()(baseClasses, variantClasses[variant][color], roundedClasses[rounded], IconButton_sizeClasses[size], fullWidthClasses[fullWidth], IconButton_disabledClasses[disabled], className),
20585
21032
  style: {
20586
- padding: size === 'toolbar' ? '10px' : null
21033
+ padding
20587
21034
  },
20588
21035
  ref: buttonElement,
20589
21036
  onClick: handleOnClick,
@@ -20606,7 +21053,7 @@ IconButton.defaultProps = {
20606
21053
  };
20607
21054
  IconButton.propTypes = {
20608
21055
  children: (prop_types_default()).node.isRequired,
20609
- size: prop_types_default().oneOf(['small', 'medium', 'large', 'initial', 'toolbar']),
21056
+ size: prop_types_default().oneOf(['small', 'medium', 'large', 'initial', 'toolbar', 'toolbox']),
20610
21057
  rounded: prop_types_default().oneOf(['none', 'small', 'medium', 'large', 'full']),
20611
21058
  variant: prop_types_default().oneOf(['text', 'outlined', 'contained']),
20612
21059
  color: prop_types_default().oneOf(['default', 'primary', 'secondary', 'white', 'black', 'inherit']),
@@ -23262,7 +23709,7 @@ var emotion_use_insertion_effect_with_fallbacks_browser_esm_useInsertionEffectWi
23262
23709
 
23263
23710
 
23264
23711
 
23265
- ;// CONCATENATED MODULE: ../../../node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js
23712
+ ;// CONCATENATED MODULE: ../../../node_modules/@emotion/react/dist/emotion-element-43c6fea0.browser.esm.js
23266
23713
 
23267
23714
 
23268
23715
 
@@ -23273,8 +23720,8 @@ var emotion_use_insertion_effect_with_fallbacks_browser_esm_useInsertionEffectWi
23273
23720
 
23274
23721
 
23275
23722
 
23276
- var emotion_element_c39617d8_browser_esm_isBrowser = "object" !== 'undefined';
23277
- var emotion_element_c39617d8_browser_esm_hasOwnProperty = {}.hasOwnProperty;
23723
+ var emotion_element_43c6fea0_browser_esm_isBrowser = "object" !== 'undefined';
23724
+ var hasOwn = {}.hasOwnProperty;
23278
23725
 
23279
23726
  var EmotionCacheContext = /* #__PURE__ */react.createContext( // we're doing this to avoid preconstruct's dead code elimination in this one case
23280
23727
  // because this module is primarily intended for the browser and node
@@ -23288,12 +23735,12 @@ typeof HTMLElement !== 'undefined' ? /* #__PURE__ */emotion_cache_browser_esm_cr
23288
23735
 
23289
23736
  if (false) {}
23290
23737
 
23291
- var emotion_element_c39617d8_browser_esm_CacheProvider = EmotionCacheContext.Provider;
23738
+ var emotion_element_43c6fea0_browser_esm_CacheProvider = EmotionCacheContext.Provider;
23292
23739
  var __unsafe_useEmotionCache = function useEmotionCache() {
23293
23740
  return useContext(EmotionCacheContext);
23294
23741
  };
23295
23742
 
23296
- var emotion_element_c39617d8_browser_esm_withEmotionCache = function withEmotionCache(func) {
23743
+ var emotion_element_43c6fea0_browser_esm_withEmotionCache = function withEmotionCache(func) {
23297
23744
  // $FlowFixMe
23298
23745
  return /*#__PURE__*/(0,react.forwardRef)(function (props, ref) {
23299
23746
  // the cache will never be null in the browser
@@ -23302,8 +23749,8 @@ var emotion_element_c39617d8_browser_esm_withEmotionCache = function withEmotion
23302
23749
  });
23303
23750
  };
23304
23751
 
23305
- if (!emotion_element_c39617d8_browser_esm_isBrowser) {
23306
- emotion_element_c39617d8_browser_esm_withEmotionCache = function withEmotionCache(func) {
23752
+ if (!emotion_element_43c6fea0_browser_esm_isBrowser) {
23753
+ emotion_element_43c6fea0_browser_esm_withEmotionCache = function withEmotionCache(func) {
23307
23754
  return function (props) {
23308
23755
  var cache = (0,react.useContext)(EmotionCacheContext);
23309
23756
 
@@ -23326,12 +23773,12 @@ if (!emotion_element_c39617d8_browser_esm_isBrowser) {
23326
23773
  };
23327
23774
  }
23328
23775
 
23329
- var emotion_element_c39617d8_browser_esm_ThemeContext = /* #__PURE__ */react.createContext({});
23776
+ var emotion_element_43c6fea0_browser_esm_ThemeContext = /* #__PURE__ */react.createContext({});
23330
23777
 
23331
23778
  if (false) {}
23332
23779
 
23333
23780
  var useTheme = function useTheme() {
23334
- return React.useContext(emotion_element_c39617d8_browser_esm_ThemeContext);
23781
+ return React.useContext(emotion_element_43c6fea0_browser_esm_ThemeContext);
23335
23782
  };
23336
23783
 
23337
23784
  var getTheme = function getTheme(outerTheme, theme) {
@@ -23354,13 +23801,13 @@ var createCacheWithTheme = /* #__PURE__ */(/* unused pure expression or super */
23354
23801
  });
23355
23802
  })));
23356
23803
  var ThemeProvider = function ThemeProvider(props) {
23357
- var theme = React.useContext(emotion_element_c39617d8_browser_esm_ThemeContext);
23804
+ var theme = React.useContext(emotion_element_43c6fea0_browser_esm_ThemeContext);
23358
23805
 
23359
23806
  if (props.theme !== theme) {
23360
23807
  theme = createCacheWithTheme(theme)(props.theme);
23361
23808
  }
23362
23809
 
23363
- return /*#__PURE__*/React.createElement(emotion_element_c39617d8_browser_esm_ThemeContext.Provider, {
23810
+ return /*#__PURE__*/React.createElement(emotion_element_43c6fea0_browser_esm_ThemeContext.Provider, {
23364
23811
  value: theme
23365
23812
  }, props.children);
23366
23813
  };
@@ -23368,7 +23815,7 @@ function withTheme(Component) {
23368
23815
  var componentName = Component.displayName || Component.name || 'Component';
23369
23816
 
23370
23817
  var render = function render(props, ref) {
23371
- var theme = React.useContext(emotion_element_c39617d8_browser_esm_ThemeContext);
23818
+ var theme = React.useContext(emotion_element_43c6fea0_browser_esm_ThemeContext);
23372
23819
  return /*#__PURE__*/React.createElement(Component, _extends({
23373
23820
  theme: theme,
23374
23821
  ref: ref
@@ -23432,7 +23879,7 @@ var createEmotionProps = function createEmotionProps(type, props) {
23432
23879
  var newProps = {};
23433
23880
 
23434
23881
  for (var key in props) {
23435
- if (emotion_element_c39617d8_browser_esm_hasOwnProperty.call(props, key)) {
23882
+ if (hasOwn.call(props, key)) {
23436
23883
  newProps[key] = props[key];
23437
23884
  }
23438
23885
  }
@@ -23457,7 +23904,7 @@ var Insertion = function Insertion(_ref) {
23457
23904
  return null;
23458
23905
  };
23459
23906
 
23460
- var Emotion = /* #__PURE__ */emotion_element_c39617d8_browser_esm_withEmotionCache(function (props, cache, ref) {
23907
+ var Emotion = /* #__PURE__ */emotion_element_43c6fea0_browser_esm_withEmotionCache(function (props, cache, ref) {
23461
23908
  var cssProp = props.css; // so that using `css` from `emotion` and passing the result to the css prop works
23462
23909
  // not passing the registered cache to serializeStyles because it would
23463
23910
  // make certain babel optimisations not possible
@@ -23476,7 +23923,7 @@ var Emotion = /* #__PURE__ */emotion_element_c39617d8_browser_esm_withEmotionCac
23476
23923
  className = props.className + " ";
23477
23924
  }
23478
23925
 
23479
- var serialized = emotion_serialize_browser_esm_serializeStyles(registeredStyles, undefined, react.useContext(emotion_element_c39617d8_browser_esm_ThemeContext));
23926
+ var serialized = emotion_serialize_browser_esm_serializeStyles(registeredStyles, undefined, react.useContext(emotion_element_43c6fea0_browser_esm_ThemeContext));
23480
23927
 
23481
23928
  if (false) { var labelFromStack; }
23482
23929
 
@@ -23484,7 +23931,7 @@ var Emotion = /* #__PURE__ */emotion_element_c39617d8_browser_esm_withEmotionCac
23484
23931
  var newProps = {};
23485
23932
 
23486
23933
  for (var key in props) {
23487
- if (emotion_element_c39617d8_browser_esm_hasOwnProperty.call(props, key) && key !== 'css' && key !== typePropName && ( true || 0)) {
23934
+ if (hasOwn.call(props, key) && key !== 'css' && key !== typePropName && ( true || 0)) {
23488
23935
  newProps[key] = props[key];
23489
23936
  }
23490
23937
  }
@@ -23519,7 +23966,7 @@ var Emotion$1 = Emotion;
23519
23966
 
23520
23967
  var pkg = {
23521
23968
  name: "@emotion/react",
23522
- version: "11.11.3",
23969
+ version: "11.11.4",
23523
23970
  main: "dist/emotion-react.cjs.js",
23524
23971
  module: "dist/emotion-react.esm.js",
23525
23972
  browser: {
@@ -23652,7 +24099,7 @@ var pkg = {
23652
24099
  var jsx = function jsx(type, props) {
23653
24100
  var args = arguments;
23654
24101
 
23655
- if (props == null || !emotion_element_c39617d8_browser_esm_hasOwnProperty.call(props, 'css')) {
24102
+ if (props == null || !hasOwn.call(props, 'css')) {
23656
24103
  // $FlowFixMe
23657
24104
  return react.createElement.apply(undefined, args);
23658
24105
  }
@@ -30281,18 +30728,13 @@ function LayoutSelector({
30281
30728
  gridTemplateColumns: gridSize.repeat(columns),
30282
30729
  gridTemplateRows: gridSize.repeat(rows),
30283
30730
  backgroundColor: '#090c29' // primary-dark
30284
- },
30285
- className: "p-2"
30731
+ }
30286
30732
  }, Array.apply(null, Array(rows * columns)).map(function (_, i) {
30287
30733
  return i;
30288
30734
  }).map(index => /*#__PURE__*/react.createElement("div", {
30289
30735
  key: index,
30290
- style: {
30291
- border: '1px solid white',
30292
- backgroundColor: isHovered(index) ? '#5acce6' : '#0b1a42'
30293
- },
30736
+ className: `border-primary-dark border ${isHovered(index) ? 'bg-primary-active' : 'bg-[#04225b]'} cursor-pointer`,
30294
30737
  "data-cy": `Layout-${index % columns}-${Math.floor(index / columns)}`,
30295
- className: "cursor-pointer",
30296
30738
  onClick: () => {
30297
30739
  const x = index % columns;
30298
30740
  const y = Math.floor(index / columns);
@@ -30307,7 +30749,7 @@ function LayoutSelector({
30307
30749
  }
30308
30750
  LayoutSelector.defaultProps = {
30309
30751
  onSelection: () => {},
30310
- columns: 3,
30752
+ columns: 4,
30311
30753
  rows: 3
30312
30754
  };
30313
30755
  LayoutSelector.propTypes = {
@@ -31251,12 +31693,7 @@ const NavBar = ({
31251
31693
  isSticky
31252
31694
  }) => {
31253
31695
  return /*#__PURE__*/react.createElement("div", {
31254
- className: classnames_default()('bg-secondary-dark z-20 flex flex-row items-center border-b-4 border-black px-1', isSticky && stickyClasses, !isSticky && notStickyClasses, className),
31255
- style: {
31256
- paddingTop: '4px',
31257
- paddingBottom: '4px',
31258
- minHeight: '52px'
31259
- }
31696
+ className: classnames_default()('bg-secondary-dark z-20 border-black px-1', isSticky && stickyClasses, !isSticky && notStickyClasses, className)
31260
31697
  }, children);
31261
31698
  };
31262
31699
  NavBar.propTypes = {
@@ -32156,7 +32593,7 @@ const SegmentItem = ({
32156
32593
  "data-cy": 'segment-item'
32157
32594
  }, /*#__PURE__*/react.createElement("div", {
32158
32595
  className: classnames_default()('bg-primary-dark group/number grid w-[32px] place-items-center', {
32159
- 'bg-primary-light border-primary-light rounded-l-[4px] border text-black': isActive,
32596
+ '!bg-primary-light border-primary-light rounded-l-[4px] border text-black': isActive,
32160
32597
  'border-primary-dark border': !isActive
32161
32598
  }),
32162
32599
  onMouseEnter: () => setIsNumberBoxHovering(true),
@@ -32566,8 +33003,8 @@ const getGridStyle = (side, numTabs = 0, gridWidth, expandedWidth) => {
32566
33003
  width: `${gridWidth}px`
32567
33004
  };
32568
33005
  };
32569
- const getTabClassNames = (numColumns, numTabs, tabIndex, isActiveTab) => classnames_default()('h-[28px] mb-[2px] cursor-pointer text-white bg-black', {
32570
- 'hover:text-primary-active': !isActiveTab,
33006
+ const getTabClassNames = (numColumns, numTabs, tabIndex, isActiveTab, isTabDisabled) => classnames_default()('h-[28px] mb-[2px] cursor-pointer text-white bg-black', {
33007
+ 'hover:text-primary-active': !isActiveTab && !isTabDisabled,
32571
33008
  'rounded-l': tabIndex % numColumns === 0,
32572
33009
  'rounded-r': (tabIndex + 1) % numColumns === 0 || tabIndex === numTabs - 1
32573
33010
  });
@@ -32603,6 +33040,11 @@ const createStyleMap = (expandedWidth, borderSize, collapsedWidth) => {
32603
33040
  }
32604
33041
  };
32605
33042
  };
33043
+ const getToolTipContent = (label, disabled) => {
33044
+ return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", null, label), disabled && /*#__PURE__*/react.createElement("div", {
33045
+ className: "text-white"
33046
+ }, 'Not available based on current context'));
33047
+ };
32606
33048
  const createBaseStyle = expandedWidth => {
32607
33049
  return {
32608
33050
  maxWidth: `${expandedWidth}px`,
@@ -32667,18 +33109,21 @@ const SidePanel = ({
32667
33109
  }, _childComponents.map((childComponent, index) => /*#__PURE__*/react.createElement(components_Tooltip, {
32668
33110
  position: side === 'left' ? 'right' : 'left',
32669
33111
  key: index,
32670
- content: `${childComponent.label}`,
33112
+ content: getToolTipContent(childComponent.label, childComponent.disabled),
32671
33113
  className: classnames_default()('flex items-center', side === 'left' ? 'justify-end ' : 'justify-start ')
32672
33114
  }, /*#__PURE__*/react.createElement("div", {
32673
33115
  id: `${childComponent.name}-btn`,
32674
33116
  "data-cy": `${childComponent.name}-btn`,
32675
33117
  className: "text-primary-active hover:cursor-pointer",
32676
33118
  onClick: () => {
32677
- updateActiveTabIndex(index);
33119
+ return childComponent.disabled ? null : updateActiveTabIndex(index);
32678
33120
  }
32679
33121
  }, /*#__PURE__*/react.createElement(Icon/* default */.A, {
32680
33122
  name: childComponent.iconName,
32681
- className: "text-primary-active",
33123
+ className: classnames_default()({
33124
+ 'text-primary-active': true,
33125
+ 'ohif-disabled': childComponent.disabled
33126
+ }),
32682
33127
  style: {
32683
33128
  width: '22px',
32684
33129
  height: '22px'
@@ -32708,6 +33153,9 @@ const SidePanel = ({
32708
33153
  className: classnames_default()('bg-primary-dark text-primary-active flex flex-wrap'),
32709
33154
  style: getGridStyle(side, tabs.length, gridWidth, expandedWidth)
32710
33155
  }, tabs.map((tab, tabIndex) => {
33156
+ const {
33157
+ disabled
33158
+ } = tab;
32711
33159
  return /*#__PURE__*/react.createElement(react.Fragment, {
32712
33160
  key: tabIndex
32713
33161
  }, tabIndex % numCols !== 0 && /*#__PURE__*/react.createElement("div", {
@@ -32717,16 +33165,19 @@ const SidePanel = ({
32717
33165
  })), /*#__PURE__*/react.createElement(components_Tooltip, {
32718
33166
  position: 'bottom',
32719
33167
  key: tabIndex,
32720
- content: `${tab.label}`
33168
+ content: getToolTipContent(tab.label, disabled)
32721
33169
  }, /*#__PURE__*/react.createElement("div", {
32722
- className: getTabClassNames(numCols, tabs.length, tabIndex, tabIndex === activeTabIndex),
33170
+ className: getTabClassNames(numCols, tabs.length, tabIndex, tabIndex === activeTabIndex, disabled),
32723
33171
  style: getTabStyle(tabs.length),
32724
- onClick: () => updateActiveTabIndex(tabIndex),
33172
+ onClick: () => {
33173
+ return disabled ? null : updateActiveTabIndex(tabIndex);
33174
+ },
32725
33175
  "data-cy": `${tab.name}-btn`
32726
33176
  }, /*#__PURE__*/react.createElement("div", {
32727
33177
  className: getTabIconClassNames(tabs.length, tabIndex === activeTabIndex)
32728
33178
  }, /*#__PURE__*/react.createElement(Icon/* default */.A, {
32729
33179
  name: tab.iconName,
33180
+ className: `${tab.disabled && 'ohif-disabled'}`,
32730
33181
  style: {
32731
33182
  width: '22px',
32732
33183
  height: '22px'
@@ -32786,6 +33237,8 @@ var react_outside_click_handler = __webpack_require__(17076);
32786
33237
 
32787
33238
 
32788
33239
 
33240
+ const flex = 'flex flex-row justify-between items-center';
33241
+ const theme = 'bg-indigo-dark text-white';
32789
33242
  const ListMenu = ({
32790
33243
  items = [],
32791
33244
  renderer,
@@ -32797,24 +33250,23 @@ const ListMenu = ({
32797
33250
  index,
32798
33251
  isSelected
32799
33252
  }) => {
32800
- const flex = 'flex flex-row justify-between items-center';
32801
- const theme = 'bg-indigo-dark';
32802
33253
  const onClickHandler = () => {
32803
33254
  setSelectedIndex(index);
32804
33255
  onClick({
32805
33256
  item,
32806
33257
  selectedIndex: index
32807
33258
  });
32808
- if (item.onClick) {
32809
- item.onClick({
32810
- ...item,
32811
- index,
32812
- isSelected
32813
- });
32814
- }
33259
+ item.onClick?.({
33260
+ ...item,
33261
+ index,
33262
+ isSelected
33263
+ });
32815
33264
  };
32816
33265
  return /*#__PURE__*/react.createElement("div", {
32817
- className: classnames_default()(flex, theme, 'cursor-pointer'),
33266
+ className: classnames_default()(flex, theme, {
33267
+ 'cursor-pointer': !item.disabled,
33268
+ 'ohif-disabled': item.disabled
33269
+ }),
32818
33270
  onClick: onClickHandler,
32819
33271
  "data-cy": item.id
32820
33272
  }, renderer && renderer({
@@ -32859,36 +33311,28 @@ function SplitButton_extends() { SplitButton_extends = Object.assign ? Object.as
32859
33311
 
32860
33312
  const SplitButton_baseClasses = {
32861
33313
  Button: 'flex items-center rounded-md border-transparent cursor-pointer group/button',
32862
- Primary:
32863
- // By default border on left, top and bottom for hover effect and only rounded on left side.
32864
- // Extra padding on right to compensate for no right border.
32865
- 'h-full border-l-2 border-t-2 border-b-2 rounded-tl-md rounded-bl-md group/primary !pl-2 !py-2',
33314
+ Primary: 'h-full border-l-2 border-t-2 border-b-2 rounded-tl-md rounded-bl-md group/primary !pl-2 !py-2',
32866
33315
  Secondary: 'h-full flex items-center justify-center rounded-tr-md rounded-br-md w-4 border-2 border-transparent group/secondary',
32867
33316
  SecondaryIcon: 'w-4 h-full stroke-1',
32868
- Separator: 'border-l py-2.5',
33317
+ Separator: 'border-l py-3 ml-0.5',
32869
33318
  Content: 'absolute z-10 top-0 mt-12'
32870
33319
  };
32871
33320
  const SplitButton_classes = {
32872
33321
  Button: ({
32873
- isExpanded,
32874
- primary
32875
- }) => classnames_default()(SplitButton_baseClasses.Button, !isExpanded && !primary.isActive && 'hover:!bg-primary-dark hover:border-primary-dark'),
33322
+ isExpanded
33323
+ }) => classnames_default()(SplitButton_baseClasses.Button, !isExpanded && 'hover:!bg-primary-dark hover:border-primary-dark'),
32876
33324
  Interface: 'h-full flex flex-row items-center',
32877
33325
  Primary: ({
32878
- primary,
32879
- isExpanded
32880
- }) => classnames_default()(SplitButton_baseClasses.Primary, primary.isActive ? isExpanded ? 'border-primary-dark !bg-primary-dark hover:border-primary-dark !text-primary-light' : `${primary.isToggle ? 'border-secondary-dark bg-secondary-light' : 'border-primary-light bg-primary-light'}
32881
- border-2 rounded-md !p-2` // Full, rounded border with less right padding when active.
32882
- : `focus:!text-black focus:!rounded-md focus:!border-primary-light focus:!bg-primary-light
32883
- ${isExpanded ? 'border-primary-dark bg-primary-dark !text-primary-light' : 'border-secondary-dark bg-secondary-dark group-hover/button:border-primary-dark group-hover/button:text-primary-light hover:!bg-primary-dark hover:border-primary-dark focus:!text-black'}
32884
- `),
33326
+ isExpanded,
33327
+ isActive
33328
+ }) => classnames_default()(SplitButton_baseClasses.Primary, isActive ? isExpanded ? 'border-primary-dark !bg-primary-dark hover:border-primary-dark !text-primary-light' : 'border-primary-light bg-primary-light border-2 rounded-md !p-2' : `focus:!text-black focus:!rounded-md focus:!border-primary-light focus:!bg-primary-light ${isExpanded ? 'border-primary-dark bg-primary-dark !text-primary-light' : 'border-secondary-dark bg-secondary-dark group-hover/button:border-primary-dark group-hover/button:text-primary-light hover:!bg-primary-dark hover:border-primary-dark focus:!text-black'}`),
32885
33329
  Secondary: ({
32886
33330
  isExpanded,
32887
33331
  primary
32888
33332
  }) => classnames_default()(SplitButton_baseClasses.Secondary, isExpanded ? 'bg-primary-light !rounded-tr-md !rounded-br-md' : primary.isActive ? 'bg-secondary-dark' : 'hover:bg-primary-dark bg-secondary-dark group-hover/button:border-primary-dark'),
32889
33333
  SecondaryIcon: ({
32890
33334
  isExpanded
32891
- }) => classnames_default()(SplitButton_baseClasses.SecondaryIcon, isExpanded ? 'text-primary-dark' : 'text-[#348cfd] group-hover/secondary:text-primary-light'),
33335
+ }) => classnames_default()(SplitButton_baseClasses.SecondaryIcon, isExpanded ? 'text-primary-dark' : 'text-primary-active group-hover/secondary:text-primary-light'),
32892
33336
  Separator: ({
32893
33337
  primary,
32894
33338
  isExpanded,
@@ -32898,14 +33342,36 @@ const SplitButton_classes = {
32898
33342
  isExpanded
32899
33343
  }) => classnames_default()(SplitButton_baseClasses.Content, isExpanded ? 'block' : 'hidden')
32900
33344
  };
33345
+ const DefaultListItemRenderer = props => {
33346
+ const {
33347
+ t,
33348
+ icon,
33349
+ label,
33350
+ className,
33351
+ isActive
33352
+ } = props;
33353
+ return /*#__PURE__*/react.createElement("div", {
33354
+ className: classnames_default()('flex h-8 w-full flex-row items-center p-3', 'whitespace-pre text-base', className, `${isActive ? 'hover:opacity-80' : 'hover:bg-primary-dark '}`)
33355
+ }, icon && /*#__PURE__*/react.createElement("span", {
33356
+ className: "mr-4"
33357
+ }, /*#__PURE__*/react.createElement(Icon/* default */.A, {
33358
+ name: icon,
33359
+ className: "h-5 w-5"
33360
+ })), /*#__PURE__*/react.createElement("span", {
33361
+ className: "mr-5"
33362
+ }, t?.(label)));
33363
+ };
33364
+
33365
+ /**
33366
+ * This is a more generic version of SplitButton without the isActive
33367
+ * and other interaction props
33368
+ */
32901
33369
  const SplitButton = ({
32902
- isToggle,
32903
33370
  groupId,
32904
33371
  primary,
32905
33372
  secondary,
32906
33373
  items,
32907
33374
  renderer,
32908
- isActive,
32909
33375
  onInteraction,
32910
33376
  Component
32911
33377
  }) => {
@@ -32928,22 +33394,11 @@ const SplitButton = ({
32928
33394
  ...state,
32929
33395
  isExpanded: false
32930
33396
  });
32931
- const renderPrimaryButton = () => /*#__PURE__*/react.createElement(Component, SplitButton_extends({
32932
- key: primary.id
32933
- }, primary, {
32934
- isActive: isActive,
32935
- onInteraction: onInteraction,
32936
- rounded: "none",
32937
- className: SplitButton_classes.Primary({
32938
- ...state,
32939
- primary: {
32940
- isActive,
32941
- isToggle
32942
- }
32943
- }),
32944
- "data-tool": primary.id,
32945
- "data-cy": `${groupId}-split-button-primary`
32946
- }));
33397
+ const listItemRenderer = renderer || DefaultListItemRenderer;
33398
+ const primaryClassNames = classnames_default()(SplitButton_classes.Primary({
33399
+ isExpanded: state.isExpanded,
33400
+ isActive: primary.isActive
33401
+ }), primary.className);
32947
33402
  return /*#__PURE__*/react.createElement(react_outside_click_handler["default"], {
32948
33403
  onOutsideClick: collapse,
32949
33404
  disabled: !state.isExpanded
@@ -32952,10 +33407,7 @@ const SplitButton = ({
32952
33407
  className: "relative"
32953
33408
  }, /*#__PURE__*/react.createElement("div", {
32954
33409
  className: SplitButton_classes.Button({
32955
- ...state,
32956
- primary: {
32957
- isActive
32958
- }
33410
+ ...state
32959
33411
  }),
32960
33412
  style: {
32961
33413
  height: '40px'
@@ -32966,19 +33418,23 @@ const SplitButton = ({
32966
33418
  className: SplitButton_classes.Interface
32967
33419
  }, /*#__PURE__*/react.createElement("div", {
32968
33420
  onClick: collapse
32969
- }, renderPrimaryButton()), /*#__PURE__*/react.createElement("div", {
33421
+ }, /*#__PURE__*/react.createElement(Component, SplitButton_extends({
33422
+ key: primary.id
33423
+ }, primary, {
33424
+ onInteraction: onInteraction,
33425
+ rounded: "none",
33426
+ className: primaryClassNames,
33427
+ "data-tool": primary.id,
33428
+ "data-cy": `${groupId}-split-button-primary`
33429
+ }))), /*#__PURE__*/react.createElement("div", {
32970
33430
  className: SplitButton_classes.Separator({
32971
33431
  ...state,
32972
- primary: {
32973
- isActive
32974
- }
33432
+ primary
32975
33433
  })
32976
33434
  }), /*#__PURE__*/react.createElement("div", {
32977
33435
  className: SplitButton_classes.Secondary({
32978
33436
  ...state,
32979
- primary: {
32980
- isActive
32981
- }
33437
+ primary
32982
33438
  }),
32983
33439
  onClick: toggleExpanded,
32984
33440
  "data-cy": `${groupId}-split-button-secondary`
@@ -32989,10 +33445,7 @@ const SplitButton = ({
32989
33445
  }, /*#__PURE__*/react.createElement(Icon/* default */.A, {
32990
33446
  name: secondary.icon,
32991
33447
  className: SplitButton_classes.SecondaryIcon({
32992
- ...state,
32993
- primary: {
32994
- isActive
32995
- }
33448
+ ...state
32996
33449
  })
32997
33450
  }))))), /*#__PURE__*/react.createElement("div", {
32998
33451
  className: SplitButton_classes.Content({
@@ -33002,7 +33455,7 @@ const SplitButton = ({
33002
33455
  }, /*#__PURE__*/react.createElement(components_ListMenu, {
33003
33456
  items: items,
33004
33457
  onClick: collapse,
33005
- renderer: args => renderer({
33458
+ renderer: args => listItemRenderer({
33006
33459
  ...args,
33007
33460
  t
33008
33461
  })
@@ -33017,7 +33470,8 @@ SplitButton.propTypes = {
33017
33470
  renderer: (prop_types_default()).func,
33018
33471
  isActive: (prop_types_default()).bool,
33019
33472
  onInteraction: (prop_types_default()).func.isRequired,
33020
- Component: (prop_types_default()).elementType
33473
+ Component: (prop_types_default()).elementType,
33474
+ interactionType: prop_types_default().oneOf(['action', 'tool', 'toggle'])
33021
33475
  };
33022
33476
  SplitButton.defaultProps = {
33023
33477
  isToggle: false,
@@ -33666,7 +34120,7 @@ const Thumbnail = ({
33666
34120
  }, imageSrc ? /*#__PURE__*/react.createElement("img", {
33667
34121
  src: imageSrc,
33668
34122
  alt: imageAltText,
33669
- className: "min-h-32 object-none",
34123
+ className: "min-h-32 object-contain",
33670
34124
  crossOrigin: "anonymous"
33671
34125
  }) : /*#__PURE__*/react.createElement("div", null, imageAltText)), /*#__PURE__*/react.createElement("div", {
33672
34126
  className: "flex flex-1 flex-row items-center pt-2 text-base text-blue-300"
@@ -33830,6 +34284,9 @@ ThumbnailNoImage.propTypes = {
33830
34284
 
33831
34285
 
33832
34286
 
34287
+
34288
+ // Todo: This class to me feels like it belongs in an extension, not in platform/ui
34289
+ // because it is dealing with mode specific components/information
33833
34290
  function ThumbnailTracked({
33834
34291
  displaySetInstanceUID,
33835
34292
  className,
@@ -33920,7 +34377,6 @@ function ThumbnailTracked({
33920
34377
  onDoubleClick: onDoubleClick
33921
34378
  }));
33922
34379
  }
33923
- ;
33924
34380
  ThumbnailTracked.propTypes = {
33925
34381
  /**
33926
34382
  * Data the thumbnail should expose to a receiving drop target. Use a matching
@@ -34959,9 +35415,7 @@ function ToolbarButton_extends() { ToolbarButton_extends = Object.assign ? Objec
34959
35415
 
34960
35416
 
34961
35417
 
34962
-
34963
35418
  const ToolbarButton = ({
34964
- type = 'tool',
34965
35419
  id,
34966
35420
  icon,
34967
35421
  label,
@@ -34969,39 +35423,33 @@ const ToolbarButton = ({
34969
35423
  onInteraction,
34970
35424
  dropdownContent,
34971
35425
  //
34972
- isActive,
34973
35426
  className,
35427
+ size,
35428
+ toolTipClassName,
35429
+ disableToolTip = false,
34974
35430
  ...rest
34975
35431
  //
34976
35432
  }) => {
34977
- const classes = {
34978
- tool: isActive ? 'text-black' : 'text-common-bright hover:!bg-primary-dark hover:text-primary-light',
34979
- toggle: isActive ? '!text-[#348CFD]' : 'text-common-bright hover:!bg-primary-dark hover:text-primary-light',
34980
- action: isActive ? 'text-black' : 'text-common-bright hover:!bg-primary-dark hover:text-primary-light'
34981
- };
34982
- const bgClasses = {
34983
- toggle: isActive && 'bg-transparent'
34984
- };
34985
- const activeClass = isActive ? 'active' : '';
34986
- const shouldShowDropdown = !!isActive && !!dropdownContent;
35433
+ const shouldShowDropdown = !!dropdownContent;
34987
35434
  const iconEl = icon ? /*#__PURE__*/react.createElement(Icon/* default */.A, {
34988
35435
  name: icon
34989
35436
  }) : /*#__PURE__*/react.createElement("div", null, label || 'Missing icon and label');
35437
+ const sizeToUse = size ?? 'toolbar';
35438
+ const toolTipClassNameToUse = toolTipClassName !== undefined ? toolTipClassName : sizeToUse === 'toolbar' ? 'w-[40px] h-[40px]' : 'w-[32px] h-[32px]';
34990
35439
  return /*#__PURE__*/react.createElement("div", {
34991
35440
  key: id
34992
35441
  }, /*#__PURE__*/react.createElement(components_Tooltip, {
34993
35442
  isSticky: shouldShowDropdown,
34994
35443
  content: shouldShowDropdown ? dropdownContent : label,
34995
- tight: shouldShowDropdown
35444
+ tight: shouldShowDropdown,
35445
+ className: toolTipClassNameToUse,
35446
+ isDisabled: disableToolTip
34996
35447
  }, /*#__PURE__*/react.createElement(components_IconButton, ToolbarButton_extends({
34997
- variant: isActive ? 'contained' : 'text',
34998
- bgColor: bgClasses[type],
34999
- size: "toolbar",
35000
- className: classnames_default()(activeClass, classes[type], className),
35448
+ size: sizeToUse,
35449
+ className: className,
35001
35450
  onClick: () => {
35002
35451
  onInteraction({
35003
35452
  itemId: id,
35004
- interactionType: type,
35005
35453
  commands
35006
35454
  });
35007
35455
  },
@@ -35011,25 +35459,21 @@ const ToolbarButton = ({
35011
35459
  }, rest), iconEl)));
35012
35460
  };
35013
35461
  ToolbarButton.defaultProps = {
35014
- dropdownContent: null,
35015
- isActive: false,
35016
- type: 'action'
35462
+ dropdownContent: null
35017
35463
  };
35018
35464
  ToolbarButton.propTypes = {
35019
35465
  /* Influences background/hover styling */
35020
- type: prop_types_default().oneOf(['action', 'toggle', 'tool']),
35021
35466
  id: (prop_types_default()).string.isRequired,
35022
- isActive: (prop_types_default()).bool,
35023
35467
  className: (prop_types_default()).string,
35024
- commands: prop_types_default().arrayOf(prop_types_default().shape({
35025
- commandName: (prop_types_default()).string.isRequired,
35026
- commandOptions: (prop_types_default()).object
35027
- })),
35028
- onInteraction: (prop_types_default()).func.isRequired,
35468
+ commands: prop_types_default().oneOfType([(prop_types_default()).array, (prop_types_default()).object, (prop_types_default()).string]),
35469
+ onInteraction: (prop_types_default()).func,
35029
35470
  icon: (prop_types_default()).string.isRequired,
35030
35471
  label: (prop_types_default()).string.isRequired,
35031
35472
  /** Tooltip content can be replaced for a customized content by passing a node to this value. */
35032
- dropdownContent: prop_types_default().oneOfType([(prop_types_default()).node, (prop_types_default()).func])
35473
+ dropdownContent: prop_types_default().oneOfType([(prop_types_default()).node, (prop_types_default()).func]),
35474
+ size: (prop_types_default()).string,
35475
+ toolTipClassName: (prop_types_default()).string,
35476
+ disableToolTip: (prop_types_default()).bool
35033
35477
  };
35034
35478
  /* harmony default export */ const ToolbarButton_ToolbarButton = (ToolbarButton);
35035
35479
  ;// CONCATENATED MODULE: ../../ui/src/components/ToolbarButton/index.js
@@ -36329,6 +36773,7 @@ UserPreferences.defaultProps = {
36329
36773
 
36330
36774
  /* harmony default export */ const components_UserPreferences = (UserPreferences_UserPreferences);
36331
36775
  ;// CONCATENATED MODULE: ../../ui/src/components/Header/Header.tsx
36776
+ function Header_extends() { Header_extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return Header_extends.apply(this, arguments); }
36332
36777
 
36333
36778
 
36334
36779
 
@@ -36358,13 +36803,12 @@ function Header_Header({
36358
36803
  onClickReturnButton();
36359
36804
  }
36360
36805
  };
36361
- return /*#__PURE__*/react.createElement(components_NavBar, {
36362
- className: "justify-between border-b-4 border-black",
36806
+ return /*#__PURE__*/react.createElement(components_NavBar, Header_extends({
36363
36807
  isSticky: isSticky
36808
+ }, props), /*#__PURE__*/react.createElement("div", {
36809
+ className: "relative h-[48px] items-center "
36364
36810
  }, /*#__PURE__*/react.createElement("div", {
36365
- className: "flex flex-1 justify-between"
36366
- }, /*#__PURE__*/react.createElement("div", {
36367
- className: "flex items-center"
36811
+ className: "absolute left-0 top-1/2 -translate-y-1/2 "
36368
36812
  }, /*#__PURE__*/react.createElement("div", {
36369
36813
  className: classnames_default()('mr-3 inline-flex items-center', isReturnEnabled && 'cursor-pointer'),
36370
36814
  onClick: onClickReturn,
@@ -36377,9 +36821,11 @@ function Header_Header({
36377
36821
  }, WhiteLabeling?.createLogoComponentFn?.(react, props) || /*#__PURE__*/react.createElement(components_Svg, {
36378
36822
  name: "logo-ohif"
36379
36823
  })))), /*#__PURE__*/react.createElement("div", {
36380
- className: "flex items-center"
36381
- }, children), /*#__PURE__*/react.createElement("div", {
36382
- className: "flex items-center"
36824
+ className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform"
36825
+ }, /*#__PURE__*/react.createElement("div", {
36826
+ className: "flex items-center justify-center space-x-2"
36827
+ }, children)), /*#__PURE__*/react.createElement("div", {
36828
+ className: "absolute right-0 top-1/2 -translate-y-1/2 "
36383
36829
  }, /*#__PURE__*/react.createElement(Dropdown_Dropdown, {
36384
36830
  id: "options",
36385
36831
  showDropdownIcon: false,
@@ -36516,11 +36962,11 @@ const ViewportOverlay = ({
36516
36962
  topRight,
36517
36963
  bottomRight,
36518
36964
  bottomLeft,
36519
- color
36965
+ color = 'text-primary-light'
36520
36966
  }) => {
36521
36967
  const overlay = 'absolute pointer-events-none viewport-overlay';
36522
36968
  return /*#__PURE__*/react.createElement("div", {
36523
- className: classnames_default()(color ? color : 'text-primary-light')
36969
+ className: color
36524
36970
  }, /*#__PURE__*/react.createElement("div", {
36525
36971
  "data-cy": 'viewport-overlay-top-left',
36526
36972
  className: classnames_default()(overlay, ViewportOverlay_classes.topLeft)
@@ -49480,7 +49926,8 @@ PanelSection.propTypes = {
49480
49926
  const SETTING_TYPES = {
49481
49927
  RANGE: 'range',
49482
49928
  RADIO: 'radio',
49483
- CUSTOM: 'custom'
49929
+ CUSTOM: 'custom',
49930
+ DOUBLE_RANGE: 'double-range'
49484
49931
  };
49485
49932
  function ToolSettings({
49486
49933
  options
@@ -49488,68 +49935,103 @@ function ToolSettings({
49488
49935
  if (!options) {
49489
49936
  return null;
49490
49937
  }
49491
- const getButtons = option => {
49492
- const buttons = [];
49493
- option.values?.map(({
49494
- label,
49495
- value: optionValue
49496
- }, index) => {
49497
- buttons.push({
49498
- children: label,
49499
- onClick: () => option.onChange(optionValue),
49500
- key: `button-${option.id}-${index}` // A unique key
49501
- });
49502
- });
49503
- return buttons;
49504
- };
49505
49938
  return /*#__PURE__*/react.createElement("div", {
49506
49939
  className: "space-y-2 py-2 text-white"
49507
49940
  }, options?.map(option => {
49508
- if (option.type === SETTING_TYPES.RANGE) {
49509
- return /*#__PURE__*/react.createElement("div", {
49510
- className: "flex items-center",
49511
- key: option.id
49512
- }, /*#__PURE__*/react.createElement("div", {
49513
- className: "w-1/3 text-[13px]"
49514
- }, option.name), /*#__PURE__*/react.createElement("div", {
49515
- className: "w-2/3"
49516
- }, /*#__PURE__*/react.createElement(components_InputRange, {
49517
- minValue: option.min,
49518
- maxValue: option.max,
49519
- step: option.step,
49520
- value: option.value,
49521
- onChange: e => option.onChange(e),
49522
- allowNumberEdit: true,
49523
- showAdjustmentArrows: false,
49524
- inputClassName: "ml-1 w-4/5 cursor-pointer"
49525
- })));
49526
- }
49527
- if (option.type === SETTING_TYPES.RADIO) {
49528
- return /*#__PURE__*/react.createElement("div", {
49529
- className: "flex items-center justify-between text-[13px]",
49530
- key: option.id
49531
- }, /*#__PURE__*/react.createElement("span", null, option.name), /*#__PURE__*/react.createElement("div", {
49532
- className: "max-w-1/2"
49533
- }, /*#__PURE__*/react.createElement(components_ButtonGroup, {
49534
- buttons: getButtons(option),
49535
- defaultActiveIndex: option.defaultActiveIndex,
49536
- size: size.small
49537
- })));
49941
+ if (option.condition && option.condition?.({
49942
+ options
49943
+ }) === false) {
49944
+ return null;
49538
49945
  }
49539
- if (option.type === SETTING_TYPES.CUSTOM) {
49540
- return /*#__PURE__*/react.createElement("div", {
49541
- key: option.id
49542
- }, typeof option.children === 'function' ? option.children() : option.children);
49946
+ switch (option.type) {
49947
+ case SETTING_TYPES.RANGE:
49948
+ return renderRangeSetting(option);
49949
+ case SETTING_TYPES.RADIO:
49950
+ return renderRadioSetting(option);
49951
+ case SETTING_TYPES.DOUBLE_RANGE:
49952
+ return renderDoubleRangeSetting(option);
49953
+ case SETTING_TYPES.CUSTOM:
49954
+ return renderCustomSetting(option);
49955
+ default:
49956
+ return null;
49543
49957
  }
49544
49958
  }));
49545
49959
  }
49960
+ const renderRangeSetting = option => {
49961
+ return /*#__PURE__*/react.createElement("div", {
49962
+ className: "flex items-center",
49963
+ key: option.id
49964
+ }, /*#__PURE__*/react.createElement("div", {
49965
+ className: "w-1/3 text-[13px]"
49966
+ }, option.name), /*#__PURE__*/react.createElement("div", {
49967
+ className: "w-2/3"
49968
+ }, /*#__PURE__*/react.createElement(components_InputRange, {
49969
+ minValue: option.min,
49970
+ maxValue: option.max,
49971
+ step: option.step,
49972
+ value: option.value,
49973
+ onChange: value => option.commands?.(value),
49974
+ allowNumberEdit: true,
49975
+ showAdjustmentArrows: false,
49976
+ inputClassName: "ml-1 w-4/5 cursor-pointer"
49977
+ })));
49978
+ };
49979
+ const renderRadioSetting = option => {
49980
+ const renderButtons = option => {
49981
+ return option.values?.map(({
49982
+ label,
49983
+ value: optionValue
49984
+ }, index) => /*#__PURE__*/react.createElement("button", {
49985
+ onClick: () => {
49986
+ option.commands?.(optionValue);
49987
+ },
49988
+ key: `button-${option.id}-${index}`
49989
+ }, label));
49990
+ };
49991
+ return /*#__PURE__*/react.createElement("div", {
49992
+ className: "flex items-center justify-between text-[13px]",
49993
+ key: option.id
49994
+ }, /*#__PURE__*/react.createElement("span", null, option.name), /*#__PURE__*/react.createElement("div", {
49995
+ className: "max-w-1/2"
49996
+ }, /*#__PURE__*/react.createElement(components_ButtonGroup, {
49997
+ activeIndex: option.values.findIndex(({
49998
+ value
49999
+ }) => value === option.value) || 0
50000
+ }, renderButtons(option))));
50001
+ };
50002
+ const renderDoubleRangeSetting = option => {
50003
+ return /*#__PURE__*/react.createElement("div", {
50004
+ className: "flex w-full items-center",
50005
+ key: option.id
50006
+ }, /*#__PURE__*/react.createElement(components_InputDoubleRange, {
50007
+ values: option.values,
50008
+ onChange: option.commands,
50009
+ minValue: option.min,
50010
+ maxValue: option.max,
50011
+ step: option.step,
50012
+ showLabel: true,
50013
+ allowNumberEdit: true,
50014
+ showAdjustmentArrows: false,
50015
+ containerClassName: "w-full"
50016
+ }));
50017
+ };
50018
+ const renderCustomSetting = option => {
50019
+ return /*#__PURE__*/react.createElement("div", {
50020
+ key: option.id
50021
+ }, typeof option.children === 'function' ? option.children() : option.children);
50022
+ };
49546
50023
  /* harmony default export */ const AdvancedToolbox_ToolSettings = (ToolSettings);
49547
50024
  ;// CONCATENATED MODULE: ../../ui/src/components/AdvancedToolbox/AdvancedToolbox.tsx
49548
50025
 
49549
50026
 
49550
50027
 
49551
50028
 
49552
- const AdvancedToolbox = ({
50029
+
50030
+ /**
50031
+ * Use Toolbox component instead of this although it doesn't have "Advanced" in its name
50032
+ * it is better to use it instead of this one
50033
+ */
50034
+ const AdvancedToolbox_AdvancedToolbox = ({
49553
50035
  title,
49554
50036
  items
49555
50037
  }) => {
@@ -49593,11 +50075,13 @@ const AdvancedToolbox = ({
49593
50075
  options: activeItemOptions
49594
50076
  }))));
49595
50077
  };
49596
- AdvancedToolbox.propTypes = {};
49597
- /* harmony default export */ const AdvancedToolbox_AdvancedToolbox = (AdvancedToolbox);
50078
+ AdvancedToolbox_AdvancedToolbox.propTypes = {};
50079
+ /* harmony default export */ const components_AdvancedToolbox_AdvancedToolbox = ((/* unused pure expression or super */ null && (AdvancedToolbox_AdvancedToolbox)));
49598
50080
  ;// CONCATENATED MODULE: ../../ui/src/components/AdvancedToolbox/index.js
49599
50081
 
49600
- /* harmony default export */ const components_AdvancedToolbox = (AdvancedToolbox_AdvancedToolbox);
50082
+
50083
+ /* harmony default export */ const components_AdvancedToolbox = ((/* unused pure expression or super */ null && (AdvancedToolbox)));
50084
+
49601
50085
  ;// CONCATENATED MODULE: ../../ui/src/components/InputDoubleRange/InputDoubleRange.css
49602
50086
  // extracted by mini-css-extract-plugin
49603
50087
 
@@ -49772,6 +50256,373 @@ InputDoubleRange.defaultProps = {
49772
50256
  ;// CONCATENATED MODULE: ../../ui/src/components/InputDoubleRange/index.js
49773
50257
 
49774
50258
  /* harmony default export */ const components_InputDoubleRange = (InputDoubleRange_InputDoubleRange);
50259
+ ;// CONCATENATED MODULE: ../../ui/src/components/LegacySplitButton/LegacySplitButton.tsx
50260
+ function LegacySplitButton_extends() { LegacySplitButton_extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return LegacySplitButton_extends.apply(this, arguments); }
50261
+
50262
+
50263
+
50264
+
50265
+
50266
+
50267
+
50268
+
50269
+ const LegacySplitButton_baseClasses = {
50270
+ Button: 'flex items-center rounded-md border-transparent cursor-pointer group/button',
50271
+ Primary:
50272
+ // By default border on left, top and bottom for hover effect and only rounded on left side.
50273
+ // Extra padding on right to compensate for no right border.
50274
+ 'h-full border-l-2 border-t-2 border-b-2 rounded-tl-md rounded-bl-md group/primary !pl-2 !py-2',
50275
+ Secondary: 'h-full flex items-center justify-center rounded-tr-md rounded-br-md w-4 border-2 border-transparent group/secondary',
50276
+ SecondaryIcon: 'w-4 h-full stroke-1',
50277
+ Separator: 'border-l py-2.5',
50278
+ Content: 'absolute z-10 top-0 mt-12'
50279
+ };
50280
+ const LegacySplitButton_classes = {
50281
+ Button: ({
50282
+ isExpanded,
50283
+ primary
50284
+ }) => classnames_default()(LegacySplitButton_baseClasses.Button, !isExpanded && !primary.isActive && 'hover:!bg-primary-dark hover:border-primary-dark'),
50285
+ Interface: 'h-full flex flex-row items-center',
50286
+ Primary: ({
50287
+ isActive,
50288
+ isExpanded
50289
+ }) => classnames_default()(LegacySplitButton_baseClasses.Primary, isActive ? isExpanded ? 'border-primary-dark !bg-primary-dark hover:border-primary-dark !text-primary-light' : 'border-primary-light bg-primary-light border-2 rounded-md !p-2' : `focus:!text-black focus:!rounded-md focus:!border-primary-light focus:!bg-primary-light
50290
+ ${isExpanded ? 'border-primary-dark bg-primary-dark !text-primary-light' : 'border-secondary-dark bg-secondary-dark group-hover/button:border-primary-dark group-hover/button:text-primary-light hover:!bg-primary-dark hover:border-primary-dark focus:!text-black'}
50291
+ `),
50292
+ Secondary: ({
50293
+ isExpanded,
50294
+ primary
50295
+ }) => classnames_default()(LegacySplitButton_baseClasses.Secondary, isExpanded ? 'bg-primary-light !rounded-tr-md !rounded-br-md' : primary.isActive ? 'bg-secondary-dark' : 'hover:bg-primary-dark bg-secondary-dark group-hover/button:border-primary-dark'),
50296
+ SecondaryIcon: ({
50297
+ isExpanded
50298
+ }) => classnames_default()(LegacySplitButton_baseClasses.SecondaryIcon, isExpanded ? 'text-primary-dark' : 'text-primary-active group-hover/secondary:text-primary-light'),
50299
+ Separator: ({
50300
+ primary,
50301
+ isExpanded,
50302
+ isHovering
50303
+ }) => classnames_default()(LegacySplitButton_baseClasses.Separator, isHovering || isExpanded || primary.isActive ? 'border-transparent' : 'border-primary-active'),
50304
+ Content: ({
50305
+ isExpanded
50306
+ }) => classnames_default()(LegacySplitButton_baseClasses.Content, isExpanded ? 'block' : 'hidden')
50307
+ };
50308
+ const LegacySplitButton_SplitButton = ({
50309
+ groupId,
50310
+ primary,
50311
+ secondary,
50312
+ items,
50313
+ renderer,
50314
+ onInteraction,
50315
+ Component,
50316
+ isActive
50317
+ }) => {
50318
+ const {
50319
+ t
50320
+ } = (0,es/* useTranslation */.Bd)('Buttons');
50321
+ const [state, setState] = (0,react.useState)({
50322
+ isHovering: false,
50323
+ isExpanded: false
50324
+ });
50325
+ const toggleExpanded = () => setState({
50326
+ ...state,
50327
+ isExpanded: !state.isExpanded
50328
+ });
50329
+ const setHover = hovering => setState({
50330
+ ...state,
50331
+ isHovering: hovering
50332
+ });
50333
+ const collapse = () => setState({
50334
+ ...state,
50335
+ isExpanded: false
50336
+ });
50337
+ const renderPrimaryButton = () => /*#__PURE__*/react.createElement(Component, LegacySplitButton_extends({
50338
+ key: primary.id
50339
+ }, primary, {
50340
+ isActive: isActive,
50341
+ onInteraction: onInteraction,
50342
+ rounded: "none",
50343
+ className: LegacySplitButton_classes.Primary({
50344
+ isActive,
50345
+ isExpanded: state.isExpanded
50346
+ }),
50347
+ "data-tool": primary.id,
50348
+ "data-cy": `${groupId}-split-button-primary`
50349
+ }));
50350
+ return /*#__PURE__*/react.createElement(react_outside_click_handler["default"], {
50351
+ onOutsideClick: collapse,
50352
+ disabled: !state.isExpanded
50353
+ }, /*#__PURE__*/react.createElement("div", {
50354
+ id: "SplitButton",
50355
+ className: "relative"
50356
+ }, /*#__PURE__*/react.createElement("div", {
50357
+ className: LegacySplitButton_classes.Button({
50358
+ ...state,
50359
+ primary: {
50360
+ isActive
50361
+ }
50362
+ }),
50363
+ style: {
50364
+ height: '40px'
50365
+ },
50366
+ onMouseEnter: () => setHover(true),
50367
+ onMouseLeave: () => setHover(false)
50368
+ }, /*#__PURE__*/react.createElement("div", {
50369
+ className: LegacySplitButton_classes.Interface
50370
+ }, /*#__PURE__*/react.createElement("div", {
50371
+ onClick: collapse
50372
+ }, renderPrimaryButton()), /*#__PURE__*/react.createElement("div", {
50373
+ className: LegacySplitButton_classes.Separator({
50374
+ ...state,
50375
+ primary: {
50376
+ isActive
50377
+ }
50378
+ })
50379
+ }), /*#__PURE__*/react.createElement("div", {
50380
+ className: LegacySplitButton_classes.Secondary({
50381
+ ...state,
50382
+ primary: {
50383
+ isActive
50384
+ }
50385
+ }),
50386
+ onClick: toggleExpanded,
50387
+ "data-cy": `${groupId}-split-button-secondary`
50388
+ }, /*#__PURE__*/react.createElement(components_Tooltip, {
50389
+ isDisabled: state.isExpanded || !secondary.tooltip,
50390
+ content: secondary.tooltip,
50391
+ className: "h-full"
50392
+ }, /*#__PURE__*/react.createElement(Icon/* default */.A, {
50393
+ name: secondary.icon,
50394
+ className: LegacySplitButton_classes.SecondaryIcon({
50395
+ ...state
50396
+ })
50397
+ }))))), /*#__PURE__*/react.createElement("div", {
50398
+ className: LegacySplitButton_classes.Content({
50399
+ ...state
50400
+ }),
50401
+ "data-cy": `${groupId}-list-menu`
50402
+ }, /*#__PURE__*/react.createElement(components_ListMenu, {
50403
+ items: items,
50404
+ onClick: collapse,
50405
+ renderer: args => renderer({
50406
+ ...args,
50407
+ t
50408
+ })
50409
+ }))));
50410
+ };
50411
+ LegacySplitButton_SplitButton.propTypes = {
50412
+ isToggle: (prop_types_default()).bool,
50413
+ groupId: (prop_types_default()).string.isRequired,
50414
+ primary: (prop_types_default()).object.isRequired,
50415
+ secondary: (prop_types_default()).object.isRequired,
50416
+ items: (prop_types_default()).array.isRequired,
50417
+ renderer: (prop_types_default()).func,
50418
+ isActive: (prop_types_default()).bool,
50419
+ onInteraction: (prop_types_default()).func.isRequired,
50420
+ Component: (prop_types_default()).elementType
50421
+ };
50422
+ LegacySplitButton_SplitButton.defaultProps = {
50423
+ isToggle: false,
50424
+ renderer: null,
50425
+ isActive: false,
50426
+ Component: null
50427
+ };
50428
+ /* harmony default export */ const LegacySplitButton_LegacySplitButton = ((/* unused pure expression or super */ null && (LegacySplitButton_SplitButton)));
50429
+ ;// CONCATENATED MODULE: ../../ui/src/components/LegacySplitButton/index.js
50430
+
50431
+ /* harmony default export */ const components_LegacySplitButton = ((/* unused pure expression or super */ null && (LegacySplitButton)));
50432
+ ;// CONCATENATED MODULE: ../../ui/src/components/Toolbox/ToolboxUI.tsx
50433
+ function ToolboxUI_extends() { ToolboxUI_extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return ToolboxUI_extends.apply(this, arguments); }
50434
+
50435
+
50436
+
50437
+ const ItemsPerRow = 4;
50438
+
50439
+ /**
50440
+ * Just refactoring from the toolbox component to make it more readable
50441
+ */
50442
+ function ToolboxUI(props) {
50443
+ const {
50444
+ toolbarButtons,
50445
+ handleToolSelect,
50446
+ activeToolOptions,
50447
+ numRows,
50448
+ servicesManager,
50449
+ title,
50450
+ useCollapsedPanel = true
50451
+ } = props;
50452
+ const render = () => {
50453
+ return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
50454
+ className: "flex flex-col bg-black"
50455
+ }, /*#__PURE__*/react.createElement("div", {
50456
+ className: "bg-primary-dark mt-0.5 flex flex-wrap py-2"
50457
+ }, toolbarButtons.map((toolDef, index) => {
50458
+ if (!toolDef) {
50459
+ return null;
50460
+ }
50461
+ const {
50462
+ id,
50463
+ Component,
50464
+ componentProps
50465
+ } = toolDef;
50466
+ const isLastRow = Math.floor(index / ItemsPerRow) + 1 === numRows;
50467
+ const toolClasses = `ml-1 ${isLastRow ? '' : 'mb-2'}`;
50468
+ const onInteraction = ({
50469
+ itemId,
50470
+ id,
50471
+ commands
50472
+ }) => {
50473
+ handleToolSelect(itemId || id);
50474
+ props.onInteraction({
50475
+ itemId,
50476
+ commands
50477
+ });
50478
+ };
50479
+ return /*#__PURE__*/react.createElement("div", {
50480
+ key: id,
50481
+ className: classnames_default()({
50482
+ [toolClasses]: true,
50483
+ 'flex flex-col items-center justify-center': true
50484
+ })
50485
+ }, componentProps.disabled ? /*#__PURE__*/react.createElement(components_Tooltip, {
50486
+ position: "bottom",
50487
+ content: componentProps.label,
50488
+ secondaryContent: 'Not available on the current viewport'
50489
+ }, /*#__PURE__*/react.createElement(Component, ToolboxUI_extends({}, componentProps, props, {
50490
+ id: id,
50491
+ servicesManager: servicesManager,
50492
+ onInteraction: onInteraction,
50493
+ size: "toolbox"
50494
+ }))) : /*#__PURE__*/react.createElement(Component, ToolboxUI_extends({}, componentProps, props, {
50495
+ id: id,
50496
+ servicesManager: servicesManager,
50497
+ onInteraction: onInteraction,
50498
+ size: "toolbox"
50499
+ })));
50500
+ }))), /*#__PURE__*/react.createElement("div", {
50501
+ className: "bg-primary-dark h-auto px-2"
50502
+ }, activeToolOptions && /*#__PURE__*/react.createElement(AdvancedToolbox_ToolSettings, {
50503
+ options: activeToolOptions
50504
+ })));
50505
+ };
50506
+ return useCollapsedPanel ? /*#__PURE__*/react.createElement(components_PanelSection, {
50507
+ title: title
50508
+ }, render()) : render();
50509
+ }
50510
+
50511
+ ;// CONCATENATED MODULE: ../../ui/src/components/Toolbox/Toolbox.tsx
50512
+ function Toolbox_extends() { Toolbox_extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return Toolbox_extends.apply(this, arguments); }
50513
+
50514
+
50515
+
50516
+
50517
+
50518
+ /**
50519
+ * A toolbox is a collection of buttons and commands that they invoke, used to provide
50520
+ * custom control panels to users. This component is a generic UI component that
50521
+ * interacts with services and commands in a generic fashion. While it might
50522
+ * seem unconventional to import it from the UI and integrate it into the JSX,
50523
+ * it belongs in the UI components as there isn't anything in this component that
50524
+ * couldn't be used for a completely different type of app. It plays a crucial
50525
+ * role in enhancing the app with a toolbox by providing a way to integrate
50526
+ * and display various tools and their corresponding options
50527
+ */
50528
+ function Toolbox({
50529
+ servicesManager,
50530
+ buttonSectionId,
50531
+ commandsManager,
50532
+ title,
50533
+ ...props
50534
+ }) {
50535
+ const {
50536
+ state: toolboxState,
50537
+ api
50538
+ } = useToolbox(buttonSectionId);
50539
+ const {
50540
+ onInteraction,
50541
+ toolbarButtons
50542
+ } = (0,src/* useToolbar */.tR)({
50543
+ servicesManager,
50544
+ buttonSection: buttonSectionId
50545
+ });
50546
+ const prevButtonIdsRef = (0,react.useRef)();
50547
+ (0,react.useEffect)(() => {
50548
+ const currentButtonIdsStr = JSON.stringify(toolbarButtons.map(button => {
50549
+ const {
50550
+ id,
50551
+ componentProps
50552
+ } = button;
50553
+ if (componentProps.items?.length) {
50554
+ return componentProps.items.map(item => `${item.id}-${item.disabled}`);
50555
+ }
50556
+ return `${id}-${componentProps.disabled}`;
50557
+ }));
50558
+ if (prevButtonIdsRef.current === currentButtonIdsStr) {
50559
+ return;
50560
+ }
50561
+ prevButtonIdsRef.current = currentButtonIdsStr;
50562
+ const initializeOptionsWithEnhancements = toolbarButtons.reduce((accumulator, toolbarButton) => {
50563
+ const {
50564
+ id: buttonId,
50565
+ componentProps
50566
+ } = toolbarButton;
50567
+ const createEnhancedOptions = (options, parentId) => options.map(option => {
50568
+ return {
50569
+ ...option,
50570
+ value: toolboxState.toolOptions?.[parentId]?.find(prop => prop.id === option.id)?.value ?? option.value,
50571
+ commands: value => {
50572
+ api.handleToolOptionChange(parentId, option.id, value);
50573
+ const {
50574
+ isArray
50575
+ } = Array;
50576
+ const cmds = isArray(option.commands) ? option.commands : [option.commands];
50577
+ cmds.forEach(command => {
50578
+ const isString = typeof command === 'string';
50579
+ const isObject = typeof command === 'object';
50580
+ if (isString) {
50581
+ commandsManager.run(command, {
50582
+ value
50583
+ });
50584
+ } else if (isObject) {
50585
+ commandsManager.run({
50586
+ ...command,
50587
+ commandOptions: {
50588
+ ...command.commandOptions,
50589
+ ...option,
50590
+ value
50591
+ }
50592
+ });
50593
+ }
50594
+ });
50595
+ }
50596
+ };
50597
+ });
50598
+ if (componentProps.items?.length) {
50599
+ componentProps.items.forEach(item => {
50600
+ accumulator[item.id] = createEnhancedOptions(item.options, item.id);
50601
+ });
50602
+ } else if (componentProps.options?.length) {
50603
+ accumulator[buttonId] = createEnhancedOptions(componentProps.options, buttonId);
50604
+ }
50605
+ return accumulator;
50606
+ }, {});
50607
+ api.initializeToolOptions(initializeOptionsWithEnhancements);
50608
+ }, [toolbarButtons, api]);
50609
+ const handleToolOptionChange = (toolName, optionName, newValue) => {
50610
+ api.handleToolOptionChange(toolName, optionName, newValue);
50611
+ };
50612
+ return /*#__PURE__*/react.createElement(ToolboxUI, Toolbox_extends({}, props, {
50613
+ title: title,
50614
+ toolbarButtons: toolbarButtons,
50615
+ activeToolOptions: toolboxState.toolOptions?.[toolboxState.activeTool],
50616
+ handleToolSelect: id => api.handleToolSelect(id),
50617
+ handleToolOptionChange: handleToolOptionChange,
50618
+ onInteraction: onInteraction
50619
+ }));
50620
+ }
50621
+ /* harmony default export */ const Toolbox_Toolbox = (Toolbox);
50622
+ ;// CONCATENATED MODULE: ../../ui/src/components/Toolbox/index.js
50623
+
50624
+
50625
+
49775
50626
  ;// CONCATENATED MODULE: ../../ui/src/components/InvestigationalUseDialog/InvestigationalUseDialog.tsx
49776
50627
 
49777
50628
 
@@ -49875,6 +50726,45 @@ InvestigationalUseDialog.defaultProps = {
49875
50726
  ;// CONCATENATED MODULE: ../../ui/src/components/InvestigationalUseDialog/index.js
49876
50727
 
49877
50728
  /* harmony default export */ const components_InvestigationalUseDialog = (InvestigationalUseDialog_InvestigationalUseDialog);
50729
+ // EXTERNAL MODULE: ../../ui/src/components/Icon/Icon.tsx
50730
+ var Icon_Icon = __webpack_require__(66348);
50731
+ ;// CONCATENATED MODULE: ../../ui/src/components/LayoutPreset/LayoutPreset.tsx
50732
+
50733
+
50734
+
50735
+ function LayoutPreset({
50736
+ onSelection,
50737
+ title,
50738
+ icon,
50739
+ commandOptions,
50740
+ classNames
50741
+ }) {
50742
+ return /*#__PURE__*/react.createElement("div", {
50743
+ className: classNames,
50744
+ onClick: () => {
50745
+ onSelection(commandOptions);
50746
+ }
50747
+ }, /*#__PURE__*/react.createElement(Icon_Icon/* default */.A, {
50748
+ name: icon,
50749
+ className: "group-hover:text-primary-light"
50750
+ }), title && /*#__PURE__*/react.createElement("div", {
50751
+ className: "font-inter text-sm text-white"
50752
+ }, title));
50753
+ }
50754
+ LayoutPreset.defaultProps = {
50755
+ onSelection: () => {}
50756
+ };
50757
+ LayoutPreset.propTypes = {
50758
+ onSelection: (prop_types_default()).func.isRequired,
50759
+ title: (prop_types_default()).string,
50760
+ icon: (prop_types_default()).string.isRequired,
50761
+ commandOptions: (prop_types_default()).object.isRequired,
50762
+ classNames: (prop_types_default()).string
50763
+ };
50764
+ /* harmony default export */ const LayoutPreset_LayoutPreset = (LayoutPreset);
50765
+ ;// CONCATENATED MODULE: ../../ui/src/components/LayoutPreset/index.js
50766
+
50767
+ /* harmony default export */ const components_LayoutPreset = (LayoutPreset_LayoutPreset);
49878
50768
  ;// CONCATENATED MODULE: ../../ui/src/components/index.js
49879
50769
 
49880
50770
 
@@ -49955,6 +50845,10 @@ InvestigationalUseDialog.defaultProps = {
49955
50845
 
49956
50846
 
49957
50847
 
50848
+
50849
+
50850
+
50851
+
49958
50852
 
49959
50853
 
49960
50854
 
@@ -50011,12 +50905,6 @@ ModalComponent.propTypes = {
50011
50905
  };
50012
50906
  /* harmony default export */ const contextProviders_ModalComponent = ((/* unused pure expression or super */ null && (ModalComponent)));
50013
50907
  ;// CONCATENATED MODULE: ../../ui/src/index.js
50014
- /** UTILS */
50015
- //import utils from './utils';
50016
- //export { utils };
50017
-
50018
- /** CONTEXT/HOOKS */
50019
- // Export types - need to do as two lines due to a bug in babel
50020
50908
 
50021
50909
 
50022
50910
 
@@ -50173,7 +51061,7 @@ function _getImageOrientationPatient(image) {
50173
51061
 
50174
51062
  /***/ }),
50175
51063
 
50176
- /***/ 14283:
51064
+ /***/ 78198:
50177
51065
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
50178
51066
 
50179
51067
  "use strict";
@@ -50199,7 +51087,7 @@ __webpack_require__.d(__webpack_exports__, {
50199
51087
  Rc: () => (/* reexport */ pubSubServiceInterface/* PubSubService */.R),
50200
51088
  CS: () => (/* reexport */ ServicesManager),
50201
51089
  wb: () => (/* reexport */ services_StateSyncService),
50202
- hx: () => (/* reexport */ ToolBarService),
51090
+ ToolbarService: () => (/* reexport */ ToolBarService),
50203
51091
  u$: () => (/* reexport */ UIDialogService),
50204
51092
  zo: () => (/* reexport */ services_UIModalService),
50205
51093
  v4: () => (/* reexport */ services_UINotificationService),
@@ -50213,6 +51101,7 @@ __webpack_require__.d(__webpack_exports__, {
50213
51101
  ot: () => (/* binding */ hotkeys),
50214
51102
  Rm: () => (/* reexport */ src_log),
50215
51103
  Ml: () => (/* reexport */ pubSubServiceInterface/* default */.A),
51104
+ tR: () => (/* reexport */ useToolbar),
50216
51105
  utils: () => (/* reexport */ utils/* default */.Ay)
50217
51106
  });
50218
51107
 
@@ -50354,7 +51243,7 @@ class MeasurementService extends pubSubServiceInterface/* PubSubService */.R {
50354
51243
  super(EVENTS);
50355
51244
  this.VALUE_TYPES = VALUE_TYPES;
50356
51245
  this.measurements = new Map();
50357
- this.unmappedMeasurements = new Set();
51246
+ this.unmappedMeasurements = new Map();
50358
51247
  /**
50359
51248
  * Check if a given measurement service event is valid.
50360
51249
  *
@@ -50696,7 +51585,15 @@ class MeasurementService extends pubSubServiceInterface/* PubSubService */.R {
50696
51585
  measurement = toMeasurementSchema(sourceAnnotationDetail);
50697
51586
  measurement.source = source;
50698
51587
  } catch (error) {
50699
- this.unmappedMeasurements.add(sourceAnnotationDetail.uid);
51588
+ // Todo: handle other
51589
+ this.unmappedMeasurements.set(sourceAnnotationDetail.uid, {
51590
+ ...sourceAnnotationDetail,
51591
+ source: {
51592
+ name: source.name,
51593
+ version: source.version,
51594
+ uid: source.uid
51595
+ }
51596
+ });
50700
51597
  console.log('Failed to map', error);
50701
51598
  throw new Error(`Failed to map '${sourceInfo}' measurement for annotationType ${annotationType}: ${error.message}`);
50702
51599
  }
@@ -50761,10 +51658,9 @@ class MeasurementService extends pubSubServiceInterface/* PubSubService */.R {
50761
51658
  });
50762
51659
  }
50763
51660
  clearMeasurements() {
50764
- this.unmappedMeasurements.clear();
50765
-
50766
51661
  // Make a copy of the measurements
50767
- const measurements = [...this.measurements.values()];
51662
+ const measurements = [...this.measurements.values(), ...this.unmappedMeasurements.values()];
51663
+ this.unmappedMeasurements.clear();
50768
51664
  this.measurements.clear();
50769
51665
  this._broadcastEvent(this.EVENTS.MEASUREMENTS_CLEARED, {
50770
51666
  measurements
@@ -50913,10 +51809,16 @@ MeasurementService.VALUE_TYPES = VALUE_TYPES;
50913
51809
  class ServicesManager {
50914
51810
  constructor(commandsManager) {
50915
51811
  this.services = {};
51812
+ this.registeredServiceNames = [];
51813
+ this._commandsManager = void 0;
51814
+ this._extensionManager = void 0;
50916
51815
  this._commandsManager = commandsManager;
50917
51816
  this.services = {};
50918
51817
  this.registeredServiceNames = [];
50919
51818
  }
51819
+ setExtensionManager(extensionManager) {
51820
+ this._extensionManager = extensionManager;
51821
+ }
50920
51822
 
50921
51823
  /**
50922
51824
  * Registers a new service.
@@ -50941,7 +51843,8 @@ class ServicesManager {
50941
51843
  this.services[service.name] = service.create({
50942
51844
  configuration,
50943
51845
  commandsManager: this._commandsManager,
50944
- servicesManager: this
51846
+ servicesManager: this,
51847
+ extensionManager: this._extensionManager
50945
51848
  });
50946
51849
  if (service.altName) {
50947
51850
  console.log('Registering old name', service.altName);
@@ -51814,76 +52717,174 @@ class DisplaySetMessageList {
51814
52717
 
51815
52718
  /* harmony default export */ const services_DisplaySetService = (DisplaySetService);
51816
52719
 
51817
- // EXTERNAL MODULE: ../../../node_modules/lodash.merge/index.js
51818
- var lodash_merge = __webpack_require__(40592);
51819
- var lodash_merge_default = /*#__PURE__*/__webpack_require__.n(lodash_merge);
51820
52720
  ;// CONCATENATED MODULE: ../../core/src/services/ToolBarService/ToolbarService.ts
51821
52721
  var ToolbarService_class;
51822
52722
 
51823
-
51824
52723
  const ToolbarService_EVENTS = {
51825
52724
  TOOL_BAR_MODIFIED: 'event::toolBarService:toolBarModified',
51826
52725
  TOOL_BAR_STATE_MODIFIED: 'event::toolBarService:toolBarStateModified'
51827
52726
  };
51828
52727
  class ToolbarService extends pubSubServiceInterface/* PubSubService */.R {
51829
- static _createButton(type, id, icon, label, commands, tooltip, extraOptions) {
51830
- return {
52728
+ static createButton(options) {
52729
+ const {
51831
52730
  id,
51832
52731
  icon,
51833
52732
  label,
51834
- type,
51835
52733
  commands,
51836
52734
  tooltip,
51837
- ...extraOptions
52735
+ evaluate,
52736
+ listeners
52737
+ } = options;
52738
+ return {
52739
+ id,
52740
+ icon,
52741
+ label,
52742
+ commands,
52743
+ tooltip: tooltip || label,
52744
+ evaluate,
52745
+ listeners
51838
52746
  };
51839
52747
  }
51840
- constructor(commandsManager) {
52748
+ constructor(commandsManager, extensionManager, servicesManager) {
51841
52749
  super(ToolbarService_EVENTS);
51842
- this.buttons = {};
51843
52750
  this.state = {
51844
- primaryToolId: '',
51845
- toggles: {},
51846
- groups: {}
51847
- };
51848
- this.buttonSections = {
51849
- /**
51850
- * primary: ['Zoom', 'Wwwc'],
51851
- * secondary: ['Length', 'RectangleRoi']
51852
- */
52751
+ buttons: {},
52752
+ buttonSections: {}
51853
52753
  };
51854
52754
  this._commandsManager = void 0;
51855
- this.extensionManager = void 0;
51856
- this.defaultTool = void 0;
52755
+ this._extensionManager = void 0;
52756
+ this._servicesManager = void 0;
52757
+ this._evaluateFunction = {};
52758
+ this._serviceSubscriptions = [];
52759
+ this.handleEvaluateNested = props => {
52760
+ const {
52761
+ primary,
52762
+ items
52763
+ } = props;
52764
+ // handle group evaluate function
52765
+ this.handleEvaluate(props);
52766
+
52767
+ // primary and items evaluate functions
52768
+ if (primary) {
52769
+ this.handleEvaluate(primary);
52770
+ }
52771
+ items.forEach(item => this.handleEvaluate(item));
52772
+ };
52773
+ this.handleEvaluate = props => {
52774
+ const {
52775
+ evaluate
52776
+ } = props;
52777
+ if (typeof evaluate === 'function') {
52778
+ return;
52779
+ }
52780
+ if (Array.isArray(evaluate)) {
52781
+ const evaluators = evaluate.map(evaluatorName => {
52782
+ const evaluateFunction = this._evaluateFunction[evaluatorName];
52783
+ if (!evaluateFunction) {
52784
+ throw new Error(`Evaluate function not found for name: ${evaluatorName}, you can register an evaluate function with the getToolbarModule in your extensions`);
52785
+ }
52786
+ return evaluateFunction;
52787
+ });
52788
+ props.evaluate = args => {
52789
+ const results = evaluators.map(evaluator => evaluator(args));
52790
+ const mergedResult = results.reduce((acc, result) => {
52791
+ return {
52792
+ ...acc,
52793
+ ...result
52794
+ };
52795
+ }, {});
52796
+ return mergedResult;
52797
+ };
52798
+ return;
52799
+ }
52800
+ if (typeof evaluate === 'string') {
52801
+ const evaluateFunction = this._evaluateFunction[evaluate];
52802
+ if (evaluateFunction) {
52803
+ props.evaluate = evaluateFunction;
52804
+ return;
52805
+ }
52806
+ throw new Error(`Evaluate function not found for name: ${evaluate}, you can register an evaluate function with the getToolbarModule in your extensions`);
52807
+ }
52808
+ if (typeof evaluate === 'object') {
52809
+ const {
52810
+ name,
52811
+ options
52812
+ } = evaluate;
52813
+ const evaluateFunction = this._evaluateFunction[name];
52814
+ if (evaluateFunction) {
52815
+ props.evaluate = args => evaluateFunction({
52816
+ ...args,
52817
+ ...options
52818
+ });
52819
+ return;
52820
+ }
52821
+ throw new Error(`Evaluate function not found for name: ${name}, you can register an evaluate function with the getToolbarModule in your extensions`);
52822
+ }
52823
+ };
51857
52824
  this._commandsManager = commandsManager;
51858
- }
51859
- init(extensionManager) {
51860
- this.extensionManager = extensionManager;
52825
+ this._extensionManager = extensionManager;
52826
+ this._servicesManager = servicesManager;
51861
52827
  }
51862
52828
  reset() {
51863
52829
  this.unsubscriptions.forEach(unsub => unsub());
51864
52830
  this.state = {
51865
- primaryToolId: 'WindowLevel',
51866
- toggles: {},
51867
- groups: {}
52831
+ buttons: {},
52832
+ buttonSections: {}
51868
52833
  };
51869
52834
  this.unsubscriptions = [];
51870
- this.buttonSections = {};
51871
- this.buttons = {};
51872
52835
  }
51873
52836
  onModeEnter() {
51874
52837
  this.reset();
51875
52838
  }
51876
52839
 
51877
52840
  /**
51878
- * Sets the default tool that will be activated whenever the primary tool is
51879
- * deactivated without activating another/different tool.
51880
- * @param interaction the interaction command that will set the default tool active
52841
+ * Registers an evaluate function with the specified name.
52842
+ *
52843
+ * @param name - The name of the evaluate function.
52844
+ * @param handler - The evaluate function handler.
51881
52845
  */
51882
- setDefaultTool(interaction) {
51883
- this.defaultTool = interaction;
52846
+ registerEvaluateFunction(name, handler) {
52847
+ this._evaluateFunction[name] = handler;
51884
52848
  }
51885
- getDefaultTool() {
51886
- return this.defaultTool;
52849
+
52850
+ /**
52851
+ * Registers a service and its event to listen for updates and refreshes the toolbar state when the event is triggered.
52852
+ * @param service - The service to register.
52853
+ * @param event - The event to listen for.
52854
+ */
52855
+ registerEventForToolbarUpdate(service, events) {
52856
+ const {
52857
+ viewportGridService
52858
+ } = this._servicesManager.services;
52859
+ const callback = () => {
52860
+ const viewportId = viewportGridService.getActiveViewportId();
52861
+ this.refreshToolbarState({
52862
+ viewportId
52863
+ });
52864
+ };
52865
+ const unsubscriptions = events.map(event => {
52866
+ if (service.subscribe) {
52867
+ return service.subscribe(event, callback);
52868
+ } else if (service.addEventListener) {
52869
+ return service.addEventListener(event, callback);
52870
+ }
52871
+ });
52872
+ unsubscriptions.forEach(unsub => this._serviceSubscriptions.push(unsub));
52873
+ }
52874
+
52875
+ /**
52876
+ * Adds buttons to the toolbar.
52877
+ * @param buttons - The buttons to be added.
52878
+ */
52879
+ addButtons(buttons) {
52880
+ buttons.forEach(button => {
52881
+ if (!this.state.buttons[button.id]) {
52882
+ this.state.buttons[button.id] = button;
52883
+ }
52884
+ });
52885
+ this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, {
52886
+ ...this.state
52887
+ });
51887
52888
  }
51888
52889
 
51889
52890
  /**
@@ -51894,162 +52895,182 @@ class ToolbarService extends pubSubServiceInterface/* PubSubService */.R {
51894
52895
  * called with {...commandOptions,...options}
51895
52896
  */
51896
52897
  recordInteraction(interaction, options) {
51897
- if (!interaction) {
51898
- return;
51899
- }
51900
- const commandsManager = this._commandsManager;
51901
- const {
51902
- groupId,
51903
- itemId,
51904
- commands,
51905
- type
51906
- } = interaction;
51907
- let {
51908
- interactionType
51909
- } = interaction;
51910
-
51911
- // if not interaction type, assume the type can be used
51912
- if (!interactionType) {
51913
- interactionType = type;
51914
- }
51915
- switch (interactionType) {
51916
- case 'action':
51917
- {
51918
- commandsManager.run(commands, options);
51919
- break;
51920
- }
51921
- case 'tool':
51922
- {
51923
- try {
51924
- const alternateInteraction = this.state.primaryToolId === itemId && this.defaultTool?.itemId !== itemId && this.getDefaultTool();
51925
- if (alternateInteraction) {
51926
- // Allow toggling the mode off
51927
- return this.recordInteraction(alternateInteraction, options);
51928
- }
51929
- commandsManager.run(commands, options);
51930
-
51931
- // only set the primary tool if no error was thrown.
51932
- // if the itemId is not undefined use it; otherwise, set the first tool in
51933
- // the commands as the primary tool
51934
- this.state.primaryToolId = itemId || commands[0].commandOptions?.toolName;
51935
- } catch (error) {
51936
- console.warn(error);
51937
- }
51938
- break;
51939
- }
51940
- case 'toggle':
51941
- {
51942
- const {
51943
- commands
51944
- } = interaction;
51945
- let commandExecuted;
51946
-
51947
- // only toggle if a command was executed
51948
- this.state.toggles[itemId] = this.state.toggles[itemId] === undefined ? true : !this.state.toggles[itemId];
51949
- if (!commands) {
51950
- break;
51951
- }
51952
- commands.forEach(({
51953
- commandName,
51954
- commandOptions,
51955
- context
51956
- }) => {
51957
- if (!commandOptions) {
51958
- commandOptions = {};
51959
- }
51960
- if (commandName) {
51961
- commandOptions.toggledState = this.state.toggles[itemId];
51962
- try {
51963
- commandsManager.runCommand(commandName, commandOptions, context);
51964
- commandExecuted = true;
51965
- } catch (error) {
51966
- console.warn(error);
51967
- }
51968
- }
51969
- });
51970
- if (!commandExecuted) {
51971
- // If no command was executed, we need to toggle the state back
51972
- this.state.toggles[itemId] = !this.state.toggles[itemId];
51973
- }
51974
- break;
51975
- }
51976
- default:
51977
- throw new Error(`Invalid interaction type: ${interactionType}`);
51978
- }
51979
-
51980
- // Todo: comment out for now
51981
- // Run command if there's one associated
51982
- //
51983
- // NOTE: Should probably just do this for tools as well?
51984
- // But would be nice if we could enforce at least the command name?
51985
- // let unsubscribe;
51986
- // if (commandName) {
51987
- // unsubscribe = commandsManager.runCommand(commandName, commandOptions);
51988
- // }
51989
-
51990
- // // Storing the unsubscribe for later resetting
51991
- // if (unsubscribe && typeof unsubscribe === 'function') {
51992
- // if (this.unsubscriptions.indexOf(unsubscribe) === -1) {
51993
- // this.unsubscriptions.push(unsubscribe);
51994
- // }
51995
- // }
52898
+ // if interaction is a string, we can assume it is the itemId
52899
+ // and get the props to get the other properties
52900
+ if (typeof interaction === 'string') {
52901
+ interaction = this.getButtonProps(interaction);
52902
+ }
52903
+ const itemId = interaction.itemId ?? interaction.id;
52904
+ interaction.itemId = itemId;
52905
+ const commands = Array.isArray(interaction.commands) ? interaction.commands : [interaction.commands];
52906
+ if (!commands?.length) {
52907
+ this.refreshToolbarState({
52908
+ ...options?.refreshProps,
52909
+ itemId,
52910
+ interaction
52911
+ });
52912
+ }
52913
+ const commandOptions = {
52914
+ ...options,
52915
+ ...interaction
52916
+ };
51996
52917
 
51997
- // Track last touched id for each group
51998
- if (groupId) {
51999
- this.state.groups[groupId] = itemId;
52000
- }
52001
- this._broadcastEvent(this.EVENTS.TOOL_BAR_STATE_MODIFIED, {
52002
- ...this.state
52918
+ // Loop through commands and run them with the combined options
52919
+ this._commandsManager.run(commands, commandOptions);
52920
+ this.refreshToolbarState({
52921
+ ...options?.refreshProps,
52922
+ itemId,
52923
+ interaction
52003
52924
  });
52004
52925
  }
52005
- getButtons() {
52006
- return this.buttons;
52007
- }
52008
- getActiveTools() {
52009
- const activeTools = [this.state.primaryToolId];
52010
- Object.keys(this.state.toggles).forEach(key => {
52011
- if (this.state.toggles[key]) {
52012
- activeTools.push(key);
52926
+
52927
+ /**
52928
+ * Consolidates the state of the toolbar after an interaction, it accepts
52929
+ * props that get passed to the buttons
52930
+ *
52931
+ * @param refreshProps - The props that buttons need to get evaluated, they can be
52932
+ * { viewportId, toolGroup} for cornerstoneTools.
52933
+ *
52934
+ * Todo: right now refreshToolbarState should be used in the context where
52935
+ * we have access to the toolGroup and viewportId, but we should be able to
52936
+ * pass the props to the toolbar service and it should be able to decide
52937
+ * which buttons to evaluate based on the props
52938
+ */
52939
+ refreshToolbarState(refreshProps) {
52940
+ const buttons = this.state.buttons;
52941
+
52942
+ // Tracks evaluated buttons to avoid re-evaluating them (this will
52943
+ // cause issue for toggles where if the button is in primary
52944
+ // and secondary it will be evaluated twice)
52945
+ const evaluationResults = new Map();
52946
+ const evaluateButtonProps = (button, props, refreshProps) => {
52947
+ if (evaluationResults.has(button.id)) {
52948
+ const {
52949
+ disabled,
52950
+ className,
52951
+ isActive
52952
+ } = evaluationResults.get(button.id);
52953
+ return {
52954
+ ...props,
52955
+ disabled,
52956
+ className,
52957
+ isActive
52958
+ };
52959
+ } else {
52960
+ const evaluated = props.evaluate?.({
52961
+ ...refreshProps,
52962
+ button
52963
+ });
52964
+ const updatedProps = {
52965
+ ...props,
52966
+ disabled: evaluated?.disabled || false,
52967
+ className: evaluated?.className || '',
52968
+ isActive: evaluated?.isActive // isActive will be undefined for buttons without this prop
52969
+ };
52970
+ evaluationResults.set(button.id, updatedProps);
52971
+ return updatedProps;
52972
+ }
52973
+ };
52974
+ const refreshedButtons = Object.values(buttons).reduce((acc, button) => {
52975
+ const isNested = button.props?.groupId;
52976
+ if (!isNested) {
52977
+ this.handleEvaluate(button.props);
52978
+ const buttonProps = button.props;
52979
+ const updatedProps = evaluateButtonProps(button, buttonProps, refreshProps);
52980
+ acc[button.id] = {
52981
+ ...button,
52982
+ props: updatedProps
52983
+ };
52984
+ } else {
52985
+ let buttonProps = button.props;
52986
+ // if it is nested we should perform evaluate on each item in the group
52987
+ this.handleEvaluateNested(buttonProps);
52988
+ const {
52989
+ evaluate: groupEvaluate
52990
+ } = buttonProps;
52991
+ const groupEvaluated = groupEvaluate?.({
52992
+ ...refreshProps,
52993
+ button
52994
+ });
52995
+ // handle group evaluate function which might switch the primary
52996
+ // item in the group
52997
+ buttonProps = {
52998
+ ...buttonProps,
52999
+ primary: groupEvaluated?.primary || buttonProps.primary
53000
+ };
53001
+ const {
53002
+ primary,
53003
+ items
53004
+ } = buttonProps;
53005
+
53006
+ // primary and items evaluate functions
53007
+ let updatedPrimary;
53008
+ if (primary) {
53009
+ updatedPrimary = evaluateButtonProps(primary, primary, refreshProps);
53010
+ }
53011
+ const updatedItems = items.map(item => evaluateButtonProps(item, item, refreshProps));
53012
+ buttonProps = {
53013
+ ...buttonProps,
53014
+ primary: updatedPrimary,
53015
+ items: updatedItems
53016
+ };
53017
+ acc[button.id] = {
53018
+ ...button,
53019
+ props: buttonProps
53020
+ };
52013
53021
  }
52014
- });
52015
- return activeTools;
52016
- }
52017
- getActivePrimaryTool() {
52018
- return this.state.primaryToolId;
53022
+ return acc;
53023
+ }, {});
53024
+ this.setButtons(refreshedButtons);
53025
+ return this.state;
52019
53026
  }
52020
53027
 
52021
- /** Sets the toggle state of a button to the isToggled state */
52022
- setToggled(id, isToggled) {
52023
- if (isToggled) {
52024
- this.state.toggles[id] = true;
52025
- } else {
52026
- delete this.state.toggles[id];
52027
- }
52028
- }
52029
- setButton(id, button) {
52030
- if (this.buttons[id]) {
52031
- this.buttons[id] = lodash_merge_default()(this.buttons[id], button);
52032
- this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, {
52033
- buttons: this.buttons,
52034
- button: this.buttons[id],
52035
- buttonSections: this.buttonSections
52036
- });
52037
- }
53028
+ /**
53029
+ * Sets the buttons for the toolbar, don't use this method to record an
53030
+ * interaction, since it doesn't update the state of the buttons, use
53031
+ * this if you know the buttons you want to set and you want to set them
53032
+ * all at once.
53033
+ * @param buttons - The buttons to set.
53034
+ */
53035
+ setButtons(buttons) {
53036
+ this.state.buttons = buttons;
53037
+ this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, {
53038
+ buttons: this.state.buttons,
53039
+ buttonSections: this.state.buttonSections
53040
+ });
52038
53041
  }
53042
+
53043
+ /**
53044
+ * Retrieves a button by its ID.
53045
+ * @param id - The ID of the button to retrieve.
53046
+ * @returns The button with the specified ID.
53047
+ */
52039
53048
  getButton(id) {
52040
- return this.buttons[id];
53049
+ return this.state.buttons[id];
52041
53050
  }
52042
53051
 
52043
- /** Gets a nested button, found in the items/props for the children */
52044
- getNestedButton(id) {
52045
- if (this.buttons[id]) {
52046
- return this.buttons[id];
52047
- }
52048
- for (const buttonId of Object.keys(this.buttons)) {
53052
+ /**
53053
+ * Retrieves the buttons from the toolbar service.
53054
+ * @returns An array of buttons.
53055
+ */
53056
+ getButtons() {
53057
+ return this.state.buttons;
53058
+ }
53059
+
53060
+ /**
53061
+ * Retrieves the button properties for the specified button ID.
53062
+ * It prioritizes nested buttons over regular buttons if the ID is found
53063
+ * in both.
53064
+ *
53065
+ * @param id - The ID of the button.
53066
+ * @returns The button properties.
53067
+ */
53068
+ getButtonProps(id) {
53069
+ for (const buttonId of Object.keys(this.state.buttons)) {
52049
53070
  const {
52050
53071
  primary,
52051
53072
  items
52052
- } = this.buttons[buttonId].props || {};
53073
+ } = this.state.buttons[buttonId].props || {};
52053
53074
  if (primary?.id === id) {
52054
53075
  return primary;
52055
53076
  }
@@ -52058,79 +53079,52 @@ class ToolbarService extends pubSubServiceInterface/* PubSubService */.R {
52058
53079
  return found;
52059
53080
  }
52060
53081
  }
52061
- }
52062
- setButtons(buttons) {
52063
- this.buttons = buttons;
52064
- this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, {
52065
- buttons: this.buttons,
52066
- buttonSections: this.buttonSections
52067
- });
52068
- }
52069
- _buttonTypes() {
52070
- const buttonTypes = {};
52071
- const registeredToolbarModules = this.extensionManager.modules['toolbarModule'];
52072
- if (Array.isArray(registeredToolbarModules) && registeredToolbarModules.length) {
52073
- registeredToolbarModules.forEach(toolbarModule => toolbarModule.module.forEach(def => {
52074
- buttonTypes[def.name] = def;
52075
- }));
53082
+
53083
+ // This should be checked after we checked the nested buttons, since
53084
+ // we are checking based on the ids, the nested objects are higher priority
53085
+ // and more specific
53086
+ if (this.state.buttons[id]) {
53087
+ return this.state.buttons[id].props;
52076
53088
  }
52077
- return buttonTypes;
52078
53089
  }
52079
- createButtonSection(key, buttons) {
52080
- // Maybe do this mapping at time of return, instead of time of create
52081
- // Props check important for validation here...
52082
-
52083
- this.buttonSections[key] = buttons;
52084
- this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, {});
53090
+ _getButtonUITypes() {
53091
+ const registeredToolbarModules = this._extensionManager.modules['toolbarModule'];
53092
+ if (!Array.isArray(registeredToolbarModules)) {
53093
+ return {};
53094
+ }
53095
+ return registeredToolbarModules.reduce((buttonTypes, toolbarModule) => {
53096
+ toolbarModule.module.forEach(def => {
53097
+ buttonTypes[def.name] = def;
53098
+ });
53099
+ return buttonTypes;
53100
+ }, {});
52085
53101
  }
52086
53102
 
52087
53103
  /**
52088
- *
52089
- * Finds a button section by it's name/tool group id, then maps the list of string name
52090
- * identifiers to schema/values that can be used to render the buttons.
52091
- *
52092
- * @param toolGroupId - the tool group id
52093
- * @param props - optional properties to apply to every button of the section
52094
- * @param defaultToolGroupId - the fallback section to return if the given toolGroupId section is not available
53104
+ * Creates a button section with the specified key and buttons.
53105
+ * @param {string} key - The key of the button section.
53106
+ * @param {Array} buttons - The buttons to be added to the section.
52095
53107
  */
52096
- getButtonSection(toolGroupId, props, defaultToolGroupId = 'primary') {
52097
- const buttonSectionIds = this.buttonSections[toolGroupId] || this.buttonSections[defaultToolGroupId];
52098
- const buttonsInSection = [];
52099
- if (buttonSectionIds && buttonSectionIds.length !== 0) {
52100
- buttonSectionIds.forEach(btnId => {
52101
- const btn = this.buttons[btnId];
52102
- const metadata = {};
52103
- const mappedBtn = this._mapButtonToDisplay(btn, toolGroupId, metadata, props);
52104
- buttonsInSection.push(mappedBtn);
52105
- });
52106
- }
52107
- return buttonsInSection;
53108
+ createButtonSection(key, buttons) {
53109
+ this.state.buttonSections[key] = buttons;
53110
+ this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, {
53111
+ ...this.state
53112
+ });
52108
53113
  }
52109
53114
 
52110
53115
  /**
53116
+ * Retrieves the button section with the specified sectionId.
52111
53117
  *
52112
- * @param {object[]} buttons
52113
- * @param {string} buttons[].id
53118
+ * @param sectionId - The ID of the button section to retrieve.
53119
+ * @param props - Optional additional properties for mapping the button to display.
53120
+ * @returns An array of buttons in the specified section, mapped to their display representation.
52114
53121
  */
52115
- addButtons(buttons) {
52116
- buttons.forEach(button => {
52117
- if (!this.buttons[button.id]) {
52118
- this.buttons[button.id] = button;
52119
- }
52120
- });
52121
- this._setTogglesForButtonItems(buttons);
52122
- this._broadcastEvent(this.EVENTS.TOOL_BAR_MODIFIED, {});
52123
- }
52124
- _setTogglesForButtonItems(buttons) {
52125
- if (!buttons) {
52126
- return;
52127
- }
52128
- buttons.forEach(buttonItem => {
52129
- if (buttonItem.type === 'toggle') {
52130
- this.setToggled(buttonItem.id, buttonItem.isActive);
52131
- }
52132
- this._setTogglesForButtonItems(buttonItem.props?.items);
52133
- });
53122
+ getButtonSection(sectionId, props) {
53123
+ const buttonSectionIds = this.state.buttonSections[sectionId];
53124
+ return buttonSectionIds?.map(btnId => {
53125
+ const btn = this.state.buttons[btnId];
53126
+ return this._mapButtonToDisplay(btn, props);
53127
+ }) || [];
52134
53128
  }
52135
53129
 
52136
53130
  /**
@@ -52140,19 +53134,23 @@ class ToolbarService extends pubSubServiceInterface/* PubSubService */.R {
52140
53134
  * @param {*} metadata
52141
53135
  * @param {*} props - Props set by the Viewer layer
52142
53136
  */
52143
- _mapButtonToDisplay(btn, btnSection, metadata, props) {
53137
+ _mapButtonToDisplay(btn, props) {
52144
53138
  if (!btn) {
52145
53139
  return;
52146
53140
  }
52147
53141
  const {
52148
53142
  id,
52149
- type,
53143
+ uiType,
52150
53144
  component
52151
53145
  } = btn;
52152
- const buttonType = this._buttonTypes()[type];
53146
+ const {
53147
+ groupId
53148
+ } = btn.props;
53149
+ const buttonType = this._getButtonUITypes()[uiType];
52153
53150
  if (!buttonType) {
52154
53151
  return;
52155
53152
  }
53153
+ !groupId ? this.handleEvaluate(btn.props) : this.handleEvaluateNested(btn.props);
52156
53154
  return {
52157
53155
  id,
52158
53156
  Component: component || buttonType.defaultComponent,
@@ -52160,23 +53158,21 @@ class ToolbarService extends pubSubServiceInterface/* PubSubService */.R {
52160
53158
  };
52161
53159
  }
52162
53160
  getButtonComponentForUIType(uiType) {
52163
- return uiType ? this._buttonTypes()[uiType]?.defaultComponent ?? null : null;
53161
+ return uiType ? this._getButtonUITypes()[uiType]?.defaultComponent ?? null : null;
52164
53162
  }
52165
53163
  }
52166
53164
  ToolbarService_class = ToolbarService;
52167
53165
  ToolbarService.REGISTRATION = {
52168
53166
  name: 'toolbarService',
52169
- // Note the old name is ToolBarService, with an upper B
52170
53167
  altName: 'ToolBarService',
52171
53168
  create: ({
52172
- commandsManager
53169
+ commandsManager,
53170
+ extensionManager,
53171
+ servicesManager
52173
53172
  }) => {
52174
- return new ToolbarService_class(commandsManager);
53173
+ return new ToolbarService_class(commandsManager, extensionManager, servicesManager);
52175
53174
  }
52176
53175
  };
52177
- ToolbarService._createActionButton = ToolbarService_class._createButton.bind(null, 'action');
52178
- ToolbarService._createToggleButton = ToolbarService_class._createButton.bind(null, 'toggle');
52179
- ToolbarService._createToolButton = ToolbarService_class._createButton.bind(null, 'tool');
52180
53176
  ;// CONCATENATED MODULE: ../../core/src/services/ToolBarService/index.ts
52181
53177
 
52182
53178
  /* harmony default export */ const ToolBarService = (ToolbarService);
@@ -52334,7 +53330,8 @@ class ViewportGridService extends pubSubServiceInterface/* PubSubService */.R {
52334
53330
  reset: resetImplementation,
52335
53331
  onModeExit: onModeExitImplementation,
52336
53332
  set: setImplementation,
52337
- getNumViewportPanes: getNumViewportPanesImplementation
53333
+ getNumViewportPanes: getNumViewportPanesImplementation,
53334
+ setViewportIsReady: setViewportIsReadyImplementation
52338
53335
  }) {
52339
53336
  if (getStateImplementation) {
52340
53337
  this.serviceImplementation._getState = getStateImplementation;
@@ -52360,6 +53357,12 @@ class ViewportGridService extends pubSubServiceInterface/* PubSubService */.R {
52360
53357
  if (getNumViewportPanesImplementation) {
52361
53358
  this.serviceImplementation._getNumViewportPanes = getNumViewportPanesImplementation;
52362
53359
  }
53360
+ if (setViewportIsReadyImplementation) {
53361
+ this.serviceImplementation._setViewportIsReady = setViewportIsReadyImplementation;
53362
+ }
53363
+ }
53364
+ publishViewportsReady() {
53365
+ this._broadcastEvent(this.EVENTS.VIEWPORTS_READY, {});
52363
53366
  }
52364
53367
  setActiveViewportId(id) {
52365
53368
  this.serviceImplementation._setActiveViewport(id);
@@ -52370,6 +53373,9 @@ class ViewportGridService extends pubSubServiceInterface/* PubSubService */.R {
52370
53373
  getState() {
52371
53374
  return this.serviceImplementation._getState();
52372
53375
  }
53376
+ setViewportIsReady(viewportId, callback) {
53377
+ this.serviceImplementation._setViewportIsReady(viewportId, callback);
53378
+ }
52373
53379
  getActiveViewportId() {
52374
53380
  const state = this.getState();
52375
53381
  return state.activeViewportId;
@@ -52402,6 +53408,17 @@ class ViewportGridService extends pubSubServiceInterface/* PubSubService */.R {
52402
53408
  });
52403
53409
  }
52404
53410
 
53411
+ /**
53412
+ * Retrieves the display set instance UIDs for a given viewport.
53413
+ * @param viewportId The ID of the viewport.
53414
+ * @returns An array of display set instance UIDs.
53415
+ */
53416
+ getDisplaySetsUIDsForViewport(viewportId) {
53417
+ const state = this.getState();
53418
+ const viewport = state.viewports.get(viewportId);
53419
+ return viewport?.displaySetInstanceUIDs;
53420
+ }
53421
+
52405
53422
  /**
52406
53423
  *
52407
53424
  * @param numCols, numRows - the number of columns and rows to apply
@@ -52469,7 +53486,8 @@ ViewportGridService.EVENTS = {
52469
53486
  ACTIVE_VIEWPORT_ID_CHANGED: 'event::activeviewportidchanged',
52470
53487
  LAYOUT_CHANGED: 'event::layoutChanged',
52471
53488
  GRID_STATE_CHANGED: 'event::gridStateChanged',
52472
- GRID_SIZE_CHANGED: 'event::gridSizeChanged'
53489
+ GRID_SIZE_CHANGED: 'event::gridSizeChanged',
53490
+ VIEWPORTS_READY: 'event::viewportsReady'
52473
53491
  };
52474
53492
  ViewportGridService.REGISTRATION = {
52475
53493
  name: 'viewportGridService',
@@ -52486,82 +53504,81 @@ ViewportGridService.getPresentationIds = getPresentationIds;
52486
53504
 
52487
53505
  /* harmony default export */ const services_ViewportGridService = (ViewportGridService_ViewportGridService);
52488
53506
  ;// CONCATENATED MODULE: ../../core/src/services/CineService/CineService.ts
52489
- const CineService_name = 'CineService';
52490
- const CineService_publicAPI = {
52491
- name: CineService_name,
52492
- getState: _getState,
52493
- setCine: _setCine,
52494
- setIsCineEnabled: _setIsCineEnabled,
52495
- playClip: _playClip,
52496
- stopClip: _stopClip,
52497
- onModeExit: _onModeExit,
52498
- setServiceImplementation: CineService_setServiceImplementation
52499
- };
52500
- const CineService_serviceImplementation = {
52501
- _getState: () => console.warn('getState() NOT IMPLEMENTED'),
52502
- _setCine: () => console.warn('setCine() NOT IMPLEMENTED'),
52503
- _playClip: () => console.warn('playClip() NOT IMPLEMENTED'),
52504
- _stopClip: () => console.warn('stopClip() NOT IMPLEMENTED'),
52505
- _setIsCineEnabled: () => console.warn('setIsCineEnabled() NOT IMPLEMENTED')
52506
- };
52507
- function _getState() {
52508
- return CineService_serviceImplementation._getState();
52509
- }
52510
- function _setCine({
52511
- id,
52512
- frameRate,
52513
- isPlaying
52514
- }) {
52515
- return CineService_serviceImplementation._setCine({
53507
+ var CineService_class;
53508
+
53509
+ class CineService extends pubSubServiceInterface/* PubSubService */.R {
53510
+ constructor() {
53511
+ super(CineService.EVENTS);
53512
+ this.serviceImplementation = {};
53513
+ this.serviceImplementation = {};
53514
+ }
53515
+ getState() {
53516
+ return this.serviceImplementation._getState();
53517
+ }
53518
+ setCine({
52516
53519
  id,
52517
53520
  frameRate,
52518
53521
  isPlaying
52519
- });
52520
- }
52521
- function _setIsCineEnabled(isCineEnabled) {
52522
- return CineService_serviceImplementation._setIsCineEnabled(isCineEnabled);
52523
- }
52524
- function _playClip(element, playClipOptions) {
52525
- return CineService_serviceImplementation._playClip(element, playClipOptions);
52526
- }
52527
- function _stopClip(element) {
52528
- return CineService_serviceImplementation._stopClip(element);
52529
- }
52530
- function _onModeExit() {
52531
- _setIsCineEnabled(false);
52532
- }
52533
- function CineService_setServiceImplementation({
52534
- getState: getStateImplementation,
52535
- setCine: setCineImplementation,
52536
- setIsCineEnabled: setIsCineEnabledImplementation,
52537
- playClip: playClipImplementation,
52538
- stopClip: stopClipImplementation
52539
- }) {
52540
- if (getStateImplementation) {
52541
- CineService_serviceImplementation._getState = getStateImplementation;
53522
+ }) {
53523
+ return this.serviceImplementation._setCine({
53524
+ id,
53525
+ frameRate,
53526
+ isPlaying
53527
+ });
52542
53528
  }
52543
- if (setCineImplementation) {
52544
- CineService_serviceImplementation._setCine = setCineImplementation;
53529
+ setIsCineEnabled(isCineEnabled) {
53530
+ this.serviceImplementation._setIsCineEnabled(isCineEnabled);
53531
+ // Todo: for some reason i need to do this setTimeout since the
53532
+ // reducer state does not get updated right away and if we publish the
53533
+ // event and we use the cineService.getState() it will return the old state
53534
+ setTimeout(() => {
53535
+ this._broadcastEvent(this.EVENTS.CINE_STATE_CHANGED, isCineEnabled);
53536
+ }, 0);
52545
53537
  }
52546
- if (setIsCineEnabledImplementation) {
52547
- CineService_serviceImplementation._setIsCineEnabled = setIsCineEnabledImplementation;
53538
+ playClip(element, playClipOptions) {
53539
+ return this.serviceImplementation._playClip(element, playClipOptions);
52548
53540
  }
52549
- if (playClipImplementation) {
52550
- CineService_serviceImplementation._playClip = playClipImplementation;
53541
+ stopClip(element) {
53542
+ return this.serviceImplementation._stopClip(element);
52551
53543
  }
52552
- if (stopClipImplementation) {
52553
- CineService_serviceImplementation._stopClip = stopClipImplementation;
53544
+ _onModeExit() {
53545
+ this.setIsCineEnabled(false);
52554
53546
  }
52555
- }
52556
- const CineService = {
52557
- REGISTRATION: {
52558
- altName: CineService_name,
52559
- name: 'cineService',
52560
- create: ({
52561
- configuration = {}
52562
- }) => {
52563
- return CineService_publicAPI;
53547
+ setServiceImplementation({
53548
+ getState: getStateImplementation,
53549
+ setCine: setCineImplementation,
53550
+ setIsCineEnabled: setIsCineEnabledImplementation,
53551
+ playClip: playClipImplementation,
53552
+ stopClip: stopClipImplementation
53553
+ }) {
53554
+ if (getStateImplementation) {
53555
+ this.serviceImplementation._getState = getStateImplementation;
53556
+ }
53557
+ if (setCineImplementation) {
53558
+ this.serviceImplementation._setCine = setCineImplementation;
53559
+ }
53560
+ if (setIsCineEnabledImplementation) {
53561
+ this.serviceImplementation._setIsCineEnabled = setIsCineEnabledImplementation;
53562
+ }
53563
+ if (playClipImplementation) {
53564
+ this.serviceImplementation._playClip = playClipImplementation;
52564
53565
  }
53566
+ if (stopClipImplementation) {
53567
+ this.serviceImplementation._stopClip = stopClipImplementation;
53568
+ }
53569
+ }
53570
+ }
53571
+ CineService_class = CineService;
53572
+ CineService.EVENTS = {
53573
+ CINE_STATE_CHANGED: 'event::cineStateChanged'
53574
+ };
53575
+ CineService.REGISTRATION = {
53576
+ name: 'cineService',
53577
+ altName: 'CineService',
53578
+ create: ({
53579
+ configuration = {}
53580
+ }) => {
53581
+ return new CineService_class();
52565
53582
  }
52566
53583
  };
52567
53584
  /* harmony default export */ const CineService_CineService = (CineService);
@@ -54790,7 +55807,7 @@ HangingProtocolService.REGISTRATION = {
54790
55807
  const UserAuthenticationService_name = 'userAuthenticationService';
54791
55808
  const UserAuthenticationService_publicAPI = {
54792
55809
  name: UserAuthenticationService_name,
54793
- getState: UserAuthenticationService_getState,
55810
+ getState: _getState,
54794
55811
  setUser: _setUser,
54795
55812
  getUser: _getUser,
54796
55813
  getAuthorizationHeader: _getAuthorizationHeader,
@@ -54810,7 +55827,7 @@ const UserAuthenticationService_serviceImplementation = {
54810
55827
  _reset: () => console.warn('reset() NOT IMPLEMENTED'),
54811
55828
  _set: () => console.warn('set() NOT IMPLEMENTED')
54812
55829
  };
54813
- function UserAuthenticationService_getState() {
55830
+ function _getState() {
54814
55831
  return UserAuthenticationService_serviceImplementation._getState();
54815
55832
  }
54816
55833
  function _setUser(user) {
@@ -54876,6 +55893,9 @@ function UserAuthenticationService_setServiceImplementation({
54876
55893
  ;// CONCATENATED MODULE: ../../core/src/services/UserAuthenticationService/index.js
54877
55894
 
54878
55895
  /* harmony default export */ const services_UserAuthenticationService = (UserAuthenticationService);
55896
+ // EXTERNAL MODULE: ../../../node_modules/lodash.merge/index.js
55897
+ var lodash_merge = __webpack_require__(40592);
55898
+ var lodash_merge_default = /*#__PURE__*/__webpack_require__.n(lodash_merge);
54879
55899
  ;// CONCATENATED MODULE: ../../core/src/services/CustomizationService/CustomizationService.ts
54880
55900
  var CustomizationService_class;
54881
55901
 
@@ -55002,10 +56022,10 @@ class CustomizationService extends pubSubServiceInterface/* PubSubService */.R {
55002
56022
  return this.getModeCustomization(customizationId, defaultValue);
55003
56023
  }
55004
56024
 
55005
- /** Mode customizations are changes to the behaviour of the extensions
56025
+ /** Mode customizations are changes to the behavior of the extensions
55006
56026
  * when running in a given mode. Reset clears mode customizations.
55007
56027
  * Note that global customizations over-ride mode customizations.
55008
- * @param defautlValue to return if no customization specified.
56028
+ * @param defaultValue to return if no customization specified.
55009
56029
  */
55010
56030
  getModeCustomization(customizationId, defaultValue) {
55011
56031
  const customization = this.globalCustomizations[customizationId] ?? this.modeCustomizations[customizationId] ?? defaultValue;
@@ -55134,8 +56154,6 @@ CustomizationService.REGISTRATION = {
55134
56154
  ;// CONCATENATED MODULE: ../../core/src/services/CustomizationService/index.ts
55135
56155
 
55136
56156
  /* harmony default export */ const services_CustomizationService = (CustomizationService);
55137
- // EXTERNAL MODULE: ../../core/src/types/Services.ts
55138
- var Services = __webpack_require__(53857);
55139
56157
  ;// CONCATENATED MODULE: ../../core/src/services/StateSyncService/StateSyncService.ts
55140
56158
  var StateSyncService_class;
55141
56159
 
@@ -55288,7 +56306,6 @@ PanelService.REGISTRATION = {
55288
56306
 
55289
56307
 
55290
56308
 
55291
-
55292
56309
  ;// CONCATENATED MODULE: ../../core/src/extensions/ExtensionManager.ts
55293
56310
 
55294
56311
 
@@ -55325,6 +56342,16 @@ class ExtensionManager extends pubSubServiceInterface/* PubSubService */.R {
55325
56342
  this._commandsManager = void 0;
55326
56343
  this._servicesManager = void 0;
55327
56344
  this._hotkeysManager = void 0;
56345
+ this.modulesMap = void 0;
56346
+ this.modules = void 0;
56347
+ this.registeredExtensionIds = void 0;
56348
+ this.moduleTypeNames = void 0;
56349
+ this._appConfig = void 0;
56350
+ this._extensionLifeCycleHooks = void 0;
56351
+ this.dataSourceMap = void 0;
56352
+ this.dataSourceDefs = void 0;
56353
+ this.defaultDataSourceName = void 0;
56354
+ this.activeDataSource = void 0;
55328
56355
  /**
55329
56356
  * An array of extensions, or an array of arrays that contains extension
55330
56357
  * configuration pairs.
@@ -55399,52 +56426,64 @@ class ExtensionManager extends pubSubServiceInterface/* PubSubService */.R {
55399
56426
  // Register Modules
55400
56427
  this.moduleTypeNames.forEach(moduleType => {
55401
56428
  const extensionModule = this._getExtensionModule(moduleType, extension, extensionId, configuration);
55402
- if (extensionModule) {
55403
- switch (moduleType) {
55404
- case MODULE_TYPES.COMMANDS:
55405
- this._initCommandsModule(extensionModule);
55406
- break;
55407
- case MODULE_TYPES.DATA_SOURCE:
55408
- this._initDataSourcesModule(extensionModule, extensionId, dataSources);
55409
- break;
55410
- case MODULE_TYPES.HANGING_PROTOCOL:
55411
- this._initHangingProtocolsModule(extensionModule, extensionId);
55412
- case MODULE_TYPES.TOOLBAR:
55413
- case MODULE_TYPES.VIEWPORT:
55414
- case MODULE_TYPES.PANEL:
55415
- case MODULE_TYPES.SOP_CLASS_HANDLER:
55416
- case MODULE_TYPES.CONTEXT:
55417
- case MODULE_TYPES.LAYOUT_TEMPLATE:
55418
- case MODULE_TYPES.CUSTOMIZATION:
55419
- case MODULE_TYPES.STATE_SYNC:
55420
- case MODULE_TYPES.UTILITY:
55421
- // Default for most extension points,
55422
- // Just adds each entry ready for consumption by mode.
55423
- extensionModule.forEach(element => {
55424
- if (!element.name) {
55425
- throw new Error(`Extension ID ${extensionId} module ${moduleType} element has no name`);
55426
- }
55427
- const id = `${extensionId}.${moduleType}.${element.name}`;
55428
- element.id = id;
55429
- this.modulesMap[id] = element;
55430
- });
55431
- break;
55432
- default:
55433
- throw new Error(`Module type invalid: ${moduleType}`);
55434
- }
55435
- this.modules[moduleType].push({
55436
- extensionId,
55437
- module: extensionModule
55438
- });
56429
+ if (!extensionModule) {
56430
+ return;
56431
+ }
56432
+ switch (moduleType) {
56433
+ case MODULE_TYPES.COMMANDS:
56434
+ this._initCommandsModule(extensionModule);
56435
+ break;
56436
+ case MODULE_TYPES.DATA_SOURCE:
56437
+ this._initDataSourcesModule(extensionModule, extensionId, dataSources);
56438
+ break;
56439
+ case MODULE_TYPES.HANGING_PROTOCOL:
56440
+ this._initHangingProtocolsModule(extensionModule, extensionId);
56441
+ break;
56442
+ case MODULE_TYPES.PANEL:
56443
+ this._initPanelModule(extensionModule, extensionId);
56444
+ break;
56445
+ case MODULE_TYPES.TOOLBAR:
56446
+ this._initToolbarModule(extensionModule, extensionId);
56447
+ break;
56448
+ case MODULE_TYPES.VIEWPORT:
56449
+ case MODULE_TYPES.SOP_CLASS_HANDLER:
56450
+ case MODULE_TYPES.CONTEXT:
56451
+ case MODULE_TYPES.LAYOUT_TEMPLATE:
56452
+ case MODULE_TYPES.CUSTOMIZATION:
56453
+ case MODULE_TYPES.STATE_SYNC:
56454
+ case MODULE_TYPES.UTILITY:
56455
+ this.processExtensionModule(extensionModule, extensionId, moduleType);
56456
+ break;
56457
+ default:
56458
+ throw new Error(`Module type invalid: ${moduleType}`);
55439
56459
  }
56460
+ this.modules[moduleType].push({
56461
+ extensionId,
56462
+ module: extensionModule
56463
+ });
55440
56464
  });
55441
56465
 
55442
56466
  // Track extension registration
55443
56467
  this.registeredExtensionIds.push(extensionId);
55444
56468
  };
56469
+ /**
56470
+ * Retrieves the module entry associated with the given string entry
56471
+ * @param stringEntry - The string entry to retrieve the module entry for which is
56472
+ * in the format of `${extensionId}.${moduleType}.${moduleName}`
56473
+ * @returns The module entry associated with the given string entry.
56474
+ */
55445
56475
  this.getModuleEntry = stringEntry => {
55446
56476
  return this.modulesMap[stringEntry];
55447
56477
  };
56478
+ /**
56479
+ * Retrieves all modules of a given type for all registered extensions.
56480
+ *
56481
+ * @param moduleType - The type of modules to retrieve.
56482
+ * @returns An array of modules of the specified type.
56483
+ */
56484
+ this.getModulesByType = moduleType => {
56485
+ return this.modules[moduleType];
56486
+ };
55448
56487
  this.getDataSources = dataSourceName => {
55449
56488
  if (dataSourceName === undefined) {
55450
56489
  // Default to the activeDataSource
@@ -55521,6 +56560,21 @@ class ExtensionManager extends pubSubServiceInterface/* PubSubService */.R {
55521
56560
  }
55522
56561
  });
55523
56562
  };
56563
+ this._initPanelModule = (extensionModule, extensionId) => {
56564
+ this.processExtensionModule(extensionModule, extensionId, MODULE_TYPES.PANEL);
56565
+ };
56566
+ this._initToolbarModule = (extensionModule, extensionId) => {
56567
+ // check if the toolbar module has a handler function for evaluation of
56568
+ // the toolbar button state
56569
+ const {
56570
+ toolbarService
56571
+ } = this._servicesManager.services;
56572
+ extensionModule.forEach(toolbarButton => {
56573
+ if (toolbarButton.evaluate) {
56574
+ toolbarService.registerEvaluateFunction(toolbarButton.name, toolbarButton.evaluate);
56575
+ }
56576
+ });
56577
+ };
55524
56578
  /**
55525
56579
  *
55526
56580
  * @private
@@ -55636,6 +56690,23 @@ class ExtensionManager extends pubSubServiceInterface/* PubSubService */.R {
55636
56690
  }
55637
56691
  }
55638
56692
  }
56693
+ /**
56694
+ * Processes an extension module.
56695
+ * @param extensionModule - The extension module to process.
56696
+ * @param extensionId - The ID of the extension.
56697
+ * @param moduleType - The type of the module.
56698
+ */
56699
+ processExtensionModule(extensionModule, extensionId, moduleType) {
56700
+ extensionModule.forEach(element => {
56701
+ if (!element.name) {
56702
+ throw new Error(`Extension ID ${extensionId} module ${moduleType} element has no name`);
56703
+ }
56704
+ const id = `${extensionId}.${moduleType}.${element.name}`;
56705
+ element.id = id;
56706
+ this.modulesMap[id] = element;
56707
+ });
56708
+ }
56709
+
55639
56710
  /**
55640
56711
  * Adds the given data source and optionally sets it as the active data source.
55641
56712
  * The method does this by first creating the data source.
@@ -55715,6 +56786,7 @@ class ExtensionManager extends pubSubServiceInterface/* PubSubService */.R {
55715
56786
  ExtensionManager.EVENTS = {
55716
56787
  ACTIVE_DATA_SOURCE_CHANGED: 'event::activedatasourcechanged'
55717
56788
  };
56789
+ ExtensionManager.MODULE_TYPES = MODULE_TYPES;
55718
56790
  function _capitalizeFirstCharacter(lower) {
55719
56791
  return lower.charAt(0).toUpperCase() + lower.substring(1);
55720
56792
  }
@@ -55881,7 +56953,10 @@ class CommandsManager {
55881
56953
  * Run one or more commands with specified extra options.
55882
56954
  * Returns the result of the last command run.
55883
56955
  *
55884
- * @param toRun - A specification of one or more commands
56956
+ * @param toRun - A specification of one or more commands,
56957
+ * typically an object of { commandName, commandOptions, context }
56958
+ * or an array of such objects. It can also be a single commandName as string
56959
+ * if no options are needed.
55885
56960
  * @param options - to include in the commands run beyond
55886
56961
  * the commandOptions specified in the base.
55887
56962
  */
@@ -55889,11 +56964,33 @@ class CommandsManager {
55889
56964
  if (!toRun) {
55890
56965
  return;
55891
56966
  }
55892
- const commands = Array.isArray(toRun) && toRun || toRun.commandName && [toRun] || Array.isArray(toRun.commands) && toRun.commands;
55893
- if (!commands) {
56967
+
56968
+ // Normalize `toRun` to an array of `ComplexCommand`
56969
+ let commands = [];
56970
+ if (typeof toRun === 'string') {
56971
+ commands = [{
56972
+ commandName: toRun
56973
+ }];
56974
+ } else if ('commandName' in toRun) {
56975
+ commands = [toRun];
56976
+ } else if ('commands' in toRun) {
56977
+ const commandsInput = toRun.commands;
56978
+ commands = Array.isArray(commandsInput) ? commandsInput.map(cmd => typeof cmd === 'string' ? {
56979
+ commandName: cmd
56980
+ } : cmd) : [{
56981
+ commandName: commandsInput
56982
+ }];
56983
+ } else if (Array.isArray(toRun)) {
56984
+ commands = toRun.map(cmd => typeof cmd === 'string' ? {
56985
+ commandName: cmd
56986
+ } : cmd);
56987
+ }
56988
+ if (commands.length === 0) {
55894
56989
  console.log("Command isn't runnable", toRun);
55895
56990
  return;
55896
56991
  }
56992
+
56993
+ // Execute each command in the array
55897
56994
  let result;
55898
56995
  commands.forEach(({
55899
56996
  commandName,
@@ -56197,13 +57294,6 @@ class HotkeysManager {
56197
57294
  }
56198
57295
  }
56199
57296
  /* harmony default export */ const classes_HotkeysManager = (HotkeysManager);
56200
-
56201
- // Commands Contexts:
56202
-
56203
- // --> Name and Priority
56204
- // GLOBAL: 0
56205
- // VIEWER::CORNERSTONE: 1
56206
- // VIEWER::VTK: 1
56207
57297
  // EXTERNAL MODULE: ../../core/src/classes/ImageSet.ts
56208
57298
  var ImageSet = __webpack_require__(14169);
56209
57299
  // EXTERNAL MODULE: ../../../node_modules/query-string/index.js
@@ -57531,6 +58621,67 @@ let TimingEnum = /*#__PURE__*/function (TimingEnum) {
57531
58621
  ;// CONCATENATED MODULE: ../../core/src/enums/index.ts
57532
58622
 
57533
58623
 
58624
+ // EXTERNAL MODULE: ../../../node_modules/react/index.js
58625
+ var react = __webpack_require__(41766);
58626
+ ;// CONCATENATED MODULE: ../../core/src/hooks/useToolbar.tsx
58627
+
58628
+ function useToolbar({
58629
+ servicesManager,
58630
+ buttonSection = 'primary'
58631
+ }) {
58632
+ const {
58633
+ toolbarService,
58634
+ viewportGridService
58635
+ } = servicesManager.services;
58636
+ const {
58637
+ EVENTS
58638
+ } = toolbarService;
58639
+ const [toolbarButtons, setToolbarButtons] = (0,react.useState)(toolbarService.getButtonSection(buttonSection));
58640
+
58641
+ // Callback function for handling toolbar interactions
58642
+ const onInteraction = (0,react.useCallback)(args => {
58643
+ const viewportId = viewportGridService.getActiveViewportId();
58644
+ const refreshProps = {
58645
+ viewportId
58646
+ };
58647
+ toolbarService.recordInteraction(args, {
58648
+ refreshProps
58649
+ });
58650
+ }, [toolbarService, viewportGridService]);
58651
+
58652
+ // Effect to handle toolbar modification events
58653
+ (0,react.useEffect)(() => {
58654
+ const handleToolbarModified = () => {
58655
+ setToolbarButtons(toolbarService.getButtonSection(buttonSection));
58656
+ };
58657
+ const subs = [EVENTS.TOOL_BAR_MODIFIED, EVENTS.TOOL_BAR_STATE_MODIFIED].map(event => {
58658
+ return toolbarService.subscribe(event, handleToolbarModified);
58659
+ });
58660
+ return () => {
58661
+ subs.forEach(sub => sub.unsubscribe());
58662
+ };
58663
+ }, [toolbarService]);
58664
+
58665
+ // Effect to handle active viewportId change event
58666
+ (0,react.useEffect)(() => {
58667
+ const events = [viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED, viewportGridService.EVENTS.VIEWPORTS_READY];
58668
+ const subscriptions = events.map(event => {
58669
+ return viewportGridService.subscribe(event, ({
58670
+ viewportId
58671
+ }) => {
58672
+ viewportId = viewportId || viewportGridService.getActiveViewportId();
58673
+ toolbarService.refreshToolbarState({
58674
+ viewportId
58675
+ });
58676
+ });
58677
+ });
58678
+ return () => subscriptions.forEach(sub => sub.unsubscribe());
58679
+ }, [viewportGridService, toolbarService]);
58680
+ return {
58681
+ toolbarButtons,
58682
+ onInteraction
58683
+ };
58684
+ }
57534
58685
  ;// CONCATENATED MODULE: ../../core/src/DataSources/IWebApiDataSource.js
57535
58686
  // TODO: Use above to inject so dependent datasources don't need to import or
57536
58687
  // depend on @ohif/core?
@@ -57626,6 +58777,7 @@ const IWebApiDataSource = {
57626
58777
 
57627
58778
 
57628
58779
 
58780
+
57629
58781
  const hotkeys = {
57630
58782
  ...utils/* default.hotkeys */.Ay.hotkeys,
57631
58783
  defaults: {
@@ -57669,7 +58821,8 @@ const OHIF = {
57669
58821
  DicomMetadataStore: services_DicomMetadataStore,
57670
58822
  pubSubServiceInterface: pubSubServiceInterface/* default */.A,
57671
58823
  PubSubService: pubSubServiceInterface/* PubSubService */.R,
57672
- PanelService: services_PanelService
58824
+ PanelService: services_PanelService,
58825
+ useToolbar: useToolbar
57673
58826
  };
57674
58827
 
57675
58828
 
@@ -58158,13 +59311,6 @@ class PubSubService {
58158
59311
  }
58159
59312
  }
58160
59313
 
58161
- /***/ }),
58162
-
58163
- /***/ 53857:
58164
- /***/ (() => {
58165
-
58166
-
58167
-
58168
59314
  /***/ }),
58169
59315
 
58170
59316
  /***/ 44563:
@@ -58362,7 +59508,7 @@ function uuidv4() {
58362
59508
  /* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11374);
58363
59509
  /* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_1__);
58364
59510
  /* harmony import */ var _Typography__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64597);
58365
- /* harmony import */ var _Icon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(53589);
59511
+ /* harmony import */ var _Icon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1675);
58366
59512
 
58367
59513
 
58368
59514
 
@@ -58401,6 +59547,36 @@ ContextMenu.propTypes = {
58401
59547
 
58402
59548
  /***/ }),
58403
59549
 
59550
+ /***/ 66348:
59551
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
59552
+
59553
+ "use strict";
59554
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
59555
+ /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
59556
+ /* harmony export */ });
59557
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41766);
59558
+ /* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11374);
59559
+ /* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_1__);
59560
+ /* harmony import */ var _getIcon__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32854);
59561
+
59562
+
59563
+
59564
+ const Icon = ({
59565
+ name,
59566
+ ...otherProps
59567
+ }) => {
59568
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createElement(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,_getIcon__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Ay)(name, {
59569
+ ...otherProps
59570
+ }));
59571
+ };
59572
+ Icon.propTypes = {
59573
+ name: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().string).isRequired,
59574
+ className: (prop_types__WEBPACK_IMPORTED_MODULE_1___default().string)
59575
+ };
59576
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Icon);
59577
+
59578
+ /***/ }),
59579
+
58404
59580
  /***/ 64692:
58405
59581
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
58406
59582
 
@@ -135496,7 +136672,7 @@ vtk.register = register;
135496
136672
  /* harmony export */ });
135497
136673
  /* unused harmony exports IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, UNSAFE_DeferredData, UNSAFE_ErrorResponseImpl, UNSAFE_convertRouteMatchToUiMatch, UNSAFE_convertRoutesToDataRoutes, UNSAFE_warning, createHashHistory, createMemoryHistory, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, isDeferredData, json, matchPath, normalizePathname, redirect, redirectDocument, resolvePath */
135498
136674
  /**
135499
- * @remix-run/router v1.15.0
136675
+ * @remix-run/router v1.15.3
135500
136676
  *
135501
136677
  * Copyright (c) Remix Software Inc.
135502
136678
  *
@@ -135914,6 +137090,10 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
135914
137090
  // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297
135915
137091
  let base = window.location.origin !== "null" ? window.location.origin : window.location.href;
135916
137092
  let href = typeof to === "string" ? to : createPath(to);
137093
+ // Treating this as a full URL will strip any trailing spaces so we need to
137094
+ // pre-encode them since they might be part of a matching splat param from
137095
+ // an ancestor route
137096
+ href = href.replace(/ $/, "%20");
135917
137097
  invariant(base, "No window.location.(origin|href) available to create URL for href: " + href);
135918
137098
  return new URL(href, base);
135919
137099
  }
@@ -136020,14 +137200,14 @@ function matchRoutes(routes, locationArg, basename) {
136020
137200
  rankRouteBranches(branches);
136021
137201
  let matches = null;
136022
137202
  for (let i = 0; matches == null && i < branches.length; ++i) {
136023
- matches = matchRouteBranch(branches[i],
136024
137203
  // Incoming pathnames are generally encoded from either window.location
136025
137204
  // or from router.navigate, but we want to match against the unencoded
136026
137205
  // paths in the route definitions. Memory router locations won't be
136027
137206
  // encoded here but there also shouldn't be anything to decode so this
136028
137207
  // should be a safe operation. This avoids needing matchRoutes to be
136029
137208
  // history-aware.
136030
- safelyDecodeURI(pathname));
137209
+ let decoded = decodePath(pathname);
137210
+ matches = matchRouteBranch(branches[i], decoded);
136031
137211
  }
136032
137212
  return matches;
136033
137213
  }
@@ -136286,7 +137466,7 @@ function matchPath(pattern, pathname) {
136286
137466
  if (isOptional && !value) {
136287
137467
  memo[paramName] = undefined;
136288
137468
  } else {
136289
- memo[paramName] = safelyDecodeURIComponent(value || "", paramName);
137469
+ memo[paramName] = (value || "").replace(/%2F/g, "/");
136290
137470
  }
136291
137471
  return memo;
136292
137472
  }, {});
@@ -136338,22 +137518,14 @@ function compilePath(path, caseSensitive, end) {
136338
137518
  let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
136339
137519
  return [matcher, params];
136340
137520
  }
136341
- function safelyDecodeURI(value) {
137521
+ function decodePath(value) {
136342
137522
  try {
136343
- return decodeURI(value);
137523
+ return value.split("/").map(v => decodeURIComponent(v).replace(/\//g, "%2F")).join("/");
136344
137524
  } catch (error) {
136345
137525
  warning(false, "The URL path \"" + value + "\" could not be decoded because it is is a " + "malformed URL segment. This is probably due to a bad percent " + ("encoding (" + error + ")."));
136346
137526
  return value;
136347
137527
  }
136348
137528
  }
136349
- function safelyDecodeURIComponent(value, paramName) {
136350
- try {
136351
- return decodeURIComponent(value);
136352
- } catch (error) {
136353
- warning(false, "The value for the URL param \"" + paramName + "\" will not be decoded because" + (" the string \"" + value + "\" is a malformed URL segment. This is probably") + (" due to a bad percent encoding (" + error + ")."));
136354
- return value;
136355
- }
136356
- }
136357
137529
  /**
136358
137530
  * @private
136359
137531
  */
@@ -136879,7 +138051,21 @@ function createRouter(init) {
136879
138051
  // were marked for explicit hydration
136880
138052
  let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
136881
138053
  let errors = init.hydrationData ? init.hydrationData.errors : null;
136882
- initialized = initialMatches.every(m => m.route.loader && m.route.loader.hydrate !== true && (loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined));
138054
+ let isRouteInitialized = m => {
138055
+ // No loader, nothing to initialize
138056
+ if (!m.route.loader) return true;
138057
+ // Explicitly opting-in to running on hydration
138058
+ if (m.route.loader.hydrate === true) return false;
138059
+ // Otherwise, initialized if hydrated with data or an error
138060
+ return loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined;
138061
+ };
138062
+ // If errors exist, don't consider routes below the boundary
138063
+ if (errors) {
138064
+ let idx = initialMatches.findIndex(m => errors[m.route.id] !== undefined);
138065
+ initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized);
138066
+ } else {
138067
+ initialized = initialMatches.every(isRouteInitialized);
138068
+ }
136883
138069
  } else {
136884
138070
  // Without partial hydration - we're initialized if we were provided any
136885
138071
  // hydrationData - which is expected to be complete
@@ -137532,7 +138718,7 @@ function createRouter(init) {
137532
138718
  // preserving any new action data or existing action data (in the case of
137533
138719
  // a revalidation interrupting an actionReload)
137534
138720
  // If we have partialHydration enabled, then don't update the state for the
137535
- // initial data load since iot's not a "navigation"
138721
+ // initial data load since it's not a "navigation"
137536
138722
  if (!isUninterruptedRevalidation && (!future.v7_partialHydration || !initialHydration)) {
137537
138723
  revalidatingFetchers.forEach(rf => {
137538
138724
  let fetcher = state.fetchers.get(rf.key);
@@ -137618,6 +138804,18 @@ function createRouter(init) {
137618
138804
  }
137619
138805
  });
137620
138806
  });
138807
+ // During partial hydration, preserve SSR errors for routes that don't re-run
138808
+ if (future.v7_partialHydration && initialHydration && state.errors) {
138809
+ Object.entries(state.errors).filter(_ref2 => {
138810
+ let [id] = _ref2;
138811
+ return !matchesToLoad.some(m => m.route.id === id);
138812
+ }).forEach(_ref3 => {
138813
+ let [routeId, error] = _ref3;
138814
+ errors = Object.assign(errors || {}, {
138815
+ [routeId]: error
138816
+ });
138817
+ });
138818
+ }
137621
138819
  let updatedFetchers = markFetchRedirectsDone();
137622
138820
  let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);
137623
138821
  let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;
@@ -138160,12 +139358,12 @@ function createRouter(init) {
138160
139358
  blockers
138161
139359
  });
138162
139360
  }
138163
- function shouldBlockNavigation(_ref2) {
139361
+ function shouldBlockNavigation(_ref4) {
138164
139362
  let {
138165
139363
  currentLocation,
138166
139364
  nextLocation,
138167
139365
  historyAction
138168
- } = _ref2;
139366
+ } = _ref4;
138169
139367
  if (blockerFunctions.size === 0) {
138170
139368
  return;
138171
139369
  }
@@ -138776,8 +139974,8 @@ function normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) {
138776
139974
  }
138777
139975
  let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ?
138778
139976
  // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
138779
- Array.from(opts.body.entries()).reduce((acc, _ref3) => {
138780
- let [name, value] = _ref3;
139977
+ Array.from(opts.body.entries()).reduce((acc, _ref5) => {
139978
+ let [name, value] = _ref5;
138781
139979
  return "" + acc + name + "=" + value + "\n";
138782
139980
  }, "") : String(opts.body);
138783
139981
  return {
@@ -166376,6 +167574,55 @@ module.exports = TypeError;
166376
167574
  module.exports = URIError;
166377
167575
 
166378
167576
 
167577
+ /***/ }),
167578
+
167579
+ /***/ 65902:
167580
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
167581
+
167582
+ "use strict";
167583
+
167584
+
167585
+ var $TypeError = __webpack_require__(18709);
167586
+
167587
+ /** @type {import('./RequireObjectCoercible')} */
167588
+ module.exports = function RequireObjectCoercible(value) {
167589
+ if (value == null) {
167590
+ throw new $TypeError((arguments.length > 0 && arguments[1]) || ('Cannot call method on ' + value));
167591
+ }
167592
+ return value;
167593
+ };
167594
+
167595
+
167596
+ /***/ }),
167597
+
167598
+ /***/ 44566:
167599
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
167600
+
167601
+ "use strict";
167602
+
167603
+
167604
+ var $Object = __webpack_require__(89170);
167605
+ var RequireObjectCoercible = __webpack_require__(65902);
167606
+
167607
+ /** @type {import('./ToObject')} */
167608
+ module.exports = function ToObject(value) {
167609
+ RequireObjectCoercible(value);
167610
+ return $Object(value);
167611
+ };
167612
+
167613
+
167614
+ /***/ }),
167615
+
167616
+ /***/ 89170:
167617
+ /***/ ((module) => {
167618
+
167619
+ "use strict";
167620
+
167621
+
167622
+ /** @type {import('.')} */
167623
+ module.exports = Object;
167624
+
167625
+
166379
167626
  /***/ }),
166380
167627
 
166381
167628
  /***/ 75153:
@@ -175177,13 +176424,17 @@ module.exports = hasPropertyDescriptors;
175177
176424
 
175178
176425
 
175179
176426
  var test = {
176427
+ __proto__: null,
175180
176428
  foo: {}
175181
176429
  };
175182
176430
 
175183
176431
  var $Object = Object;
175184
176432
 
176433
+ /** @type {import('.')} */
175185
176434
  module.exports = function hasProto() {
175186
- return { __proto__: test }.foo === test.foo && !({ __proto__: null } instanceof $Object);
176435
+ // @ts-expect-error: TS errors on an inherited property for some reason
176436
+ return { __proto__: test }.foo === test.foo
176437
+ && !(test instanceof $Object);
175187
176438
  };
175188
176439
 
175189
176440
 
@@ -208296,7 +209547,7 @@ module.exports = function shimAssign() {
208296
209547
  "use strict";
208297
209548
 
208298
209549
 
208299
- var RequireObjectCoercible = __webpack_require__(70867);
209550
+ var RequireObjectCoercible = __webpack_require__(65902);
208300
209551
  var callBound = __webpack_require__(61389);
208301
209552
 
208302
209553
  var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
@@ -229293,9 +230544,7 @@ var gOPD = __webpack_require__(95121);
229293
230544
  var $TypeError = __webpack_require__(18709);
229294
230545
  var $floor = GetIntrinsic('%Math.floor%');
229295
230546
 
229296
- /** @typedef {(...args: unknown[]) => unknown} Func */
229297
-
229298
- /** @type {<T extends Func = Func>(fn: T, length: number, loose?: boolean) => T} */
230547
+ /** @type {import('.')} */
229299
230548
  module.exports = function setFunctionLength(fn, length) {
229300
230549
  if (typeof fn !== 'function') {
229301
230550
  throw new $TypeError('`fn` is not a function');
@@ -230121,8 +231370,8 @@ module.exports = str => encodeURIComponent(str).replace(/[!'()*]/g, x => `%${x.c
230121
231370
  "use strict";
230122
231371
 
230123
231372
 
230124
- var RequireObjectCoercible = __webpack_require__(70867);
230125
- var ToString = __webpack_require__(52169);
231373
+ var RequireObjectCoercible = __webpack_require__(65902);
231374
+ var ToString = __webpack_require__(78382);
230126
231375
  var callBound = __webpack_require__(61389);
230127
231376
  var $replace = callBound('String.prototype.replace');
230128
231377
 
@@ -230152,7 +231401,7 @@ module.exports = function trim() {
230152
231401
 
230153
231402
  var callBind = __webpack_require__(20325);
230154
231403
  var define = __webpack_require__(27086);
230155
- var RequireObjectCoercible = __webpack_require__(70867);
231404
+ var RequireObjectCoercible = __webpack_require__(65902);
230156
231405
 
230157
231406
  var implementation = __webpack_require__(32900);
230158
231407
  var getPolyfill = __webpack_require__(45937);
@@ -231552,7 +232801,7 @@ var react_dom__WEBPACK_IMPORTED_MODULE_1___namespace_cache;
231552
232801
  /* harmony import */ var react_router__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10971);
231553
232802
  /* harmony import */ var _remix_run_router__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(29042);
231554
232803
  /**
231555
- * React Router DOM v6.22.0
232804
+ * React Router DOM v6.22.3
231556
232805
  *
231557
232806
  * Copyright (c) Remix Software Inc.
231558
232807
  *
@@ -233001,7 +234250,7 @@ var react__WEBPACK_IMPORTED_MODULE_0___namespace_cache;
233001
234250
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41766);
233002
234251
  /* harmony import */ var _remix_run_router__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(29042);
233003
234252
  /**
233004
- * React Router v6.22.0
234253
+ * React Router v6.22.3
233005
234254
  *
233006
234255
  * Copyright (c) Remix Software Inc.
233007
234256
  *
@@ -233327,7 +234576,26 @@ function useRoutesImpl(routes, locationArg, dataRouterState, future) {
233327
234576
  location = locationFromContext;
233328
234577
  }
233329
234578
  let pathname = location.pathname || "/";
233330
- let remainingPathname = parentPathnameBase === "/" ? pathname : pathname.slice(parentPathnameBase.length) || "/";
234579
+ let remainingPathname = pathname;
234580
+ if (parentPathnameBase !== "/") {
234581
+ // Determine the remaining pathname by removing the # of URL segments the
234582
+ // parentPathnameBase has, instead of removing based on character count.
234583
+ // This is because we can't guarantee that incoming/outgoing encodings/
234584
+ // decodings will match exactly.
234585
+ // We decode paths before matching on a per-segment basis with
234586
+ // decodeURIComponent(), but we re-encode pathnames via `new URL()` so they
234587
+ // match what `window.location.pathname` would reflect. Those don't 100%
234588
+ // align when it comes to encoded URI characters such as % and &.
234589
+ //
234590
+ // So we may end up with:
234591
+ // pathname: "/descendant/a%25b/match"
234592
+ // parentPathnameBase: "/descendant/a%b"
234593
+ //
234594
+ // And the direct substring removal approach won't work :/
234595
+ let parentSegments = parentPathnameBase.replace(/^\//, "").split("/");
234596
+ let segments = pathname.replace(/^\//, "").split("/");
234597
+ remainingPathname = "/" + segments.slice(parentSegments.length).join("/");
234598
+ }
233331
234599
  let matches = (0,_remix_run_router__WEBPACK_IMPORTED_MODULE_1__/* .matchRoutes */ .ue)(routes, {
233332
234600
  pathname: remainingPathname
233333
234601
  });
@@ -235558,17 +236826,6 @@ module.exports = function OrdinaryDefineOwnProperty(O, P, Desc) {
235558
236826
  };
235559
236827
 
235560
236828
 
235561
- /***/ }),
235562
-
235563
- /***/ 70867:
235564
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
235565
-
235566
- "use strict";
235567
-
235568
-
235569
- module.exports = __webpack_require__(71776);
235570
-
235571
-
235572
236829
  /***/ }),
235573
236830
 
235574
236831
  /***/ 62074:
@@ -235740,18 +236997,9 @@ module.exports = function ToNumber(argument) {
235740
236997
  "use strict";
235741
236998
 
235742
236999
 
235743
- var GetIntrinsic = __webpack_require__(45159);
235744
-
235745
- var $Object = GetIntrinsic('%Object%');
235746
-
235747
- var RequireObjectCoercible = __webpack_require__(70867);
235748
-
235749
237000
  // https://262.ecma-international.org/6.0/#sec-toobject
235750
237001
 
235751
- module.exports = function ToObject(value) {
235752
- RequireObjectCoercible(value);
235753
- return $Object(value);
235754
- };
237002
+ module.exports = __webpack_require__(44566);
235755
237003
 
235756
237004
 
235757
237005
  /***/ }),
@@ -236105,21 +237353,24 @@ module.exports = function truncate(x) {
236105
237353
 
236106
237354
  /***/ }),
236107
237355
 
236108
- /***/ 71776:
237356
+ /***/ 78382:
236109
237357
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
236110
237358
 
236111
237359
  "use strict";
236112
237360
 
236113
237361
 
237362
+ var GetIntrinsic = __webpack_require__(45159);
237363
+
237364
+ var $String = GetIntrinsic('%String%');
236114
237365
  var $TypeError = __webpack_require__(18709);
236115
237366
 
236116
- // http://262.ecma-international.org/5.1/#sec-9.10
237367
+ // https://262.ecma-international.org/6.0/#sec-tostring
236117
237368
 
236118
- module.exports = function CheckObjectCoercible(value, optMessage) {
236119
- if (value == null) {
236120
- throw new $TypeError(optMessage || ('Cannot call method on ' + value));
237369
+ module.exports = function ToString(argument) {
237370
+ if (typeof argument === 'symbol') {
237371
+ throw new $TypeError('Cannot convert a Symbol value to a string');
236121
237372
  }
236122
- return value;
237373
+ return $String(argument);
236123
237374
  };
236124
237375
 
236125
237376
 
@@ -236408,7 +237659,7 @@ module.exports = function isPropertyDescriptor(Desc) {
236408
237659
  return false;
236409
237660
  }
236410
237661
 
236411
- for (var key in Desc) { // eslint-disable-line
237662
+ for (var key in Desc) { // eslint-disable-line
236412
237663
  if (hasOwn(Desc, key) && !allowed[key]) {
236413
237664
  return false;
236414
237665
  }
@@ -241170,7 +242421,7 @@ var selectOrdinal = function selectOrdinal() {
241170
242421
  /******/ // This function allow to reference async chunks
241171
242422
  /******/ __webpack_require__.u = (chunkId) => {
241172
242423
  /******/ // return url for filenames based on template
241173
- /******/ return "" + ({"525":"dicom-microscopy-viewer","572":"polySeg"}[chunkId] || chunkId) + ".bundle." + {"50":"55ad62f1f656f5fd5a36","68":"efc5ba2a44aa2b96ee1a","109":"b4fee2a22b622839baf5","121":"f6c25e845985d96c423c","155":"9e3dd18c9a3961232504","164":"710b5db3fef4d536a59f","188":"528e9ad81159c776affa","191":"4850ab82949bb6f0eb73","250":"d8b502b7ef6afc79a87e","270":"fd387adff5b064fca506","290":"8b4d7dfbc7cfe418a0f1","295":"c132f53e1397ef9d432a","297":"81d63bb0b66d63df6d86","317":"dd0879c5035c4b90fad3","339":"591a0a6075220b14c249","342":"a039c24e9f661f3b884d","481":"a2b01ffe06a262fa9375","504":"aa165082e2acc5ccf080","525":"d3a56dc9f62df5e11019","530":"ef1ea9d98f7b377a9d3a","544":"05b543f28d0c124950ef","559":"fc08eab02848a451ed34","572":"99be036bab9b7f011b0c","594":"3a5fa2e7d5636ddccb32","644":"1e77691d2eeb96a423b0","704":"842ada45436f1fb029aa","724":"294a41af83a5af33f3cc","726":"2bdb443d1b5620d74e6e","835":"15aff0b7433bb0dd6d6d","862":"c8eba798644149650775","889":"a776c87be9e3580f3437","905":"73a711d0255cb988fa6e","907":"6932f0458b9e0143c18a","931":"d270a1fda9a2836c3cc5","939":"84ee0b844023d924a22b","961":"6cf1599ed3a2871c040f","963":"874395d7b2d80f9e5831"}[chunkId] + ".js";
242424
+ /******/ return "" + ({"525":"dicom-microscopy-viewer","572":"polySeg"}[chunkId] || chunkId) + ".bundle." + {"41":"58b85dd990fb6fac615e","90":"abde898ebd3c74f521f9","109":"b4fee2a22b622839baf5","121":"fda405f29003c308ce09","155":"a57744809d0f46030ee0","164":"ff12d6019a627cda2a6c","188":"c448aed48915741e9f97","191":"4850ab82949bb6f0eb73","270":"16ac8114c5c4ce006f4a","290":"8b4d7dfbc7cfe418a0f1","295":"57700cd41fd87e1521b4","297":"81d63bb0b66d63df6d86","339":"57dac3644803cefe3e3d","342":"a039c24e9f661f3b884d","448":"d195aba3aef25ec286d1","481":"a2b01ffe06a262fa9375","504":"aa165082e2acc5ccf080","525":"d3a56dc9f62df5e11019","530":"72d9812f117036615a38","544":"c3009e245ceb1554c70a","559":"05bd51e94422a2cab116","572":"c1cec6312eb6c6dc3701","594":"14b122ab995e4b13e652","638":"a63003e18bed65f227bb","644":"1e77691d2eeb96a423b0","699":"efc67171e6d212f25a24","701":"bc40f1a7d5d6b1a4dd38","724":"3945f8d2e9c8b0b23628","726":"2bdb443d1b5620d74e6e","835":"15aff0b7433bb0dd6d6d","862":"d787dac01f4567560a42","889":"ffc727aa6d1a74f2138d","905":"6b5b42b2403e4676bb3a","907":"fbd5768fa5b53f9d3f86","931":"d270a1fda9a2836c3cc5","939":"84ee0b844023d924a22b","961":"8bb5a713fc5a3817c6a6"}[chunkId] + ".js";
241174
242425
  /******/ };
241175
242426
  /******/ })();
241176
242427
  /******/
@@ -241279,6 +242530,9 @@ var selectOrdinal = function selectOrdinal() {
241279
242530
  /******/
241280
242531
  /******/ linkTag.rel = "stylesheet";
241281
242532
  /******/ linkTag.type = "text/css";
242533
+ /******/ if (__webpack_require__.nc) {
242534
+ /******/ linkTag.nonce = __webpack_require__.nc;
242535
+ /******/ }
241282
242536
  /******/ var onLinkComplete = (event) => {
241283
242537
  /******/ // avoid mem leaks.
241284
242538
  /******/ linkTag.onerror = linkTag.onload = null;
@@ -241336,7 +242590,7 @@ var selectOrdinal = function selectOrdinal() {
241336
242590
  /******/ };
241337
242591
  /******/
241338
242592
  /******/ __webpack_require__.f.miniCss = (chunkId, promises) => {
241339
- /******/ var cssChunks = {"50":1,"155":1,"481":1,"544":1,"889":1,"963":1};
242593
+ /******/ var cssChunks = {"155":1,"481":1,"544":1,"638":1,"701":1,"889":1};
241340
242594
  /******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);
241341
242595
  /******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {
241342
242596
  /******/ promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(() => {
@@ -241458,9 +242712,6 @@ var selectOrdinal = function selectOrdinal() {
241458
242712
  /******/ /* webpack/runtime/chunk prefetch trigger */
241459
242713
  /******/ (() => {
241460
242714
  /******/ var chunkToChildrenMap = {
241461
- /******/ "50": [
241462
- /******/ 295
241463
- /******/ ],
241464
242715
  /******/ "155": [
241465
242716
  /******/ 530,
241466
242717
  /******/ 862
@@ -241471,14 +242722,17 @@ var selectOrdinal = function selectOrdinal() {
241471
242722
  /******/ "559": [
241472
242723
  /******/ 530
241473
242724
  /******/ ],
242725
+ /******/ "638": [
242726
+ /******/ 295
242727
+ /******/ ],
242728
+ /******/ "701": [
242729
+ /******/ 889
242730
+ /******/ ],
241474
242731
  /******/ "907": [
241475
242732
  /******/ 297
241476
242733
  /******/ ],
241477
242734
  /******/ "961": [
241478
242735
  /******/ 939
241479
- /******/ ],
241480
- /******/ "963": [
241481
- /******/ 889
241482
242736
  /******/ ]
241483
242737
  /******/ };
241484
242738
  /******/ __webpack_require__.f.prefetch = (chunkId, promises) => (Promise.all(promises).then(() => {
@@ -241492,7 +242746,7 @@ var selectOrdinal = function selectOrdinal() {
241492
242746
  /******/ // startup
241493
242747
  /******/ // Load entry module and return exports
241494
242748
  /******/ // This entry module is referenced by other modules so it can't be inlined
241495
- /******/ var __webpack_exports__ = __webpack_require__(45573);
242749
+ /******/ var __webpack_exports__ = __webpack_require__(68870);
241496
242750
  /******/
241497
242751
  /******/ })()
241498
242752
  ;