feat: Add White Labelling, Hanging Protocols, and tons of Extensions / Mode fixes

* modified

* new files in existing extensions/libraries/modes

* fixed bugs and tests

* Clean up

* fix: viewport display fixed

* Fixed configs for deployment

* Removed unnecessary files and functions

* Fixed default HP module

* Added white labelling

* Fixed hash routing

* Removed unnecessary routers

Co-authored-by: Alireza Sedghi <ar.sedghi@gmail.com>
This commit is contained in:
Erik ZieglerandAlireza Sedghi authored and GitHub committed 2021-05-28 14:32:48 -04:00
1 parent 0db81b30f3
commit 99b8dc4759
93 files changed
+3825 -1293

No files matched your search

@@ -10,9 +10,9 @@ services:
ohif_viewer:
build:
# Project root
context: ./../../
context: ./../../../../
# Relative to context
dockerfile: ./docker/OpenResty-Orthanc/dockerfile
dockerfile: ./platform/viewer/.recipes/OpenResty-Orthanc/dockerfile
image: webapp:latest
container_name: webapp
volumes:
@@ -23,20 +23,39 @@
# Stage 1: Build the application
FROM node:11.2.0-slim as builder
FROM node:12.22.1-slim as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# Copy Files
COPY .docker /usr/src/app/.docker
COPY .webpack /usr/src/app/.webpack
COPY extensions /usr/src/app/extensions
COPY modes /usr/src/app/modes
COPY platform /usr/src/app/platform
COPY .browserslistrc /usr/src/app/.browserslistrc
COPY aliases.config.js /usr/src/app/aliases.config.js
COPY babel.config.js /usr/src/app/babel.config.js
COPY lerna.json /usr/src/app/lerna.json
COPY package.json /usr/src/app/package.json
COPY postcss.config.js /usr/src/app/postcss.config.js
COPY yarn.lock /usr/src/app/yarn.lock
# ADD . /usr/src/app/
RUN yarn config set workspaces-experimental true
RUN yarn install
ENV APP_CONFIG=config/docker_openresty-orthanc.js
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
COPY yarn.lock /usr/src/app/yarn.lock
ENV QUICK_BUILD true
RUN yarn run build
# ADD . /usr/src/app/
# RUN yarn install
# RUN yarn run build:web
ADD . /usr/src/app/
RUN yarn install
RUN yarn run build:web
# Stage 2: Bundle the built application into a Docker container
# which runs openresty (nginx) using Alpine Linux
@@ -60,6 +79,6 @@ RUN luarocks install lua-resty-openidc
RUN luarocks install luacrypto
# Copy build output to image
COPY --from=builder /usr/src/app/build /var/www/html
COPY --from=builder /usr/src/app/platform/viewer/dist /var/www/html
ENTRYPOINT ["/usr/local/openresty/nginx/sbin/nginx", "-g", "daemon off;"]
+21
View File
@@ -0,0 +1,21 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
+1 -1
View File
@@ -55,7 +55,7 @@
"@types/react": "^16.0.0",
"classnames": "^2.2.6",
"core-js": "^3.2.1",
"cornerstone-math": "^0.1.8",
"cornerstone-math": "^0.1.9",
"cornerstone-tools": "5.1.2",
"cornerstone-wado-image-loader": "^3.1.2",
"dcmjs": "0.16.1",
+19
View File
@@ -25,5 +25,24 @@ window.config = {
},
},
],
// whiteLabeling: {
// /* Optional: Should return a React component to be rendered in the "Logo" section of the application's Top Navigation bar */
// createLogoComponentFn: function (React) {
// return React.createElement(
// 'a',
// {
// target: '_self',
// rel: 'noopener noreferrer',
// className: 'text-purple-600 line-through',
// href: '/',
// },
// React.createElement('img',
// {
// src: './customLogo.svg',
// className: 'w-8 h-8',
// }
// ))
// },
// },
defaultDataSourceName: 'dicomweb',
};
@@ -1,9 +1,14 @@
window.config = {
routerBasename: '/',
showStudyList: true,
servers: {
dicomWeb: [
{
extensions: [],
modes: [],
dataSources: [
{
friendlyName: 'Orthanc Server',
namespace: 'org.ohif.default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
name: 'Orthanc',
wadoUriRoot: '/wado',
qidoRoot: '/dicom-web',
@@ -12,6 +17,7 @@ window.config = {
imageRendering: 'wadors',
thumbnailRendering: 'wadors',
},
],
},
},
],
defaultDataSourceName: 'dicomweb',
};
@@ -1,10 +1,14 @@
window.config = {
routerBasename: '/',
showStudyList: true,
servers: {
// This is an array, but we'll only use the first entry for now
dicomWeb: [
{
extensions: [],
modes: [],
dataSources: [
{
friendlyName: 'Orthanc Server',
namespace: 'org.ohif.default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
name: 'Orthanc',
wadoUriRoot: 'http://127.0.0.1/pacs/wado',
qidoRoot: 'http://127.0.0.1/pacs/dicom-web',
@@ -12,11 +16,8 @@ window.config = {
qidoSupportsIncludeField: false,
imageRendering: 'wadors',
thumbnailRendering: 'wadors',
// requestOptions: {
// undefined to use JWT + Bearer auth
// auth: 'orthanc:orthanc',
// },
},
],
},
},
],
defaultDataSourceName: 'dicomweb',
};
@@ -1,11 +1,14 @@
window.config = {
// default: '/'
routerBasename: '/',
// default: ''
showStudyList: true,
servers: {
dicomWeb: [
{
extensions: [],
modes: [],
dataSources: [
{
friendlyName: 'DCM4CHEE Server',
namespace: 'org.ohif.default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
configuration: {
name: 'DCM4CHEE',
wadoUriRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado',
qidoRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs',
@@ -17,7 +20,8 @@ window.config = {
auth: 'admin:admin',
},
},
],
},
},
],
studyListFunctionsEnabled: true,
defaultDataSourceName: 'dicomweb',
};
+65
View File
@@ -0,0 +1,65 @@
<svg xmlns="http://www.w3.org/2000/svg" width="265" height="24" viewBox="0 0 265 24">
<g fill="none" fill-rule="evenodd">
<g>
<path fill="#FFF" d="M2.431 8.257c.733.734 1.582 1.12 2.547 1.12.964 0 1.813-.348 2.546-1.12.733-.733 1.08-1.736 1.08-3.01 0-1.273-.385-2.276-1.118-3.01-.733-.732-1.582-1.08-2.547-1.08-.965 0-1.814.348-2.547 1.08-.733.734-1.119 1.737-1.119 3.01.077 1.274.425 2.316 1.158 3.01m7.563-3.01c0 1.583-.463 2.856-1.428 3.82-.965.965-2.122 1.467-3.55 1.467-1.427 0-2.624-.502-3.588-1.505C.463 8.026 0 6.753 0 5.21c0-1.543.502-2.817 1.466-3.781C2.431.463 3.627 0 5.016 0c1.35 0 2.547.463 3.511 1.428.965.964 1.467 2.238 1.467 3.82" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M2.431 8.257c.733.734 1.582 1.12 2.547 1.12.964 0 1.813-.348 2.546-1.12.733-.733 1.08-1.736 1.08-3.01 0-1.273-.385-2.276-1.118-3.01-.733-.732-1.582-1.08-2.547-1.08-.965 0-1.814.348-2.547 1.08-.733.734-1.119 1.737-1.119 3.01.077 1.274.425 2.316 1.158 3.01zm7.563-3.01c0 1.583-.463 2.856-1.428 3.82-.965.965-2.122 1.467-3.55 1.467-1.427 0-2.624-.502-3.588-1.505C.463 8.026 0 6.753 0 5.21c0-1.543.502-2.817 1.466-3.781C2.431.463 3.627 0 5.016 0c1.35 0 2.547.463 3.511 1.428.965.964 1.467 2.238 1.467 3.82z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M13.35 6.945c0 .85.232 1.467.657 1.93.424.463.964.694 1.582.694.617 0 1.119-.231 1.543-.733.425-.501.618-1.119.618-1.929s-.193-1.428-.618-1.89c-.424-.464-.926-.734-1.543-.734-.618 0-1.158.231-1.582.695-.425.463-.656 1.119-.656 1.967m.964 6.715h-2.893c-.116 0-.193-.04-.193-.155v-.617c0-.116.077-.155.193-.155h.81V4.322h-.772c-.116 0-.193-.039-.193-.155V3.55c0-.116.077-.154.193-.154h1.698c.116 0 .193.038.193.154v1.119c.193-.386.463-.733.887-1.003.425-.27.926-.425 1.505-.425.965 0 1.737.347 2.354 1.003.617.656.887 1.544.887 2.624s-.308 1.968-.887 2.663c-.579.694-1.35 1.003-2.354 1.003-.579 0-1.08-.154-1.505-.424-.386-.27-.694-.618-.849-1.004h-.038c.038.31.038.54.038.656v2.933h.926c.116 0 .193.038.193.154v.618c0 .154-.077.193-.193.193" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M13.35 6.945c0 .85.232 1.467.657 1.93.424.463.964.694 1.582.694.617 0 1.119-.231 1.543-.733.425-.501.618-1.119.618-1.929s-.193-1.428-.618-1.89c-.424-.464-.926-.734-1.543-.734-.618 0-1.158.231-1.582.695-.425.463-.656 1.119-.656 1.967zm.965 6.715h-2.893c-.116 0-.193-.04-.193-.155v-.617c0-.116.077-.155.193-.155h.81V4.322h-.772c-.116 0-.193-.039-.193-.155V3.55c0-.116.077-.154.193-.154h1.698c.116 0 .193.038.193.154v1.119c.193-.386.463-.733.887-1.003.425-.27.926-.425 1.505-.425.965 0 1.737.347 2.354 1.003.617.656.887 1.544.887 2.624s-.308 1.968-.887 2.663c-.579.694-1.35 1.003-2.354 1.003-.579 0-1.08-.154-1.505-.424-.386-.27-.694-.618-.849-1.004h-.038c.038.31.038.54.038.656v2.933h.926c.116 0 .193.038.193.154v.618c0 .154-.077.193-.193.193z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M24.811 4.746c-.347-.347-.81-.54-1.39-.54-.578 0-1.08.154-1.465.501-.425.31-.656.81-.734 1.467h4.168c-.039-.618-.232-1.08-.579-1.428m1.582 2.315h-5.17c.038.81.308 1.39.771 1.852.463.464 1.003.656 1.582.656.579 0 1.08-.115 1.505-.386.424-.231.694-.501.849-.733.077-.077.154-.115.27-.038l.386.386c.039.038.077.115.077.154 0 .039-.038.077-.077.154s-.116.155-.27.309c-.155.154-.309.309-.579.502-.27.192-.579.347-.965.463-.386.115-.81.193-1.234.193-1.004 0-1.853-.348-2.509-1.004-.656-.656-1.003-1.543-1.003-2.662s.347-2.007 1.003-2.662c.656-.656 1.505-.965 2.47-.965.965 0 1.736.309 2.276.926.54.617.85 1.466.85 2.547v.115c-.04.116-.116.193-.232.193" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M24.811 4.746c-.347-.347-.81-.54-1.39-.54-.578 0-1.08.154-1.465.501-.425.31-.656.81-.734 1.467h4.168c-.039-.618-.232-1.08-.579-1.428zm1.582 2.315h-5.17c.038.81.308 1.39.771 1.852.463.464 1.003.656 1.582.656.579 0 1.08-.115 1.505-.386.424-.231.694-.501.849-.733.077-.077.154-.115.27-.038l.386.386c.039.038.077.115.077.154 0 .039-.038.077-.077.154s-.116.155-.27.309c-.155.154-.309.309-.579.502-.27.192-.579.347-.965.463-.386.115-.81.193-1.234.193-1.004 0-1.853-.348-2.509-1.004-.656-.656-1.003-1.543-1.003-2.662s.347-2.007 1.003-2.662c.656-.656 1.505-.965 2.47-.965.965 0 1.736.309 2.276.926.54.617.85 1.466.85 2.547v.115c-.04.116-.116.193-.232.193z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M35.345 10.457h-1.35c-.425 0-.618-.193-.618-.618V6.058c0-.54-.154-1.003-.386-1.312-.27-.309-.656-.463-1.157-.463-.733 0-1.312.309-1.737.926-.038.039-.116.155-.193.309v3.936h.772c.116 0 .193.038.193.154v.617c0 .116-.077.155-.193.155h-2.74c-.115 0-.192-.039-.192-.155v-.617c0-.116.077-.154.192-.154h.772V4.322h-.772c-.115 0-.192-.039-.192-.155V3.55c0-.116.077-.154.192-.154h1.698c.116 0 .193.038.193.154l-.038.965h.038c.502-.85 1.274-1.235 2.315-1.235.772 0 1.35.231 1.814.694.463.463.656 1.042.656 1.814v3.704h.81c.116 0 .193.039.193.155v.617c-.077.116-.116.193-.27.193" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M35.345 10.457h-1.35c-.425 0-.618-.193-.618-.618V6.058c0-.54-.154-1.003-.386-1.312-.27-.309-.656-.463-1.157-.463-.733 0-1.312.309-1.737.926-.038.039-.116.155-.193.309v3.936h.772c.116 0 .193.038.193.154v.617c0 .116-.077.155-.193.155h-2.74c-.115 0-.192-.039-.192-.155v-.617c0-.116.077-.154.192-.154h.772V4.322h-.772c-.115 0-.192-.039-.192-.155V3.55c0-.116.077-.154.192-.154h1.698c.116 0 .193.038.193.154l-.038.965h.038c.502-.85 1.274-1.235 2.315-1.235.772 0 1.35.231 1.814.694.463.463.656 1.042.656 1.814v3.704h.81c.116 0 .193.039.193.155v.617c-.077.116-.116.193-.27.193z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M51.513 10.457H48.04c-.116 0-.193-.039-.193-.155V9.57c0-.115.039-.154.193-.154h1.119V5.904h-5.364v3.511h1.12c.115 0 .192.039.192.154v.733c0 .116-.077.155-.193.155H41.48c-.116 0-.193-.039-.193-.155V9.57c0-.115.077-.154.193-.154h1.08V1.196h-1.08c-.116 0-.193-.038-.193-.154V.309c0-.116.077-.155.193-.155h3.434c.116 0 .193.039.193.155v.733c0 .116-.077.154-.193.154h-1.119v3.589h5.364V1.196h-1.12c-.115 0-.192-.038-.192-.154V.309c0-.116.039-.155.193-.155h3.473c.115 0 .192.039.192.155v.733c0 .116-.038.154-.192.154h-1.12v8.18h1.12c.115 0 .192.039.192.155v.733c0 .116-.077.193-.192.193" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M51.513 10.457H48.04c-.116 0-.193-.039-.193-.155V9.57c0-.115.039-.154.193-.154h1.119V5.904h-5.364v3.511h1.12c.115 0 .192.039.192.154v.733c0 .116-.077.155-.193.155H41.48c-.116 0-.193-.039-.193-.155V9.57c0-.115.077-.154.193-.154h1.08V1.196h-1.08c-.116 0-.193-.038-.193-.154V.309c0-.116.077-.155.193-.155h3.434c.116 0 .193.039.193.155v.733c0 .116-.077.154-.193.154h-1.119v3.589h5.364V1.196h-1.12c-.115 0-.192-.038-.192-.154V.309c0-.116.039-.155.193-.155h3.473c.115 0 .192.039.192.155v.733c0 .116-.038.154-.192.154h-1.12v8.18h1.12c.115 0 .192.039.192.155v.733c0 .116-.077.193-.192.193z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M57.34 4.746c-.348-.347-.811-.54-1.39-.54-.579 0-1.08.154-1.466.501-.425.31-.656.81-.733 1.467h4.167c-.039-.618-.232-1.08-.579-1.428m1.544 2.315h-5.171c.039.81.309 1.39.772 1.852.463.425 1.003.656 1.582.656.578 0 1.08-.115 1.505-.386.424-.231.694-.501.849-.733.077-.077.154-.115.27-.038l.385.386c.039.038.078.115.078.154 0 .039-.039.077-.078.154-.038.077-.115.155-.27.309-.154.154-.308.309-.578.502-.27.192-.58.347-.965.463-.386.115-.81.193-1.235.193-1.003 0-1.852-.348-2.508-1.004-.656-.656-1.003-1.543-1.003-2.662s.347-2.007 1.003-2.662c.656-.656 1.505-.965 2.47-.965.964 0 1.736.309 2.276.926.54.617.85 1.466.85 2.547v.115c-.04.116-.078.193-.232.193" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M57.34 4.746c-.348-.347-.811-.54-1.39-.54-.579 0-1.08.154-1.466.501-.425.31-.656.81-.733 1.467h4.167c-.039-.618-.232-1.08-.579-1.428zm1.543 2.315h-5.171c.039.81.309 1.39.772 1.852.463.425 1.003.656 1.582.656.578 0 1.08-.115 1.505-.386.424-.231.694-.501.849-.733.077-.077.154-.115.27-.038l.385.386c.039.038.078.115.078.154 0 .039-.039.077-.078.154-.038.077-.115.155-.27.309-.154.154-.308.309-.578.502-.27.192-.58.347-.965.463-.386.115-.81.193-1.235.193-1.003 0-1.852-.348-2.508-1.004-.656-.656-1.003-1.543-1.003-2.662s.347-2.007 1.003-2.662c.656-.656 1.505-.965 2.47-.965.964 0 1.736.309 2.276.926.54.617.85 1.466.85 2.547v.115c-.04.116-.078.193-.232.193z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M65.25 7.138h-1.12c-.54 0-1.003.04-1.389.078-.347.038-.694.193-.926.385-.27.193-.386.464-.386.81 0 .348.155.618.425.811.27.193.617.309 1.08.309.926 0 1.698-.425 2.354-1.235l-.039-1.158zm2.006 3.319H66.02c-.424 0-.617-.193-.617-.618v-.733h-.039c-.694.965-1.62 1.467-2.817 1.467-.694 0-1.234-.193-1.698-.54-.424-.348-.656-.85-.656-1.467 0-.772.348-1.35 1.042-1.736.695-.386 1.621-.54 2.817-.54h1.196v-.155c0-1.196-.617-1.813-1.852-1.813-.578 0-1.003.038-1.273.154-.27.116-.425.193-.54.27-.116.077-.193.116-.232.154-.154.116-.231.116-.309.04l-.385-.503c-.078-.077-.04-.154.038-.231.154-.232.502-.425 1.003-.617.502-.193 1.12-.31 1.814-.31 2.006 0 3.01.966 3.01 2.856v3.319h.81c.116 0 .193.038.193.154v.617c-.077.155-.154.232-.27.232z" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M65.25 7.138h-1.12c-.54 0-1.003.04-1.389.078-.347.038-.694.193-.926.385-.27.193-.386.464-.386.81 0 .348.155.618.425.811.27.193.617.309 1.08.309.926 0 1.698-.425 2.354-1.235l-.039-1.158zm2.006 3.319H66.02c-.424 0-.617-.193-.617-.618v-.733h-.039c-.694.965-1.62 1.467-2.817 1.467-.694 0-1.234-.193-1.698-.54-.424-.348-.656-.85-.656-1.467 0-.772.348-1.35 1.042-1.736.695-.386 1.621-.54 2.817-.54h1.196v-.155c0-1.196-.617-1.813-1.852-1.813-.578 0-1.003.038-1.273.154-.27.116-.425.193-.54.27-.116.077-.193.116-.232.154-.154.116-.231.116-.309.04l-.385-.503c-.078-.077-.04-.154.038-.231.154-.232.502-.425 1.003-.617.502-.193 1.12-.31 1.814-.31 2.006 0 3.01.966 3.01 2.856v3.319h.81c.116 0 .193.038.193.154v.617c-.077.155-.154.232-.27.232z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M71.385 10.457h-2.74c-.116 0-.193-.039-.193-.155v-.617c0-.116.077-.154.193-.154h.772V1.08h-.772c-.116 0-.193-.04-.193-.155V.309c0-.116.077-.155.193-.155h1.582c.27 0 .386.116.386.348v8.952h.772c.115 0 .192.038.192.154v.617c0 .155-.077.232-.192.232" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M71.385 10.457h-2.74c-.116 0-.193-.039-.193-.155v-.617c0-.116.077-.154.193-.154h.772V1.08h-.772c-.116 0-.193-.04-.193-.155V.309c0-.116.077-.155.193-.155h1.582c.27 0 .386.116.386.348v8.952h.772c.115 0 .192.038.192.154v.617c0 .155-.077.232-.192.232z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M77.404 9.724c.039.038.039.077.039.116 0 .038-.04.077-.078.154-.424.386-.964.54-1.582.54-.617 0-1.157-.193-1.582-.617-.424-.425-.617-1.004-.617-1.814V4.322h-.81c-.155 0-.193-.078-.193-.193V3.55c0-.116.077-.193.193-.193h.81V1.89c0-.155.077-.193.193-.193h.81c.116 0 .193.077.193.193v1.466h1.814c.154 0 .193.077.193.193v.579c0 .115-.078.193-.193.193H74.78v3.743c0 .462.116.848.309 1.08.193.231.501.347.849.347.347 0 .617-.077.81-.27.077-.077.193-.077.27 0l.386.502z" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M77.404 9.724c.039.038.039.077.039.116 0 .038-.04.077-.078.154-.424.386-.964.54-1.582.54-.617 0-1.157-.193-1.582-.617-.424-.425-.617-1.004-.617-1.814V4.322h-.81c-.155 0-.193-.078-.193-.193V3.55c0-.116.077-.193.193-.193h.81V1.89c0-.155.077-.193.193-.193h.81c.116 0 .193.077.193.193v1.466h1.814c.154 0 .193.077.193.193v.579c0 .115-.078.193-.193.193H74.78v3.743c0 .462.116.848.309 1.08.193.231.501.347.849.347.347 0 .617-.077.81-.27.077-.077.193-.077.27 0l.386.502z" transform="translate(1 1) translate(33.803 4.985)"/>
<path fill="#FFF" d="M85.893 10.457h-1.35c-.425 0-.618-.193-.618-.618V6.058c0-.54-.154-1.003-.386-1.312-.27-.309-.656-.463-1.157-.463-.386 0-.695.077-.888.193-.193.116-.347.231-.463.309-.116.077-.193.193-.27.27-.116.154-.193.309-.309.463v3.936h.772c.116 0 .193.038.193.154v.617c0 .116-.077.155-.193.155h-2.74c-.115 0-.193-.039-.193-.155v-.617c0-.116.078-.154.194-.154h.771V1.08h-.771c-.116 0-.194-.038-.194-.154V.309c0-.116.078-.155.194-.155h1.813c.116 0 .193.039.193.155V3.51c0 .31 0 .618-.039.888h.039c.463-.733 1.196-1.12 2.238-1.12.772 0 1.35.232 1.813.695.463.463.656 1.042.656 1.814v3.704h.81c.116 0 .194.039.194.155v.617c-.116.116-.193.193-.309.193" transform="translate(1 1) translate(33.803 4.985)"/>
<path stroke="#FFF" stroke-width=".75" d="M85.893 10.457h-1.35c-.425 0-.618-.193-.618-.618V6.058c0-.54-.154-1.003-.386-1.312-.27-.309-.656-.463-1.157-.463-.386 0-.695.077-.888.193-.193.116-.347.231-.463.309-.116.077-.193.193-.27.27-.116.154-.193.309-.309.463v3.936h.772c.116 0 .193.038.193.154v.617c0 .116-.077.155-.193.155h-2.74c-.115 0-.193-.039-.193-.155v-.617c0-.116.078-.154.194-.154h.771V1.08h-.771c-.116 0-.194-.038-.194-.154V.309c0-.116.078-.155.194-.155h1.813c.116 0 .193.039.193.155V3.51c0 .31 0 .618-.039.888h.039c.463-.733 1.196-1.12 2.238-1.12.772 0 1.35.232 1.813.695.463.463.656 1.042.656 1.814v3.704h.81c.116 0 .194.039.194.155v.617c-.116.116-.193.193-.309.193z" transform="translate(1 1) translate(33.803 4.985)"/>
<g>
<path fill="#FFF" d="M3.627 10.302H.193c-.116 0-.193-.038-.193-.154v-.733c0-.116.077-.154.193-.154h1.08V1.042H.193C.077 1.042 0 1.003 0 .888V.154C0 .04.077 0 .193 0h3.434c.116 0 .193.039.193.154v.734c0 .115-.077.154-.193.154H2.508v8.18h1.119c.116 0 .193.039.193.154v.734c0 .115-.077.192-.193.192" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M3.627 10.302H.193c-.116 0-.193-.038-.193-.154v-.733c0-.116.077-.154.193-.154h1.08V1.042H.193C.077 1.042 0 1.003 0 .888V.154C0 .04.077 0 .193 0h3.434c.116 0 .193.039.193.154v.734c0 .115-.077.154-.193.154H2.508v8.18h1.119c.116 0 .193.039.193.154v.734c0 .115-.077.192-.193.192z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M17.094 10.302h-1.35c-.232 0-.387-.038-.464-.154-.116-.077-.154-.231-.154-.463V5.904c0-.54-.116-1.004-.386-1.312-.27-.309-.656-.463-1.158-.463-.771 0-1.35.347-1.775 1.003.039.154.077.347.077.579v3.627h.81c.117 0 .194.038.194.154v.618c0 .115-.039.154-.193.154h-2.74c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h.772V5.904c0-.54-.154-1.004-.386-1.312-.27-.309-.656-.463-1.158-.463-.385 0-.694.077-.887.193-.193.116-.347.231-.463.308-.116.078-.193.193-.27.27-.116.155-.193.31-.309.464v3.935h.695c.116 0 .193.039.193.155v.617c0 .116-.039.154-.193.154H5.248c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h.771V4.206h-.771c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.389c.154 0 .27.038.347.077.077.077.116.154.116.347l-.039.734H7.1c.501-.85 1.273-1.235 2.315-1.235s1.775.386 2.16 1.196c.541-.81 1.313-1.196 2.316-1.196.772 0 1.35.231 1.775.694.424.463.656 1.042.656 1.814v3.704h.81c.116 0 .193.039.193.154v.618c-.038.038-.116.115-.231.115" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M17.094 10.302h-1.35c-.232 0-.387-.038-.464-.154-.116-.077-.154-.231-.154-.463V5.904c0-.54-.116-1.004-.386-1.312-.27-.309-.656-.463-1.158-.463-.771 0-1.35.347-1.775 1.003.039.154.077.347.077.579v3.627h.81c.117 0 .194.038.194.154v.618c0 .115-.039.154-.193.154h-2.74c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h.772V5.904c0-.54-.154-1.004-.386-1.312-.27-.309-.656-.463-1.158-.463-.385 0-.694.077-.887.193-.193.116-.347.231-.463.308-.116.078-.193.193-.27.27-.116.155-.193.31-.309.464v3.935h.695c.116 0 .193.039.193.155v.617c0 .116-.039.154-.193.154H5.248c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h.771V4.206h-.771c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.389c.154 0 .27.038.347.077.077.077.116.154.116.347l-.039.734H7.1c.501-.85 1.273-1.235 2.315-1.235s1.775.386 2.16 1.196c.541-.81 1.313-1.196 2.316-1.196.772 0 1.35.231 1.775.694.424.463.656 1.042.656 1.814v3.704h.81c.116 0 .193.039.193.154v.618c-.038.038-.116.115-.231.115z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M23.267 6.984h-1.119c-.54 0-1.003.039-1.389.077-.347.039-.694.193-.926.386-.27.193-.386.463-.386.81 0 .348.155.618.425.81.27.194.617.31 1.08.31.926 0 1.698-.425 2.354-1.235l-.039-1.158zm2.007 3.318h-1.235c-.424 0-.617-.192-.617-.617v-.733h-.039c-.694.965-1.62 1.466-2.817 1.466-.694 0-1.234-.193-1.697-.54-.425-.347-.656-.849-.656-1.466 0-.772.347-1.35 1.042-1.736.694-.387 1.62-.54 2.816-.54h1.196V5.98c0-1.196-.617-1.814-1.852-1.814-.579 0-1.003.04-1.273.155-.27.115-.425.193-.54.27-.116.077-.193.115-.232.154-.154.116-.231.116-.309.039l-.385-.502c-.077-.077-.039-.154.038-.231.155-.232.502-.425 1.003-.618.502-.193 1.12-.309 1.814-.309 2.007 0 3.01.965 3.01 2.856v3.318h.81c.116 0 .193.039.193.155v.617c-.077.154-.154.231-.27.231z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M23.267 6.984h-1.119c-.54 0-1.003.039-1.389.077-.347.039-.694.193-.926.386-.27.193-.386.463-.386.81 0 .348.155.618.425.81.27.194.617.31 1.08.31.926 0 1.698-.425 2.354-1.235l-.039-1.158zm2.007 3.318h-1.235c-.424 0-.617-.192-.617-.617v-.733h-.039c-.694.965-1.62 1.466-2.817 1.466-.694 0-1.234-.193-1.697-.54-.425-.347-.656-.849-.656-1.466 0-.772.347-1.35 1.042-1.736.694-.387 1.62-.54 2.816-.54h1.196V5.98c0-1.196-.617-1.814-1.852-1.814-.579 0-1.003.04-1.273.155-.27.115-.425.193-.54.27-.116.077-.193.115-.232.154-.154.116-.231.116-.309.039l-.385-.502c-.077-.077-.039-.154.038-.231.155-.232.502-.425 1.003-.618.502-.193 1.12-.309 1.814-.309 2.007 0 3.01.965 3.01 2.856v3.318h.81c.116 0 .193.039.193.155v.617c-.077.154-.154.231-.27.231z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M27.55 6.753c0 .81.193 1.427.618 1.929.424.463.965.733 1.582.733.617 0 1.158-.231 1.582-.733.425-.502.617-1.12.617-1.93 0-.81-.192-1.427-.617-1.929-.424-.501-.926-.694-1.582-.694-.617 0-1.158.231-1.582.733-.386.463-.617 1.119-.617 1.89m2.122 6.908c-.463 0-.849-.039-1.08-.116-.232-.077-.425-.116-.58-.193-.154-.039-.27-.116-.385-.155-.116-.038-.193-.115-.309-.154-.424-.27-.579-.463-.463-.617l.386-.54c.038-.077.154-.077.231 0l.078.077c.038.038.115.077.154.116.038.038.116.077.231.154.078.038.193.116.31.154.115.039.23.077.385.116.309.077.656.116 1.042.116.694 0 1.235-.155 1.659-.502.425-.347.617-.849.617-1.543v-1.66c-.192.386-.463.734-.848 1.042-.386.31-.888.425-1.505.425-.965 0-1.775-.347-2.354-1.003-.579-.695-.888-1.582-.888-2.663 0-1.08.309-1.968.888-2.624.579-.656 1.389-1.003 2.354-1.003.578 0 1.08.154 1.505.424.424.27.694.618.887 1.004h.039v-1.12c0-.115.038-.154.192-.154h1.698c.116 0 .193.039.193.155v.617c0 .116-.038.154-.193.154h-.771v6.367c0 1.042-.31 1.814-.927 2.315-.694.54-1.504.81-2.546.81" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M27.55 6.753c0 .81.193 1.427.618 1.929.424.463.965.733 1.582.733.617 0 1.158-.231 1.582-.733.425-.502.617-1.12.617-1.93 0-.81-.192-1.427-.617-1.929-.424-.501-.926-.694-1.582-.694-.617 0-1.158.231-1.582.733-.386.463-.617 1.119-.617 1.89zm2.123 6.907c-.463 0-.849-.039-1.08-.116-.232-.077-.425-.116-.58-.193-.154-.039-.27-.116-.385-.155-.116-.038-.193-.115-.309-.154-.424-.27-.579-.463-.463-.617l.386-.54c.038-.077.154-.077.231 0l.078.077c.038.038.115.077.154.116.038.038.116.077.231.154.078.038.193.116.31.154.115.039.23.077.385.116.309.077.656.116 1.042.116.694 0 1.235-.155 1.659-.502.425-.347.617-.849.617-1.543v-1.66c-.192.386-.463.734-.848 1.042-.386.31-.888.425-1.505.425-.965 0-1.775-.347-2.354-1.003-.579-.695-.888-1.582-.888-2.663 0-1.08.309-1.968.888-2.624.579-.656 1.389-1.003 2.354-1.003.578 0 1.08.154 1.505.424.424.27.694.618.887 1.004h.039v-1.12c0-.115.038-.154.192-.154h1.698c.116 0 .193.039.193.155v.617c0 .116-.038.154-.193.154h-.771v6.367c0 1.042-.31 1.814-.927 2.315-.694.54-1.504.81-2.546.81z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M37.274 1.08c.155.155.232.348.232.58 0 .23-.077.424-.232.54-.154.154-.347.231-.579.231-.231 0-.424-.077-.578-.232-.155-.154-.232-.347-.232-.54 0-.231.077-.424.232-.579.154-.154.347-.23.578-.23.232 0 .425.076.58.23m.81 9.223h-2.74c-.116 0-.193-.039-.193-.155v-.617c0-.116.077-.155.193-.155h.772V4.167h-.772c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h1.814c.115 0 .192.039.192.155v5.942h.772c.116 0 .193.038.193.154v.618c-.039.115-.077.193-.231.193" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M37.274 1.08c.155.155.232.348.232.58 0 .23-.077.424-.232.54-.154.154-.347.231-.579.231-.231 0-.424-.077-.578-.232-.155-.154-.232-.347-.232-.54 0-.231.077-.424.232-.579.154-.154.347-.23.578-.23.232 0 .425.076.58.23zm.81 9.223h-2.739c-.116 0-.193-.039-.193-.155v-.617c0-.116.077-.155.193-.155h.772V4.167h-.772c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h1.814c.115 0 .192.039.192.155v5.942h.772c.116 0 .193.038.193.154v.618c-.039.115-.077.193-.231.193z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M47.037 10.302h-1.351c-.424 0-.617-.192-.617-.617V5.904c0-.54-.155-1.004-.386-1.312-.27-.309-.656-.463-1.158-.463-.733 0-1.312.309-1.736.926-.039.039-.116.154-.193.309v3.935h.772c.115 0 .193.039.193.155v.617c0 .116-.078.154-.193.154h-2.74c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h.772V4.206h-.772c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.698c.116 0 .193.038.193.154l-.039.965h.039c.501-.849 1.273-1.235 2.315-1.235.772 0 1.35.232 1.814.695.462.463.655 1.041.655 1.813v3.704h.81c.116 0 .194.04.194.155v.617c-.116.077-.155.154-.27.154" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M47.037 10.302h-1.351c-.424 0-.617-.192-.617-.617V5.904c0-.54-.155-1.004-.386-1.312-.27-.309-.656-.463-1.158-.463-.733 0-1.312.309-1.736.926-.039.039-.116.154-.193.309v3.935h.772c.115 0 .193.039.193.155v.617c0 .116-.078.154-.193.154h-2.74c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h.772V4.206h-.772c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.698c.116 0 .193.038.193.154l-.039.965h.039c.501-.849 1.273-1.235 2.315-1.235.772 0 1.35.232 1.814.695.462.463.655 1.041.655 1.813v3.704h.81c.116 0 .194.04.194.155v.617c-.116.077-.155.154-.27.154z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M49.197 6.753c0 .81.193 1.427.618 1.929.424.463.965.733 1.582.733.617 0 1.157-.231 1.582-.733.424-.502.617-1.12.617-1.93 0-.81-.193-1.427-.617-1.929-.425-.501-.926-.694-1.582-.694-.617 0-1.158.231-1.582.733-.425.501-.618 1.119-.618 1.89m2.161 6.908c-.463 0-.849-.039-1.08-.116-.232-.077-.425-.116-.579-.193-.154-.039-.27-.116-.386-.155-.116-.038-.193-.115-.308-.154-.425-.27-.58-.463-.464-.617l.386-.54c.039-.077.155-.077.232 0l.077.077c.039.038.116.077.154.116.039.038.116.077.232.154.077.038.193.116.309.154.115.039.231.077.385.116.31.077.656.116 1.042.116.695 0 1.235-.155 1.66-.502.424-.347.617-.849.617-1.543v-1.66c-.193.386-.463.734-.85 1.042-.385.31-.887.425-1.504.425-.965 0-1.775-.347-2.354-1.003-.578-.695-.887-1.582-.887-2.663 0-1.08.309-1.968.887-2.624.58-.656 1.39-1.003 2.354-1.003.579 0 1.08.154 1.505.424.424.27.695.618.887 1.004h.039v-1.12c0-.115.039-.154.193-.154h1.698c.115 0 .193.039.193.155v.617c0 .116-.039.154-.193.154h-.772v6.367c0 1.042-.309 1.814-.926 2.315-.733.54-1.544.81-2.547.81" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M49.197 6.753c0 .81.193 1.427.618 1.929.424.463.965.733 1.582.733.617 0 1.157-.231 1.582-.733.424-.502.617-1.12.617-1.93 0-.81-.193-1.427-.617-1.929-.425-.501-.926-.694-1.582-.694-.617 0-1.158.231-1.582.733-.425.501-.618 1.119-.618 1.89zm2.161 6.907c-.463 0-.849-.039-1.08-.116-.232-.077-.425-.116-.579-.193-.154-.039-.27-.116-.386-.155-.116-.038-.193-.115-.308-.154-.425-.27-.58-.463-.464-.617l.386-.54c.039-.077.155-.077.232 0l.077.077c.039.038.116.077.154.116.039.038.116.077.232.154.077.038.193.116.309.154.115.039.231.077.385.116.31.077.656.116 1.042.116.695 0 1.235-.155 1.66-.502.424-.347.617-.849.617-1.543v-1.66c-.193.386-.463.734-.85 1.042-.385.31-.887.425-1.504.425-.965 0-1.775-.347-2.354-1.003-.578-.695-.887-1.582-.887-2.663 0-1.08.309-1.968.887-2.624.58-.656 1.39-1.003 2.354-1.003.579 0 1.08.154 1.505.424.424.27.695.618.887 1.004h.039v-1.12c0-.115.039-.154.193-.154h1.698c.115 0 .193.039.193.155v.617c0 .116-.039.154-.193.154h-.772v6.367c0 1.042-.309 1.814-.926 2.315-.733.54-1.544.81-2.547.81z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M65.596 10.302h-3.974c-.116 0-.193-.038-.193-.154v-.733c0-.116.077-.154.193-.154h1.08V1.042h-1.08c-.116 0-.193-.039-.193-.154V.154c0-.115.077-.154.193-.154h7.37c.116 0 .193.039.193.154V2.47c0 .116-.077.194-.193.194h-.771c-.116 0-.194-.078-.194-.194V1.08h-4.09v3.55h3.396c.116 0 .193.039.193.155v.733c0 .116-.077.154-.193.154h-3.396v3.512h1.62c.117 0 .194.038.194.154v.733c.038.154-.039.231-.155.231" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M65.596 10.302h-3.974c-.116 0-.193-.038-.193-.154v-.733c0-.116.077-.154.193-.154h1.08V1.042h-1.08c-.116 0-.193-.039-.193-.154V.154c0-.115.077-.154.193-.154h7.37c.116 0 .193.039.193.154V2.47c0 .116-.077.194-.193.194h-.771c-.116 0-.194-.078-.194-.194V1.08h-4.09v3.55h3.396c.116 0 .193.039.193.155v.733c0 .116-.077.154-.193.154h-3.396v3.512h1.62c.117 0 .194.038.194.154v.733c.038.154-.039.231-.155.231z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M70.535 6.753c0 .771.232 1.427.695 1.929.463.502 1.003.733 1.698.733.694 0 1.235-.231 1.698-.733.463-.502.694-1.12.694-1.93 0-.771-.231-1.427-.694-1.89-.463-.463-1.004-.733-1.66-.733-.656 0-1.196.231-1.697.733-.502.463-.734 1.08-.734 1.89m4.94 2.625c-.656.656-1.544 1.003-2.586 1.003-1.042 0-1.89-.347-2.585-1.003-.656-.656-1.003-1.544-1.003-2.663 0-1.119.347-1.968 1.003-2.624.695-.656 1.544-.965 2.547-.965 1.003 0 1.89.348 2.546 1.004.656.656 1.004 1.543 1.004 2.624.077 1.08-.232 1.968-.926 2.624" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M70.535 6.753c0 .771.232 1.427.695 1.929.463.502 1.003.733 1.698.733.694 0 1.235-.231 1.698-.733.463-.502.694-1.12.694-1.93 0-.771-.231-1.427-.694-1.89-.463-.463-1.004-.733-1.66-.733-.656 0-1.196.231-1.697.733-.502.463-.734 1.08-.734 1.89zm4.94 2.624c-.656.656-1.544 1.003-2.586 1.003-1.042 0-1.89-.347-2.585-1.003-.656-.656-1.003-1.544-1.003-2.663 0-1.119.347-1.968 1.003-2.624.695-.656 1.544-.965 2.547-.965 1.003 0 1.89.348 2.546 1.004.656.656 1.004 1.543 1.004 2.624.077 1.08-.232 1.968-.926 2.624z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M84.812 10.302h-1.234c-.425 0-.618-.192-.618-.617v-.54h-.038c-.386.81-1.158 1.235-2.238 1.235-.772 0-1.39-.232-1.814-.695-.424-.463-.656-1.08-.694-1.813V4.167h-.81c-.116 0-.194-.038-.194-.154v-.617c0-.116.039-.155.193-.155h1.39c.424 0 .617.193.617.618V7.64c0 .54.154 1.003.386 1.312.27.309.656.463 1.196.463.695 0 1.234-.27 1.659-.772.193-.231.27-.385.27-.424V4.167h-.772c-.115 0-.193-.038-.193-.154v-.617c0-.116.04-.155.193-.155h1.775c.116 0 .193.039.193.155v5.942h.81c.116 0 .194.038.194.154v.618c-.078.115-.155.192-.27.192" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M84.812 10.302h-1.234c-.425 0-.618-.192-.618-.617v-.54h-.038c-.386.81-1.158 1.235-2.238 1.235-.772 0-1.39-.232-1.814-.695-.424-.463-.656-1.08-.694-1.813V4.167h-.81c-.116 0-.194-.038-.194-.154v-.617c0-.116.039-.155.193-.155h1.39c.424 0 .617.193.617.618V7.64c0 .54.154 1.003.386 1.312.27.309.656.463 1.196.463.695 0 1.234-.27 1.659-.772.193-.231.27-.385.27-.424V4.167h-.772c-.115 0-.193-.038-.193-.154v-.617c0-.116.04-.155.193-.155h1.775c.116 0 .193.039.193.155v5.942h.81c.116 0 .194.038.194.154v.618c-.078.115-.155.192-.27.192z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M93.687 10.302h-1.35c-.425 0-.618-.192-.618-.617V5.904c0-.54-.154-1.004-.385-1.312-.27-.309-.656-.463-1.158-.463-.733 0-1.312.309-1.736.926-.04.039-.116.154-.193.309v3.935h.771c.116 0 .193.039.193.155v.617c0 .116-.077.154-.193.154h-2.74c-.115 0-.192-.038-.192-.154v-.617c0-.116.077-.155.193-.155h.772V4.206h-.772c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.698c.115 0 .192.038.192.154l-.038.965h.038c.502-.849 1.274-1.235 2.316-1.235.771 0 1.35.232 1.813.695.463.463.656 1.041.656 1.813v3.704h.81c.116 0 .193.04.193.155v.617c-.077.077-.154.154-.27.154" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M93.687 10.302h-1.35c-.425 0-.618-.192-.618-.617V5.904c0-.54-.154-1.004-.385-1.312-.27-.309-.656-.463-1.158-.463-.733 0-1.312.309-1.736.926-.04.039-.116.154-.193.309v3.935h.771c.116 0 .193.039.193.155v.617c0 .116-.077.154-.193.154h-2.74c-.115 0-.192-.038-.192-.154v-.617c0-.116.077-.155.193-.155h.772V4.206h-.772c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.698c.115 0 .192.038.192.154l-.038.965h.038c.502-.849 1.274-1.235 2.316-1.235.771 0 1.35.232 1.813.695.463.463.656 1.041.656 1.813v3.704h.81c.116 0 .193.04.193.155v.617c-.077.077-.154.154-.27.154z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M95.77 6.714c0 .81.194 1.428.618 1.93.425.5.965.732 1.582.732.656 0 1.158-.231 1.583-.733.424-.501.617-1.119.617-1.929s-.193-1.428-.617-1.89c-.425-.464-.965-.695-1.583-.695-.617 0-1.157.231-1.582.694-.386.463-.617 1.12-.617 1.891m6.367 3.589h-1.235c-.232 0-.386-.039-.463-.155-.116-.077-.154-.231-.154-.463v-.81c-.155.386-.425.772-.85 1.042-.424.308-.925.463-1.543.463-.965 0-1.736-.348-2.353-1.004-.58-.655-.888-1.543-.888-2.623 0-1.08.309-1.968.888-2.624.578-.656 1.388-1.003 2.353-1.003.579 0 1.08.154 1.466.424.386.27.695.617.85 1.003V.965h-.811c-.116 0-.193-.039-.193-.155V.193c0-.116.077-.154.193-.154h1.775c.116 0 .193.038.193.154v9.183h.81c.116 0 .193.04.193.155v.617c-.077.077-.116.155-.231.155" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M95.77 6.714c0 .81.194 1.428.618 1.93.425.5.965.732 1.582.732.656 0 1.158-.231 1.583-.733.424-.501.617-1.119.617-1.929s-.193-1.428-.617-1.89c-.425-.464-.965-.695-1.583-.695-.617 0-1.157.231-1.582.694-.386.463-.617 1.12-.617 1.891zm6.368 3.589h-1.235c-.232 0-.386-.039-.463-.155-.116-.077-.154-.231-.154-.463v-.81c-.155.386-.425.772-.85 1.042-.424.308-.925.463-1.543.463-.965 0-1.736-.348-2.353-1.004-.58-.655-.888-1.543-.888-2.623 0-1.08.309-1.968.888-2.624.578-.656 1.388-1.003 2.353-1.003.579 0 1.08.154 1.466.424.386.27.695.617.85 1.003V.965h-.811c-.116 0-.193-.039-.193-.155V.193c0-.116.077-.154.193-.154h1.775c.116 0 .193.038.193.154v9.183h.81c.116 0 .193.04.193.155v.617c-.077.077-.116.155-.231.155z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M108.466 6.984h-1.158c-.54 0-1.003.039-1.389.077-.347.039-.695.193-.926.386-.27.193-.386.463-.386.81 0 .348.116.618.425.81.308.194.617.31 1.08.31.926 0 1.698-.425 2.354-1.235V6.984zm2.006 3.318h-1.234c-.425 0-.618-.192-.618-.617v-.733h-.038c-.695.965-1.621 1.466-2.817 1.466-.695 0-1.235-.193-1.698-.54-.424-.347-.656-.849-.656-1.466 0-.772.347-1.35 1.042-1.736.694-.387 1.62-.54 2.817-.54h1.196V5.98c0-1.196-.618-1.814-1.852-1.814-.579 0-1.004.04-1.274.155-.27.115-.463.193-.54.27-.116.077-.193.115-.27.154-.154.116-.27.116-.309.039l-.385-.502c-.078-.077-.078-.154.038-.231.154-.232.502-.425 1.003-.618.502-.193 1.12-.309 1.814-.309 2.006 0 3.01.965 3.01 2.856v3.318h.81c.116 0 .193.039.193.155v.617c-.077.154-.116.231-.232.231z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M108.466 6.984h-1.158c-.54 0-1.003.039-1.389.077-.347.039-.695.193-.926.386-.27.193-.386.463-.386.81 0 .348.116.618.425.81.308.194.617.31 1.08.31.926 0 1.698-.425 2.354-1.235V6.984zm2.006 3.318h-1.234c-.425 0-.618-.192-.618-.617v-.733h-.038c-.695.965-1.621 1.466-2.817 1.466-.695 0-1.235-.193-1.698-.54-.424-.347-.656-.849-.656-1.466 0-.772.347-1.35 1.042-1.736.694-.387 1.62-.54 2.817-.54h1.196V5.98c0-1.196-.618-1.814-1.852-1.814-.579 0-1.004.04-1.274.155-.27.115-.463.193-.54.27-.116.077-.193.115-.27.154-.154.116-.27.116-.309.039l-.385-.502c-.078-.077-.078-.154.038-.231.154-.232.502-.425 1.003-.618.502-.193 1.12-.309 1.814-.309 2.006 0 3.01.965 3.01 2.856v3.318h.81c.116 0 .193.039.193.155v.617c-.077.154-.116.231-.232.231z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M116.106 9.57c.039.038.077.077.077.115 0 .039-.038.077-.077.155-.425.385-.965.54-1.582.54-.618 0-1.158-.193-1.582-.618-.425-.424-.618-1.003-.618-1.813V4.167h-.81c-.116 0-.193-.077-.193-.193v-.578c0-.116.077-.194.193-.194h.81V1.736c0-.154.078-.192.193-.192h.81c.117 0 .194.077.194.192v1.466h1.813c.116 0 .193.078.193.194v.578c0 .116-.077.193-.193.193h-1.813V7.91c0 .463.115.85.308 1.08.193.232.502.348.85.348.346 0 .617-.077.81-.27.077-.077.192-.077.27 0l.347.501z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M116.106 9.57c.039.038.077.077.077.115 0 .039-.038.077-.077.155-.425.385-.965.54-1.582.54-.618 0-1.158-.193-1.582-.618-.425-.424-.618-1.003-.618-1.813V4.167h-.81c-.116 0-.193-.077-.193-.193v-.578c0-.116.077-.194.193-.194h.81V1.736c0-.154.078-.192.193-.192h.81c.117 0 .194.077.194.192v1.466h1.813c.116 0 .193.078.193.194v.578c0 .116-.077.193-.193.193h-1.813V7.91c0 .463.115.85.308 1.08.193.232.502.348.85.348.346 0 .617-.077.81-.27.077-.077.192-.077.27 0l.347.501z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M119.077 1.08c.154.155.231.348.231.58 0 .23-.077.424-.231.54-.154.154-.347.231-.579.231-.231 0-.424-.077-.579-.232-.154-.154-.231-.347-.231-.54 0-.231.077-.424.231-.579.155-.154.348-.23.58-.23.23 0 .424.076.578.23m.81 9.223h-2.74c-.115 0-.192-.039-.192-.155v-.617c0-.116.077-.155.193-.155h.771V4.167h-.771c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h1.813c.116 0 .193.039.193.155v5.942h.772c.116 0 .193.038.193.154v.618c-.039.115-.077.193-.232.193" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M119.077 1.08c.154.155.231.348.231.58 0 .23-.077.424-.231.54-.154.154-.347.231-.579.231-.231 0-.424-.077-.579-.232-.154-.154-.231-.347-.231-.54 0-.231.077-.424.231-.579.155-.154.348-.23.58-.23.23 0 .424.076.578.23zm.81 9.223h-2.74c-.115 0-.192-.039-.192-.155v-.617c0-.116.077-.155.193-.155h.771V4.167h-.771c-.116 0-.193-.038-.193-.154v-.617c0-.116.077-.155.193-.155h1.813c.116 0 .193.039.193.155v5.942h.772c.116 0 .193.038.193.154v.618c-.039.115-.077.193-.232.193z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M122.202 6.753c0 .771.232 1.427.695 1.929.463.502 1.042.733 1.698.733.656 0 1.235-.231 1.698-.733.463-.502.694-1.12.694-1.93 0-.771-.231-1.427-.694-1.89-.463-.463-1.042-.733-1.66-.733-.617 0-1.196.231-1.697.733-.502.463-.734 1.08-.734 1.89m4.978 2.625c-.656.656-1.543 1.003-2.585 1.003s-1.89-.347-2.585-1.003c-.695-.656-1.004-1.544-1.004-2.663 0-1.119.348-1.968 1.042-2.624.695-.656 1.544-.965 2.585-.965 1.042 0 1.891.348 2.547 1.004.656.656 1.003 1.543 1.003 2.624 0 1.08-.347 1.968-1.003 2.624" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M122.202 6.753c0 .771.232 1.427.695 1.929.463.502 1.042.733 1.698.733.656 0 1.235-.231 1.698-.733.463-.502.694-1.12.694-1.93 0-.771-.231-1.427-.694-1.89-.463-.463-1.042-.733-1.66-.733-.617 0-1.196.231-1.697.733-.502.463-.734 1.08-.734 1.89zm4.978 2.624c-.656.656-1.543 1.003-2.585 1.003s-1.89-.347-2.585-1.003c-.695-.656-1.004-1.544-1.004-2.663 0-1.119.348-1.968 1.042-2.624.695-.656 1.544-.965 2.585-.965 1.042 0 1.891.348 2.547 1.004.656.656 1.003 1.543 1.003 2.624 0 1.08-.347 1.968-1.003 2.624z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path fill="#FFF" d="M136.865 10.302h-1.35c-.424 0-.618-.192-.618-.617V5.904c0-.54-.115-1.004-.385-1.312-.27-.309-.656-.463-1.158-.463-.733 0-1.312.309-1.737.926-.038.039-.115.154-.192.309v3.935h.771c.116 0 .193.039.193.155v.617c0 .116-.077.154-.193.154h-2.74c-.115 0-.192-.038-.192-.154v-.617c0-.116.077-.155.193-.155h.771V4.206h-.771c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.698c.115 0 .193.038.193.154l-.04.965h.04c.501-.849 1.273-1.235 2.315-1.235.771 0 1.35.232 1.813.695.463.463.656 1.041.656 1.813v3.704h.81c.116 0 .193.04.193.155v.617c-.077.077-.115.154-.27.154" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
<path stroke="#FFF" stroke-width=".75" d="M136.865 10.302h-1.35c-.424 0-.618-.192-.618-.617V5.904c0-.54-.115-1.004-.385-1.312-.27-.309-.656-.463-1.158-.463-.733 0-1.312.309-1.737.926-.038.039-.115.154-.192.309v3.935h.771c.116 0 .193.039.193.155v.617c0 .116-.077.154-.193.154h-2.74c-.115 0-.192-.038-.192-.154v-.617c0-.116.077-.155.193-.155h.771V4.206h-.771c-.116 0-.193-.039-.193-.154v-.618c0-.116.077-.154.193-.154h1.698c.115 0 .193.038.193.154l-.04.965h.04c.501-.849 1.273-1.235 2.315-1.235.771 0 1.35.232 1.813.695.463.463.656 1.041.656 1.813v3.704h.81c.116 0 .193.04.193.155v.617c-.077.077-.115.154-.27.154z" transform="translate(1 1) translate(33.803 4.985) translate(91.924 .113)"/>
</g>
</g>
<g fill="#FFF" fill-rule="nonzero">
<path d="M22.85 21.43c0 .713-.58 1.294-1.293 1.294h-8.308c-.713 0-1.293-.58-1.293-1.293v-8.308c0-.713.58-1.293 1.293-1.293h8.308c.712 0 1.293.58 1.293 1.293v8.308zm-1.327-8.273h-8.24v8.24h8.24v-8.24zM22.85 8.937c0 .713-.58 1.293-1.293 1.293h-8.308c-.713 0-1.293-.58-1.293-1.293V.63c0-.712.58-1.292 1.293-1.292h8.308c.712 0 1.293.58 1.293 1.292v8.308zM21.523.663h-8.24v8.24h8.24V.663zM10.23 21.43c0 .713-.58 1.294-1.293 1.294H.63c-.712 0-1.292-.58-1.292-1.293v-8.308c0-.713.58-1.293 1.292-1.293h8.308c.713 0 1.293.58 1.293 1.293v8.308zm-1.327-8.273H.663v8.24h8.24v-8.24zM10.23 8.937c0 .713-.58 1.293-1.293 1.293H.63c-.712 0-1.292-.58-1.292-1.293V.63c0-.712.58-1.292 1.292-1.292h8.308c.713 0 1.293.58 1.293 1.292v8.308zm-1.327-.034V.663H.663v8.24h8.24z" transform="translate(1 1)"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 39 KiB

+16 -21
View File
@@ -3,7 +3,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import i18n from '@ohif/i18n';
import { I18nextProvider } from 'react-i18next';
import { BrowserRouter, HashRouter } from 'react-router-dom';
import { Router } from 'react-router-dom';
import {
DialogProvider,
Modal,
@@ -12,7 +12,6 @@ import {
ThemeWrapper,
ViewportDialogProvider,
ViewportGridProvider,
HangingProtocolProvider,
CineProvider,
} from '@ohif/ui';
// Viewer Project
@@ -20,6 +19,7 @@ import {
import { AppConfigProvider } from '@state';
import createRoutes from './routes';
import appInit from './appInit.js';
import history from './history'
// TODO: Temporarily for testing
import '@ohif/mode-longitudinal';
@@ -27,9 +27,7 @@ import '@ohif/mode-longitudinal';
/**
* ENV Variable to determine routing behavior
*/
const Router = JSON.parse(process.env.USE_HASH_ROUTER)
? HashRouter
: BrowserRouter;
const OHIFRouter = Router
let commandsManager, extensionManager, servicesManager, hotkeysManager;
@@ -59,32 +57,29 @@ function App({ config, defaultExtensions }) {
UINotificationService,
UIViewportDialogService,
ViewportGridService, // TODO: Should this be a "UI" Service?
HangingProtocolService,
CineService
} = servicesManager.services;
return (
<AppConfigProvider value={appConfigState}>
<I18nextProvider i18n={i18n}>
<Router basename={routerBasename}>
<OHIFRouter basename={routerBasename} history={history}>
<ThemeWrapper>
<ViewportGridProvider service={ViewportGridService}>
<HangingProtocolProvider service={HangingProtocolService}>
<ViewportDialogProvider service={UIViewportDialogService}>
<CineProvider service={CineService}>
<SnackbarProvider service={UINotificationService}>
<DialogProvider service={UIDialogService}>
<ModalProvider modal={Modal} service={UIModalService}>
{appRoutes}
</ModalProvider>
</DialogProvider>
</SnackbarProvider>
</CineProvider>
</ViewportDialogProvider>
</HangingProtocolProvider>
<ViewportDialogProvider service={UIViewportDialogService}>
<CineProvider service={CineService}>
<SnackbarProvider service={UINotificationService}>
<DialogProvider service={UIDialogService}>
<ModalProvider modal={Modal} service={UIModalService}>
{appRoutes}
</ModalProvider>
</DialogProvider>
</SnackbarProvider>
</CineProvider>
</ViewportDialogProvider>
</ViewportGridProvider>
</ThemeWrapper>
</Router>
</OHIFRouter>
</I18nextProvider>
</AppConfigProvider>
);
+1
View File
@@ -81,6 +81,7 @@ function appInit(appConfigOrFunc, defaultExtensions) {
// appConfig.modes.push(window.segmentationMode);
}
return {
appConfig,
commandsManager,
+51 -29
View File
@@ -26,38 +26,38 @@ function ViewerViewportGrid(props) {
HangingProtocolService,
} = servicesManager.services;
// This is a placeholder for applying hanging protocols
// It probably shouldn't be done here
// For now it just hangs the first display set in the study in 1x1
// as sorted by SeriesNumber
// Using Hanging protocol engine to match the displaysets
useEffect(() => {
const { unsubscribe } = DisplaySetService.subscribe(
DisplaySetService.EVENTS.DISPLAY_SETS_ADDED,
eventData => {
const { displaySetsAdded } = eventData;
const data = HangingProtocolService.getState();
// TODO: Sometimes this is undefined?
const { hpAlreadyApplied } = data;
const [
matchDetails,
hpAlreadyApplied,
] = HangingProtocolService.getState();
if (!matchDetails.length) return;
// Match each viewport individually
const numViewports = numRows * numCols;
const numViewports = viewportGrid.numRows * viewportGrid.numCols;
for (let i = 0; i < numViewports; i++) {
if (hpAlreadyApplied[i] === true) {
return;
continue;
}
// Temporary until matching is ported back over from the Meteor version.
const reqSeriesInstanceUID =
data.hangingProtocol.stages[0].viewports[0].seriesMatchingRules[0]
.constraint.equals.value;
// if current viewport doesn't have a match
if (matchDetails[i] === undefined) return
const { SeriesInstanceUID } = matchDetails[i];
const matchingDisplaySet = displaySetsAdded.find(ds => {
return ds.SeriesInstanceUID === reqSeriesInstanceUID;
return ds.SeriesInstanceUID === SeriesInstanceUID;
});
if (!matchingDisplaySet) {
return;
continue;
}
viewportGridService.setDisplaysetForViewport({
@@ -73,7 +73,23 @@ function ViewerViewportGrid(props) {
return () => {
unsubscribe();
};
}, []);
}, [numRows, numCols]);
// Layout change based on hanging protocols
useEffect(() => {
const { unsubscribe } = HangingProtocolService.subscribe(
HangingProtocolService.EVENTS.NEW_LAYOUT,
({ numRows, numCols }) => {
viewportGridService.setLayout({ numRows, numCols });
}
);
return () => {
unsubscribe();
};
}, [viewports]);
useEffect(() => {
const { unsubscribe } = MeasurementService.subscribe(
@@ -82,16 +98,24 @@ function ViewerViewportGrid(props) {
const referencedDisplaySetInstanceUID =
measurement.displaySetInstanceUID;
// If the viewport does not contain the displaySet, then hang that displaySet.
const viewportsDisplaySetInstanceUIDs = viewports.map(
vp => vp.displaySetInstanceUID
);
// if we already have the displayset in one of the viewports
if (
viewports[viewportIndex].displaySetInstanceUID !==
referencedDisplaySetInstanceUID
viewportsDisplaySetInstanceUIDs.indexOf(
referencedDisplaySetInstanceUID
) > -1
) {
viewportGridService.setDisplaysetForViewport({
viewportIndex,
displaySetInstanceUID: referencedDisplaySetInstanceUID,
});
return;
}
// If not in any of the viewports, hang it inside the active viewport
viewportGridService.setDisplaysetForViewport({
viewportIndex,
displaySetInstanceUID: referencedDisplaySetInstanceUID,
});
}
);
@@ -208,11 +232,9 @@ function ViewerViewportGrid(props) {
return viewportPanes;
};
// const ViewportPanes = React.useMemo(getViewportPanes, [
// viewportComponents,
// activeViewportIndex,
// viewportGrid,
// ]);
if (!numCols || !numCols) {
return null;
}
return (
<ViewportGrid numRows={numRows} numCols={numCols}>
+5
View File
@@ -0,0 +1,5 @@
import { createBrowserHistory, createHashHistory } from 'history';
const useHashRouting = JSON.parse(process.env.USE_HASH_ROUTER);
const router = useHashRouting ? createHashHistory() : createBrowserHistory();
export default router;
+172 -152
View File
@@ -1,14 +1,57 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { useParams } from 'react-router';
import PropTypes from 'prop-types';
// TODO: DicomMetadataStore should be injected?
import { DicomMetadataStore, utils } from '@ohif/core';
import { DicomMetadataStore } from '@ohif/core';
import { DragAndDropProvider, ImageViewerProvider } from '@ohif/ui';
import { useQuery } from '@hooks';
import ViewportGrid from '@components/ViewportGrid';
import Compose from './Compose';
const { isLowPriorityModality } = utils;
async function defaultRouteInit({
servicesManager,
studyInstanceUIDs,
dataSource,
}) {
const {
DisplaySetService,
HangingProtocolService,
} = servicesManager.services;
const unsubscriptions = [];
// TODO: This should be baked into core, not manuall?
// DisplaySetService would wire this up?
const {
unsubscribe: instanceAddedUnsubscribe,
} = DicomMetadataStore.subscribe(
DicomMetadataStore.EVENTS.INSTANCES_ADDED,
({ StudyInstanceUID, SeriesInstanceUID, madeInClient = false }) => {
const seriesMetadata = DicomMetadataStore.getSeries(
StudyInstanceUID,
SeriesInstanceUID
);
DisplaySetService.makeDisplaySets(seriesMetadata.instances, madeInClient);
}
);
unsubscriptions.push(instanceAddedUnsubscribe);
studyInstanceUIDs.forEach(StudyInstanceUID => {
dataSource.retrieveSeriesMetadata({ StudyInstanceUID });
});
const { unsubscribe: seriesAddedUnsubscribe } = DicomMetadataStore.subscribe(
DicomMetadataStore.EVENTS.SERIES_ADDED,
({ StudyInstanceUID }) => {
const studyMetadata = DicomMetadataStore.getStudy(StudyInstanceUID);
HangingProtocolService.run(studyMetadata);
}
);
unsubscriptions.push(seriesAddedUnsubscribe);
return unsubscriptions;
}
export default function ModeRoute({
location,
@@ -20,15 +63,25 @@ export default function ModeRoute({
}) {
// Parse route params/querystring
const query = useQuery();
const queryStudyInstanceUIDs = query.get('StudyInstanceUIDs');
const { StudyInstanceUIDs: paramsStudyInstanceUIDs } = useParams();
const StudyInstanceUIDs = queryStudyInstanceUIDs || paramsStudyInstanceUIDs;
const StudyInstanceUIDsAsArray =
StudyInstanceUIDs && Array.isArray(StudyInstanceUIDs)
? StudyInstanceUIDs
: [StudyInstanceUIDs];
const params = useParams();
const { extensions, sopClassHandlers, hotkeys } = mode;
const [studyInstanceUIDs, setStudyInstanceUIDs] = useState();
const [refresh, setRefresh] = useState(false);
const layoutTemplateData = useRef(false);
const locationRef = useRef(null);
const isMounted = useRef(false);
if (location !== locationRef.current) {
layoutTemplateData.current = null;
locationRef.current = location;
}
const {
DisplaySetService,
HangingProtocolService,
} = servicesManager.services;
const { extensions, sopClassHandlers, hotkeys, hangingProtocols } = mode;
if (dataSourceName === undefined) {
dataSourceName = extensionManager.defaultDataSourceName;
@@ -43,19 +96,6 @@ export default function ModeRoute({
// Only handling one route per mode for now
const route = mode.routes[0];
const {
DisplaySetService,
MeasurementService,
ViewportGridService,
HangingProtocolService,
} = servicesManager.services;
const layoutTemplateData = route.layoutTemplate({ location });
const layoutTemplateModuleEntry = extensionManager.getModuleEntry(
layoutTemplateData.id
);
const LayoutComponent = layoutTemplateModuleEntry.component;
// For each extension, look up their context modules
// TODO: move to extension manager.
let contextModules = [];
@@ -81,9 +121,52 @@ export default function ModeRoute({
return ViewportGrid({ ...props, dataSource });
}
useEffect(() => {
// Preventing state update for unmounted component
isMounted.current = true;
return () => {
isMounted.current = false;
};
}, []);
useEffect(() => {
// Todo: this should not be here, data source should not care about params
const initializeDataSource = async (params, query) => {
const studyInstanceUIDs = await dataSource.parseRouteParams({
params,
query,
});
setStudyInstanceUIDs(studyInstanceUIDs);
};
initializeDataSource(params, query);
return () => {
layoutTemplateData.current = null;
};
}, [location]);
useEffect(() => {
const retrieveLayoutData = async () => {
const layoutData = await route.layoutTemplate({
location,
servicesManager,
studyInstanceUIDs,
});
if (isMounted.current) {
layoutTemplateData.current = layoutData;
setRefresh(!refresh);
}
};
if (studyInstanceUIDs?.length && studyInstanceUIDs[0] !== undefined) {
retrieveLayoutData();
}
return () => {
layoutTemplateData.current = null;
};
}, [studyInstanceUIDs]);
useEffect(() => {
if (!hotkeys) {
console.warn('[hotkeys] No bindings defined for hotkeys hook!');
return;
}
@@ -96,19 +179,61 @@ export default function ModeRoute({
}, []);
useEffect(() => {
if (!layoutTemplateData.current) {
return;
}
// TODO: For some reason this is running before the Providers
// are calling setServiceImplementation
// are calling setServiceImplementationf
// TOOD -> iterate through services.
// Extension
// Add SOPClassHandlers to a new SOPClassManager.
DisplaySetService.init(extensionManager, sopClassHandlers);
extensionManager.onModeEnter();
mode?.onModeEnter({ servicesManager, extensionManager });
// Mode
route.init({ servicesManager, extensionManager });
// Adding hanging protocols of extensions after onModeEnter since
// it will reset the protocols
hangingProtocols.forEach(extentionProtocols => {
const hangingProtocolModule = extensionManager.getModuleEntry(extentionProtocols);
if (hangingProtocolModule?.protocols) {
HangingProtocolService.addProtocols(hangingProtocolModule.protocols);
}
});
const setupRouteInit = async () => {
if (route.init) {
return await route.init({
servicesManager,
extensionManager,
hotkeysManager,
studyInstanceUIDs,
dataSource,
});
}
return await defaultRouteInit({
servicesManager,
extensionManager,
hotkeysManager,
studyInstanceUIDs,
dataSource,
});
};
let unsubscriptions;
setupRouteInit().then(unsubs => {
unsubscriptions = unsubs;
});
return () => {
extensionManager.onModeExit();
mode?.onModeExit({ servicesManager, extensionManager });
unsubscriptions.forEach(unsub => {
unsub();
});
};
}, [
mode,
@@ -118,140 +243,35 @@ export default function ModeRoute({
servicesManager,
extensionManager,
hotkeysManager,
studyInstanceUIDs,
refresh,
hangingProtocols,
]);
// This queries for series, but... What does it do with them?
useEffect(() => {
// Add SOPClassHandlers to a new SOPClassManager.
DisplaySetService.init(extensionManager, sopClassHandlers);
// TODO: This should be baked into core, not manuel?
// DisplaySetService would wire this up?
const { unsubscribe } = DicomMetadataStore.subscribe(
DicomMetadataStore.EVENTS.INSTANCES_ADDED,
({ StudyInstanceUID, SeriesInstanceUID, madeInClient = false }) => {
const seriesMetadata = DicomMetadataStore.getSeries(
StudyInstanceUID,
SeriesInstanceUID
);
DisplaySetService.makeDisplaySets(
seriesMetadata.instances,
madeInClient
);
}
const renderLayoutData = props => {
const layoutTemplateModuleEntry = extensionManager.getModuleEntry(
layoutTemplateData.current.id
);
const LayoutComponent = layoutTemplateModuleEntry.component;
StudyInstanceUIDsAsArray.forEach(StudyInstanceUID => {
dataSource.retrieveSeriesMetadata({ StudyInstanceUID });
});
return unsubscribe;
}, [
mode,
dataSourceName,
location,
DisplaySetService,
extensionManager,
sopClassHandlers,
StudyInstanceUIDsAsArray,
dataSource,
]);
useEffect(() => {
const { unsubscribe } = DicomMetadataStore.subscribe(
DicomMetadataStore.EVENTS.SERIES_ADDED,
({ StudyInstanceUID }) => {
const studyMetadata = DicomMetadataStore.getStudy(StudyInstanceUID);
const sortedSeries = studyMetadata.series.sort((a, b) => {
const aLowPriority = isLowPriorityModality(a.Modality);
const bLowPriority = isLowPriorityModality(b.Modality);
if (!aLowPriority && bLowPriority) {
return -1;
}
if (aLowPriority && !bLowPriority) {
return 1;
}
return a.SeriesNumber - b.SeriesNumber;
});
const { SeriesInstanceUID } = sortedSeries[0];
HangingProtocolService.setHangingProtocol({
/*protocolMatchingRules: [
{
id: '7tmuq7KzDMCWFeapc',
weight: 2,
required: false,
attribute: 'x00081030',
constraint: {
contains: {
value: 'DFCI CT CHEST',
},
},
},
],*/
stages: [
{
/*id: 'v5PfGt9F6mffZPif5',
viewportStructure: {
type: 'grid',
properties: {
Rows: 1,
Columns: 1,
},
layoutTemplateName: 'gridLayout',
},*/
viewports: [
{
viewportSettings: {},
imageMatchingRules: [],
seriesMatchingRules: [
{
id: 'mXnsCcNzZL56z7mTZ',
weight: 1,
required: true,
attribute: 'SeriesInstanceUID',
constraint: {
equals: {
value: SeriesInstanceUID,
},
},
},
],
studyMatchingRules: [],
},
],
},
],
});
}
);
return unsubscribe;
}, [
mode,
dataSourceName,
location,
DisplaySetService,
extensionManager,
sopClassHandlers,
StudyInstanceUIDsAsArray,
dataSource,
]);
return <LayoutComponent {...props} />;
};
return (
<ImageViewerProvider
initialState={{ StudyInstanceUIDs: StudyInstanceUIDsAsArray }}
// initialState={{ StudyInstanceUIDs: StudyInstanceUIDs }}
StudyInstanceUIDs={studyInstanceUIDs}
// reducer={reducer}
>
<CombinedContextProvider>
<DragAndDropProvider>
<LayoutComponent
{...layoutTemplateData.props}
StudyInstanceUIDs={StudyInstanceUIDs}
ViewportGridComp={ViewportGridWithDataSource}
/>
{layoutTemplateData.current &&
studyInstanceUIDs?.length &&
studyInstanceUIDs[0] !== undefined &&
renderLayoutData({
...layoutTemplateData.current.props,
ViewportGridComp: ViewportGridWithDataSource,
})}
</DragAndDropProvider>
</CombinedContextProvider>
</ImageViewerProvider>
@@ -408,7 +408,7 @@ function WorkList({
'h-screen': !hasStudies,
})}
>
<Header isSticky menuOptions={menuOptions} isReturnEnabled={false} />
<Header isSticky menuOptions={menuOptions} isReturnEnabled={false} WhiteLabeling={appConfig.whiteLabeling} />
<StudyListFilter
numOfStudies={pageNumber * resultsPerPage > 100 ? 101 : numOfStudies}
filtersMeta={filtersMeta}