From d541c23117a4292348102c49b92a63911b66037b Mon Sep 17 00:00:00 2001 From: Erik Ziegler Date: Fri, 14 Dec 2018 14:38:36 +0100 Subject: [PATCH] wip, very broken as I moved stuff to ohif-core --- OHIFViewer/.meteor/packages | 2 - OHIFViewer/.meteor/versions | 3 - OHIFViewer/client/body.styl | 4 - OHIFViewer/client/components/App.css | 16 +- OHIFViewer/client/components/App.js | 7 +- .../client/components/ViewerFromStudyData.js | 48 +- OHIFViewer/client/components/ViewerRouting.js | 9 + .../components/flexboxLayout/flexboxLayout.js | 2 +- OHIFViewer/client/components/index.js | 4 +- .../components/ohifViewer/ohifViewer.js | 15 +- .../toolbarSection/toolbarSection.js | 2 +- OHIFViewer/client/components/viewer/viewer.js | 40 +- OHIFViewer/client/config.js | 2 +- OHIFViewer/client/routes.js | 52 - OHIFViewer/package-lock.json | 5 +- OHIFViewer/package.json | 2 +- Packages/ohif-core/client/base.js | 5 - Packages/ohif-core/client/classes.js | 6 - .../client/classes/CommandsManager.js | 113 - .../client/classes/HotkeysContext.js | 65 - .../client/classes/HotkeysManager.js | 159 - Packages/ohif-core/client/classes/ImageSet.js | 69 - .../client/classes/MetadataProvider.js | 354 -- .../ohif-core/client/classes/OHIFError.js | 14 - .../client/classes/OHIFStudyMetadataSource.js | 74 - .../client/classes/OHIFStudySummary.js | 52 - Packages/ohif-core/client/classes/README.md | 167 - .../client/classes/ResizeViewportManager.js | 151 - .../StackImagePositionOffsetSynchronizer.js | 218 -- .../client/classes/StudyLoadingListener.js | 398 -- .../client/classes/StudyMetadataSource.js | 30 - .../client/classes/StudyPrefetcher.js | 331 -- .../client/classes/TypeSafeCollection.js | 498 --- Packages/ohif-core/client/classes/index.js | 69 - .../classes/metadata/InstanceMetadata.js | 227 -- .../client/classes/metadata/Metadata.js | 127 - .../classes/metadata/OHIFInstanceMetadata.js | 117 - .../classes/metadata/OHIFSeriesMetadata.js | 32 - .../classes/metadata/OHIFStudyMetadata.js | 31 - .../client/classes/metadata/README.md | 128 - .../client/classes/metadata/SeriesMetadata.js | 195 - .../client/classes/metadata/StudyMetadata.js | 396 -- .../client/classes/metadata/StudySummary.js | 78 - .../classes/metadata/WadoRsMetaDataBuilder.js | 50 - .../client/classes/metadata/index.js | 21 - .../client/classes/plugins/OHIFPlugin.js | 75 - .../client/classes/plugins/ViewportPlugin.js | 170 - .../ohif-core/client/classes/plugins/index.js | 18 - .../client/collections/currentServer.js | 11 - .../ohif-core/client/collections/index.js | 4 - .../ohif-core/client/collections/servers.js | 17 - Packages/ohif-core/client/commands.js | 18 - .../client/components/base/component.js | 49 - .../ohif-core/client/components/base/index.js | 39 - .../ohif-core/client/components/base/mixin.js | 138 - .../client/components/base/mixins/action.js | 72 - .../client/components/base/mixins/button.js | 18 - .../client/components/base/mixins/checkbox.js | 26 - .../components/base/mixins/component.js | 10 - .../client/components/base/mixins/dropdown.js | 322 -- .../client/components/base/mixins/form.js | 108 - .../client/components/base/mixins/formItem.js | 337 -- .../client/components/base/mixins/group.js | 169 - .../components/base/mixins/groupRadio.js | 32 - .../client/components/base/mixins/input.js | 18 - .../client/components/base/mixins/link.js | 26 - .../client/components/base/mixins/popover.js | 40 - .../components/base/mixins/schemaData.js | 189 - .../client/components/base/mixins/select.js | 18 - .../client/components/base/mixins/select2.js | 229 -- .../components/base/section/section.html | 3 - .../client/components/base/section/section.js | 61 - .../client/components/base/template.js | 112 - .../components/base/templates/button.html | 12 - .../components/base/templates/custom.html | 3 - .../client/components/base/templates/div.html | 9 - .../components/base/templates/form.html | 23 - .../components/base/templates/input.html | 17 - .../components/base/templates/link.html | 11 - .../components/base/templates/select.html | 28 - .../client/components/base/templates/tr.html | 9 - .../components/base/wrappers/label.html | 15 - .../base/wrappers/labelContent.html | 9 - .../bootstrap/dialog/bootstrap.styl | 14 - .../components/bootstrap/dialog/confirm.html | 7 - .../components/bootstrap/dialog/form.html | 45 - .../components/bootstrap/dialog/form.js | 114 - .../components/bootstrap/dialog/header.html | 16 - .../components/bootstrap/dialog/info.html | 19 - .../components/bootstrap/dialog/info.js | 16 - .../components/bootstrap/dialog/loading.html | 7 - .../components/bootstrap/dialog/loading.js | 14 - .../components/bootstrap/dialog/loading.styl | 9 - .../components/bootstrap/dialog/login.html | 6 - .../components/bootstrap/dialog/login.js | 17 - .../components/bootstrap/dialog/progress.html | 17 - .../components/bootstrap/dialog/progress.js | 87 - .../components/bootstrap/dialog/progress.styl | 14 - .../components/bootstrap/dialog/simple.html | 13 - .../components/bootstrap/dialog/simple.js | 61 - .../dialog/unsavedChangesDialog.html | 35 - .../bootstrap/dialog/unsavedChangesDialog.js | 132 - .../dialog/unsavedChangesDialog.styl | 7 - .../bootstrap/dropdown/dropdown.styl | 61 - .../components/bootstrap/dropdown/form.html | 41 - .../components/bootstrap/dropdown/form.js | 22 - .../components/bootstrap/form/button.html | 8 - .../components/bootstrap/form/form.html | 8 - .../components/bootstrap/form/group.html | 9 - .../components/bootstrap/form/link.html | 8 - .../client/components/bootstrap/index.js | 39 - .../components/bootstrap/input/checkbox.html | 15 - .../bootstrap/input/groupRadio.html | 22 - .../components/bootstrap/input/hidden.html | 7 - .../components/bootstrap/input/number.html | 14 - .../components/bootstrap/input/password.html | 7 - .../components/bootstrap/input/radio.html | 15 - .../components/bootstrap/input/range.html | 14 - .../components/bootstrap/input/select.html | 17 - .../components/bootstrap/input/text.html | 13 - .../bootstrap/notification/index.js | 3 - .../bootstrap/notification/notification.styl | 70 - .../notification/notificationNote.html | 18 - .../notification/notificationNote.js | 21 - .../components/bootstrap/popover/form.html | 17 - .../bootstrap/popover/popoverSimple.html | 4 - .../client/components/header/header.html | 12 - .../client/components/header/header.js | 29 - .../client/components/header/header.styl | 26 - .../client/components/header/index.js | 3 - .../hotkeys/confirmReplacementPopover.html | 6 - .../client/components/hotkeys/form.html | 21 - .../client/components/hotkeys/form.js | 237 -- .../client/components/hotkeys/formTable.html | 18 - .../client/components/hotkeys/formTable.js | 17 - .../client/components/hotkeys/index.js | 7 - Packages/ohif-core/client/components/index.js | 8 - .../client/components/pages/error/error.html | 16 - .../client/components/pages/error/error.js | 13 - .../client/components/pages/error/error.styl | 19 - .../client/components/pages/error/index.js | 3 - .../client/components/pages/index.js | 2 - .../client/components/pages/message/index.js | 2 - .../components/pages/message/message.html | 9 - .../components/pages/message/message.styl | 31 - .../client/components/paginationArea/index.js | 3 - .../paginationArea/paginationArea.html | 29 - .../paginationArea/paginationArea.js | 82 - .../paginationArea/paginationArea.styl | 67 - .../client/components/playground/index.js | 3 - .../components/playground/playground.html | 28 - .../components/playground/playground.js | 46 - .../components/playground/playground.styl | 37 - .../client/components/scrollArea/index.js | 3 - .../components/scrollArea/scrollArea.html | 9 - .../components/scrollArea/scrollArea.js | 93 - .../components/scrollArea/scrollArea.styl | 79 - Packages/ohif-core/client/cornerstone.js | 5 - Packages/ohif-core/client/header.js | 11 - Packages/ohif-core/client/helpers/blaze.js | 32 - Packages/ohif-core/client/helpers/data.js | 61 - Packages/ohif-core/client/helpers/debug.js | 17 - Packages/ohif-core/client/helpers/index.js | 8 - Packages/ohif-core/client/helpers/logical.js | 73 - Packages/ohif-core/client/helpers/number.js | 21 - Packages/ohif-core/client/helpers/string.js | 20 - Packages/ohif-core/client/helpers/typing.js | 21 - Packages/ohif-core/client/helpers/ui.js | 11 - Packages/ohif-core/client/hotkeys.js | 12 - Packages/ohif-core/client/ie.js | 12 - Packages/ohif-core/client/index.js | 15 - .../client/lib/DICOMTagDescriptions.js | 3260 ----------------- .../client/lib/DICOMWeb/getAttribute.js | 44 - .../lib/DICOMWeb/getAuthorizationHeader.js | 26 - .../client/lib/DICOMWeb/getModalities.js | 21 - .../ohif-core/client/lib/DICOMWeb/getName.js | 26 - .../client/lib/DICOMWeb/getNumber.js | 21 - .../client/lib/DICOMWeb/getString.js | 23 - .../ohif-core/client/lib/DICOMWeb/index.js | 19 - Packages/ohif-core/client/lib/absoluteUrl.js | 10 - Packages/ohif-core/client/lib/blaze.js | 66 - Packages/ohif-core/client/lib/cornerstone.js | 312 -- .../ohif-core/client/lib/getCurrentServer.js | 17 - .../ohif-core/client/lib/getStudyBoxData.js | 15 - Packages/ohif-core/client/lib/index.js | 18 - Packages/ohif-core/client/lib/loadStudy.js | 82 - Packages/ohif-core/client/lib/object.js | 52 - .../ohif-core/client/lib/parseFloatArray.js | 14 - Packages/ohif-core/client/lib/parsingUtils.js | 79 - .../client/lib/retrieveStudiesMetadata.js | 32 - .../client/lib/retrieveStudyMetadata.js | 61 - .../ohif-core/client/lib/searchStudies.js | 27 - Packages/ohif-core/client/lib/string.js | 51 - .../third-party/transition-to-from-auto.js | 151 - Packages/ohif-core/client/lib/ui.js | 90 - Packages/ohif-core/client/lib/user.js | 16 - Packages/ohif-core/client/lib/utils.js | 42 - Packages/ohif-core/client/lib/viewer.js | 3 - Packages/ohif-core/client/lib/writeScript.js | 14 - Packages/ohif-core/client/metadata.js | 11 - Packages/ohif-core/client/schema.js | 35 - Packages/ohif-core/client/schema/servers.js | 314 -- Packages/ohif-core/client/services/index.js | 15 - .../client/services/qido/instances.js | 92 - .../ohif-core/client/services/qido/studies.js | 134 - .../client/services/wado/retrieveMetadata.js | 391 -- Packages/ohif-core/client/startup.js | 22 - Packages/ohif-core/client/studies.js | 9 - .../ohif-core/client/ui/bounded/bounded.js | 240 -- .../ohif-core/client/ui/dialog/display.js | 94 - .../ohif-core/client/ui/dialog/spatial.js | 30 - .../client/ui/dialog/unsavedChangesDialog.js | 14 - .../client/ui/dimensional/dimensional.js | 50 - .../client/ui/dimensional/dimensional.styl | 2 - .../client/ui/draggable/draggable.js | 229 -- .../ohif-core/client/ui/dropdown/class.js | 38 - .../ohif-core/client/ui/dropdown/display.js | 43 - Packages/ohif-core/client/ui/handleError.js | 35 - Packages/ohif-core/client/ui/index.js | 14 - .../client/ui/notifications/notifications.js | 112 - .../ohif-core/client/ui/popover/display.js | 88 - .../client/ui/resizable/resizable.js | 182 - .../client/ui/resizable/resizable.styl | 58 - Packages/ohif-core/client/ui/styleProperty.js | 68 - .../ui/unsavedChanges/unsavedChanges.js | 555 --- .../ohif-core/client/utils/absoluteUrl.js | 19 - Packages/ohif-core/client/utils/guid.js | 13 - Packages/ohif-core/client/utils/index.js | 8 - Packages/ohif-core/client/utils/objectPath.js | 116 - Packages/ohif-core/main.js | 18 - Packages/ohif-core/package.js | 51 - Packages/ohif-core/public/js/svgxuse.min.js | 12 - .../client/classes/Protocol.js | 2 +- .../client/classes/Rule.js | 2 +- .../client/classes/Stage.js | 2 +- .../matchedProtocols/matchedProtocols.js | 2 +- .../nextPresentationGroupButton.js | 1 - .../previousPresentationGroupButton.js | 1 - .../protocolEditor/protocolEditor.js | 7 +- .../ruleEntryDialog/ruleEntryDialog.js | 2 +- .../components/stageDetails/stageDetails.js | 2 - .../components/stageSortable/stageSortable.js | 17 +- .../client/matcher/HPMatcher.js | 2 +- .../client/protocolEngine.js | 2 +- Packages/ohif-hanging-protocols/package.js | 5 +- .../client/configuration/configuration.js | 2 +- .../client/configuration/dataExchange.js | 2 +- .../ohif-measurement-table/client/index.js | 2 +- .../client/schema/arrowAnnotate.js | 3 +- .../client/schema/ellipticalRoi.js | 3 +- .../client/schema/length.js | 3 +- .../client/schema/rectangleRoi.js | 3 +- .../client/schema/simpleAngle.js | 3 +- .../client/schema/toolGroupSchema.js | 3 +- .../utils/retrieveDataFromMeasurements.js | 2 +- Packages/ohif-measurement-table/package.js | 3 +- Packages/ohif-measurements/package.js | 1 - Packages/ohif-measurements/src/base.js | 2 +- .../src/configuration/measurements.js | 6 +- .../src/configuration/timepoints.js | 4 +- .../src/conformance/ConformanceCriteria.js | 2 +- .../src/helpers/measurements.js | 2 +- .../MeasurementHandlers.js | 2 +- .../handleChildMeasurementAdded.js | 2 +- .../handleChildMeasurementModified.js | 2 +- .../handleChildMeasurementRemoved.js | 2 +- .../handleSingleMeasurementAdded.js | 2 +- .../handleSingleMeasurementModified.js | 2 +- .../handleSingleMeasurementRemoved.js | 2 +- .../src/lib/MeasurementManager.js | 2 +- .../src/lib/activateMeasurements.js | 2 +- .../src/lib/clearCornerstoneToolState.js | 2 +- .../src/lib/deactivateAllToolData.js | 2 +- .../ohif-measurements/src/lib/exportPdf.js | 2 +- .../ohif-measurements/src/lib/exportToCsv.js | 2 +- .../src/lib/findAndRenderDisplaySet.js | 4 +- .../src/lib/getActiveTimepoint.js | 5 +- .../src/lib/getImageDataUrl.js | 2 +- .../src/lib/getLocationLabel.js | 2 +- .../src/lib/getMeasurementsGroupedByNumber.js | 2 +- .../src/lib/getParentToolData.js | 2 +- .../src/lib/getTimepointName.js | 2 +- .../src/lib/getToolConfiguration.js | 2 +- .../src/lib/hangingProtocolCustomizations.js | 2 +- .../src/lib/isNewLesionsMeasurement.js | 2 +- .../src/lib/isSaveDisabled.js | 2 +- .../src/lib/jumpToRowItem.js | 4 +- .../src/lib/navigateOverLesions.js | 2 +- .../src/lib/openLocationModal.js | 2 +- .../src/lib/saveMeasurements.js | 2 +- .../src/lib/syncMeasurementAndToolData.js | 2 +- .../src/lib/toggleLabelButton.js | 2 +- .../src/lib/triggerTimepointUnsavedChanges.js | 2 +- .../src/lib/updateMeasurementsDescription.js | 2 +- .../src/reports/reportMeasurementData.js | 2 +- .../src/schema/measurements.js | 3 +- .../src/schema/timepoints.js | 3 +- Packages/ohif-study-list/client/base.js | 2 +- .../client/collections/studies.js | 2 +- .../client/components/StudyList.js | 2 +- .../seriesDetailsTable/seriesDetailsTable.js | 2 +- .../client/components/studylist/studylist.js | 2 +- .../studylistResult/studylistResult.js | 2 +- .../studylistStudy/studylistStudy.js | 2 +- .../studylistToolbar/studylistToolbar.js | 7 +- Packages/ohif-study-list/client/dropdown.js | 2 +- .../client/lib/exportSelectedStudies.js | 2 +- .../client/lib/exportStudies.js | 2 +- .../client/lib/getSelectedStudies.js | 2 +- .../client/lib/getStudyPriors.js | 2 +- .../client/lib/getStudyPriorsMap.js | 2 +- .../client/lib/queryStudies.js | 2 +- .../ohif-study-list/client/lib/studylist.js | 5 +- .../client/lib/viewSeriesDetails.js | 2 +- .../ohif-study-list/client/lib/viewStudies.js | 2 +- Packages/ohif-study-list/package.js | 5 +- .../client/compatibility/dialogPolyfill.js | 412 --- .../client/compatibility/dialogPolyfill.styl | 34 - .../components/basic/aboutModal/aboutModal.js | 2 +- .../components/basic/layout/layout.html | 3 - .../client/components/browser/item.js | 2 +- .../client/components/browser/quickSwitch.js | 2 +- .../client/components/browser/series.js | 2 +- .../associationModal/associationModal.js | 3 +- .../studyAssociationTable.js | 2 +- .../measurements/caseProgress/caseProgress.js | 2 +- .../measurementEditDescription.js | 2 +- .../measurementLightTableRow.js | 2 +- .../measurementLightTableView.js | 2 +- .../measurements/measurementTable/index.js | 4 - .../measurementTable/measurementTable.js | 2 +- .../measurementTableHUD.html | 20 - .../measurementTableHUD.js | 72 - .../measurementTableHUD.styl | 95 - .../measurementTableHeaderRow.js | 2 +- .../measurementTableRow.js | 2 +- .../measurementTableTimepointCell.js | 2 +- .../measurementTableView.js | 2 +- .../client/components/selectTree/mixin.js | 2 +- .../selectTree/selectTree/selectTree.js | 4 +- .../components/serverInformation/index.js | 4 +- .../serverInformationForm.js | 2 +- .../viewer/GridLayout/GridLayout.js | 2 +- .../ToolContextMenu/toolContextMenu-blz.js | 2 +- .../viewer/ViewerMain/ViewerMain.js | 113 +- .../viewer/ViewerMain/ViewerMain.styl | 2 +- .../viewer/cineDialog/cineDialog.html | 50 - .../viewer/cineDialog/cineDialog.js | 310 -- .../viewer/cineDialog/cineDialog.styl | 162 - .../viewer/downloadDialog/downloadDialog.js | 4 +- .../viewer/layoutChooser/layoutChooser.js | 15 +- .../seriesQuickSwitch/seriesQuickSwitch.js | 10 +- .../studySeriesQuickSwitch.js | 5 +- .../studyTimepointBrowser/studyTimepoint.js | 2 +- .../studyTimepointBrowser.js | 2 +- .../studyTimepointStudy.js | 2 +- .../toolbarSectionButton.js | 3 +- .../viewer/windowLevelPresets/form.js | 2 +- Packages/ohif-viewerbase/client/index.js | 5 +- .../client/lib/StackManager.js | 2 +- .../ohif-viewerbase/client/lib/WLPresets.js | 2 +- .../client/lib/classes/LayoutManager.js | 19 +- .../client/lib/createStacks.js | 2 +- .../client/lib/debugReactivity.js | 70 - .../client/lib/displayReferenceLines.js | 2 +- .../client/lib/getImageIdForImagePath.js | 2 +- .../client/lib/getStudyMetadata.js | 2 +- .../client/lib/getWADORSImageId.js | 2 +- .../lib/helpers/capitalizeFirstLetter.js | 16 - .../client/lib/helpers/formatDA.js | 25 - .../client/lib/helpers/formatJSDate.js | 19 - .../lib/helpers/formatNumberPrecision.js | 14 - .../client/lib/helpers/formatPN.js | 30 - .../client/lib/helpers/formatTM.js | 35 - .../client/lib/helpers/getUsername.js | 15 - .../client/lib/helpers/ifTypeIs.js | 12 - .../ohif-viewerbase/client/lib/helpers/inc.js | 5 - .../client/lib/helpers/index.js | 42 - .../client/lib/helpers/isDisplaySetActive.js | 57 - .../client/lib/helpers/isTouchDevice.js | 24 - .../client/lib/helpers/isValidNumber.js | 3 - .../client/lib/helpers/jsDateFromNow.js | 17 - .../client/lib/helpers/objectEach.js | 9 - .../client/lib/helpers/objectToPairs.js | 12 - .../lib/helpers/prettyPrintStringify.js | 21 - .../client/lib/helpers/sorting.js | 57 - .../client/lib/helpers/studyThumbnails.js | 27 - .../ohif-viewerbase/client/lib/hotkeyUtils.js | 11 +- .../client/lib/panelNavigation.js | 2 +- .../client/lib/prepareViewerData.js | 2 +- .../client/lib/redux/actions.js | 9 - .../ohif-viewerbase/client/lib/redux/index.js | 8 - .../client/lib/redux/reducers/index.js | 10 - .../client/lib/redux/reducers/tools.js | 101 - .../client/lib/redux/reducers/viewports.js | 15 - .../client/lib/renderViewer.js | 33 - .../client/lib/setActiveViewport.js | 5 +- .../lib/setMammogramViewportAlignment.js | 2 +- .../ohif-viewerbase/client/lib/sortStudy.js | 2 +- .../client/lib/textMarkerUtils.js | 87 - .../ohif-viewerbase/client/lib/toolManager.js | 5 +- .../client/lib/unloadHandlers.js | 2 +- .../client/lib/updateMetaDataManager.js | 2 +- .../client/lib/viewportUtils.js | 19 +- Packages/ohif-viewerbase/main.js | 4 +- Packages/ohif-viewerbase/namespace.js | 2 +- Packages/ohif-viewerbase/package.js | 20 +- .../viewer/gridLayout/gridLayout.tests.js | 4 - .../tests/coverage/exportCoverageReport.js | 1 - ...0a3252f025c3b436cda09bf88f5ead9f975d4be.js | 28 +- .../toolbarSection/toolbarSection.js | 2 +- .../client/components/viewer/viewer.js | 2 +- .../StandaloneViewer/client/config.js | 2 +- .../StandaloneViewer/client/headerItems.js | 2 +- StandaloneViewer/StandaloneViewer/routes.js | 2 +- ...612d22bc068486bdea0fa7e7b80702ebb1d8df5.js | 32 +- config/dcm4chee-dicomweb-clientonly.json | 37 + packages/ohif-core/log.js | 28 - 418 files changed, 402 insertions(+), 19154 deletions(-) delete mode 100644 OHIFViewer/client/body.styl delete mode 100644 OHIFViewer/client/routes.js delete mode 100644 Packages/ohif-core/client/base.js delete mode 100644 Packages/ohif-core/client/classes.js delete mode 100644 Packages/ohif-core/client/classes/CommandsManager.js delete mode 100644 Packages/ohif-core/client/classes/HotkeysContext.js delete mode 100644 Packages/ohif-core/client/classes/HotkeysManager.js delete mode 100644 Packages/ohif-core/client/classes/ImageSet.js delete mode 100644 Packages/ohif-core/client/classes/MetadataProvider.js delete mode 100644 Packages/ohif-core/client/classes/OHIFError.js delete mode 100644 Packages/ohif-core/client/classes/OHIFStudyMetadataSource.js delete mode 100644 Packages/ohif-core/client/classes/OHIFStudySummary.js delete mode 100644 Packages/ohif-core/client/classes/README.md delete mode 100644 Packages/ohif-core/client/classes/ResizeViewportManager.js delete mode 100644 Packages/ohif-core/client/classes/StackImagePositionOffsetSynchronizer.js delete mode 100644 Packages/ohif-core/client/classes/StudyLoadingListener.js delete mode 100644 Packages/ohif-core/client/classes/StudyMetadataSource.js delete mode 100644 Packages/ohif-core/client/classes/StudyPrefetcher.js delete mode 100644 Packages/ohif-core/client/classes/TypeSafeCollection.js delete mode 100644 Packages/ohif-core/client/classes/index.js delete mode 100644 Packages/ohif-core/client/classes/metadata/InstanceMetadata.js delete mode 100644 Packages/ohif-core/client/classes/metadata/Metadata.js delete mode 100644 Packages/ohif-core/client/classes/metadata/OHIFInstanceMetadata.js delete mode 100644 Packages/ohif-core/client/classes/metadata/OHIFSeriesMetadata.js delete mode 100644 Packages/ohif-core/client/classes/metadata/OHIFStudyMetadata.js delete mode 100644 Packages/ohif-core/client/classes/metadata/README.md delete mode 100644 Packages/ohif-core/client/classes/metadata/SeriesMetadata.js delete mode 100644 Packages/ohif-core/client/classes/metadata/StudyMetadata.js delete mode 100644 Packages/ohif-core/client/classes/metadata/StudySummary.js delete mode 100644 Packages/ohif-core/client/classes/metadata/WadoRsMetaDataBuilder.js delete mode 100644 Packages/ohif-core/client/classes/metadata/index.js delete mode 100644 Packages/ohif-core/client/classes/plugins/OHIFPlugin.js delete mode 100644 Packages/ohif-core/client/classes/plugins/ViewportPlugin.js delete mode 100644 Packages/ohif-core/client/classes/plugins/index.js delete mode 100644 Packages/ohif-core/client/collections/currentServer.js delete mode 100644 Packages/ohif-core/client/collections/index.js delete mode 100644 Packages/ohif-core/client/collections/servers.js delete mode 100644 Packages/ohif-core/client/commands.js delete mode 100644 Packages/ohif-core/client/components/base/component.js delete mode 100644 Packages/ohif-core/client/components/base/index.js delete mode 100644 Packages/ohif-core/client/components/base/mixin.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/action.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/button.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/checkbox.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/component.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/dropdown.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/form.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/formItem.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/group.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/groupRadio.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/input.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/link.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/popover.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/schemaData.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/select.js delete mode 100644 Packages/ohif-core/client/components/base/mixins/select2.js delete mode 100644 Packages/ohif-core/client/components/base/section/section.html delete mode 100644 Packages/ohif-core/client/components/base/section/section.js delete mode 100644 Packages/ohif-core/client/components/base/template.js delete mode 100644 Packages/ohif-core/client/components/base/templates/button.html delete mode 100644 Packages/ohif-core/client/components/base/templates/custom.html delete mode 100644 Packages/ohif-core/client/components/base/templates/div.html delete mode 100644 Packages/ohif-core/client/components/base/templates/form.html delete mode 100644 Packages/ohif-core/client/components/base/templates/input.html delete mode 100644 Packages/ohif-core/client/components/base/templates/link.html delete mode 100644 Packages/ohif-core/client/components/base/templates/select.html delete mode 100644 Packages/ohif-core/client/components/base/templates/tr.html delete mode 100644 Packages/ohif-core/client/components/base/wrappers/label.html delete mode 100644 Packages/ohif-core/client/components/base/wrappers/labelContent.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/bootstrap.styl delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/confirm.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/form.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/form.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/header.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/info.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/info.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/loading.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/loading.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/loading.styl delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/login.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/login.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/progress.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/progress.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/progress.styl delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/simple.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/simple.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.styl delete mode 100644 Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl delete mode 100644 Packages/ohif-core/client/components/bootstrap/dropdown/form.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/dropdown/form.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/form/button.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/form/form.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/form/group.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/form/link.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/index.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/checkbox.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/groupRadio.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/hidden.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/number.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/password.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/radio.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/range.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/select.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/input/text.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/notification/index.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/notification/notification.styl delete mode 100644 Packages/ohif-core/client/components/bootstrap/notification/notificationNote.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/notification/notificationNote.js delete mode 100644 Packages/ohif-core/client/components/bootstrap/popover/form.html delete mode 100644 Packages/ohif-core/client/components/bootstrap/popover/popoverSimple.html delete mode 100644 Packages/ohif-core/client/components/header/header.html delete mode 100644 Packages/ohif-core/client/components/header/header.js delete mode 100644 Packages/ohif-core/client/components/header/header.styl delete mode 100644 Packages/ohif-core/client/components/header/index.js delete mode 100644 Packages/ohif-core/client/components/hotkeys/confirmReplacementPopover.html delete mode 100644 Packages/ohif-core/client/components/hotkeys/form.html delete mode 100644 Packages/ohif-core/client/components/hotkeys/form.js delete mode 100644 Packages/ohif-core/client/components/hotkeys/formTable.html delete mode 100644 Packages/ohif-core/client/components/hotkeys/formTable.js delete mode 100644 Packages/ohif-core/client/components/hotkeys/index.js delete mode 100644 Packages/ohif-core/client/components/index.js delete mode 100644 Packages/ohif-core/client/components/pages/error/error.html delete mode 100644 Packages/ohif-core/client/components/pages/error/error.js delete mode 100644 Packages/ohif-core/client/components/pages/error/error.styl delete mode 100644 Packages/ohif-core/client/components/pages/error/index.js delete mode 100644 Packages/ohif-core/client/components/pages/index.js delete mode 100644 Packages/ohif-core/client/components/pages/message/index.js delete mode 100644 Packages/ohif-core/client/components/pages/message/message.html delete mode 100644 Packages/ohif-core/client/components/pages/message/message.styl delete mode 100644 Packages/ohif-core/client/components/paginationArea/index.js delete mode 100644 Packages/ohif-core/client/components/paginationArea/paginationArea.html delete mode 100644 Packages/ohif-core/client/components/paginationArea/paginationArea.js delete mode 100644 Packages/ohif-core/client/components/paginationArea/paginationArea.styl delete mode 100644 Packages/ohif-core/client/components/playground/index.js delete mode 100644 Packages/ohif-core/client/components/playground/playground.html delete mode 100644 Packages/ohif-core/client/components/playground/playground.js delete mode 100644 Packages/ohif-core/client/components/playground/playground.styl delete mode 100644 Packages/ohif-core/client/components/scrollArea/index.js delete mode 100644 Packages/ohif-core/client/components/scrollArea/scrollArea.html delete mode 100644 Packages/ohif-core/client/components/scrollArea/scrollArea.js delete mode 100644 Packages/ohif-core/client/components/scrollArea/scrollArea.styl delete mode 100644 Packages/ohif-core/client/cornerstone.js delete mode 100644 Packages/ohif-core/client/header.js delete mode 100644 Packages/ohif-core/client/helpers/blaze.js delete mode 100644 Packages/ohif-core/client/helpers/data.js delete mode 100644 Packages/ohif-core/client/helpers/debug.js delete mode 100644 Packages/ohif-core/client/helpers/index.js delete mode 100644 Packages/ohif-core/client/helpers/logical.js delete mode 100644 Packages/ohif-core/client/helpers/number.js delete mode 100644 Packages/ohif-core/client/helpers/string.js delete mode 100644 Packages/ohif-core/client/helpers/typing.js delete mode 100644 Packages/ohif-core/client/helpers/ui.js delete mode 100644 Packages/ohif-core/client/hotkeys.js delete mode 100644 Packages/ohif-core/client/ie.js delete mode 100644 Packages/ohif-core/client/index.js delete mode 100644 Packages/ohif-core/client/lib/DICOMTagDescriptions.js delete mode 100644 Packages/ohif-core/client/lib/DICOMWeb/getAttribute.js delete mode 100644 Packages/ohif-core/client/lib/DICOMWeb/getAuthorizationHeader.js delete mode 100644 Packages/ohif-core/client/lib/DICOMWeb/getModalities.js delete mode 100644 Packages/ohif-core/client/lib/DICOMWeb/getName.js delete mode 100644 Packages/ohif-core/client/lib/DICOMWeb/getNumber.js delete mode 100644 Packages/ohif-core/client/lib/DICOMWeb/getString.js delete mode 100644 Packages/ohif-core/client/lib/DICOMWeb/index.js delete mode 100644 Packages/ohif-core/client/lib/absoluteUrl.js delete mode 100644 Packages/ohif-core/client/lib/blaze.js delete mode 100644 Packages/ohif-core/client/lib/cornerstone.js delete mode 100644 Packages/ohif-core/client/lib/getCurrentServer.js delete mode 100644 Packages/ohif-core/client/lib/getStudyBoxData.js delete mode 100644 Packages/ohif-core/client/lib/index.js delete mode 100644 Packages/ohif-core/client/lib/loadStudy.js delete mode 100644 Packages/ohif-core/client/lib/object.js delete mode 100644 Packages/ohif-core/client/lib/parseFloatArray.js delete mode 100644 Packages/ohif-core/client/lib/parsingUtils.js delete mode 100644 Packages/ohif-core/client/lib/retrieveStudiesMetadata.js delete mode 100644 Packages/ohif-core/client/lib/retrieveStudyMetadata.js delete mode 100644 Packages/ohif-core/client/lib/searchStudies.js delete mode 100644 Packages/ohif-core/client/lib/string.js delete mode 100644 Packages/ohif-core/client/lib/third-party/transition-to-from-auto.js delete mode 100644 Packages/ohif-core/client/lib/ui.js delete mode 100644 Packages/ohif-core/client/lib/user.js delete mode 100644 Packages/ohif-core/client/lib/utils.js delete mode 100644 Packages/ohif-core/client/lib/viewer.js delete mode 100644 Packages/ohif-core/client/lib/writeScript.js delete mode 100644 Packages/ohif-core/client/metadata.js delete mode 100644 Packages/ohif-core/client/schema.js delete mode 100644 Packages/ohif-core/client/schema/servers.js delete mode 100644 Packages/ohif-core/client/services/index.js delete mode 100644 Packages/ohif-core/client/services/qido/instances.js delete mode 100644 Packages/ohif-core/client/services/qido/studies.js delete mode 100644 Packages/ohif-core/client/services/wado/retrieveMetadata.js delete mode 100644 Packages/ohif-core/client/startup.js delete mode 100644 Packages/ohif-core/client/studies.js delete mode 100644 Packages/ohif-core/client/ui/bounded/bounded.js delete mode 100644 Packages/ohif-core/client/ui/dialog/display.js delete mode 100644 Packages/ohif-core/client/ui/dialog/spatial.js delete mode 100644 Packages/ohif-core/client/ui/dialog/unsavedChangesDialog.js delete mode 100644 Packages/ohif-core/client/ui/dimensional/dimensional.js delete mode 100644 Packages/ohif-core/client/ui/dimensional/dimensional.styl delete mode 100644 Packages/ohif-core/client/ui/draggable/draggable.js delete mode 100644 Packages/ohif-core/client/ui/dropdown/class.js delete mode 100644 Packages/ohif-core/client/ui/dropdown/display.js delete mode 100644 Packages/ohif-core/client/ui/handleError.js delete mode 100644 Packages/ohif-core/client/ui/index.js delete mode 100644 Packages/ohif-core/client/ui/notifications/notifications.js delete mode 100644 Packages/ohif-core/client/ui/popover/display.js delete mode 100644 Packages/ohif-core/client/ui/resizable/resizable.js delete mode 100644 Packages/ohif-core/client/ui/resizable/resizable.styl delete mode 100644 Packages/ohif-core/client/ui/styleProperty.js delete mode 100644 Packages/ohif-core/client/ui/unsavedChanges/unsavedChanges.js delete mode 100644 Packages/ohif-core/client/utils/absoluteUrl.js delete mode 100644 Packages/ohif-core/client/utils/guid.js delete mode 100644 Packages/ohif-core/client/utils/index.js delete mode 100644 Packages/ohif-core/client/utils/objectPath.js delete mode 100644 Packages/ohif-core/main.js delete mode 100644 Packages/ohif-core/package.js delete mode 100644 Packages/ohif-core/public/js/svgxuse.min.js delete mode 100644 Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.js delete mode 100644 Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.styl delete mode 100644 Packages/ohif-viewerbase/client/components/basic/layout/layout.html delete mode 100644 Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.html delete mode 100644 Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.js delete mode 100644 Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.styl delete mode 100644 Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.html delete mode 100644 Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.js delete mode 100644 Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.styl delete mode 100644 Packages/ohif-viewerbase/client/lib/debugReactivity.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/capitalizeFirstLetter.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/formatDA.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/formatJSDate.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/formatNumberPrecision.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/formatPN.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/formatTM.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/getUsername.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/ifTypeIs.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/inc.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/index.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/isDisplaySetActive.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/isTouchDevice.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/isValidNumber.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/jsDateFromNow.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/objectEach.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/objectToPairs.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/prettyPrintStringify.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/sorting.js delete mode 100644 Packages/ohif-viewerbase/client/lib/helpers/studyThumbnails.js delete mode 100644 Packages/ohif-viewerbase/client/lib/redux/actions.js delete mode 100644 Packages/ohif-viewerbase/client/lib/redux/index.js delete mode 100644 Packages/ohif-viewerbase/client/lib/redux/reducers/index.js delete mode 100644 Packages/ohif-viewerbase/client/lib/redux/reducers/tools.js delete mode 100644 Packages/ohif-viewerbase/client/lib/redux/reducers/viewports.js delete mode 100644 Packages/ohif-viewerbase/client/lib/renderViewer.js delete mode 100644 Packages/ohif-viewerbase/client/lib/textMarkerUtils.js create mode 100644 config/dcm4chee-dicomweb-clientonly.json delete mode 100644 packages/ohif-core/log.js diff --git a/OHIFViewer/.meteor/packages b/OHIFViewer/.meteor/packages index 36a0d13ea..14bcec316 100644 --- a/OHIFViewer/.meteor/packages +++ b/OHIFViewer/.meteor/packages @@ -26,12 +26,10 @@ standard-minifier-js@2.4.0 shell-server@0.4.0 # OHIF Packages -ohif:core ohif:cornerstone ohif:viewerbase ohif:study-list ohif:hanging-protocols -ohif:measurement-table fortawesome:fontawesome aldeed:simple-schema # Third party package to deal with schemas diff --git a/OHIFViewer/.meteor/versions b/OHIFViewer/.meteor/versions index 91d6d56eb..52f12788e 100644 --- a/OHIFViewer/.meteor/versions +++ b/OHIFViewer/.meteor/versions @@ -63,11 +63,8 @@ mongo-id@1.0.7 natestrauser:select2@4.0.3 npm-mongo@3.1.2-beta181.7 observe-sequence@1.0.16 -ohif:core@0.0.1 ohif:cornerstone@0.0.1 ohif:hanging-protocols@0.0.1 -ohif:measurement-table@0.0.1 -ohif:measurements@0.0.1 ohif:study-list@0.0.1 ohif:themes@0.0.1 ohif:themes-common@0.0.1 diff --git a/OHIFViewer/client/body.styl b/OHIFViewer/client/body.styl deleted file mode 100644 index 69da11a5a..000000000 --- a/OHIFViewer/client/body.styl +++ /dev/null @@ -1,4 +0,0 @@ -body - background-color: black - height: 100% - width: 100% diff --git a/OHIFViewer/client/components/App.css b/OHIFViewer/client/components/App.css index 08cc04a48..de919d2ba 100644 --- a/OHIFViewer/client/components/App.css +++ b/OHIFViewer/client/components/App.css @@ -1,4 +1,16 @@ +html, +body, #root { - height: 100%; - width: 100%; + background-color: black; + height: 100%; + width: 100%; + margin: 0; } + +body { + box-sizing: border-box; + margin: 0; + padding: 0; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} \ No newline at end of file diff --git a/OHIFViewer/client/components/App.js b/OHIFViewer/client/components/App.js index 5f05a2bcc..15d490f91 100644 --- a/OHIFViewer/client/components/App.js +++ b/OHIFViewer/client/components/App.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { withRouter } from 'react-router'; import { Route, Switch } from 'react-router-dom'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import ViewerRouting from "./ViewerRouting.js"; import IHEInvokeImageDisplay from './IHEInvokeImageDisplay.js'; import './App.css'; @@ -20,6 +20,11 @@ function setContext(context) { class App extends Component { componentDidMount() { + // Temporary until the rest of the UI is in React + window.router = { + history: this.props.history + }; + this.unlisten = this.props.history.listen((location, action) => { setContext(window.location.pathname); }); diff --git a/OHIFViewer/client/components/ViewerFromStudyData.js b/OHIFViewer/client/components/ViewerFromStudyData.js index 191a4ac4b..a077656ec 100644 --- a/OHIFViewer/client/components/ViewerFromStudyData.js +++ b/OHIFViewer/client/components/ViewerFromStudyData.js @@ -1,7 +1,46 @@ import React, {Component} from "react"; import PropTypes from "prop-types"; import Viewer from "./viewer/viewer.js"; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; + +function createDisplaySets(studies) { + // Define the OHIF.viewer.data global object + OHIF.viewer.data = OHIF.viewer.data || {}; + + // @TypeSafeStudies + // Clears OHIF.viewer.Studies collection + OHIF.viewer.Studies.removeAll(); + + // @TypeSafeStudies + // Clears OHIF.viewer.StudyMetadataList collection + OHIF.viewer.StudyMetadataList.removeAll(); + + OHIF.viewer.data.studyInstanceUids = []; + + const updatedStudies = studies.map(study => { + const studyMetadata = new OHIF.metadata.OHIFStudyMetadata(study, study.studyInstanceUid); + let displaySets = study.displaySets; + + if (!study.displaySets) { + displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata); + study.displaySets = displaySets; + } + + studyMetadata.setDisplaySets(displaySets); + + study.selected = true; + OHIF.viewer.Studies.insert(study); + OHIF.viewer.StudyMetadataList.insert(studyMetadata); + OHIF.viewer.data.studyInstanceUids.push(study.studyInstanceUid); + + // Updates WADO-RS metaDataManager + OHIF.viewerbase.updateMetaDataManager(study); + + return study; + }); + + return updatedStudies; +} class ViewerFromStudyData extends Component { constructor(props) { @@ -25,8 +64,11 @@ class ViewerFromStudyData extends Component { // Render the viewer when the data is ready promise.then(({ studies, viewerData }) => { OHIF.viewer.data = viewerData; + + const updatedStudies = createDisplaySets(studies); + this.setState({ - studies, + studies: updatedStudies, }); }).catch(error => { this.setState({ @@ -50,7 +92,7 @@ class ViewerFromStudyData extends Component { } ViewerFromStudyData.propTypes = { - studyInstanceUids: PropTypes.array, + studyInstanceUids: PropTypes.array.isRequired, seriesInstanceUids: PropTypes.array }; diff --git a/OHIFViewer/client/components/ViewerRouting.js b/OHIFViewer/client/components/ViewerRouting.js index 76e59b3d4..2d5f42059 100644 --- a/OHIFViewer/client/components/ViewerRouting.js +++ b/OHIFViewer/client/components/ViewerRouting.js @@ -20,4 +20,13 @@ function ViewerRouting({ match }) { ); } +ViewerRouting.propTypes = { + match: PropTypes.shape({ + params: PropTypes.shape({ + studyInstanceUids: PropTypes.string.isRequired, + seriesInstanceUids: PropTypes.string + }) + }) +}; + export default ViewerRouting; diff --git a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js b/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js index a481873ed..4f40cfbe1 100644 --- a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js +++ b/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { Viewerbase } from 'meteor/ohif:viewerbase'; import { StudyBrowser } from 'react-viewerbase'; diff --git a/OHIFViewer/client/components/index.js b/OHIFViewer/client/components/index.js index 762a82894..2d857e7ff 100644 --- a/OHIFViewer/client/components/index.js +++ b/OHIFViewer/client/components/index.js @@ -4,9 +4,9 @@ import { BrowserRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import App from './App.js'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; -const store = createStore(OHIF.viewerbase.redux.combinedReducer); +const store = createStore(OHIF.redux.combinedReducer); // TODO[react] Use a provider when the whole tree is React window.store = store; diff --git a/OHIFViewer/client/components/ohifViewer/ohifViewer.js b/OHIFViewer/client/components/ohifViewer/ohifViewer.js index dc89ac640..bc6ed73c9 100644 --- a/OHIFViewer/client/components/ohifViewer/ohifViewer.js +++ b/OHIFViewer/client/components/ohifViewer/ohifViewer.js @@ -1,8 +1,7 @@ -import { Meteor } from 'meteor/meteor'; import { Template } from 'meteor/templating'; import { Session } from 'meteor/session'; import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import Viewer from '../viewer/viewer.js'; @@ -61,18 +60,8 @@ Template.ohifViewer.onCreated(() => { }); Template.ohifViewer.events({ - 'click .js-toggle-studyList'(event, instance) { + 'click .js-toggle-studyList'(event) { event.preventDefault(); - const isViewer = Session.get('ViewerOpened'); - - /*if (isViewer) { - Router.go('studylist'); - } else { - const { studyInstanceUids } = OHIF.viewer.data; - if (studyInstanceUids) { - Router.go('viewerStudies', { studyInstanceUids }); - } - }*/ } }); diff --git a/OHIFViewer/client/components/toolbarSection/toolbarSection.js b/OHIFViewer/client/components/toolbarSection/toolbarSection.js index ba9a567fc..3ba04b054 100644 --- a/OHIFViewer/client/components/toolbarSection/toolbarSection.js +++ b/OHIFViewer/client/components/toolbarSection/toolbarSection.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import 'meteor/ohif:viewerbase'; function isThereSeries(studies) { diff --git a/OHIFViewer/client/components/viewer/viewer.js b/OHIFViewer/client/components/viewer/viewer.js index b57b8bdfe..b87952eb8 100644 --- a/OHIFViewer/client/components/viewer/viewer.js +++ b/OHIFViewer/client/components/viewer/viewer.js @@ -1,7 +1,7 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { MeasurementTable } from 'meteor/ohif:measurement-table'; import { CineDialog } from 'react-viewerbase'; @@ -79,51 +79,17 @@ class Viewer extends Component { constructor(props) { super(props); - // Define the OHIF.viewer.data global object - OHIF.viewer.data = OHIF.viewer.data || {}; - - // @TypeSafeStudies - // Clears OHIF.viewer.Studies collection - OHIF.viewer.Studies.removeAll(); - - // @TypeSafeStudies - // Clears OHIF.viewer.StudyMetadataList collection - OHIF.viewer.StudyMetadataList.removeAll(); - - OHIF.viewer.data.studyInstanceUids = []; - - const studies = this.props.studies; - studies.forEach(study => { - const studyMetadata = new OHIF.metadata.StudyMetadata(study, study.studyInstanceUid); - let displaySets = study.displaySets; - - if (!study.displaySets) { - displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata); - study.displaySets = displaySets; - } - - studyMetadata.setDisplaySets(displaySets); - - study.selected = true; - OHIF.viewer.Studies.insert(study); - OHIF.viewer.StudyMetadataList.insert(studyMetadata); - OHIF.viewer.data.studyInstanceUids.push(study.studyInstanceUid); - - // Updates WADO-RS metaDataManager - OHIF.viewerbase.updateMetaDataManager(study); - }); - this.state = { leftSidebar: 'studies', rightSidebar: 'measurements', - studies + studies: this.props.studies }; } render() { return (<>
- + {/**/}
{/**/} diff --git a/OHIFViewer/client/config.js b/OHIFViewer/client/config.js index 44264fb85..4891a161a 100644 --- a/OHIFViewer/client/config.js +++ b/OHIFViewer/client/config.js @@ -1,5 +1,5 @@ import { Meteor } from 'meteor/meteor'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstoneWADOImageLoader } from 'meteor/ohif:cornerstone'; import sha from './sha.js'; import version from './version.js'; diff --git a/OHIFViewer/client/routes.js b/OHIFViewer/client/routes.js deleted file mode 100644 index 996b3b388..000000000 --- a/OHIFViewer/client/routes.js +++ /dev/null @@ -1,52 +0,0 @@ -import { Meteor } from "meteor/meteor"; -//import { Router } from 'meteor/clinical:router'; -import { OHIF } from 'meteor/ohif:core'; - -/*Router.configure({ - layoutTemplate: 'layout', -}); - - -Router.onBeforeAction('loading'); - -Router.route('/', function() { - Router.go('studylist', {}, { replaceState: true }); -}, { name: 'home' }); - -Router.route('/studylist', function() { - this.render('ohifViewer', { data: { template: 'studylist' } }); -}, { name: 'studylist' }); - -Router.route('/viewer/:studyInstanceUids', function() { - const studyInstanceUids = this.params.studyInstanceUids.split(';'); - OHIF.viewerbase.renderViewer(this, { studyInstanceUids }, 'ohifViewer'); -}, { name: 'viewerStudies' }); - -// OHIF #98 Show specific series of study -Router.route('/study/:studyInstanceUid/series/:seriesInstanceUids', function () { - const studyInstanceUid = this.params.studyInstanceUid; - const seriesInstanceUids = this.params.seriesInstanceUids.split(';'); - OHIF.viewerbase.renderViewer(this, { studyInstanceUids: [studyInstanceUid], seriesInstanceUids }, 'ohifViewer'); -}, { name: 'viewerSeries' }); - -Router.route('/IHEInvokeImageDisplay', function() { - const requestType = this.params.query.requestType; - - if (requestType === "STUDY") { - const studyInstanceUids = this.params.query.studyUID.split(';'); - - OHIF.viewerbase.renderViewer(this, {studyInstanceUids}, 'ohifViewer'); - } else if (requestType === "STUDYBASE64") { - const uids = this.params.query.studyUID; - const decodedData = window.atob(uids); - const studyInstanceUids = decodedData.split(';'); - - OHIF.viewerbase.renderViewer(this, {studyInstanceUids}, 'ohifViewer'); - } else if (requestType === "PATIENT") { - const patientUids = this.params.query.patientID.split(';'); - - Router.go('studylist', {}, {replaceState: true}); - } else { - Router.go('studylist', {}, {replaceState: true}); - } -});*/ diff --git a/OHIFViewer/package-lock.json b/OHIFViewer/package-lock.json index b148d689a..6c319263e 100644 --- a/OHIFViewer/package-lock.json +++ b/OHIFViewer/package-lock.json @@ -4159,8 +4159,9 @@ } }, "react-viewerbase": { - "version": "git://github.com/OHIF/react-viewerbase.git#af26417b7c1da75b713f70b38c9dc3ce29e5c359", - "from": "git://github.com/OHIF/react-viewerbase.git", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/react-viewerbase/-/react-viewerbase-0.1.2.tgz", + "integrity": "sha512-ibhnYNe6eVavzZGPN9s/gzRJ7cnkYz8nGMesjH6nigVDdkYgQTCnHzC1laJRFQBgeoNlsd9uKPyvOwjD9ftVuA==", "requires": { "classnames": "^2.2.6" } diff --git a/OHIFViewer/package.json b/OHIFViewer/package.json index 0205e45a3..4bcc4a4da 100644 --- a/OHIFViewer/package.json +++ b/OHIFViewer/package.json @@ -16,7 +16,7 @@ "react-dom": "^16.6.3", "react-redux": "^6.0.0", "react-router-dom": "^4.3.1", - "react-viewerbase": "git://github.com:OHIF/react-viewerbase.git", + "react-viewerbase": "^0.1.2", "redux": "^4.0.1", "underscore": "1.9.1" }, diff --git a/Packages/ohif-core/client/base.js b/Packages/ohif-core/client/base.js deleted file mode 100644 index 5da3e99ea..000000000 --- a/Packages/ohif-core/client/base.js +++ /dev/null @@ -1,5 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -OHIF.servers = { - collections: {} -}; diff --git a/Packages/ohif-core/client/classes.js b/Packages/ohif-core/client/classes.js deleted file mode 100644 index df100b2df..000000000 --- a/Packages/ohif-core/client/classes.js +++ /dev/null @@ -1,6 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import classes from './classes/'; - -OHIF.classes = classes; - -export default classes; diff --git a/Packages/ohif-core/client/classes/CommandsManager.js b/Packages/ohif-core/client/classes/CommandsManager.js deleted file mode 100644 index 6067b2fbe..000000000 --- a/Packages/ohif-core/client/classes/CommandsManager.js +++ /dev/null @@ -1,113 +0,0 @@ -import { ReactiveVar } from 'meteor/reactive-var'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -export class CommandsManager { - constructor() { - this.contexts = {}; - - // Enable reactivity by storing the last executed command - this.last = new ReactiveVar(''); - } - - getContext(contextName) { - const context = this.contexts[contextName]; - if (!context) { - return OHIF.log.warn(`No context found with name "${contextName}"`); - } - - return context; - } - - getCurrentContext() { - const contextName = OHIF.context.get(); - if (!contextName) { - return OHIF.log.warn('There is no selected context'); - } - - return this.getContext(contextName); - } - - createContext(contextName) { - if (!contextName) return; - if (this.contexts[contextName]) { - return this.clear(contextName); - } - - this.contexts[contextName] = {}; - } - - set(contextName, definitions, extend=false) { - if (typeof definitions !== 'object') return; - const context = this.getContext(contextName); - if (!context) return; - - if (!extend) { - this.clear(contextName); - } - - Object.keys(definitions).forEach(command => (context[command] = definitions[command])); - } - - register(contextName, command, definition) { - if (typeof definition !== 'object') return; - const context = this.getContext(contextName); - if (!context) return; - - context[command] = definition; - } - - setDisabledFunction(contextName, command, func) { - if (!command || typeof func !== 'function') return; - const context = this.getContext(contextName); - if (!context) return; - const definition = context[command]; - if (!definition) { - return OHIF.log.warn(`Trying to set a disabled function to a command "${command}" that was not yet defined`); - } - - definition.disabled = func; - } - - clear(contextName) { - if (!contextName) return; - this.contexts[contextName] = {}; - } - - getDefinition(command) { - const context = this.getCurrentContext(); - if (!context) return; - return context[command]; - } - - isDisabled(command) { - const definition = this.getDefinition(command); - if (!definition) return false; - const { disabled } = definition; - if (_.isFunction(disabled) && disabled()) return true; - if (!_.isFunction(disabled) && disabled) return true; - return false; - } - - run(command) { - const definition = this.getDefinition(command); - if (!definition) { - return OHIF.log.warn(`Command "${command}" not found in current context`); - } - - const { action, params } = definition; - if (this.isDisabled(command)) return; - if (typeof action !== 'function') { - return OHIF.log.warn(`No action was defined for command "${command}"`); - } else { - const result = action(params); - if (this.last.get() === command) { - this.last.dep.changed(); - } else { - this.last.set(command); - } - - return result; - } - } -} diff --git a/Packages/ohif-core/client/classes/HotkeysContext.js b/Packages/ohif-core/client/classes/HotkeysContext.js deleted file mode 100644 index 56cc60be3..000000000 --- a/Packages/ohif-core/client/classes/HotkeysContext.js +++ /dev/null @@ -1,65 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -export class HotkeysContext { - constructor(name, definitions, enabled) { - this.name = name; - this.definitions = Object.assign({}, definitions); - this.enabled = enabled; - } - - extend(definitions={}) { - if (typeof definitions !== 'object') return; - this.definitions = Object.assign({}, definitions); - Object.keys(definitions).forEach(command => { - const hotkey = definitions[command]; - this.unregister(command); - if (hotkey) { - this.register(command, hotkey); - } - - this.definitions[command] = hotkey; - }); - } - - register(command, hotkey) { - if (!hotkey) { - return; - } - - if (!command) { - return OHIF.log.warn(`No command was defined for hotkey "${hotkey}"`); - } - - const bindingKey = `keydown.hotkey.${this.name}.${command}`; - const bind = hotkey => $(document).bind(bindingKey, hotkey, event => { - if (!this.enabled.get()) return; - OHIF.commands.run(command); - event.preventDefault(); - }); - - if (hotkey instanceof Array) { - hotkey.forEach(hotkey => bind(hotkey)); - } else { - bind(hotkey); - } - } - - unregister(command) { - const bindingKey = `keydown.hotkey.${this.name}.${command}`; - if (this.definitions[command]) { - $(document).unbind(bindingKey); - delete this.definitions[command]; - } - } - - initialize() { - Object.keys(this.definitions).forEach(command => { - const hotkey = this.definitions[command]; - this.register(command, hotkey); - }); - } - - destroy() { - $(document).unbind(`keydown.hotkey.${this.name}`); - } -} diff --git a/Packages/ohif-core/client/classes/HotkeysManager.js b/Packages/ohif-core/client/classes/HotkeysManager.js deleted file mode 100644 index e895499ad..000000000 --- a/Packages/ohif-core/client/classes/HotkeysManager.js +++ /dev/null @@ -1,159 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Tracker } from 'meteor/tracker'; -import { Session } from 'meteor/session'; -import { OHIF } from 'meteor/ohif:core'; -import { HotkeysContext } from './HotkeysContext'; - -export class HotkeysManager { - constructor() { - this.contexts = {}; - this.defaults = {}; - this.currentContextName = null; - this.enabled = new ReactiveVar(true); - this.retrieveFunction = null; - this.storeFunction = null; - this.changeObserver = new Tracker.Dependency(); - - Tracker.autorun(() => { - const contextName = OHIF.context.get(); - - // Avoind falling in MongoDB collections reactivity - Tracker.nonreactive(() => this.switchToContext(contextName)); - }); - } - - setRetrieveFunction(retrieveFunction) { - this.retrieveFunction = retrieveFunction; - } - - setStoreFunction(storeFunction) { - this.storeFunction = storeFunction; - } - - store(contextName, definitions) { - const storageKey = `hotkeysDefinitions.${contextName}`; - return new Promise((resolve, reject) => { - if (this.storeFunction) { - this.storeFunction.call(this, storageKey, definitions).then(resolve).catch(reject); - } else if (OHIF.user.userLoggedIn()) { - OHIF.user.setData(storageKey, definitions).then(resolve).catch(reject); - } else { - const definitionsJSON = JSON.stringify(definitions); - localStorage.setItem(storageKey, definitionsJSON); - resolve(); - } - }); - } - - retrieve(contextName) { - const storageKey = `hotkeysDefinitions.${contextName}`; - return new Promise((resolve, reject) => { - if (this.retrieveFunction) { - this.retrieveFunction(contextName).then(resolve).catch(reject); - } else if (OHIF.user.userLoggedIn()) { - try { - resolve(OHIF.user.getData(storageKey)); - } catch(error) { - reject(error); - } - } else { - const definitionsJSON = localStorage.getItem(storageKey) || ''; - const definitions = JSON.parse(definitionsJSON) || undefined; - resolve(definitions); - } - }); - } - - disable() { - this.enabled.set(false); - } - - enable() { - this.enabled.set(true); - } - - getContext(contextName) { - return this.contexts[contextName]; - } - - getCurrentContext() { - return this.getContext(this.currentContextName); - } - - load(contextName) { - return new Promise((resolve, reject) => { - const context = this.getContext(contextName); - if (!context) return reject(); - this.retrieve(contextName).then(defs => { - const definitions = defs || this.defaults[contextName]; - if (!definitions) { - this.changeObserver.changed(); - return reject(); - } - - context.destroy(); - context.definitions = definitions; - context.initialize(); - this.changeObserver.changed(); - resolve(definitions); - }).catch(reject); - }); - } - - set(contextName, contextDefinitions, isDefaultDefinitions=false) { - const enabled = this.enabled; - const context = new HotkeysContext(contextName, contextDefinitions, enabled); - const currentContext = this.getCurrentContext(); - if (currentContext && currentContext.name === contextName) { - currentContext.destroy(); - context.initialize(); - } - - this.contexts[contextName] = context; - if (isDefaultDefinitions) { - this.defaults[contextName] = contextDefinitions; - } - } - - register(contextName, command, hotkey) { - if (!command || !hotkey) return; - const context = this.getContext(contextName); - if (!context) { - this.set(contextName, {}); - } - - context.register(command, hotkey); - } - - unsetContext(contextName) { - if (contextName === this.currentContextName) { - this.getCurrentContext().destroy(); - } - - delete this.contexts[contextName]; - delete this.defaults[contextName]; - } - - resetDefaults(contextName) { - const context = this.getContext(contextName); - const definitions = this.defaults[contextName]; - if (!context || !definitions) return; - context.extend(definitions); - return this.store(contextName, definitions); - } - - switchToContext(contextName) { - const currentContext = this.getCurrentContext(); - if (currentContext) { - currentContext.destroy(); - } - - const newContext = this.contexts[contextName]; - if (!newContext) return; - - this.currentContextName = contextName; - newContext.initialize(); - this.load(contextName).catch(() => {}); - } -} diff --git a/Packages/ohif-core/client/classes/ImageSet.js b/Packages/ohif-core/client/classes/ImageSet.js deleted file mode 100644 index e91494ad4..000000000 --- a/Packages/ohif-core/client/classes/ImageSet.js +++ /dev/null @@ -1,69 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { OHIFError } from './OHIFError'; - -const OBJECT = 'object'; - -/** - * This class defines an ImageSet object which will be used across the viewer. This object represents - * a list of images that are associated by any arbitrary criteria being thus content agnostic. Besides the - * main attributes (images and uid) it allows additional attributes to be appended to it (currently - * indiscriminately, but this should be changed). - */ -export class ImageSet { - - constructor(images) { - - if (Array.isArray(images) !== true) { - throw new OHIFError('ImageSet expects an array of images'); - } - - // @property "images" - Object.defineProperty(this, 'images', { - enumerable: false, - configurable: false, - writable: false, - value: images - }); - - // @property "uid" - Object.defineProperty(this, 'uid', { - enumerable: false, - configurable: false, - writable: false, - value: OHIF.utils.guid() // Unique ID of the instance - }); - - } - - getUID() { - return this.uid; - } - - setAttribute(attribute, value) { - this[attribute] = value; - } - - getAttribute(attribute) { - return this[attribute]; - } - - setAttributes(attributes) { - if (typeof attributes === OBJECT && attributes !== null) { - const imageSet = this, hasOwn = Object.prototype.hasOwnProperty; - for (let attribute in attributes) { - if (hasOwn.call(attributes, attribute)) { - imageSet[attribute] = attributes[attribute]; - } - } - } - } - - getImage(index) { - return this.images[index]; - } - - sortBy(sortingCallback) { - return this.images.sort(sortingCallback); - } - -} diff --git a/Packages/ohif-core/client/classes/MetadataProvider.js b/Packages/ohif-core/client/classes/MetadataProvider.js deleted file mode 100644 index ebdfa4d9f..000000000 --- a/Packages/ohif-core/client/classes/MetadataProvider.js +++ /dev/null @@ -1,354 +0,0 @@ -import { cornerstoneMath } from 'meteor/ohif:cornerstone'; -import { parsingUtils } from '../lib/parsingUtils'; - -const FUNCTION = 'function'; - -export class MetadataProvider { - - constructor() { - - // Define the main "metadataLookup" private property as an immutable property. - Object.defineProperty(this, 'metadataLookup', { - configurable: false, - enumerable: false, - writable: false, - value: new Map() - }); - - // Local reference to provider function bound to current instance. - Object.defineProperty(this, '_provider', { - configurable: false, - enumerable: false, - writable: true, - value: null - }); - - } - - /** - * Cornerstone Metadata provider to store image meta data - * Data from instances, series, and studies are associated with - * imageIds to facilitate usage of this information by Cornerstone's Tools - * - * e.g. the imagePlane metadata object contains instance information about - * row/column pixel spacing, patient position, and patient orientation. It - * is used in CornerstoneTools to position reference lines and orientation markers. - * - * @param {String} imageId The Cornerstone ImageId - * @param {Object} data An object containing instance, series, and study metadata - */ - addMetadata(imageId, data) { - const instanceMetadata = data.instance; - const seriesMetadata = data.series; - const studyMetadata = data.study; - const numImages = data.numImages; - const metadata = {}; - - metadata.frameNumber = data.frameNumber; - - metadata.study = { - accessionNumber: studyMetadata.accessionNumber, - patientId: studyMetadata.patientId, - studyInstanceUid: studyMetadata.studyInstanceUid, - studyDate: studyMetadata.studyDate, - studyTime: studyMetadata.studyTime, - studyDescription: studyMetadata.studyDescription, - institutionName: studyMetadata.institutionName, - patientHistory: studyMetadata.patientHistory - }; - - metadata.series = { - seriesDescription: seriesMetadata.seriesDescription, - seriesNumber: seriesMetadata.seriesNumber, - seriesDate: seriesMetadata.seriesDate, - seriesTime: seriesMetadata.seriesTime, - modality: seriesMetadata.modality, - seriesInstanceUid: seriesMetadata.seriesInstanceUid, - numImages: numImages - }; - - metadata.instance = instanceMetadata; - - metadata.patient = { - name: studyMetadata.patientName, - id: studyMetadata.patientId, - birthDate: studyMetadata.patientBirthDate, - sex: studyMetadata.patientSex, - age: studyMetadata.patientAge - }; - - // If there is sufficient information, populate - // the imagePlane object for easier use in the Viewer - metadata.imagePlane = this.getImagePlane(instanceMetadata); - - // Add the metadata to the imageId lookup object - this.metadataLookup.set(imageId, metadata); - } - - /** - * Return the metadata for the given imageId - * @param {String} imageId The Cornerstone ImageId - * @returns image metadata - */ - getMetadata(imageId) { - return this.metadataLookup.get(imageId); - } - - /** - * Adds a set of metadata to the Cornerstone metadata provider given a specific - * imageId, type, and dataset - * - * @param imageId - * @param type (e.g. series, instance, tagDisplay) - * @param data - */ - addSpecificMetadata(imageId, type, data) { - const metadata = {}; - metadata[type] = data; - - const oldMetadata = this.metadataLookup.get(imageId); - this.metadataLookup.set(imageId, Object.assign(oldMetadata, metadata)); - } - - getFromImage(image, type, tag, attrName, defaultValue) { - let value; - - if (image.data) { - value = this.getFromDataSet(image.data, type, tag); - } else { - value = image.instance[attrName]; - } - - return value === null ? defaultValue : value; - } - - getFromDataSet(dataSet, type, tag) { - if (!dataSet) { - return; - } - - const fn = dataSet[type]; - if (!fn) { - return; - } - - return fn.call(dataSet, tag); - } - - getFrameIncrementPointer(image) { - const dataSet = image.data; - let frameInstancePointer = ''; - - if (parsingUtils.isValidDataSet(dataSet)) { - const frameInstancePointerNames = { - x00181063: 'frameTime', - x00181065: 'frameTimeVector' - }; - - // (0028,0009) = Frame Increment Pointer - const frameInstancePointerTag = parsingUtils.attributeTag(dataSet, 'x00280009'); - frameInstancePointer = frameInstancePointerNames[frameInstancePointerTag]; - } else { - frameInstancePointer = image.instance.frameIncrementPointer; - } - - return frameInstancePointer || ''; - } - - getFrameTimeVector(image) { - const dataSet = image.data; - - if (parsingUtils.isValidDataSet(dataSet)) { - // Frame Increment Pointer points to Frame Time Vector (0018,1065) field - return parsingUtils.floatArray(dataSet, 'x00181065'); - } - - return image.instance.frameTimeVector; - } - - getFrameTime(image) { - const dataSet = image.data; - - if (parsingUtils.isValidDataSet(dataSet)) { - // Frame Increment Pointer points to Frame Time (0018,1063) field or is not defined (for addtional flexibility). - // Yet another value is possible for this field (5200,9230 for Multi-frame Functional Groups) - // but that case is currently not supported. - return dataSet.floatString('x00181063', -1); - } - - return image.instance.frameTime; - } - - /** - * Updates the related metadata for missing fields given a specified image - * - * @param image - */ - updateMetadata(image) { - const imageMetadata = this.metadataLookup.get(image.imageId); - if (!imageMetadata) { - return; - } - - imageMetadata.patient.age = imageMetadata.patient.age || this.getFromDataSet(image.data, 'string', 'x00101010'); - - imageMetadata.instance.rows = imageMetadata.instance.rows || image.rows; - imageMetadata.instance.columns = imageMetadata.instance.columns || image.columns; - - imageMetadata.instance.sopClassUid = imageMetadata.instance.sopClassUid || this.getFromDataSet(image.data, 'string', 'x00080016'); - imageMetadata.instance.sopInstanceUid = imageMetadata.instance.sopInstanceUid || this.getFromDataSet(image.data, 'string', 'x00080018'); - - imageMetadata.instance.pixelSpacing = imageMetadata.instance.pixelSpacing || this.getFromDataSet(image.data, 'string', 'x00280030'); - imageMetadata.instance.frameOfReferenceUID = imageMetadata.instance.frameOfReferenceUID || this.getFromDataSet(image.data, 'string', 'x00200052'); - imageMetadata.instance.imageOrientationPatient = imageMetadata.instance.imageOrientationPatient || this.getFromDataSet(image.data, 'string', 'x00200037'); - imageMetadata.instance.imagePositionPatient = imageMetadata.instance.imagePositionPatient || this.getFromDataSet(image.data, 'string', 'x00200032'); - - imageMetadata.instance.sliceThickness = imageMetadata.instance.sliceThickness || this.getFromDataSet(image.data, 'string', 'x00180050'); - imageMetadata.instance.sliceLocation = imageMetadata.instance.sliceLocation || this.getFromDataSet(image.data, 'string', 'x00201041'); - imageMetadata.instance.tablePosition = imageMetadata.instance.tablePosition || this.getFromDataSet(image.data, 'string', 'x00189327'); - imageMetadata.instance.spacingBetweenSlices = imageMetadata.instance.spacingBetweenSlices || this.getFromDataSet(image.data, 'string', 'x00180088'); - - imageMetadata.instance.lossyImageCompression = imageMetadata.instance.lossyImageCompression || this.getFromDataSet(image.data, 'string', 'x00282110'); - imageMetadata.instance.lossyImageCompressionRatio = imageMetadata.instance.lossyImageCompressionRatio || this.getFromDataSet(image.data, 'string', 'x00282112'); - - imageMetadata.instance.frameIncrementPointer = imageMetadata.instance.frameIncrementPointer || this.getFromDataSet(image.data, 'string', 'x00280009'); - imageMetadata.instance.frameTime = imageMetadata.instance.frameTime || this.getFromDataSet(image.data, 'string', 'x00181063'); - imageMetadata.instance.frameTimeVector = imageMetadata.instance.frameTimeVector || this.getFromDataSet(image.data, 'string', 'x00181065'); - - if ((image.data || image.instance) && !imageMetadata.instance.multiframeMetadata) { - imageMetadata.instance.multiframeMetadata = this.getMultiframeModuleMetadata(image); - } - - imageMetadata.imagePlane = imageMetadata.imagePlane || this.getImagePlane(imageMetadata.instance); - } - - /** - * Constructs and returns the imagePlane given the metadata instance - * - * @param metadataInstance The metadata instance (InstanceMetadata class) containing information to construct imagePlane - * @returns imagePlane The constructed imagePlane to be used in viewer easily - */ - getImagePlane(instance) { - if (!instance.rows || !instance.columns || !instance.pixelSpacing || - !instance.frameOfReferenceUID || !instance.imageOrientationPatient || - !instance.imagePositionPatient) { - return; - } - - const imageOrientation = instance.imageOrientationPatient.split('\\'); - const imagePosition = instance.imagePositionPatient.split('\\'); - - let columnPixelSpacing = 1.0; - let rowPixelSpacing = 1.0; - if (instance.pixelSpacing) { - const split = instance.pixelSpacing.split('\\'); - rowPixelSpacing = parseFloat(split[0]); - columnPixelSpacing = parseFloat(split[1]); - } - - return { - frameOfReferenceUID: instance.frameOfReferenceUID, - rows: instance.rows, - columns: instance.columns, - rowCosines: - new cornerstoneMath.Vector3(parseFloat(imageOrientation[0]), parseFloat(imageOrientation[1]), parseFloat(imageOrientation[2])), - columnCosines: - new cornerstoneMath.Vector3(parseFloat(imageOrientation[3]), parseFloat(imageOrientation[4]), parseFloat(imageOrientation[5])), - imagePositionPatient: - new cornerstoneMath.Vector3(parseFloat(imagePosition[0]), parseFloat(imagePosition[1]), parseFloat(imagePosition[2])), - rowPixelSpacing, - columnPixelSpacing, - }; - } - - /** - * This function extracts miltiframe information from a dicomParser.DataSet object. - * - * @param dataSet {Object} An instance of dicomParser.DataSet object where multiframe information can be found. - * @return {Object} An object containing multiframe image metadata (frameIncrementPointer, frameTime, frameTimeVector, etc). - */ - getMultiframeModuleMetadata(image) { - const imageInfo = { - isMultiframeImage: false, - frameIncrementPointer: null, - numberOfFrames: 0, - frameTime: 0, - frameTimeVector: null, - averageFrameRate: 0 // backwards compatibility only... it might be useless in the future - }; - - let frameTime; - - const numberOfFrames = this.getFromImage(image, 'intString', 'x00280008', 'numberOfFrames', -1); - - if (numberOfFrames > 0) { - // set multi-frame image indicator - imageInfo.isMultiframeImage = true; - imageInfo.numberOfFrames = numberOfFrames; - - // (0028,0009) = Frame Increment Pointer - const frameIncrementPointer = this.getFrameIncrementPointer(image); - - if (frameIncrementPointer === 'frameTimeVector') { - // Frame Increment Pointer points to Frame Time Vector (0018,1065) field - const frameTimeVector = this.getFrameTimeVector(image); - - if (frameTimeVector instanceof Array && frameTimeVector.length > 0) { - imageInfo.frameIncrementPointer = frameIncrementPointer; - imageInfo.frameTimeVector = frameTimeVector; - frameTime = frameTimeVector.reduce((a, b) => a + b) / frameTimeVector.length; - imageInfo.averageFrameRate = 1000 / frameTime; - } - } else if (frameIncrementPointer === 'frameTime' || frameIncrementPointer === '') { - frameTime = this.getFrameTime(image); - - if (frameTime > 0) { - imageInfo.frameIncrementPointer = frameIncrementPointer; - imageInfo.frameTime = frameTime; - imageInfo.averageFrameRate = 1000 / frameTime; - } - } - - } - - return imageInfo; - } - - /** - * Get a bound reference to the provider function. - */ - getProvider() { - let provider = this._provider; - if (typeof this._provider !== FUNCTION) { - provider = this.provider.bind(this); - this._provider = provider; - } - - return provider; - } - - /** - * Looks up metadata for Cornerstone Tools given a specified type and imageId - * A type may be, e.g. 'study', or 'patient', or 'imagePlane'. These types - * are keys in the stored metadata objects. - * - * @param type - * @param imageId - * @returns {Object} Relevant metadata of the specified type - */ - provider(type, imageId) { - // TODO: Cornerstone Tools use 'imagePlaneModule', but OHIF use 'imagePlane'. It must be consistent. - if (type === 'imagePlaneModule') { - type = 'imagePlane'; - } - - const imageMetadata = this.metadataLookup.get(imageId); - if (!imageMetadata) { - return; - } - - if (imageMetadata.hasOwnProperty(type)) { - return imageMetadata[type]; - } - } -} diff --git a/Packages/ohif-core/client/classes/OHIFError.js b/Packages/ohif-core/client/classes/OHIFError.js deleted file mode 100644 index 1e3f4ed43..000000000 --- a/Packages/ohif-core/client/classes/OHIFError.js +++ /dev/null @@ -1,14 +0,0 @@ -// @TODO: improve this object -/** - * Objects to be used to throw errors, specially - * in Trackers functions (afterFlush, Flush). - */ -export class OHIFError extends Error { - - constructor(message) { - super(); - this.message = message; - this.stack = (new Error()).stack; - this.name = this.constructor.name; - } -} \ No newline at end of file diff --git a/Packages/ohif-core/client/classes/OHIFStudyMetadataSource.js b/Packages/ohif-core/client/classes/OHIFStudyMetadataSource.js deleted file mode 100644 index 0767e5af5..000000000 --- a/Packages/ohif-core/client/classes/OHIFStudyMetadataSource.js +++ /dev/null @@ -1,74 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -// Important metadata classes -const { OHIFError, metadata } = OHIF.viewerbase; -const { StudySummary, StudyMetadata } = metadata; - -export class OHIFStudyMetadataSource extends OHIF.viewerbase.StudyMetadataSource { - - /** - * Get study metadata for a study with given study InstanceUID - * @param {String} studyInstanceUID Study InstanceUID - * @return {Promise} A Promise object - */ - getByInstanceUID(studyInstanceUID) { - return OHIF.studies.retrieveStudyMetadata(studyInstanceUID); - } - - /** - * Load study info (OHIF.viewer.Studies) and study metadata (OHIF.viewer.StudyMetadataList) for a given study. - * @param {StudySummary|StudyMetadata} study of StudySummary or StudyMetadata object. - */ - loadStudy(study) { - if (!(study instanceof StudyMetadata) && !(study instanceof StudySummary)) { - throw new OHIFError('OHIFStudyMetadataSource::loadStudy study is not an instance of StudySummary or StudyMetadata'); - } - - return new Promise((resolve, reject) => { - const studyInstanceUID = study.getStudyInstanceUID(); - - if (study instanceof StudyMetadata) { - const alreadyLoaded = OHIF.viewer.Studies.findBy({ - studyInstanceUid: studyInstanceUID - }); - - if (!alreadyLoaded) { - OHIFStudyMetadataSource._updateStudyCollections(study); - } - - resolve(study); - return; - } - - this.getByInstanceUID(studyInstanceUID).then(studyInfo => { - // Create study metadata object - const studyMetadata = new OHIF.metadata.StudyMetadata(studyInfo, studyInfo.studyInstanceUid); - - // Get Study display sets - const displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata); - - // Set studyMetadata display sets - studyMetadata.setDisplaySets(displaySets); - - OHIFStudyMetadataSource._updateStudyCollections(studyMetadata); - resolve(studyMetadata); - }).catch(reject); - }); - } - - // Static methods - static _updateStudyCollections(studyMetadata) { - const studyInfo = studyMetadata.getData(); - - // Set some studyInfo properties - studyInfo.selected = true; - studyInfo.displaySets = studyMetadata.getDisplaySets(); - - // Insert new study info object in Studies TypeSafeCollection - OHIF.viewer.Studies.insert(studyInfo); - - // Insert new study metadata in StudyMetadataList TypeSafeCollection - OHIF.viewer.StudyMetadataList.insert(studyMetadata); - } - -} diff --git a/Packages/ohif-core/client/classes/OHIFStudySummary.js b/Packages/ohif-core/client/classes/OHIFStudySummary.js deleted file mode 100644 index f54afc93a..000000000 --- a/Packages/ohif-core/client/classes/OHIFStudySummary.js +++ /dev/null @@ -1,52 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import 'meteor/ohif:viewerbase'; - -/** - * Constants - */ - -const STRING = 'string'; -const propertyReplacementMap = { - modalities: 'ModalitiesInStudy', - patientBirthdate: 'PatientBirthDate' -}; - -/** - * OHIF Viewers specialized version of StudySummary class - */ -export class OHIFStudySummary extends OHIF.viewerbase.metadata.StudySummary { - - // @Override - addTags(tagMap) { - const _hasOwn = Object.prototype.hasOwnProperty; - const _tagMap = Object.create(null); - for (let property in tagMap) { - if (_hasOwn.call(tagMap, property)) { - let standardProperty = OHIFStudySummary.getStandardPropertyName(property); - if (standardProperty) { - _tagMap[standardProperty] = tagMap[property]; - } - } - } - super.addTags(_tagMap); - } - - /** - * Turns a non-standard, OHIF specific, DICOM property name into a standard one. - * @param {string} property A string representing a non-conforming keyword. - * @returns {string|undefined} Returns a standard-conforming property name. - */ - static getStandardPropertyName(property) { - let standardProperty; - if (typeof property === STRING && property.charAt(0) !== '_') { - if (property in propertyReplacementMap) { - standardProperty = propertyReplacementMap[propertyReplacementMap]; - } else { - standardProperty = property.replace(/^sop/, 'SOP').replace(/Uid$/, 'UID').replace(/Id$/, 'ID'); - standardProperty = standardProperty.charAt(0).toUpperCase() + standardProperty.substr(1); - } - } - return standardProperty; - } - -} diff --git a/Packages/ohif-core/client/classes/README.md b/Packages/ohif-core/client/classes/README.md deleted file mode 100644 index 1367e14b7..000000000 --- a/Packages/ohif-core/client/classes/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# Table of contents -In this document, some important objects are described. In the files there are comments that can help better undestand their methods and properties. - - [ResizeViewportManager object](#the-resize-viewport-manager-object) - - [ImageSet object](#the-image-set-object) - - [Layout Manager](#the-layout-manager-object) - - [Type Safe Collections](#the-type-safe-collections) - -# The Resize Viewport Manager object -This object has multiple functions to manage window resize event. It relocates Dialogs, resizes viewport elements and scrollbars and some other UI components such as Study and Series Quick Switch, when available. - -## Usage -It's only necessary to bind **handleResize** function to the window resize event as follows. The **ohif:viewerbase** package needs to be imported by the referring code as well. -```javascript -import { Viewerbase } from 'meteor/ohif:viewerbase'; - -const ResizeViewportManager = new Viewerbase.ResizeViewportManager(); -window.addEventListener('resize', ResizeViewportManager.getResizeHandler()); -``` -An example os its usage can be found in **ohif-viewerbase/client/components/viewer/viewerMain/viewerMain.js**. - -# The Image Set object -An object that represents a list of images that are associated by any arbitrary criteria being thus content agnostic. Besides the main attributes (**images** and **uid**) it allows additional attributes to be appended to it (currently indiscriminately, but this should be changed). - -## Usage -ImageSet constructor requires an array of SOP instances like in the example below. It's necessary to import **ohif:viewerbase**. - -```javascript -import { Viewerbase } from 'meteor/ohif:viewerbase'; - -const imageSet = new Viewerbase.ImageSet(sopInstances); - -imageSet.setAttributes({ - displaySetInstanceUid: imageSet.uid, - seriesInstanceUid: seriesData.seriesInstanceUid, - seriesNumber: seriesData.seriesNumber, - seriesDescription: seriesData.seriesDescription, - numImageFrames: instances.length, - frameRate: instance.getRawValue('x00181063'), - modality: seriesData.modality, - isMultiFrame: isMultiFrame(instance) -}); - -// Sort instances by InstanceNumber (0020,0013) -imageSet.sortBy((a, b) => { - return (parseInt(a.getRawValue('x00200013', 0)) || 0) - (parseInt(b.getRawValue('x00200013', 0)) || 0); -}); -``` -Each SOP instance in this example is an instance of **OHIFInstanceMetadata** object, which is a specialization of **InstanceMetadata**. To read more about the **Metadata API** click [here](metadata/). - -# The Layout Manager object -Objects of this class are responsible for creating, organizing and maintaining (manage) viewport rendering. It creates a grid, positioning viewports accordingly to it's configuration keeping all viewports data (in **viewportData** property) for easy access from other components. It support many layout configurations and some of them were fully tested: 1x1, 1x2, 1x3, 2x1, 2x2, 2x3, 3x1, 3x2, 3x3. Other configurations may work as well. -Finally it provides some useful functions to move through viewports and zoom it. - -## Usage -In order to use _LayoutManager_ the **ohif:viewerbase** package needs to be imported by the referring code and instantiated as follows. An example os its usage is in **ohif-viewerbase/client/components/viewer/viewerMain/viewerMain.js**. - -```javascript -import { Viewerbase } from 'meteor/ohif:viewerbase'; - -// Get an array of studies object. This function needs to be implemented, it does not exist. -const studies = getArrayOfStudiesObjects(); -const parentElement = document.getElementById('layoutManagerTarget'); -const LayoutManager = new Viewerbase.LayoutManager(parentElement, studies); -``` - -The default configuration is 1x1, and to change it just set **layoutProps** and call **updateViewports** to update the layout as follows. - -```javascript -import { Viewerbase } from 'meteor/ohif:viewerbase'; - -// Get an array of studies object. This function needs to be implemented, it does not exist. -const studies = getArrayOfStudiesObjects(); -const parentElement = document.getElementById('layoutManagerTarget'); -const LayoutManager = new LayoutManager(parentElement, studies); - -// Set the layout proprerties to 2x2 layout -LayoutManager.layoutProps = { - rows: 2, - columns: 2 -}; - -// It will render four viewports: two in each row. -LayoutManager.updateViewports(); -``` - -The layoutManagerTarget element will have a new class **layout-2-2** (to allow further styling) and it's inner content will a new div#imageViewerViewports that has four inner elements like the following (some elements and attributes were removed for example purpose): -```html -
-
-
- -
-
-
-
-
-
-
-``` - -Each of this _div.viewportContainer_ will have some classes to help CSS specific styling accordingly to the element's position in the grid: **top**, **middle** and **bottom**. This classes are added by **viewer/components/gridLayout/** component in ohif-viewerbase package. - -# The Type Safe Collections - -With the introduction of the new _Study Metadata API_ in which study metadata is represented by class hierarchies (using prototype-based inheritance), the usage of standard _Minimongo_ collections as a central client-side storage for this data became no longer an option. Standard _Mongo_ and _Minimongo_ collections internally _flatten_ data (in other words, data gets serialized) before storage hence no functions or prototype chains are preserved. In that scenario, when an object is restored (fetched), what is returned is actually a flattened copy of the original object with no functions or prototype (it's no longer an instance of it's original class). As an attempt to overcome this limitation a new type of collection was intruduced: the *TypeSafeCollection*. - -The `TypeSafeCollection` is a simple list-like collection which tries to implement an API _similar_ but not compatible with _Mongo_'s API. It supports basic features like search by attribute map and ID, retrieval by index, sorting of result sets, insertion, removal and reactive operations but, unlike _Mongo_'s API, it (still) lacks support to advanced functionality like complex search criterea or flexible sorting options. - -## Implementation - -The `TypeSafeCollection` is implemented on top of the _JavaScript_ `Array` object. Each element inserted in the collection is appended to the end of its internal array as a _key-value pair (KVP)_ object where the _key_ is a unique randomly generated ID string and the _value_ is the element itself. Once the object has been successfully stored, the generated ID (its ID) is returned to the client code and can later be used to access that specific element. At this point, an important difference to the _Minimongo_ API can be highlighted: a _TypeSafeCollection_ instance will never make any changes to the stored element (e.g., no "\_id" property will ever be assigned to the original object). Another relevant feature that is supported by this design decision is that _not only objects_ can be stored in this collections, but literally _anything_. - -Inside the codebase, the _value_ attribute of each _KVP_ entry in the collection is refered to as _the **payload** of the entry_ since it's what really matters to the user. Hence, this term will also be used here to refer to the _value that has been stored in the collection_. That being said, we can approach another important feature of these collections: A single _payload_ cannot be stored more than once in a given collection. When an attempt of inserting a _payload_ which is already present in the collection is detected, the insert operation will fail and `null` will be returned. In that regard, the collection behaves like `Set` object not permitting a payload to be stored more than once. Strict equality is used when comparing payloads, thus cloned objects are not considered the same. This feature adds an additional garantee that a given study/series/instance will not be listed more than once (it was designed as a replacement for central study collections which were always checked for duplicates). - -Please refer to the codebase for the full `TypeSafeCollection` API. - -## Usage - -In order to use the `TypeSafeCollection` class, the **ohif:viewerbase** package needs to be imported by the referring code and instantiated as follows: - -```javascript -import { Viewerbase } from 'meteor/ohif:viewerbase'; // i.e., Viewerbase.TypeSafeCollection -OR -import { OHIF } from 'meteor/ohif:core'; -import 'meteor/ohif:viewerbase'; // i.e., OHIF.viewerbase.TypeSafeCollection -// The later is preferred when the client code already makes use of the "OHIF" namespace making the second -// "import" a garantee that the ".viewerbase" namespace has been properly loaded. -``` - -A few usage examples: - -```javascript - -const Users = new OHIF.viewerbase.TypeSafeCollection(); - -[[ ... ]] - -// Insert a User object... -let userId = Users.insert({ - data: { - firstName: 'John', - lastName: 'Doe', - age: 45 - }, - getFullName() { - return `${this.data.firstName} ${this.data.lastName}`; - }, - getAge() { - return this.data.age; - } -}); - -[[ ... ]] - -let theUserWeJustStored = Users.findById(userId); // ;-) - -[[ ... ]] - -// Retrieve a single user with "Doe" as `lastName`... -let myUser = Users.findBy({ 'data.lastName': 'Doe' }); -// Or all users with "Doe" as `lastName`, sorted by `firstName` in ascending -// order and using the `age` attribute to break ties in descending order... -let myUsers = Users.findAllBy({ 'data.lastName': 'Doe' }, { - sort: [ [ 'data.firstName', 'asc' ], [ 'data.age', 'desc' ] ] -}); - -``` diff --git a/Packages/ohif-core/client/classes/ResizeViewportManager.js b/Packages/ohif-core/client/classes/ResizeViewportManager.js deleted file mode 100644 index a0e93c415..000000000 --- a/Packages/ohif-core/client/classes/ResizeViewportManager.js +++ /dev/null @@ -1,151 +0,0 @@ -import { Session } from 'meteor/session'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; -//import { getInstanceClassDefaultViewport } from '../instanceClassSpecificViewport'; - -// Manage resizing viewports triggered by window resize -export class ResizeViewportManager { - constructor() { - this._resizeHandler = null; - } - - // Reposition Study Series Quick Switch based whether side bars are opened or not - repositionStudySeriesQuickSwitch() { - OHIF.log.info('ResizeViewportManager repositionStudySeriesQuickSwitch'); - - // Stop here if viewer is not displayed - const isViewer = Session.get('ViewerOpened'); - if (!isViewer) return; - - // Stop here if there is no one or only one viewport - const nViewports = OHIF.viewerbase.layoutManager.viewportData.length; - if (!nViewports || nViewports <= 1) return; - - const $viewer = $('#viewer'); - const leftSidebar = $viewer.find('.sidebar-left.sidebar-open'); - const rightSidebar = $viewer.find('.sidebar-right.sidebar-open'); - - const $leftQuickSwitch = $('.quickSwitchWrapper.left'); - const $rightQuickSwitch = $('.quickSwitchWrapper.right'); - - const hasLeftSidebar = leftSidebar.length > 0; - const hasRightSidebar = rightSidebar.length > 0; - - $rightQuickSwitch.removeClass('left-sidebar-only'); - $leftQuickSwitch.removeClass('right-sidebar-only'); - - let leftOffset = 0; - - if (hasLeftSidebar) { - leftOffset = (leftSidebar.width() / $(window).width()) * 100; - - if (!hasRightSidebar) { - $rightQuickSwitch.addClass('left-sidebar-only'); - } - } - - if (hasRightSidebar && !hasLeftSidebar) { - $leftQuickSwitch.addClass('right-sidebar-only'); - } - - const leftPosition = (($('#imageViewerViewports').width() / nViewports) / $(window).width()) * 100 + leftOffset; - const rightPosition = 100 - leftPosition; - - $leftQuickSwitch.css('right', rightPosition + '%'); - $rightQuickSwitch.css('left', leftPosition + '%'); - } - - // Relocate dialogs positions - relocateDialogs(){ - OHIF.log.info('ResizeViewportManager relocateDialogs'); - - const $bottomRightDialogs = $('#annotationDialog, #textMarkerOptionsDialog'); - $bottomRightDialogs.css({ - top: '', // This removes the CSS property completely - left: '', - bottom: 0, - right: 0 - }); - - const centerDialogs = $('.draggableDialog').not($bottomRightDialogs); - - centerDialogs.css({ - top: 0, - left: 0, - bottom: 0, - right: 0 - }); - } - - // Resize viewport scrollbars - resizeScrollbars(element) { - OHIF.log.info('ResizeViewportManager resizeScrollbars'); - - const $currentOverlay = $(element).siblings('.imageViewerViewportOverlay'); - $currentOverlay.find('.scrollbar').trigger('rescale'); - } - - // Resize a single viewport element - resizeViewportElement(element, fitToWindow = true) { - let enabledElement; - try { - enabledElement = cornerstone.getEnabledElement(element); - } catch(error) { - return; - } - - cornerstone.resize(element, fitToWindow); - - /*if (enabledElement.fitToWindow === false) { - const imageId = enabledElement.image.imageId; - const instance = cornerstone.metaData.get('instance', imageId); - const instanceClassViewport = getInstanceClassDefaultViewport(instance, enabledElement, imageId); - cornerstone.setViewport(element, instanceClassViewport); - }*/ - } - - // Resize each viewport element - resizeViewportElements() { - this.relocateDialogs(); - - setTimeout(() => { - this.repositionStudySeriesQuickSwitch(); - - const elements = $('.imageViewerViewport').not('.empty'); - elements.each((index, element) => { - this.resizeViewportElement(element); - this.resizeScrollbars(element); - }); - }, 1); - } - - // Function to override resizeViewportElements function - setResizeViewportElement(resizeViewportElements) { - this.resizeViewportElements = resizeViewportElements; - } - - // Avoid doing DOM manipulation during the resize handler - // because it is fired very often. - // Resizing is therefore performed 100 ms after the resize event stops. - handleResize() { - clearTimeout(this.resizeTimer); - this.resizeTimer = setTimeout(() => { - OHIF.log.info('ResizeViewportManager resizeViewportElements'); - this.resizeViewportElements(); - }, 100); - } - - /** - * Returns a unique event handler function associated with a given instance using lazy assignment. - * @return {function} Returns a unique copy of the event handler of this class. - */ - getResizeHandler() { - let resizeHandler = this._resizeHandler; - if (resizeHandler === null) { - resizeHandler = this.handleResize.bind(this); - this._resizeHandler = resizeHandler; - } - - return resizeHandler; - } -} diff --git a/Packages/ohif-core/client/classes/StackImagePositionOffsetSynchronizer.js b/Packages/ohif-core/client/classes/StackImagePositionOffsetSynchronizer.js deleted file mode 100644 index 0251227ee..000000000 --- a/Packages/ohif-core/client/classes/StackImagePositionOffsetSynchronizer.js +++ /dev/null @@ -1,218 +0,0 @@ -import { Session } from 'meteor/session'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; -import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; -import { toolManager } from '../toolManager'; - -export class StackImagePositionOffsetSynchronizer { - constructor() { - this.active = false; - this.syncedViewports = []; - this.synchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.stackImagePositionOffsetSynchronizer); - } - - static get ELEMENT_DISABLED_EVENT() { - return 'cornerstoneelementdisabled.StackImagePositionOffsetSynchronizer'; - } - - isActive() { - return this.active; - } - - activate() { - const viewports = this.getLinkableViewports(); - this.syncViewports(viewports); - } - - activateByViewportIndexes(viewportIndexes) { - const viewports = this.getViewportByIndexes(viewportIndexes); - this.syncViewports(viewports); - } - - deactivate() { - if (!this.isActive()) { - return; - } - - while (this.syncedViewports.length) { - const viewport = this.syncedViewports[0]; - this.removeViewport(viewport); - } - - this.active = false; - toolManager.deactivateCommandButton('linkStackScroll'); - } - - update() { - if (!this.isActive()) { - return; - } - - const activeViewportElement = this.getActiveViewportElement(); - - if (this.isViewportSynced(activeViewportElement)) { - return; - } - - this.deactivate(); - this.activate(); - } - - syncViewports(viewports) { - const viewportIndexes = []; - - if (this.isActive() || (viewports.length <= 1)) { - return; - } - - viewports.forEach((viewport, index) => { - this.synchronizer.add(viewport.element); - this.syncedViewports.push(viewport); - viewportIndexes.push(viewport.index); - if (!this.disabledListener) { - this.disabledListener = this.elementDisabledHandler(this); - } - - viewport.element.addEventListener(StackImagePositionOffsetSynchronizer.ELEMENT_DISABLED_EVENT, this.disabledListener); - }); - - this.active = true; - toolManager.activateCommandButton('linkStackScroll'); - Session.set('StackImagePositionOffsetSynchronizerLinkedViewports', viewportIndexes); - } - - isViewportSynced(viewportElement) { - return !!this.getViewportByElement(viewportElement); - } - - getActiveViewportElement() { - const viewportIndex = window.store.getState().viewports.activeViewport || 0; - return $('.imageViewerViewport').get(viewportIndex); - } - - removeViewport(viewport) { - const index = this.syncedViewports.indexOf(viewport); - - if (index === -1) { - return; - } - - this.syncedViewports.splice(index, 1); - this.synchronizer.remove(viewport.element); - this.removeLinkedViewportFromSession(viewport); - viewport.element.removeEventListener(StackImagePositionOffsetSynchronizer.ELEMENT_DISABLED_EVENT, this.disabledListener); - } - - getViewportByElement(viewportElement) { - const length = this.syncedViewports.length; - - for (let i = 0; i < length; i++) { - const viewport = this.syncedViewports[i]; - - if (viewport.element === viewportElement) { - return viewport; - } - } - } - - removeViewportByElement(viewportElement) { - let viewport = this.getViewportByElement(viewportElement); - - if (viewport) { - this.removeViewport(viewport); - } - } - - removeLinkedViewportFromSession(viewport) { - const linkedViewports = Session.get('StackImagePositionOffsetSynchronizerLinkedViewports'); - const index = linkedViewports.indexOf(viewport.index); - - if (index !== -1) { - linkedViewports.splice(index, 1); - Session.set('StackImagePositionOffsetSynchronizerLinkedViewports', linkedViewports); - } - } - - elementDisabledHandler(context) { - return e => context.removeViewportByElement(e.detail.element); - } - - getViewportByIndexes(viewportIndexes) { - const viewports = []; - const $viewportElements = $('.imageViewerViewport'); - - viewportIndexes.forEach(index => { - const element = $viewportElements.get(index); - - if (!element) { - return; - } - - viewports.push({ - index, - element - }); - }); - - return viewports; - } - - isViewportsLinkable(viewportElementA, viewportElementB) { - const viewportAImageNormal = this.getViewportImageNormal(viewportElementA); - const viewportBImageNormal = this.getViewportImageNormal(viewportElementB); - - if (viewportAImageNormal && viewportBImageNormal) { - const angleInRadians = viewportBImageNormal.angleTo(viewportAImageNormal); - - // Pi / 12 radians = 15 degrees - // If the angle between two vectors is Pi, it means they are just inverted - return angleInRadians < Math.PI / 12 || angleInRadians === Math.PI; - } - - return false; - } - - getLinkableViewports() { - const activeViewportElement = this.getActiveViewportElement(); - const viewports = []; - - $('.imageViewerViewport').each((index, viewportElement) => { - if (this.isViewportsLinkable(activeViewportElement, viewportElement)) { - viewports.push({ - index: index, - element: viewportElement - }); - } - }); - - return viewports; - } - - getViewportImageNormal(element) { - if (!element) { - return; - } - - element = $(element).get(0); - - try { - const enabledElement = cornerstone.getEnabledElement(element); - - if (!enabledElement.image) { - return; - } - - const imageId = enabledElement.image.imageId; - const imagePlane = cornerstone.metaData.get('imagePlane', imageId); - - if (!imagePlane || !imagePlane.rowCosines || !imagePlane.columnCosines) { - return; - } - - return imagePlane.rowCosines.clone().cross(imagePlane.columnCosines); - } catch(error) { - const errorMessage = error.message || error; - OHIF.log.info(`StackImagePositionOffsetSynchronizer getViewportImageNormal: ${errorMessage}`); - } - } -} diff --git a/Packages/ohif-core/client/classes/StudyLoadingListener.js b/Packages/ohif-core/client/classes/StudyLoadingListener.js deleted file mode 100644 index 350772cf4..000000000 --- a/Packages/ohif-core/client/classes/StudyLoadingListener.js +++ /dev/null @@ -1,398 +0,0 @@ -import $ from 'jquery'; -import { Session } from 'meteor/session'; -import { OHIF } from 'meteor/ohif:core'; -import { cornerstone, cornerstoneWADOImageLoader } from 'meteor/ohif:cornerstone'; - -class BaseLoadingListener { - constructor(stack, options) { - options = options || {}; - - this.id = BaseLoadingListener.getNewId(); - this.stack = stack; - this.startListening(); - this.statsItemsLimit = options.statsItemsLimit || 2; - this.stats = { - items: [], - total: 0, - elapsedTime: 0, - speed: 0 - }; - - // Register the start point to make it possible to calculate - // bytes/s or frames/s when the first byte or frame is received - this._addStatsData(0); - - // Update the progress before starting the download - // to make it possible to update the UI - this._updateProgress(); - } - - _addStatsData(value) { - const date = new Date(); - const stats = this.stats; - const items = stats.items; - const newItem = { - value, - date - }; - - items.push(newItem); - stats.total += newItem.value; - - // Remove items until it gets below the limit - while (items.length > this.statsItemsLimit) { - const item = items.shift(); - stats.total -= item.value; - } - - // Update the elapsedTime (seconds) based on first and last - // elements and recalculate the speed (bytes/s or frames/s) - if (items.length > 1) { - const oldestItem = items[0]; - stats.elapsedTime = (newItem.date.getTime() - oldestItem.date.getTime()) / 1000; - stats.speed = (stats.total - oldestItem.value) / stats.elapsedTime; - } - } - - _getProgressSessionId() { - const displaySetInstanceUid = this.stack.displaySetInstanceUid; - return 'StackProgress:' + displaySetInstanceUid; - } - - _clearSession() { - const progressSessionId = this._getProgressSessionId(); - Session.set(progressSessionId, undefined); - delete Session.keys.progressSessionId; - } - - startListening() { - throw new Error('`startListening` must be implemented by child clases'); - } - - stopListening() { - throw new Error('`stopListening` must be implemented by child clases'); - } - - destroy() { - this.stopListening(); - this._clearSession(); - } - - static getNewId() { - const timeSlice = (new Date()).getTime().toString().slice(-8); - const randomNumber = parseInt(Math.random() * 1000000000); - - return timeSlice.toString() + randomNumber.toString(); - } -} - -class DICOMFileLoadingListener extends BaseLoadingListener { - constructor(stack) { - super(stack); - this._dataSetUrl = this._getDataSetUrl(stack); - this._lastLoaded = 0; - - // Check how many instances has already been download (cached) - this._checkCachedData(); - } - - _checkCachedData() { - const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(this._dataSetUrl); - - if (dataSet) { - const dataSetLength = dataSet.byteArray.length; - - this._updateProgress({ - percentComplete: 100, - loaded: dataSetLength, - total: dataSetLength - }); - } - } - - _getImageLoadProgressEventName() { - return 'cornerstoneimageloadprogress.' + this.id; - } - - startListening() { - const imageLoadProgressEventName = this._getImageLoadProgressEventName(); - const imageLoadProgressEventHandle = this._imageLoadProgressEventHandle.bind(this); - - this.stopListening(); - - cornerstone.events.addEventListener(imageLoadProgressEventName, imageLoadProgressEventHandle); - } - - stopListening() { - const imageLoadProgressEventName = this._getImageLoadProgressEventName(); - cornerstone.events.removeEventListener(imageLoadProgressEventName); - } - - _imageLoadProgressEventHandle(e) { - const eventData = e.detail; - const dataSetUrl = this._convertImageIdToDataSetUrl(eventData.imageId); - const bytesDiff = eventData.loaded - this._lastLoaded; - - if (!this._dataSetUrl === dataSetUrl) { - return; - } - - // Add the bytes downloaded to the stats - this._addStatsData(bytesDiff); - - // Update the download progress - this._updateProgress(eventData); - - // Cache the last eventData.loaded value - this._lastLoaded = eventData.loaded; - } - - _updateProgress(eventData) { - const progressSessionId = this._getProgressSessionId(); - eventData = eventData || {}; - - Session.set(progressSessionId, { - multiFrame: false, - percentComplete: eventData.percentComplete, - bytesLoaded: eventData.loaded, - bytesTotal: eventData.total, - bytesPerSecond: this.stats.speed - }); - } - - _convertImageIdToDataSetUrl(imageId) { - // Remove the prefix ("dicomweb:" or "wadouri:"") - imageId = imageId.replace(/^(dicomweb:|wadouri:)/i, ''); - - // Remove "frame=999&" from the imageId - imageId = imageId.replace(/frame=\d+&?/i, ''); - - // Remove the last "&" like in "http://...?foo=1&bar=2&" - imageId = imageId.replace(/&$/, ''); - - return imageId; - } - - _getDataSetUrl(stack) { - const imageId = stack.imageIds[0]; - return this._convertImageIdToDataSetUrl(imageId); - } -} - -class StackLoadingListener extends BaseLoadingListener { - constructor(stack) { - super(stack, { statsItemsLimit: 20 }); - this.imageDataMap = this._convertImageIdsArrayToMap(stack.imageIds); - this.framesStatus = this._createArray(stack.imageIds.length, false); - this.loadedCount = 0; - - // Check how many instances has already been download (cached) - this._checkCachedData(); - } - - _convertImageIdsArrayToMap(imageIds) { - const imageIdsMap = new Map(); - - for (let i = 0; i < imageIds.length; i++) { - imageIdsMap.set(imageIds[i], { - index: i, - loaded: false - }); - } - - return imageIdsMap; - } - - _createArray(length, defaultValue) { - // `new Array(length)` is an anti-pattern in javascript because its - // funny API. Otherwise I would go for `new Array(length).fill(false)` - const array = []; - - for (let i = 0; i < length; i++) { - array[i] = defaultValue; - } - - return array; - } - - _checkCachedData() { - // const imageIds = this.stack.imageIds; - - // TODO: No way to check status of Promise. - /*for(let i = 0; i < imageIds.length; i++) { - const imageId = imageIds[i]; - - const imagePromise = cornerstone.imageCache.getImageLoadObject(imageId).promise; - - if (imagePromise && (imagePromise.state() === 'resolved')) { - this._updateFrameStatus(imageId, true); - } - }*/ - } - - _getImageLoadedEventName() { - return 'cornerstoneimageloaded.' + this.id; - } - - _getImageCachePromiseRemoveEventName() { - return 'cornerstoneimagecachepromiseremoved.' + this.id; - } - - startListening() { - const imageLoadedEventName = this._getImageLoadedEventName(); - const imageCachePromiseRemovedEventName = this._getImageCachePromiseRemoveEventName(); - const imageLoadedEventHandle = this._imageLoadedEventHandle.bind(this); - const imageCachePromiseRemovedEventHandle = this._imageCachePromiseRemovedEventHandle.bind(this); - - this.stopListening(); - - cornerstone.events.addEventListener(imageLoadedEventName, imageLoadedEventHandle); - cornerstone.events.addEventListener(imageCachePromiseRemovedEventName, imageCachePromiseRemovedEventHandle); - } - - stopListening() { - const imageLoadedEventName = this._getImageLoadedEventName(); - const imageCachePromiseRemovedEventName = this._getImageCachePromiseRemoveEventName(); - - cornerstone.events.removeEventListener(imageLoadedEventName); - cornerstone.events.removeEventListener(imageCachePromiseRemovedEventName); - } - - _updateFrameStatus(imageId, loaded) { - const imageData = this.imageDataMap.get(imageId); - - if (!imageData || (imageData.loaded === loaded)) { - return; - } - - // Add one more frame to the stats - if (loaded) { - this._addStatsData(1); - } - - imageData.loaded = loaded; - this.framesStatus[imageData.index] = loaded; - this.loadedCount += loaded ? 1 : -1; - this._updateProgress(); - } - - _imageLoadedEventHandle(e) { - this._updateFrameStatus(e.detail.image.imageId, true); - } - - _imageCachePromiseRemovedEventHandle(e) { - this._updateFrameStatus(e.detail.imageId, false); - } - - _updateProgress() { - const totalFramesCount = this.stack.imageIds.length; - const loadedFramesCount = this.loadedCount; - const loadingFramesCount = totalFramesCount - loadedFramesCount; - const percentComplete = Math.round(loadedFramesCount / totalFramesCount * 100); - const progressSessionId = this._getProgressSessionId(); - - Session.set(progressSessionId, { - multiFrame: true, - totalFramesCount, - loadedFramesCount, - loadingFramesCount, - percentComplete, - framesPerSecond: this.stats.speed, - framesStatus: this.framesStatus - }); - } - - _logProgress() { - const totalFramesCount = this.stack.imageIds.length; - const displaySetInstanceUid = this.stack.displaySetInstanceUid; - let progressBar = '['; - - for (let i = 0; i < totalFramesCount; i++) { - const ch = this.framesStatus[i] ? '|' : '.'; - progressBar += `${ch}`; - } - - progressBar += ']'; - OHIF.log.info(`${displaySetInstanceUid}: ${progressBar}`); - } -} - -class StudyLoadingListener { - constructor() { - this.listeners = {}; - } - - addStack(stack, stackMetaData) { - const displaySetInstanceUid = stack.displaySetInstanceUid; - - if (!this.listeners[displaySetInstanceUid]) { - const listener = this._createListener(stack, stackMetaData); - if (listener) { - this.listeners[displaySetInstanceUid] = listener; - } - } - } - - addStudy(study) { - study.displaySets.forEach(displaySet => { - const stack = OHIF.viewerbase.stackManager.findOrCreateStack(study, displaySet); - this.addStack(stack, { - isMultiFrame: displaySet.isMultiFrame - }); - }); - } - - addStudies(studies) { - if (!studies || !studies.length) { - return; - } - - studies.forEach(study => this.addStudy(study)); - } - - clear() { - const displaySetInstanceUids = Object.keys(this.listeners); - const length = displaySetInstanceUids.length; - - for (let i = 0; i < length; i++) { - const displaySetInstanceUid = displaySetInstanceUids[i]; - const displaySet = this.listeners[displaySetInstanceUid]; - - displaySet.destroy(); - } - - this.listeners = {}; - } - - _createListener(stack, stackMetaData) { - const schema = this._getSchema(stack); - - // A StackLoadingListener can be created if it's wadors or not a multiframe - // wadouri instance (single file) that means "N" files will have to be - // downloaded where "N" is the number of frames. DICOMFileLoadingListener - // is created only if it's a single DICOM file and there's no way to know - // how many frames has already been loaded (bytes/s instead of frames/s). - if ((schema === 'wadors') || !stackMetaData.isMultiFrame) { - return new StackLoadingListener(stack); - } else { - return new DICOMFileLoadingListener(stack); - } - } - - _getSchema(stack) { - const imageId = stack.imageIds[0]; - const colonIndex = imageId.indexOf(':'); - return imageId.substring(0, colonIndex); - } - - // Singleton - static getInstance() { - if (!StudyLoadingListener._instance) { - StudyLoadingListener._instance = new StudyLoadingListener(); - } - - return StudyLoadingListener._instance; - } -} - -export { StudyLoadingListener, StackLoadingListener, DICOMFileLoadingListener }; diff --git a/Packages/ohif-core/client/classes/StudyMetadataSource.js b/Packages/ohif-core/client/classes/StudyMetadataSource.js deleted file mode 100644 index c8a09eec1..000000000 --- a/Packages/ohif-core/client/classes/StudyMetadataSource.js +++ /dev/null @@ -1,30 +0,0 @@ -import { OHIFError } from './OHIFError'; - -/** - * Abstract class to fetch study metadata. - */ -export class StudyMetadataSource { - - /** - * Get study metadata for a study with given study InstanceUID. - * @param {String} studyInstanceUID Study InstanceUID. - */ - getByInstanceUID(studyInstanceUID) { - /** - * Please override this method on a specialized class. - */ - throw new OHIFError('StudyMetadataSource::getByInstanceUID is not overriden. Please, override it in a specialized class. See OHIFStudyMetadataSource for example'); - } - - /** - * Load study info and study metadata for a given study into the viewer. - * @param {StudySummary|StudyMetadata} study of StudySummary or StudyMetadata object. - */ - loadStudy(study) { - /** - * Please override this method on a specialized class. - */ - throw new OHIFError('StudyMetadataSource::loadStudy is not overriden. Please, override it in a specialized class. See OHIFStudyMetadataSource for example'); - } - -} diff --git a/Packages/ohif-core/client/classes/StudyPrefetcher.js b/Packages/ohif-core/client/classes/StudyPrefetcher.js deleted file mode 100644 index e0095743a..000000000 --- a/Packages/ohif-core/client/classes/StudyPrefetcher.js +++ /dev/null @@ -1,331 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Session } from 'meteor/session'; -import $ from 'jquery'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; -import { OHIFError } from './OHIFError'; -//import { getImageId } from '../getImageId.js'; - -export class StudyPrefetcher { - - constructor(studies) { - this.studies = studies || []; - this.prefetchDisplaySetsTimeout = 300; - this.lastActiveViewportElement = null; - this.cacheFullHandlerBound = _.bind(this.cacheFullHandler, this); - - cornerstone.events.addEventListener('cornerstoneimagecachefull.StudyPrefetcher', this.cacheFullHandlerBound); - } - - destroy() { - this.stopPrefetching(); - cornerstone.events.removeEventListener('cornerstoneimagecachefull.StudyPrefetcher', this.cacheFullHandlerBound); - } - - static getInstance() { - if (!StudyPrefetcher.instance) { - StudyPrefetcher.instance = new StudyPrefetcher(); - } - - return StudyPrefetcher.instance; - } - - setStudies(studies) { - this.stopPrefetching(); - this.studies = studies; - } - - prefetch() { - if (!this.studies || !this.studies.length) { - return; - } - - this.stopPrefetching(); - this.prefetchActiveViewport(); - this.prefetchDisplaySets(); - } - - stopPrefetching() { - this.disableViewportPrefetch(); - cornerstoneTools.requestPoolManager.clearRequestStack('prefetch'); - } - - prefetchActiveViewport() { - const activeViewportElement = OHIF.viewerbase.viewportUtils.getActiveViewportElement(); - this.enablePrefetchOnElement(activeViewportElement); - this.attachActiveViewportListeners(activeViewportElement); - } - - disableViewportPrefetch() { - $('.imageViewerViewport').each(function() { - if (!$(this).find('canvas').length) { - return; - } - - cornerstoneTools.stackPrefetch.disable(this); - }); - } - - hasStack(element) { - const stack = cornerstoneTools.getToolState(element, 'stack'); - return stack && stack.data.length && (stack.data[0].imageIds.length > 1); - } - - /** - * This function enables stack prefetching for a specified element (viewport) - * It first disables any prefetching currently occurring on any other viewports. - * - * @param element {node} DOM Node representing the viewport element - */ - enablePrefetchOnElement(element) { - if (!$(element).find('canvas').length) { - return; - } - - // Make sure there is a stack to fetch - if (this.hasStack(element)) { - // Check if this is a clip or not - const activeViewportIndex = window.store.getState().viewports.activeViewport; - const displaySetInstanceUid = OHIF.viewer.data.loadedSeriesData[activeViewportIndex].displaySetInstanceUid; - - const { StackManager } = OHIF.viewerbase; - - const stack = StackManager.findStack(displaySetInstanceUid); - - if (!stack) { - throw new OHIFError(`Requested stack ${displaySetInstanceUid} was not created`); - } - - cornerstoneTools.stackPrefetch.enable(element); - } - } - - attachActiveViewportListeners(activeViewportElement) { - function newImageHandler() { - // It needs to be called asynchronously because cornerstone does it at the same way. - // All instance urls to be prefetched will be removed again if we add them before - // Cornerstone callback (see stackPrefetch.onImageUpdated). - StudyPrefetcher.prefetchDisplaySetsAsync(); - } - - if (this.lastActiveViewportElement) { - this.lastActiveViewportElement.removeEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler); - } - - activeViewportElement.removeEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler); - - // Cornerstone will not attach an event listener if the element doesn't have a stack - if (this.hasStack(activeViewportElement)) { - activeViewportElement.addEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler); - } - - this.lastActiveViewportElement = activeViewportElement; - } - - prefetchDisplaySetsAsync(timeout) { - timeout = timeout || this.prefetchDisplaySetsTimeout; - - clearTimeout(this.prefetchDisplaySetsHandler); - this.prefetchDisplaySetsHandler = setTimeout(() => { - this.prefetchDisplaySets(); - }, timeout); - } - - prefetchDisplaySets() { - let config; - if (Meteor.settings && - Meteor.settings.public && - Meteor.settings.prefetch) { - config = Meteor.settings.public.prefetch; - } else { - config = { - order: 'closest', - displaySetCount: 1 - }; - } - - const displaySetsToPrefetch = this.getDisplaySetsToPrefetch(config); - const imageIds = this.getImageIdsFromDisplaySets(displaySetsToPrefetch); - - this.prefetchImageIds(imageIds); - } - - prefetchImageIds(imageIds) { - const nonCachedImageIds = this.filterCachedImageIds(imageIds); - const requestPoolManager = cornerstoneTools.requestPoolManager; - const requestType = 'prefetch'; - const preventCache = false; - const noop = () => {}; - - nonCachedImageIds.forEach(imageId => { - requestPoolManager.addRequest({}, imageId, requestType, preventCache, noop, noop); - }); - - requestPoolManager.startGrabbing(); - } - - getActiveViewportImage() { - const element = OHIF.viewerbase.viewportUtils.getActiveViewportElement(); - - if (!element) { - return; - } - - const enabledElement = cornerstone.getEnabledElement(element); - const image = enabledElement.image; - - return image; - } - - getStudy(image) { - const studyMetadata = cornerstone.metaData.get('study', image.imageId); - return OHIF.viewer.Studies.find(study => study.studyInstanceUid === studyMetadata.studyInstanceUid); - } - - getSeries(study, image) { - const seriesMetadata = cornerstone.metaData.get('series', image.imageId); - const studyMetadata = OHIF.viewerbase.getStudyMetadata(study); - - return studyMetadata.getSeriesByUID(seriesMetadata.seriesInstanceUid); - } - - getInstance(series, image) { - const instanceMetadata = cornerstone.metaData.get('instance', image.imageId); - return series.getInstanceByUID(instanceMetadata.sopInstanceUid); - } - - getActiveDisplaySet(displaySets, instance) { - return _.find(displaySets, displaySet => { - return _.some(displaySet.images, displaySetImage => { - return displaySetImage.sopInstanceUid === instance.sopInstanceUid; - }); - }); - } - - getDisplaySetsToPrefetch(config) { - const image = this.getActiveViewportImage(); - - if (!image || !config || !config.displaySetCount) { - return []; - } - - const study = this.getStudy(image); - const series = this.getSeries(study, image); - const instance = this.getInstance(series, image); - const displaySets = study.displaySets; - const activeDisplaySet = this.getActiveDisplaySet(displaySets, instance); - const prefetchMethodMap = { - topdown: 'getFirstDisplaySets', - downward: 'getNextDisplaySets', - closest: 'getClosestDisplaySets' - }; - - const prefetchOrder = config.order; - const methodName = prefetchMethodMap[prefetchOrder]; - const getDisplaySets = this[methodName]; - - if (!getDisplaySets) { - if (prefetchOrder) { - OHIF.log.warn(`Invalid prefetch order configuration (${prefetchOrder})`); - } - - return []; - } - - return getDisplaySets.call(this, displaySets, activeDisplaySet, config.displaySetCount); - } - - getFirstDisplaySets(displaySets, activeDisplaySet, displaySetCount) { - const length = displaySets.length; - const selectedDisplaySets = []; - - for (let i = 0; (i < length) && displaySetCount; i++) { - const displaySet = displaySets[i]; - - if (displaySet !== activeDisplaySet) { - selectedDisplaySets.push(displaySet); - displaySetCount--; - } - } - - return selectedDisplaySets; - } - - getNextDisplaySets(displaySets, activeDisplaySet, displaySetCount) { - const activeDisplaySetIndex = displaySets.indexOf(activeDisplaySet); - const begin = activeDisplaySetIndex + 1; - const end = Math.min(begin + displaySetCount, displaySets.length); - - return displaySets.slice(begin, end); - } - - getClosestDisplaySets(displaySets, activeDisplaySet, displaySetCount) { - const activeDisplaySetIndex = displaySets.indexOf(activeDisplaySet); - const length = displaySets.length; - const selectedDisplaySets = []; - let left = activeDisplaySetIndex - 1; - let right = activeDisplaySetIndex + 1; - - while (((left >= 0) || (right < length)) && displaySetCount) { - if (left >= 0) { - selectedDisplaySets.push(displaySets[left]); - displaySetCount--; - left--; - } - - if ((right < length) && displaySetCount) { - selectedDisplaySets.push(displaySets[right]); - displaySetCount--; - right++; - } - } - - return selectedDisplaySets; - } - - getImageIdsFromDisplaySets(displaySets) { - let imageIds = []; - - displaySets.forEach(displaySet => { - imageIds = imageIds.concat(this.getImageIdsFromDisplaySet(displaySet)); - }); - - return imageIds; - } - - getImageIdsFromDisplaySet(displaySet) { - const imageIds = []; - - /*displaySet.images.forEach(image => { - const numFrames = image.numFrames; - if (numFrames > 1) { - for (let i = 0; i < numFrames; i++) { - let imageId = getImageId(image, i); - imageIds.push(imageId); - } - } else { - let imageId = getImageId(image); - imageIds.push(imageId); - } - });*/ - - return [];//imageIds; - } - - filterCachedImageIds(imageIds) { - return _.filter(imageIds, imageId => { - return !this.isImageCached(imageId); - }); - } - - isImageCached(imageId) { - const image = cornerstone.imageCache.imageCache[imageId]; - return image && image.sizeInBytes; - } - - cacheFullHandler() { - OHIF.log.warn('Cache full'); - this.stopPrefetching(); - } - -} diff --git a/Packages/ohif-core/client/classes/TypeSafeCollection.js b/Packages/ohif-core/client/classes/TypeSafeCollection.js deleted file mode 100644 index b0577c1b4..000000000 --- a/Packages/ohif-core/client/classes/TypeSafeCollection.js +++ /dev/null @@ -1,498 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { ReactiveVar } from 'meteor/reactive-var'; - -/** - * Constants - */ - -const PROPERTY_SEPARATOR = '.'; -const ORDER_ASC = 'asc'; -const ORDER_DESC = 'desc'; -const MIN_COUNT = 0x00000000; -const MAX_COUNT = 0x7FFFFFFF; - -/** - * Class Definition - */ - -export class TypeSafeCollection { - - constructor() { - this._operationCount = new ReactiveVar(MIN_COUNT); - this._elementList = []; - this._handlers = Object.create(null); - } - - /** - * Private Methods - */ - - _invalidate() { - let count = this._operationCount.get(); - this._operationCount.set(count < MAX_COUNT ? count + 1 : MIN_COUNT); - } - - _elements(silent) { - (silent === true || this._operationCount.get()); - return this._elementList; - } - - _elementWithPayload(payload, silent) { - return this._elements(silent).find(item => item.payload === payload); - } - - _elementWithId(id, silent) { - return this._elements(silent).find(item => item.id === id); - } - - _trigger(event, data) { - let handlers = this._handlers; - if (event in handlers) { - handlers = handlers[event]; - if (!(handlers instanceof Array)) { - return; - } - for (let i = 0, limit = handlers.length; i < limit; ++i) { - let handler = handlers[i]; - if (_isFunction(handler)) { - handler.call(null, data); - } - } - } - } - - /** - * Public Methods - */ - - onInsert(callback) { - if (_isFunction(callback)) { - let handlers = this._handlers.insert; - if (!(handlers instanceof Array)) { - handlers = []; - this._handlers.insert = handlers; - } - handlers.push(callback); - } - } - - /** - * Update the payload associated with the given ID to be the new supplied payload. - * @param {string} id The ID of the entry that will be updated. - * @param {any} payload The element that will replace the previous payload. - * @returns {boolean} Returns true if the given ID is present in the collection, false otherwise. - */ - updateById(id, payload) { - let result = false, - found = this._elementWithPayload(payload, true); - if (found) { - // nothing to do since the element is already in the collection... - if (found.id === id) { - // set result to true since the ids match... - result = true; - this._invalidate(); - } - } else { - found = this._elementWithId(id, true); - if (found) { - found.payload = payload; - result = true; - this._invalidate(); - } - } - return result; - } - - /** - * Signal that the given element has been changed by notifying reactive data-source observers. - * This method is basically a means to invalidate the inernal reactive data-source. - * @param {any} payload The element that has been altered. - * @returns {boolean} Returns true if the element is present in the collection, false otherwise. - */ - update(payload) { - let result = false, - found = this._elementWithPayload(payload, true); - if (found) { - // nothing to do since the element is already in the collection... - result = true; - this._invalidate(); - } - return result; - } - - /** - * Insert an element in the collection. On success, the element ID (a unique string) is returned. On failure, returns null. - * A failure scenario only happens when the given payload is already present in the collection. Note that NO exceptions are thrown! - * @param {any} payload The element to be stored. - * @returns {string} The ID of the inserted element or null if the element already exists... - */ - insert(payload) { - let id = null, - found = this._elementWithPayload(payload, true); - if (!found) { - id = OHIF.utils.guid(); - this._elements(true).push({ id, payload }); - this._invalidate(); - this._trigger('insert', { id, data: payload }); - } - return id; - } - - /** - * Remove all elements from the collection. - * @returns {void} No meaningful value is returned. - */ - removeAll() { - let all = this._elements(true), - length = all.length; - for (let i = length - 1; i >= 0; i--) { - let item = all[i]; - delete item.id; - delete item.payload; - all[i] = null; - } - all.splice(0, length); - this._invalidate(); - } - - /** - * Remove elements from the collection that match the criteria given in the property map. - * @param {Object} propertyMap A property map that will be macthed against all collection elements. - * @returns {Array} A list with all removed elements. - */ - remove(propertyMap) { - let found = this.findAllEntriesBy(propertyMap), - foundCount = found.length, - removed = []; - if (foundCount > 0) { - const all = this._elements(true); - for (let i = foundCount - 1; i >= 0; i--) { - let item = found[i]; - all.splice(item[2], 1); - removed.push(item[0]); - } - this._invalidate(); - } - return removed; - } - - /** - * Provides the ID of the given element inside the collection. - * @param {any} payload The element being searched for. - * @returns {string} The ID of the given element or undefined if the element is not present. - */ - getElementId(payload) { - let found = this._elementWithPayload(payload); - return found && found.id; - } - - /** - * Provides the position of the given element in the internal list returning -1 if the element is not present. - * @param {any} payload The element being searched for. - * @returns {number} The position of the given element in the internal list. If the element is not present -1 is returned. - */ - findById(id) { - let found = this._elementWithId(id); - return found && found.payload; - } - - /** - * Provides the position of the given element in the internal list returning -1 if the element is not present. - * @param {any} payload The element being searched for. - * @returns {number} The position of the given element in the internal list. If the element is not present -1 is returned. - */ - indexOfElement(payload) { - return this._elements().indexOf(this._elementWithPayload(payload, true)); - } - - /** - * Provides the position of the element associated with the given ID in the internal list returning -1 if the element is not present. - * @param {string} id The index of the element. - * @returns {number} The position of the element associated with the given ID in the internal list. If the element is not present -1 is returned. - */ - indexOfId(id) { - return this._elements().indexOf(this._elementWithId(id, true)); - } - - /** - * Provides a list-like approach to the collection returning an element by index. - * @param {number} index The index of the element. - * @returns {any} If out of bounds, undefined is returned. Otherwise the element in the given position is returned. - */ - getElementByIndex(index) { - let found = ((this._elements())[index >= 0 ? index : -1]); - return found && found.payload; - } - - /** - * Find an element by a criteria defined by the given callback function. - * Attention!!! The reactive source will not be notified if no valid callback is supplied... - * @param {function} callback A callback function which will define the search criteria. The callback - * function will be passed the collection element, its ID and its index in this very order. The callback - * shall return true when its criterea has been fulfilled. - * @returns {any} The matched element or undefined if not match was found. - */ - find(callback) { - let found; - if (_isFunction(callback)) { - found = this._elements().find((item, index) => { - return callback.call(this, item.payload, item.id, index); - }); - } - return found && found.payload; - } - - /** - * Find the first element that strictly matches the specified property map. - * @param {Object} propertyMap A property map that will be macthed against all collection elements. - * @param {Object} options A set of options. Currently only "options.sort" option is supported. - * @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied - * but is not valid, an exception will be thrown. - * @returns {Any} The matched element or undefined if not match was found. - */ - findBy(propertyMap, options) { - let found; - if (_isObject(options)) { - // if the "options" argument is provided and is a valid object, - // it must be applied to the dataset before search... - const all = this.all(options); - if (all.length > 0) { - if (_isObject(propertyMap)) { - found = all.find(item => _compareToPropertyMapStrict(propertyMap, item)); - } else { - found = all[0]; // simply extract the first element... - } - } - } else if (_isObject(propertyMap)) { - found = this._elements().find(item => _compareToPropertyMapStrict(propertyMap, item.payload)); - if (found) { - found = found.payload; - } - } - return found; - } - - /** - * Find all elements that strictly match the specified property map. - * Attention!!! The reactive source will not be notified if no valid property map is supplied... - * @param {Object} propertyMap A property map that will be macthed against all collection elements. - * @returns {Array} An array of entries of all elements that match the given criteria. Each set in - * in the array has the following format: [ elementData, elementId, elementIndex ]. - */ - findAllEntriesBy(propertyMap) { - const found = []; - if (_isObject(propertyMap)) { - this._elements().forEach((item, index) => { - if (_compareToPropertyMapStrict(propertyMap, item.payload)) { - // Match! Add it to the found list... - found.push([ item.payload, item.id, index ]); - } - }); - } - return found; - } - - /** - * Find all elements that match a specified property map. - * Attention!!! The reactive source will not be notified if no valid property map is supplied... - * @param {Object} propertyMap A property map that will be macthed against all collection elements. - * @param {Object} options A set of options. Currently only "options.sort" option is supported. - * @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied - * but is not valid, an exception will be thrown. - * @returns {Array} An array with all elements that match the given criteria and sorted in the specified sorting order. - */ - findAllBy(propertyMap, options) { - const found = this.findAllEntriesBy(propertyMap).map(item => item[0]); // Only payload is relevant... - if (_isObject(options)) { - if ('sort' in options) { - _sortListBy(found, options.sort); - } - } - return found; - } - - /** - * Executes the supplied callback function for each element of the collection. - * Attention!!! The reactive source will not be notified if no valid property map is supplied... - * @param {function} callback The callback function to be executed. The callback is passed the element, - * its ID and its index in this very order. - * @returns {void} Nothing is returned. - */ - forEach(callback) { - if (_isFunction(callback)) { - this._elements().forEach((item, index) => { - callback.call(this, item.payload, item.id, index); - }); - } - } - - /** - * Count the number of elements currently in the collection. - * @returns {number} The current number of elements in the collection. - */ - count() { - return this._elements().length; - } - - /** - * Returns a list with all elements of the collection optionally sorted by a sorting specifier criteria. - * @param {Object} options A set of options. Currently only "options.sort" option is supported. - * @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied - * but is not valid, an exception will be thrown. - * @returns {Array} An array with all elements stored in the collection. - */ - all(options) { - let list = this._elements().map(item => item.payload); - if (_isObject(options)) { - if ('sort' in options) { - _sortListBy(list, options.sort); - } - } - return list; - } - -} - -/** - * Utility Functions - */ - -/** - * Test if supplied argument is a valid object for current class purposes. - * Atention! The underscore version of this function should not be used for performance reasons. - */ -function _isObject(subject) { - return subject instanceof Object || typeof subject === 'object' && subject !== null; -} - -/** - * Test if supplied argument is a valid string for current class purposes. - * Atention! The underscore version of this function should not be used for performance reasons. - */ -function _isString(subject) { - return typeof subject === 'string'; -} - -/** - * Test if supplied argument is a valid function for current class purposes. - * Atention! The underscore version of this function should not be used for performance reasons. - */ -function _isFunction(subject) { - return typeof subject === 'function'; -} - -/** - * Shortcut for Object's prototype "hasOwnProperty" method. - */ -const _hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * Retrieve an object's property value by name. Composite property names (e.g., 'address.country.name') are accepted. - * @param {Object} targetObject The object we want read the property from... - * @param {String} propertyName The property to be read (e.g., 'address.street.name' or 'address.street.number' - * to read object.address.street.name or object.address.street.number, respectively); - * @returns {Any} Returns whatever the property holds or undefined if the property cannot be read or reached. - */ -function _getPropertyValue(targetObject, propertyName) { - let propertyValue; // undefined (the default return value) - if (_isObject(targetObject) && _isString(propertyName)) { - const fragments = propertyName.split(PROPERTY_SEPARATOR); - const fragmentCount = fragments.length; - if (fragmentCount > 0) { - const firstFragment = fragments[0]; - const remainingFragments = fragmentCount > 1 ? fragments.slice(1).join(PROPERTY_SEPARATOR) : null; - propertyValue = targetObject[firstFragment]; - if (remainingFragments !== null) { - propertyValue = _getPropertyValue(propertyValue, remainingFragments); - } - } - } - return propertyValue; -} - -/** - * Compare a property map with a target object using strict comparison. - * @param {Object} propertyMap The property map whose properties will be used for comparison. Composite - * property names (e.g., 'address.country.name') will be tested against the "resolved" properties from the target object. - * @param {Object} targetObject The target object whose properties will be tested. - * @returns {boolean} Returns true if the properties match, false otherwise. - */ -function _compareToPropertyMapStrict(propertyMap, targetObject) { - let result = false; - // "for in" loops do not thown exceptions for invalid data types... - for (let propertyName in propertyMap) { - if (_hasOwnProperty.call(propertyMap, propertyName)) { - if (propertyMap[propertyName] !== _getPropertyValue(targetObject, propertyName)) { - result = false; - break; - } else if (result !== true) { - result = true; - } - } - } - return result; -} - -/** - * Checks if a sorting specifier is valid. - * A valid sorting specifier consists of an array of arrays being each subarray a pair - * in the format ["property name", "sorting order"]. - * The following exemple can be used to sort studies by "date"" and use "time" to break ties in descending order. - * [ [ 'study.date', 'desc' ], [ 'study.time', 'desc' ] ] - * @param {Array} specifiers The sorting specifier to be tested. - * @returns {boolean} Returns true if the specifiers are valid, false otherwise. - */ -function _isValidSortingSpecifier(specifiers) { - let result = true; - if (specifiers instanceof Array && specifiers.length > 0) { - for (let i = specifiers.length - 1; i >= 0; i--) { - const item = specifiers[i]; - if (item instanceof Array) { - const property = item[0]; - const order = item[1]; - if (_isString(property) && (order === ORDER_ASC || order === ORDER_DESC)) { - continue; - } - } - result = false; - break; - } - } - return result; -} - -/** - * Sorts an array based on sorting specifier options. - * @param {Array} list The that needs to be sorted. - * @param {Array} specifiers An array of specifiers. Please read isValidSortingSpecifier method definition for further details. - * @returns {void} No value is returned. The array is sorted in place. - */ -function _sortListBy(list, specifiers) { - if (list instanceof Array && _isValidSortingSpecifier(specifiers)) { - const specifierCount = specifiers.length; - list.sort(function _sortListByCallback(a, b) { // callback name for stack traces... - let index = 0; - while (index < specifierCount) { - const specifier = specifiers[index]; - const property = specifier[0]; - const order = specifier[1] === ORDER_DESC ? -1 : 1; - const aValue = _getPropertyValue(a, property); - const bValue = _getPropertyValue(b, property); - // @TODO: should we check for the types being compared, like: - // ~~ if (typeof aValue !== typeof bValue) continue; - // Not sure because dates, for example, can be correctly compared to numbers... - if (aValue < bValue) { - return order * -1; - } - if (aValue > bValue) { - return order * 1; - } - if (++index >= specifierCount) { - return 0; - } - } - }); - } else { - throw new Error('Invalid Arguments'); - } -} diff --git a/Packages/ohif-core/client/classes/index.js b/Packages/ohif-core/client/classes/index.js deleted file mode 100644 index 511a80265..000000000 --- a/Packages/ohif-core/client/classes/index.js +++ /dev/null @@ -1,69 +0,0 @@ -import MetadataProvider from './MetadataProvider.js'; -import CommandsManager from './CommandsManager.js'; -import HotkeysContext from './HotkeysContext.js'; -import HotkeysManager from './HotkeysManager.js'; -import { ImageSet } from './ImageSet'; -import { StudyPrefetcher } from './StudyPrefetcher'; -import { ResizeViewportManager } from './ResizeViewportManager'; -import { StudyLoadingListener } from './StudyLoadingListener'; -import { StackLoadingListener } from './StudyLoadingListener'; -import { DICOMFileLoadingListener } from './StudyLoadingListener'; -import { StudyMetadata } from './metadata/StudyMetadata'; -import { SeriesMetadata } from './metadata/SeriesMetadata'; -import { InstanceMetadata } from './metadata/InstanceMetadata'; -//import { StudySummary } from './metadata/StudySummary'; -import { plugins } from './plugins/'; -import { TypeSafeCollection } from './TypeSafeCollection'; -import { OHIFError } from './OHIFError.js'; -//import { StackImagePositionOffsetSynchronizer } from './StackImagePositionOffsetSynchronizer'; -import { StudyMetadataSource } from './StudyMetadataSource'; - -export { - MetadataProvider, - CommandsManager, - HotkeysContext, - HotkeysManager, - ImageSet, - StudyPrefetcher, - ResizeViewportManager, - StudyLoadingListener, - StackLoadingListener, - DICOMFileLoadingListener, - StudyMetadata, - SeriesMetadata, - InstanceMetadata, - //StudySummary, - TypeSafeCollection, - OHIFError, - //StackImagePositionOffsetSynchronizer, - StudyMetadataSource -}; - -const classes = { - MetadataProvider, - CommandsManager, - HotkeysContext, - HotkeysManager, - ImageSet, - StudyPrefetcher, - ResizeViewportManager, - StudyLoadingListener, - StackLoadingListener, - DICOMFileLoadingListener, - StudyMetadata, - SeriesMetadata, - InstanceMetadata, - //StudySummary, - TypeSafeCollection, - OHIFError, - //StackImagePositionOffsetSynchronizer, - StudyMetadataSource -}; - -export default classes; - -//Viewerbase.metadata = { StudyMetadata, SeriesMetadata, InstanceMetadata, StudySummary }; -//Viewerbase.plugins = plugins; - -// TypeSafeCollection -//Viewerbase.TypeSafeCollection = TypeSafeCollection; diff --git a/Packages/ohif-core/client/classes/metadata/InstanceMetadata.js b/Packages/ohif-core/client/classes/metadata/InstanceMetadata.js deleted file mode 100644 index 781d6e9e4..000000000 --- a/Packages/ohif-core/client/classes/metadata/InstanceMetadata.js +++ /dev/null @@ -1,227 +0,0 @@ -import { Metadata } from './Metadata'; -import { OHIFError } from '../OHIFError.js'; - -/** - * ATTENTION! This class should never depend on StudyMetadata or SeriesMetadata classes as this could - * possibly cause circular dependency issues. - */ - -const UNDEFINED = 'undefined'; -const NUMBER = 'number'; -const STRING = 'string'; -const STUDY_INSTANCE_UID = 'x0020000d'; -const SERIES_INSTANCE_UID = 'x0020000e'; - -export class InstanceMetadata extends Metadata { - - constructor(data, uid) { - super(data, uid); - // Initialize Private Properties - Object.defineProperties(this, { - _sopInstanceUID: { - configurable: true, // configurable so that it can be redefined in sub-classes... - enumerable: false, - writable: true, - value: null - }, - _imageId: { - configurable: true, // configurable so that it can be redefined in sub-classes... - enumerable: false, - writable: true, - value: null - } - }); - // Initialize Public Properties - this._definePublicProperties(); - } - - /** - * Private Methods - */ - - /** - * Define Public Properties - * This method should only be called during initialization (inside the class constructor) - */ - _definePublicProperties() { - - /** - * Property: this.sopInstanceUID - * Same as this.getSOPInstanceUID() - * It's specially useful in contexts where a method call is not suitable like in search criteria. For example: - * sopInstanceCollection.findBy({ - * sopInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0' - * }); - */ - Object.defineProperty(this, 'sopInstanceUID', { - configurable: false, - enumerable: false, - get: function() { - return this.getSOPInstanceUID(); - } - }); - - } - - /** - * Public Methods - */ - - /** - * Returns the StudyInstanceUID of the current instance. This method is basically a shorthand the full "getTagValue" method call. - */ - getStudyInstanceUID() { - return this.getTagValue(STUDY_INSTANCE_UID, null); - } - - /** - * Returns the SeriesInstanceUID of the current instance. This method is basically a shorthand the full "getTagValue" method call. - */ - getSeriesInstanceUID() { - return this.getTagValue(SERIES_INSTANCE_UID, null); - } - - /** - * Returns the SOPInstanceUID of the current instance. - */ - getSOPInstanceUID() { - return this._sopInstanceUID; - } - - // @TODO: Improve this... (E.g.: blob data) - getStringValue(tagOrProperty, index, defaultValue) { - let value = this.getTagValue(tagOrProperty, defaultValue); - - if (typeof value !== STRING && typeof value !== UNDEFINED) { - value = value.toString(); - } - - return InstanceMetadata.getIndexedValue(value, index, defaultValue); - } - - // @TODO: Improve this... (E.g.: blob data) - getFloatValue(tagOrProperty, index, defaultValue) { - let value = this.getTagValue(tagOrProperty, defaultValue); - value = InstanceMetadata.getIndexedValue(value, index, defaultValue); - - if(value instanceof Array) { - value.forEach( (val, idx) => { - value[idx] = parseFloat(val); - }); - - return value; - } - - return typeof value === STRING ? parseFloat(value) : value; - } - - // @TODO: Improve this... (E.g.: blob data) - getIntValue(tagOrProperty, index, defaultValue) { - let value = this.getTagValue(tagOrProperty, defaultValue); - value = InstanceMetadata.getIndexedValue(value, index, defaultValue); - - if(value instanceof Array) { - value.forEach( (val, idx) => { - value[idx] = parseFloat(val); - }); - - return value; - } - - return typeof value === STRING ? parseInt(value) : value; - } - - /** - * @deprecated Please use getTagValue instead. - */ - getRawValue(tagOrProperty, defaultValue) { - return this.getTagValue(tagOrProperty, defaultValue); - } - - /** - * This function should be overriden by specialized classes in order to allow client libraries or viewers to take advantage of the Study Metadata API. - */ - getTagValue(tagOrProperty, defaultValue) { - /** - * Please override this method on a specialized class. - */ - throw new OHIFError('InstanceMetadata::getTagValue is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example'); - } - - /** - * Compares the current instance with another one. - * @param {InstanceMetadata} instance An instance of the InstanceMetadata class. - * @returns {boolean} Returns true if both instances refer to the same instance. - */ - equals(instance) { - const self = this; - return ( - instance === self || - ( - instance instanceof InstanceMetadata && - instance.getSOPInstanceUID() === self.getSOPInstanceUID() - ) - ); - } - - /** - * Check if the tagOrProperty exists - * @param {String} tagOrProperty tag or property be checked - * @return {Boolean} True if the tag or property exists or false if doesn't - */ - tagExists(tagOrProperty) { - /** - * Please override this method - */ - throw new OHIFError('InstanceMetadata::tagExists is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example'); - } - - /** - * Get custom image id of a sop instance - * @return {Any} sop instance image id - */ - getImageId(frame) { - /** - * Please override this method - */ - throw new OHIFError('InstanceMetadata::getImageId is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example'); - } - - /** - * Static Methods - */ - - /** - * Get an value based that can be index based. This function is called by all getters. See above functions. - * - If value is a String and has indexes: - * - If undefined index: returns an array of the split values. - * - If defined index: - * - If invalid: returns defaultValue - * - If valid: returns the indexed value - * - If value is not a String, returns default value. - */ - static getIndexedValue(value, index, defaultValue) { - let result = defaultValue; - - if (typeof value === STRING) { - const hasIndexValues = value.indexOf('\\') !== -1; - - result = value; - - if(hasIndexValues) { - const splitValues = value.split('\\'); - if (Metadata.isValidIndex(index)) { - const indexedValue = splitValues[index]; - - result = typeof indexedValue !== STRING ? defaultValue : indexedValue; - } - else { - result = splitValues; - } - } - } - - return result; - } - -} diff --git a/Packages/ohif-core/client/classes/metadata/Metadata.js b/Packages/ohif-core/client/classes/metadata/Metadata.js deleted file mode 100644 index 796c61782..000000000 --- a/Packages/ohif-core/client/classes/metadata/Metadata.js +++ /dev/null @@ -1,127 +0,0 @@ - -/** - * Constants - */ - -const STRING = 'string'; -const NUMBER = 'number'; -const FUNCTION = 'function'; -const OBJECT = 'object'; - -/** - * Class Definition - */ - -export class Metadata { - - /** - * Constructor and Instance Methods - */ - - constructor(data, uid) { - // Define the main "_data" private property as an immutable property. - // IMPORTANT: This property can only be set during instance construction. - Object.defineProperty(this, '_data', { - configurable: false, - enumerable: false, - writable: false, - value: data - }); - - // Define the main "_uid" private property as an immutable property. - // IMPORTANT: This property can only be set during instance construction. - Object.defineProperty(this, '_uid', { - configurable: false, - enumerable: false, - writable: false, - value: uid - }); - - // Define "_custom" properties as an immutable property. - // IMPORTANT: This property can only be set during instance construction. - Object.defineProperty(this, '_custom', { - configurable: false, - enumerable: false, - writable: false, - value: Object.create(null) - }); - } - - getData() { - return this._data; - } - - getDataProperty(propertyName) { - let propertyValue; - const _data = this._data; - if (_data instanceof Object || typeof _data === OBJECT && _data !== null) { - propertyValue = _data[propertyName]; - } - return propertyValue; - } - - /** - * Get unique object ID - */ - getObjectID() { - return this._uid; - } - - /** - * Set custom attribute value - * @param {String} attribute Custom attribute name - * @param {Any} value Custom attribute value - */ - setCustomAttribute(attribute, value) { - this._custom[attribute] = value; - } - - /** - * Get custom attribute value - * @param {String} attribute Custom attribute name - * @return {Any} Custom attribute value - */ - getCustomAttribute(attribute) { - return this._custom[attribute]; - } - - /** - * Check if a custom attribute exists - * @param {String} attribute Custom attribute name - * @return {Boolean} True if custom attribute exists or false if not - */ - customAttributeExists(attribute) { - return attribute in this._custom; - } - - /** - * Set custom attributes in batch mode. - * @param {Object} attributeMap An object whose own properties will be used as custom attributes. - */ - setCustomAttributes(attributeMap) { - const _hasOwn = Object.prototype.hasOwnProperty; - const _custom = this._custom; - for (let attribute in attributeMap) { - if (_hasOwn.call(attributeMap, attribute)) { - _custom[attribute] = attributeMap[attribute]; - } - } - } - - /** - * Static Methods - */ - - static isValidUID(uid) { - return typeof uid === STRING && uid.length > 0; - } - - static isValidIndex(index) { - return typeof index === NUMBER && index >= 0 && (index | 0) === index; - } - - static isValidCallback(callback) { - return typeof callback === FUNCTION; - } - -} diff --git a/Packages/ohif-core/client/classes/metadata/OHIFInstanceMetadata.js b/Packages/ohif-core/client/classes/metadata/OHIFInstanceMetadata.js deleted file mode 100644 index c6306b333..000000000 --- a/Packages/ohif-core/client/classes/metadata/OHIFInstanceMetadata.js +++ /dev/null @@ -1,117 +0,0 @@ -import { InstanceMetadata } from './InstanceMetadata'; -import { DICOMTagDescriptions } from '../../lib/DICOMTagDescriptions.js'; - -export class OHIFInstanceMetadata extends InstanceMetadata { - - /** - * @param {Object} Instance object. - */ - constructor(data, series, study, uid) { - super(data, uid); - this.init(series, study); - } - - init(series, study) { - const instance = this.getData(); - - // Initialize Private Properties - Object.defineProperties(this, { - _sopInstanceUID: { - configurable: false, - enumerable: false, - writable: false, - value: instance.sopInstanceUid - }, - _study: { - configurable: false, - enumerable: false, - writable: false, - value: study - }, - _series: { - configurable: false, - enumerable: false, - writable: false, - value: series - }, - _instance: { - configurable: false, - enumerable: false, - writable: false, - value: instance - }, - _cache: { - configurable: false, - enumerable: false, - writable: false, - value: Object.create(null) - } - }); - } - - // Override - getTagValue(tagOrProperty, defaultValue, bypassCache) { - - // check if this property has been cached... - if (tagOrProperty in this._cache && bypassCache !== true) { - return this._cache[tagOrProperty]; - } - - const propertyName = OHIFInstanceMetadata.getPropertyName(tagOrProperty); - - // Search property value in the whole study metadata chain... - let rawValue; - if (propertyName in this._instance) { - rawValue = this._instance[propertyName]; - } else if (propertyName in this._series) { - rawValue = this._series[propertyName]; - } else if (propertyName in this._study) { - rawValue = this._study[propertyName]; - } - - if (rawValue !== void 0) { - // if rawValue value is not undefined, cache result... - this._cache[tagOrProperty] = rawValue; - return rawValue; - } - - return defaultValue; - } - - // Override - tagExists(tagOrProperty) { - const propertyName = OHIFInstanceMetadata.getPropertyName(tagOrProperty); - - return (propertyName in this._instance || propertyName in this._series || propertyName in this._study); - } - - // Override - getImageId(frame, thumbnail) { - // If _imageID is not cached, create it - if (this._imageId === null) { - this._imageId = Viewerbase.getImageId(this.getData(), frame, thumbnail); - } - - return this._imageId; - } - - /** - * Static methods - */ - - // @TODO: The current mapping of standard DICOM property names to local property names is not optimal. - // The inconsistency in property naming makes this function increasingly complex. - // A possible solution to improve this would be adapt retriveMetadata names to use DICOM standard names as in dicomTagDescriptions.js - static getPropertyName(tagOrProperty) { - let propertyName; - const tagInfo = DICOMTagDescriptions.find(tagOrProperty); - - if (tagInfo !== void 0) { - // This function tries to translate standard DICOM property names into local naming convention. - propertyName = tagInfo.keyword.replace(/^SOP/, 'sop').replace(/UID$/, 'Uid').replace(/ID$/, 'Id'); - propertyName = propertyName.charAt(0).toLowerCase() + propertyName.substr(1); - } - - return propertyName; - } -} diff --git a/Packages/ohif-core/client/classes/metadata/OHIFSeriesMetadata.js b/Packages/ohif-core/client/classes/metadata/OHIFSeriesMetadata.js deleted file mode 100644 index a8e05b917..000000000 --- a/Packages/ohif-core/client/classes/metadata/OHIFSeriesMetadata.js +++ /dev/null @@ -1,32 +0,0 @@ -import { SeriesMetadata } from './SeriesMetadata'; -import { OHIFInstanceMetadata } from './OHIFInstanceMetadata'; - -export class OHIFSeriesMetadata extends SeriesMetadata { - - /** - * @param {Object} Series object. - */ - constructor(data, study, uid) { - super(data, uid); - this.init(study); - } - - init(study) { - const series = this.getData(); - - // define "_seriesInstanceUID" protected property... - Object.defineProperty(this, '_seriesInstanceUID', { - configurable: false, - enumerable: false, - writable: false, - value: series.seriesInstanceUid - }); - - // populate internal list of instances... - series.instances.forEach(instance => { - this.addInstance(new OHIFInstanceMetadata(instance, series, study)); - }); - } - -} - diff --git a/Packages/ohif-core/client/classes/metadata/OHIFStudyMetadata.js b/Packages/ohif-core/client/classes/metadata/OHIFStudyMetadata.js deleted file mode 100644 index 9f523793e..000000000 --- a/Packages/ohif-core/client/classes/metadata/OHIFStudyMetadata.js +++ /dev/null @@ -1,31 +0,0 @@ -import { StudyMetadata } from './StudyMetadata'; -import { OHIFSeriesMetadata } from './OHIFSeriesMetadata'; - -export class OHIFStudyMetadata extends StudyMetadata { - - /** - * @param {Object} Study object. - */ - constructor(data, uid) { - super(data, uid); - this.init(); - } - - init() { - const study = this.getData(); - - // define "_studyInstanceUID" protected property - Object.defineProperty(this, '_studyInstanceUID', { - configurable: false, - enumerable: false, - writable: false, - value: study.studyInstanceUid - }); - - // populate internal list of series - study.seriesList.forEach(series => { - this.addSeries(new OHIFSeriesMetadata(series, study)); - }); - } - -} diff --git a/Packages/ohif-core/client/classes/metadata/README.md b/Packages/ohif-core/client/classes/metadata/README.md deleted file mode 100644 index af0451a8c..000000000 --- a/Packages/ohif-core/client/classes/metadata/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# Study Metadata Module - -This module defines the API/Data-Model by which OHIF Viewerbase package and possibly distinct viewer -implementations can access studies metadata. This module does not attempt to define any means of -*loading* study metadata from any data end-point but only how the data that has been previously -loaded into the application context will be accessed by any of the routines or algorithm implementations -that need the data. - -## Intro - -For various reasons like sorting, grouping or simply rendering study information, OHIF Viewerbase package -and applications depending on it usualy have the need to access study metadata. Before the current -initiative there was no uniform way of achieving that since each implementation provides study metadata -on its own specific ways. The application and the package itself needed to have a deep knowledge of the -data structures provided by the data endpoint to perform any of the operations mentioned above, meaning -that any data access code needed to be adapted or rewritten. - -The intent of the current module is to provide a fairly consistent and flexible API/Data-Model by which -OHIF Viewerbase package (and different viewer implementations that depend on it) can manipulate DICOM matadata -retrieved from distinct data end points (e.g., a proprietary back end servers) in uniform ways with minor -to no modifications needed. - -## Implementation - -The current API implementation defines three classes of objects: `StudyMetadata`, `SeriesMetadata` -and `InstanceMetadata`. Inside OHIF Viewerbase package, every access to Study, Series or SOP Instance -metadata is achieved by the interface exposed by these three classes. By inheriting from them and -overriding or extending their methods, different applications with different data models can adapt -even the most peculiar data structures to the uniform interface defined by those classes. Together -these classes define a flexible and extensible data manipulation layer leaving routines and -algorithms that depend on that data untouched. - -## Design Decisions & "*Protected*" Members - -In order to provide for good programming practices, attributes and methods meant to be used exclusevily by -the classes themselves (for internal purposes only) were written with an initial '_' character, being thus treated -as "*protected*" members. The idea behind this practice was never to hide them from the programmers -(what makes debugging tasks painful) but only advise for something that's not part of the official public API -and thus should not be relied on. Usage of "protected" members makes the code less readable and prone to -compatibility issues. - -As an example, the initial implementation of the `StudyMetadata` class defined the attribute `_studyInstanceUID` -and the method `getStudyInstanceUID`. This implies that whenever the *StudyInstanceUID* of a given study needs -to be retrieved the `getStudyInstanceUID` method should be called instead of directly accessing the -attribute `_studyInstanceUID` (which might not even be populated since `getStudyInstanceUID` can be possiblity -overriden by a subclass to satisfy specific implementation needs, leaving the attribute `_studyInstanceUID` unused). - -Ex: - -```javascript -let studyUID = myStudy.getStudyInstanceUID(); // GOOD! :-) -[ ... ] -let otherStudyUID = anotherStudy._studyInstanceUID; // BAD... :-( -``` - -Another important topic is the preference of *methods* over *attributes* on the public API. This design -decision was made to ensure extensibility and flexibility (methods are extensible while standalone -attributes are not, and can be adapted – through overrides, for example – to support even the most -peculiar data models) even though the overhead a few additional function calls may incur. - -## Abstract Classes - -Some classes defined in this module are "*abstract*" classes (even though JavaScript does not *officially* -support such programming facility). They are *abstract* in the sense that a few methods (very important ones, -by the way) were left "*blank*" (unimplemented, or more precisely implemented as empty NOP functions) in -order to be implemented by specialized subclasses. Methods believed to be more generic were implemented in -an attempt to satify most implementation needs but nothing prevents a subclass from overriding them as well -(again, flexibility and extensibility are design goals). Most implemented methods rely on the implementation -of an unimplemented method. For example, the method `getStringValue` from `InstanceMetadata` class, which -has indeed been implemented and is meant to retrieve a metadata value as a string, internally calls the -`getRawValue` method which *was NOT implemented* and is meant to query the internal data structures for the -requested metadata value and return it *as is*. Used in that way, an application would not benefit much -from the already implemented methods. On the other hand, by simply overriding the `getRawValue` method -on a specialized class to deal with the intrinsics of its internal data structures, this very application -would now benefit from all already implemented methods. - -The following code snippet tries to illustrate the idea: - -```javascript - -// -- InstanceMetadata.js - -class InstanceMetadata { - [ ... ] - getRawValue(tagOrProperty, defaultValue) { - // Please implement this method in a specialized subclass... - } - [ ... ] - getStringValue(tagOrProperty, index, defaultValue) { - let rawValue = this.getRawValue(tagOrProperty, ''); - // parse the returned value into a string... - [ ... ] - return stringValue; - } - [ ... ] -} - -// -- MyFancyAppInstanceMetadata.js - -class MyFancyAppInstanceMetadata extends InstanceMetadata { - // Overriding this method will make all methods implemented in the super class - // that rely on it to be immediately available... - getRawValue(tagOrProperty, defaultValue) { - let rawValue; - // retrieve raw value from internal data structures... - [ ... ] - return rawValue; - } -} - -// -- main.js - -[ ... ] -let sopInstaceMetadata = new MyFancyAppInstanceMetadata(myInternalData); -if (sopInstaceMetadata instanceof MyFancyAppInstanceMetadata) { // true - // this code will be executed... -} -if (sopInstaceMetadata instanceof InstanceMetadata) { // also true - // this code will also be executed... -} -// The following will also work since the internal "getRawValue" call inside -// "getStringValue" method will now be satisfied... (thanks to the override) -let patientName = sopInstaceMetadata.getStringValue('PatientName', ''); -[ ... ] - -``` - -_Copyright © 2016 nucleushealth™. All rights reserved_ diff --git a/Packages/ohif-core/client/classes/metadata/SeriesMetadata.js b/Packages/ohif-core/client/classes/metadata/SeriesMetadata.js deleted file mode 100644 index 121bf8403..000000000 --- a/Packages/ohif-core/client/classes/metadata/SeriesMetadata.js +++ /dev/null @@ -1,195 +0,0 @@ -import { Metadata } from './Metadata'; -import { InstanceMetadata } from './InstanceMetadata'; - -export class SeriesMetadata extends Metadata { - - constructor(data, uid) { - super(data, uid); - // Initialize Private Properties - Object.defineProperties(this, { - _seriesInstanceUID: { - configurable: true, // configurable so that it can be redefined in sub-classes... - enumerable: false, - writable: true, - value: null - }, - _instances: { - configurable: false, - enumerable: false, - writable: false, - value: [] - }, - _firstInstance: { - configurable: false, - enumerable: false, - writable: true, - value: null - } - }); - // Initialize Public Properties - this._definePublicProperties(); - } - - /** - * Private Methods - */ - - /** - * Define Public Properties - * This method should only be called during initialization (inside the class constructor) - */ - _definePublicProperties() { - - /** - * Property: this.seriesInstanceUID - * Same as this.getSeriesInstanceUID() - * It's specially useful in contexts where a method call is not suitable like in search criteria. For example: - * seriesCollection.findBy({ - * seriesInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0' - * }); - */ - Object.defineProperty(this, 'seriesInstanceUID', { - configurable: false, - enumerable: false, - get: function() { - return this.getSeriesInstanceUID(); - } - }); - - } - - /** - * Public Methods - */ - - /** - * Returns the SeriesInstanceUID of the current series. - */ - getSeriesInstanceUID() { - return this._seriesInstanceUID; - } - - /** - * Append an instance to the current series. - * @param {InstanceMetadata} instance The instance to be added to the current series. - * @returns {boolean} Returns true on success, false otherwise. - */ - addInstance(instance) { - let result = false; - if (instance instanceof InstanceMetadata && this.getInstanceByUID(instance.getSOPInstanceUID()) === void 0) { - this._instances.push(instance); - result = true; - } - return result; - } - - /** - * Get the first instance of the current series retaining a consistent result across multiple calls. - * @return {InstanceMetadata} An instance of the InstanceMetadata class or null if it does not exist. - */ - getFirstInstance() { - let instance = this._firstInstance; - if (!(instance instanceof InstanceMetadata)) { - instance = null; - const found = this.getInstanceByIndex(0); - if (found instanceof InstanceMetadata) { - this._firstInstance = found; - instance = found; - } - } - return instance; - } - - /** - * Find an instance by index. - * @param {number} index An integer representing a list index. - * @returns {InstanceMetadata} Returns a InstanceMetadata instance when found or undefined otherwise. - */ - getInstanceByIndex(index) { - let found; // undefined by default... - if (Metadata.isValidIndex(index)) { - found = this._instances[index]; - } - return found; - } - - /** - * Find an instance by SOPInstanceUID. - * @param {string} uid An UID string. - * @returns {InstanceMetadata} Returns a InstanceMetadata instance when found or undefined otherwise. - */ - getInstanceByUID(uid) { - let found; // undefined by default... - if (Metadata.isValidUID(uid)) { - found = this._instances.find(instance => { - return instance.getSOPInstanceUID() === uid; - }); - } - return found; - } - - /** - * Retrieve the number of instances within the current series. - * @returns {number} The number of instances in the current series. - */ - getInstanceCount() { - return this._instances.length; - } - - /** - * Invokes the supplied callback for each instance in the current series passing - * two arguments: instance (an InstanceMetadata instance) and index (the integer - * index of the instance within the current series) - * @param {function} callback The callback function which will be invoked for each instance in the series. - * @returns {undefined} Nothing is returned. - */ - forEachInstance(callback) { - if (Metadata.isValidCallback(callback)) { - this._instances.forEach((instance, index) => { - callback.call(null, instance, index); - }); - } - } - - /** - * Find the index of an instance inside the series. - * @param {InstanceMetadata} instance An instance of the SeriesMetadata class. - * @returns {number} The index of the instance inside the series or -1 if not found. - */ - indexOfInstance(instance) { - return this._instances.indexOf(instance); - } - - /** - * Search the associated instances using the supplied callback as criteria. The callback is passed - * two arguments: instance (a InstanceMetadata instance) and index (the integer - * index of the instance within its series) - * @param {function} callback The callback function which will be invoked for each instance. - * @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it - * returns a InstanceMetadata. "undefined" is returned otherwise - */ - findInstance(callback) { - if (Metadata.isValidCallback(callback)) { - return this._instances.find((instance, index) => { - return callback.call(null, instance, index); - }); - } - } - - /** - * Compares the current series with another one. - * @param {SeriesMetadata} series An instance of the SeriesMetadata class. - * @returns {boolean} Returns true if both instances refer to the same series. - */ - equals(series) { - const self = this; - return ( - series === self || - ( - series instanceof SeriesMetadata && - series.getSeriesInstanceUID() === self.getSeriesInstanceUID() - ) - ); - } - -} diff --git a/Packages/ohif-core/client/classes/metadata/StudyMetadata.js b/Packages/ohif-core/client/classes/metadata/StudyMetadata.js deleted file mode 100644 index b04c58172..000000000 --- a/Packages/ohif-core/client/classes/metadata/StudyMetadata.js +++ /dev/null @@ -1,396 +0,0 @@ -import { Metadata } from './Metadata'; -import { SeriesMetadata } from './SeriesMetadata'; -import { InstanceMetadata } from './InstanceMetadata'; -import { ImageSet } from '../ImageSet'; -import { OHIFError } from '../OHIFError'; - -export class StudyMetadata extends Metadata { - - constructor(data, uid) { - super(data, uid); - // Initialize Private Properties - Object.defineProperties(this, { - _studyInstanceUID: { - configurable: true, // configurable so that it can be redefined in sub-classes... - enumerable: false, - writable: true, - value: null - }, - _series: { - configurable: false, - enumerable: false, - writable: false, - value: [] - }, - _displaySets: { - configurable: false, - enumerable: false, - writable: false, - value: [] - }, - _firstSeries: { - configurable: false, - enumerable: false, - writable: true, - value: null - }, - _firstInstance: { - configurable: false, - enumerable: false, - writable: true, - value: null - } - }); - // Initialize Public Properties - this._definePublicProperties(); - } - - /** - * Private Methods - */ - - /** - * Define Public Properties - * This method should only be called during initialization (inside the class constructor) - */ - _definePublicProperties() { - - /** - * Property: this.studyInstanceUID - * Same as this.getStudyInstanceUID() - * It's specially useful in contexts where a method call is not suitable like in search criteria. For example: - * studyCollection.findBy({ - * studyInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0' - * }); - */ - Object.defineProperty(this, 'studyInstanceUID', { - configurable: false, - enumerable: false, - get: function() { - return this.getStudyInstanceUID(); - } - }); - - } - - /** - * Public Methods - */ - - /** - * Getter for displaySets - * @return {Array} Array of display set object - */ - getDisplaySets() { - return this._displaySets.slice(); - } - - /** - * Set display sets - * @param {Array} displaySets Array of display sets (ImageSet[]) - */ - setDisplaySets(displaySets) { - displaySets.forEach(displaySet => this.addDisplaySet(displaySet)); - } - - /** - * Add a single display set to the list - * @param {Object} displaySet Display set object - * @returns {boolean} True on success, false on failure. - */ - addDisplaySet(displaySet) { - if (displaySet instanceof ImageSet) { - this._displaySets.push(displaySet); - return true; - } - return false; - } - - /** - * Invokes the supplied callback for each display set in the current study passing - * two arguments: display set (a ImageSet instance) and index (the integer - * index of the display set within the current study) - * @param {function} callback The callback function which will be invoked for each display set instance. - * @returns {undefined} Nothing is returned. - */ - forEachDisplaySet(callback) { - if (Metadata.isValidCallback(callback)) { - this._displaySets.forEach((displaySet, index) => { - callback.call(null, displaySet, index); - }); - } - } - - /** - * Search the associated display sets using the supplied callback as criteria. The callback is passed - * two arguments: display set (a ImageSet instance) and index (the integer - * index of the display set within the current study) - * @param {function} callback The callback function which will be invoked for each display set instance. - * @returns {undefined} Nothing is returned. - */ - findDisplaySet(callback) { - if (Metadata.isValidCallback(callback)) { - return this._displaySets.find((displaySet, index) => { - return callback.call(null, displaySet, index); - }); - } - } - - /** - * Retrieve the number of display sets within the current study. - * @returns {number} The number of display sets in the current study. - */ - getDisplaySetCount() { - return this._displaySets.length; - } - - /** - * Returns the StudyInstanceUID of the current study. - */ - getStudyInstanceUID() { - return this._studyInstanceUID; - } - - /** - * Getter for series - * @return {Array} Array of SeriesMetadata object - */ - getSeries() { - return this._series.slice(); - } - - /** - * Append a series to the current study. - * @param {SeriesMetadata} series The series to be added to the current study. - * @returns {boolean} Returns true on success, false otherwise. - */ - addSeries(series) { - let result = false; - if (series instanceof SeriesMetadata && this.getSeriesByUID(series.getSeriesInstanceUID()) === void 0) { - this._series.push(series); - result = true; - } - return result; - } - - /** - * Find a series by index. - * @param {number} index An integer representing a list index. - * @returns {SeriesMetadata} Returns a SeriesMetadata instance when found or undefined otherwise. - */ - getSeriesByIndex(index) { - let found; // undefined by default... - if (Metadata.isValidIndex(index)) { - found = this._series[index]; - } - return found; - } - - /** - * Find a series by SeriesInstanceUID. - * @param {string} uid An UID string. - * @returns {SeriesMetadata} Returns a SeriesMetadata instance when found or undefined otherwise. - */ - getSeriesByUID(uid) { - let found; // undefined by default... - if (Metadata.isValidUID(uid)) { - found = this._series.find(series => { - return series.getSeriesInstanceUID() === uid; - }); - } - return found; - } - - /** - * Retrieve the number of series within the current study. - * @returns {number} The number of series in the current study. - */ - getSeriesCount() { - return this._series.length; - } - - /** - * Retrieve the number of instances within the current study. - * @returns {number} The number of instances in the current study. - */ - getInstanceCount() { - return this._series.reduce((sum, series) => { - return sum + series.getInstanceCount(); - }, 0); - } - - /** - * Invokes the supplied callback for each series in the current study passing - * two arguments: series (a SeriesMetadata instance) and index (the integer - * index of the series within the current study) - * @param {function} callback The callback function which will be invoked for each series instance. - * @returns {undefined} Nothing is returned. - */ - forEachSeries(callback) { - if (Metadata.isValidCallback(callback)) { - this._series.forEach((series, index) => { - callback.call(null, series, index); - }); - } - } - - /** - * Find the index of a series inside the study. - * @param {SeriesMetadata} series An instance of the SeriesMetadata class. - * @returns {number} The index of the series inside the study or -1 if not found. - */ - indexOfSeries(series) { - return this._series.indexOf(series); - } - - /** - * It sorts the series based on display sets order. Each series must be an instance - * of SeriesMetadata and each display sets must be an instance of ImageSet. - * Useful example of usage: - * Study data provided by backend does not sort series at all and client-side - * needs series sorted by the same criteria used for sorting display sets. - */ - sortSeriesByDisplaySets() { - // Object for mapping display sets' index by seriesInstanceUid - const displaySetsMapping = {}; - - // Loop through each display set to create the mapping - this.forEachDisplaySet( (displaySet, index) => { - if (!(displaySet instanceof ImageSet)) { - throw new OHIFError(`StudyMetadata::sortSeriesByDisplaySets display set at index ${index} is not an instance of ImageSet`); - } - - // In case of multiframe studies, just get the first index occurence - if (displaySetsMapping[displaySet.seriesInstanceUid] === void 0) { - displaySetsMapping[displaySet.seriesInstanceUid] = index; - } - }); - - // Clone of actual series - const actualSeries = this.getSeries(); - - actualSeries.forEach((series, index) => { - if (!(series instanceof SeriesMetadata)) { - throw new OHIFError(`StudyMetadata::sortSeriesByDisplaySets series at index ${index} is not an instance of SeriesMetadata`); - } - - // Get the new series index - const seriesIndex = displaySetsMapping[series.getSeriesInstanceUID()]; - - // Update the series object with the new series position - this._series[seriesIndex] = series; - }); - } - - /** - * Compares the current study instance with another one. - * @param {StudyMetadata} study An instance of the StudyMetadata class. - * @returns {boolean} Returns true if both instances refer to the same study. - */ - equals(study) { - const self = this; - return ( - study === self || - ( - study instanceof StudyMetadata && - study.getStudyInstanceUID() === self.getStudyInstanceUID() - ) - ); - } - - /** - * Get the first series of the current study retaining a consistent result across multiple calls. - * @return {SeriesMetadata} An instance of the SeriesMetadata class or null if it does not exist. - */ - getFirstSeries() { - let series = this._firstSeries; - if (!(series instanceof SeriesMetadata)) { - series = null; - const found = this.getSeriesByIndex(0); - if (found instanceof SeriesMetadata) { - this._firstSeries = found; - series = found; - } - } - return series; - } - - /** - * Get the first instance of the current study retaining a consistent result across multiple calls. - * @return {InstanceMetadata} An instance of the InstanceMetadata class or null if it does not exist. - */ - getFirstInstance() { - let instance = this._firstInstance; - if (!(instance instanceof InstanceMetadata)) { - instance = null; - const firstSeries = this.getFirstSeries(); - if (firstSeries instanceof SeriesMetadata) { - const found = firstSeries.getFirstInstance(); - if (found instanceof InstanceMetadata) { - this._firstInstance = found; - instance = found; - } - } - } - return instance; - } - - /** - * Search the associated series to find an specific instance using the supplied callback as criteria. - * The callback is passed two arguments: instance (a InstanceMetadata instance) and index (the integer - * index of the instance within the current series) - * @param {function} callback The callback function which will be invoked for each instance instance. - * @returns {Object} Result object containing series (SeriesMetadata) and instance (InstanceMetadata) - * objects or an empty object if not found. - */ - findSeriesAndInstanceByInstance(callback) { - let result; - - if (Metadata.isValidCallback(callback)) { - let instance; - - const series = this._series.find(series => { - instance = series.findInstance(callback); - return instance instanceof InstanceMetadata; - }); - - // No series found - if (series instanceof SeriesMetadata) { - result = { - series, - instance - }; - } - } - - return result || {}; - } - - /** - * Find series by instance using the supplied callback as criteria. The callback is passed - * two arguments: instance (a InstanceMetadata instance) and index (the integer index of - * the instance within its series) - * @param {function} callback The callback function which will be invoked for each instance. - * @returns {SeriesMetadata|undefined} If a series is found based on callback criteria it - * returns a SeriesMetadata. "undefined" is returned otherwise - */ - findSeriesByInstance(callback) { - const result = this.findSeriesAndInstanceByInstance(callback); - - return result.series; - } - - /** - * Find an instance using the supplied callback as criteria. The callback is passed - * two arguments: instance (a InstanceMetadata instance) and index (the integer index of - * the instance within its series) - * @param {function} callback The callback function which will be invoked for each instance. - * @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it - * returns a InstanceMetadata. "undefined" is returned otherwise - */ - findInstance(callback) { - const result = this.findSeriesAndInstanceByInstance(callback); - - return result.instance; - } -} diff --git a/Packages/ohif-core/client/classes/metadata/StudySummary.js b/Packages/ohif-core/client/classes/metadata/StudySummary.js deleted file mode 100644 index c88f0ccb2..000000000 --- a/Packages/ohif-core/client/classes/metadata/StudySummary.js +++ /dev/null @@ -1,78 +0,0 @@ -import { Metadata } from './Metadata'; -import { OHIFError } from '../OHIFError'; -import { DICOMTagDescriptions } from '../../DICOMTagDescriptions'; - -/** - * Constants - */ - -const STUDY_INSTANCE_UID = 'x0020000d'; - -/** - * Class Definition - */ - -export class StudySummary extends Metadata { - - constructor(tagMap, attributeMap, uid) { - - // Call the superclass constructor passing an plain object with no prototype to be used as the main "_data" attribute. - const _data = Object.create(null); - super(_data, uid); - - // Initialize internal tag map if first argument is given. - if (tagMap !== void 0) { - this.addTags(tagMap); - } - - // Initialize internal property map if second argument is given. - if (attributeMap !== void 0) { - this.setCustomAttributes(attributeMap); - } - - } - - getStudyInstanceUID() { - // This method should return null if StudyInstanceUID is not available to keep compatibility StudyMetadata API - return this.getTagValue(STUDY_INSTANCE_UID) || null; - } - - /** - * Append tags to internal tag map. - * @param {Object} tagMap An object whose own properties will be used as tag values and appended to internal tag map. - */ - addTags(tagMap) { - const _hasOwn = Object.prototype.hasOwnProperty; - const _data = this._data; - for (let tag in tagMap) { - if (_hasOwn.call(tagMap, tag)) { - const description = DICOMTagDescriptions.find(tag); - // When a description is available, use its tag as internal key... - if (description) { - _data[description.tag] = tagMap[tag]; - } else { - _data[tag] = tagMap[tag]; - } - } - } - } - - tagExists(tagName) { - const _data = this._data; - const description = DICOMTagDescriptions.find(tagName); - if (description) { - return (description.tag in _data); - } - return (tagName in _data); - } - - getTagValue(tagName) { - const _data = this._data; - const description = DICOMTagDescriptions.find(tagName); - if (description) { - return _data[description.tag]; - } - return _data[tagName]; - } - -} diff --git a/Packages/ohif-core/client/classes/metadata/WadoRsMetaDataBuilder.js b/Packages/ohif-core/client/classes/metadata/WadoRsMetaDataBuilder.js deleted file mode 100644 index 87a23d118..000000000 --- a/Packages/ohif-core/client/classes/metadata/WadoRsMetaDataBuilder.js +++ /dev/null @@ -1,50 +0,0 @@ -import _ from 'underscore'; - -export class WadoRsMetaDataBuilder { - constructor() { - this.tags = {}; - } - - addTag(tag, value, multi) { - this.tags[tag] = { - tag, - value, - multi - }; - - return this; - } - - toJSON() { - const json = {}; - const keys = Object.keys(this.tags); - - keys.forEach(key => { - if (!this.tags.hasOwnProperty(key)) { - return; - } - - const tag = this.tags[key]; - const multi = !!tag.multi; - let value = tag.value; - - if ((value == null) || ((value.length === 1) && (value[0] == null))) { - return; - } - - if ((typeof value === 'string') && multi) { - value = value.split('\\'); - } - - if (!_.isArray(value)) { - value = [value]; - } - - json[key] = { - Value: value - }; - }); - - return json; - } -} diff --git a/Packages/ohif-core/client/classes/metadata/index.js b/Packages/ohif-core/client/classes/metadata/index.js deleted file mode 100644 index e4cfe38dd..000000000 --- a/Packages/ohif-core/client/classes/metadata/index.js +++ /dev/null @@ -1,21 +0,0 @@ -import { StudyMetadata } from './StudyMetadata'; -import { SeriesMetadata } from './SeriesMetadata'; -import { InstanceMetadata } from './InstanceMetadata'; -import { OHIFStudyMetadata } from './OHIFStudyMetadata'; -import { OHIFSeriesMetadata } from './OHIFSeriesMetadata'; -import { OHIFInstanceMetadata } from './OHIFInstanceMetadata'; -import { Metadata } from './Metadata'; -import { WadoRsMetaDataBuilder } from './WadoRsMetaDataBuilder'; - -const metadata = { - Metadata, - WadoRsMetaDataBuilder, - StudyMetadata, - SeriesMetadata, - InstanceMetadata, - OHIFStudyMetadata, - OHIFSeriesMetadata, - OHIFInstanceMetadata -} - -export default metadata; diff --git a/Packages/ohif-core/client/classes/plugins/OHIFPlugin.js b/Packages/ohif-core/client/classes/plugins/OHIFPlugin.js deleted file mode 100644 index c31408edc..000000000 --- a/Packages/ohif-core/client/classes/plugins/OHIFPlugin.js +++ /dev/null @@ -1,75 +0,0 @@ -export class OHIFPlugin { - // TODO: this class is still under development and will - // likely change in the near future - constructor () { - this.name = "Unnamed plugin"; - this.description = "No description available"; - } - - // load an individual script URL - static loadScript(scriptURL, type = "text/javascript") { - return new Promise((resolve, reject) => { - const head = document.getElementsByTagName("head")[0]; - const script = document.createElement("script"); - - script.onload = () => { - head.removeChild(script); - resolve(); - }; - - script.onerror = reject; - - script.src = scriptURL; - script.type = type; - script.async = false; - - head.appendChild(script); - }); - } - - // reload all the dependency scripts and also - // the main plugin script url. - static reloadPlugin(plugin) { - if (plugin.scriptURLs && plugin.scriptURLs.length) { - plugin.scriptURLs.forEach(scriptURL => { - this.loadScript(scriptURL); - }); - } - - // TODO: Later we should probably merge script and module URLs - if (plugin.moduleURLs && plugin.moduleURLs.length) { - plugin.moduleURLs.forEach(moduleURLs => { - this.loadScript(moduleURLs, "module"); - }); - } - - if (plugin.styleURLs && plugin.styleURLs.length) { - plugin.styleURLs.forEach(styleURLs => { - this.loadScript(styleURLs, "text/css"); - }); - } - - let scriptURL = plugin.url; - - if (plugin.allowCaching === false) { - scriptURL += "?" + performance.now(); - } - - const type = plugin.module === true ? 'module' : 'text/javascript' - - console.warn(`Calling loadScript for ${plugin.name}`); - console.time(`loadScript ${plugin.name}`); - this.loadScript(scriptURL, type).then((script) => { - console.timeEnd(`loadScript ${plugin.name}`); - const entryPointFunction = OHIF.plugins.entryPoints[plugin.name]; - - if (entryPointFunction) { - entryPointFunction(); - } else { - throw new Error(`No entry point found for ${plugin.name}`); - } - }, error => { - throw new Error(error); - }); - } -} diff --git a/Packages/ohif-core/client/classes/plugins/ViewportPlugin.js b/Packages/ohif-core/client/classes/plugins/ViewportPlugin.js deleted file mode 100644 index ef33a6175..000000000 --- a/Packages/ohif-core/client/classes/plugins/ViewportPlugin.js +++ /dev/null @@ -1,170 +0,0 @@ -import { Session } from 'meteor/session'; -import { Tracker } from 'meteor/tracker'; - -import { OHIF } from 'meteor/ohif:core'; - -import { OHIFPlugin } from "./OHIFPlugin"; - -export class ViewportPlugin extends OHIFPlugin { - constructor(name) { - super(); - - this.name = name; - this._destroyed = false; - - this._setupListeners(); - } - - /** - * Retrieve a Display Set for a specific viewport by viewport index, - * if one is already displayed in the viewport. - * - * @static - * @param {Number} viewportIndex - * @return {undefined|ImageSet} - */ - static getDisplaySet(viewportIndex) { - // TODO: Move layoutManager from viewerbase to viewer - const { layoutManager } = OHIF.viewerbase; - const viewportData = layoutManager.viewportData[viewportIndex]; - const { studyInstanceUid, displaySetInstanceUid } = viewportData; - const studyMetadata = OHIF.viewer.StudyMetadataList.findBy({ studyInstanceUID: studyInstanceUid }); - - return studyMetadata.findDisplaySet(displaySet => { - return displaySet.displaySetInstanceUid === displaySetInstanceUid; - }); - } - - /** - * Set up the viewport using the plugin. - * - * This should be implemented by the child class. - * - * @abstract - * - * @param {HTMLElement} div - * @param {ImageSet} displaySet - * @param {Object} viewportDetails - */ - setupViewport(div, displaySet, viewportDetails) { - throw new Error('You must override this method!'); - } - - /** - * Switch a single viewport to use the current ViewportPlugin - * - * @param {Number} viewportIndex The viewport to switch to the current plugin type - */ - setViewportToPlugin(viewportIndex) { - if (!this.name) { - throw new Error('ViewportPlugin subclasses must have a name'); - } - - const { layoutManager } = OHIF.viewerbase; - const viewportData = layoutManager.viewportData[viewportIndex]; - if (viewportData.plugin === this.name) { - OHIF.log.info(`setViewportToPlugin: Viewport ${viewportIndex} already set to plugin ${this.name}`); - } - - viewportData.plugin = this.name; - - layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, viewportData); - } - - /** - * Runs 'setupViewport' for the ViewportPlugin on all viewports which should - * be rendered by this plugin, but have not yet been initialized. Viewports - * which already contain contents are skipped. - * - * @private - */ - _initEmptyPluginViewports() { - if (!this.name) { - throw new Error('ViewportPlugin subclasses must have a name'); - } - - // Find all Viewport HTMLElements currently using this plugin - const pluginDivs = Array.from(document.querySelectorAll(`.viewport-plugin-${this.name}`)); - - // If there are no Viewports using this plugin, stop here - if (!pluginDivs.length) { - return; - } - - const emptyPluginDivs = pluginDivs.filter(div => { - // Keep only divs owned by the plugin which have no contents - return div.innerHTML.trim() === ''; - }); - - OHIF.log.info(`${this.name}: Initializing ${emptyPluginDivs.length} viewports`); - - // Retrieve the list of all viewports, so we can figure out the viewport details - const allViewports = Array.from(document.querySelectorAll('.viewportContainer')); - - const { layoutManager } = OHIF.viewerbase; - - emptyPluginDivs.forEach(div => { - // Identify the Viewport index, and any display set that is currently - // hung in the viewport - const viewportIndex = allViewports.indexOf(div.parentNode); - const viewportData = layoutManager.viewportData[viewportIndex]; - const displaySet = ViewportPlugin.getDisplaySet(viewportIndex); - - // Use the plugin's setupViewport function to render the contents - // of this viewport. - this.setupViewport(div, viewportData, displaySet); - }); - } - - /** - * Listen for changes to the viewport layout which would necessitate a - * rerendering of the viewports. When this happens, re-render all viewports - * which are using this plugin. - * - * @private - */ - _setupListeners() { - if (!this.name) { - throw new Error('ViewportPlugin subclasses must have a name'); - } - - console.warn(`_setupListeners: ${this.name}`); - - // TODO: Stop using Meteor's reactivity here - Tracker.autorun((computation) => { - const random = Session.get('LayoutManagerUpdated'); - console.warn(`LayoutManagerUpdated: ${this.name}: ${random}`); - - // Bail out if this is the first time the autorun - // executes (i.e. when it is being defined). - // - // Note: This has to be checked after the dependency on the - // Session variable above, or the reactive dependency will not - // be established. - if (computation.firstRun === true) { - return; - } - - // In case we need to disable the use - // of this plugin, we can also stop the - // reactive computation by setting - // this.destroyed to true. - if (this._destroyed === true) { - computation.stop(); - } - - // Identify all viewports which should be - // rendered by the ViewportPlugin, and render - // them. - this._initEmptyPluginViewports(); - }); - } - - /** - * Stop listening for changes to the viewport layout in order to - * automatically rerender viewports setup for use by this plugin. - */ - stopListeners() { - this._destroyed = true; - } -} diff --git a/Packages/ohif-core/client/classes/plugins/index.js b/Packages/ohif-core/client/classes/plugins/index.js deleted file mode 100644 index d77b077a0..000000000 --- a/Packages/ohif-core/client/classes/plugins/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -import { OHIFPlugin } from './OHIFPlugin'; -import { ViewportPlugin } from './ViewportPlugin'; - -// Each plugin registers an entry point function to be called -// when the loading is complete. - -const plugins = { - OHIFPlugin, - ViewportPlugin, - entryPoints: {} -}; - -// TODO: When we reorganize the packages, we should figure out where to put this. -OHIF.plugins = plugins; - -export default plugins; diff --git a/Packages/ohif-core/client/collections/currentServer.js b/Packages/ohif-core/client/collections/currentServer.js deleted file mode 100644 index 2778fa8db..000000000 --- a/Packages/ohif-core/client/collections/currentServer.js +++ /dev/null @@ -1,11 +0,0 @@ -import { Mongo } from 'meteor/mongo'; -import { OHIF } from 'meteor/ohif:core'; - -// CurrentServer is a single document collection to describe which of the Servers is being used -const CurrentServer = new Mongo.Collection(null); -CurrentServer._debugName = 'CurrentServer'; -OHIF.servers = OHIF.servers || {}; -OHIF.servers.collections = OHIF.servers.collections || {}; -OHIF.servers.collections.currentServer = CurrentServer; - -export { CurrentServer }; diff --git a/Packages/ohif-core/client/collections/index.js b/Packages/ohif-core/client/collections/index.js deleted file mode 100644 index 34743b128..000000000 --- a/Packages/ohif-core/client/collections/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { CurrentServer } from './currentServer.js'; -import { Servers } from './servers.js'; - -export { CurrentServer, Servers }; diff --git a/Packages/ohif-core/client/collections/servers.js b/Packages/ohif-core/client/collections/servers.js deleted file mode 100644 index 4579c1118..000000000 --- a/Packages/ohif-core/client/collections/servers.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Mongo } from 'meteor/mongo'; -import { OHIF } from 'meteor/ohif:core'; -// import { Servers as ServerSchema } from 'meteor/ohif:servers/both/schema/servers.js'; - -let collectionName = 'servers'; -if (Meteor.settings && Meteor.settings.public && Meteor.settings.public.clientOnly === true) { - collectionName = null; -} - -// Servers describe the DICOM servers configurations -const Servers = new Mongo.Collection(collectionName); -// TODO: Make the Schema match what we are currently sticking into the Collection -//Servers.attachSchema(ServerSchema); -Servers._debugName = 'Servers'; -OHIF.servers.collections.servers = Servers; - -export { Servers }; diff --git a/Packages/ohif-core/client/commands.js b/Packages/ohif-core/client/commands.js deleted file mode 100644 index e155f311a..000000000 --- a/Packages/ohif-core/client/commands.js +++ /dev/null @@ -1,18 +0,0 @@ -import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; -import { CommandsManager } from './classes/CommandsManager'; - -// Create context namespace using a ReactiveVar -const context = new ReactiveVar(null); - -// Append context namespace to OHIF namespace -OHIF.context = context; - -// Create commands namespace using a CommandsManager class instance -const commands = new CommandsManager(context); - -// Append commands namespace to OHIF namespace -OHIF.commands = commands; - -// Export relevant objects -export { context, commands }; diff --git a/Packages/ohif-core/client/components/base/component.js b/Packages/ohif-core/client/components/base/component.js deleted file mode 100644 index 7a81769d9..000000000 --- a/Packages/ohif-core/client/components/base/component.js +++ /dev/null @@ -1,49 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -/* - * Base component to template instances of all dynamic components - */ -class Component { - - // Set up the component - constructor(templateInstance) { - // Store the component in the current view - templateInstance.view._component = this; - - // Create an object to register section's content - templateInstance.sections = {}; - - // Store the template instance in the component - this.templateInstance = templateInstance; - - // Store the component's registered sub-components - this.registeredItems = new Set(); - } - - // Self register the component in its first parent component - registerSelf() { - const parent = OHIF.blaze.getParentComponent(this.templateInstance.view); - if (parent) { - // Store this component's parent in a property - this.parent = parent; - - // Add this component in its parent's registered items list - parent.registeredItems.add(this); - } - } - - // Self unregister the component in its first parent component - unregisterSelf() { - const parent = OHIF.blaze.getParentComponent(this.templateInstance.view); - if (parent) { - // Remove the parent property from this component - delete this.parent; - - // Remove this component from its parent's registered items list - parent.registeredItems.delete(this); - } - } - -} - -OHIF.Component = Component; diff --git a/Packages/ohif-core/client/components/base/index.js b/Packages/ohif-core/client/components/base/index.js deleted file mode 100644 index c494cd8e8..000000000 --- a/Packages/ohif-core/client/components/base/index.js +++ /dev/null @@ -1,39 +0,0 @@ -// Core files -import './component.js'; -import './mixin.js'; -import './template.js'; - -// Section -import './section/section.html'; -import './section/section.js'; - -// Mixins -import './mixins/action.js'; -import './mixins/button.js'; -import './mixins/checkbox.js'; -import './mixins/component.js'; -import './mixins/dropdown.js'; -import './mixins/form.js'; -import './mixins/formItem.js'; -import './mixins/group.js'; -import './mixins/groupRadio.js'; -import './mixins/input.js'; -import './mixins/link.js'; -import './mixins/popover.js'; -import './mixins/schemaData.js'; -import './mixins/select.js'; -import './mixins/select2.js'; - -// Templates -import './templates/button.html'; -import './templates/custom.html'; -import './templates/div.html'; -import './templates/form.html'; -import './templates/input.html'; -import './templates/link.html'; -import './templates/select.html'; -import './templates/tr.html'; - -// wrappers -import './wrappers/label.html'; -import './wrappers/labelContent.html'; diff --git a/Packages/ohif-core/client/components/base/mixin.js b/Packages/ohif-core/client/components/base/mixin.js deleted file mode 100644 index 6a167a1db..000000000 --- a/Packages/ohif-core/client/components/base/mixin.js +++ /dev/null @@ -1,138 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import _ from 'underscore'; - -// Create an object to store all the application mixins -OHIF.mixins = {}; - -// Class to manage new mixins and its dependencies -class Mixin { - - // Create the mixin instance - constructor({ dependencies, composition }) { - // Store the mixin dependencies - this.dependencies = dependencies || ''; - - // Store the mixin composition - this.composition = composition; - } - - // Initialize the mixin applying all its composition functions - init(template, data, applied, behaviors) { - const dependenciesArray = this.dependencies.split(' '); - _.each(dependenciesArray, dependency => { - // Go to next dependency if the current dependency string is blank - if (!dependency) { - return; - } - - // Get the dependent mixin to be initizalized - const mixin = Mixin.getMixin(dependency); - - // Throw an error if a cyclic dependency was found on this mixin - if (mixin === this) { - throw new Error(`Mixin ${dependency} has a cyclic dependency.`); - } - - // Initizalize the mixin dependencies recursively - mixin.init(template, data, applied, behaviors); - }); - - // Apply the mixin's composition behaviors to the template - this.apply(template, data, applied, behaviors); - } - - // Add the mixin's composition behaviors to the template - apply(template, data, applied, behaviors) { - // Ignore if the mixin was already applied to the template - if (_.contains(applied, this)) { - return; - } - - // Store the mixin's composition - const composition = this.composition; - - // Iterate over each behavior - _.each(behaviors, behavior => { - // Execute something only after all the mixins are done - let functionName = behavior; - if (functionName === 'onMixins') { - functionName = 'onRendered'; - } - - if (behavior === 'onData' && composition[behavior]) { - // If it's just data manipulation, call it immediately - composition[behavior](data); - } else if (composition[behavior]) { - // Register the behavior in the template - template[functionName](composition[behavior]); - } - }); - - // Set the current mixin's state as applied - applied.push(this); - } - - // Initialize all data manipulation mixins - static initData(data) { - // Split the mixins by space - const mixinsArray = data.mixins.split(' '); - - // Control and ignore the mixins that have already been applied - const appliedOnData = []; - _.each(mixinsArray, mixinName => { - // Ignore blank strings - if (!mixinName) { - return; - } - - // Get the current mixin - const mixin = Mixin.getMixin(mixinName); - - // Initialize the data manipulation composition - mixin.init(null, data, appliedOnData, ['onData']); - }); - } - - // Initialize all the template's mixins - static initAll(template, data) { - // Split the mixins by space - const mixinsArray = data.mixins.split(' '); - - // Control and ignore the mixins that have already been applied - const appliedCommon = []; - const appliedOnMixins = []; - _.each(mixinsArray, mixinName => { - // Ignore blank strings - if (!mixinName) { - return; - } - - // Get the current mixin - const mixin = Mixin.getMixin(mixinName); - - // Initialize blaze default compositions - mixin.init(template, data, appliedCommon, ['onCreated', 'onRendered', 'onDestroyed', 'events', 'helpers']); - - // Execute some behaviors after all mixins are applied - mixin.init(template, data, appliedOnMixins, ['onMixins']); - }); - } - - // Get a mixin by name - static getMixin(mixinName) { - // Get the mixin from mixins object - const mixin = OHIF.mixins[mixinName]; - - // Throw an error if the mixin does not exists - if (!mixin) { - throw new Error(`Mixin ${mixinName} not found.`); - } - - // Return the found mixin - return mixin; - } - -} - -// Store the Mixin class inside the shared OHIF object -OHIF.Mixin = Mixin; diff --git a/Packages/ohif-core/client/components/base/mixins/action.js b/Packages/ohif-core/client/components/base/mixins/action.js deleted file mode 100644 index fef0e96db..000000000 --- a/Packages/ohif-core/client/components/base/mixins/action.js +++ /dev/null @@ -1,72 +0,0 @@ -import { Template } from 'meteor/templating'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; - -/* - * action: controls an element that will trigger some form API's method - */ -OHIF.mixins.action = new OHIF.Mixin({ - dependencies: 'formItem', - composition: { - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Add the form-action identification class - component.$element.addClass('form-action'); - }, - - events: { - 'click .form-action'(event, instance) { - event.preventDefault(); - const component = instance.component; - - // Extract action, disabled state and params - const { action } = instance.data; - const params = instance.data.params ? instance.data.params : event; - - // Set the focus back to the input that triggered the click with Enter key - const $focused = $(':focus'); - const applyFocus = () => { - if ($focused[0] && event.currentTarget !== $focused[0]) { - setTimeout(() => $focused.focus()); - } - }; - - // Stop here if the component is disabled - if (component.$element.hasClass('disabled')) return; - - // Get the current component's API - const api = component.getApi(); - - if (typeof action === 'function') { - // Call the action if it's a function - component.actionResult = action.call(event.currentTarget, params, event); - } else if (!api || !action || typeof api[action] !== 'function') { - // Stop here if no API or action was defined - return true; - } else { - // Call the defined action function - component.actionResult = api[action].call(event.currentTarget, params, event); - } - - // Prepend a spinner into the action element content if it's a promise - if (component.actionResult instanceof Promise) { - const form = component.getForm(); - form.disable(true); - const $spinner = $(''); - component.$element.prepend($spinner); - const finishAction = () => { - $spinner.remove(); - form.disable(false); - applyFocus(); - }; - - component.actionResult.then(finishAction).catch(finishAction); - } else { - applyFocus(); - } - } - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/button.js b/Packages/ohif-core/client/components/base/mixins/button.js deleted file mode 100644 index 690c4ca65..000000000 --- a/Packages/ohif-core/client/components/base/mixins/button.js +++ /dev/null @@ -1,18 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; - -/* - * button: controls a button - */ -OHIF.mixins.button = new OHIF.Mixin({ - dependencies: 'formItem', - composition: { - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Set the element to be controlled - component.$element = instance.$('button').first(); - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/checkbox.js b/Packages/ohif-core/client/components/base/mixins/checkbox.js deleted file mode 100644 index 590145861..000000000 --- a/Packages/ohif-core/client/components/base/mixins/checkbox.js +++ /dev/null @@ -1,26 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; -import _ from 'underscore'; - -/* - * inputCheckbox: controls a checkbox input - */ -OHIF.mixins.checkbox = new OHIF.Mixin({ - dependencies: 'input', - composition: { - onCreated() { - const instance = Template.instance(); - const component = instance.component; - - // Get or set the checked state using jQuery's prop method - component.value = value => { - const isGet = _.isUndefined(value); - if (isGet) { - return component.parseData(component.$element.is(':checked')); - } - - component.$element.prop('checked', value).trigger('change'); - }; - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/component.js b/Packages/ohif-core/client/components/base/mixins/component.js deleted file mode 100644 index 0b9860b70..000000000 --- a/Packages/ohif-core/client/components/base/mixins/component.js +++ /dev/null @@ -1,10 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; - -/* - * component: base component structure - */ -OHIF.mixins.component = new OHIF.Mixin({ - composition: { - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/dropdown.js b/Packages/ohif-core/client/components/base/mixins/dropdown.js deleted file mode 100644 index 4d9981f7e..000000000 --- a/Packages/ohif-core/client/components/base/mixins/dropdown.js +++ /dev/null @@ -1,322 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import { Blaze } from 'meteor/blaze'; -import { ReactiveVar } from 'meteor/reactive-var'; -import $ from 'jquery'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -/* - * dropdown: controls a dropdown - */ -OHIF.mixins.dropdown = new OHIF.Mixin({ - dependencies: 'form', - composition: { - onRendered() { - const instance = Template.instance(); - const { event, centered, marginTop, $parentLi, reactiveClose } = instance.data.options; - // Get the dropdown element to enable position manipulation - const $dropdown = instance.$('.dropdown'); - const dropdown = $dropdown[0]; - const $dropdownMenu = $dropdown.children('.dropdown-menu'); - - // Get the timeout to dismiss the dropdown form - let { dismissTimeout } = instance.data.options; - if (_.isUndefined(dismissTimeout)) { - dismissTimeout = 500; - } - - // Set a opening state to the component - instance.opening = true; - - // Destroy the Blaze created view (either created with template calls or with renderWithData) - instance.destroyView = () => { - const destroyHandle = () => { - if (typeof instance.data.destroyView === 'function') { - instance.data.destroyView(); - } else { - Blaze.remove(instance.view); - } - }; - - const timeout = setTimeout(destroyHandle, dismissTimeout); - $dropdownMenu.one('transitionend', () => { - destroyHandle(); - clearTimeout(timeout); - }); - $dropdown.removeClass('open'); - }; - - // Destroy the view when the promise is fullfilled - instance.data.promise.then(instance.destroyView, instance.destroyView); - - // Close submenu if exists - instance.closeSubmenu = focusSelf => { - if (instance.reactiveClose) { - if (focusSelf) { - $(instance.lastSubmenu).focus(); - } - - instance.reactiveClose.set(true); - delete instance.reactiveClose; - delete instance.lastSubmenu; - } - }; - - // Close the dropdown resolving or rejecting the promise - instance.close = (isResolve, result) => { - const method = instance.data[isResolve ? 'promiseResolve' : 'promiseReject']; - const param = result instanceof Promise ? null : result; - method(param); - instance.closeSubmenu(false); - instance.closed = true; - }; - - // Close the dropdown if the reactiveClose suffered changes - if (reactiveClose) { - instance.autorun(() => { - const isClosed = reactiveClose.get(); - if (!isClosed) return; - instance.close(false); - }); - } - - // Stop here and destroy the view if no items was given - if (!instance.data.items.length) { - return instance.close(false); - } - - dropdown.oncontextmenu = () => false; - - const cssBefore = {}; - if (event) { - cssBefore.position = 'fixed'; - $dropdownMenu.bounded(); - } - - if (marginTop) { - cssBefore['margin-top'] = marginTop; - } - - $dropdownMenu.css(cssBefore); - - // Postpone visibility change to allow CSS transitions - Meteor.defer(() => { - // Show the dropdown and focus the first option - $dropdown.addClass('open').find('a:first').focus(); - - // Add a handler to change the opening state - $dropdownMenu.one('transitionend', event => { - instance.opening = false; - }); - - // Change the dropdown position if mouse event was given - if (event) { - const originalEventTouches = event.originalEvent && event.originalEvent.touches; - const position = { - left: 0, - top: 0 - }; - - if (originalEventTouches && originalEventTouches.length > 0) { - position.left = originalEventTouches[0].pageX; - position.top = originalEventTouches[0].pageY; - } else { - position.left = event.clientX; - position.top = event.clientY; - } - - if (centered) { - // Center the dropdown menu based on the event mouse position - position.left -= $dropdownMenu.outerWidth() / 2; - position.top -= $dropdownMenu.outerHeight() / 2; - } else if ($parentLi) { - // Change the dropdown menu position based on the parent menu item - const $parentDm = $parentLi.closest('.dropdown-menu'); - const dmWidth = $dropdownMenu.outerWidth(); - const pdmWidth = $parentDm.outerWidth(); - const pdmOffset = $parentDm.offset(); - const pliOffset = OHIF.ui.getOffset($parentLi[0]); - Object.assign(position, { - left: pdmWidth + pdmOffset.left, - top: pliOffset.top - }); - - // Check if the element position is going beyond the window right boundary - let rightToLeft = false; - if (position.left < pdmOffset.left + pdmWidth || position.left > document.body.clientWidth - dmWidth) { - position.left -= pdmWidth + $dropdownMenu.outerWidth(); - rightToLeft = true; - } - - const menuClass = rightToLeft ? 'origin-top-right' : 'origin-top-left'; - $dropdownMenu.addClass(menuClass); - } - - // Fix dropdown position if it is going outside the window boundaries - $dropdownMenu.css(position).trigger('spatialChanged'); - - // Check if scrolling will be needed - const isFixed = $dropdownMenu.css('position') === 'fixed'; - if (isFixed && $dropdownMenu.outerHeight() > window.innerHeight) { - $dropdownMenu.css({ - 'overflow-y': 'scroll', - 'max-height': window.innerHeight - }); - } - } - }); - }, - - events: { - 'click .form-action'(event, instance) { - const $target = $(event.currentTarget); - const isDisabled = $target.hasClass('disabled'); - - if (isDisabled) { - instance.close(false); - } else { - const component = $target.data('component'); - instance.close(true, component.actionResult); - } - }, - - 'mouseenter .form-action, openSubmenu .form-action'(event, instance) { - // Postpone the submenu opening if it's still being animated - if (instance.opening) { - instance.$('.dropdown-menu').one('transitionend', event => { - $(event.currentTarget).trigger('openSubmenu'); - }); - - return; - } - - // Stop here if dropdown is already closed or event was triggered in child elements - if (instance.closed || event.target !== event.currentTarget) return; - - // Close the submenu if a sibling element was hovered - if (instance.lastSubmenu && instance.lastSubmenu !== event.currentTarget) { - instance.closeSubmenu(!this.items); - } - - // Stop here if submenu is already opened for the current menu item - if (!this.items || instance.lastSubmenu === event.currentTarget) return; - - // Close the current opened submenu (if exists) in order to open another one - instance.closeSubmenu(!this.items); - - // Set the reactive closing elementcontroller and the last submenu element trigger - const reactiveClose = new ReactiveVar(false); - instance.reactiveClose = reactiveClose; - instance.lastSubmenu = event.currentTarget; - - // Get the triggering li element and render the submenu - const $parentLi = $(event.currentTarget).closest('li'); - OHIF.ui.showDropdown(this.items, { - event, - reactiveClose: instance.reactiveClose, - $parentLi, - parentInstance: instance, - dismissTimeout: instance.data.options && instance.data.options.dismissTimeout - }).then(instance.data.promiseResolve).catch(() => {}); - }, - - 'keydown .form-action'(event, instance) { - event.stopPropagation(); - const key = event.which; - const $target = $(event.currentTarget); - - // Allow navigation using DOWN and UP arrow keys - if (key === 38 || key === 40) { - const $parentLi = $target.closest('li'); - const $liList = $parentLi.parent().children(); - const index = $parentLi.index(); - - let $newLi; - if (key === 38) { - // Control the UP key - if (index === 0) { - $newLi = $liList.eq($liList.length - 1); - } else { - $newLi = $parentLi.prev(); - } - } else { - // Control the DOWN key - if (index === $liList.length - 1) { - $newLi = $liList.eq(0); - } else { - $newLi = $parentLi.next(); - } - } - - // Focus the link inside the new li element - event.preventDefault(); - $newLi.find('a:first').focus(); - return; - } - - // Close the submenu if LEFT, BACKSPACE or ESC key was pressed - const { parentInstance } = instance.data.options; - if (parentInstance && (key === 37 || key === 8 || key === 27)) { - event.preventDefault(); - return parentInstance.closeSubmenu(true); - } - - // Close the dropdown if there's no submenu open and ESC key was pressed - if (!parentInstance && key === 27) { - return instance.close(false); - } - - // Stop here if it's not a submenu trigger - if (!this.items) return; - - // Open the submenu if RIGHT, ENTER or SPACE key was pressed - if (key === 39 || key === 13 || key === 32) { - $target.trigger('openSubmenu'); - event.preventDefault(); - } - }, - - 'mousedown .dropdown'(event) { - // This is required to stop blur event which is fired before click event - // when a dropdown item is clicked, otherwise click event is not fired - event.stopPropagation(); - }, - - 'blur .dropdown'(event, instance) { - // Stop here if it's closed or if it's a submenu not being closed - if (instance.closed) return; - if (instance.reactiveClose && !instance.reactiveClose.get()) return; - - // Postpone the execution to enable getting the focused element - Meteor.defer(() => { - const $focus = $(':focus'); - - // Iterate over all parent dropdowns and check if one of them has the focus - let hasFocus = false; - let currentInstance = instance; - do { - if ($.contains(currentInstance.$('.dropdown')[0], $focus[0])) { - hasFocus = true; - break; - } - - if (!currentInstance.data.options.parentInstance) { - break; - } else { - currentInstance = currentInstance.data.options.parentInstance; - - // Close the current instance's submenu as it has no focus - currentInstance.closeSubmenu(false); - } - } while (currentInstance); - - // Close all dropdown levels if it lost the focus - if (!hasFocus) { - currentInstance.close(false); - } - }); - } - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/form.js b/Packages/ohif-core/client/components/base/mixins/form.js deleted file mode 100644 index aa74460e2..000000000 --- a/Packages/ohif-core/client/components/base/mixins/form.js +++ /dev/null @@ -1,108 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; -import { Tracker } from 'meteor/tracker'; -import { Spacebars } from 'meteor/spacebars'; -import _ from 'underscore'; -import $ from 'jquery'; - -/* - * form: controls a form and its registered inputs - */ -OHIF.mixins.form = new OHIF.Mixin({ - dependencies: 'group', - composition: { - onCreated() { - const instance = Template.instance(); - const component = instance.component; - - // Set the form identifier flag - component.isForm = true; - - // Set the form validated flag - component.isValidatedAlready = false; - - component.validationObserver = new Tracker.Dependency(); - - // Reset the pathKey - instance.data.pathKey = ''; - - // Debound the observer call to prevent tons of re-rendering - component.validationRan = _.throttle(() => { - // Enable reactivity by changing a Tracker.Dependency observer - component.validationObserver.changed(); - }, 200); - - // Change the validation function to focus the fields with error - const validateSelf = component.validate; - component.validate = () => { - // Call the original validation function - const validationResult = validateSelf(); - - // Change the form validated flag to true - component.isValidatedAlready = true; - - // Focus the first error field if some validation failed - if (component.schema && component.schema._invalidKeys.length) { - Tracker.afterFlush(() => instance.$('.state-error :input:first').focus()); - } - - return validationResult; - }; - }, - - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Set the component main and style elements - component.$style = component.$element = instance.$('form').first(); - - // Block page redirecting on submit - component.$element[0].onsubmit = () => false; - }, - - events: { - 'click .validation-error-container a'(event, instance) { - // Get the target key - const targetKey = $(event.currentTarget).attr('data-target'); - - // Focus the first input inside the element with error state - instance.$(`.state-error[data-key="${targetKey}"]`).find(':input:first').focus(); - } - }, - - helpers: { - validationErrors() { - const instance = Template.instance(); - const component = instance.component; - - // Create a dependency on child components validation - component.validationObserver.depend(); - - // Stop here if no schema was defined for the form - if (!component.schema) { - return; - } - - // Check if there were some validation errors - if (component.schema._invalidKeys.length) { - const result = []; - - // Iterate over each validation error and add to result - component.schema._invalidKeys.forEach(item => { - const label = component.schema._schema[item.name].label; - let message = component.schema.keyErrorMessage(item.name); - message = message.replace(label, `${label}`); - result.push({ - key: item.name, - message: Spacebars.SafeString(message) - }); - }); - - // Return the resulting validation errors - return result; - } - } - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/formItem.js b/Packages/ohif-core/client/components/base/mixins/formItem.js deleted file mode 100644 index ecd88afb2..000000000 --- a/Packages/ohif-core/client/components/base/mixins/formItem.js +++ /dev/null @@ -1,337 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; -import { Tracker } from 'meteor/tracker'; -import { Meteor } from 'meteor/meteor'; -import _ from 'underscore'; -import $ from 'jquery'; - -/* - * formItem: create a generic controller for form items - * It may be used to manage all components that belong to forms - */ -OHIF.mixins.formItem = new OHIF.Mixin({ - dependencies: 'schemaData', - composition: { - - onCreated() { - const instance = Template.instance(); - const component = instance.component; - - // Create a observer to monitor changed values - component.changeObserver = new Tracker.Dependency(); - - // Register the component in the parent component - component.registerSelf(); - - // Declare the component elements that will be manipulated - component.$element = $(); - component.$style = $(); - component.$wrapper = $(); - - // Get or set the component's value using jQuery's val method - component.value = value => { - const isGet = _.isUndefined(value); - if (isGet) { - return component.parseData(component.$element.val()); - } - - // Deferring the `change` event because it was being triggered before - // formItem.onMixins execution when a defaultValue was specified. In - // this case $elem.data('component') code from the event handler was - // returning `undefined` and breaking the app - Meteor.defer(() => { - component.$element.val(value).trigger('change'); - }); - }; - - // Disable or enable the component - component.disable = isDisable => { - component.$element.prop('disabled', !!isDisable); - }; - - // Set or unset component's readonly property - component.readonly = isReadonly => { - component.$element.prop('readonly', !!isReadonly); - }; - - // Show or hide the component - component.show = isShow => { - const method = isShow ? 'show' : 'hide'; - component.$wrapper[method](); - }; - - // Check if the focus is inside this element - component.hasFocus = () => { - // Get the focused element - const focused = $(':focus')[0]; - - // Check if the focused element is inside the component - const contains = $.contains(component.$wrapper[0], focused); - const isEqual = component.$wrapper[0] === focused; - - // Return true if he component has the focus - return contains || isEqual; - }; - - // Add or remove a state from the component - component.state = (state, flag) => { - component.$wrapper.toggleClass(`state-${state}`, !!flag); - }; - - // Set the component in error state and display the error message - component.error = errorMessage => { - // Set the component error state - component.state('error', !!errorMessage); - - // Set or remove the error message - if (errorMessage) { - component.$wrapper.attr('data-error', errorMessage); - } else { - component.$wrapper.removeAttr('data-error', errorMessage); - } - }; - - // Toggle the tooltip over the component - component.toggleTooltip = (isShow, message) => { - if (isShow && message) { - const tooltipId = component.$wrapper.attr('aria-describedby'); - const $tooltip = $(document.getElementById(tooltipId)); - if ($tooltip.length) { - // Change the message if the tooltip is already created - $tooltip.find('.tooltip-inner').text(message); - } else { - // Destroy the tooltip if already created, creating it again - component.$wrapper.tooltip('destroy').tooltip({ - trigger: 'manual', - title: message - }).tooltip('show'); - } - } else { - // Destroy the tooltip - component.$wrapper.tooltip('destroy'); - } - }; - - // Toggle a state message as a tooltip over the component - component.toggleMessage = isShow => { - // Check if the action is to hide - if (!isShow) { - Meteor.setTimeout(() => { - // Check if the component has the focus - if (component.hasFocus()) { - // Prevent the tooltip from being hidden - return; - } - - // Hide the tooltip - component.toggleTooltip(false); - }, 100); - return; - } - - // Check for error state and message - const errorMessage = component.$wrapper.attr('data-error'); - if (errorMessage) { - // Show the tooltip with the error message - component.toggleTooltip(true, errorMessage); - } - }; - - // Search for the parent form component - component.getForm = () => { - let currentComponent = component; - while (currentComponent) { - currentComponent = currentComponent.parent; - if (currentComponent && currentComponent.isForm) { - return currentComponent; - } - } - }; - - // Get the current component API - component.getApi = () => { - const api = instance.data.api; - - // Check if the API was not given - if (!api) { - // Stop here if the component is form and API was not given - if (component.isForm) { - return; - } - - // Get the current component's form - const form = component.getForm(); - - // Stop here if the component has no form - if (!form) { - return; - } - - return form.getApi(); - } - - // Return the given API - return api; - }; - - // Check if the component value is valid in its form's schema - component.validate = () => { - // Get the component's form - const form = component.getForm(); - - // Get the form's data schema - const schema = form && form.schema; - - // Get the current component's key - const key = instance.data.pathKey; - - // Return true if validation is not needed - if (!key || !schema || !component.$wrapper.is(':visible')) { - return true; - } - - // Create the data document for validation - const document = OHIF.object.getNestedObject({ - [key]: component.value() - }); - - // Get the validation result - const validationResult = schema.validateOne(document, key); - - // Notify the form that the validation ran - form.validationRan(); - - // Check if the document validation failed - if (!validationResult) { - // Set the component in error state and display the message - component.error(schema.keyErrorMessage(key)); - - // Return false for validation - return false; - } - - // Remove the component error state and message - component.error(false); - - // Return true for validation - return true; - }; - - component.depend = () => { - return component.changeObserver.depend(); - }; - - // Click the first submit (or first button if submit not found) button on closest form - component.triggerFormMainButton = () => { - const $form = component.$element.closest('form'); - let $formButton = $form.find('button[type=submit]:first'); - if (!$formButton.length) { - $formButton = $form.find('button:first'); - } - - $formButton.click(); - }; - - }, - - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Set the element to be controlled - component.$element = instance.$(':input').first(); - - // Set the most outer wrapper element - component.$wrapper = instance.wrapper.$('*').first(); - - // Add the pathKey to the wrapper element - component.$wrapper.attr('data-key', instance.data.pathKey); - - // Get the component's form - const form = component.getForm(); - - // Observer for changes and revalidate the component - instance.autorun(computation => { - component.changeObserver.depend(); - - // Stop here if it is the first run - if (computation.firstRun) return; - - // Revalidate the component if form is already validated - if (form && form.isValidatedAlready) { - component.validate(); - } - }); - }, - - onDestroyed() { - const instance = Template.instance(); - const component = instance.component; - - // Get the component's form for further use - const form = component.getForm(); - - // Unregister the component in the parent component - component.unregisterSelf(); - - // Remove the component tooltip, error state and message - component.error(false); - component.toggleTooltip(false); - - // Revalidate the form to remove this component from validation results - if (form && form.isValidatedAlready) { - form.validate(); - } - }, - - onMixins() { - const instance = Template.instance(); - const component = instance.component; - - // If no style element was defined, set it as the element itself - if (!component.$style.length) { - component.$style = component.$element; - } - - // Set the component in element and wrapper jQuery data - component.$element.data('component', component); - component.$wrapper.data('component', component); - }, - - events: { - - // Handle the change event for the component - change(event, instance) { - const component = instance.component; - - // Prevent execution on upper components - if (event.currentTarget === component.$element[0]) { - // Enable reactivity by changing a Tracker.Dependency observer - component.changeObserver.changed(); - } - }, - - focus(event, instance) { - const component = instance.component; - const isGroupOrCustomFocus = component.isGroup || component.isCustomFocus; - const isSameTarget = event.target === event.currentTarget; - if (!isGroupOrCustomFocus && isSameTarget) { - // Check for state messages and show it - component.toggleMessage(true); - } - }, - - blur(event, instance) { - const component = instance.component; - const isGroupOrCustomFocus = component.isGroup || component.isCustomFocus; - const isSameTarget = event.target === event.currentTarget; - if (!isGroupOrCustomFocus && isSameTarget) { - // Check for state messages and show it - component.toggleMessage(false); - } - } - - } - - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/group.js b/Packages/ohif-core/client/components/base/mixins/group.js deleted file mode 100644 index 8d248da52..000000000 --- a/Packages/ohif-core/client/components/base/mixins/group.js +++ /dev/null @@ -1,169 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; -import _ from 'underscore'; - -/* - * group: controls a group and its registered items - */ -OHIF.mixins.group = new OHIF.Mixin({ - dependencies: 'formItem', - composition: { - onCreated() { - const instance = Template.instance(); - const component = instance.component; - - // Set the group identifier flag - component.isGroup = true; - - // Run this computation every time the schema property is changed - instance.autorun(() => { - let schema = instance.data.schema; - - // Check if the schema is reactive - if (schema instanceof ReactiveVar) { - // Register a dependency on schema property - schema = schema.get(); - } - - // Set the form's data schema - component.schema = schema && schema.newContext(); - }); - - // Get or set the child components values - component.value = value => { - const isGet = _.isUndefined(value); - const isArray = instance.data.arrayValues; - - // Create the result data as array or object - const result = isArray ? [] : {}; - - // Get the group current value and return it - if (isGet) { - // Iterate over each registered item and extract its value - component.registeredItems.forEach(child => { - // Check if it is an array or an object group - if (isArray) { - // Get the mixins array - const mixins = child.templateInstance.data.mixins.split(' '); - - // Prevent reading action components - if (mixins.indexOf('action') > -1) return; - - // Push the item value to the result array - result.push(child.value()); - } else { - // Get the item key - const key = child.templateInstance.data.key; - - //Check if a key is set for the item - if (key) { - // Add the item value to the result object - result[key] = child.value(); - } - } - }); - - // Return the resulting data as array or object - return result; - } - - // Get the group current value - const groupValue = typeof value === 'object' ? value : result; - - // Stop here if there is no value defined for this group - if (!groupValue) { - return; - } - - // Iterate over each registered item and set its value - let i = 0; - component.registeredItems.forEach(child => { - const mixins = child.templateInstance.data.mixins.split(' '); - - // Prevent reading action components - if (isArray && mixins.indexOf('action') > -1) return; - - const key = isArray ? i : child.templateInstance.data.key; - const childValue = _.isUndefined(groupValue[key]) ? null : groupValue[key]; - child.value(childValue); - i++; - }); - - // Trigger the change event after setting the new value - component.$element.trigger('change'); - }; - - // Get a registered item in form by its key - component.item = itemKey => { - let found; - - // Iterate over each registered form item - component.registeredItems.forEach(child => { - const key = child.templateInstance.data.key; - - // Change the found item if current key is the same as given - if (key === itemKey) { - found = child; - } - }); - - // Return the found item or undefined if it was not found - return found; - }; - - // Check if the form data is valid in its schema - const validateSelf = component.validate; - component.validate = () => { - // Assume validation result as true - let result = true; - - // Return true if there's no data schema defined - if (component.isForm && !component.schema) { - return result; - } - - // Reset the validation - const schema = component.isForm ? component.schema : component.getForm().schema; - schema.resetValidation(); - - // Validate the component itself if it has a key - if (instance.data.pathKey && !validateSelf()) { - result = false; - } - - // Iterate over each registered form item and validate it - component.registeredItems.forEach(child => { - const key = child.templateInstance.data.key; - - // Change result to false if any form item is invalid - if ((key || instance.data.arrayValues) && !child.validate()) { - result = false; - } - }); - - // Return the validation result - return result; - }; - - // Disable or enable the component - component.disable = isDisable => { - component.registeredItems.forEach(child => child.disable(isDisable)); - }; - - // Set or unset component's readonly property - component.readonly = isReadonly => { - component.registeredItems.forEach(child => child.readonly(isReadonly)); - }; - - }, - - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Set the element to be controlled - component.$element = instance.$('.component-group').first(); - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/groupRadio.js b/Packages/ohif-core/client/components/base/mixins/groupRadio.js deleted file mode 100644 index 760696707..000000000 --- a/Packages/ohif-core/client/components/base/mixins/groupRadio.js +++ /dev/null @@ -1,32 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; -import _ from 'underscore'; -import $ from 'jquery'; - -/* - * groupRadio: controls all the radio inputs inside the group - */ -OHIF.mixins.groupRadio = new OHIF.Mixin({ - dependencies: 'group', - composition: { - - onCreated() { - const instance = Template.instance(); - const component = instance.component; - - // Get the selected radio's value or select a radio based on value - component.value = value => { - const isGet = _.isUndefined(value); - const elements = []; - component.registeredItems.forEach(child => elements.push(child.$element[0])); - const $elements = $(elements); - if (isGet) { - return component.parseData($elements.filter(':checked').val()); - } - - $elements.filter(`[value='${value}']`).prop('checked', true).trigger('change'); - }; - } - - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/input.js b/Packages/ohif-core/client/components/base/mixins/input.js deleted file mode 100644 index cc4d41aba..000000000 --- a/Packages/ohif-core/client/components/base/mixins/input.js +++ /dev/null @@ -1,18 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; - -/* - * input: controls a basic input - */ -OHIF.mixins.input = new OHIF.Mixin({ - dependencies: 'formItem', - composition: { - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Set the element to be controlled - component.$element = instance.$('input').first(); - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/link.js b/Packages/ohif-core/client/components/base/mixins/link.js deleted file mode 100644 index f9e34c69e..000000000 --- a/Packages/ohif-core/client/components/base/mixins/link.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; - -/* - * link: controls a link - */ -OHIF.mixins.link = new OHIF.Mixin({ - dependencies: 'formItem', - composition: { - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Set the element to be controlled - component.$element = instance.$('a').first(); - }, - - events: { - 'click a'(event, instance) { - if (instance.data.action) { - event.preventDefault(); - } - } - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/popover.js b/Packages/ohif-core/client/components/base/mixins/popover.js deleted file mode 100644 index 8c65b6caf..000000000 --- a/Packages/ohif-core/client/components/base/mixins/popover.js +++ /dev/null @@ -1,40 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; - -/* - * popover: controls a popover - */ -OHIF.mixins.popover = new OHIF.Mixin({ - dependencies: 'form', - composition: { - onRendered() { - const instance = Template.instance(); - instance.$form = instance.$('form').first(); - instance.$form.find(':input:first').focus(); - }, - - events: { - 'blur form'(event, instance) { - Meteor.defer(() => { - const $focus = $(':focus'); - if (!$.contains(instance.$form[0], $focus[0])) { - instance.data.promiseReject(); - } - }); - }, - - 'click .btn-cancel'(event, instance) { - event.stopPropagation(); - instance.data.promiseReject(); - }, - - 'click .btn-confirm'(event, instance) { - event.stopPropagation(); - const form = instance.$('form').data('component'); - instance.data.promiseResolve(form.value()); - } - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/schemaData.js b/Packages/ohif-core/client/components/base/mixins/schemaData.js deleted file mode 100644 index 40cde1d7a..000000000 --- a/Packages/ohif-core/client/components/base/mixins/schemaData.js +++ /dev/null @@ -1,189 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Blaze } from 'meteor/blaze'; -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Tracker } from 'meteor/tracker'; -import _ from 'underscore'; - -// Helper function to get the component's current schema -const getCurrentSchemaDefs = (parentComponent, key) => { - // Get the parent component schema - let schema = parentComponent && parentComponent.schema; - let schemaComponentHolder = parentComponent; - - // Try to get the form schema if it was not found - if (parentComponent && !schema) { - const form = parentComponent.getForm(); - schema = form && form.schema; - schemaComponentHolder = form; - } - - // Stop here if there's no key or schema defined - if (!key || !schema) { - return { schemaComponentHolder }; - } - - // Get the current schema data using component's key - const currentSchema = _.clone(schema._schema[key]); - - // Stop here if no schema was found for the given key - if (!currentSchema) { - return { schemaComponentHolder }; - } - - // Merge the sub-schema properties if it's an array - if (Array.isArray(currentSchema.type())) { - _.extend(currentSchema, schema._schema[key + '.$']); - } - - // Return the component's schema definitions - return { - currentSchema, - schemaComponentHolder - }; -}; - -/* - * schemaData: change the component data based on its form's schema data - */ -OHIF.mixins.schemaData = new OHIF.Mixin({ - dependencies: 'component', - composition: { - - onData() { - // Get the current template data - const data = Template.currentData(); - - // Get the parent component - const parent = OHIF.blaze.getParentComponent(Blaze.currentView); - - // Get he parent component key - const parentKey = parent && parent.templateInstance.data.pathKey; - - // Check if the parent is an array group - const isParentArray = parent && parent.templateInstance.data.arrayValues; - - // Set the path key for this component - data.pathKey = data.key || (isParentArray ? '$' : ''); - if (data.pathKey && typeof parentKey === 'string') { - const prefix = parentKey ? `${parentKey}.` : ''; - data.pathKey = `${prefix}${data.pathKey}`; - } - - // Get the current schema data using component's key - const { currentSchema } = getCurrentSchemaDefs(parent, data.pathKey); - - // Stop here if there's no schema data for current key - if (!currentSchema) { - return; - } - - // Use schema's label if it was not defined - if (!data.label) { - data.label = new ReactiveVar(currentSchema.label); - } - - // Set the min value - if (_.isUndefined(data.min) && currentSchema.min) { - data.min = currentSchema.min; - } - - // Set the max value - if (_.isUndefined(data.max) && currentSchema.max) { - data.max = currentSchema.max; - } - - // Set the emptyOption data attribute if given on schema - if (currentSchema.emptyOption) { - data.emptyOption = currentSchema.emptyOption; - } - - // Fill the items if it's an array schema - if (!data.items && Array.isArray(currentSchema.allowedValues)) { - data.items = data.items instanceof ReactiveVar ? data.items : new ReactiveVar(); - - Tracker.autorun(() => { - const schemaDefs = getCurrentSchemaDefs(parent, data.pathKey); - - // Check if schema is reactive and add reactivity to this function if so - const componentHolder = schemaDefs.schemaComponentHolder; - if (componentHolder.templateInstance.data.schema instanceof ReactiveVar) { - componentHolder.templateInstance.data.schema.dep.depend(); - } - - // Get the values and labels arrays from schema - const values = schemaDefs.currentSchema.allowedValues; - const labels = schemaDefs.currentSchema.valuesLabels || []; - - // Initialize the items array - const items = []; - - // Iterate the allowed values array - for (let i = 0; i < values.length; i++) { - // Push the current item to the items array - items.push({ - value: values[i], - label: labels[i] || values[i] - }); - } - - // Add the items to a reactive instance - data.items.set(items); - }); - } - }, - - onCreated() { - const instance = Template.instance(); - const component = instance.component; - - // Create a data parser according to current schema key - component.parseData = value => { - // Get the current schema data using component's key - const { currentSchema } = getCurrentSchemaDefs(component.parent, instance.data.pathKey); - const { dataType } = instance.data; - - // Stop here if there's no schema data for current key or no dataType defined - if (!currentSchema && !dataType) { - return value; - } - - // Get the schema type - const schemaType = currentSchema && currentSchema.type; - - // Check if the type is Number - if (schemaType === Number || dataType === 'Number') { - return parseFloat(value); - } - - // Check if the type is Boolean - if (schemaType === Boolean || dataType === 'Boolean') { - return !!value; - } - - // Return the original value if none of the checks matched - return value; - }; - }, - - onMixins() { - const instance = Template.instance(); - const component = instance.component; - - // Get the current schema data using component's key - const { currentSchema } = getCurrentSchemaDefs(component.parent, instance.data.pathKey); - - // Stop here if there's no schema data for current key - if (!currentSchema) { - return; - } - - // Fill the component with its default value after rendering - if (!_.isUndefined(currentSchema.defaultValue)) { - component.defaultValue = currentSchema.defaultValue; - component.value(currentSchema.defaultValue); - } - } - - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/select.js b/Packages/ohif-core/client/components/base/mixins/select.js deleted file mode 100644 index ea5383faf..000000000 --- a/Packages/ohif-core/client/components/base/mixins/select.js +++ /dev/null @@ -1,18 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; - -/* - * input: controls a basic select - */ -OHIF.mixins.select = new OHIF.Mixin({ - dependencies: 'formItem', - composition: { - onRendered() { - const instance = Template.instance(); - const component = instance.component; - - // Set the element to be controlled - component.$element = instance.$('select').first(); - } - } -}); diff --git a/Packages/ohif-core/client/components/base/mixins/select2.js b/Packages/ohif-core/client/components/base/mixins/select2.js deleted file mode 100644 index 9e45d869e..000000000 --- a/Packages/ohif-core/client/components/base/mixins/select2.js +++ /dev/null @@ -1,229 +0,0 @@ -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { Tracker } from 'meteor/tracker'; -import _ from 'underscore'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; - -/* - * input: controls a select2 component - */ -OHIF.mixins.select2 = new OHIF.Mixin({ - dependencies: 'select', - composition: { - onCreated() { - const instance = Template.instance(); - const { component, data } = instance; - - // Controls select2 initialization - instance.isInitialized = false; - - // Set the custom focus flag - component.isCustomFocus = true; - - const valueMethod = component.value; - component.value = value => { - if (_.isUndefined(value) && !instance.isInitialized) { - if (!_.isUndefined(instance.data.value)) return instance.data.value; - if (!_.isUndefined(component.defaultValue)) return component.defaultValue; - return; - } - - return valueMethod(value); - }; - - // Utility function to get the dropdown jQuery element - instance.getDropdownContainerElement = () => { - const $select2 = component.$element.nextAll('.select2:first'); - const containerId = $select2.find('.select2-selection').attr('aria-owns'); - return $(`#${containerId}`).closest('.select2-container'); - }; - - // Check if this select will include a placeholder - const placeholder = data.options && data.options.placeholder; - if (placeholder) { - instance.autorun(() => { - // Get the option items - let items = data.items; - - // Check if the items are reactive and get them if true - const isReactive = items instanceof ReactiveVar; - if (isReactive) { - items = items.get(); - } - - // Check if there is already an empty option on items list - // Note: If this is a multi-select input. Do not add a placeholder - const isMultiple = instance.data.options && instance.data.options.multiple; - if (!_.findWhere(items, { value: '' }) && isMultiple === false) { - // Clone the current items - const newItems = _.clone(items) || []; - newItems.unshift({ - label: placeholder, - value: '' - }); - - // Set the new items list including the empty option - if (isReactive) { - data.items.set(newItems); - } else { - data.items = newItems; - } - } - }); - } - }, - - onRendered() { - const instance = Template.instance(); - const { component, data } = instance; - - // Destroy and re-create the select2 instance - instance.rebuildSelect2 = () => { - // Destroy the select2 instance if exists and re-create it - if (component.select2Instance) { - component.select2Instance.destroy(); - } - - // Clone the options and check if the select2 should be initialized inside a modal - const options = _.clone(data.options); - const $closestModal = component.$element.closest('.modal'); - if ($closestModal.length) { - options.dropdownParent = $closestModal; - } - - // Apply the select2 to the component - component.$element.select2(options); - - // Store the select2 instance to allow its further destruction - component.select2Instance = component.$element.data('select2'); - - // Get the focusable elements - const elements = []; - const $select2 = component.$element.nextAll('.select2:first'); - const $select2Selection = $select2.find('.select2-selection'); - elements.push(component.$element[0]); - elements.push($select2Selection[0]); - - // Attach focus and blur handlers to focusable elements - $(elements).on('focus', event => { - instance.isFocused = true; - if (event.target === event.currentTarget) { - // Show the state message on elements focus - component.toggleMessage(true); - } - }).on('blur', event => { - instance.isFocused = false; - if (event.target === event.currentTarget) { - // Hide the state message on elements blur - component.toggleMessage(false); - } - }); - - // Redirect keydown events from input to the select2 selection handler - component.$element.on('keydown ', event => { - event.preventDefault(); - $select2.find('.select2-selection').trigger(event); - }); - - // Keep focus on element if ESC was pressed - $select2.on('keydown ', event => { - if (event.which === 27) { - instance.component.$element.focus(); - } - }); - - // Handle dropdown opening when focusing the selection element - $select2Selection.on('keydown ', event => { - const skipKeys = new Set([8, 9, 12, 16, 17, 18, 20, 27, 46, 91, 93]); - const functionKeysRegex = /F[0-9]([0-9])?$/; - const isFunctionKey = functionKeysRegex.test(event.key); - if (skipKeys.has(event.which) || isFunctionKey) { - return; - } - - event.preventDefault(); - event.stopPropagation(); - - // Open the select2 dropdown - instance.component.$element.select2('open'); - - // Check if the pressed key will produce a character - const searchSelector = '.select2-search__field'; - const $search = component.select2Instance.$dropdown.find(searchSelector); - const isChar = OHIF.ui.isCharacterKeyPress(event); - const char = event.key; - if ($search.length && isChar && char.length === 1) { - // Event needs to be triggered twice to work properly with this plugin - $search.val(char).trigger('input').trigger('input'); - } - }); - - // Set select2 as initialized - instance.isInitialized = true; - }; - - instance.autorun(() => { - // Run this computation every time the reactive items suffer any changes - const isReactive = data.items instanceof ReactiveVar; - if (isReactive) { - data.items.dep.depend(); - } - - if (isReactive) { - // Keep the current value of the component - const currentValue = component.value(); - const wasFocused = instance.isFocused; - - Tracker.afterFlush(() => { - component.$element.val(currentValue); - instance.rebuildSelect2(); - - if (wasFocused) { - component.$element.focus(); - } - }); - } else { - instance.rebuildSelect2(); - } - }); - }, - - events: { - // Focus element when selecting a value - 'select2:select'(event, instance) { - instance.component.$element.focus(); - }, - - // Focus the element when closing the dropdown container using ESC key - 'select2:open'(event, instance) { - const { minimumResultsForSearch } = instance.data.options; - if (minimumResultsForSearch === Infinity || minimumResultsForSearch === -1) return; - const $container = instance.getDropdownContainerElement(); - - if (!instance.data.wrapText) { - $container.addClass('select2-container-nowrap'); - } - - const $searchInput = $container.find('.select2-search__field'); - $searchInput.on('keydown.focusOnFinish', event => { - const keys = new Set([9, 13, 27]); - if (keys.has(event.which)) { - $searchInput.off('keydown.focusOnFinish'); - instance.component.$element.focus(); - } - }); - } - }, - - onDestroyed() { - const instance = Template.instance(); - const { component } = instance; - - // Destroy the select2 instance to remove unwanted DOM elements - if (component.select2Instance) { - component.select2Instance.destroy(); - } - } - } -}); diff --git a/Packages/ohif-core/client/components/base/section/section.html b/Packages/ohif-core/client/components/base/section/section.html deleted file mode 100644 index 51fc98269..000000000 --- a/Packages/ohif-core/client/components/base/section/section.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/section/section.js b/Packages/ohif-core/client/components/base/section/section.js deleted file mode 100644 index b8f86af0f..000000000 --- a/Packages/ohif-core/client/components/base/section/section.js +++ /dev/null @@ -1,61 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Tracker } from 'meteor/tracker'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; - -Template.section.onCreated(() => { - const instance = Template.instance(); - - // Create the render function and section data as reactive objects - instance.renderFunction = new ReactiveVar(null); - instance.sectionData = new ReactiveVar(null); - - // Get the section name - const sectionName = instance.data; - - // Stop here if no section name was defined - if (!sectionName) { - return; - } - - // Get the content block - const templateContentBlock = instance.view.templateContentBlock; - - // Get the parent template view of this section block - let currentView = OHIF.blaze.getParentTemplateView(instance.view); - - // Check if it is defining or printing the section content - if (templateContentBlock) { - // Define a section map for template's view if none was yet set - if (!currentView._sectionMap) { - currentView._sectionMap = new Map(); - } - - // Define the content - currentView._sectionMap.set(sectionName, { - data: Object.assign({}, currentView._templateInstance.data), - renderFunction: templateContentBlock.renderFunction - }); - } else { - // Wait for re-rendering and print the section content - Tracker.afterFlush(() => { - // Get the defined section's content - const section = OHIF.blaze.getSectionContent(currentView, sectionName); - - // Stop here if the section content is not defined - if (!section) { - return; - } - - // Set the section data on its respective reactive object - instance.sectionData.set(section.data); - - // Set the render function on its respective reactive object - instance.renderFunction.set(new Template(section.renderFunction)); - }); - } -}); - -Template.registerHelper('hasSection', sectionName => { - return !!OHIF.blaze.getSectionContent(Template.instance().view, sectionName); -}); diff --git a/Packages/ohif-core/client/components/base/template.js b/Packages/ohif-core/client/components/base/template.js deleted file mode 100644 index ff7ad486c..000000000 --- a/Packages/ohif-core/client/components/base/template.js +++ /dev/null @@ -1,112 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Blaze } from 'meteor/blaze'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -// Create a new custom template for the base component -Template.baseComponent = new Template('baseComponent', () => {}); - -// Inject some custom behaviors in the view's construction function -Template.baseComponent.constructView = function(contentFunc, elseFunc) { - // Get the data passed to the template - const data = Template.currentData(); - - if (!data) { - return; - } - - // Check the base template. If it's not informed set as the custom base - data.base || (data.base = 'baseCustom'); - - // Get the base template object - const baseTemplate = Template[data.base]; - - // Throw an error if the base template does not exists - if (!baseTemplate) { - throw new Error(`Template ${data.base} not found.`); - } - - // Declare the template object and name it as base name + 'Component' - const template = OHIF.blaze.cloneTemplate(baseTemplate, data.base + 'Component'); - - // Extract the render function from the base template - template.renderFunction = baseTemplate.renderFunction; - - // Init the data manipulation mixins - OHIF.Mixin.initData(data); - - // Create and fill a list of wrappers that will enclose the component - const wrappers = []; - if (data.wrappers) { - const wrappersList = data.wrappers.split(' '); - _.each(wrappersList, wrapper => wrapper && wrappers.push(wrapper)); - } - - // Declare a variable to store the wrapper instances that will be rendered - const wrapperInstances = []; - - // Declare the content function to render the component - let contentFunction = () => { - // Create the most inner content function - const innerContentFunction = () => { - // Return the view instance - return template.constructView(contentFunc, elseFunc); - }; - - // Assign properties to all wrappers after template's creation - template.onCreated(() => { - const instance = Template.instance(); - - // create the base structure to aplly specific component mixins - instance.component = new OHIF.Component(instance); - - // Assign the template most outer wrapper - instance.wrapper = wrapperInstances[0] || instance; - - // Iterate over all wrappers and assign the component to them - wrapperInstances.forEach(wrapperInstance => { - wrapperInstance.component = instance.component; - }); - }); - - // Apply the mixins to the component - OHIF.Mixin.initAll(template, data); - - // Return the recursive function for wrappers - return Blaze.With(data, innerContentFunction); - }; - - let wrapper; - while (wrapper = wrappers.shift()) { - // Get the wrapper template - const wrapperTemplate = Template[wrapper]; - - // Throw an error if the wrapper template does not exists - if (!wrapperTemplate) { - throw new Error(`Template ${wrapper} not found.`); - } - - // Clone the wrapper template to avoid assigning duplicated handlers - const currentTemplate = OHIF.blaze.cloneTemplate(wrapperTemplate); - - // Store the child content function to render it inside the wrapper - const childContentFunction = contentFunction; - - // Create a function that will enable the recursion for wrappers - const enclosingContentFunction = () => { - // Add the current wrapper's instance to the wrapper instances list - currentTemplate.onCreated(() => wrapperInstances.push(Template.instance())); - - // Return the wrapper view instance with its child as content - return currentTemplate.constructView(childContentFunction, elseFunc); - }; - - // Replace the content function enclosing it recursively - contentFunction = () => { - return Blaze.With(data, enclosingContentFunction); - }; - - } - - return contentFunction(contentFunc, elseFunc); -}; diff --git a/Packages/ohif-core/client/components/base/templates/button.html b/Packages/ohif-core/client/components/base/templates/button.html deleted file mode 100644 index 592881fb6..000000000 --- a/Packages/ohif-core/client/components/base/templates/button.html +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/templates/custom.html b/Packages/ohif-core/client/components/base/templates/custom.html deleted file mode 100644 index 302917fd3..000000000 --- a/Packages/ohif-core/client/components/base/templates/custom.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/templates/div.html b/Packages/ohif-core/client/components/base/templates/div.html deleted file mode 100644 index a39733ce3..000000000 --- a/Packages/ohif-core/client/components/base/templates/div.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/templates/form.html b/Packages/ohif-core/client/components/base/templates/form.html deleted file mode 100644 index ca7c66c00..000000000 --- a/Packages/ohif-core/client/components/base/templates/form.html +++ /dev/null @@ -1,23 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/templates/input.html b/Packages/ohif-core/client/components/base/templates/input.html deleted file mode 100644 index a707d3b41..000000000 --- a/Packages/ohif-core/client/components/base/templates/input.html +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/templates/link.html b/Packages/ohif-core/client/components/base/templates/link.html deleted file mode 100644 index e08fac065..000000000 --- a/Packages/ohif-core/client/components/base/templates/link.html +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/templates/select.html b/Packages/ohif-core/client/components/base/templates/select.html deleted file mode 100644 index 139965e38..000000000 --- a/Packages/ohif-core/client/components/base/templates/select.html +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/Packages/ohif-core/client/components/base/templates/tr.html b/Packages/ohif-core/client/components/base/templates/tr.html deleted file mode 100644 index 003ae583a..000000000 --- a/Packages/ohif-core/client/components/base/templates/tr.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/wrappers/label.html b/Packages/ohif-core/client/components/base/wrappers/label.html deleted file mode 100644 index 10f5f9e4d..000000000 --- a/Packages/ohif-core/client/components/base/wrappers/label.html +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/base/wrappers/labelContent.html b/Packages/ohif-core/client/components/base/wrappers/labelContent.html deleted file mode 100644 index f4feb0f86..000000000 --- a/Packages/ohif-core/client/components/base/wrappers/labelContent.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/bootstrap.styl b/Packages/ohif-core/client/components/bootstrap/dialog/bootstrap.styl deleted file mode 100644 index 695ad3731..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/bootstrap.styl +++ /dev/null @@ -1,14 +0,0 @@ -.modal - .modal-header:empty, .modal-footer:empty - display: none - - .modal-blank - - .modal-content - border: 0 - - .modal-header, .modal-footer - display: none - - .modal-body - padding: 0 diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/confirm.html b/Packages/ohif-core/client/components/bootstrap/dialog/confirm.html deleted file mode 100644 index 57baa6518..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/confirm.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/form.html b/Packages/ohif-core/client/components/bootstrap/dialog/form.html deleted file mode 100644 index 5ece500d6..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/form.html +++ /dev/null @@ -1,45 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/form.js b/Packages/ohif-core/client/components/bootstrap/dialog/form.js deleted file mode 100644 index e7b2fd6b4..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/form.js +++ /dev/null @@ -1,114 +0,0 @@ -import { Template } from 'meteor/templating'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -Template.dialogForm.onCreated(() => { - const instance = Template.instance(); - - const dismissModal = (promiseFunction, param) => { - // Hide the modal, removing the backdrop - instance.$('.modal').one('hidden.bs.modal', event => { - // Resolve or reject the promise with the given parameter - promiseFunction(param); - }).modal('hide'); - }; - - instance.api = { - - confirm() { - // Check if the form has valid data - const form = instance.$('form').data('component'); - if (!form.validate()) { - return; - } - - const formData = form.value(); - const dismiss = param => dismissModal(instance.data.promiseResolve, param); - - if (_.isFunction(instance.data.confirmCallback)) { - const result = instance.data.confirmCallback(formData); - if (result instanceof Promise) { - return result.then(dismiss); - } else { - return dismiss(result); - } - } - - dismiss(formData); - }, - - cancel() { - const dismiss = param => dismissModal(instance.data.promiseReject, param); - - if (_.isFunction(instance.data.cancelCallback)) { - const result = instance.data.cancelCallback(); - if (result instanceof Promise) { - return result.then(dismiss); - } else { - return dismiss(result); - } - } - - dismiss(); - } - - }; -}); - -Template.dialogForm.onRendered(() => { - const instance = Template.instance(); - - // Allow options ovewrite - const modalOptions = _.extend({ - backdrop: 'static', - keyboard: false - }, instance.data.modalOptions); - - const $modal = instance.$('.modal'); - - // Create the bootstrap modal - $modal.modal(modalOptions); - - // Check if dialog will be repositioned - let position = instance.data.position; - const event = instance.data.event; - if (!position && event && event.clientX) { - position = { - x: event.clientX, - y: event.clientY - }; - } - - // Reposition dialog if position object was filled - if (position) { - OHIF.ui.repositionDialog($modal, position.x, position.y); - } -}); - -Template.dialogForm.events({ - keydown(event) { - const instance = Template.instance(), - keyCode = event.keyCode || event.which; - - let handled = false; - - if (keyCode === 27) { - instance.$('.btn.btn-cancel').click(); - handled = true; - } else if (keyCode === 13) { - instance.$('.btn.btn-confirm').click(); - handled = true; - } - - if (handled) { - event.stopPropagation(); - } - } -}); - -Template.dialogForm.helpers({ - isError() { - const data = Template.instance().data; - return data instanceof Error || (data && data.error instanceof Error); - } -}); diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/header.html b/Packages/ohif-core/client/components/bootstrap/dialog/header.html deleted file mode 100644 index e21e97b3f..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/header.html +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/info.html b/Packages/ohif-core/client/components/bootstrap/dialog/info.html deleted file mode 100644 index de3a50b70..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/info.html +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/info.js b/Packages/ohif-core/client/components/bootstrap/dialog/info.js deleted file mode 100644 index 47d6ad678..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/info.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Template } from 'meteor/templating'; - -Template.dialogInfo.onRendered(() => { - const instance = Template.instance(); - - const $modal = instance.$('.modal'); - - $modal.one('hidden.bs.modal', () => instance.data.promiseResolve()); -}); - -Template.dialogInfo.helpers({ - isError() { - const data = Template.instance().data; - return data instanceof Error || (data && data.error instanceof Error); - } -}); diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/loading.html b/Packages/ohif-core/client/components/bootstrap/dialog/loading.html deleted file mode 100644 index c122eecec..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/loading.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/loading.js b/Packages/ohif-core/client/components/bootstrap/dialog/loading.js deleted file mode 100644 index 60f1bfc83..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/loading.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Template } from 'meteor/templating'; - -Template.dialogLoading.onRendered(() => { - const instance = Template.instance(); - - const $modal = instance.$('.modal'); - - // Create the bootstrap modal - $modal.modal({ - backdrop: 'static', - keyboard: false, - show: true - }); -}); diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/loading.styl b/Packages/ohif-core/client/components/bootstrap/dialog/loading.styl deleted file mode 100644 index 8b3015bd9..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/loading.styl +++ /dev/null @@ -1,9 +0,0 @@ -@import "{ohif:viewerbase}/app" - -.modal .loading-text - theme('color', '$textSecondaryColor') - font-size: 30px - height: 100vh - line-height: 100vh - text-align: center - text-shadow: 1px 1px 0 #000, -1px -1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px 0 0 #000, 0 -1px 0 #000, 1px 0 0 #000, 0 1px 0 #000 diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/login.html b/Packages/ohif-core/client/components/bootstrap/dialog/login.html deleted file mode 100644 index bc719273d..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/login.html +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/login.js b/Packages/ohif-core/client/components/bootstrap/dialog/login.js deleted file mode 100644 index 8ad40f073..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/login.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Template } from 'meteor/templating'; -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; - -Template.dialogLogin.onCreated(() => { - const instance = Template.instance(); - - instance.schema = new SimpleSchema({ - username: { - type: String, - label: 'Username' - }, - password: { - type: String, - label: 'Password' - } - }); -}); diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/progress.html b/Packages/ohif-core/client/components/bootstrap/dialog/progress.html deleted file mode 100644 index 9adb00e37..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/progress.html +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/progress.js b/Packages/ohif-core/client/components/bootstrap/dialog/progress.js deleted file mode 100644 index ca63483da..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/progress.js +++ /dev/null @@ -1,87 +0,0 @@ -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; -import _ from 'underscore'; - -Template.dialogProgress.onCreated(() => { - const instance = Template.instance(); - - instance.state = new ReactiveVar({ - processed: 0, - total: instance.data.total, - message: instance.data.message - }); -}); - -Template.dialogProgress.onRendered(() => { - const instance = Template.instance(); - const task = instance.data.task; - - const progressDialog = { - promise: instance.data.promise, - - done: value => { - // Hide the modal, removing the backdrop - instance.$('.modal').on('hidden.bs.modal', event => { - instance.data.promiseResolve(value); - }).modal('hide'); - }, - - cancel: () => { - // Hide the modal, removing the backdrop - instance.$('.modal').on('hidden.bs.modal', event => { - instance.data.promiseReject(); - }).modal('hide'); - }, - - update: _.throttle(processed => { - const state = instance.state.get(); - state.processed = Math.max(0, processed); - - instance.state.set(state); - }, 100), - - setTotal: _.throttle(total => { - const state = instance.state.get(); - state.total = total; - - instance.state.set(state); - }, 100), - - setMessage: _.throttle(message => { - const state = instance.state.get(); - state.message = message; - - instance.state.set(state); - }, 100) - }; - - task.run(progressDialog); -}); - -Template.dialogProgress.helpers({ - progress() { - const instance = Template.instance(); - const state = instance.state.get(); - - if (!state || !state.total) { - return 0; - } - - return Math.min(1, state.processed / state.total) * 100; - }, - - message() { - const instance = Template.instance(); - const state = instance.state.get(); - - if (!state) { - return; - } - - if (typeof state.message === 'function') { - return state.message(state); - } - - return state.message; - } -}); diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/progress.styl b/Packages/ohif-core/client/components/bootstrap/dialog/progress.styl deleted file mode 100644 index ef1c24a0b..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/progress.styl +++ /dev/null @@ -1,14 +0,0 @@ -.modal-progress - .status - .progress-bar-container - border: solid 1px #28405E - overflow: auto; - margin: 0 0 10px - border-radius: 3px - - .percentage - margin: 0 5px - - .btn-confirm - display: none - \ No newline at end of file diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/simple.html b/Packages/ohif-core/client/components/bootstrap/dialog/simple.html deleted file mode 100644 index c59b5f120..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/simple.html +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/simple.js b/Packages/ohif-core/client/components/bootstrap/dialog/simple.js deleted file mode 100644 index e4717edae..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/simple.js +++ /dev/null @@ -1,61 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -Template.dialogSimple.onCreated(() => { - const instance = Template.instance(); - - instance.close = () => { - instance.$('.modal').modal('hide'); - }; - - // Automatically close the modal if a timeout value was given - if (instance.data.timeout) { - Meteor.setTimeout(instance.close, instance.data.timeout); - } -}); - -Template.dialogSimple.onRendered(() => { - const instance = Template.instance(); - - // Allow options ovewrite - const modalOptions = _.extend({ - backdrop: 'static', - keyboard: false - }, instance.data.modalOptions); - - const $modal = instance.$('.modal'); - - // Create the bootstrap modal - $modal.modal(modalOptions); - - // Resolve the promise as soon as the modal is closed - $modal.one('hidden.bs.modal', () => instance.data.promiseResolve()); - - let position = instance.data.position; - - const { event } = instance.data; - if (!position && event && !_.isUndefined(event.clientX)) { - position = { - x: event.clientX, - y: event.clientY - }; - } - - if (position) { - OHIF.ui.repositionDialog($modal, position.x, position.y); - } -}); - -Template.dialogSimple.events({ - keydown(event) { - const instance = Template.instance(); - const keyCode = event.keyCode || event.which; - - if (keyCode === 27) { - instance.close(); - event.stopPropagation(); - } - } -}); diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.html b/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.html deleted file mode 100644 index e12e33fd3..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.html +++ /dev/null @@ -1,35 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.js b/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.js deleted file mode 100644 index 38d0c2874..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.js +++ /dev/null @@ -1,132 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import { Template } from 'meteor/templating'; -import _ from 'underscore'; -import $ from 'jquery'; - -const MARGIN_RIGHT = 15; -const MARGIN_BOTTOM = 15; - -Template.unsavedChangesDialog.onRendered(function() { - - const instance = Template.instance(); - const $modal = instance.$('.modal.unsavedChangesDialog'); - - // Routine which effectively displays the BS modal... - instance.displayModal = () => { - - // Make modal options extensible... - const modalOptions = _.extend({ - backdrop: 'static', - keyboard: false - }, instance.data.modalOptions); - - // Set handler for "hidden" event... Simply remove the view! - $modal.one('hidden.bs.modal', () => { - Blaze.remove(instance.view); - }); - - // Create the bootstrap modal - $modal.modal(modalOptions); - - }; - - // Routine which repositions the modal before display... - instance.displayModalWithPosition = (position) => { - - // Preserve original CSS rules... - const origCSS = { - display: $modal.css('display'), - visibility: $modal.css('visibility') - }; - - // Make sure modal is propperly rendered before proceeding with math... - if (origCSS.display === 'none') { - $modal.css({ - visibility: 'hidden', - display: 'block' - }); - } - - // Run presentation code on next tick... - setTimeout(() => { - - let dimension; - const $dialog = $modal.find('.modal-dialog'); - - const dialogRect = { - position: { - x: parseInt(position.x) || 0, - y: parseInt(position.y) || 0 - }, - size: { - width: $dialog.outerWidth(), - height: $dialog.outerHeight() - } - }; - - const modalSize = { - width: $modal.width(), - height: $modal.height() - }; - - dimension = dialogRect.position.x + dialogRect.size.width + MARGIN_RIGHT; - if (dimension > modalSize.width) { - dialogRect.position.x -= dimension - modalSize.width; - } - - if (dialogRect.position.x < 0) { - dialogRect.position.x = 0; - } - - dimension = dialogRect.position.y + dialogRect.size.height + MARGIN_BOTTOM; - if (dimension > modalSize.height) { - dialogRect.position.y -= dimension - modalSize.height; - } - - if (dialogRect.position.y < 0) { - dialogRect.position.y = 0; - } - - // Restore original CSS... - $modal.css(origCSS); - - // Set new position... - $dialog.css({ - position: 'fixed', - margin: 0, - left: dialogRect.position.x, - top: dialogRect.position.y - }); - - instance.displayModal(); - - }, 0); - - }; - - // Check if modal will be presented with custom positioning... - let position = instance.data.position; - if (position && 'x' in position && 'y' in position) { - instance.displayModalWithPosition(position); - } else { - instance.displayModal(); - } - -}); - -Template.unsavedChangesDialog.events({ - - 'click button[data-choice]'(event) { - - const instance = Template.instance(); - const callback = instance.data.callback; - const choice = $(event.currentTarget).attr('data-choice') || ''; - - // if callback is a function, call it passing user choice... - if (typeof callback === 'function') { - callback.call(instance, choice); - } - - } - -}); diff --git a/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.styl b/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.styl deleted file mode 100644 index d1e3f0226..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dialog/unsavedChangesDialog.styl +++ /dev/null @@ -1,7 +0,0 @@ -.modal.unsavedChangesDialog - - .modal-dialog - width: 400px - - .modal-footer - border-top: 0 none diff --git a/Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl b/Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl deleted file mode 100644 index 15d607c5d..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dropdown/dropdown.styl +++ /dev/null @@ -1,61 +0,0 @@ -@require '{ohif:viewerbase}/app' - -.dropdown - cursor: default - outline: none - - &>ul.dropdown-menu - display: block - z-index: 1000 - transform(scale(0)) - transition(transform 0.3s ease) - - &.dropdown-menu-left, &.origin-top-left - transform-origin(0% 0%) - - &.dropdown-menu-right, &.origin-top-right - transform-origin(100% 0%) - - li.divider - margin: 4px 0 - - li a - outline: none - padding: 8px 20px - - i - font-size: 14px - margin-right: 4px - - svg - display: inline-block - max-width: 18px - max-height: 18px - vertical-align: middle - - &.open>ul.dropdown-menu - transform(scale(1)) - - -.dropdown-submenu - - &:hover - - &>.dropdown-menu - display: block - - &>a:after - border-left-color: #000000 - - &>a:after - display: block - float: right - content: ' ' - width: 0 - height: 0 - border-color: transparent - border-style: solid - border-width: 5px 0 5px 5px - border-left-color: #666666 - margin-top: 5px - margin-right: -10px diff --git a/Packages/ohif-core/client/components/bootstrap/dropdown/form.html b/Packages/ohif-core/client/components/bootstrap/dropdown/form.html deleted file mode 100644 index 99a6bb545..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dropdown/form.html +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/Packages/ohif-core/client/components/bootstrap/dropdown/form.js b/Packages/ohif-core/client/components/bootstrap/dropdown/form.js deleted file mode 100644 index 382295aa3..000000000 --- a/Packages/ohif-core/client/components/bootstrap/dropdown/form.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Template } from 'meteor/templating'; - -Template.dropdownFormMenu.helpers({ - isVisible(item) { - let isVisible = true; - if (typeof item.visible === 'function') { - isVisible = item.visible(); - } else if (typeof item.visible !== 'undefined') { - isVisible = !!item.visible; - } - - return isVisible; - }, - - getText(item) { - if (typeof item.text === 'function') { - return item.text(item.params || {}); - } - - return item.text || ''; - } -}); diff --git a/Packages/ohif-core/client/components/bootstrap/form/button.html b/Packages/ohif-core/client/components/bootstrap/form/button.html deleted file mode 100644 index 6f8ce2581..000000000 --- a/Packages/ohif-core/client/components/bootstrap/form/button.html +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/form/form.html b/Packages/ohif-core/client/components/bootstrap/form/form.html deleted file mode 100644 index ca90b0101..000000000 --- a/Packages/ohif-core/client/components/bootstrap/form/form.html +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/form/group.html b/Packages/ohif-core/client/components/bootstrap/form/group.html deleted file mode 100644 index 402f38fc2..000000000 --- a/Packages/ohif-core/client/components/bootstrap/form/group.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/form/link.html b/Packages/ohif-core/client/components/bootstrap/form/link.html deleted file mode 100644 index a96e1fe88..000000000 --- a/Packages/ohif-core/client/components/bootstrap/form/link.html +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/index.js b/Packages/ohif-core/client/components/bootstrap/index.js deleted file mode 100644 index 64cdfc92b..000000000 --- a/Packages/ohif-core/client/components/bootstrap/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import './dialog/confirm.html'; -import './dialog/form.html'; -import './dialog/form.js'; -import './dialog/header.html'; -import './dialog/info.html'; -import './dialog/info.js'; -import './dialog/loading.html'; -import './dialog/loading.js'; -import './dialog/login.html'; -import './dialog/login.js'; -import './dialog/progress.html'; -import './dialog/progress.js'; -import './dialog/simple.html'; -import './dialog/simple.js'; -import './dialog/unsavedChangesDialog.html'; -import './dialog/unsavedChangesDialog.js'; - -import './dropdown/form.html'; -import './dropdown/form.js'; - -import './form/button.html'; -import './form/form.html'; -import './form/group.html'; -import './form/link.html'; - -import './input/checkbox.html'; -import './input/hidden.html'; -import './input/groupRadio.html'; -import './input/number.html'; -import './input/password.html'; -import './input/radio.html'; -import './input/range.html'; -import './input/select.html'; -import './input/text.html'; - -import './notification'; - -import './popover/form.html'; -import './popover/popoverSimple.html'; diff --git a/Packages/ohif-core/client/components/bootstrap/input/checkbox.html b/Packages/ohif-core/client/components/bootstrap/input/checkbox.html deleted file mode 100644 index 038312206..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/checkbox.html +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/groupRadio.html b/Packages/ohif-core/client/components/bootstrap/input/groupRadio.html deleted file mode 100644 index afc11e7bd..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/groupRadio.html +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/hidden.html b/Packages/ohif-core/client/components/bootstrap/input/hidden.html deleted file mode 100644 index 01ec712ea..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/hidden.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/number.html b/Packages/ohif-core/client/components/bootstrap/input/number.html deleted file mode 100644 index 2d31b0a2c..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/number.html +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/password.html b/Packages/ohif-core/client/components/bootstrap/input/password.html deleted file mode 100644 index caf51a343..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/password.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/radio.html b/Packages/ohif-core/client/components/bootstrap/input/radio.html deleted file mode 100644 index d2377667e..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/radio.html +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/range.html b/Packages/ohif-core/client/components/bootstrap/input/range.html deleted file mode 100644 index aeb04c9aa..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/range.html +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/select.html b/Packages/ohif-core/client/components/bootstrap/input/select.html deleted file mode 100644 index fae5bd98b..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/select.html +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/input/text.html b/Packages/ohif-core/client/components/bootstrap/input/text.html deleted file mode 100644 index 7baded756..000000000 --- a/Packages/ohif-core/client/components/bootstrap/input/text.html +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/notification/index.js b/Packages/ohif-core/client/components/bootstrap/notification/index.js deleted file mode 100644 index 9f2cb2c1f..000000000 --- a/Packages/ohif-core/client/components/bootstrap/notification/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import './notification.styl'; -import './notificationNote.html'; -import './notificationNote.js'; diff --git a/Packages/ohif-core/client/components/bootstrap/notification/notification.styl b/Packages/ohif-core/client/components/bootstrap/notification/notification.styl deleted file mode 100644 index 92791c675..000000000 --- a/Packages/ohif-core/client/components/bootstrap/notification/notification.styl +++ /dev/null @@ -1,70 +0,0 @@ -@require '{ohif:viewerbase}/app' - -.notification-area - position: fixed - right: 0 - top: 50px - max-width: 320px - z-index: 10000 - -.notification-note - opacity: 0 - position: relative - transition(opacity 0.5s linear\, max-height 0.5s linear) - width: 300px - z-index: 2 - - .note-container - padding: 10px - transform(translateY(0)) - transition(transform 0.5s linear) - - .note-body - margin: 0 - padding: 10px - position: relative - - &:not(.hide-dismiss) - padding-right: 50px - - .note-dismiss - display: block - - .alert-success - background-color: #D9F2E9 - color: #000000 - - .note-dismiss - bottom: 0 - cursor: pointer - display: none - position: absolute - right: 0 - top: 0 - transition(background-color 0.3s ease) - width: 40px - - i - display: block - font-size: 20px - left: 0 - position: absolute - text-align: center - top: 50% - transform(translateY(-50%)) - width: 100% - - &:hover - background-color: rgba(0, 0, 0, 0.1) - - &.in - max-height: auto - opacity: 1 - - &.out - max-height: 0 !important - opacity: 0 - z-index: 1 - - .note-container - transform(translateY(-100%)) diff --git a/Packages/ohif-core/client/components/bootstrap/notification/notificationNote.html b/Packages/ohif-core/client/components/bootstrap/notification/notificationNote.html deleted file mode 100644 index a11f42c43..000000000 --- a/Packages/ohif-core/client/components/bootstrap/notification/notificationNote.html +++ /dev/null @@ -1,18 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/notification/notificationNote.js b/Packages/ohif-core/client/components/bootstrap/notification/notificationNote.js deleted file mode 100644 index c0581c38b..000000000 --- a/Packages/ohif-core/client/components/bootstrap/notification/notificationNote.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; - -Template.notificationNote.onRendered(() => { - const instance = Template.instance(); - Meteor.setTimeout(() => { - const $note = instance.$('.notification-note'); - $note.css('max-height', $note.outerHeight()).addClass('in'); - }, 100); -}); - -Template.notificationNote.events({ - 'click .note-dismiss'(event, instance) { - if (instance.data.promiseResolve) { - instance.data.promiseResolve(); - } else { - OHIF.ui.notifications.dismiss(instance.data.id); - } - } -}); diff --git a/Packages/ohif-core/client/components/bootstrap/popover/form.html b/Packages/ohif-core/client/components/bootstrap/popover/form.html deleted file mode 100644 index ace107a75..000000000 --- a/Packages/ohif-core/client/components/bootstrap/popover/form.html +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/bootstrap/popover/popoverSimple.html b/Packages/ohif-core/client/components/bootstrap/popover/popoverSimple.html deleted file mode 100644 index c9790d379..000000000 --- a/Packages/ohif-core/client/components/bootstrap/popover/popoverSimple.html +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/Packages/ohif-core/client/components/header/header.html b/Packages/ohif-core/client/components/header/header.html deleted file mode 100644 index 14c21f73b..000000000 --- a/Packages/ohif-core/client/components/header/header.html +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/header/header.js b/Packages/ohif-core/client/components/header/header.js deleted file mode 100644 index 40e97c9e4..000000000 --- a/Packages/ohif-core/client/components/header/header.js +++ /dev/null @@ -1,29 +0,0 @@ -import { Template } from 'meteor/templating'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; - -Template.header.onCreated(() => { - const instance = Template.instance(); - - instance.dropdownItems = []; - instance.autorun(() => { - OHIF.header.dropdown.observer.depend(); - instance.dropdownItems = OHIF.header.dropdown.getItems(); - }); -}); - -Template.header.events({ - 'click .header-menu'(event, instance) { - event.preventDefault(); - - // Prevent dropdown from being opened if there's one already opened - if ($(event.currentTarget).find('.dropdown').length) return; - - // Show the dropdown - OHIF.ui.showDropdown(instance.dropdownItems, { - parentElement: event.currentTarget, - menuClasses: 'dropdown-menu-right', - marginTop: '25px' - }); - } -}); diff --git a/Packages/ohif-core/client/components/header/header.styl b/Packages/ohif-core/client/components/header/header.styl deleted file mode 100644 index 293a0f6bc..000000000 --- a/Packages/ohif-core/client/components/header/header.styl +++ /dev/null @@ -1,26 +0,0 @@ -@import "{ohif:viewerbase}/app" - -body>.header - height: $topBarHeight - padding: 10px 10px 0 - theme('color', '$textPrimaryColor') - theme('background-color', '$primaryBackgroundColor') - transition(all 0.5s ease) - - &>.clearfix - position: relative - - .header-menu - padding: 4px 0 - font-size: 13px - font-weight: 400 - line-height: 18px - text-decoration: none - theme('color', '$defaultColor') - - &:empty - display: none - - &.header-big - height: $topBarExpandedHeight - background-color: rgba(21, 25, 30, 0.7) diff --git a/Packages/ohif-core/client/components/header/index.js b/Packages/ohif-core/client/components/header/index.js deleted file mode 100644 index d93efa6fc..000000000 --- a/Packages/ohif-core/client/components/header/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import './header.html'; -import './header.js'; -import './header.styl'; diff --git a/Packages/ohif-core/client/components/hotkeys/confirmReplacementPopover.html b/Packages/ohif-core/client/components/hotkeys/confirmReplacementPopover.html deleted file mode 100644 index 2f47094bf..000000000 --- a/Packages/ohif-core/client/components/hotkeys/confirmReplacementPopover.html +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/hotkeys/form.html b/Packages/ohif-core/client/components/hotkeys/form.html deleted file mode 100644 index 8487288d5..000000000 --- a/Packages/ohif-core/client/components/hotkeys/form.html +++ /dev/null @@ -1,21 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/hotkeys/form.js b/Packages/ohif-core/client/components/hotkeys/form.js deleted file mode 100644 index d9f30192a..000000000 --- a/Packages/ohif-core/client/components/hotkeys/form.js +++ /dev/null @@ -1,237 +0,0 @@ -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; -import $ from 'jquery'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -Template.hotkeysForm.onCreated(() => { - const instance = Template.instance(); - const { contextName } = instance.data; - - instance.api = { - save() { - const form = instance.$('form').first().data('component'); - const definitions = form.value(); - const promise = OHIF.hotkeys.store(contextName, definitions); - promise.then(() => { - const successMessage = 'The keyboard shortcut preferences were successfully saved.'; - OHIF.ui.notifications.success({ text: successMessage }); - OHIF.hotkeys.load(contextName).then(defs => instance.hotkeysDefinitions.set(defs)); - }); - return promise; - }, - - resetDefaults() { - const dialogOptions = { - class: 'themed', - title: 'Reset Keyboard Shortcuts', - message: 'Are you sure you want to reset all the shortcuts to their defaults?' - }; - - return OHIF.ui.showDialog('dialogConfirm', dialogOptions).then(() => { - const resetDefaults = OHIF.hotkeys.resetDefaults(contextName); - resetDefaults.then(() => { - OHIF.hotkeys.load(contextName).then(defs => instance.hotkeysDefinitions.set(defs)); - }); - }); - } - }; - - const rg = (start, end) => _.range(start, end + 1); - instance.allowedKeys = _.union( - [8, 13, 27, 32, 46], // BACKSPACE, ENTER, ESCAPE, SPACE, DELETE - [12, 106, 107, 109, 110, 111], // Numpad keys - rg(219, 221), // [\] - rg(186, 191), // ;=,-./ - rg(112, 130), // F1-F19 - rg(33, 40), // arrow keys, home/end, pg dn/up - rg(48, 57), // 0-9 - rg(65, 90) // A-Z - ); - - instance.updateInputText = (event, displayPressedKey=false) => { - const $target = $(event.currentTarget); - const keysPressedArray = instance.getKeysPressedArray(event); - - if (displayPressedKey) { - const specialKeyName = jQuery.hotkeys.specialKeys[event.which]; - const keyName = specialKeyName || String.fromCharCode(event.keyCode) || event.key; - keysPressedArray.push(keyName.toUpperCase()); - } - - $target.val(keysPressedArray.join('+')); - }; - - instance.getKeysPressedArray = event => { - const keysPressedArray = []; - - if (event.ctrlKey && !event.altKey) { - keysPressedArray.push('CTRL'); - } - - if (event.shiftKey && !event.altKey) { - keysPressedArray.push('SHIFT'); - } - - if (event.altKey && !event.ctrlKey) { - keysPressedArray.push('ALT'); - } - - return keysPressedArray; - }; - - instance.getConflictingCommand = (currentCommand, currentCombination) => { - const form = instance.$('form').first().data('component'); - const hotkeys = form.value(); - - let conflict = ''; - _.each(hotkeys, (combination, command) => { - if (combination && combination === currentCombination && command !== currentCommand) { - conflict = command; - } - }); - - return conflict; - }; - - instance.disallowedCombinations = { - '': [], - ALT: ['SPACE'], - SHIFT: [], - CTRL: ['F4', 'F5', 'F11', 'W', 'R', 'T', 'O', 'P', 'A', 'D', 'F', 'G', 'H', 'J', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'PAGEDOWN', 'PAGEUP'], - 'CTRL+SHIFT': ['Q', 'W', 'R', 'T', 'P', 'A', 'H', 'V', 'B', 'N'] - }; - - const hotkeysContext = OHIF.hotkeys.getContext(contextName) || {}; - instance.hotkeysDefinitions = new ReactiveVar(hotkeysContext.definitions); - OHIF.hotkeys.load(contextName).then(defs => instance.hotkeysDefinitions.set(defs)); -}); - -Template.hotkeysForm.events({ - 'keydown .hotkey'(event, instance) { - // Prevent ESC key from propagating and closing the modal - if (event.keyCode === 27) { - event.stopPropagation(); - } - - if (instance.allowedKeys.indexOf(event.keyCode) > -1) { - instance.updateInputText(event, true); - $(event.currentTarget).trigger('hotkeyChange'); - } else { - instance.updateInputText(event); - } - - event.preventDefault(); - }, - - 'hotkeyChange .hotkey'(event, instance, data={}) { - const $target = $(event.currentTarget); - const combination = $target.val(); - const keys = combination.split('+'); - const lastKey = keys.pop(); - const modifierCombination = keys.join('+'); - const isModifier = ['CTRL', 'ALT', 'SHIFT'].indexOf(lastKey) > -1; - - const formItem = $target.data('component'); - const conflictedCommand = instance.getConflictingCommand(this.key, combination); - if (isModifier) { - // Clean the input if left with only a modifier key or browser specific command - formItem.error(`It's not possible to define only modifier keys (CTRL, ALT and SHIFT) as a shortcut`); - $target.val('').focus(); - } else if (instance.disallowedCombinations[modifierCombination].indexOf(lastKey) > -1) { - // Clean the input and show error if combination is not allowed - formItem.error(`The "${combination}" shortcut combination is not allowed`); - $target.val('').focus(); - } else if (conflictedCommand) { - if (data.blurTrigger) return; - - // Remove the error message - formItem.error(false); - formItem.toggleTooltip(false); - - const placement = $target.closest('.hotkeys-left').length ? 'right' : 'left'; - const commandsContext = OHIF.commands.getContext(instance.data.contextName); - const popoverData = { - conflictedFunctionName: commandsContext[conflictedCommand].name, - newFunctionName: commandsContext[this.key].name, - hotkeyCombination: combination, - }; - - const popoverOptions = { - event, - placement - }; - - const conflictedFormItem = instance.$('form').first().data('component').item(conflictedCommand); - formItem.state('error', true); - conflictedFormItem.state('error', true); - - const cleanup = () => { - instance.popoverVisible = false; - formItem.state('error', false); - conflictedFormItem.state('error', false); - }; - - const popoverTemplate = 'hotkeysConfirmReplacementPopover'; - instance.popoverVisible = true; - OHIF.ui.showPopover(popoverTemplate, popoverData, popoverOptions).then(() => { - cleanup(); - formItem.value(combination); - conflictedFormItem.value(''); - $target.blur(); - }).catch(() => { - cleanup(); - $target.val('').focus(); - }); - } else { - // Remove the error message and blur the component if everything is fine - formItem.error(false); - if (!data.blurTrigger) { - $target.blur(); - } - } - }, - - 'blur .hotkey'(event, instance, data={}) { - $(event.currentTarget).trigger('hotkeyChange', { blurTrigger: true }); - }, - - 'keyup .hotkey'(event, instance) { - if (!instance.popoverVisible) { - instance.updateInputText(event); - } - } -}); - -Template.hotkeysForm.helpers({ - getHotkeyInputInformationLists() { - OHIF.hotkeys.changeObserver.depend(); - - const instance = Template.instance(); - const { contextName } = instance.data; - - const hotkeyDefinitions = instance.hotkeysDefinitions.get(); - const commandsContext = OHIF.commands.getContext(contextName); - if (!hotkeyDefinitions || !commandsContext) return {}; - - const commands = Object.keys(OHIF.hotkeys.defaults[contextName] || {}); - const list = []; - commands.forEach(commandName => { - const commandDefinitions = commandsContext[commandName]; - if (!commandDefinitions) return; - list.push({ - key: commandName, - label: commandDefinitions.name, - value: hotkeyDefinitions[commandName] || '' - }); - }); - - const left = list.splice(0, Math.ceil(list.length / 2)); - const right = list; - - return { - left, - right - }; - } -}); diff --git a/Packages/ohif-core/client/components/hotkeys/formTable.html b/Packages/ohif-core/client/components/hotkeys/formTable.html deleted file mode 100644 index e0039c7d5..000000000 --- a/Packages/ohif-core/client/components/hotkeys/formTable.html +++ /dev/null @@ -1,18 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/hotkeys/formTable.js b/Packages/ohif-core/client/components/hotkeys/formTable.js deleted file mode 100644 index 4d2fb9f49..000000000 --- a/Packages/ohif-core/client/components/hotkeys/formTable.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; - -Template.hotkeysFormTable.helpers({ - getLabel(input) { - let result = input.label; - if (input.key.indexOf('WLPreset') === 0) { - const presetIndex = parseInt(input.key.replace('WLPreset', '')); - const preset = OHIF.viewer.wlPresets[presetIndex]; - if (preset.id) { - result += ` (${preset.id})`; - } - } - - return result; - } -}); diff --git a/Packages/ohif-core/client/components/hotkeys/index.js b/Packages/ohif-core/client/components/hotkeys/index.js deleted file mode 100644 index 143029491..000000000 --- a/Packages/ohif-core/client/components/hotkeys/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import './confirmReplacementPopover.html'; - -import './form.html'; -import './form.js'; - -import './formTable.html'; -import './formTable.js'; diff --git a/Packages/ohif-core/client/components/index.js b/Packages/ohif-core/client/components/index.js deleted file mode 100644 index 999e83bc3..000000000 --- a/Packages/ohif-core/client/components/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import './base'; -import './bootstrap'; -import './header'; -import './hotkeys'; -import './pages'; -import './paginationArea'; -import './playground'; -import './scrollArea'; diff --git a/Packages/ohif-core/client/components/pages/error/error.html b/Packages/ohif-core/client/components/pages/error/error.html deleted file mode 100644 index e9d2b7771..000000000 --- a/Packages/ohif-core/client/components/pages/error/error.html +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/pages/error/error.js b/Packages/ohif-core/client/components/pages/error/error.js deleted file mode 100644 index 78766f36e..000000000 --- a/Packages/ohif-core/client/components/pages/error/error.js +++ /dev/null @@ -1,13 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; - -Template.pageError.helpers({ - shallDisplayErrorStack() { - return Meteor.isDevelopment; - }, - - getDefaultErrorMessage() { - const instance = Template.instance(); - return instance.view.templateContentBlock ? '' : 'An error has ocurred.'; - } -}); diff --git a/Packages/ohif-core/client/components/pages/error/error.styl b/Packages/ohif-core/client/components/pages/error/error.styl deleted file mode 100644 index c1c4858f4..000000000 --- a/Packages/ohif-core/client/components/pages/error/error.styl +++ /dev/null @@ -1,19 +0,0 @@ -@require '{ohif:viewerbase}/app' - -.page-error .error-stack - display: table - margin-top: 10px - table-layout: fixed - width: 100% - - p - theme('background-color', '$uiGrayDarkest') - theme('border', '1px solid $uiGray') - border-radius(4px) - display: inline-block - font-family: monospace - margin: 0 - padding: 10px 20px - overflow-x: auto - white-space: pre - width: 100% diff --git a/Packages/ohif-core/client/components/pages/error/index.js b/Packages/ohif-core/client/components/pages/error/index.js deleted file mode 100644 index c8ab38d0e..000000000 --- a/Packages/ohif-core/client/components/pages/error/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import './error.html'; -import './error.js'; -import './error.styl'; diff --git a/Packages/ohif-core/client/components/pages/index.js b/Packages/ohif-core/client/components/pages/index.js deleted file mode 100644 index b3d517bff..000000000 --- a/Packages/ohif-core/client/components/pages/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import './error'; -import './message'; diff --git a/Packages/ohif-core/client/components/pages/message/index.js b/Packages/ohif-core/client/components/pages/message/index.js deleted file mode 100644 index d6c7a9b72..000000000 --- a/Packages/ohif-core/client/components/pages/message/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import './message.html'; -import './message.styl'; diff --git a/Packages/ohif-core/client/components/pages/message/message.html b/Packages/ohif-core/client/components/pages/message/message.html deleted file mode 100644 index 1ba3c9d0c..000000000 --- a/Packages/ohif-core/client/components/pages/message/message.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/pages/message/message.styl b/Packages/ohif-core/client/components/pages/message/message.styl deleted file mode 100644 index 052aeeb21..000000000 --- a/Packages/ohif-core/client/components/pages/message/message.styl +++ /dev/null @@ -1,31 +0,0 @@ -@require '{ohif:viewerbase}/app' - -.page-message - theme('color', '$textPrimaryColor') - font-weight: 300 - padding: 10px 0 20px - - .message-container - display: table - margin: 0 auto - padding: 0 32px - - .message-title - theme('color', '$textSecondaryColor') - font-size: 30px - font-weight: 300 - - .message-content - font-size: 18px - - a - &, &:hover, &:active, &:focus - theme('color', '$activeColor') - -.modal .page-message - - .page-message, .message-container - padding: 0 - - .message-title - display: none diff --git a/Packages/ohif-core/client/components/paginationArea/index.js b/Packages/ohif-core/client/components/paginationArea/index.js deleted file mode 100644 index e48878db0..000000000 --- a/Packages/ohif-core/client/components/paginationArea/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import './paginationArea.html'; -import './paginationArea.js'; -import './paginationArea.styl'; diff --git a/Packages/ohif-core/client/components/paginationArea/paginationArea.html b/Packages/ohif-core/client/components/paginationArea/paginationArea.html deleted file mode 100644 index 884a35316..000000000 --- a/Packages/ohif-core/client/components/paginationArea/paginationArea.html +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/paginationArea/paginationArea.js b/Packages/ohif-core/client/components/paginationArea/paginationArea.js deleted file mode 100644 index 3d7a5d204..000000000 --- a/Packages/ohif-core/client/components/paginationArea/paginationArea.js +++ /dev/null @@ -1,82 +0,0 @@ -import { Template } from 'meteor/templating'; -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; -import $ from 'jquery'; - -Template.paginationArea.onCreated(function() { - const instance = Template.instance(); - - // Create the rowsPerPage schema - instance.schema = new SimpleSchema({ - rowsPerPage: { - type: Number, - allowedValues: [25, 50, 100], - defaultValue: 25 - } - }); -}); - -Template.paginationArea.onRendered(() => { - const instance = Template.instance(); - - // Track changes on recordCount and rowsPerPage - instance.autorun(() => { - const recordCount = instance.data.recordCount.get(); - const rowsPerPage = instance.data.rowsPerPage.get(); - const currentPage = instance.data.currentPage.get(); - - Meteor.defer(() => { - const prevButton = instance.$('.prev')[0]; - const nextButton = instance.$('.next')[0]; - if (!prevButton || !nextButton) { - return; - } - - // Enable if there are potentially more records, otherwise disable it - if (recordCount >= rowsPerPage) { - nextButton.classList.remove('disabled'); - } else { - nextButton.classList.add('disabled'); - } - - // Enable the previous button if it is not the first page, otherwise disable it - if (currentPage > 0) { - prevButton.classList.remove('disabled'); - } else { - prevButton.classList.add('disabled'); - } - }); - }); -}); - -Template.paginationArea.helpers({ - paginationButtonsEnabled() { - const instance = Template.instance(); - - const recordCount = instance.data.recordCount.get(); - const rowsPerPage = instance.data.rowsPerPage.get(); - const currentPage = instance.data.currentPage.get(); - - // Show pagination if it is not first page or there are potentially more records - return currentPage > 0 || recordCount >= rowsPerPage; - } -}); - -Template.paginationArea.events({ - 'click .prev > a'(event, instance) { - const currentPage = instance.data.currentPage.get(); - instance.data.currentPage.set(currentPage - 1); - }, - - 'click .next > a'(event, instance) { - const currentPage = instance.data.currentPage.get(); - instance.data.currentPage.set(currentPage + 1); - }, - - 'change [data-key=rowsPerPage]'(event, instance) { - const rowsPerPage = $(event.currentTarget).data('component').value(); - - // Update rowsPerPage - instance.data.rowsPerPage.set(parseInt(rowsPerPage, 10)); - instance.data.currentPage.set(0); - } -}); diff --git a/Packages/ohif-core/client/components/paginationArea/paginationArea.styl b/Packages/ohif-core/client/components/paginationArea/paginationArea.styl deleted file mode 100644 index a1c675b2e..000000000 --- a/Packages/ohif-core/client/components/paginationArea/paginationArea.styl +++ /dev/null @@ -1,67 +0,0 @@ -@require '{ohif:viewerbase}/app' - -.pagination-area - font-size: 13px - font-weight: normal !important - - label - font-weight: normal - - select - theme('background-color', '$primaryBackgroundColor') - color: white - - .rows-per-page label.wrapperLabel - display: inline-table !important - margin: 0 4px - - select - width: 42px - - .page-buttons - margin: 0 - text-align: right - - label - font-weight: normal - - ul.pagination-control - margin: 0 - - li - display: table-cell - padding: 5px 2px - - a - padding: 4px 8px - theme('background-color', '$primaryBackgroundColor') - theme('border-color', '$uiGray') - theme('background-color', '$uiGrayDarkest') - color: white - text-decoration: none - - &:hover - theme('color', '$activeColor') - - .active - a - theme('background-color', '$uiGray') - border-color: #ddd - color: white - - .disabled - cursor: not-allowed - - a, a:hover, a:focus, a:active - theme('background-color', '$uiGrayDarkest') - theme('border-color', '$uiGray') - theme('color', '$uiGrayLight') - pointer-events: none - - &:not(.disabled):hover a - theme('background-color', '$uiGrayDark') - theme('color', '$activeColor') - - &.active a - theme('background-color', '$uiGrayDark') - theme('color', '$activeColor') diff --git a/Packages/ohif-core/client/components/playground/index.js b/Packages/ohif-core/client/components/playground/index.js deleted file mode 100644 index 0668f3dc1..000000000 --- a/Packages/ohif-core/client/components/playground/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import './playground.html'; -import './playground.js'; -import './playground.styl'; diff --git a/Packages/ohif-core/client/components/playground/playground.html b/Packages/ohif-core/client/components/playground/playground.html deleted file mode 100644 index 59749e0ba..000000000 --- a/Packages/ohif-core/client/components/playground/playground.html +++ /dev/null @@ -1,28 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/playground/playground.js b/Packages/ohif-core/client/components/playground/playground.js deleted file mode 100644 index 44dc4ef25..000000000 --- a/Packages/ohif-core/client/components/playground/playground.js +++ /dev/null @@ -1,46 +0,0 @@ -import { Template } from 'meteor/templating'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; - -OHIF.ui.layoutState = { - leftSidebar: new ReactiveVar(false), - rightSidebar: new ReactiveVar(false), - toolsDrawer: new ReactiveVar(false) -}; - -Template.componentPlayground.onRendered(() => { - const instance = Template.instance(); - - instance.$('.toolbar-drawer').adjustMax('height'); - instance.autorun(() => { - const state = OHIF.ui.layoutState.toolsDrawer.get(); - instance.$('.toolbar-drawer').toggleClass('open', state); - }); - - instance.$('.layout-sidebar-left').adjustMax('width'); - instance.autorun(() => { - const state = OHIF.ui.layoutState.leftSidebar.get(); - instance.$('.layout-sidebar-left').toggleClass('open', state); - }); - - instance.$('.layout-sidebar-right').adjustMax('width'); - instance.autorun(() => { - const state = OHIF.ui.layoutState.rightSidebar.get(); - instance.$('.layout-sidebar-right').toggleClass('open', state); - }); -}); - -Template.componentPlayground.events({ - 'click .js-tool-more'(event, instance) { - const currentState = OHIF.ui.layoutState.toolsDrawer.get(); - OHIF.ui.layoutState.toolsDrawer.set(!currentState); - }, - 'click .js-toggle-left'(event, instance) { - const currentState = OHIF.ui.layoutState.leftSidebar.get(); - OHIF.ui.layoutState.leftSidebar.set(!currentState); - }, - 'click .js-toggle-right'(event, instance) { - const currentState = OHIF.ui.layoutState.rightSidebar.get(); - OHIF.ui.layoutState.rightSidebar.set(!currentState); - } -}); diff --git a/Packages/ohif-core/client/components/playground/playground.styl b/Packages/ohif-core/client/components/playground/playground.styl deleted file mode 100644 index 9510ba4bc..000000000 --- a/Packages/ohif-core/client/components/playground/playground.styl +++ /dev/null @@ -1,37 +0,0 @@ -.layout-container - align-items: stretch - display: flex - flex-flow: column nowrap - height: 100vh - - .layout-header - background-color: cyan - flex-grow: 0 - - .layout-body - align-items: stretch - display: flex - flex-grow: 1 - -.layout-sidebar - background-color: lime - flex-grow: 0 - -.layout-main - background-color: white - flex-grow: 1 - -.toolbar-drawer - overflow: hidden - transition: max-height 0.3s ease - - &:not(.open) - max-height: 0 !important - -.layout-sidebar-left -.layout-sidebar-right - overflow: hidden - transition: max-width 0.3s ease - - &:not(.open) - max-width: 0 !important diff --git a/Packages/ohif-core/client/components/scrollArea/index.js b/Packages/ohif-core/client/components/scrollArea/index.js deleted file mode 100644 index b0e46a47c..000000000 --- a/Packages/ohif-core/client/components/scrollArea/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import './scrollArea.html'; -import './scrollArea.js'; -import './scrollArea.styl'; diff --git a/Packages/ohif-core/client/components/scrollArea/scrollArea.html b/Packages/ohif-core/client/components/scrollArea/scrollArea.html deleted file mode 100644 index fbf60fb95..000000000 --- a/Packages/ohif-core/client/components/scrollArea/scrollArea.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/Packages/ohif-core/client/components/scrollArea/scrollArea.js b/Packages/ohif-core/client/components/scrollArea/scrollArea.js deleted file mode 100644 index 4ef3c4e45..000000000 --- a/Packages/ohif-core/client/components/scrollArea/scrollArea.js +++ /dev/null @@ -1,93 +0,0 @@ -import { Template } from 'meteor/templating'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -Template.scrollArea.onCreated(() => { - const instance = Template.instance(); - const { data } = instance; - const defaultConfig = { - hideScrollbar: true, - scrollY: true, - scrollX: false, - scrollStep: 100 - }; - - instance.config = _.defaults(data || {}, defaultConfig); -}); - -Template.scrollArea.onRendered(() => { - const instance = Template.instance(); - - instance.adjustMargins = _.throttle(() => { - const { config } = instance; - if (config.hideScrollbar) { - const $scrollable = instance.$('.scrollable').first(); - const x = config.scrollX ? 1 : 0; - const y = config.scrollY ? 1 : 0; - const scrollbarSize = OHIF.ui.getScrollbarSize(); - $scrollable.css({ - 'margin-right': 0 - (scrollbarSize[0]) * y, - 'margin-bottom': 0 - (scrollbarSize[1]) * x - }); - } - }, 150); - - instance.$scrollable = instance.$('.scrollable').first(); - instance.scrollHandler = _.throttle(event => { - const $scrollable = event ? $(event.currentTarget) : instance.$scrollable; - const $scrollArea = $scrollable.closest('.scroll-area'); - if ($scrollable[0] !== instance.$('.scrollable')[0]) return; - $scrollArea.removeClass('can-scroll-up can-scroll-down'); - const height = $scrollable.outerHeight(); - const scrollTop = $scrollable.scrollTop(); - const { scrollHeight } = $scrollable[0]; - - // Stop here if unable to scroll - if (scrollHeight <= height) return; - - // Check if can scroll up - if (scrollTop) { - $scrollArea.addClass('can-scroll-up'); - } - - // Check if can scroll down - if (scrollTop + height < scrollHeight) { - $scrollArea.addClass('can-scroll-down'); - } - }, 150); - - instance.scrollHandler(); - - instance.adjustMargins(); - $(window).on('resize', instance.adjustMargins); -}); - -Template.scrollArea.onDestroyed(() => { - const instance = Template.instance(); - $(window).off('resize', instance.adjustMargins); -}); - -Template.scrollArea.events({ - 'scroll .scrollable, mouseenter .scrollable, transitionend .scrollable'(event, instance) { - instance.scrollHandler(event); - }, - - 'click .scroll-nav-down'(event, instance) { - const $scrollable = $(event.currentTarget).siblings('.scrollable'); - const height = $scrollable.outerHeight(); - const currentTop = $scrollable.scrollTop(); - const { scrollHeight } = $scrollable[0]; - const limit = scrollHeight - height; - let scrollTop = currentTop + instance.data.scrollStep; - scrollTop = scrollTop > limit ? limit : scrollTop; - $scrollable.stop().animate({ scrollTop }, 150, 'swing'); - }, - - 'click .scroll-nav-up'(event, instance) { - const $scrollable = $(event.currentTarget).siblings('.scrollable'); - const currentTop = $scrollable.scrollTop(); - let scrollTop = currentTop - instance.data.scrollStep; - scrollTop = scrollTop < 0 ? 0 : scrollTop; - $scrollable.stop().animate({ scrollTop }, 150, 'swing'); - }, -}); diff --git a/Packages/ohif-core/client/components/scrollArea/scrollArea.styl b/Packages/ohif-core/client/components/scrollArea/scrollArea.styl deleted file mode 100644 index 8731d4927..000000000 --- a/Packages/ohif-core/client/components/scrollArea/scrollArea.styl +++ /dev/null @@ -1,79 +0,0 @@ -@require '{ohif:viewerbase}/app' - -$scrollNavSize = 24px - -.scroll-area - overflow: hidden - position: relative - - .scrollable - max-height: inherit - overflow: hidden - zoom: 1 - - &.scroll-x - overflow-x: scroll - - &.scroll-y - overflow-y: scroll - - &.fit - height: 100% - width: 100% - - .scrollable - bottom: 0 - left: 0 - max-height: none - position: absolute - right: 0 - top: 0 - - .scroll-nav - background-color: rgba(0, 0, 0, 0.75) - box-shadow(0 0 10px 10px rgba(0, 0, 0, 0.75)) - cursor: pointer - height: $scrollNavSize - left: 10px - opacity: 0 - position: absolute - right: 10px - transition(transform 0.3s ease\, opacity 0.3s ease\, background-color 0.3s ease\, box-shadow 0.3s ease) - - &:after - theme('color', '$activeColor') - display: block - font-family: FontAwesome - font-size: 20px - text-align: center - transition(color 0.3s ease) - - &:hover - background-color: rgba(0, 0, 0, 0.9) - box-shadow(0 0 10px 10px rgba(0, 0, 0, 0.9)) - - &:after - theme('color', '$hoverColor') - - .scroll-nav-up - border-bottom-left-radius($scrollNavSize / 2) - border-bottom-right-radius($scrollNavSize / 2) - top: 0 - transform(translateY(- $scrollNavSize)) - - &:after - content: '\f102' - - .scroll-nav-down - border-top-left-radius($scrollNavSize / 2) - border-top-right-radius($scrollNavSize / 2) - bottom: 0 - transform(translateY($scrollNavSize)) - - &:after - content: '\f103' - - &.can-scroll-up .scroll-nav-up, - &.can-scroll-down .scroll-nav-down - opacity: 1 - transform(translateY(0)) diff --git a/Packages/ohif-core/client/cornerstone.js b/Packages/ohif-core/client/cornerstone.js deleted file mode 100644 index 65b51de71..000000000 --- a/Packages/ohif-core/client/cornerstone.js +++ /dev/null @@ -1,5 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { MetadataProvider } from './classes/MetadataProvider'; - -OHIF.cornerstone.MetadataProvider = MetadataProvider; - diff --git a/Packages/ohif-core/client/header.js b/Packages/ohif-core/client/header.js deleted file mode 100644 index 7ec438718..000000000 --- a/Packages/ohif-core/client/header.js +++ /dev/null @@ -1,11 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -/* - * Defines the base OHIF header object - */ -const dropdown = new OHIF.ui.Dropdown(); -const header = { dropdown }; - -OHIF.header = header; - -export { header }; diff --git a/Packages/ohif-core/client/helpers/blaze.js b/Packages/ohif-core/client/helpers/blaze.js deleted file mode 100644 index fd71b5943..000000000 --- a/Packages/ohif-core/client/helpers/blaze.js +++ /dev/null @@ -1,32 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Session } from 'meteor/session'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; - -/** - * Global Blaze UI helpers to work with Blaze - */ - -// Return the absolute url -Template.registerHelper('absoluteUrl', path => { - return OHIF.utils.absoluteUrl(path); -}); - -// Return the current template instance -Template.registerHelper('instance', () => { - return Template.instance(); -}); - -// Return the session value for the given key -Template.registerHelper('session', key => { - return Session.get(key); -}); - -// Return the value for given parameter regardless if it's reactive or not -Template.registerHelper('reactive', parameter => { - if (parameter instanceof ReactiveVar) { - return parameter.get(); - } - - return parameter; -}); diff --git a/Packages/ohif-core/client/helpers/data.js b/Packages/ohif-core/client/helpers/data.js deleted file mode 100644 index 13305e011..000000000 --- a/Packages/ohif-core/client/helpers/data.js +++ /dev/null @@ -1,61 +0,0 @@ -import _ from 'underscore'; -import { Template } from 'meteor/templating'; - -/** - * Global Blaze UI helpers to manipulate data - */ - -// Base extend function to be used by extend and clone helpers -const extend = (...argsArray) => { - // Create the resulting object - const result = argsArray[0] || {}; - - // Extract the Spacebars kw hash - const lastArg = _.last(argsArray); - const kwHash = lastArg ? lastArg.hash : null; - - // Extract the given objects - const objects = _.initial(argsArray); - - // Iterate over the given objects - _.each(objects, current => { - // Stop here if the current argument is not an object - if (typeof current !== 'object') { - return; - } - - // Extend the resulting object with the current argument object - _.extend(result, current); - }); - - // Extend the resulting object with the Spacebars kw hash - _.extend(result, kwHash); - - // Return the resulting object - return result; -}; - -// Extend the first argument object it with the other argument objects -Template.registerHelper('extend', (...argsArray) => { - return extend(...argsArray); -}); - -// Create a new object and extends it with the argument objects -Template.registerHelper('clone', (...argsArray) => { - const newArgs = argsArray.slice(); - newArgs.unshift({}); - return extend(...newArgs); -}); - -// Choose the first truthy value in the given values -Template.registerHelper('choose', (...values) => { - let result; - _.each(_.initial(values, 1), value => { - if (result) { - return; - } - - result = value; - }); - return result; -}); diff --git a/Packages/ohif-core/client/helpers/debug.js b/Packages/ohif-core/client/helpers/debug.js deleted file mode 100644 index 217920031..000000000 --- a/Packages/ohif-core/client/helpers/debug.js +++ /dev/null @@ -1,17 +0,0 @@ -import _ from 'underscore'; -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; - -/** - * Global Blaze UI helpers to development debugging - */ - -// Stop here if it's not development environment -if (!Meteor.isDevelopment) { - return; -} - -// Debug some value on console -Template.registerHelper('debug', (...values) => { - console.debug(...values); -}); diff --git a/Packages/ohif-core/client/helpers/index.js b/Packages/ohif-core/client/helpers/index.js deleted file mode 100644 index d0167cc05..000000000 --- a/Packages/ohif-core/client/helpers/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import './blaze.js'; -import './data.js'; -import './debug.js'; -import './logical.js'; -import './number.js'; -import './string.js'; -import './typing.js'; -import './ui.js'; diff --git a/Packages/ohif-core/client/helpers/logical.js b/Packages/ohif-core/client/helpers/logical.js deleted file mode 100644 index daf1a462e..000000000 --- a/Packages/ohif-core/client/helpers/logical.js +++ /dev/null @@ -1,73 +0,0 @@ -import _ from 'underscore'; -import { Template } from 'meteor/templating'; - -/** - * Global Blaze UI helpers to work with logical operations - */ - -// Convert any value into a boolean value -Template.registerHelper('bool', value => { - return !!value; -}); - -// Check if two values are identical -Template.registerHelper('eq', (a, b) => { - return a === b; -}); - -// Check if two values are different -Template.registerHelper('ne', (a, b) => { - return a !== b; -}); - -// Check if the first value is greater than the second one -Template.registerHelper('gt', (a, b) => { - return a > b; -}); - -// Check if the first value is lesser than the second one -Template.registerHelper('lt', (a, b) => { - return a < b; -}); - -// Check if the first value is greater than or equals the second one -Template.registerHelper('gte', (a, b) => { - return a >= b; -}); - -// Check if the first value is lesser than or equals the second one -Template.registerHelper('lte', (a, b) => { - return a <= b; -}); - -// Get the boolean negation for the given value -Template.registerHelper('not', value => { - return !value; -}); - -// Check if all the given values are true -Template.registerHelper('and', (...values) => { - let result = true; - _.each(_.initial(values, 1), value => { - return !value && (result = false); - }); - return result; -}); - -// Check if one of the given values is true -Template.registerHelper('or', (...values) => { - let result = false; - _.each(_.initial(values, 1), value => { - return value && (result = true); - }); - return result; -}); - -// Return the second parameter if the first is true or the third if it's false -Template.registerHelper('valueIf', (condition, valueIfTrue, valueIfFalse) => { - if (condition) { - return valueIfTrue; - } - - return valueIfFalse; -}); diff --git a/Packages/ohif-core/client/helpers/number.js b/Packages/ohif-core/client/helpers/number.js deleted file mode 100644 index b5b7d44a8..000000000 --- a/Packages/ohif-core/client/helpers/number.js +++ /dev/null @@ -1,21 +0,0 @@ -import _ from 'underscore'; -import { Template } from 'meteor/templating'; - -/** - * Global Blaze UI helpers to work with numeric operations - */ - -// Sum all the given numbers -Template.registerHelper('sum', (...values) => { - let result = 0; - _.each(_.initial(values, 1), value => (result += (value | 0))); - return result; -}); - -Template.registerHelper('isValidNumber', value => { - return typeof value === 'number' && !isNaN(value); -}); - -Template.registerHelper('filterNaN', value => { - return isNaN(value) ? '' : value; -}); diff --git a/Packages/ohif-core/client/helpers/string.js b/Packages/ohif-core/client/helpers/string.js deleted file mode 100644 index e6f5a2f42..000000000 --- a/Packages/ohif-core/client/helpers/string.js +++ /dev/null @@ -1,20 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import _ from 'underscore'; -import { Template } from 'meteor/templating'; - -/** - * Global Blaze UI helpers to work with Strings - */ - -// Concatenate the give strings -Template.registerHelper('concat', (...args) => { - const values = _.initial(args, 1); - let result = ''; - _.each(values, value => { - result += typeof value !== 'undefined' ? value : ''; - }); - return result; -}); - -// Encode any string into a safe format for HTML id attribute -Template.registerHelper('encodeId', OHIF.string.encodeId); diff --git a/Packages/ohif-core/client/helpers/typing.js b/Packages/ohif-core/client/helpers/typing.js deleted file mode 100644 index 7b5010d2e..000000000 --- a/Packages/ohif-core/client/helpers/typing.js +++ /dev/null @@ -1,21 +0,0 @@ -import _ from 'underscore'; -import { Template } from 'meteor/templating'; - -/** - * Global Blaze UI helpers to work with Strings - */ - -// Check if the value's type is undefined -Template.registerHelper('isUndefined', value => { - return _.isUndefined(value); -}); - -// Check if the value's type is object -Template.registerHelper('isObject', value => { - return _.isObject(value); -}); - -// Check if the value is an array instance -Template.registerHelper('isArray', value => { - return _.isArray(value); -}); diff --git a/Packages/ohif-core/client/helpers/ui.js b/Packages/ohif-core/client/helpers/ui.js deleted file mode 100644 index ad8bfffbc..000000000 --- a/Packages/ohif-core/client/helpers/ui.js +++ /dev/null @@ -1,11 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Template } from 'meteor/templating'; - -/** - * Global Blaze UI helpers - */ - -// Access OHIF.uiSettings object -Template.registerHelper('uiSettings', () => { - return OHIF.uiSettings; -}); diff --git a/Packages/ohif-core/client/hotkeys.js b/Packages/ohif-core/client/hotkeys.js deleted file mode 100644 index 168fdc83e..000000000 --- a/Packages/ohif-core/client/hotkeys.js +++ /dev/null @@ -1,12 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { HotkeysManager } from './classes/HotkeysManager'; -import 'jquery.hotkeys'; - -// Create hotkeys namespace using a HotkeysManager class instance -const hotkeys = new HotkeysManager(); - -// Append hotkeys namespace to OHIF namespace -OHIF.hotkeys = hotkeys; - -// Export relevant objects -export { hotkeys }; diff --git a/Packages/ohif-core/client/ie.js b/Packages/ohif-core/client/ie.js deleted file mode 100644 index b40cbb5d2..000000000 --- a/Packages/ohif-core/client/ie.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import writeScript from './lib/writeScript'; - -// Check if browser is IE and add the polyfill scripts -if (navigator && /MSIE \d|Trident.*rv:/.test(navigator.userAgent)) { - Meteor.startup(() => { - window.onload = () => { - // Fix SVG+USE issues by calling the SVG polyfill - writeScript('svgxuse.min.js'); - }; - }); -} diff --git a/Packages/ohif-core/client/index.js b/Packages/ohif-core/client/index.js deleted file mode 100644 index de0ac5ddb..000000000 --- a/Packages/ohif-core/client/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import './studies.js'; -import './lib'; -import './helpers'; -import './commands'; -import './hotkeys'; -import './components'; -import './ui'; -import './header.js'; -import './schema.js'; -import './utils/'; -import './metadata.js'; -import './startup.js'; -import './classes/'; -import './cornerstone.js'; -import './classes.js'; diff --git a/Packages/ohif-core/client/lib/DICOMTagDescriptions.js b/Packages/ohif-core/client/lib/DICOMTagDescriptions.js deleted file mode 100644 index d76965e25..000000000 --- a/Packages/ohif-core/client/lib/DICOMTagDescriptions.js +++ /dev/null @@ -1,3260 +0,0 @@ -// TODO: Deprecate since we have the same thing in dcmjs? -const NUMBER = 'number'; -const STRING = 'string'; -const REGEX_TAG = /^x[0-9a-fx]{8}$/; - -const DICOMTagDescriptions = Object.create(Object.prototype, { - _descriptions: { - configurable: false, - enumerable: false, - writable: false, - value: Object.create(null) - }, - tagNumberToString: { - configurable: false, - enumerable: true, - writable: false, - value: function tagNumberToString(tag) { - let string; // by default, undefined is returned... - if (this.isValidTagNumber(tag)) { - // if it's a number, build its hexadecimal representation... - string = 'x' + ('00000000' + tag.toString(16)).substr(-8); - } - return string; - } - }, - isValidTagNumber: { - configurable: false, - enumerable: true, - writable: false, - value: function isValidTagNumber(tag) { - return (typeof tag === NUMBER && tag >= 0 && tag <= 0xFFFFFFFF); - } - }, - isValidTag: { - configurable: false, - enumerable: true, - writable: false, - value: function isValidTag(tag) { - return (typeof tag === STRING ? REGEX_TAG.test(tag) : this.isValidTagNumber(tag)); - } - }, - find: { - configurable: false, - enumerable: true, - writable: false, - value: function find(name) { - let description; // by default, undefined is returned... - if (typeof name !== STRING) { - // if it's a number, a tag string will be returned... - name = this.tagNumberToString(name); - } - if (typeof name === STRING) { - description = this._descriptions[name]; - } - return description; - } - }, - init: { - configurable: false, - enumerable: true, - writable: false, - value: function init(descriptionMap) { - const _hasOwn = Object.prototype.hasOwnProperty; - const _descriptions = this._descriptions; - for (let tag in descriptionMap) { - if (_hasOwn.call(descriptionMap, tag)) { - if (!this.isValidTag(tag)) { - // Skip in case tag is not valid... - console.info(`DICOMTagDescriptions: Invalid tag "${tag}"...`); - continue; - } - if (tag in _descriptions) { - // Skip in case the tag is duplicated... - console.info(`DICOMTagDescriptions: Duplicated tag "${tag}"...`); - continue; - } - // Save keyword... - const keyword = descriptionMap[tag]; - // Create a description entry and freeze it... - const entry = Object.create(null); - entry.tag = tag; - entry.keyword = keyword; - Object.freeze(entry); - // Add tag references to entry... - _descriptions[tag] = entry; - // Add keyword references to entry (if not present already)... - if (keyword in _descriptions) { - const currentEntry = _descriptions[keyword]; - console.info(`DICOMTagDescriptions: Using <${currentEntry.tag},${currentEntry.keyword}> instead of <${entry.tag},${entry.keyword}> for keyword "${keyword}"...`); - } else { - _descriptions[keyword] = entry; - } - } - } - // Freeze internal description map... - Object.freeze(_descriptions); - // Freeze itself... - Object.freeze(this); - } - }, -}); - -/** - * Map with DICOM Tag Descriptions - */ -let initialTagDescriptionMap = { - x00020000: 'FileMetaInfoGroupLength', - x00020001: 'FileMetaInfoVersion', - x00020002: 'MediaStorageSOPClassUID', - x00020003: 'MediaStorageSOPInstanceUID', - x00020010: 'TransferSyntaxUID', - x00020012: 'ImplementationClassUID', - x00020013: 'ImplementationVersionName', - x00020016: 'SourceApplicationEntityTitle', - x00020100: 'PrivateInformationCreatorUID', - x00020102: 'PrivateInformation', - x00041130: 'FileSetID', - x00041141: 'FileSetDescriptorFileID', - x00041142: 'SpecificCharacterSetOfFile', - x00041200: 'FirstDirectoryRecordOffset', - x00041202: 'LastDirectoryRecordOffset', - x00041212: 'FileSetConsistencyFlag', - x00041220: 'DirectoryRecordSequence', - x00041400: 'OffsetOfNextDirectoryRecord', - x00041410: 'RecordInUseFlag', - x00041420: 'LowerLevelDirectoryEntityOffset', - x00041430: 'DirectoryRecordType', - x00041432: 'PrivateRecordUID', - x00041500: 'ReferencedFileID', - x00041504: 'MRDRDirectoryRecordOffset', - x00041510: 'ReferencedSOPClassUIDInFile', - x00041511: 'ReferencedSOPInstanceUIDInFile', - x00041512: 'ReferencedTransferSyntaxUIDInFile', - x0004151a: 'ReferencedRelatedSOPClassUIDInFile', - x00041600: 'NumberOfReferences', - x00080000: 'IdentifyingGroupLength', - x00080001: 'LengthToEnd', - x00080005: 'SpecificCharacterSet', - x00080006: 'LanguageCodeSequence', - x00080008: 'ImageType', - x00080010: 'RecognitionCode', - x00080012: 'InstanceCreationDate', - x00080013: 'InstanceCreationTime', - x00080014: 'InstanceCreatorUID', - x00080016: 'SOPClassUID', - x00080018: 'SOPInstanceUID', - x0008001a: 'RelatedGeneralSOPClassUID', - x0008001b: 'OriginalSpecializedSOPClassUID', - x00080020: 'StudyDate', - x00080021: 'SeriesDate', - x00080022: 'AcquisitionDate', - x00080023: 'ContentDate', - x00080024: 'OverlayDate', - x00080025: 'CurveDate', - x0008002a: 'AcquisitionDateTime', - x00080030: 'StudyTime', - x00080031: 'SeriesTime', - x00080032: 'AcquisitionTime', - x00080033: 'ContentTime', - x00080034: 'OverlayTime', - x00080035: 'CurveTime', - x00080040: 'DataSetType', - x00080041: 'DataSetSubtype', - x00080042: 'NuclearMedicineSeriesType', - x00080050: 'AccessionNumber', - x00080052: 'QueryRetrieveLevel', - x00080054: 'RetrieveAETitle', - x00080056: 'InstanceAvailability', - x00080058: 'FailedSOPInstanceUIDList', - x00080060: 'Modality', - x00080061: 'ModalitiesInStudy', - x00080062: 'SOPClassesInStudy', - x00080064: 'ConversionType', - x00080068: 'PresentationIntentType', - x00080070: 'Manufacturer', - x00080080: 'InstitutionName', - x00080081: 'InstitutionAddress', - x00080082: 'InstitutionCodeSequence', - x00080090: 'ReferringPhysicianName', - x00080092: 'ReferringPhysicianAddress', - x00080094: 'ReferringPhysicianTelephoneNumber', - x00080096: 'ReferringPhysicianIDSequence', - x00080100: 'CodeValue', - x00080102: 'CodingSchemeDesignator', - x00080103: 'CodingSchemeVersion', - x00080104: 'CodeMeaning', - x00080105: 'MappingResource', - x00080106: 'ContextGroupVersion', - x00080107: 'ContextGroupLocalVersion', - x0008010b: 'ContextGroupExtensionFlag', - x0008010c: 'CodingSchemeUID', - x0008010d: 'ContextGroupExtensionCreatorUID', - x0008010f: 'ContextIdentifier', - x00080110: 'CodingSchemeIDSequence', - x00080112: 'CodingSchemeRegistry', - x00080114: 'CodingSchemeExternalID', - x00080115: 'CodingSchemeName', - x00080116: 'CodingSchemeResponsibleOrganization', - x00080117: 'ContextUID', - x00080201: 'TimezoneOffsetFromUTC', - x00081000: 'NetworkID', - x00081010: 'StationName', - x00081030: 'StudyDescription', - x00081032: 'ProcedureCodeSequence', - x0008103e: 'SeriesDescription', - x00081040: 'InstitutionalDepartmentName', - x00081048: 'PhysiciansOfRecord', - x00081049: 'PhysiciansOfRecordIDSequence', - x00081050: 'PerformingPhysicianName', - x00081052: 'PerformingPhysicianIDSequence', - x00081060: 'NameOfPhysicianReadingStudy', - x00081062: 'PhysicianReadingStudyIDSequence', - x00081070: 'OperatorsName', - x00081072: 'OperatorIDSequence', - x00081080: 'AdmittingDiagnosesDescription', - x00081084: 'AdmittingDiagnosesCodeSequence', - x00081090: 'ManufacturersModelName', - x00081100: 'ReferencedResultsSequence', - x00081110: 'ReferencedStudySequence', - x00081111: 'ReferencedPerformedProcedureStepSequence', - x00081115: 'ReferencedSeriesSequence', - x00081120: 'ReferencedPatientSequence', - x00081125: 'ReferencedVisitSequence', - x00081130: 'ReferencedOverlaySequence', - x0008113a: 'ReferencedWaveformSequence', - x00081140: 'ReferencedImageSequence', - x00081145: 'ReferencedCurveSequence', - x0008114a: 'ReferencedInstanceSequence', - x00081150: 'ReferencedSOPClassUID', - x00081155: 'ReferencedSOPInstanceUID', - x0008115a: 'SOPClassesSupported', - x00081160: 'ReferencedFrameNumber', - x00081161: 'SimpleFrameList', - x00081162: 'CalculatedFrameList', - x00081163: 'TimeRange', - x00081164: 'FrameExtractionSequence', - x00081195: 'TransactionUID', - x00081197: 'FailureReason', - x00081198: 'FailedSOPSequence', - x00081199: 'ReferencedSOPSequence', - x00081200: 'OtherReferencedStudiesSequence', - x00081250: 'RelatedSeriesSequence', - x00082110: 'LossyImageCompressionRetired', - x00082111: 'DerivationDescription', - x00082112: 'SourceImageSequence', - x00082120: 'StageName', - x00082122: 'StageNumber', - x00082124: 'NumberOfStages', - x00082127: 'ViewName', - x00082128: 'ViewNumber', - x00082129: 'NumberOfEventTimers', - x0008212a: 'NumberOfViewsInStage', - x00082130: 'EventElapsedTimes', - x00082132: 'EventTimerNames', - x00082133: 'EventTimerSequence', - x00082134: 'EventTimeOffset', - x00082135: 'EventCodeSequence', - x00082142: 'StartTrim', - x00082143: 'StopTrim', - x00082144: 'RecommendedDisplayFrameRate', - x00082200: 'TransducerPosition', - x00082204: 'TransducerOrientation', - x00082208: 'AnatomicStructure', - x00082218: 'AnatomicRegionSequence', - x00082220: 'AnatomicRegionModifierSequence', - x00082228: 'PrimaryAnatomicStructureSequence', - x00082229: 'AnatomicStructureOrRegionSequence', - x00082230: 'AnatomicStructureModifierSequence', - x00082240: 'TransducerPositionSequence', - x00082242: 'TransducerPositionModifierSequence', - x00082244: 'TransducerOrientationSequence', - x00082246: 'TransducerOrientationModifierSeq', - x00082253: 'AnatomicEntrancePortalCodeSeqTrial', - x00082255: 'AnatomicApproachDirCodeSeqTrial', - x00082256: 'AnatomicPerspectiveDescrTrial', - x00082257: 'AnatomicPerspectiveCodeSeqTrial', - x00083001: 'AlternateRepresentationSequence', - x00083010: 'IrradiationEventUID', - x00084000: 'IdentifyingComments', - x00089007: 'FrameType', - x00089092: 'ReferencedImageEvidenceSequence', - x00089121: 'ReferencedRawDataSequence', - x00089123: 'CreatorVersionUID', - x00089124: 'DerivationImageSequence', - x00089154: 'SourceImageEvidenceSequence', - x00089205: 'PixelPresentation', - x00089206: 'VolumetricProperties', - x00089207: 'VolumeBasedCalculationTechnique', - x00089208: 'ComplexImageComponent', - x00089209: 'AcquisitionContrast', - x00089215: 'DerivationCodeSequence', - x00089237: 'GrayscalePresentationStateSequence', - x00089410: 'ReferencedOtherPlaneSequence', - x00089458: 'FrameDisplaySequence', - x00089459: 'RecommendedDisplayFrameRateInFloat', - x00089460: 'SkipFrameRangeFlag', - // x00091001: 'FullFidelity', - // x00091002: 'SuiteID', - // x00091004: 'ProductID', - // x00091027: 'ImageActualDate', - // x00091030: 'ServiceID', - // x00091031: 'MobileLocationNumber', - // x000910e3: 'EquipmentUID', - // x000910e6: 'GenesisVersionNow', - // x000910e7: 'ExamRecordChecksum', - // x000910e9: 'ActualSeriesDataTimeStamp', - x00100000: 'PatientGroupLength', - x00100010: 'PatientName', - x00100020: 'PatientID', - x00100021: 'IssuerOfPatientID', - x00100022: 'TypeOfPatientID', - x00100030: 'PatientBirthDate', - x00100032: 'PatientBirthTime', - x00100040: 'PatientSex', - x00100050: 'PatientInsurancePlanCodeSequence', - x00100101: 'PatientPrimaryLanguageCodeSeq', - x00100102: 'PatientPrimaryLanguageCodeModSeq', - x00101000: 'OtherPatientIDs', - x00101001: 'OtherPatientNames', - x00101002: 'OtherPatientIDsSequence', - x00101005: 'PatientBirthName', - x00101010: 'PatientAge', - x00101020: 'PatientSize', - x00101030: 'PatientWeight', - x00101040: 'PatientAddress', - x00101050: 'InsurancePlanIdentification', - x00101060: 'PatientMotherBirthName', - x00101080: 'MilitaryRank', - x00101081: 'BranchOfService', - x00101090: 'MedicalRecordLocator', - x00102000: 'MedicalAlerts', - x00102110: 'Allergies', - x00102150: 'CountryOfResidence', - x00102152: 'RegionOfResidence', - x00102154: 'PatientTelephoneNumbers', - x00102160: 'EthnicGroup', - x00102180: 'Occupation', - x001021a0: 'SmokingStatus', - x001021b0: 'AdditionalPatientHistory', - x001021c0: 'PregnancyStatus', - x001021d0: 'LastMenstrualDate', - x001021f0: 'PatientReligiousPreference', - x00102201: 'PatientSpeciesDescription', - x00102202: 'PatientSpeciesCodeSequence', - x00102203: 'PatientSexNeutered', - x00102210: 'AnatomicalOrientationType', - x00102292: 'PatientBreedDescription', - x00102293: 'PatientBreedCodeSequence', - x00102294: 'BreedRegistrationSequence', - x00102295: 'BreedRegistrationNumber', - x00102296: 'BreedRegistryCodeSequence', - x00102297: 'ResponsiblePerson', - x00102298: 'ResponsiblePersonRole', - x00102299: 'ResponsibleOrganization', - x00104000: 'PatientComments', - x00109431: 'ExaminedBodyThickness', - x00111010: 'PatientStatus', - x00120010: 'ClinicalTrialSponsorName', - x00120020: 'ClinicalTrialProtocolID', - x00120021: 'ClinicalTrialProtocolName', - x00120030: 'ClinicalTrialSiteID', - x00120031: 'ClinicalTrialSiteName', - x00120040: 'ClinicalTrialSubjectID', - x00120042: 'ClinicalTrialSubjectReadingID', - x00120050: 'ClinicalTrialTimePointID', - x00120051: 'ClinicalTrialTimePointDescription', - x00120060: 'ClinicalTrialCoordinatingCenter', - x00120062: 'PatientIdentityRemoved', - x00120063: 'DeidentificationMethod', - x00120064: 'DeidentificationMethodCodeSequence', - x00120071: 'ClinicalTrialSeriesID', - x00120072: 'ClinicalTrialSeriesDescription', - x00120084: 'DistributionType', - x00120085: 'ConsentForDistributionFlag', - x00180000: 'AcquisitionGroupLength', - x00180010: 'ContrastBolusAgent', - x00180012: 'ContrastBolusAgentSequence', - x00180014: 'ContrastBolusAdministrationRoute', - x00180015: 'BodyPartExamined', - x00180020: 'ScanningSequence', - x00180021: 'SequenceVariant', - x00180022: 'ScanOptions', - x00180023: 'MRAcquisitionType', - x00180024: 'SequenceName', - x00180025: 'AngioFlag', - x00180026: 'InterventionDrugInformationSeq', - x00180027: 'InterventionDrugStopTime', - x00180028: 'InterventionDrugDose', - x00180029: 'InterventionDrugSequence', - x0018002a: 'AdditionalDrugSequence', - x00180030: 'Radionuclide', - x00180031: 'Radiopharmaceutical', - x00180032: 'EnergyWindowCenterline', - x00180033: 'EnergyWindowTotalWidth', - x00180034: 'InterventionDrugName', - x00180035: 'InterventionDrugStartTime', - x00180036: 'InterventionSequence', - x00180037: 'TherapyType', - x00180038: 'InterventionStatus', - x00180039: 'TherapyDescription', - x0018003a: 'InterventionDescription', - x00180040: 'CineRate', - x00180042: 'InitialCineRunState', - x00180050: 'SliceThickness', - x00180060: 'KVP', - x00180070: 'CountsAccumulated', - x00180071: 'AcquisitionTerminationCondition', - x00180072: 'EffectiveDuration', - x00180073: 'AcquisitionStartCondition', - x00180074: 'AcquisitionStartConditionData', - x00180075: 'AcquisitionEndConditionData', - x00180080: 'RepetitionTime', - x00180081: 'EchoTime', - x00180082: 'InversionTime', - x00180083: 'NumberOfAverages', - x00180084: 'ImagingFrequency', - x00180085: 'ImagedNucleus', - x00180086: 'EchoNumber', - x00180087: 'MagneticFieldStrength', - x00180088: 'SpacingBetweenSlices', - x00180089: 'NumberOfPhaseEncodingSteps', - x00180090: 'DataCollectionDiameter', - x00180091: 'EchoTrainLength', - x00180093: 'PercentSampling', - x00180094: 'PercentPhaseFieldOfView', - x00180095: 'PixelBandwidth', - x00181000: 'DeviceSerialNumber', - x00181002: 'DeviceUID', - x00181003: 'DeviceID', - x00181004: 'PlateID', - x00181005: 'GeneratorID', - x00181006: 'GridID', - x00181007: 'CassetteID', - x00181008: 'GantryID', - x00181010: 'SecondaryCaptureDeviceID', - x00181011: 'HardcopyCreationDeviceID', - x00181012: 'DateOfSecondaryCapture', - x00181014: 'TimeOfSecondaryCapture', - x00181016: 'SecondaryCaptureDeviceManufacturer', - x00181017: 'HardcopyDeviceManufacturer', - x00181018: 'SecondaryCaptureDeviceModelName', - x00181019: 'SecondaryCaptureDeviceSoftwareVers', - x0018101a: 'HardcopyDeviceSoftwareVersion', - x0018101b: 'HardcopyDeviceModelName', - x00181020: 'SoftwareVersion', - x00181022: 'VideoImageFormatAcquired', - x00181023: 'DigitalImageFormatAcquired', - x00181030: 'ProtocolName', - x00181040: 'ContrastBolusRoute', - x00181041: 'ContrastBolusVolume', - x00181042: 'ContrastBolusStartTime', - x00181043: 'ContrastBolusStopTime', - x00181044: 'ContrastBolusTotalDose', - x00181045: 'SyringeCounts', - x00181046: 'ContrastFlowRate', - x00181047: 'ContrastFlowDuration', - x00181048: 'ContrastBolusIngredient', - x00181049: 'ContrastBolusConcentration', - x00181050: 'SpatialResolution', - x00181060: 'TriggerTime', - x00181061: 'TriggerSourceOrType', - x00181062: 'NominalInterval', - x00181063: 'FrameTime', - x00181064: 'CardiacFramingType', - x00181065: 'FrameTimeVector', - x00181066: 'FrameDelay', - x00181067: 'ImageTriggerDelay', - x00181068: 'MultiplexGroupTimeOffset', - x00181069: 'TriggerTimeOffset', - x0018106a: 'SynchronizationTrigger', - x0018106c: 'SynchronizationChannel', - x0018106e: 'TriggerSamplePosition', - x00181070: 'RadiopharmaceuticalRoute', - x00181071: 'RadiopharmaceuticalVolume', - x00181072: 'RadiopharmaceuticalStartTime', - x00181073: 'RadiopharmaceuticalStopTime', - x00181074: 'RadionuclideTotalDose', - x00181075: 'RadionuclideHalfLife', - x00181076: 'RadionuclidePositronFraction', - x00181077: 'RadiopharmaceuticalSpecActivity', - x00181078: 'RadiopharmaceuticalStartDateTime', - x00181079: 'RadiopharmaceuticalStopDateTime', - x00181080: 'BeatRejectionFlag', - x00181081: 'LowRRValue', - x00181082: 'HighRRValue', - x00181083: 'IntervalsAcquired', - x00181084: 'IntervalsRejected', - x00181085: 'PVCRejection', - x00181086: 'SkipBeats', - x00181088: 'HeartRate', - x00181090: 'CardiacNumberOfImages', - x00181094: 'TriggerWindow', - x00181100: 'ReconstructionDiameter', - x00181110: 'DistanceSourceToDetector', - x00181111: 'DistanceSourceToPatient', - x00181114: 'EstimatedRadiographicMagnification', - x00181120: 'GantryDetectorTilt', - x00181121: 'GantryDetectorSlew', - x00181130: 'TableHeight', - x00181131: 'TableTraverse', - x00181134: 'TableMotion', - x00181135: 'TableVerticalIncrement', - x00181136: 'TableLateralIncrement', - x00181137: 'TableLongitudinalIncrement', - x00181138: 'TableAngle', - x0018113a: 'TableType', - x00181140: 'RotationDirection', - x00181141: 'AngularPosition', - x00181142: 'RadialPosition', - x00181143: 'ScanArc', - x00181144: 'AngularStep', - x00181145: 'CenterOfRotationOffset', - x00181146: 'RotationOffset', - x00181147: 'FieldOfViewShape', - x00181149: 'FieldOfViewDimensions', - x00181150: 'ExposureTime', - x00181151: 'XRayTubeCurrent', - x00181152: 'Exposure', - x00181153: 'ExposureInMicroAmpSec', - x00181154: 'AveragePulseWidth', - x00181155: 'RadiationSetting', - x00181156: 'RectificationType', - x0018115a: 'RadiationMode', - x0018115e: 'ImageAreaDoseProduct', - x00181160: 'FilterType', - x00181161: 'TypeOfFilters', - x00181162: 'IntensifierSize', - x00181164: 'ImagerPixelSpacing', - x00181166: 'Grid', - x00181170: 'GeneratorPower', - x00181180: 'CollimatorGridName', - x00181181: 'CollimatorType', - x00181182: 'FocalDistance', - x00181183: 'XFocusCenter', - x00181184: 'YFocusCenter', - x00181190: 'FocalSpots', - x00181191: 'AnodeTargetMaterial', - x001811a0: 'BodyPartThickness', - x001811a2: 'CompressionForce', - x00181200: 'DateOfLastCalibration', - x00181201: 'TimeOfLastCalibration', - x00181210: 'ConvolutionKernel', - x00181240: 'UpperLowerPixelValues', - x00181242: 'ActualFrameDuration', - x00181243: 'CountRate', - x00181244: 'PreferredPlaybackSequencing', - x00181250: 'ReceiveCoilName', - x00181251: 'TransmitCoilName', - x00181260: 'PlateType', - x00181261: 'PhosphorType', - x00181300: 'ScanVelocity', - x00181301: 'WholeBodyTechnique', - x00181302: 'ScanLength', - x00181310: 'AcquisitionMatrix', - x00181312: 'InPlanePhaseEncodingDirection', - x00181314: 'FlipAngle', - x00181315: 'VariableFlipAngleFlag', - x00181316: 'SAR', - x00181318: 'DB-Dt', - x00181400: 'AcquisitionDeviceProcessingDescr', - x00181401: 'AcquisitionDeviceProcessingCode', - x00181402: 'CassetteOrientation', - x00181403: 'CassetteSize', - x00181404: 'ExposuresOnPlate', - x00181405: 'RelativeXRayExposure', - x00181450: 'ColumnAngulation', - x00181460: 'TomoLayerHeight', - x00181470: 'TomoAngle', - x00181480: 'TomoTime', - x00181490: 'TomoType', - x00181491: 'TomoClass', - x00181495: 'NumberOfTomosynthesisSourceImages', - x00181500: 'PositionerMotion', - x00181508: 'PositionerType', - x00181510: 'PositionerPrimaryAngle', - x00181511: 'PositionerSecondaryAngle', - x00181520: 'PositionerPrimaryAngleIncrement', - x00181521: 'PositionerSecondaryAngleIncrement', - x00181530: 'DetectorPrimaryAngle', - x00181531: 'DetectorSecondaryAngle', - x00181600: 'ShutterShape', - x00181602: 'ShutterLeftVerticalEdge', - x00181604: 'ShutterRightVerticalEdge', - x00181606: 'ShutterUpperHorizontalEdge', - x00181608: 'ShutterLowerHorizontalEdge', - x00181610: 'CenterOfCircularShutter', - x00181612: 'RadiusOfCircularShutter', - x00181620: 'VerticesOfPolygonalShutter', - x00181622: 'ShutterPresentationValue', - x00181623: 'ShutterOverlayGroup', - x00181624: 'ShutterPresentationColorCIELabVal', - x00181700: 'CollimatorShape', - x00181702: 'CollimatorLeftVerticalEdge', - x00181704: 'CollimatorRightVerticalEdge', - x00181706: 'CollimatorUpperHorizontalEdge', - x00181708: 'CollimatorLowerHorizontalEdge', - x00181710: 'CenterOfCircularCollimator', - x00181712: 'RadiusOfCircularCollimator', - x00181720: 'VerticesOfPolygonalCollimator', - x00181800: 'AcquisitionTimeSynchronized', - x00181801: 'TimeSource', - x00181802: 'TimeDistributionProtocol', - x00181803: 'NTPSourceAddress', - x00182001: 'PageNumberVector', - x00182002: 'FrameLabelVector', - x00182003: 'FramePrimaryAngleVector', - x00182004: 'FrameSecondaryAngleVector', - x00182005: 'SliceLocationVector', - x00182006: 'DisplayWindowLabelVector', - x00182010: 'NominalScannedPixelSpacing', - x00182020: 'DigitizingDeviceTransportDirection', - x00182030: 'RotationOfScannedFilm', - x00183100: 'IVUSAcquisition', - x00183101: 'IVUSPullbackRate', - x00183102: 'IVUSGatedRate', - x00183103: 'IVUSPullbackStartFrameNumber', - x00183104: 'IVUSPullbackStopFrameNumber', - x00183105: 'LesionNumber', - x00184000: 'AcquisitionComments', - x00185000: 'OutputPower', - x00185010: 'TransducerData', - x00185012: 'FocusDepth', - x00185020: 'ProcessingFunction', - x00185021: 'PostprocessingFunction', - x00185022: 'MechanicalIndex', - x00185024: 'BoneThermalIndex', - x00185026: 'CranialThermalIndex', - x00185027: 'SoftTissueThermalIndex', - x00185028: 'SoftTissueFocusThermalIndex', - x00185029: 'SoftTissueSurfaceThermalIndex', - x00185030: 'DynamicRange', - x00185040: 'TotalGain', - x00185050: 'DepthOfScanField', - x00185100: 'PatientPosition', - x00185101: 'ViewPosition', - x00185104: 'ProjectionEponymousNameCodeSeq', - x00185210: 'ImageTransformationMatrix', - x00185212: 'ImageTranslationVector', - x00186000: 'Sensitivity', - x00186011: 'SequenceOfUltrasoundRegions', - x00186012: 'RegionSpatialFormat', - x00186014: 'RegionDataType', - x00186016: 'RegionFlags', - x00186018: 'RegionLocationMinX0', - x0018601a: 'RegionLocationMinY0', - x0018601c: 'RegionLocationMaxX1', - x0018601e: 'RegionLocationMaxY1', - x00186020: 'ReferencePixelX0', - x00186022: 'ReferencePixelY0', - x00186024: 'PhysicalUnitsXDirection', - x00186026: 'PhysicalUnitsYDirection', - x00186028: 'ReferencePixelPhysicalValueX', - x0018602a: 'ReferencePixelPhysicalValueY', - x0018602c: 'PhysicalDeltaX', - x0018602e: 'PhysicalDeltaY', - x00186030: 'TransducerFrequency', - x00186031: 'TransducerType', - x00186032: 'PulseRepetitionFrequency', - x00186034: 'DopplerCorrectionAngle', - x00186036: 'SteeringAngle', - x00186038: 'DopplerSampleVolumeXPosRetired', - x00186039: 'DopplerSampleVolumeXPosition', - x0018603a: 'DopplerSampleVolumeYPosRetired', - x0018603b: 'DopplerSampleVolumeYPosition', - x0018603c: 'TMLinePositionX0Retired', - x0018603d: 'TMLinePositionX0', - x0018603e: 'TMLinePositionY0Retired', - x0018603f: 'TMLinePositionY0', - x00186040: 'TMLinePositionX1Retired', - x00186041: 'TMLinePositionX1', - x00186042: 'TMLinePositionY1Retired', - x00186043: 'TMLinePositionY1', - x00186044: 'PixelComponentOrganization', - x00186046: 'PixelComponentMask', - x00186048: 'PixelComponentRangeStart', - x0018604a: 'PixelComponentRangeStop', - x0018604c: 'PixelComponentPhysicalUnits', - x0018604e: 'PixelComponentDataType', - x00186050: 'NumberOfTableBreakPoints', - x00186052: 'TableOfXBreakPoints', - x00186054: 'TableOfYBreakPoints', - x00186056: 'NumberOfTableEntries', - x00186058: 'TableOfPixelValues', - x0018605a: 'TableOfParameterValues', - x00186060: 'RWaveTimeVector', - x00187000: 'DetectorConditionsNominalFlag', - x00187001: 'DetectorTemperature', - x00187004: 'DetectorType', - x00187005: 'DetectorConfiguration', - x00187006: 'DetectorDescription', - x00187008: 'DetectorMode', - x0018700a: 'DetectorID', - x0018700c: 'DateOfLastDetectorCalibration', - x0018700e: 'TimeOfLastDetectorCalibration', - x00187010: 'DetectorExposuresSinceCalibration', - x00187011: 'DetectorExposuresSinceManufactured', - x00187012: 'DetectorTimeSinceLastExposure', - x00187014: 'DetectorActiveTime', - x00187016: 'DetectorActiveOffsetFromExposure', - x0018701a: 'DetectorBinning', - x00187020: 'DetectorElementPhysicalSize', - x00187022: 'DetectorElementSpacing', - x00187024: 'DetectorActiveShape', - x00187026: 'DetectorActiveDimensions', - x00187028: 'DetectorActiveOrigin', - x0018702a: 'DetectorManufacturerName', - x0018702b: 'DetectorManufacturersModelName', - x00187030: 'FieldOfViewOrigin', - x00187032: 'FieldOfViewRotation', - x00187034: 'FieldOfViewHorizontalFlip', - x00187040: 'GridAbsorbingMaterial', - x00187041: 'GridSpacingMaterial', - x00187042: 'GridThickness', - x00187044: 'GridPitch', - x00187046: 'GridAspectRatio', - x00187048: 'GridPeriod', - x0018704c: 'GridFocalDistance', - x00187050: 'FilterMaterial', - x00187052: 'FilterThicknessMinimum', - x00187054: 'FilterThicknessMaximum', - x00187060: 'ExposureControlMode', - x00187062: 'ExposureControlModeDescription', - x00187064: 'ExposureStatus', - x00187065: 'PhototimerSetting', - x00188150: 'ExposureTimeInMicroSec', - x00188151: 'XRayTubeCurrentInMicroAmps', - x00189004: 'ContentQualification', - x00189005: 'PulseSequenceName', - x00189006: 'MRImagingModifierSequence', - x00189008: 'EchoPulseSequence', - x00189009: 'InversionRecovery', - x00189010: 'FlowCompensation', - x00189011: 'MultipleSpinEcho', - x00189012: 'MultiPlanarExcitation', - x00189014: 'PhaseContrast', - x00189015: 'TimeOfFlightContrast', - x00189016: 'Spoiling', - x00189017: 'SteadyStatePulseSequence', - x00189018: 'EchoPlanarPulseSequence', - x00189019: 'TagAngleFirstAxis', - x00189020: 'MagnetizationTransfer', - x00189021: 'T2Preparation', - x00189022: 'BloodSignalNulling', - x00189024: 'SaturationRecovery', - x00189025: 'SpectrallySelectedSuppression', - x00189026: 'SpectrallySelectedExcitation', - x00189027: 'SpatialPresaturation', - x00189028: 'Tagging', - x00189029: 'OversamplingPhase', - x00189030: 'TagSpacingFirstDimension', - x00189032: 'GeometryOfKSpaceTraversal', - x00189033: 'SegmentedKSpaceTraversal', - x00189034: 'RectilinearPhaseEncodeReordering', - x00189035: 'TagThickness', - x00189036: 'PartialFourierDirection', - x00189037: 'CardiacSynchronizationTechnique', - x00189041: 'ReceiveCoilManufacturerName', - x00189042: 'MRReceiveCoilSequence', - x00189043: 'ReceiveCoilType', - x00189044: 'QuadratureReceiveCoil', - x00189045: 'MultiCoilDefinitionSequence', - x00189046: 'MultiCoilConfiguration', - x00189047: 'MultiCoilElementName', - x00189048: 'MultiCoilElementUsed', - x00189049: 'MRTransmitCoilSequence', - x00189050: 'TransmitCoilManufacturerName', - x00189051: 'TransmitCoilType', - x00189052: 'SpectralWidth', - x00189053: 'ChemicalShiftReference', - x00189054: 'VolumeLocalizationTechnique', - x00189058: 'MRAcquisitionFrequencyEncodeSteps', - x00189059: 'Decoupling', - x00189060: 'DecoupledNucleus', - x00189061: 'DecouplingFrequency', - x00189062: 'DecouplingMethod', - x00189063: 'DecouplingChemicalShiftReference', - x00189064: 'KSpaceFiltering', - x00189065: 'TimeDomainFiltering', - x00189066: 'NumberOfZeroFills', - x00189067: 'BaselineCorrection', - x00189069: 'ParallelReductionFactorInPlane', - x00189070: 'CardiacRRIntervalSpecified', - x00189073: 'AcquisitionDuration', - x00189074: 'FrameAcquisitionDateTime', - x00189075: 'DiffusionDirectionality', - x00189076: 'DiffusionGradientDirectionSequence', - x00189077: 'ParallelAcquisition', - x00189078: 'ParallelAcquisitionTechnique', - x00189079: 'InversionTimes', - x00189080: 'MetaboliteMapDescription', - x00189081: 'PartialFourier', - x00189082: 'EffectiveEchoTime', - x00189083: 'MetaboliteMapCodeSequence', - x00189084: 'ChemicalShiftSequence', - x00189085: 'CardiacSignalSource', - x00189087: 'DiffusionBValue', - x00189089: 'DiffusionGradientOrientation', - x00189090: 'VelocityEncodingDirection', - x00189091: 'VelocityEncodingMinimumValue', - x00189093: 'NumberOfKSpaceTrajectories', - x00189094: 'CoverageOfKSpace', - x00189095: 'SpectroscopyAcquisitionPhaseRows', - x00189096: 'ParallelReductFactorInPlaneRetired', - x00189098: 'TransmitterFrequency', - x00189100: 'ResonantNucleus', - x00189101: 'FrequencyCorrection', - x00189103: 'MRSpectroscopyFOV-GeometrySequence', - x00189104: 'SlabThickness', - x00189105: 'SlabOrientation', - x00189106: 'MidSlabPosition', - x00189107: 'MRSpatialSaturationSequence', - x00189112: 'MRTimingAndRelatedParametersSeq', - x00189114: 'MREchoSequence', - x00189115: 'MRModifierSequence', - x00189117: 'MRDiffusionSequence', - x00189118: 'CardiacTriggerSequence', - x00189119: 'MRAveragesSequence', - x00189125: 'MRFOV-GeometrySequence', - x00189126: 'VolumeLocalizationSequence', - x00189127: 'SpectroscopyAcquisitionDataColumns', - x00189147: 'DiffusionAnisotropyType', - x00189151: 'FrameReferenceDateTime', - x00189152: 'MRMetaboliteMapSequence', - x00189155: 'ParallelReductionFactorOutOfPlane', - x00189159: 'SpectroscopyOutOfPlanePhaseSteps', - x00189166: 'BulkMotionStatus', - x00189168: 'ParallelReductionFactSecondInPlane', - x00189169: 'CardiacBeatRejectionTechnique', - x00189170: 'RespiratoryMotionCompTechnique', - x00189171: 'RespiratorySignalSource', - x00189172: 'BulkMotionCompensationTechnique', - x00189173: 'BulkMotionSignalSource', - x00189174: 'ApplicableSafetyStandardAgency', - x00189175: 'ApplicableSafetyStandardDescr', - x00189176: 'OperatingModeSequence', - x00189177: 'OperatingModeType', - x00189178: 'OperatingMode', - x00189179: 'SpecificAbsorptionRateDefinition', - x00189180: 'GradientOutputType', - x00189181: 'SpecificAbsorptionRateValue', - x00189182: 'GradientOutput', - x00189183: 'FlowCompensationDirection', - x00189184: 'TaggingDelay', - x00189185: 'RespiratoryMotionCompTechDescr', - x00189186: 'RespiratorySignalSourceID', - x00189195: 'ChemicalShiftsMinIntegrateLimitHz', - x00189196: 'ChemicalShiftsMaxIntegrateLimitHz', - x00189197: 'MRVelocityEncodingSequence', - x00189198: 'FirstOrderPhaseCorrection', - x00189199: 'WaterReferencedPhaseCorrection', - x00189200: 'MRSpectroscopyAcquisitionType', - x00189214: 'RespiratoryCyclePosition', - x00189217: 'VelocityEncodingMaximumValue', - x00189218: 'TagSpacingSecondDimension', - x00189219: 'TagAngleSecondAxis', - x00189220: 'FrameAcquisitionDuration', - x00189226: 'MRImageFrameTypeSequence', - x00189227: 'MRSpectroscopyFrameTypeSequence', - x00189231: 'MRAcqPhaseEncodingStepsInPlane', - x00189232: 'MRAcqPhaseEncodingStepsOutOfPlane', - x00189234: 'SpectroscopyAcqPhaseColumns', - x00189236: 'CardiacCyclePosition', - x00189239: 'SpecificAbsorptionRateSequence', - x00189240: 'RFEchoTrainLength', - x00189241: 'GradientEchoTrainLength', - x00189295: 'ChemicalShiftsMinIntegrateLimitPPM', - x00189296: 'ChemicalShiftsMaxIntegrateLimitPPM', - x00189301: 'CTAcquisitionTypeSequence', - x00189302: 'AcquisitionType', - x00189303: 'TubeAngle', - x00189304: 'CTAcquisitionDetailsSequence', - x00189305: 'RevolutionTime', - x00189306: 'SingleCollimationWidth', - x00189307: 'TotalCollimationWidth', - x00189308: 'CTTableDynamicsSequence', - x00189309: 'TableSpeed', - x00189310: 'TableFeedPerRotation', - x00189311: 'SpiralPitchFactor', - x00189312: 'CTGeometrySequence', - x00189313: 'DataCollectionCenterPatient', - x00189314: 'CTReconstructionSequence', - x00189315: 'ReconstructionAlgorithm', - x00189316: 'ConvolutionKernelGroup', - x00189317: 'ReconstructionFieldOfView', - x00189318: 'ReconstructionTargetCenterPatient', - x00189319: 'ReconstructionAngle', - x00189320: 'ImageFilter', - x00189321: 'CTExposureSequence', - x00189322: 'ReconstructionPixelSpacing', - x00189323: 'ExposureModulationType', - x00189324: 'EstimatedDoseSaving', - x00189325: 'CTXRayDetailsSequence', - x00189326: 'CTPositionSequence', - x00189327: 'TablePosition', - x00189328: 'ExposureTimeInMilliSec', - x00189329: 'CTImageFrameTypeSequence', - x00189330: 'XRayTubeCurrentInMilliAmps', - x00189332: 'ExposureInMilliAmpSec', - x00189333: 'ConstantVolumeFlag', - x00189334: 'FluoroscopyFlag', - x00189335: 'SourceToDataCollectionCenterDist', - x00189337: 'ContrastBolusAgentNumber', - x00189338: 'ContrastBolusIngredientCodeSeq', - x00189340: 'ContrastAdministrationProfileSeq', - x00189341: 'ContrastBolusUsageSequence', - x00189342: 'ContrastBolusAgentAdministered', - x00189343: 'ContrastBolusAgentDetected', - x00189344: 'ContrastBolusAgentPhase', - x00189345: 'CTDIvol', - x00189346: 'CTDIPhantomTypeCodeSequence', - x00189351: 'CalciumScoringMassFactorPatient', - x00189352: 'CalciumScoringMassFactorDevice', - x00189353: 'EnergyWeightingFactor', - x00189360: 'CTAdditionalXRaySourceSequence', - x00189401: 'ProjectionPixelCalibrationSequence', - x00189402: 'DistanceSourceToIsocenter', - x00189403: 'DistanceObjectToTableTop', - x00189404: 'ObjectPixelSpacingInCenterOfBeam', - x00189405: 'PositionerPositionSequence', - x00189406: 'TablePositionSequence', - x00189407: 'CollimatorShapeSequence', - x00189412: 'XA-XRFFrameCharacteristicsSequence', - x00189417: 'FrameAcquisitionSequence', - x00189420: 'XRayReceptorType', - x00189423: 'AcquisitionProtocolName', - x00189424: 'AcquisitionProtocolDescription', - x00189425: 'ContrastBolusIngredientOpaque', - x00189426: 'DistanceReceptorPlaneToDetHousing', - x00189427: 'IntensifierActiveShape', - x00189428: 'IntensifierActiveDimensions', - x00189429: 'PhysicalDetectorSize', - x00189430: 'PositionOfIsocenterProjection', - x00189432: 'FieldOfViewSequence', - x00189433: 'FieldOfViewDescription', - x00189434: 'ExposureControlSensingRegionsSeq', - x00189435: 'ExposureControlSensingRegionShape', - x00189436: 'ExposureControlSensRegionLeftEdge', - x00189437: 'ExposureControlSensRegionRightEdge', - x00189440: 'CenterOfCircExposControlSensRegion', - x00189441: 'RadiusOfCircExposControlSensRegion', - x00189447: 'ColumnAngulationPatient', - x00189449: 'BeamAngle', - x00189451: 'FrameDetectorParametersSequence', - x00189452: 'CalculatedAnatomyThickness', - x00189455: 'CalibrationSequence', - x00189456: 'ObjectThicknessSequence', - x00189457: 'PlaneIdentification', - x00189461: 'FieldOfViewDimensionsInFloat', - x00189462: 'IsocenterReferenceSystemSequence', - x00189463: 'PositionerIsocenterPrimaryAngle', - x00189464: 'PositionerIsocenterSecondaryAngle', - x00189465: 'PositionerIsocenterDetRotAngle', - x00189466: 'TableXPositionToIsocenter', - x00189467: 'TableYPositionToIsocenter', - x00189468: 'TableZPositionToIsocenter', - x00189469: 'TableHorizontalRotationAngle', - x00189470: 'TableHeadTiltAngle', - x00189471: 'TableCradleTiltAngle', - x00189472: 'FrameDisplayShutterSequence', - x00189473: 'AcquiredImageAreaDoseProduct', - x00189474: 'CArmPositionerTabletopRelationship', - x00189476: 'XRayGeometrySequence', - x00189477: 'IrradiationEventIDSequence', - x00189504: 'XRay3DFrameTypeSequence', - x00189506: 'ContributingSourcesSequence', - x00189507: 'XRay3DAcquisitionSequence', - x00189508: 'PrimaryPositionerScanArc', - x00189509: 'SecondaryPositionerScanArc', - x00189510: 'PrimaryPositionerScanStartAngle', - x00189511: 'SecondaryPositionerScanStartAngle', - x00189514: 'PrimaryPositionerIncrement', - x00189515: 'SecondaryPositionerIncrement', - x00189516: 'StartAcquisitionDateTime', - x00189517: 'EndAcquisitionDateTime', - x00189524: 'ApplicationName', - x00189525: 'ApplicationVersion', - x00189526: 'ApplicationManufacturer', - x00189527: 'AlgorithmType', - x00189528: 'AlgorithmDescription', - x00189530: 'XRay3DReconstructionSequence', - x00189531: 'ReconstructionDescription', - x00189538: 'PerProjectionAcquisitionSequence', - x00189601: 'DiffusionBMatrixSequence', - x00189602: 'DiffusionBValueXX', - x00189603: 'DiffusionBValueXY', - x00189604: 'DiffusionBValueXZ', - x00189605: 'DiffusionBValueYY', - x00189606: 'DiffusionBValueYZ', - x00189607: 'DiffusionBValueZZ', - x00189701: 'DecayCorrectionDateTime', - x00189715: 'StartDensityThreshold', - x00189722: 'TerminationTimeThreshold', - x00189725: 'DetectorGeometry', - x00189727: 'AxialDetectorDimension', - x00189735: 'PETPositionSequence', - x00189739: 'NumberOfIterations', - x00189740: 'NumberOfSubsets', - x00189751: 'PETFrameTypeSequence', - x00189756: 'ReconstructionType', - x00189758: 'DecayCorrected', - x00189759: 'AttenuationCorrected', - x00189760: 'ScatterCorrected', - x00189761: 'DeadTimeCorrected', - x00189762: 'GantryMotionCorrected', - x00189763: 'PatientMotionCorrected', - x00189765: 'RandomsCorrected', - x00189767: 'SensitivityCalibrated', - x00189801: 'DepthsOfFocus', - x00189804: 'ExclusionStartDatetime', - x00189805: 'ExclusionDuration', - x00189807: 'ImageDataTypeSequence', - x00189808: 'DataType', - x0018980b: 'AliasedDataType', - x0018a001: 'ContributingEquipmentSequence', - x0018a002: 'ContributionDateTime', - x0018a003: 'ContributionDescription', - // x00191002: 'NumberOfCellsIInDetector', - // x00191003: 'CellNumberAtTheta', - // x00191004: 'CellSpacing', - // x0019100f: 'HorizFrameOfRef', - // x00191011: 'SeriesContrast', - // x00191012: 'LastPseq', - // x00191013: 'StartNumberForBaseline', - // x00191014: 'EndNumberForBaseline', - // x00191015: 'StartNumberForEnhancedScans', - // x00191016: 'EndNumberForEnhancedScans', - // x00191017: 'SeriesPlane', - // x00191018: 'FirstScanRas', - // x00191019: 'FirstScanLocation', - // x0019101a: 'LastScanRas', - // x0019101b: 'LastScanLoc', - // x0019101e: 'DisplayFieldOfView', - // x00191023: 'TableSpeed', - // x00191024: 'MidScanTime', - // x00191025: 'MidScanFlag', - // x00191026: 'DegreesOfAzimuth', - // x00191027: 'GantryPeriod', - // x0019102a: 'XRayOnPosition', - // x0019102b: 'XRayOffPosition', - // x0019102c: 'NumberOfTriggers', - // x0019102e: 'AngleOfFirstView', - // x0019102f: 'TriggerFrequency', - // x00191039: 'ScanFOVType', - // x00191040: 'StatReconFlag', - // x00191041: 'ComputeType', - // x00191042: 'SegmentNumber', - // x00191043: 'TotalSegmentsRequested', - // x00191044: 'InterscanDelay', - // x00191047: 'ViewCompressionFactor', - // x0019104a: 'TotalNoOfRefChannels', - // x0019104b: 'DataSizeForScanData', - // x00191052: 'ReconPostProcflag', - // x00191057: 'CTWaterNumber', - // x00191058: 'CTBoneNumber', - // x0019105a: 'AcquisitionDuration', - // x0019105e: 'NumberOfChannels', - // x0019105f: 'IncrementBetweenChannels', - // x00191060: 'StartingView', - // x00191061: 'NumberOfViews', - // x00191062: 'IncrementBetweenViews', - // x0019106a: 'DependantOnNoViewsProcessed', - // x0019106b: 'FieldOfViewInDetectorCells', - // x00191070: 'ValueOfBackProjectionButton', - // x00191071: 'SetIfFatqEstimatesWereUsed', - // x00191072: 'ZChanAvgOverViews', - // x00191073: 'AvgOfLeftRefChansOverViews', - // x00191074: 'MaxLeftChanOverViews', - // x00191075: 'AvgOfRightRefChansOverViews', - // x00191076: 'MaxRightChanOverViews', - // x0019107d: 'SecondEcho', - // x0019107e: 'NumberOfEchoes', - // x0019107f: 'TableDelta', - // x00191081: 'Contiguous', - // x00191084: 'PeakSAR', - // x00191085: 'MonitorSAR', - // x00191087: 'CardiacRepetitionTime', - // x00191088: 'ImagesPerCardiacCycle', - // x0019108a: 'ActualReceiveGainAnalog', - // x0019108b: 'ActualReceiveGainDigital', - // x0019108d: 'DelayAfterTrigger', - // x0019108f: 'Swappf', - // x00191090: 'PauseInterval', - // x00191091: 'PulseTime', - // x00191092: 'SliceOffsetOnFreqAxis', - // x00191093: 'CenterFrequency', - // x00191094: 'TransmitGain', - // x00191095: 'AnalogReceiverGain', - // x00191096: 'DigitalReceiverGain', - // x00191097: 'BitmapDefiningCVs', - // x00191098: 'CenterFreqMethod', - // x0019109b: 'PulseSeqMode', - // x0019109c: 'PulseSeqName', - // x0019109d: 'PulseSeqDate', - // x0019109e: 'InternalPulseSeqName', - // x0019109f: 'TransmittingCoil', - // x001910a0: 'SurfaceCoilType', - // x001910a1: 'ExtremityCoilFlag', - // x001910a2: 'RawDataRunNumber', - // x001910a3: 'CalibratedFieldStrength', - // x001910a4: 'SATFatWaterBone', - // x001910a5: 'ReceiveBandwidth', - // x001910a7: 'UserData01', - // x001910a8: 'UserData02', - // x001910a9: 'UserData03', - // x001910aa: 'UserData04', - // x001910ab: 'UserData05', - // x001910ac: 'UserData06', - // x001910ad: 'UserData07', - // x001910ae: 'UserData08', - // x001910af: 'UserData09', - // x001910b0: 'UserData10', - // x001910b1: 'UserData11', - // x001910b2: 'UserData12', - // x001910b3: 'UserData13', - // x001910b4: 'UserData14', - // x001910b5: 'UserData15', - // x001910b6: 'UserData16', - // x001910b7: 'UserData17', - // x001910b8: 'UserData18', - // x001910b9: 'UserData19', - // x001910ba: 'UserData20', - // x001910bb: 'UserData21', - // x001910bc: 'UserData22', - // x001910bd: 'UserData23', - // x001910be: 'ProjectionAngle', - // x001910c0: 'SaturationPlanes', - // x001910c1: 'SurfaceCoilIntensity', - // x001910c2: 'SATLocationR', - // x001910c3: 'SATLocationL', - // x001910c4: 'SATLocationA', - // x001910c5: 'SATLocationP', - // x001910c6: 'SATLocationH', - // x001910c7: 'SATLocationF', - // x001910c8: 'SATThicknessR-L', - // x001910c9: 'SATThicknessA-P', - // x001910ca: 'SATThicknessH-F', - // x001910cb: 'PrescribedFlowAxis', - // x001910cc: 'VelocityEncoding', - // x001910cd: 'ThicknessDisclaimer', - // x001910ce: 'PrescanType', - // x001910cf: 'PrescanStatus', - // x001910d0: 'RawDataType', - // x001910d2: 'ProjectionAlgorithm', - // x001910d3: 'ProjectionAlgorithm', - // x001910d5: 'FractionalEcho', - // x001910d6: 'PrepPulse', - // x001910d7: 'CardiacPhases', - // x001910d8: 'VariableEchoflag', - // x001910d9: 'ConcatenatedSAT', - // x001910da: 'ReferenceChannelUsed', - // x001910db: 'BackProjectorCoefficient', - // x001910dc: 'PrimarySpeedCorrectionUsed', - // x001910dd: 'OverrangeCorrectionUsed', - // x001910de: 'DynamicZAlphaValue', - // x001910df: 'UserData', - // x001910e0: 'UserData', - // x001910e2: 'VelocityEncodeScale', - // x001910f2: 'FastPhases', - // x001910f9: 'TransmissionGain', - x00200000: 'RelationshipGroupLength', - x0020000d: 'StudyInstanceUID', - x0020000e: 'SeriesInstanceUID', - x00200010: 'StudyID', - x00200011: 'SeriesNumber', - x00200012: 'AcquisitionNumber', - x00200013: 'InstanceNumber', - x00200014: 'IsotopeNumber', - x00200015: 'PhaseNumber', - x00200016: 'IntervalNumber', - x00200017: 'TimeSlotNumber', - x00200018: 'AngleNumber', - x00200019: 'ItemNumber', - x00200020: 'PatientOrientation', - x00200022: 'OverlayNumber', - x00200024: 'CurveNumber', - x00200026: 'LookupTableNumber', - x00200030: 'ImagePosition', - x00200032: 'ImagePositionPatient', - x00200035: 'ImageOrientation', - x00200037: 'ImageOrientationPatient', - x00200050: 'Location', - x00200052: 'FrameOfReferenceUID', - x00200060: 'Laterality', - x00200062: 'ImageLaterality', - x00200070: 'ImageGeometryType', - x00200080: 'MaskingImage', - x00200100: 'TemporalPositionIdentifier', - x00200105: 'NumberOfTemporalPositions', - x00200110: 'TemporalResolution', - x00200200: 'SynchronizationFrameOfReferenceUID', - x00201000: 'SeriesInStudy', - x00201001: 'AcquisitionsInSeries', - x00201002: 'ImagesInAcquisition', - x00201003: 'ImagesInSeries', - x00201004: 'AcquisitionsInStudy', - x00201005: 'ImagesInStudy', - x00201020: 'Reference', - x00201040: 'PositionReferenceIndicator', - x00201041: 'SliceLocation', - x00201070: 'OtherStudyNumbers', - x00201200: 'NumberOfPatientRelatedStudies', - x00201202: 'NumberOfPatientRelatedSeries', - x00201204: 'NumberOfPatientRelatedInstances', - x00201206: 'NumberOfStudyRelatedSeries', - x00201208: 'NumberOfStudyRelatedInstances', - x00201209: 'NumberOfSeriesRelatedInstances', - x002031xx: 'SourceImageIDs', - x00203401: 'ModifyingDeviceID', - x00203402: 'ModifiedImageID', - x00203403: 'ModifiedImageDate', - x00203404: 'ModifyingDeviceManufacturer', - x00203405: 'ModifiedImageTime', - x00203406: 'ModifiedImageDescription', - x00204000: 'ImageComments', - x00205000: 'OriginalImageIdentification', - x00205002: 'OriginalImageIdentNomenclature', - x00209056: 'StackID', - x00209057: 'InStackPositionNumber', - x00209071: 'FrameAnatomySequence', - x00209072: 'FrameLaterality', - x00209111: 'FrameContentSequence', - x00209113: 'PlanePositionSequence', - x00209116: 'PlaneOrientationSequence', - x00209128: 'TemporalPositionIndex', - x00209153: 'TriggerDelayTime', - x00209156: 'FrameAcquisitionNumber', - x00209157: 'DimensionIndexValues', - x00209158: 'FrameComments', - x00209161: 'ConcatenationUID', - x00209162: 'InConcatenationNumber', - x00209163: 'InConcatenationTotalNumber', - x00209164: 'DimensionOrganizationUID', - x00209165: 'DimensionIndexPointer', - x00209167: 'FunctionalGroupPointer', - x00209213: 'DimensionIndexPrivateCreator', - x00209221: 'DimensionOrganizationSequence', - x00209222: 'DimensionIndexSequence', - x00209228: 'ConcatenationFrameOffsetNumber', - x00209238: 'FunctionalGroupPrivateCreator', - x00209241: 'NominalPercentageOfCardiacPhase', - x00209245: 'NominalPercentOfRespiratoryPhase', - x00209246: 'StartingRespiratoryAmplitude', - x00209247: 'StartingRespiratoryPhase', - x00209248: 'EndingRespiratoryAmplitude', - x00209249: 'EndingRespiratoryPhase', - x00209250: 'RespiratoryTriggerType', - x00209251: 'RRIntervalTimeNominal', - x00209252: 'ActualCardiacTriggerDelayTime', - x00209253: 'RespiratorySynchronizationSequence', - x00209254: 'RespiratoryIntervalTime', - x00209255: 'NominalRespiratoryTriggerDelayTime', - x00209256: 'RespiratoryTriggerDelayThreshold', - x00209257: 'ActualRespiratoryTriggerDelayTime', - x00209301: 'ImagePositionVolume', - x00209302: 'ImageOrientationVolume', - x00209308: 'ApexPosition', - x00209421: 'DimensionDescriptionLabel', - x00209450: 'PatientOrientationInFrameSequence', - x00209453: 'FrameLabel', - x00209518: 'AcquisitionIndex', - x00209529: 'ContributingSOPInstancesRefSeq', - x00209536: 'ReconstructionIndex', - // x00211003: 'SeriesFromWhichPrescribed', - // x00211005: 'GenesisVersionNow', - // x00211007: 'SeriesRecordChecksum', - // x00211018: 'GenesisVersionNow', - // x00211019: 'AcqreconRecordChecksum', - // x00211020: 'TableStartLocation', - // x00211035: 'SeriesFromWhichPrescribed', - // x00211036: 'ImageFromWhichPrescribed', - // x00211037: 'ScreenFormat', - // x0021104a: 'AnatomicalReferenceForScout', - // x0021104f: 'LocationsInAcquisition', - // x00211050: 'GraphicallyPrescribed', - // x00211051: 'RotationFromSourceXRot', - // x00211052: 'RotationFromSourceYRot', - // x00211053: 'RotationFromSourceZRot', - // x00211054: 'ImagePosition', - // x00211055: 'ImageOrientation', - // x00211056: 'IntegerSlop', - // x00211057: 'IntegerSlop', - // x00211058: 'IntegerSlop', - // x00211059: 'IntegerSlop', - // x0021105a: 'IntegerSlop', - // x0021105b: 'FloatSlop', - // x0021105c: 'FloatSlop', - // x0021105d: 'FloatSlop', - // x0021105e: 'FloatSlop', - // x0021105f: 'FloatSlop', - // x00211081: 'AutoWindowLevelAlpha', - // x00211082: 'AutoWindowLevelBeta', - // x00211083: 'AutoWindowLevelWindow', - // x00211084: 'ToWindowLevelLevel', - // x00211090: 'TubeFocalSpotPosition', - // x00211091: 'BiopsyPosition', - // x00211092: 'BiopsyTLocation', - // x00211093: 'BiopsyRefLocation', - x00220001: 'LightPathFilterPassThroughWavelen', - x00220002: 'LightPathFilterPassBand', - x00220003: 'ImagePathFilterPassThroughWavelen', - x00220004: 'ImagePathFilterPassBand', - x00220005: 'PatientEyeMovementCommanded', - x00220006: 'PatientEyeMovementCommandCodeSeq', - x00220007: 'SphericalLensPower', - x00220008: 'CylinderLensPower', - x00220009: 'CylinderAxis', - x0022000a: 'EmmetropicMagnification', - x0022000b: 'IntraOcularPressure', - x0022000c: 'HorizontalFieldOfView', - x0022000d: 'PupilDilated', - x0022000e: 'DegreeOfDilation', - x00220010: 'StereoBaselineAngle', - x00220011: 'StereoBaselineDisplacement', - x00220012: 'StereoHorizontalPixelOffset', - x00220013: 'StereoVerticalPixelOffset', - x00220014: 'StereoRotation', - x00220015: 'AcquisitionDeviceTypeCodeSequence', - x00220016: 'IlluminationTypeCodeSequence', - x00220017: 'LightPathFilterTypeStackCodeSeq', - x00220018: 'ImagePathFilterTypeStackCodeSeq', - x00220019: 'LensesCodeSequence', - x0022001a: 'ChannelDescriptionCodeSequence', - x0022001b: 'RefractiveStateSequence', - x0022001c: 'MydriaticAgentCodeSequence', - x0022001d: 'RelativeImagePositionCodeSequence', - x00220020: 'StereoPairsSequence', - x00220021: 'LeftImageSequence', - x00220022: 'RightImageSequence', - x00220030: 'AxialLengthOfTheEye', - x00220031: 'OphthalmicFrameLocationSequence', - x00220032: 'ReferenceCoordinates', - x00220035: 'DepthSpatialResolution', - x00220036: 'MaximumDepthDistortion', - x00220037: 'AlongScanSpatialResolution', - x00220038: 'MaximumAlongScanDistortion', - x00220039: 'OphthalmicImageOrientation', - x00220041: 'DepthOfTransverseImage', - x00220042: 'MydriaticAgentConcUnitsSeq', - x00220048: 'AcrossScanSpatialResolution', - x00220049: 'MaximumAcrossScanDistortion', - x0022004e: 'MydriaticAgentConcentration', - x00220055: 'IlluminationWaveLength', - x00220056: 'IlluminationPower', - x00220057: 'IlluminationBandwidth', - x00220058: 'MydriaticAgentSequence', - // x00231001: 'NumberOfSeriesInStudy', - // x00231002: 'NumberOfUnarchivedSeries', - // x00231010: 'ReferenceImageField', - // x00231050: 'SummaryImage', - // x00231070: 'StartTimeSecsInFirstAxial', - // x00231074: 'NoofUpdatesToHeader', - // x0023107d: 'IndicatesIfTheStudyHasCompleteInfo', - // x00251006: 'LastPulseSequenceUsed', - // x00251007: 'ImagesInSeries', - // x00251010: 'LandmarkCounter', - // x00251011: 'NumberOfAcquisitions', - // x00251014: 'IndicatesNoofUpdatesToHeader', - // x00251017: 'SeriesCompleteFlag', - // x00251018: 'NumberOfImagesArchived', - // x00251019: 'LastImageNumberUsed', - // x0025101a: 'PrimaryReceiverSuiteAndHost', - // x00271006: 'ImageArchiveFlag', - // x00271010: 'ScoutType', - // x0027101c: 'VmaMamp', - // x0027101d: 'VmaPhase', - // x0027101e: 'VmaMod', - // x0027101f: 'VmaClip', - // x00271020: 'SmartScanOnOffFlag', - // x00271030: 'ForeignImageRevision', - // x00271031: 'ImagingMode', - // x00271032: 'PulseSequence', - // x00271033: 'ImagingOptions', - // x00271035: 'PlaneType', - // x00271036: 'ObliquePlane', - // x00271040: 'RASLetterOfImageLocation', - // x00271041: 'ImageLocation', - // x00271042: 'CenterRCoordOfPlaneImage', - // x00271043: 'CenterACoordOfPlaneImage', - // x00271044: 'CenterSCoordOfPlaneImage', - // x00271045: 'NormalRCoord', - // x00271046: 'NormalACoord', - // x00271047: 'NormalSCoord', - // x00271048: 'RCoordOfTopRightCorner', - // x00271049: 'ACoordOfTopRightCorner', - // x0027104a: 'SCoordOfTopRightCorner', - // x0027104b: 'RCoordOfBottomRightCorner', - // x0027104c: 'ACoordOfBottomRightCorner', - // x0027104d: 'SCoordOfBottomRightCorner', - // x00271050: 'TableStartLocation', - // x00271051: 'TableEndLocation', - // x00271052: 'RASLetterForSideOfImage', - // x00271053: 'RASLetterForAnteriorPosterior', - // x00271054: 'RASLetterForScoutStartLoc', - // x00271055: 'RASLetterForScoutEndLoc', - // x00271060: 'ImageDimensionX', - // x00271061: 'ImageDimensionY', - // x00271062: 'NumberOfExcitations', - x00280000: 'ImagePresentationGroupLength', - x00280002: 'SamplesPerPixel', - x00280003: 'SamplesPerPixelUsed', - x00280004: 'PhotometricInterpretation', - x00280005: 'ImageDimensions', - x00280006: 'PlanarConfiguration', - x00280008: 'NumberOfFrames', - x00280009: 'FrameIncrementPointer', - x0028000a: 'FrameDimensionPointer', - x00280010: 'Rows', - x00280011: 'Columns', - x00280012: 'Planes', - x00280014: 'UltrasoundColorDataPresent', - x00280030: 'PixelSpacing', - x00280031: 'ZoomFactor', - x00280032: 'ZoomCenter', - x00280034: 'PixelAspectRatio', - x00280040: 'ImageFormat', - x00280050: 'ManipulatedImage', - x00280051: 'CorrectedImage', - x0028005f: 'CompressionRecognitionCode', - x00280060: 'CompressionCode', - x00280061: 'CompressionOriginator', - x00280062: 'CompressionLabel', - x00280063: 'CompressionDescription', - x00280065: 'CompressionSequence', - x00280066: 'CompressionStepPointers', - x00280068: 'RepeatInterval', - x00280069: 'BitsGrouped', - x00280070: 'PerimeterTable', - x00280071: 'PerimeterValue', - x00280080: 'PredictorRows', - x00280081: 'PredictorColumns', - x00280082: 'PredictorConstants', - x00280090: 'BlockedPixels', - x00280091: 'BlockRows', - x00280092: 'BlockColumns', - x00280093: 'RowOverlap', - x00280094: 'ColumnOverlap', - x00280100: 'BitsAllocated', - x00280101: 'BitsStored', - x00280102: 'HighBit', - x00280103: 'PixelRepresentation', - x00280104: 'SmallestValidPixelValue', - x00280105: 'LargestValidPixelValue', - x00280106: 'SmallestImagePixelValue', - x00280107: 'LargestImagePixelValue', - x00280108: 'SmallestPixelValueInSeries', - x00280109: 'LargestPixelValueInSeries', - x00280110: 'SmallestImagePixelValueInPlane', - x00280111: 'LargestImagePixelValueInPlane', - x00280120: 'PixelPaddingValue', - x00280121: 'PixelPaddingRangeLimit', - x00280200: 'ImageLocation', - x00280300: 'QualityControlImage', - x00280301: 'BurnedInAnnotation', - x00280400: 'TransformLabel', - x00280401: 'TransformVersionNumber', - x00280402: 'NumberOfTransformSteps', - x00280403: 'SequenceOfCompressedData', - x00280404: 'DetailsOfCoefficients', - x002804x2: 'CoefficientCoding', - x002804x3: 'CoefficientCodingPointers', - x00280700: 'DCTLabel', - x00280701: 'DataBlockDescription', - x00280702: 'DataBlock', - x00280710: 'NormalizationFactorFormat', - x00280720: 'ZonalMapNumberFormat', - x00280721: 'ZonalMapLocation', - x00280722: 'ZonalMapFormat', - x00280730: 'AdaptiveMapFormat', - x00280740: 'CodeNumberFormat', - x002808x0: 'CodeLabel', - x002808x2: 'NumberOfTables', - x002808x3: 'CodeTableLocation', - x002808x4: 'BitsForCodeWord', - x002808x8: 'ImageDataLocation', - x00280a02: 'PixelSpacingCalibrationType', - x00280a04: 'PixelSpacingCalibrationDescription', - x00281040: 'PixelIntensityRelationship', - x00281041: 'PixelIntensityRelationshipSign', - x00281050: 'WindowCenter', - x00281051: 'WindowWidth', - x00281052: 'RescaleIntercept', - x00281053: 'RescaleSlope', - x00281054: 'RescaleType', - x00281055: 'WindowCenterAndWidthExplanation', - x00281056: 'VOI_LUTFunction', - x00281080: 'GrayScale', - x00281090: 'RecommendedViewingMode', - x00281100: 'GrayLookupTableDescriptor', - x00281101: 'RedPaletteColorTableDescriptor', - x00281102: 'GreenPaletteColorTableDescriptor', - x00281103: 'BluePaletteColorTableDescriptor', - x00281111: 'LargeRedPaletteColorTableDescr', - x00281112: 'LargeGreenPaletteColorTableDescr', - x00281113: 'LargeBluePaletteColorTableDescr', - x00281199: 'PaletteColorTableUID', - x00281200: 'GrayLookupTableData', - x00281201: 'RedPaletteColorTableData', - x00281202: 'GreenPaletteColorTableData', - x00281203: 'BluePaletteColorTableData', - x00281211: 'LargeRedPaletteColorTableData', - x00281212: 'LargeGreenPaletteColorTableData', - x00281213: 'LargeBluePaletteColorTableData', - x00281214: 'LargePaletteColorLookupTableUID', - x00281221: 'SegmentedRedColorTableData', - x00281222: 'SegmentedGreenColorTableData', - x00281223: 'SegmentedBlueColorTableData', - x00281300: 'BreastImplantPresent', - x00281350: 'PartialView', - x00281351: 'PartialViewDescription', - x00281352: 'PartialViewCodeSequence', - x0028135a: 'SpatialLocationsPreserved', - x00281402: 'DataPathAssignment', - x00281404: 'BlendingLUT1Sequence', - x00281406: 'BlendingWeightConstant', - x00281408: 'BlendingLookupTableData', - x0028140c: 'BlendingLUT2Sequence', - x0028140e: 'DataPathID', - x0028140f: 'RGBLUTTransferFunction', - x00281410: 'AlphaLUTTransferFunction', - x00282000: 'ICCProfile', - x00282110: 'LossyImageCompression', - x00282112: 'LossyImageCompressionRatio', - x00282114: 'LossyImageCompressionMethod', - x00283000: 'ModalityLUTSequence', - x00283002: 'LUTDescriptor', - x00283003: 'LUTExplanation', - x00283004: 'ModalityLUTType', - x00283006: 'LUTData', - x00283010: 'VOILUTSequence', - x00283110: 'SoftcopyVOILUTSequence', - x00284000: 'ImagePresentationComments', - x00285000: 'BiPlaneAcquisitionSequence', - x00286010: 'RepresentativeFrameNumber', - x00286020: 'FrameNumbersOfInterest', - x00286022: 'FrameOfInterestDescription', - x00286023: 'FrameOfInterestType', - x00286030: 'MaskPointers', - x00286040: 'RWavePointer', - x00286100: 'MaskSubtractionSequence', - x00286101: 'MaskOperation', - x00286102: 'ApplicableFrameRange', - x00286110: 'MaskFrameNumbers', - x00286112: 'ContrastFrameAveraging', - x00286114: 'MaskSubPixelShift', - x00286120: 'TIDOffset', - x00286190: 'MaskOperationExplanation', - x00287fe0: 'PixelDataProviderURL', - x00289001: 'DataPointRows', - x00289002: 'DataPointColumns', - x00289003: 'SignalDomainColumns', - x00289099: 'LargestMonochromePixelValue', - x00289108: 'DataRepresentation', - x00289110: 'PixelMeasuresSequence', - x00289132: 'FrameVOILUTSequence', - x00289145: 'PixelValueTransformationSequence', - x00289235: 'SignalDomainRows', - x00289411: 'DisplayFilterPercentage', - x00289415: 'FramePixelShiftSequence', - x00289416: 'SubtractionItemID', - x00289422: 'PixelIntensityRelationshipLUTSeq', - x00289443: 'FramePixelDataPropertiesSequence', - x00289444: 'GeometricalProperties', - x00289445: 'GeometricMaximumDistortion', - x00289446: 'ImageProcessingApplied', - x00289454: 'MaskSelectionMode', - x00289474: 'LUTFunction', - x00289478: 'MaskVisibilityPercentage', - x00289501: 'PixelShiftSequence', - x00289502: 'RegionPixelShiftSequence', - x00289503: 'VerticesOfTheRegion', - x00289506: 'PixelShiftFrameRange', - x00289507: 'LUTFrameRange', - x00289520: 'ImageToEquipmentMappingMatrix', - x00289537: 'EquipmentCoordinateSystemID', - // x00291004: 'LowerRangeOfPixels1a', - // x00291005: 'LowerRangeOfPixels1b', - // x00291006: 'LowerRangeOfPixels1c', - // x00291007: 'LowerRangeOfPixels1d', - // x00291008: 'LowerRangeOfPixels1e', - // x00291009: 'LowerRangeOfPixels1f', - // x0029100a: 'LowerRangeOfPixels1g', - // x00291015: 'LowerRangeOfPixels1h', - // x00291016: 'LowerRangeOfPixels1i', - // x00291017: 'LowerRangeOfPixels2', - // x00291018: 'UpperRangeOfPixels2', - // x0029101a: 'LenOfTotHdrInBytes', - // x00291026: 'VersionOfTheHdrStruct', - // x00291034: 'AdvantageCompOverflow', - // x00291035: 'AdvantageCompUnderflow', - x00320000: 'StudyGroupLength', - x0032000a: 'StudyStatusID', - x0032000c: 'StudyPriorityID', - x00320012: 'StudyIDIssuer', - x00320032: 'StudyVerifiedDate', - x00320033: 'StudyVerifiedTime', - x00320034: 'StudyReadDate', - x00320035: 'StudyReadTime', - x00321000: 'ScheduledStudyStartDate', - x00321001: 'ScheduledStudyStartTime', - x00321010: 'ScheduledStudyStopDate', - x00321011: 'ScheduledStudyStopTime', - x00321020: 'ScheduledStudyLocation', - x00321021: 'ScheduledStudyLocationAETitle', - x00321030: 'ReasonForStudy', - x00321031: 'RequestingPhysicianIDSequence', - x00321032: 'RequestingPhysician', - x00321033: 'RequestingService', - x00321040: 'StudyArrivalDate', - x00321041: 'StudyArrivalTime', - x00321050: 'StudyCompletionDate', - x00321051: 'StudyCompletionTime', - x00321055: 'StudyComponentStatusID', - x00321060: 'RequestedProcedureDescription', - x00321064: 'RequestedProcedureCodeSequence', - x00321070: 'RequestedContrastAgent', - x00324000: 'StudyComments', - x00380004: 'ReferencedPatientAliasSequence', - x00380008: 'VisitStatusID', - x00380010: 'AdmissionID', - x00380011: 'IssuerOfAdmissionID', - x00380016: 'RouteOfAdmissions', - x0038001a: 'ScheduledAdmissionDate', - x0038001b: 'ScheduledAdmissionTime', - x0038001c: 'ScheduledDischargeDate', - x0038001d: 'ScheduledDischargeTime', - x0038001e: 'ScheduledPatientInstitResidence', - x00380020: 'AdmittingDate', - x00380021: 'AdmittingTime', - x00380030: 'DischargeDate', - x00380032: 'DischargeTime', - x00380040: 'DischargeDiagnosisDescription', - x00380044: 'DischargeDiagnosisCodeSequence', - x00380050: 'SpecialNeeds', - x00380060: 'ServiceEpisodeID', - x00380061: 'IssuerOfServiceEpisodeID', - x00380062: 'ServiceEpisodeDescription', - x00380100: 'PertinentDocumentsSequence', - x00380300: 'CurrentPatientLocation', - x00380400: 'PatientInstitutionResidence', - x00380500: 'PatientState', - x00380502: 'PatientClinicalTrialParticipSeq', - x00384000: 'VisitComments', - x003a0004: 'WaveformOriginality', - x003a0005: 'NumberOfWaveformChannels', - x003a0010: 'NumberOfWaveformSamples', - x003a001a: 'SamplingFrequency', - x003a0020: 'MultiplexGroupLabel', - x003a0200: 'ChannelDefinitionSequence', - x003a0202: 'WaveformChannelNumber', - x003a0203: 'ChannelLabel', - x003a0205: 'ChannelStatus', - x003a0208: 'ChannelSourceSequence', - x003a0209: 'ChannelSourceModifiersSequence', - x003a020a: 'SourceWaveformSequence', - x003a020c: 'ChannelDerivationDescription', - x003a0210: 'ChannelSensitivity', - x003a0211: 'ChannelSensitivityUnitsSequence', - x003a0212: 'ChannelSensitivityCorrectionFactor', - x003a0213: 'ChannelBaseline', - x003a0214: 'ChannelTimeSkew', - x003a0215: 'ChannelSampleSkew', - x003a0218: 'ChannelOffset', - x003a021a: 'WaveformBitsStored', - x003a0220: 'FilterLowFrequency', - x003a0221: 'FilterHighFrequency', - x003a0222: 'NotchFilterFrequency', - x003a0223: 'NotchFilterBandwidth', - x003a0230: 'WaveformDataDisplayScale', - x003a0231: 'WaveformDisplayBkgCIELabValue', - x003a0240: 'WaveformPresentationGroupSequence', - x003a0241: 'PresentationGroupNumber', - x003a0242: 'ChannelDisplaySequence', - x003a0244: 'ChannelRecommendDisplayCIELabValue', - x003a0245: 'ChannelPosition', - x003a0246: 'DisplayShadingFlag', - x003a0247: 'FractionalChannelDisplayScale', - x003a0248: 'AbsoluteChannelDisplayScale', - x003a0300: 'MultiplexAudioChannelsDescrCodeSeq', - x003a0301: 'ChannelIdentificationCode', - x003a0302: 'ChannelMode', - x00400001: 'ScheduledStationAETitle', - x00400002: 'ScheduledProcedureStepStartDate', - x00400003: 'ScheduledProcedureStepStartTime', - x00400004: 'ScheduledProcedureStepEndDate', - x00400005: 'ScheduledProcedureStepEndTime', - x00400006: 'ScheduledPerformingPhysiciansName', - x00400007: 'ScheduledProcedureStepDescription', - x00400008: 'ScheduledProtocolCodeSequence', - x00400009: 'ScheduledProcedureStepID', - x0040000a: 'StageCodeSequence', - x0040000b: 'ScheduledPerformingPhysicianIDSeq', - x00400010: 'ScheduledStationName', - x00400011: 'ScheduledProcedureStepLocation', - x00400012: 'PreMedication', - x00400020: 'ScheduledProcedureStepStatus', - x00400031: 'LocalNamespaceEntityID', - x00400032: 'UniversalEntityID', - x00400033: 'UniversalEntityIDType', - x00400035: 'IdentifierTypeCode', - x00400036: 'AssigningFacilitySequence', - x00400100: 'ScheduledProcedureStepSequence', - x00400220: 'ReferencedNonImageCompositeSOPSeq', - x00400241: 'PerformedStationAETitle', - x00400242: 'PerformedStationName', - x00400243: 'PerformedLocation', - x00400244: 'PerformedProcedureStepStartDate', - x00400245: 'PerformedProcedureStepStartTime', - x00400250: 'PerformedProcedureStepEndDate', - x00400251: 'PerformedProcedureStepEndTime', - x00400252: 'PerformedProcedureStepStatus', - x00400253: 'PerformedProcedureStepID', - x00400254: 'PerformedProcedureStepDescription', - x00400255: 'PerformedProcedureTypeDescription', - x00400260: 'PerformedProtocolCodeSequence', - x00400261: 'PerformedProtocolType', - x00400270: 'ScheduledStepAttributesSequence', - x00400275: 'RequestAttributesSequence', - x00400280: 'CommentsOnPerformedProcedureStep', - x00400281: 'ProcStepDiscontinueReasonCodeSeq', - x00400293: 'QuantitySequence', - x00400294: 'Quantity', - x00400295: 'MeasuringUnitsSequence', - x00400296: 'BillingItemSequence', - x00400300: 'TotalTimeOfFluoroscopy', - x00400301: 'TotalNumberOfExposures', - x00400302: 'EntranceDose', - x00400303: 'ExposedArea', - x00400306: 'DistanceSourceToEntrance', - x00400307: 'DistanceSourceToSupport', - x0040030e: 'ExposureDoseSequence', - x00400310: 'CommentsOnRadiationDose', - x00400312: 'XRayOutput', - x00400314: 'HalfValueLayer', - x00400316: 'OrganDose', - x00400318: 'OrganExposed', - x00400320: 'BillingProcedureStepSequence', - x00400321: 'FilmConsumptionSequence', - x00400324: 'BillingSuppliesAndDevicesSequence', - x00400330: 'ReferencedProcedureStepSequence', - x00400340: 'PerformedSeriesSequence', - x00400400: 'CommentsOnScheduledProcedureStep', - x00400440: 'ProtocolContextSequence', - x00400441: 'ContentItemModifierSequence', - x0040050a: 'SpecimenAccessionNumber', - x00400512: 'ContainerIdentifier', - x0040051a: 'ContainerDescription', - x00400550: 'SpecimenSequence', - x00400551: 'SpecimenIdentifier', - x00400552: 'SpecimenDescriptionSequenceTrial', - x00400553: 'SpecimenDescriptionTrial', - x00400554: 'SpecimenUID', - x00400555: 'AcquisitionContextSequence', - x00400556: 'AcquisitionContextDescription', - x0040059a: 'SpecimenTypeCodeSequence', - x00400600: 'SpecimenShortDescription', - x004006fa: 'SlideIdentifier', - x0040071a: 'ImageCenterPointCoordinatesSeq', - x0040072a: 'XOffsetInSlideCoordinateSystem', - x0040073a: 'YOffsetInSlideCoordinateSystem', - x0040074a: 'ZOffsetInSlideCoordinateSystem', - x004008d8: 'PixelSpacingSequence', - x004008da: 'CoordinateSystemAxisCodeSequence', - x004008ea: 'MeasurementUnitsCodeSequence', - x004009f8: 'VitalStainCodeSequenceTrial', - x00401001: 'RequestedProcedureID', - x00401002: 'ReasonForRequestedProcedure', - x00401003: 'RequestedProcedurePriority', - x00401004: 'PatientTransportArrangements', - x00401005: 'RequestedProcedureLocation', - x00401006: 'PlacerOrderNumber-Procedure', - x00401007: 'FillerOrderNumber-Procedure', - x00401008: 'ConfidentialityCode', - x00401009: 'ReportingPriority', - x0040100a: 'ReasonForRequestedProcedureCodeSeq', - x00401010: 'NamesOfIntendedRecipientsOfResults', - x00401011: 'IntendedRecipientsOfResultsIDSeq', - x00401101: 'PersonIdentificationCodeSequence', - x00401102: 'PersonAddress', - x00401103: 'PersonTelephoneNumbers', - x00401400: 'RequestedProcedureComments', - x00402001: 'ReasonForImagingServiceRequest', - x00402004: 'IssueDateOfImagingServiceRequest', - x00402005: 'IssueTimeOfImagingServiceRequest', - x00402006: 'PlacerOrderNumberImagingServiceRequestRetired', - x00402007: 'FillerOrderNumberImagingServiceRequestRetired', - x00402008: 'OrderEnteredBy', - x00402009: 'OrderEntererLocation', - x00402010: 'OrderCallbackPhoneNumber', - x00402016: 'PlacerOrderNum-ImagingServiceReq', - x00402017: 'FillerOrderNum-ImagingServiceReq', - x00402400: 'ImagingServiceRequestComments', - x00403001: 'ConfidentialityOnPatientDataDescr', - x00404001: 'GenPurposeScheduledProcStepStatus', - x00404002: 'GenPurposePerformedProcStepStatus', - x00404003: 'GenPurposeSchedProcStepPriority', - x00404004: 'SchedProcessingApplicationsCodeSeq', - x00404005: 'SchedProcedureStepStartDateAndTime', - x00404006: 'MultipleCopiesFlag', - x00404007: 'PerformedProcessingAppsCodeSeq', - x00404009: 'HumanPerformerCodeSequence', - x00404010: 'SchedProcStepModificationDateTime', - x00404011: 'ExpectedCompletionDateAndTime', - x00404015: 'ResultingGenPurposePerfProcStepSeq', - x00404016: 'RefGenPurposeSchedProcStepSeq', - x00404018: 'ScheduledWorkitemCodeSequence', - x00404019: 'PerformedWorkitemCodeSequence', - x00404020: 'InputAvailabilityFlag', - x00404021: 'InputInformationSequence', - x00404022: 'RelevantInformationSequence', - x00404023: 'RefGenPurSchedProcStepTransUID', - x00404025: 'ScheduledStationNameCodeSequence', - x00404026: 'ScheduledStationClassCodeSequence', - x00404027: 'SchedStationGeographicLocCodeSeq', - x00404028: 'PerformedStationNameCodeSequence', - x00404029: 'PerformedStationClassCodeSequence', - x00404030: 'PerformedStationGeogLocCodeSeq', - x00404031: 'RequestedSubsequentWorkItemCodeSeq', - x00404032: 'NonDICOMOutputCodeSequence', - x00404033: 'OutputInformationSequence', - x00404034: 'ScheduledHumanPerformersSequence', - x00404035: 'ActualHumanPerformersSequence', - x00404036: 'HumanPerformersOrganization', - x00404037: 'HumanPerformerName', - x00404040: 'RawDataHandling', - x00408302: 'EntranceDoseInMilliGy', - x00409094: 'RefImageRealWorldValueMappingSeq', - x00409096: 'RealWorldValueMappingSequence', - x00409098: 'PixelValueMappingCodeSequence', - x00409210: 'LUTLabel', - x00409211: 'RealWorldValueLastValueMapped', - x00409212: 'RealWorldValueLUTData', - x00409216: 'RealWorldValueFirstValueMapped', - x00409224: 'RealWorldValueIntercept', - x00409225: 'RealWorldValueSlope', - x0040a010: 'RelationshipType', - x0040a027: 'VerifyingOrganization', - x0040a030: 'VerificationDateTime', - x0040a032: 'ObservationDateTime', - x0040a040: 'ValueType', - x0040a043: 'ConceptNameCodeSequence', - x0040a050: 'ContinuityOfContent', - x0040a073: 'VerifyingObserverSequence', - x0040a075: 'VerifyingObserverName', - x0040a078: 'AuthorObserverSequence', - x0040a07a: 'ParticipantSequence', - x0040a07c: 'CustodialOrganizationSequence', - x0040a080: 'ParticipationType', - x0040a082: 'ParticipationDateTime', - x0040a084: 'ObserverType', - x0040a088: 'VerifyingObserverIdentCodeSequence', - x0040a090: 'EquivalentCDADocumentSequence', - x0040a0b0: 'ReferencedWaveformChannels', - x0040a120: 'DateTime', - x0040a121: 'Date', - x0040a122: 'Time', - x0040a123: 'PersonName', - x0040a124: 'UID', - x0040a130: 'TemporalRangeType', - x0040a132: 'ReferencedSamplePositions', - x0040a136: 'ReferencedFrameNumbers', - x0040a138: 'ReferencedTimeOffsets', - x0040a13a: 'ReferencedDateTime', - x0040a160: 'TextValue', - x0040a168: 'ConceptCodeSequence', - x0040a170: 'PurposeOfReferenceCodeSequence', - x0040a180: 'AnnotationGroupNumber', - x0040a195: 'ModifierCodeSequence', - x0040a300: 'MeasuredValueSequence', - x0040a301: 'NumericValueQualifierCodeSequence', - x0040a30a: 'NumericValue', - x0040a353: 'AddressTrial', - x0040a354: 'TelephoneNumberTrial', - x0040a360: 'PredecessorDocumentsSequence', - x0040a370: 'ReferencedRequestSequence', - x0040a372: 'PerformedProcedureCodeSequence', - x0040a375: 'CurrentRequestedProcEvidenceSeq', - x0040a385: 'PertinentOtherEvidenceSequence', - x0040a390: 'HL7StructuredDocumentRefSeq', - x0040a491: 'CompletionFlag', - x0040a492: 'CompletionFlagDescription', - x0040a493: 'VerificationFlag', - x0040a494: 'ArchiveRequested', - x0040a496: 'PreliminaryFlag', - x0040a504: 'ContentTemplateSequence', - x0040a525: 'IdenticalDocumentsSequence', - x0040a730: 'ContentSequence', - x0040b020: 'AnnotationSequence', - x0040db00: 'TemplateIdentifier', - x0040db06: 'TemplateVersion', - x0040db07: 'TemplateLocalVersion', - x0040db0b: 'TemplateExtensionFlag', - x0040db0c: 'TemplateExtensionOrganizationUID', - x0040db0d: 'TemplateExtensionCreatorUID', - x0040db73: 'ReferencedContentItemIdentifier', - x0040e001: 'HL7InstanceIdentifier', - x0040e004: 'HL7DocumentEffectiveTime', - x0040e006: 'HL7DocumentTypeCodeSequence', - x0040e010: 'RetrieveURI', - x0040e011: 'RetrieveLocationUID', - x00420010: 'DocumentTitle', - x00420011: 'EncapsulatedDocument', - x00420012: 'MIMETypeOfEncapsulatedDocument', - x00420013: 'SourceInstanceSequence', - x00420014: 'ListOfMIMETypes', - // x00431001: 'BitmapOfPrescanOptions', - // x00431002: 'GradientOffsetInX', - // x00431003: 'GradientOffsetInY', - // x00431004: 'GradientOffsetInZ', - // x00431005: 'ImgIsOriginalOrUnoriginal', - // x00431006: 'NumberOfEPIShots', - // x00431007: 'ViewsPerSegment', - // x00431008: 'RespiratoryRateBpm', - // x00431009: 'RespiratoryTriggerPoint', - // x0043100a: 'TypeOfReceiverUsed', - // x0043100b: 'PeakRateOfChangeOfGradientField', - // x0043100c: 'LimitsInUnitsOfPercent', - // x0043100d: 'PSDEstimatedLimit', - // x0043100e: 'PSDEstimatedLimitInTeslaPerSecond', - // x0043100f: 'Saravghead', - // x00431010: 'WindowValue', - // x00431011: 'TotalInputViews', - // x00431012: 'X-RayChain', - // x00431013: 'DeconKernelParameters', - // x00431014: 'CalibrationParameters', - // x00431015: 'TotalOutputViews', - // x00431016: 'NumberOfOverranges', - // x00431017: 'IBHImageScaleFactors', - // x00431018: 'BBHCoefficients', - // x00431019: 'NumberOfBBHChainsToBlend', - // x0043101a: 'StartingChannelNumber', - // x0043101b: 'PpscanParameters', - // x0043101c: 'GEImageIntegrity', - // x0043101d: 'LevelValue', - // x0043101e: 'DeltaStartTime', - // x0043101f: 'MaxOverrangesInAView', - // x00431020: 'AvgOverrangesAllViews', - // x00431021: 'CorrectedAfterGlowTerms', - // x00431025: 'ReferenceChannels', - // x00431026: 'NoViewsRefChansBlocked', - // x00431027: 'ScanPitchRatio', - // x00431028: 'UniqueImageIden', - // x00431029: 'HistogramTables', - // x0043102a: 'UserDefinedData', - // x0043102b: 'PrivateScanOptions', - // x0043102c: 'EffectiveEchoSpacing', - // x0043102d: 'StringSlopField1', - // x0043102e: 'StringSlopField2', - // x0043102f: 'RawDataType', - // x00431030: 'RawDataType', - // x00431031: 'RACordOfTargetReconCenter', - // x00431032: 'RawDataType', - // x00431033: 'NegScanspacing', - // x00431034: 'OffsetFrequency', - // x00431035: 'UserUsageTag', - // x00431036: 'UserFillMapMSW', - // x00431037: 'UserFillMapLSW', - // x00431038: 'User25-48', - // x00431039: 'SlopInt6-9', - // x00431040: 'TriggerOnPosition', - // x00431041: 'DegreeOfRotation', - // x00431042: 'DASTriggerSource', - // x00431043: 'DASFpaGain', - // x00431044: 'DASOutputSource', - // x00431045: 'DASAdInput', - // x00431046: 'DASCalMode', - // x00431047: 'DASCalFrequency', - // x00431048: 'DASRegXm', - // x00431049: 'DASAutoZero', - // x0043104a: 'StartingChannelOfView', - // x0043104b: 'DASXmPattern', - // x0043104c: 'TGGCTriggerMode', - // x0043104d: 'StartScanToXrayOnDelay', - // x0043104e: 'DurationOfXrayOn', - // x00431060: 'SlopInt10-17', - // x00431061: 'ScannerStudyEntityUID', - // x00431062: 'ScannerStudyID', - // x0043106f: 'ScannerTableEntry', - x00440001: 'ProductPackageIdentifier', - x00440002: 'SubstanceAdministrationApproval', - x00440003: 'ApprovalStatusFurtherDescription', - x00440004: 'ApprovalStatusDateTime', - x00440007: 'ProductTypeCodeSequence', - x00440008: 'ProductName', - x00440009: 'ProductDescription', - x0044000a: 'ProductLotIdentifier', - x0044000b: 'ProductExpirationDateTime', - x00440010: 'SubstanceAdministrationDateTime', - x00440011: 'SubstanceAdministrationNotes', - x00440012: 'SubstanceAdministrationDeviceID', - x00440013: 'ProductParameterSequence', - x00440019: 'SubstanceAdminParameterSeq', - // x00451001: 'NumberOfMacroRowsInDetector', - // x00451002: 'MacroWidthAtISOCenter', - // x00451003: 'DASType', - // x00451004: 'DASGain', - // x00451005: 'DASTemperature', - // x00451006: 'TableDirectionInOrOut', - // x00451007: 'ZSmoothingFactor', - // x00451008: 'ViewWeightingMode', - // x00451009: 'SigmaRowNumberWhichRowsWereUsed', - // x0045100a: 'MinimumDasValueFoundInTheScanData', - // x0045100b: 'MaximumOffsetShiftValueUsed', - // x0045100c: 'NumberOfViewsShifted', - // x0045100d: 'ZTrackingFlag', - // x0045100e: 'MeanZError', - // x0045100f: 'ZTrackingMaximumError', - // x00451010: 'StartingViewForRow2a', - // x00451011: 'NumberOfViewsInRow2a', - // x00451012: 'StartingViewForRow1a', - // x00451013: 'SigmaMode', - // x00451014: 'NumberOfViewsInRow1a', - // x00451015: 'StartingViewForRow2b', - // x00451016: 'NumberOfViewsInRow2b', - // x00451017: 'StartingViewForRow1b', - // x00451018: 'NumberOfViewsInRow1b', - // x00451019: 'AirFilterCalibrationDate', - // x0045101a: 'AirFilterCalibrationTime', - // x0045101b: 'PhantomCalibrationDate', - // x0045101c: 'PhantomCalibrationTime', - // x0045101d: 'ZSlopeCalibrationDate', - // x0045101e: 'ZSlopeCalibrationTime', - // x0045101f: 'CrosstalkCalibrationDate', - // x00451020: 'CrosstalkCalibrationTime', - // x00451021: 'IterboneOptionFlag', - // x00451022: 'PeristalticFlagOption', - x00460012: 'LensDescription', - x00460014: 'RightLensSequence', - x00460015: 'LeftLensSequence', - x00460018: 'CylinderSequence', - x00460028: 'PrismSequence', - x00460030: 'HorizontalPrismPower', - x00460032: 'HorizontalPrismBase', - x00460034: 'VerticalPrismPower', - x00460036: 'VerticalPrismBase', - x00460038: 'LensSegmentType', - x00460040: 'OpticalTransmittance', - x00460042: 'ChannelWidth', - x00460044: 'PupilSize', - x00460046: 'CornealSize', - x00460060: 'DistancePupillaryDistance', - x00460062: 'NearPupillaryDistance', - x00460064: 'OtherPupillaryDistance', - x00460075: 'RadiusOfCurvature', - x00460076: 'KeratometricPower', - x00460077: 'KeratometricAxis', - x00460092: 'BackgroundColor', - x00460094: 'Optotype', - x00460095: 'OptotypePresentation', - x00460100: 'AddNearSequence', - x00460101: 'AddIntermediateSequence', - x00460102: 'AddOtherSequence', - x00460104: 'AddPower', - x00460106: 'ViewingDistance', - x00460125: 'ViewingDistanceType', - x00460135: 'VisualAcuityModifiers', - x00460137: 'DecimalVisualAcuity', - x00460139: 'OptotypeDetailedDefinition', - x00460146: 'SpherePower', - x00460147: 'CylinderPower', - x00500004: 'CalibrationImage', - x00500010: 'DeviceSequence', - x00500014: 'DeviceLength', - x00500015: 'ContainerComponentWidth', - x00500016: 'DeviceDiameter', - x00500017: 'DeviceDiameterUnits', - x00500018: 'DeviceVolume', - x00500019: 'InterMarkerDistance', - x0050001b: 'ContainerComponentID', - x00500020: 'DeviceDescription', - x00540010: 'EnergyWindowVector', - x00540011: 'NumberOfEnergyWindows', - x00540012: 'EnergyWindowInformationSequence', - x00540013: 'EnergyWindowRangeSequence', - x00540014: 'EnergyWindowLowerLimit', - x00540015: 'EnergyWindowUpperLimit', - x00540016: 'RadiopharmaceuticalInformationSeq', - x00540017: 'ResidualSyringeCounts', - x00540018: 'EnergyWindowName', - x00540020: 'DetectorVector', - x00540021: 'NumberOfDetectors', - x00540022: 'DetectorInformationSequence', - x00540030: 'PhaseVector', - x00540031: 'NumberOfPhases', - x00540032: 'PhaseInformationSequence', - x00540033: 'NumberOfFramesInPhase', - x00540036: 'PhaseDelay', - x00540038: 'PauseBetweenFrames', - x00540039: 'PhaseDescription', - x00540050: 'RotationVector', - x00540051: 'NumberOfRotations', - x00540052: 'RotationInformationSequence', - x00540053: 'NumberOfFramesInRotation', - x00540060: 'RRIntervalVector', - x00540061: 'NumberOfRRIntervals', - x00540062: 'GatedInformationSequence', - x00540063: 'DataInformationSequence', - x00540070: 'TimeSlotVector', - x00540071: 'NumberOfTimeSlots', - x00540072: 'TimeSlotInformationSequence', - x00540073: 'TimeSlotTime', - x00540080: 'SliceVector', - x00540081: 'NumberOfSlices', - x00540090: 'AngularViewVector', - x00540100: 'TimeSliceVector', - x00540101: 'NumberOfTimeSlices', - x00540200: 'StartAngle', - x00540202: 'TypeOfDetectorMotion', - x00540210: 'TriggerVector', - x00540211: 'NumberOfTriggersInPhase', - x00540220: 'ViewCodeSequence', - x00540222: 'ViewModifierCodeSequence', - x00540300: 'RadionuclideCodeSequence', - x00540302: 'AdministrationRouteCodeSequence', - x00540304: 'RadiopharmaceuticalCodeSequence', - x00540306: 'CalibrationDataSequence', - x00540308: 'EnergyWindowNumber', - x00540400: 'ImageID', - x00540410: 'PatientOrientationCodeSequence', - x00540412: 'PatientOrientationModifierCodeSeq', - x00540414: 'PatientGantryRelationshipCodeSeq', - x00540500: 'SliceProgressionDirection', - x00541000: 'SeriesType', - x00541001: 'Units', - x00541002: 'CountsSource', - x00541004: 'ReprojectionMethod', - x00541100: 'RandomsCorrectionMethod', - x00541101: 'AttenuationCorrectionMethod', - x00541102: 'DecayCorrection', - x00541103: 'ReconstructionMethod', - x00541104: 'DetectorLinesOfResponseUsed', - x00541105: 'ScatterCorrectionMethod', - x00541200: 'AxialAcceptance', - x00541201: 'AxialMash', - x00541202: 'TransverseMash', - x00541203: 'DetectorElementSize', - x00541210: 'CoincidenceWindowWidth', - x00541220: 'SecondaryCountsType', - x00541300: 'FrameReferenceTime', - x00541310: 'PrimaryCountsAccumulated', - x00541311: 'SecondaryCountsAccumulated', - x00541320: 'SliceSensitivityFactor', - x00541321: 'DecayFactor', - x00541322: 'DoseCalibrationFactor', - x00541323: 'ScatterFractionFactor', - x00541324: 'DeadTimeFactor', - x00541330: 'ImageIndex', - x00541400: 'CountsIncluded', - x00541401: 'DeadTimeCorrectionFlag', - x00603000: 'HistogramSequence', - x00603002: 'HistogramNumberOfBins', - x00603004: 'HistogramFirstBinValue', - x00603006: 'HistogramLastBinValue', - x00603008: 'HistogramBinWidth', - x00603010: 'HistogramExplanation', - x00603020: 'HistogramData', - x00620001: 'SegmentationType', - x00620002: 'SegmentSequence', - x00620003: 'SegmentedPropertyCategoryCodeSeq', - x00620004: 'SegmentNumber', - x00620005: 'SegmentLabel', - x00620006: 'SegmentDescription', - x00620008: 'SegmentAlgorithmType', - x00620009: 'SegmentAlgorithmName', - x0062000a: 'SegmentIdentificationSequence', - x0062000b: 'ReferencedSegmentNumber', - x0062000c: 'RecommendedDisplayGrayscaleValue', - x0062000d: 'RecommendedDisplayCIELabValue', - x0062000e: 'MaximumFractionalValue', - x0062000f: 'SegmentedPropertyTypeCodeSequence', - x00620010: 'SegmentationFractionalType', - x00640002: 'DeformableRegistrationSequence', - x00640003: 'SourceFrameOfReferenceUID', - x00640005: 'DeformableRegistrationGridSequence', - x00640007: 'GridDimensions', - x00640008: 'GridResolution', - x00640009: 'VectorGridData', - x0064000f: 'PreDeformationMatrixRegistSeq', - x00640010: 'PostDeformationMatrixRegistSeq', - x00660001: 'NumberOfSurfaces', - x00660002: 'SurfaceSequence', - x00660003: 'SurfaceNumber', - x00660004: 'SurfaceComments', - x00660009: 'SurfaceProcessing', - x0066000a: 'SurfaceProcessingRatio', - x0066000e: 'FiniteVolume', - x00660010: 'Manifold', - x00660011: 'SurfacePointsSequence', - x00660015: 'NumberOfSurfacePoints', - x00660016: 'PointCoordinatesData', - x00660017: 'PointPositionAccuracy', - x00660018: 'MeanPointDistance', - x00660019: 'MaximumPointDistance', - x0066001b: 'AxisOfRotation', - x0066001c: 'CenterOfRotation', - x0066001e: 'NumberOfVectors', - x0066001f: 'VectorDimensionality', - x00660020: 'VectorAccuracy', - x00660021: 'VectorCoordinateData', - x00660023: 'TrianglePointIndexList', - x00660024: 'EdgePointIndexList', - x00660025: 'VertexPointIndexList', - x00660026: 'TriangleStripSequence', - x00660027: 'TriangleFanSequence', - x00660028: 'LineSequence', - x00660029: 'PrimitivePointIndexList', - x0066002a: 'SurfaceCount', - x0066002f: 'AlgorithmFamilyCodeSequ', - x00660031: 'AlgorithmVersion', - x00660032: 'AlgorithmParameters', - x00660034: 'FacetSequence', - x00660036: 'AlgorithmName', - x00700001: 'GraphicAnnotationSequence', - x00700002: 'GraphicLayer', - x00700003: 'BoundingBoxAnnotationUnits', - x00700004: 'AnchorPointAnnotationUnits', - x00700005: 'GraphicAnnotationUnits', - x00700006: 'UnformattedTextValue', - x00700008: 'TextObjectSequence', - x00700009: 'GraphicObjectSequence', - x00700010: 'BoundingBoxTopLeftHandCorner', - x00700011: 'BoundingBoxBottomRightHandCorner', - x00700012: 'BoundingBoxTextHorizJustification', - x00700014: 'AnchorPoint', - x00700015: 'AnchorPointVisibility', - x00700020: 'GraphicDimensions', - x00700021: 'NumberOfGraphicPoints', - x00700022: 'GraphicData', - x00700023: 'GraphicType', - x00700024: 'GraphicFilled', - x00700040: 'ImageRotationRetired', - x00700041: 'ImageHorizontalFlip', - x00700042: 'ImageRotation', - x00700050: 'DisplayedAreaTopLeftTrial', - x00700051: 'DisplayedAreaBottomRightTrial', - x00700052: 'DisplayedAreaTopLeft', - x00700053: 'DisplayedAreaBottomRight', - x0070005a: 'DisplayedAreaSelectionSequence', - x00700060: 'GraphicLayerSequence', - x00700062: 'GraphicLayerOrder', - x00700066: 'GraphicLayerRecDisplayGraysclValue', - x00700067: 'GraphicLayerRecDisplayRGBValue', - x00700068: 'GraphicLayerDescription', - x00700080: 'ContentLabel', - x00700081: 'ContentDescription', - x00700082: 'PresentationCreationDate', - x00700083: 'PresentationCreationTime', - x00700084: 'ContentCreatorName', - x00700086: 'ContentCreatorIDCodeSequence', - x00700100: 'PresentationSizeMode', - x00700101: 'PresentationPixelSpacing', - x00700102: 'PresentationPixelAspectRatio', - x00700103: 'PresentationPixelMagRatio', - x00700306: 'ShapeType', - x00700308: 'RegistrationSequence', - x00700309: 'MatrixRegistrationSequence', - x0070030a: 'MatrixSequence', - x0070030c: 'FrameOfRefTransformationMatrixType', - x0070030d: 'RegistrationTypeCodeSequence', - x0070030f: 'FiducialDescription', - x00700310: 'FiducialIdentifier', - x00700311: 'FiducialIdentifierCodeSequence', - x00700312: 'ContourUncertaintyRadius', - x00700314: 'UsedFiducialsSequence', - x00700318: 'GraphicCoordinatesDataSequence', - x0070031a: 'FiducialUID', - x0070031c: 'FiducialSetSequence', - x0070031e: 'FiducialSequence', - x00700401: 'GraphicLayerRecomDisplayCIELabVal', - x00700402: 'BlendingSequence', - x00700403: 'RelativeOpacity', - x00700404: 'ReferencedSpatialRegistrationSeq', - x00700405: 'BlendingPosition', - x00720002: 'HangingProtocolName', - x00720004: 'HangingProtocolDescription', - x00720006: 'HangingProtocolLevel', - x00720008: 'HangingProtocolCreator', - x0072000a: 'HangingProtocolCreationDateTime', - x0072000c: 'HangingProtocolDefinitionSequence', - x0072000e: 'HangingProtocolUserIDCodeSequence', - x00720010: 'HangingProtocolUserGroupName', - x00720012: 'SourceHangingProtocolSequence', - x00720014: 'NumberOfPriorsReferenced', - x00720020: 'ImageSetsSequence', - x00720022: 'ImageSetSelectorSequence', - x00720024: 'ImageSetSelectorUsageFlag', - x00720026: 'SelectorAttribute', - x00720028: 'SelectorValueNumber', - x00720030: 'TimeBasedImageSetsSequence', - x00720032: 'ImageSetNumber', - x00720034: 'ImageSetSelectorCategory', - x00720038: 'RelativeTime', - x0072003a: 'RelativeTimeUnits', - x0072003c: 'AbstractPriorValue', - x0072003e: 'AbstractPriorCodeSequence', - x00720040: 'ImageSetLabel', - x00720050: 'SelectorAttributeVR', - x00720052: 'SelectorSequencePointer', - x00720054: 'SelectorSeqPointerPrivateCreator', - x00720056: 'SelectorAttributePrivateCreator', - x00720060: 'SelectorATValue', - x00720062: 'SelectorCSValue', - x00720064: 'SelectorISValue', - x00720066: 'SelectorLOValue', - x00720068: 'SelectorLTValue', - x0072006a: 'SelectorPNValue', - x0072006c: 'SelectorSHValue', - x0072006e: 'SelectorSTValue', - x00720070: 'SelectorUTValue', - x00720072: 'SelectorDSValue', - x00720074: 'SelectorFDValue', - x00720076: 'SelectorFLValue', - x00720078: 'SelectorULValue', - x0072007a: 'SelectorUSValue', - x0072007c: 'SelectorSLValue', - x0072007e: 'SelectorSSValue', - x00720080: 'SelectorCodeSequenceValue', - x00720100: 'NumberOfScreens', - x00720102: 'NominalScreenDefinitionSequence', - x00720104: 'NumberOfVerticalPixels', - x00720106: 'NumberOfHorizontalPixels', - x00720108: 'DisplayEnvironmentSpatialPosition', - x0072010a: 'ScreenMinimumGrayscaleBitDepth', - x0072010c: 'ScreenMinimumColorBitDepth', - x0072010e: 'ApplicationMaximumRepaintTime', - x00720200: 'DisplaySetsSequence', - x00720202: 'DisplaySetNumber', - x00720203: 'DisplaySetLabel', - x00720204: 'DisplaySetPresentationGroup', - x00720206: 'DisplaySetPresentationGroupDescr', - x00720208: 'PartialDataDisplayHandling', - x00720210: 'SynchronizedScrollingSequence', - x00720212: 'DisplaySetScrollingGroup', - x00720214: 'NavigationIndicatorSequence', - x00720216: 'NavigationDisplaySet', - x00720218: 'ReferenceDisplaySets', - x00720300: 'ImageBoxesSequence', - x00720302: 'ImageBoxNumber', - x00720304: 'ImageBoxLayoutType', - x00720306: 'ImageBoxTileHorizontalDimension', - x00720308: 'ImageBoxTileVerticalDimension', - x00720310: 'ImageBoxScrollDirection', - x00720312: 'ImageBoxSmallScrollType', - x00720314: 'ImageBoxSmallScrollAmount', - x00720316: 'ImageBoxLargeScrollType', - x00720318: 'ImageBoxLargeScrollAmount', - x00720320: 'ImageBoxOverlapPriority', - x00720330: 'CineRelativeToRealTime', - x00720400: 'FilterOperationsSequence', - x00720402: 'FilterByCategory', - x00720404: 'FilterByAttributePresence', - x00720406: 'FilterByOperator', - x00720432: 'SynchronizedImageBoxList', - x00720434: 'TypeOfSynchronization', - x00720500: 'BlendingOperationType', - x00720510: 'ReformattingOperationType', - x00720512: 'ReformattingThickness', - x00720514: 'ReformattingInterval', - x00720516: 'ReformattingOpInitialViewDir', - x00720520: 'RenderingType3D', - x00720600: 'SortingOperationsSequence', - x00720602: 'SortByCategory', - x00720604: 'SortingDirection', - x00720700: 'DisplaySetPatientOrientation', - x00720702: 'VOIType', - x00720704: 'PseudoColorType', - x00720706: 'ShowGrayscaleInverted', - x00720710: 'ShowImageTrueSizeFlag', - x00720712: 'ShowGraphicAnnotationFlag', - x00720714: 'ShowPatientDemographicsFlag', - x00720716: 'ShowAcquisitionTechniquesFlag', - x00720717: 'DisplaySetHorizontalJustification', - x00720718: 'DisplaySetVerticalJustification', - x00741000: 'UnifiedProcedureStepState', - x00741002: 'UPSProgressInformationSequence', - x00741004: 'UnifiedProcedureStepProgress', - x00741006: 'UnifiedProcedureStepProgressDescr', - x00741008: 'UnifiedProcedureStepComURISeq', - x0074100a: 'ContactURI', - x0074100c: 'ContactDisplayName', - x00741020: 'BeamTaskSequence', - x00741022: 'BeamTaskType', - x00741024: 'BeamOrderIndex', - x00741030: 'DeliveryVerificationImageSequence', - x00741032: 'VerificationImageTiming', - x00741034: 'DoubleExposureFlag', - x00741036: 'DoubleExposureOrdering', - x00741038: 'DoubleExposureMeterset', - x0074103a: 'DoubleExposureFieldDelta', - x00741040: 'RelatedReferenceRTImageSequence', - x00741042: 'GeneralMachineVerificationSequence', - x00741044: 'ConventionalMachineVerificationSeq', - x00741046: 'IonMachineVerificationSequence', - x00741048: 'FailedAttributesSequence', - x0074104a: 'OverriddenAttributesSequence', - x0074104c: 'ConventionalControlPointVerifySeq', - x0074104e: 'IonControlPointVerificationSeq', - x00741050: 'AttributeOccurrenceSequence', - x00741052: 'AttributeOccurrencePointer', - x00741054: 'AttributeItemSelector', - x00741056: 'AttributeOccurrencePrivateCreator', - x00741200: 'ScheduledProcedureStepPriority', - x00741202: 'StudyListLabel', - x00741204: 'ProcedureStepLabel', - x00741210: 'ScheduledProcessingParametersSeq', - x00741212: 'PerformedProcessingParametersSeq', - x00741216: 'UPSPerformedProcedureSequence', - x00741220: 'RelatedProcedureStepSequence', - x00741222: 'ProcedureStepRelationshipType', - x00741230: 'DeletionLock', - x00741234: 'ReceivingAE', - x00741236: 'RequestingAE', - x00741238: 'ReasonForCancellation', - x00741242: 'SCPStatus', - x00741244: 'SubscriptionListStatus', - x00741246: 'UPSListStatus', - x00880130: 'StorageMediaFileSetID', - x00880140: 'StorageMediaFileSetUID', - x00880200: 'IconImageSequence', - x00880904: 'TopicTitle', - x00880906: 'TopicSubject', - x00880910: 'TopicAuthor', - x00880912: 'TopicKeywords', - x01000410: 'SOPInstanceStatus', - x01000420: 'SOPAuthorizationDateAndTime', - x01000424: 'SOPAuthorizationComment', - x01000426: 'AuthorizationEquipmentCertNumber', - x04000005: 'MACIDNumber', - x04000010: 'MACCalculationTransferSyntaxUID', - x04000015: 'MACAlgorithm', - x04000020: 'DataElementsSigned', - x04000100: 'DigitalSignatureUID', - x04000105: 'DigitalSignatureDateTime', - x04000110: 'CertificateType', - x04000115: 'CertificateOfSigner', - x04000120: 'Signature', - x04000305: 'CertifiedTimestampType', - x04000310: 'CertifiedTimestamp', - x04000401: 'DigitalSignaturePurposeCodeSeq', - x04000402: 'ReferencedDigitalSignatureSeq', - x04000403: 'ReferencedSOPInstanceMACSeq', - x04000404: 'MAC', - x04000500: 'EncryptedAttributesSequence', - x04000510: 'EncryptedContentTransferSyntaxUID', - x04000520: 'EncryptedContent', - x04000550: 'ModifiedAttributesSequence', - x04000561: 'OriginalAttributesSequence', - x04000562: 'AttributeModificationDateTime', - x04000563: 'ModifyingSystem', - x04000564: 'SourceOfPreviousValues', - x04000565: 'ReasonForTheAttributeModification', - x1000xxx0: 'EscapeTriplet', - x1000xxx1: 'RunLengthTriplet', - x1000xxx2: 'HuffmanTableSize', - x1000xxx3: 'HuffmanTableTriplet', - x1000xxx4: 'ShiftTableSize', - x1000xxx5: 'ShiftTableTriplet', - x1010xxxx: 'ZonalMap', - x20000010: 'NumberOfCopies', - x2000001e: 'PrinterConfigurationSequence', - x20000020: 'PrintPriority', - x20000030: 'MediumType', - x20000040: 'FilmDestination', - x20000050: 'FilmSessionLabel', - x20000060: 'MemoryAllocation', - x20000061: 'MaximumMemoryAllocation', - x20000062: 'ColorImagePrintingFlag', - x20000063: 'CollationFlag', - x20000065: 'AnnotationFlag', - x20000067: 'ImageOverlayFlag', - x20000069: 'PresentationLUTFlag', - x2000006a: 'ImageBoxPresentationLUTFlag', - x200000a0: 'MemoryBitDepth', - x200000a1: 'PrintingBitDepth', - x200000a2: 'MediaInstalledSequence', - x200000a4: 'OtherMediaAvailableSequence', - x200000a8: 'SupportedImageDisplayFormatSeq', - x20000500: 'ReferencedFilmBoxSequence', - x20000510: 'ReferencedStoredPrintSequence', - x20100010: 'ImageDisplayFormat', - x20100030: 'AnnotationDisplayFormatID', - x20100040: 'FilmOrientation', - x20100050: 'FilmSizeID', - x20100052: 'PrinterResolutionID', - x20100054: 'DefaultPrinterResolutionID', - x20100060: 'MagnificationType', - x20100080: 'SmoothingType', - x201000a6: 'DefaultMagnificationType', - x201000a7: 'OtherMagnificationTypesAvailable', - x201000a8: 'DefaultSmoothingType', - x201000a9: 'OtherSmoothingTypesAvailable', - x20100100: 'BorderDensity', - x20100110: 'EmptyImageDensity', - x20100120: 'MinDensity', - x20100130: 'MaxDensity', - x20100140: 'Trim', - x20100150: 'ConfigurationInformation', - x20100152: 'ConfigurationInformationDescr', - x20100154: 'MaximumCollatedFilms', - x2010015e: 'Illumination', - x20100160: 'ReflectedAmbientLight', - x20100376: 'PrinterPixelSpacing', - x20100500: 'ReferencedFilmSessionSequence', - x20100510: 'ReferencedImageBoxSequence', - x20100520: 'ReferencedBasicAnnotationBoxSeq', - x20200010: 'ImageBoxPosition', - x20200020: 'Polarity', - x20200030: 'RequestedImageSize', - x20200040: 'RequestedDecimate-CropBehavior', - x20200050: 'RequestedResolutionID', - x202000a0: 'RequestedImageSizeFlag', - x202000a2: 'DecimateCropResult', - x20200110: 'BasicGrayscaleImageSequence', - x20200111: 'BasicColorImageSequence', - x20200130: 'ReferencedImageOverlayBoxSequence', - x20200140: 'ReferencedVOILUTBoxSequence', - x20300010: 'AnnotationPosition', - x20300020: 'TextString', - x20400010: 'ReferencedOverlayPlaneSequence', - x20400011: 'ReferencedOverlayPlaneGroups', - x20400020: 'OverlayPixelDataSequence', - x20400060: 'OverlayMagnificationType', - x20400070: 'OverlaySmoothingType', - x20400072: 'OverlayOrImageMagnification', - x20400074: 'MagnifyToNumberOfColumns', - x20400080: 'OverlayForegroundDensity', - x20400082: 'OverlayBackgroundDensity', - x20400090: 'OverlayMode', - x20400100: 'ThresholdDensity', - x20400500: 'ReferencedImageBoxSequenceRetired', - x20500010: 'PresentationLUTSequence', - x20500020: 'PresentationLUTShape', - x20500500: 'ReferencedPresentationLUTSequence', - x21000010: 'PrintJobID', - x21000020: 'ExecutionStatus', - x21000030: 'ExecutionStatusInfo', - x21000040: 'CreationDate', - x21000050: 'CreationTime', - x21000070: 'Originator', - x21000140: 'DestinationAE', - x21000160: 'OwnerID', - x21000170: 'NumberOfFilms', - x21000500: 'ReferencedPrintJobSequencePullStoredPrint', - x21100010: 'PrinterStatus', - x21100020: 'PrinterStatusInfo', - x21100030: 'PrinterName', - x21100099: 'PrintQueueID', - x21200010: 'QueueStatus', - x21200050: 'PrintJobDescriptionSequence', - x21200070: 'ReferencedPrintJobSequence', - x21300010: 'PrintManagementCapabilitiesSeq', - x21300015: 'PrinterCharacteristicsSequence', - x21300030: 'FilmBoxContentSequence', - x21300040: 'ImageBoxContentSequence', - x21300050: 'AnnotationContentSequence', - x21300060: 'ImageOverlayBoxContentSequence', - x21300080: 'PresentationLUTContentSequence', - x213000a0: 'ProposedStudySequence', - x213000c0: 'OriginalImageSequence', - x22000001: 'LabelFromInfoExtractedFromInstance', - x22000002: 'LabelText', - x22000003: 'LabelStyleSelection', - x22000004: 'MediaDisposition', - x22000005: 'BarcodeValue', - x22000006: 'BarcodeSymbology', - x22000007: 'AllowMediaSplitting', - x22000008: 'IncludeNonDICOMObjects', - x22000009: 'IncludeDisplayApplication', - x2200000a: 'SaveCompInstancesAfterMediaCreate', - x2200000b: 'TotalNumberMediaPiecesCreated', - x2200000c: 'RequestedMediaApplicationProfile', - x2200000d: 'ReferencedStorageMediaSequence', - x2200000e: 'FailureAttributes', - x2200000f: 'AllowLossyCompression', - x22000020: 'RequestPriority', - x30020002: 'RTImageLabel', - x30020003: 'RTImageName', - x30020004: 'RTImageDescription', - x3002000a: 'ReportedValuesOrigin', - x3002000c: 'RTImagePlane', - x3002000d: 'XRayImageReceptorTranslation', - x3002000e: 'XRayImageReceptorAngle', - x30020010: 'RTImageOrientation', - x30020011: 'ImagePlanePixelSpacing', - x30020012: 'RTImagePosition', - x30020020: 'RadiationMachineName', - x30020022: 'RadiationMachineSAD', - x30020024: 'RadiationMachineSSD', - x30020026: 'RTImageSID', - x30020028: 'SourceToReferenceObjectDistance', - x30020029: 'FractionNumber', - x30020030: 'ExposureSequence', - x30020032: 'MetersetExposure', - x30020034: 'DiaphragmPosition', - x30020040: 'FluenceMapSequence', - x30020041: 'FluenceDataSource', - x30020042: 'FluenceDataScale', - x30020051: 'FluenceMode', - x30020052: 'FluenceModeID', - x30040001: 'DVHType', - x30040002: 'DoseUnits', - x30040004: 'DoseType', - x30040006: 'DoseComment', - x30040008: 'NormalizationPoint', - x3004000a: 'DoseSummationType', - x3004000c: 'GridFrameOffsetVector', - x3004000e: 'DoseGridScaling', - x30040010: 'RTDoseROISequence', - x30040012: 'DoseValue', - x30040014: 'TissueHeterogeneityCorrection', - x30040040: 'DVHNormalizationPoint', - x30040042: 'DVHNormalizationDoseValue', - x30040050: 'DVHSequence', - x30040052: 'DVHDoseScaling', - x30040054: 'DVHVolumeUnits', - x30040056: 'DVHNumberOfBins', - x30040058: 'DVHData', - x30040060: 'DVHReferencedROISequence', - x30040062: 'DVHROIContributionType', - x30040070: 'DVHMinimumDose', - x30040072: 'DVHMaximumDose', - x30040074: 'DVHMeanDose', - x30060002: 'StructureSetLabel', - x30060004: 'StructureSetName', - x30060006: 'StructureSetDescription', - x30060008: 'StructureSetDate', - x30060009: 'StructureSetTime', - x30060010: 'ReferencedFrameOfReferenceSequence', - x30060012: 'RTReferencedStudySequence', - x30060014: 'RTReferencedSeriesSequence', - x30060016: 'ContourImageSequence', - x30060020: 'StructureSetROISequence', - x30060022: 'ROINumber', - x30060024: 'ReferencedFrameOfReferenceUID', - x30060026: 'ROIName', - x30060028: 'ROIDescription', - x3006002a: 'ROIDisplayColor', - x3006002c: 'ROIVolume', - x30060030: 'RTRelatedROISequence', - x30060033: 'RTROIRelationship', - x30060036: 'ROIGenerationAlgorithm', - x30060038: 'ROIGenerationDescription', - x30060039: 'ROIContourSequence', - x30060040: 'ContourSequence', - x30060042: 'ContourGeometricType', - x30060044: 'ContourSlabThickness', - x30060045: 'ContourOffsetVector', - x30060046: 'NumberOfContourPoints', - x30060048: 'ContourNumber', - x30060049: 'AttachedContours', - x30060050: 'ContourData', - x30060080: 'RTROIObservationsSequence', - x30060082: 'ObservationNumber', - x30060084: 'ReferencedROINumber', - x30060085: 'ROIObservationLabel', - x30060086: 'RTROIIdentificationCodeSequence', - x30060088: 'ROIObservationDescription', - x300600a0: 'RelatedRTROIObservationsSequence', - x300600a4: 'RTROIInterpretedType', - x300600a6: 'ROIInterpreter', - x300600b0: 'ROIPhysicalPropertiesSequence', - x300600b2: 'ROIPhysicalProperty', - x300600b4: 'ROIPhysicalPropertyValue', - x300600b6: 'ROIElementalCompositionSequence', - x300600b7: 'ROIElementalCompAtomicNumber', - x300600b8: 'ROIElementalCompAtomicMassFraction', - x300600c0: 'FrameOfReferenceRelationshipSeq', - x300600c2: 'RelatedFrameOfReferenceUID', - x300600c4: 'FrameOfReferenceTransformType', - x300600c6: 'FrameOfReferenceTransformMatrix', - x300600c8: 'FrameOfReferenceTransformComment', - x30080010: 'MeasuredDoseReferenceSequence', - x30080012: 'MeasuredDoseDescription', - x30080014: 'MeasuredDoseType', - x30080016: 'MeasuredDoseValue', - x30080020: 'TreatmentSessionBeamSequence', - x30080021: 'TreatmentSessionIonBeamSequence', - x30080022: 'CurrentFractionNumber', - x30080024: 'TreatmentControlPointDate', - x30080025: 'TreatmentControlPointTime', - x3008002a: 'TreatmentTerminationStatus', - x3008002b: 'TreatmentTerminationCode', - x3008002c: 'TreatmentVerificationStatus', - x30080030: 'ReferencedTreatmentRecordSequence', - x30080032: 'SpecifiedPrimaryMeterset', - x30080033: 'SpecifiedSecondaryMeterset', - x30080036: 'DeliveredPrimaryMeterset', - x30080037: 'DeliveredSecondaryMeterset', - x3008003a: 'SpecifiedTreatmentTime', - x3008003b: 'DeliveredTreatmentTime', - x30080040: 'ControlPointDeliverySequence', - x30080041: 'IonControlPointDeliverySequence', - x30080042: 'SpecifiedMeterset', - x30080044: 'DeliveredMeterset', - x30080045: 'MetersetRateSet', - x30080046: 'MetersetRateDelivered', - x30080047: 'ScanSpotMetersetsDelivered', - x30080048: 'DoseRateDelivered', - x30080050: 'TreatmentSummaryCalcDoseRefSeq', - x30080052: 'CumulativeDoseToDoseReference', - x30080054: 'FirstTreatmentDate', - x30080056: 'MostRecentTreatmentDate', - x3008005a: 'NumberOfFractionsDelivered', - x30080060: 'OverrideSequence', - x30080061: 'ParameterSequencePointer', - x30080062: 'OverrideParameterPointer', - x30080063: 'ParameterItemIndex', - x30080064: 'MeasuredDoseReferenceNumber', - x30080065: 'ParameterPointer', - x30080066: 'OverrideReason', - x30080068: 'CorrectedParameterSequence', - x3008006a: 'CorrectionValue', - x30080070: 'CalculatedDoseReferenceSequence', - x30080072: 'CalculatedDoseReferenceNumber', - x30080074: 'CalculatedDoseReferenceDescription', - x30080076: 'CalculatedDoseReferenceDoseValue', - x30080078: 'StartMeterset', - x3008007a: 'EndMeterset', - x30080080: 'ReferencedMeasuredDoseReferenceSeq', - x30080082: 'ReferencedMeasuredDoseReferenceNum', - x30080090: 'ReferencedCalculatedDoseRefSeq', - x30080092: 'ReferencedCalculatedDoseRefNumber', - x300800a0: 'BeamLimitingDeviceLeafPairsSeq', - x300800b0: 'RecordedWedgeSequence', - x300800c0: 'RecordedCompensatorSequence', - x300800d0: 'RecordedBlockSequence', - x300800e0: 'TreatmentSummaryMeasuredDoseRefSeq', - x300800f0: 'RecordedSnoutSequence', - x300800f2: 'RecordedRangeShifterSequence', - x300800f4: 'RecordedLateralSpreadingDeviceSeq', - x300800f6: 'RecordedRangeModulatorSequence', - x30080100: 'RecordedSourceSequence', - x30080105: 'SourceSerialNumber', - x30080110: 'TreatmentSessionAppSetupSeq', - x30080116: 'ApplicationSetupCheck', - x30080120: 'RecordedBrachyAccessoryDeviceSeq', - x30080122: 'ReferencedBrachyAccessoryDeviceNum', - x30080130: 'RecordedChannelSequence', - x30080132: 'SpecifiedChannelTotalTime', - x30080134: 'DeliveredChannelTotalTime', - x30080136: 'SpecifiedNumberOfPulses', - x30080138: 'DeliveredNumberOfPulses', - x3008013a: 'SpecifiedPulseRepetitionInterval', - x3008013c: 'DeliveredPulseRepetitionInterval', - x30080140: 'RecordedSourceApplicatorSequence', - x30080142: 'ReferencedSourceApplicatorNumber', - x30080150: 'RecordedChannelShieldSequence', - x30080152: 'ReferencedChannelShieldNumber', - x30080160: 'BrachyControlPointDeliveredSeq', - x30080162: 'SafePositionExitDate', - x30080164: 'SafePositionExitTime', - x30080166: 'SafePositionReturnDate', - x30080168: 'SafePositionReturnTime', - x30080200: 'CurrentTreatmentStatus', - x30080202: 'TreatmentStatusComment', - x30080220: 'FractionGroupSummarySequence', - x30080223: 'ReferencedFractionNumber', - x30080224: 'FractionGroupType', - x30080230: 'BeamStopperPosition', - x30080240: 'FractionStatusSummarySequence', - x30080250: 'TreatmentDate', - x30080251: 'TreatmentTime', - x300a0002: 'RTPlanLabel', - x300a0003: 'RTPlanName', - x300a0004: 'RTPlanDescription', - x300a0006: 'RTPlanDate', - x300a0007: 'RTPlanTime', - x300a0009: 'TreatmentProtocols', - x300a000a: 'PlanIntent', - x300a000b: 'TreatmentSites', - x300a000c: 'RTPlanGeometry', - x300a000e: 'PrescriptionDescription', - x300a0010: 'DoseReferenceSequence', - x300a0012: 'DoseReferenceNumber', - x300a0013: 'DoseReferenceUID', - x300a0014: 'DoseReferenceStructureType', - x300a0015: 'NominalBeamEnergyUnit', - x300a0016: 'DoseReferenceDescription', - x300a0018: 'DoseReferencePointCoordinates', - x300a001a: 'NominalPriorDose', - x300a0020: 'DoseReferenceType', - x300a0021: 'ConstraintWeight', - x300a0022: 'DeliveryWarningDose', - x300a0023: 'DeliveryMaximumDose', - x300a0025: 'TargetMinimumDose', - x300a0026: 'TargetPrescriptionDose', - x300a0027: 'TargetMaximumDose', - x300a0028: 'TargetUnderdoseVolumeFraction', - x300a002a: 'OrganAtRiskFullVolumeDose', - x300a002b: 'OrganAtRiskLimitDose', - x300a002c: 'OrganAtRiskMaximumDose', - x300a002d: 'OrganAtRiskOverdoseVolumeFraction', - x300a0040: 'ToleranceTableSequence', - x300a0042: 'ToleranceTableNumber', - x300a0043: 'ToleranceTableLabel', - x300a0044: 'GantryAngleTolerance', - x300a0046: 'BeamLimitingDeviceAngleTolerance', - x300a0048: 'BeamLimitingDeviceToleranceSeq', - x300a004a: 'BeamLimitingDevicePositionTol', - x300a004b: 'SnoutPositionTolerance', - x300a004c: 'PatientSupportAngleTolerance', - x300a004e: 'TableTopEccentricAngleTolerance', - x300a004f: 'TableTopPitchAngleTolerance', - x300a0050: 'TableTopRollAngleTolerance', - x300a0051: 'TableTopVerticalPositionTolerance', - x300a0052: 'TableTopLongitudinalPositionTol', - x300a0053: 'TableTopLateralPositionTolerance', - x300a0055: 'RTPlanRelationship', - x300a0070: 'FractionGroupSequence', - x300a0071: 'FractionGroupNumber', - x300a0072: 'FractionGroupDescription', - x300a0078: 'NumberOfFractionsPlanned', - x300a0079: 'NumberFractionPatternDigitsPerDay', - x300a007a: 'RepeatFractionCycleLength', - x300a007b: 'FractionPattern', - x300a0080: 'NumberOfBeams', - x300a0082: 'BeamDoseSpecificationPoint', - x300a0084: 'BeamDose', - x300a0086: 'BeamMeterset', - x300a0088: 'BeamDosePointDepth', - x300a0089: 'BeamDosePointEquivalentDepth', - x300a008a: 'BeamDosePointSSD', - x300a00a0: 'NumberOfBrachyApplicationSetups', - x300a00a2: 'BrachyAppSetupDoseSpecPoint', - x300a00a4: 'BrachyApplicationSetupDose', - x300a00b0: 'BeamSequence', - x300a00b2: 'TreatmentMachineName', - x300a00b3: 'PrimaryDosimeterUnit', - x300a00b4: 'SourceAxisDistance', - x300a00b6: 'BeamLimitingDeviceSequence', - x300a00b8: 'RTBeamLimitingDeviceType', - x300a00ba: 'SourceToBeamLimitingDeviceDistance', - x300a00bb: 'IsocenterToBeamLimitingDeviceDist', - x300a00bc: 'NumberOfLeafJawPairs', - x300a00be: 'LeafPositionBoundaries', - x300a00c0: 'BeamNumber', - x300a00c2: 'BeamName', - x300a00c3: 'BeamDescription', - x300a00c4: 'BeamType', - x300a00c6: 'RadiationType', - x300a00c7: 'HighDoseTechniqueType', - x300a00c8: 'ReferenceImageNumber', - x300a00ca: 'PlannedVerificationImageSequence', - x300a00cc: 'ImagingDeviceSpecificAcqParams', - x300a00ce: 'TreatmentDeliveryType', - x300a00d0: 'NumberOfWedges', - x300a00d1: 'WedgeSequence', - x300a00d2: 'WedgeNumber', - x300a00d3: 'WedgeType', - x300a00d4: 'WedgeID', - x300a00d5: 'WedgeAngle', - x300a00d6: 'WedgeFactor', - x300a00d7: 'TotalWedgeTrayWaterEquivThickness', - x300a00d8: 'WedgeOrientation', - x300a00d9: 'IsocenterToWedgeTrayDistance', - x300a00da: 'SourceToWedgeTrayDistance', - x300a00db: 'WedgeThinEdgePosition', - x300a00dc: 'BolusID', - x300a00dd: 'BolusDescription', - x300a00e0: 'NumberOfCompensators', - x300a00e1: 'MaterialID', - x300a00e2: 'TotalCompensatorTrayFactor', - x300a00e3: 'CompensatorSequence', - x300a00e4: 'CompensatorNumber', - x300a00e5: 'CompensatorID', - x300a00e6: 'SourceToCompensatorTrayDistance', - x300a00e7: 'CompensatorRows', - x300a00e8: 'CompensatorColumns', - x300a00e9: 'CompensatorPixelSpacing', - x300a00ea: 'CompensatorPosition', - x300a00eb: 'CompensatorTransmissionData', - x300a00ec: 'CompensatorThicknessData', - x300a00ed: 'NumberOfBoli', - x300a00ee: 'CompensatorType', - x300a00f0: 'NumberOfBlocks', - x300a00f2: 'TotalBlockTrayFactor', - x300a00f3: 'TotalBlockTrayWaterEquivThickness', - x300a00f4: 'BlockSequence', - x300a00f5: 'BlockTrayID', - x300a00f6: 'SourceToBlockTrayDistance', - x300a00f7: 'IsocenterToBlockTrayDistance', - x300a00f8: 'BlockType', - x300a00f9: 'AccessoryCode', - x300a00fa: 'BlockDivergence', - x300a00fb: 'BlockMountingPosition', - x300a00fc: 'BlockNumber', - x300a00fe: 'BlockName', - x300a0100: 'BlockThickness', - x300a0102: 'BlockTransmission', - x300a0104: 'BlockNumberOfPoints', - x300a0106: 'BlockData', - x300a0107: 'ApplicatorSequence', - x300a0108: 'ApplicatorID', - x300a0109: 'ApplicatorType', - x300a010a: 'ApplicatorDescription', - x300a010c: 'CumulativeDoseReferenceCoefficient', - x300a010e: 'FinalCumulativeMetersetWeight', - x300a0110: 'NumberOfControlPoints', - x300a0111: 'ControlPointSequence', - x300a0112: 'ControlPointIndex', - x300a0114: 'NominalBeamEnergy', - x300a0115: 'DoseRateSet', - x300a0116: 'WedgePositionSequence', - x300a0118: 'WedgePosition', - x300a011a: 'BeamLimitingDevicePositionSequence', - x300a011c: 'LeafJawPositions', - x300a011e: 'GantryAngle', - x300a011f: 'GantryRotationDirection', - x300a0120: 'BeamLimitingDeviceAngle', - x300a0121: 'BeamLimitingDeviceRotateDirection', - x300a0122: 'PatientSupportAngle', - x300a0123: 'PatientSupportRotationDirection', - x300a0124: 'TableTopEccentricAxisDistance', - x300a0125: 'TableTopEccentricAngle', - x300a0126: 'TableTopEccentricRotateDirection', - x300a0128: 'TableTopVerticalPosition', - x300a0129: 'TableTopLongitudinalPosition', - x300a012a: 'TableTopLateralPosition', - x300a012c: 'IsocenterPosition', - x300a012e: 'SurfaceEntryPoint', - x300a0130: 'SourceToSurfaceDistance', - x300a0134: 'CumulativeMetersetWeight', - x300a0140: 'TableTopPitchAngle', - x300a0142: 'TableTopPitchRotationDirection', - x300a0144: 'TableTopRollAngle', - x300a0146: 'TableTopRollRotationDirection', - x300a0148: 'HeadFixationAngle', - x300a014a: 'GantryPitchAngle', - x300a014c: 'GantryPitchRotationDirection', - x300a014e: 'GantryPitchAngleTolerance', - x300a0180: 'PatientSetupSequence', - x300a0182: 'PatientSetupNumber', - x300a0183: 'PatientSetupLabel', - x300a0184: 'PatientAdditionalPosition', - x300a0190: 'FixationDeviceSequence', - x300a0192: 'FixationDeviceType', - x300a0194: 'FixationDeviceLabel', - x300a0196: 'FixationDeviceDescription', - x300a0198: 'FixationDevicePosition', - x300a0199: 'FixationDevicePitchAngle', - x300a019a: 'FixationDeviceRollAngle', - x300a01a0: 'ShieldingDeviceSequence', - x300a01a2: 'ShieldingDeviceType', - x300a01a4: 'ShieldingDeviceLabel', - x300a01a6: 'ShieldingDeviceDescription', - x300a01a8: 'ShieldingDevicePosition', - x300a01b0: 'SetupTechnique', - x300a01b2: 'SetupTechniqueDescription', - x300a01b4: 'SetupDeviceSequence', - x300a01b6: 'SetupDeviceType', - x300a01b8: 'SetupDeviceLabel', - x300a01ba: 'SetupDeviceDescription', - x300a01bc: 'SetupDeviceParameter', - x300a01d0: 'SetupReferenceDescription', - x300a01d2: 'TableTopVerticalSetupDisplacement', - x300a01d4: 'TableTopLongitudinalSetupDisplace', - x300a01d6: 'TableTopLateralSetupDisplacement', - x300a0200: 'BrachyTreatmentTechnique', - x300a0202: 'BrachyTreatmentType', - x300a0206: 'TreatmentMachineSequence', - x300a0210: 'SourceSequence', - x300a0212: 'SourceNumber', - x300a0214: 'SourceType', - x300a0216: 'SourceManufacturer', - x300a0218: 'ActiveSourceDiameter', - x300a021a: 'ActiveSourceLength', - x300a0222: 'SourceEncapsulationNomThickness', - x300a0224: 'SourceEncapsulationNomTransmission', - x300a0226: 'SourceIsotopeName', - x300a0228: 'SourceIsotopeHalfLife', - x300a0229: 'SourceStrengthUnits', - x300a022a: 'ReferenceAirKermaRate', - x300a022b: 'SourceStrength', - x300a022c: 'SourceStrengthReferenceDate', - x300a022e: 'SourceStrengthReferenceTime', - x300a0230: 'ApplicationSetupSequence', - x300a0232: 'ApplicationSetupType', - x300a0234: 'ApplicationSetupNumber', - x300a0236: 'ApplicationSetupName', - x300a0238: 'ApplicationSetupManufacturer', - x300a0240: 'TemplateNumber', - x300a0242: 'TemplateType', - x300a0244: 'TemplateName', - x300a0250: 'TotalReferenceAirKerma', - x300a0260: 'BrachyAccessoryDeviceSequence', - x300a0262: 'BrachyAccessoryDeviceNumber', - x300a0263: 'BrachyAccessoryDeviceID', - x300a0264: 'BrachyAccessoryDeviceType', - x300a0266: 'BrachyAccessoryDeviceName', - x300a026a: 'BrachyAccessoryDeviceNomThickness', - x300a026c: 'BrachyAccessoryDevNomTransmission', - x300a0280: 'ChannelSequence', - x300a0282: 'ChannelNumber', - x300a0284: 'ChannelLength', - x300a0286: 'ChannelTotalTime', - x300a0288: 'SourceMovementType', - x300a028a: 'NumberOfPulses', - x300a028c: 'PulseRepetitionInterval', - x300a0290: 'SourceApplicatorNumber', - x300a0291: 'SourceApplicatorID', - x300a0292: 'SourceApplicatorType', - x300a0294: 'SourceApplicatorName', - x300a0296: 'SourceApplicatorLength', - x300a0298: 'SourceApplicatorManufacturer', - x300a029c: 'SourceApplicatorWallNomThickness', - x300a029e: 'SourceApplicatorWallNomTrans', - x300a02a0: 'SourceApplicatorStepSize', - x300a02a2: 'TransferTubeNumber', - x300a02a4: 'TransferTubeLength', - x300a02b0: 'ChannelShieldSequence', - x300a02b2: 'ChannelShieldNumber', - x300a02b3: 'ChannelShieldID', - x300a02b4: 'ChannelShieldName', - x300a02b8: 'ChannelShieldNominalThickness', - x300a02ba: 'ChannelShieldNominalTransmission', - x300a02c8: 'FinalCumulativeTimeWeight', - x300a02d0: 'BrachyControlPointSequence', - x300a02d2: 'ControlPointRelativePosition', - x300a02d4: 'ControlPoint3DPosition', - x300a02d6: 'CumulativeTimeWeight', - x300a02e0: 'CompensatorDivergence', - x300a02e1: 'CompensatorMountingPosition', - x300a02e2: 'SourceToCompensatorDistance', - x300a02e3: 'TotalCompTrayWaterEquivThickness', - x300a02e4: 'IsocenterToCompensatorTrayDistance', - x300a02e5: 'CompensatorColumnOffset', - x300a02e6: 'IsocenterToCompensatorDistances', - x300a02e7: 'CompensatorRelStoppingPowerRatio', - x300a02e8: 'CompensatorMillingToolDiameter', - x300a02ea: 'IonRangeCompensatorSequence', - x300a02eb: 'CompensatorDescription', - x300a0302: 'RadiationMassNumber', - x300a0304: 'RadiationAtomicNumber', - x300a0306: 'RadiationChargeState', - x300a0308: 'ScanMode', - x300a030a: 'VirtualSourceAxisDistances', - x300a030c: 'SnoutSequence', - x300a030d: 'SnoutPosition', - x300a030f: 'SnoutID', - x300a0312: 'NumberOfRangeShifters', - x300a0314: 'RangeShifterSequence', - x300a0316: 'RangeShifterNumber', - x300a0318: 'RangeShifterID', - x300a0320: 'RangeShifterType', - x300a0322: 'RangeShifterDescription', - x300a0330: 'NumberOfLateralSpreadingDevices', - x300a0332: 'LateralSpreadingDeviceSequence', - x300a0334: 'LateralSpreadingDeviceNumber', - x300a0336: 'LateralSpreadingDeviceID', - x300a0338: 'LateralSpreadingDeviceType', - x300a033a: 'LateralSpreadingDeviceDescription', - x300a033c: 'LateralSpreadingDevWaterEquivThick', - x300a0340: 'NumberOfRangeModulators', - x300a0342: 'RangeModulatorSequence', - x300a0344: 'RangeModulatorNumber', - x300a0346: 'RangeModulatorID', - x300a0348: 'RangeModulatorType', - x300a034a: 'RangeModulatorDescription', - x300a034c: 'BeamCurrentModulationID', - x300a0350: 'PatientSupportType', - x300a0352: 'PatientSupportID', - x300a0354: 'PatientSupportAccessoryCode', - x300a0356: 'FixationLightAzimuthalAngle', - x300a0358: 'FixationLightPolarAngle', - x300a035a: 'MetersetRate', - x300a0360: 'RangeShifterSettingsSequence', - x300a0362: 'RangeShifterSetting', - x300a0364: 'IsocenterToRangeShifterDistance', - x300a0366: 'RangeShifterWaterEquivThickness', - x300a0370: 'LateralSpreadingDeviceSettingsSeq', - x300a0372: 'LateralSpreadingDeviceSetting', - x300a0374: 'IsocenterToLateralSpreadingDevDist', - x300a0380: 'RangeModulatorSettingsSequence', - x300a0382: 'RangeModulatorGatingStartValue', - x300a0384: 'RangeModulatorGatingStopValue', - x300a038a: 'IsocenterToRangeModulatorDistance', - x300a0390: 'ScanSpotTuneID', - x300a0392: 'NumberOfScanSpotPositions', - x300a0394: 'ScanSpotPositionMap', - x300a0396: 'ScanSpotMetersetWeights', - x300a0398: 'ScanningSpotSize', - x300a039a: 'NumberOfPaintings', - x300a03a0: 'IonToleranceTableSequence', - x300a03a2: 'IonBeamSequence', - x300a03a4: 'IonBeamLimitingDeviceSequence', - x300a03a6: 'IonBlockSequence', - x300a03a8: 'IonControlPointSequence', - x300a03aa: 'IonWedgeSequence', - x300a03ac: 'IonWedgePositionSequence', - x300a0401: 'ReferencedSetupImageSequence', - x300a0402: 'SetupImageComment', - x300a0410: 'MotionSynchronizationSequence', - x300a0412: 'ControlPointOrientation', - x300a0420: 'GeneralAccessorySequence', - x300a0421: 'GeneralAccessoryID', - x300a0422: 'GeneralAccessoryDescription', - x300a0423: 'GeneralAccessoryType', - x300a0424: 'GeneralAccessoryNumber', - x300c0002: 'ReferencedRTPlanSequence', - x300c0004: 'ReferencedBeamSequence', - x300c0006: 'ReferencedBeamNumber', - x300c0007: 'ReferencedReferenceImageNumber', - x300c0008: 'StartCumulativeMetersetWeight', - x300c0009: 'EndCumulativeMetersetWeight', - x300c000a: 'ReferencedBrachyAppSetupSeq', - x300c000c: 'ReferencedBrachyAppSetupNumber', - x300c000e: 'ReferencedSourceNumber', - x300c0020: 'ReferencedFractionGroupSequence', - x300c0022: 'ReferencedFractionGroupNumber', - x300c0040: 'ReferencedVerificationImageSeq', - x300c0042: 'ReferencedReferenceImageSequence', - x300c0050: 'ReferencedDoseReferenceSequence', - x300c0051: 'ReferencedDoseReferenceNumber', - x300c0055: 'BrachyReferencedDoseReferenceSeq', - x300c0060: 'ReferencedStructureSetSequence', - x300c006a: 'ReferencedPatientSetupNumber', - x300c0080: 'ReferencedDoseSequence', - x300c00a0: 'ReferencedToleranceTableNumber', - x300c00b0: 'ReferencedBolusSequence', - x300c00c0: 'ReferencedWedgeNumber', - x300c00d0: 'ReferencedCompensatorNumber', - x300c00e0: 'ReferencedBlockNumber', - x300c00f0: 'ReferencedControlPointIndex', - x300c00f2: 'ReferencedControlPointSequence', - x300c00f4: 'ReferencedStartControlPointIndex', - x300c00f6: 'ReferencedStopControlPointIndex', - x300c0100: 'ReferencedRangeShifterNumber', - x300c0102: 'ReferencedLateralSpreadingDevNum', - x300c0104: 'ReferencedRangeModulatorNumber', - x300e0002: 'ApprovalStatus', - x300e0004: 'ReviewDate', - x300e0005: 'ReviewTime', - x300e0008: 'ReviewerName', - x40000000: 'TextGroupLength', - x40000010: 'Arbitrary', - x40004000: 'TextComments', - x40080040: 'ResultsID', - x40080042: 'ResultsIDIssuer', - x40080050: 'ReferencedInterpretationSequence', - x40080100: 'InterpretationRecordedDate', - x40080101: 'InterpretationRecordedTime', - x40080102: 'InterpretationRecorder', - x40080103: 'ReferenceToRecordedSound', - x40080108: 'InterpretationTranscriptionDate', - x40080109: 'InterpretationTranscriptionTime', - x4008010a: 'InterpretationTranscriber', - x4008010b: 'InterpretationText', - x4008010c: 'InterpretationAuthor', - x40080111: 'InterpretationApproverSequence', - x40080112: 'InterpretationApprovalDate', - x40080113: 'InterpretationApprovalTime', - x40080114: 'PhysicianApprovingInterpretation', - x40080115: 'InterpretationDiagnosisDescription', - x40080117: 'InterpretationDiagnosisCodeSeq', - x40080118: 'ResultsDistributionListSequence', - x40080119: 'DistributionName', - x4008011a: 'DistributionAddress', - x40080200: 'InterpretationID', - x40080202: 'InterpretationIDIssuer', - x40080210: 'InterpretationTypeID', - x40080212: 'InterpretationStatusID', - x40080300: 'Impressions', - x40084000: 'ResultsComments', - x4ffe0001: 'MACParametersSequence', - x50xx0005: 'CurveDimensions', - x50xx0010: 'NumberOfPoints', - x50xx0020: 'TypeOfData', - x50xx0022: 'CurveDescription', - x50xx0030: 'AxisUnits', - x50xx0040: 'AxisLabels', - x50xx0103: 'DataValueRepresentation', - x50xx0104: 'MinimumCoordinateValue', - x50xx0105: 'MaximumCoordinateValue', - x50xx0106: 'CurveRange', - x50xx0110: 'CurveDataDescriptor', - x50xx0112: 'CoordinateStartValue', - x50xx0114: 'CoordinateStepValue', - x50xx1001: 'CurveActivationLayer', - x50xx2000: 'AudioType', - x50xx2002: 'AudioSampleFormat', - x50xx2004: 'NumberOfChannels', - x50xx2006: 'NumberOfSamples', - x50xx2008: 'SampleRate', - x50xx200a: 'TotalTime', - x50xx200c: 'AudioSampleData', - x50xx200e: 'AudioComments', - x50xx2500: 'CurveLabel', - x50xx2600: 'CurveReferencedOverlaySequence', - x50xx2610: 'ReferencedOverlayGroup', - x50xx3000: 'CurveData', - x52009229: 'SharedFunctionalGroupsSequence', - x52009230: 'PerFrameFunctionalGroupsSequence', - x54000100: 'WaveformSequence', - x54000110: 'ChannelMinimumValue', - x54000112: 'ChannelMaximumValue', - x54001004: 'WaveformBitsAllocated', - x54001006: 'WaveformSampleInterpretation', - x5400100a: 'WaveformPaddingValue', - x54001010: 'WaveformData', - x56000010: 'FirstOrderPhaseCorrectionAngle', - x56000020: 'SpectroscopyData', - x60000000: 'OverlayGroupLength', - x60xx0010: 'OverlayRows', - x60xx0011: 'OverlayColumns', - x60xx0012: 'OverlayPlanes', - x60xx0015: 'NumberOfFramesInOverlay', - x60xx0022: 'OverlayDescription', - x60xx0040: 'OverlayType', - x60xx0045: 'OverlaySubtype', - x60xx0050: 'OverlayOrigin', - x60xx0051: 'ImageFrameOrigin', - x60xx0052: 'OverlayPlaneOrigin', - x60xx0060: 'OverlayCompressionCode', - x60xx0061: 'OverlayCompressionOriginator', - x60xx0062: 'OverlayCompressionLabel', - x60xx0063: 'OverlayCompressionDescription', - x60xx0066: 'OverlayCompressionStepPointers', - x60xx0068: 'OverlayRepeatInterval', - x60xx0069: 'OverlayBitsGrouped', - x60xx0100: 'OverlayBitsAllocated', - x60xx0102: 'OverlayBitPosition', - x60xx0110: 'OverlayFormat', - x60xx0200: 'OverlayLocation', - x60xx0800: 'OverlayCodeLabel', - x60xx0802: 'OverlayNumberOfTables', - x60xx0803: 'OverlayCodeTableLocation', - x60xx0804: 'OverlayBitsForCodeWord', - x60xx1001: 'OverlayActivationLayer', - x60xx1100: 'OverlayDescriptorGray', - x60xx1101: 'OverlayDescriptorRed', - x60xx1102: 'OverlayDescriptorGreen', - x60xx1103: 'OverlayDescriptorBlue', - x60xx1200: 'OverlaysGray', - x60xx1201: 'OverlaysRed', - x60xx1202: 'OverlaysGreen', - x60xx1203: 'OverlaysBlue', - x60xx1301: 'ROIArea', - x60xx1302: 'ROIMean', - x60xx1303: 'ROIStandardDeviation', - x60xx1500: 'OverlayLabel', - x60xx3000: 'OverlayData', - x60xx4000: 'OverlayComments', - x7fxx0000: 'PixelDataGroupLength', - x7fxx0010: 'PixelData', - x7fxx0011: 'VariableNextDataGroup', - x7fxx0020: 'VariableCoefficientsSDVN', - x7fxx0030: 'VariableCoefficientsSDHN', - x7fxx0040: 'VariableCoefficientsSDDN', - xfffafffa: 'DigitalSignaturesSequence', - xfffcfffc: 'DataSetTrailingPadding', - xfffee000: 'StartOfItem', - xfffee00d: 'EndOfItems', - xfffee0dd: 'EndOfSequence' -}; - -DICOMTagDescriptions.init(initialTagDescriptionMap); - -// Discard original map... -initialTagDescriptionMap = null; - -export { DICOMTagDescriptions }; diff --git a/Packages/ohif-core/client/lib/DICOMWeb/getAttribute.js b/Packages/ohif-core/client/lib/DICOMWeb/getAttribute.js deleted file mode 100644 index 2b04c302e..000000000 --- a/Packages/ohif-core/client/lib/DICOMWeb/getAttribute.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Returns the specified element as a dicom attribute group/element. - * - * @param element - The group/element of the element (e.g. '00280009') - * @param [defaultValue] - The value to return if the element is not present - * @returns {*} - */ -export default function getAttribute(element, defaultValue) { - if (!element) { - return defaultValue; - } - // Value is not present if the attribute has a zero length value - if (!element.Value) { - return defaultValue; - } - // Sanity check to make sure we have at least one entry in the array. - if (!element.Value.length) { - return defaultValue; - } - - return convertToInt(element.Value); -}; - -function convertToInt(input) { - function padFour(input) { - var l = input.length; - - if (l == 0) return '0000'; - if (l == 1) return '000' + input; - if (l == 2) return '00' + input; - if (l == 3) return '0' + input; - - return input; - } - - var output = ''; - for (var i = 0; i < input.length; i++) { - for (var j = 0; j < input[i].length; j++) { - output += padFour(input[i].charCodeAt(j).toString(16)); - } - } - - return parseInt(output, 16); -} diff --git a/Packages/ohif-core/client/lib/DICOMWeb/getAuthorizationHeader.js b/Packages/ohif-core/client/lib/DICOMWeb/getAuthorizationHeader.js deleted file mode 100644 index f9d80d93f..000000000 --- a/Packages/ohif-core/client/lib/DICOMWeb/getAuthorizationHeader.js +++ /dev/null @@ -1,26 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { btoa } from 'isomorphic-base64'; - -/** - * Returns the Authorization header as part of an Object. - * - * @returns {Object} - */ -export default function getAuthorizationHeader() { - const headers = {}; - - // Check for OHIF.user since this can also be run on the server - const accessToken = OHIF.user && OHIF.user.getAccessToken && OHIF.user.getAccessToken(); - const server = OHIF.servers.getCurrentServer(); - - if (server && - server.requestOptions && - server.requestOptions.auth) { - // HTTP Basic Auth (user:password) - headers.Authorization = `Basic ${btoa(server.requestOptions.auth)}`; - } else if (accessToken) { - headers.Authorization = `Bearer ${accessToken}`; - } - - return headers; -} diff --git a/Packages/ohif-core/client/lib/DICOMWeb/getModalities.js b/Packages/ohif-core/client/lib/DICOMWeb/getModalities.js deleted file mode 100644 index 4c00d9378..000000000 --- a/Packages/ohif-core/client/lib/DICOMWeb/getModalities.js +++ /dev/null @@ -1,21 +0,0 @@ -export default function getModalities(modality, modalitiesInStudy) { - var modalities = {}; - if (modality) { - modalities = modality; - } - - if (modalitiesInStudy) { - // Find vr in modalities - if (modalities.vr && modalities.vr === modalitiesInStudy.vr) { - for (var i = 0; i < modalitiesInStudy.Value.length; i++) { - var value = modalitiesInStudy.Value[i]; - if (modalities.Value.indexOf(value) === -1) { - modalities.Value.push(value); - } - } - } else { - modalities = modalitiesInStudy; - } - } - return modalities; -}; diff --git a/Packages/ohif-core/client/lib/DICOMWeb/getName.js b/Packages/ohif-core/client/lib/DICOMWeb/getName.js deleted file mode 100644 index 3256633a6..000000000 --- a/Packages/ohif-core/client/lib/DICOMWeb/getName.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Returns the Alphabetic version of a PN - * - * @param element - The group/element of the element (e.g. '00200013') - * @param [defaultValue] - The default value to return if the element is not found - * @returns {*} - */ -export default function getName(element, defaultValue) { - if (!element) { - return defaultValue; - } - // Value is not present if the attribute has a zero length value - if (!element.Value) { - return defaultValue; - } - // Sanity check to make sure we have at least one entry in the array. - if (!element.Value.length) { - return defaultValue; - } - // Return the Alphabetic component group - if (element.Value[0].Alphabetic) { - return element.Value[0].Alphabetic; - } - // Orthanc does not return PN properly so this is a temporary workaround - return element.Value[0]; -}; diff --git a/Packages/ohif-core/client/lib/DICOMWeb/getNumber.js b/Packages/ohif-core/client/lib/DICOMWeb/getNumber.js deleted file mode 100644 index a8c7ce5d6..000000000 --- a/Packages/ohif-core/client/lib/DICOMWeb/getNumber.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Returns the first string value as a Javascript Number - * @param element - The group/element of the element (e.g. '00200013') - * @param [defaultValue] - The default value to return if the element does not exist - * @returns {*} - */ -export default function getNumber(element, defaultValue) { - if (!element) { - return defaultValue; - } - // Value is not present if the attribute has a zero length value - if (!element.Value) { - return defaultValue; - } - // Sanity check to make sure we have at least one entry in the array. - if (!element.Value.length) { - return defaultValue; - } - - return parseFloat(element.Value[0]); -}; diff --git a/Packages/ohif-core/client/lib/DICOMWeb/getString.js b/Packages/ohif-core/client/lib/DICOMWeb/getString.js deleted file mode 100644 index 07c1823ae..000000000 --- a/Packages/ohif-core/client/lib/DICOMWeb/getString.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Returns the specified element as a string. Multi-valued elements will be separated by a backslash - * - * @param element - The group/element of the element (e.g. '00200013') - * @param [defaultValue] - The value to return if the element is not present - * @returns {*} - */ -export default function getString(element, defaultValue) { - if (!element) { - return defaultValue; - } - // Value is not present if the attribute has a zero length value - if (!element.Value) { - return defaultValue; - } - // Sanity check to make sure we have at least one entry in the array. - if (!element.Value.length) { - return defaultValue; - } - // Join the array together separated by backslash - // NOTE: Orthanc does not correctly split values into an array so the join is a no-op - return element.Value.join('\\'); -}; diff --git a/Packages/ohif-core/client/lib/DICOMWeb/index.js b/Packages/ohif-core/client/lib/DICOMWeb/index.js deleted file mode 100644 index d983a13b3..000000000 --- a/Packages/ohif-core/client/lib/DICOMWeb/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -import getAttribute from './getAttribute.js'; -import getAuthorizationHeader from './getAuthorizationHeader.js'; -import getModalities from './getModalities.js'; -import getName from './getName.js'; -import getNumber from './getNumber.js'; -import getString from './getString.js'; - -const DICOMWeb = { - getAttribute, - getAuthorizationHeader, - getModalities, - getName, - getNumber, - getString, -}; - -OHIF.DICOMWeb = DICOMWeb; diff --git a/Packages/ohif-core/client/lib/absoluteUrl.js b/Packages/ohif-core/client/lib/absoluteUrl.js deleted file mode 100644 index 37878fa03..000000000 --- a/Packages/ohif-core/client/lib/absoluteUrl.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -export default function(path) { - if (path) { - // Remove the leading "/" - path = path.replace(/^\//, ''); - } - - return Meteor.absoluteUrl(path); -} diff --git a/Packages/ohif-core/client/lib/blaze.js b/Packages/ohif-core/client/lib/blaze.js deleted file mode 100644 index 9a8861acd..000000000 --- a/Packages/ohif-core/client/lib/blaze.js +++ /dev/null @@ -1,66 +0,0 @@ -import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; - -OHIF.blaze = {}; - -// Clone a template and return the clone -OHIF.blaze.cloneTemplate = (template, newName) => { - if (!template){ - return; - } - - const name = newName || template.viewName; - const clone = new Template(name, template.renderFunction); - clone.inheritsEventsFrom(template); - clone.inheritsHelpersFrom(template); - clone.inheritsHooksFrom(template); - return clone; -}; - -// Navigate upwards the component and get the parent with the given view name -OHIF.blaze.getParentView = (view, parentViewName) => { - let currentView = view; - while (currentView) { - if (currentView.name === parentViewName) { - break; - } - - currentView = currentView.originalParentView || currentView.parentView; - } - - return currentView; -}; - -// Search for the parent component of the given view -OHIF.blaze.getParentComponent = (view, property='_component') => { - let currentView = view; - while (currentView) { - currentView = currentView.originalParentView || currentView.parentView; - if (currentView && currentView[property]) { - return currentView[property]; - } - } -}; - -// Search for the parent template of the given view -OHIF.blaze.getParentTemplateView = view => { - let currentView = view; - while (currentView) { - currentView = currentView.originalParentView || currentView.parentView; - if (!currentView || !currentView.name) return; - if (currentView.name.indexOf('Template.') > -1 && currentView.name.indexOf('Template.__dynamic') === -1) { - return currentView; - } - } -}; - -// Get the view that contains the desired section's content and return it -OHIF.blaze.getSectionContent = (view, sectionName) => { - let currentView = view; - while (!currentView._sectionMap || !currentView._sectionMap.get(sectionName)) { - currentView = OHIF.blaze.getParentTemplateView(currentView); - if (!currentView) return; - } - - return currentView._sectionMap.get(sectionName); -}; diff --git a/Packages/ohif-core/client/lib/cornerstone.js b/Packages/ohif-core/client/lib/cornerstone.js deleted file mode 100644 index 5dab39c30..000000000 --- a/Packages/ohif-core/client/lib/cornerstone.js +++ /dev/null @@ -1,312 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import _ from 'underscore'; - -OHIF.cornerstone = {}; - -OHIF.cornerstone.getBoundingBox = (context, textLines, x, y, options) => { - if (Object.prototype.toString.call(textLines) !== '[object Array]') { - textLines = [textLines]; - } - - const padding = 5; - const font = cornerstoneTools.textStyle.getFont(); - const fontSize = cornerstoneTools.textStyle.getFontSize(); - - context.save(); - context.font = font; - context.textBaseline = 'top'; - - // Find the longest text width in the array of text data - let maxWidth = 0; - - textLines.forEach(text => { - // Get the text width in the current font - const width = context.measureText(text).width; - - // Find the maximum with for all the text rows; - maxWidth = Math.max(maxWidth, width); - }); - - // Calculate the bounding box for this text box - const boundingBox = { - width: maxWidth + (padding * 2), - height: padding + textLines.length * (fontSize + padding) - }; - - if (options && options.centering && options.centering.x === true) { - x -= boundingBox.width / 2; - } - - if (options && options.centering && options.centering.y === true) { - y -= boundingBox.height / 2; - } - - boundingBox.left = x; - boundingBox.top = y; - - context.restore(); - - // Return the bounding box so it can be used for pointNearHandle - return boundingBox; -}; - -OHIF.cornerstone.pixelToPage = (element, position) => { - const enabledElement = cornerstone.getEnabledElement(element); - const result = { - x: 0, - y: 0 - }; - - // Stop here if the cornerstone element is not enabled or position is not an object - if (!enabledElement || typeof position !== 'object') { - return result; - } - - const canvas = enabledElement.canvas; - - const canvasOffset = $(canvas).offset(); - result.x += canvasOffset.left; - result.y += canvasOffset.top; - - const canvasPosition = cornerstone.pixelToCanvas(element, position); - result.x += canvasPosition.x; - result.y += canvasPosition.y; - - return result; -}; - -OHIF.cornerstone.repositionTextBox = (eventData, measurementData, config) => { - // Stop here if it's not a measurement creating - if (!measurementData.isCreating) { - return; - } - - const element = eventData.element; - const enabledElement = cornerstone.getEnabledElement(element); - const image = enabledElement.image; - - const allowedBorders = OHIF.uiSettings.autoPositionMeasurementsTextCallOuts; - const allow = { - T: !allowedBorders || _.contains(allowedBorders, 'T'), - R: !allowedBorders || _.contains(allowedBorders, 'R'), - B: !allowedBorders || _.contains(allowedBorders, 'B'), - L: !allowedBorders || _.contains(allowedBorders, 'L') - }; - - const getAvailableBlankAreas = (enabledElement, labelWidth, labelHeight) => { - const { element, canvas, image } = enabledElement; - - const topLeft = cornerstone.pixelToCanvas(element, { - x: 0, - y: 0 - }); - - const bottomRight = cornerstone.pixelToCanvas(element, { - x: image.width, - y: image.height - }); - - const $canvas = $(canvas); - const canvasWidth = $canvas.outerWidth(); - const canvasHeight = $canvas.outerHeight(); - - const result = {}; - result['x-1'] = allow.L && (topLeft.x > labelWidth); - result['y-1'] = allow.T && (topLeft.y > labelHeight); - result.x1 = allow.R && (canvasWidth - bottomRight.x > labelWidth); - result.y1 = allow.B && (canvasHeight - bottomRight.y > labelHeight); - - return result; - }; - - const getRenderingInformation = (limits, tool) => { - const mid = {}; - mid.x = limits.x / 2; - mid.y = limits.y / 2; - - const directions = {}; - directions.x = tool.x < mid.x ? -1 : 1; - directions.y = tool.y < mid.y ? -1 : 1; - - const diffX = directions.x < 0 ? tool.x : limits.x - tool.x; - const diffY = directions.y < 0 ? tool.y : limits.y - tool.y; - let cornerAxis = diffY < diffX ? 'y' : 'x'; - - const map = { - 'x-1': 'L', - 'y-1': 'T', - x1: 'R', - y1: 'B' - }; - - let current = 0; - while (current < 4 && !allow[map[cornerAxis + directions[cornerAxis]]]) { - // Invert the direction for the next iteration - directions[cornerAxis] *= -1; - - // Invert the tempCornerAxis - cornerAxis = cornerAxis === 'x' ? 'y' : 'x'; - - current++; - } - - return { - directions, - cornerAxis - }; - }; - - const calculateAxisCenter = (axis, start, end) => { - const a = start[axis]; - const b = end[axis]; - const lowest = Math.min(a, b); - const highest = Math.max(a, b); - return lowest + ((highest - lowest) / 2); - }; - - const getTextBoxSizeInPixels = (element, bounds) => { - const topLeft = cornerstone.pageToPixel(element, 0, 0); - const bottomRight = cornerstone.pageToPixel(element, bounds.x, bounds.y); - return { - x: bottomRight.x - topLeft.x, - y: bottomRight.y - topLeft.y - }; - }; - - function getTextBoxOffset(config, cornerAxis, toolAxis, boxSize) { - config = config || {}; - const centering = config.centering || {}; - const centerX = !!centering.x; - const centerY = !!centering.y; - const halfBoxSizeX = boxSize.x / 2; - const halfBoxSizeY = boxSize.y / 2; - const offset = { - x: [], - y: [] - }; - - if (cornerAxis === 'x') { - const offsetY = centerY ? 0 : halfBoxSizeY; - - offset.x[-1] = centerX ? halfBoxSizeX : 0; - offset.x[1] = centerX ? -halfBoxSizeX : -boxSize.x; - offset.y[-1] = offsetY; - offset.y[1] = offsetY; - } else { - const offsetX = centerX ? 0 : halfBoxSizeX; - - offset.x[-1] = offsetX; - offset.x[1] = offsetX; - offset.y[-1] = centerY ? halfBoxSizeY : 0; - offset.y[1] = centerY ? -halfBoxSizeY : -boxSize.y; - } - - return offset; - } - - const handles = measurementData.handles; - const textBox = handles.textBox; - - const $canvas = $(enabledElement.canvas); - const canvasWidth = $canvas.outerWidth(); - const canvasHeight = $canvas.outerHeight(); - const offset = $canvas.offset(); - const canvasDimensions = { - x: canvasWidth, - y: canvasHeight - }; - - const bounds = {}; - bounds.x = textBox.boundingBox.width; - bounds.y = textBox.boundingBox.height; - - const getHandlePosition = key => _.pick(handles[key], ['x', 'y']); - const start = getHandlePosition('start'); - const end = getHandlePosition('end'); - - const tool = {}; - tool.x = calculateAxisCenter('x', start, end); - tool.y = calculateAxisCenter('y', start, end); - - let limits = {}; - limits.x = image.width; - limits.y = image.height; - - let { directions, cornerAxis } = getRenderingInformation(limits, tool); - - const availableAreas = getAvailableBlankAreas(enabledElement, bounds.x, bounds.y); - const tempDirections = _.clone(directions); - let tempCornerAxis = cornerAxis; - let foundPlace = false; - let current = 0; - while (current < 4) { - if (availableAreas[tempCornerAxis + tempDirections[tempCornerAxis]]) { - foundPlace = true; - break; - } - - // Invert the direction for the next iteration - tempDirections[tempCornerAxis] *= -1; - - // Invert the tempCornerAxis - tempCornerAxis = tempCornerAxis === 'x' ? 'y' : 'x'; - - current++; - } - - let cornerAxisPosition; - if (foundPlace) { - _.extend(directions, tempDirections); - cornerAxis = tempCornerAxis; - cornerAxisPosition = directions[cornerAxis] < 0 ? 0 : limits[cornerAxis]; - } else { - _.extend(limits, canvasDimensions); - - const toolPositionOnCanvas = cornerstone.pixelToCanvas(element, tool); - const renderingInformation = getRenderingInformation(limits, toolPositionOnCanvas); - directions = renderingInformation.directions; - cornerAxis = renderingInformation.cornerAxis; - - const position = { - x: directions.x < 0 ? offset.left : offset.left + canvasWidth, - y: directions.y < 0 ? offset.top : offset.top + canvasHeight - }; - - const pixelPosition = cornerstone.pageToPixel(element, position.x, position.y); - cornerAxisPosition = pixelPosition[cornerAxis]; - } - - const toolAxis = cornerAxis === 'x' ? 'y' : 'x'; - const boxSize = getTextBoxSizeInPixels(element, bounds); - - textBox[cornerAxis] = cornerAxisPosition; - textBox[toolAxis] = tool[toolAxis]; - - // Adjust the text box position reducing its size from the corner axis - const textBoxOffset = getTextBoxOffset(config, cornerAxis, toolAxis, boxSize); - textBox[cornerAxis] += textBoxOffset[cornerAxis][directions[cornerAxis]]; - - // Preventing the text box from partially going outside the canvas area - const topLeft = cornerstone.pixelToCanvas(element, textBox); - const bottomRight = { - x: topLeft.x + bounds.x, - y: topLeft.y + bounds.y - }; - const canvasBorders = { - x0: offset.left, - y0: offset.top, - x1: offset.left + canvasWidth, - y1: offset.top + canvasHeight - }; - if (topLeft[toolAxis] < 0) { - const x = canvasBorders.x0; - const y = canvasBorders.y0; - const pixelPosition = cornerstone.pageToPixel(element, x, y); - textBox[toolAxis] = pixelPosition[toolAxis]; - } else if (bottomRight[toolAxis] > canvasDimensions[toolAxis]) { - const x = canvasBorders.x1 - bounds.x; - const y = canvasBorders.y1 - bounds.y; - const pixelPosition = cornerstone.pageToPixel(element, x, y); - textBox[toolAxis] = pixelPosition[toolAxis]; - } -}; diff --git a/Packages/ohif-core/client/lib/getCurrentServer.js b/Packages/ohif-core/client/lib/getCurrentServer.js deleted file mode 100644 index b9d7ce9a9..000000000 --- a/Packages/ohif-core/client/lib/getCurrentServer.js +++ /dev/null @@ -1,17 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Servers, CurrentServer } from '../collections'; - -/** - * Retrieves the current server configuration used to retrieve studies - */ -OHIF.servers.getCurrentServer = () => { - const currentServer = CurrentServer.findOne(); - - if (!currentServer) { - return; - } - - const serverConfiguration = Servers.findOne({ _id: currentServer.serverId }); - - return serverConfiguration; -}; diff --git a/Packages/ohif-core/client/lib/getStudyBoxData.js b/Packages/ohif-core/client/lib/getStudyBoxData.js deleted file mode 100644 index a82b02e31..000000000 --- a/Packages/ohif-core/client/lib/getStudyBoxData.js +++ /dev/null @@ -1,15 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -/** - * Overridable namespace to allow getting study boxes data externally. - * - * The function must handle the first parameter as a studyInformation object containing at least the - * studyInstanceUid attribute. - * - * Shall return a promise that will be resolved with an object containing those attributes: - * - studyInstanceUid {String}: copy of studyInformation.studyInstanceUid - * - modalities {String}: 2 uppercase letters for each modality split by any non-alphabetical char(s) - * - studyDate {String}: date formatted as YYYYMMDD - * - studyDescription {String}: study description string - */ -OHIF.studies.getStudyBoxData = false; diff --git a/Packages/ohif-core/client/lib/index.js b/Packages/ohif-core/client/lib/index.js deleted file mode 100644 index b89563d02..000000000 --- a/Packages/ohif-core/client/lib/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import './blaze.js'; -import './cornerstone.js'; -import './string.js'; -import './ui.js'; -import './utils.js'; -import './viewer.js'; -import './user.js'; -import './object.js'; -import './DICOMWeb/'; -import './getCurrentServer.js'; -import './DICOMTagDescriptions.js'; -import './getStudyBoxData'; -import './loadStudy'; -import './retrieveStudiesMetadata'; -import './retrieveStudyMetadata'; -import './searchStudies'; -import './parseFloatArray'; - diff --git a/Packages/ohif-core/client/lib/loadStudy.js b/Packages/ohif-core/client/lib/loadStudy.js deleted file mode 100644 index 07267b859..000000000 --- a/Packages/ohif-core/client/lib/loadStudy.js +++ /dev/null @@ -1,82 +0,0 @@ -import { ReactiveDict } from 'meteor/reactive-dict'; -import { Tracker } from 'meteor/tracker'; -import { OHIF } from 'meteor/ohif:core'; -import { Meteor } from "meteor/meteor"; - -// Create a studies loaded state dictionary to enable reactivity. Values: loading|loaded|failed -OHIF.studies.loadingDict = new ReactiveDict(); - -/** - * Load the study metadata and store its information locally - * - * @param {String} studyInstanceUid The UID of the Study to be loaded - * @returns {Promise} that will be resolved with the study metadata or rejected with an error - */ -OHIF.studies.loadStudy = studyInstanceUid => new Promise((resolve, reject) => { - // Disable reactivity to get the current loading state - let currentLoadingState; - Tracker.nonreactive(() => { - currentLoadingState = OHIF.studies.loadingDict.get(studyInstanceUid) || ''; - }); - - // Set the loading state as the study is not yet loaded - if (currentLoadingState !== 'loading') { - OHIF.studies.loadingDict.set(studyInstanceUid, 'loading'); - } - - const studyLoaded = OHIF.viewer.Studies.findBy({ studyInstanceUid: studyInstanceUid }); - if (studyLoaded) { - OHIF.studies.loadingDict.set(studyInstanceUid, 'loaded'); - resolve(studyLoaded); - return; - } - - return OHIF.studies.retrieveStudyMetadata(studyInstanceUid).then(study => { - if (window.HipaaLogger && - OHIF.user && - OHIF.user.userLoggedIn && - OHIF.user.userLoggedIn()) { - window.HipaaLogger.logEvent({ - eventType: 'viewed', - userId: OHIF.user.getUserId(), - userName: OHIF.user.getName(), - collectionName: 'Study', - recordId: studyInstanceUid, - patientId: study.patientId, - patientName: study.patientName - }); - } - - // Once the data was retrieved, the series are sorted by series and instance number - OHIF.viewerbase.sortStudy(study); - - // Updates WADO-RS metaDataManager - OHIF.viewerbase.updateMetaDataManager(study); - - // Transform the study in a StudyMetadata object - const studyMetadata = new OHIF.metadata.StudyMetadata(study); - - // Add the display sets to the study - study.displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata); - study.displaySets.forEach(displaySet => { - OHIF.viewerbase.stackManager.makeAndAddStack(study, displaySet); - studyMetadata.addDisplaySet(displaySet); - }); - - // Persist study data into OHIF.viewer - OHIF.viewer.Studies.insert(study); - OHIF.viewer.StudyMetadataList.insert(study); - - // Add the study to the loading listener to allow loading progress handling - const studyLoadingListener = OHIF.viewerbase.StudyLoadingListener.getInstance(); - studyLoadingListener.addStudy(study); - - // Add the studyInstanceUid to the loaded state dictionary - OHIF.studies.loadingDict.set(studyInstanceUid, 'loaded'); - - resolve(study); - }).catch((...args) => { - OHIF.studies.loadingDict.set(studyInstanceUid, 'failed'); - reject(args); - }); -}); diff --git a/Packages/ohif-core/client/lib/object.js b/Packages/ohif-core/client/lib/object.js deleted file mode 100644 index 6ff06f9d7..000000000 --- a/Packages/ohif-core/client/lib/object.js +++ /dev/null @@ -1,52 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -OHIF.object = {}; - -// Transforms a shallow object with keys separated by "." into a nested object -OHIF.object.getNestedObject = shallowObject => { - const nestedObject = {}; - for (let key in shallowObject) { - if (!shallowObject.hasOwnProperty(key)) continue; - const value = shallowObject[key]; - const propertyArray = key.split('.'); - let currentObject = nestedObject; - while (propertyArray.length) { - const currentProperty = propertyArray.shift(); - if (!propertyArray.length) { - currentObject[currentProperty] = value; - } else { - if (!currentObject[currentProperty]) { - currentObject[currentProperty] = {}; - } - - currentObject = currentObject[currentProperty]; - } - } - } - - return nestedObject; -}; - -// Transforms a nested object into a shallowObject merging its keys with "." character -OHIF.object.getShallowObject = nestedObject => { - const shallowObject = {}; - const putValues = (baseKey, nestedObject, resultObject) => { - for (let key in nestedObject) { - if (!nestedObject.hasOwnProperty(key)) continue; - let currentKey = baseKey ? `${baseKey}.${key}` : key; - const currentValue = nestedObject[key]; - if (typeof currentValue === 'object') { - if (currentValue instanceof Array) { - currentKey += '[]'; - } - - putValues(currentKey, currentValue, resultObject); - } else { - resultObject[currentKey] = currentValue; - } - } - }; - - putValues('', nestedObject, shallowObject); - return shallowObject; -}; diff --git a/Packages/ohif-core/client/lib/parseFloatArray.js b/Packages/ohif-core/client/lib/parseFloatArray.js deleted file mode 100644 index 22641318e..000000000 --- a/Packages/ohif-core/client/lib/parseFloatArray.js +++ /dev/null @@ -1,14 +0,0 @@ -export const parseFloatArray = function(obj) { - var result = []; - - if (!obj) { - return result; - } - - var objs = obj.split("\\"); - for (var i = 0; i < objs.length; i++) { - result.push(parseFloat(objs[i])); - } - - return result; -}; diff --git a/Packages/ohif-core/client/lib/parsingUtils.js b/Packages/ohif-core/client/lib/parsingUtils.js deleted file mode 100644 index 5c244d8fe..000000000 --- a/Packages/ohif-core/client/lib/parsingUtils.js +++ /dev/null @@ -1,79 +0,0 @@ -import { dicomParser } from 'meteor/ohif:cornerstone'; - -/** - * A small set of utilities to help parsing DICOM element values. - * In the future the functionality provided by this library might - * be incorporated into dicomParser library. - */ - -export const parsingUtils = { - - /** - * Check if supplied argument is a valid instance of the dicomParser.DataSet class. - * @param data {Object} An instance of the dicomParser.DataSet class. - * @returns {Boolean} Returns true if data is a valid instance of the dicomParser.DataSet class. - */ - isValidDataSet: function(data) { - return (data instanceof dicomParser.DataSet); - }, - - /** - * Parses an element tag according to the 'AT' VR definition. - * @param data {Object} An instance of the dicomParser.DataSet class. - * @param tag {String} A DICOM tag with in the format xGGGGEEEE. - * @returns {String} A string representation of a data element tag or null if the field is not present or data is not long enough. - */ - attributeTag: function(data, tag) { - if (this.isValidDataSet(data) && tag in data.elements) { - let element = data.elements[tag]; - if (element && element.length === 4) { - let parser = data.byteArrayParser.readUint16, - bytes = data.byteArray, - offset = element.dataOffset; - return 'x' + ('00000000' + (parser(bytes, offset) * 256 * 256 + parser(bytes, offset + 2)).toString(16)).substr(-8); - } - } - - return null; - }, - - /** - * Parses the string representation of a multi-valued element into an array of strings. If the parser - * parameter is passed and is a function, it will be applied to each element of the resulting array. - * @param data {Object} An instance of the dicomParser.DataSet class. - * @param tag {String} A DICOM tag with in the format xGGGGEEEE. - * @param parser {Function} An optional parser function that can be applied to each element of the array. - * @returns {Array} An array of floating point numbers or null if the field is not present or data is not long enough. - */ - multiValue: function(data, tag, parser) { - if (this.isValidDataSet(data) && tag in data.elements) { - let element = data.elements[tag]; - if (element && element.length > 0) { - let string = dicomParser.readFixedString(data.byteArray, element.dataOffset, element.length); - if (typeof string === 'string' && string.length > 0) { - if (typeof parser !== 'function') { - parser = null; - } - - return string.split('\\').map(function(value) { - value = value.trim(); - return parser !== null ? parser(value) : value; - }); - } - } - } - - return null; - }, - - /** - * Parses a string to an array of floats for a multi-valued element. - * @param data {Object} An instance of the dicomParser.DataSet class. - * @param tag {String} A DICOM tag with in the format xGGGGEEEE. - * @returns {Array} An array of floating point numbers or null if the field is not present or data is not long enough. - */ - floatArray: function(data, tag) { - return this.multiValue(data, tag, parseFloat); - } - -}; diff --git a/Packages/ohif-core/client/lib/retrieveStudiesMetadata.js b/Packages/ohif-core/client/lib/retrieveStudiesMetadata.js deleted file mode 100644 index 48918c36d..000000000 --- a/Packages/ohif-core/client/lib/retrieveStudiesMetadata.js +++ /dev/null @@ -1,32 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -/** - * Retrieves metaData for multiple studies at once. - * - * This function calls retrieveStudyMetadata several times, asynchronously, - * and waits for all of the results to be returned. - * - * @param studyInstanceUids The UIDs of the Studies to be retrieved - * @return Promise - */ -OHIF.studies.retrieveStudiesMetadata = (studyInstanceUids, seriesInstanceUids) => { - // Create an empty array to store the Promises for each metaData retrieval call - const promises = []; - - // Loop through the array of studyInstanceUids - studyInstanceUids.forEach(function(studyInstanceUid) { - // Send the call and resolve or reject the related promise based on its outcome - const promise = OHIF.studies.retrieveStudyMetadata(studyInstanceUid, seriesInstanceUids); - - // Add the current promise to the array of promises - promises.push(promise); - }); - - // When all of the promises are complete, this callback runs - const promise = Promise.all(promises); - - // Warn the error on console if some retrieval failed - promise.catch(error => OHIF.log.warn(error)); - - return promise; -}; diff --git a/Packages/ohif-core/client/lib/retrieveStudyMetadata.js b/Packages/ohif-core/client/lib/retrieveStudyMetadata.js deleted file mode 100644 index 4d691abd5..000000000 --- a/Packages/ohif-core/client/lib/retrieveStudyMetadata.js +++ /dev/null @@ -1,61 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { OHIF } from 'meteor/ohif:core'; - -// Define the StudyMetaDataPromises object. This is used as a cache to store study meta data -// promises and prevent unnecessary subsequent calls to the server -const StudyMetaDataPromises = new Map(); - - -/** - * Delete the cached study metadata retrieval promise to ensure that the browser will - * re-retrieve the study metadata when it is next requested - * - * @param {String} studyInstanceUid The UID of the Study to be removed from cache - * - */ -OHIF.studies.deleteStudyMetadataPromise = (studyInstanceUid) => { - if (StudyMetaDataPromises.has(studyInstanceUid)) { - StudyMetaDataPromises.delete(studyInstanceUid); - } -}; - -/** - * Retrieves study metadata using a server call - * - * @param {String} studyInstanceUid The UID of the Study to be retrieved - * @returns {Promise} that will be resolved with the metadata or rejected with the error - */ -OHIF.studies.retrieveStudyMetadata = (studyInstanceUid, seriesInstanceUids) => { - - // @TODO: Whenever a study metadata request has failed, its related promise will be rejected once and for all - // and further requests for that metadata will always fail. On failure, we probably need to remove the - // corresponding promise from the "StudyMetaDataPromises" map... - - // If the StudyMetaDataPromises cache already has a pending or resolved promise related to the - // given studyInstanceUid, then that promise is returned - if (StudyMetaDataPromises.has(studyInstanceUid)) { - return StudyMetaDataPromises.get(studyInstanceUid); - } - - const seriesKeys = Array.isArray(seriesInstanceUids) ? '|' + seriesInstanceUids.join('|') : ''; - const timingKey = `retrieveStudyMetadata[${studyInstanceUid}${seriesKeys}]`; - OHIF.log.time(timingKey); - - // Create a promise to handle the data retrieval - const promise = new Promise((resolve, reject) => { - const server = OHIF.servers.getCurrentServer(); - - // If no study metadata is in the cache variable, we need to retrieve it from - // the server with a call. - if (server.type === 'dicomWeb' && server.requestOptions.requestFromBrowser === true) { - OHIF.studies.services.WADO.RetrieveMetadata(server, studyInstanceUid).then(function (data) { - resolve(data) - }, reject); - } - }); - - // Store the promise in cache - StudyMetaDataPromises.set(studyInstanceUid, promise); - - return promise; -}; diff --git a/Packages/ohif-core/client/lib/searchStudies.js b/Packages/ohif-core/client/lib/searchStudies.js deleted file mode 100644 index d53ce2d13..000000000 --- a/Packages/ohif-core/client/lib/searchStudies.js +++ /dev/null @@ -1,27 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { OHIF } from 'meteor/ohif:core'; - -const studySearchPromises = new Map(); - -/** - * Search for studies information by the given filter - * - * @param {Object} filter Filter that will be used on search - * @returns {Promise} resolved with an array of studies information or rejected with an error - */ -OHIF.studies.searchStudies = filter => { - const promiseKey = JSON.stringify(filter); - if (studySearchPromises.has(promiseKey)) { - return studySearchPromises.get(promiseKey); - } else { - const promise = new Promise((resolve, reject) => { - const server = OHIF.servers.getCurrentServer(); - - if (server.type === 'dicomWeb' && server.requestOptions.requestFromBrowser === true) { - OHIF.studies.services.QIDO.Studies(server, filter).then(resolve, reject); - } - }); - studySearchPromises.set(promiseKey, promise); - return promise; - } -}; diff --git a/Packages/ohif-core/client/lib/string.js b/Packages/ohif-core/client/lib/string.js deleted file mode 100644 index fe47eda1e..000000000 --- a/Packages/ohif-core/client/lib/string.js +++ /dev/null @@ -1,51 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import _ from 'underscore'; -import $ from 'jquery'; - -OHIF.string = {}; - -// Search for some string inside any object or array -OHIF.string.search = (object, query, property=null, result=[]) => { - // Create the search pattern - const pattern = new RegExp($.trim(query), 'i'); - - _.each(object, item => { - // Stop here if item is empty - if (!item) { - return; - } - - // Get the value to be compared - const value = _.isString(property) ? item[property] : item; - - // Check if the value match the pattern - if (_.isString(value) && pattern.test(value)) { - // Add the current item to the result - result.push(item); - } - - if (_.isObject(item)) { - // Search recursively the item if the current item is an object - OHIF.string.search(item, query, property, result); - } - }); - - // Return the found items - return result; -}; - -// Encode any string into a safe format for HTML id attribute -OHIF.string.encodeId = input => { - const string = input && input.toString ? input.toString() : input; - - // Return an underscore if the given string is empty or if it's not a string - if (string === '' || typeof string !== 'string') { - return '_'; - } - - // Create a converter to replace non accepted chars - const converter = match => '_' + match[0].charCodeAt(0).toString(16) + '_'; - - // Encode the given string and return it - return string.replace(/[^a-zA-Z0-9-]/g, converter); -}; diff --git a/Packages/ohif-core/client/lib/third-party/transition-to-from-auto.js b/Packages/ohif-core/client/lib/third-party/transition-to-from-auto.js deleted file mode 100644 index a32fd8603..000000000 --- a/Packages/ohif-core/client/lib/third-party/transition-to-from-auto.js +++ /dev/null @@ -1,151 +0,0 @@ -/*! - * transition-to-from-auto 0.5.2 - * https://github.com/75lb/transition-to-from-auto - * Copyright 2015 Lloyd Brookes <75pound@gmail.com> - */ - -/** -@module -@alias transition -*/ -(function(window, document){ - "use strict"; - - var getComputedStyle = window.getComputedStyle; - var isTransition = "data-ttfaInTransition"; - - var elements = []; - var data = []; - - // Transition detecting - var transitionProp = false; - var transitionEnd = false; - var testStyle = document.createElement("a").style; - var testProp; - - if(testStyle[testProp = "webkitTransition"] !== undefined) { - transitionProp = testProp; - transitionEnd = testProp + "End"; - } - - if(testStyle[testProp = "transition"] !== undefined) { - transitionProp = testProp; - transitionEnd = testProp + "end"; - } - - function process(options, data) { - var el = options.element; - var val = options.val; - var prop = options.prop; - var style = el.style; - var startVal; - var autoVal; - - if(!transitionProp) { - return style[prop] = val; - } - - if(el.hasAttribute(isTransition)) { - el.removeEventListener(transitionEnd, data.l); - } else { - style[transitionProp] = "none"; - - startVal = getComputedStyle(el)[prop]; - style[prop] = "auto"; - autoVal = getComputedStyle(el)[prop]; - - // Interrupt - if(startVal === val || val === "auto" && startVal === autoVal) { - return; - } - - data.auto = autoVal; - el.setAttribute(isTransition, 1); - - // Transition - style[prop] = startVal; - el.offsetWidth; - style[transitionProp] = options.style; - } - - style[prop] = val === "auto" ? data.auto : val; - - data.l = function (e) { - if(e.propertyName === prop) { - el.removeAttribute(isTransition); - el.removeEventListener(transitionEnd, data.l); - if(val === "auto") { - /* avoid transition flashes in Safari */ - style[transitionProp] = "none"; - style[prop] = val; - } - } - }; - - el.addEventListener(transitionEnd, data.l); - } - - /** - @param options {Object} - @param options.element {string | element} - The DOM element or selector to transition - @param options.val {string} - The value you want to transition to - @param [options.prop] {string} - The CSS property to transition, defaults to `"height"` - @param [options.style] {string} - The desired value for the `transition` CSS property (e.g. `"height 1s"`). If specified, this value is added inline and will override your CSS. Leave this value blank if you already have it defined in your stylesheet. - @alias module:transition-to-from-auto - */ - function transition(options){ - var element = options.element; - var datum; - var index; - - if(typeof element === "string") { - element = document.querySelector(element); - } - - element = options.element = element instanceof Node ? element : false; - options.prop = options.prop || "height"; - options.style = options.style || ""; - - if(element) { - index = elements.indexOf(element); - if(~index) { - datum = data[index]; - } else { - datum = {}; - elements.push(element); - data.push(datum); - } - - process(options, datum); - } - } - - /** - The name of the vendor-specific transition CSS property - @type {string} - @example - el.style[transition.prop + 'Duration'] = '1s'; - */ - transition.prop = transitionProp; - - /** - * The name of the [transition end event](https://developer.mozilla.org/en-US/docs/Web/Events/transitionend) in the current browser (typically `"transitionend"` or `"webkitTransitionEnd"`) - * @type {string} - * @example - * el.addEventListener(transition.end, function(){ - * // the transition ended.. - * }); - */ - transition.end = transitionEnd; - - - if (typeof module === "object" && module.exports){ - module.exports = transition; - } else if (typeof define === "function" && define.amd){ - define(function(){ - return transition; - }); - } else { - window.transition = transition; - } -})(window, document); diff --git a/Packages/ohif-core/client/lib/ui.js b/Packages/ohif-core/client/lib/ui.js deleted file mode 100644 index 3e5aac43d..000000000 --- a/Packages/ohif-core/client/lib/ui.js +++ /dev/null @@ -1,90 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { Meteor } from 'meteor/meteor'; - -// Get the UI settings -const ui = Meteor.settings && Meteor.settings.public && Meteor.settings.public.ui; -OHIF.uiSettings = ui || {}; - -/** - * Get the offset for the given element - * - * @param {Object} element DOM element which will have the offser calculated - * @returns {Object} Object containing the top and left offset - */ -OHIF.ui.getOffset = element => { - let top = 0; - let left = 0; - if (element.offsetParent) { - do { - left += element.offsetLeft; - top += element.offsetTop; - } while (element = element.offsetParent); - } - - return { - left, - top - }; -}; - -/** - * Get the vertical and horizontal scrollbar sizes - * Got from https://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes - * - * @returns {Array} Array containing the scrollbar horizontal and vertical sizes - */ -OHIF.ui.getScrollbarSize = () => { - const inner = document.createElement('p'); - inner.style.width = '100%'; - inner.style.height = '100%'; - - const outer = document.createElement('div'); - outer.style.position = 'absolute'; - outer.style.top = '0px'; - outer.style.left = '0px'; - outer.style.visibility = 'hidden'; - outer.style.width = '100px'; - outer.style.height = '100px'; - outer.style.overflow = 'hidden'; - outer.appendChild(inner); - - document.body.appendChild(outer); - - const w1 = inner.offsetWidth; - const h1 = inner.offsetHeight; - outer.style.overflow = 'scroll'; - let w2 = inner.offsetWidth; - let h2 = inner.offsetHeight; - - if (w1 === w2) { - w2 = outer.clientWidth; - } - - if (h1 === h2) { - h2 = outer.clientHeight; - } - - document.body.removeChild(outer); - - return [(w1 - w2), (h1 - h2)]; -}; - -/** - * Check if the pressed key combination will result in a character input - * Got from https://stackoverflow.com/questions/4179708/how-to-detect-if-the-pressed-key-will-produce-a-character-inside-an-input-text - * - * @returns {Boolean} Wheter the pressed key combination will input a character or not - */ -OHIF.ui.isCharacterKeyPress = event => { - if (typeof event.which === 'undefined') { - // This is IE, which only fires keypress events for printable keys - return true; - } else if (typeof event.which === 'number' && event.which > 0) { - // In other browsers except old versions of WebKit, event.which is - // only greater than zero if the keypress is a printable key. - // We need to filter out backspace and ctrl/alt/meta key combinations - return !event.ctrlKey && !event.metaKey && !event.altKey && event.which !== 8; - } - - return false; -}; diff --git a/Packages/ohif-core/client/lib/user.js b/Packages/ohif-core/client/lib/user.js deleted file mode 100644 index eacfb8dbf..000000000 --- a/Packages/ohif-core/client/lib/user.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { OHIF } from 'meteor/ohif:core'; - -OHIF.user = OHIF.user || {}; - -// These should be overridden by the implementation -OHIF.user.schema = null; -OHIF.user.userLoggedIn = () => false; -OHIF.user.getUserId = () => null; -OHIF.user.getName = () => null; -OHIF.user.getAccessToken = () => null; -OHIF.user.login = () => new Promise((resolve, reject) => reject()); -OHIF.user.logout = () => new Promise((resolve, reject) => reject()); -OHIF.user.getData = (key) => null; -OHIF.user.setData = (key, value) => null; -OHIF.user.validate = () => null; diff --git a/Packages/ohif-core/client/lib/utils.js b/Packages/ohif-core/client/lib/utils.js deleted file mode 100644 index 7bd90c660..000000000 --- a/Packages/ohif-core/client/lib/utils.js +++ /dev/null @@ -1,42 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -// Return the array sorting function for its object's properties -OHIF.utils.sortBy = function() { - var fields = [].slice.call(arguments), - n_fields = fields.length; - - return function(A, B) { - var a, b, field, key, primer, reverse, result, i; - - for (i = 0; i < n_fields; i++) { - result = 0; - field = fields[i]; - - key = typeof field === 'string' ? field : field.name; - - a = A[key]; - b = B[key]; - - if (typeof field.primer !== 'undefined') { - a = field.primer(a); - b = field.primer(b); - } - - reverse = (field.reverse) ? -1 : 1; - - if (a < b) { - result = reverse * -1; - } - - if (a > b) { - result = reverse * 1; - } - - if (result !== 0) { - break; - } - } - - return result; - }; -}; diff --git a/Packages/ohif-core/client/lib/viewer.js b/Packages/ohif-core/client/lib/viewer.js deleted file mode 100644 index a1674ee63..000000000 --- a/Packages/ohif-core/client/lib/viewer.js +++ /dev/null @@ -1,3 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -OHIF.viewer = {}; \ No newline at end of file diff --git a/Packages/ohif-core/client/lib/writeScript.js b/Packages/ohif-core/client/lib/writeScript.js deleted file mode 100644 index 451e74f3b..000000000 --- a/Packages/ohif-core/client/lib/writeScript.js +++ /dev/null @@ -1,14 +0,0 @@ -/* jshint -W060 */ -import absoluteUrl from './absoluteUrl'; - -export default function(fileName, callback) { - const script = document.createElement('script'); - script.src = absoluteUrl(`/packages/ohif_polyfill/public/js/${fileName}`); - script.onload = () => { - if (typeof callback === 'function') { - callback(script); - } - }; - - document.body.appendChild(script); -} diff --git a/Packages/ohif-core/client/metadata.js b/Packages/ohif-core/client/metadata.js deleted file mode 100644 index 4e402cdaf..000000000 --- a/Packages/ohif-core/client/metadata.js +++ /dev/null @@ -1,11 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import metadata from './classes/metadata/'; - -/** - * Append Metadata namespace to OHIF namespace... - */ - -OHIF.metadata = metadata; - -export { metadata }; - diff --git a/Packages/ohif-core/client/schema.js b/Packages/ohif-core/client/schema.js deleted file mode 100644 index f99247351..000000000 --- a/Packages/ohif-core/client/schema.js +++ /dev/null @@ -1,35 +0,0 @@ -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; -import { Match } from 'meteor/check'; - -/* - Extend the available options on schema definitions: - - * valuesLabels: Used in conjunction with allowedValues to define the text - label for each value (used on forms) - - * textOptional: Used to allow empty strings - - */ -SimpleSchema.extendOptions({ - valuesLabels: Match.Optional([String]), - textOptional: Match.Optional(Boolean) -}); - -// Add default required validation for empty strings which can be bypassed -// using textOptional=true definition -SimpleSchema.addValidator(function() { - if ( - this.definition.optional !== true && - this.definition.textOptional !== true && - this.value === '' - ) { - return 'required'; - } -}); - -// Including [label] for some messages -SimpleSchema.messages({ - maxCount: '[label] can not have more than [maxCount] values', - minCount: '[label] must have at least [minCount] values', - notAllowed: '[label] has an invalid value: "[value]"' -}); diff --git a/Packages/ohif-core/client/schema/servers.js b/Packages/ohif-core/client/schema/servers.js deleted file mode 100644 index d12820095..000000000 --- a/Packages/ohif-core/client/schema/servers.js +++ /dev/null @@ -1,314 +0,0 @@ -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; - -const serverNameDefinitions = { - type: String, - label: 'Server Name', - max: 100 -}; - -const serverTypeDefinitions = { - type: String, - label: 'Server Type', - allowedValues: ['dicomWeb', 'dimse'], - valuesLabels: ['DICOM Web', 'DIMSE'], - optional: true -}; - -const wadoUriRootDefinitions = { - type: String, - label: 'WADO URI root', - max: 1000 -}; - -const availableMouseButtonTools = ['wwwc', 'zoom', 'pan', 'stackScroll']; - -export const DICOMWebRequestOptions = new SimpleSchema({ - auth: { - type: String, - label: 'Authentication', - defaultValue: 'orthanc:orthanc', - optional: true - }, - requestFromBrowser: { - type: Boolean, - label: 'Make DICOMWeb requests from the Browser', - defaultValue: false, - optional: true - }, - logRequests: { - type: Boolean, - defaultValue: true, - label: 'Requests' - }, - logResponses: { - type: Boolean, - defaultValue: false, - label: 'Responses' - }, - logTiming: { - type: Boolean, - defaultValue: true, - label: 'Timing' - } -}); - -export const DICOMWebServer = new SimpleSchema({ - name: serverNameDefinitions, - type: serverTypeDefinitions, - wadoUriRoot: wadoUriRootDefinitions, - wadoRoot: { - type: String, - label: 'WADO root', - max: 1000 - }, - imageRendering: { - type: String, - label: 'Image rendering', - allowedValues: ['wadouri', 'wadors'], - valuesLabels: ['WADO URI', 'WADO RS'], - defaultValue: 'wadouri' - }, - thumbnailRendering: { - type: String, - label: 'Thumbnail rendering', - allowedValues: ['wadouri', 'wadors'], - valuesLabels: ['WADO URI', 'WADO RS'], - defaultValue: 'wadouri' - }, - qidoRoot: { - type: String, - label: 'QIDO root', - max: 1000 - }, - qidoSupportsIncludeField: { - type: Boolean, - label: 'QIDO supports "includefield" query key', - defaultValue: false - }, - requestOptions: { - type: DICOMWebRequestOptions, - label: 'Request Options' - } -}); - -export const DIMSEPeer = new SimpleSchema({ - aeTitle: { - type: String, - label: 'AE Title' - }, - hostAE: { - type: String, - label: 'AE Host', - optional: true - }, - host: { - type: String, - label: 'Host Domain/IP', - regEx: SimpleSchema.RegEx.WeakDomain - }, - port: { - type: Number, - label: 'Port', - min: 1, - defaultValue: 11112, - max: 65535 - }, - default: { - type: Boolean, - label: 'Default', - defaultValue: false - }, - server: { - type: Boolean, - label: 'Server', - defaultValue: false - }, - supportsInstanceRetrievalByStudyUid: { - type: Boolean, - label: 'Supports instance retrieval by StudyUid', - defaultValue: true - } -}); - -export const DIMSEServer = new SimpleSchema({ - name: serverNameDefinitions, - type: serverTypeDefinitions, - wadoUriRoot: wadoUriRootDefinitions, - requestOptions: { - type: DICOMWebRequestOptions, - label: 'Request Options' - }, - peers: { - type: [DIMSEPeer], - label: 'Peer List', - minCount: 1 - } -}); - -export const UISettings = new SimpleSchema({ - studyListFunctionsEnabled: { - type: Boolean, - label: 'Study List Functions Enabled?', - defaultValue: true - }, - leftSidebarOpen: { - type: Boolean, - label: 'Left sidebar open by default?', - defaultValue: false - }, - leftSidebarDragAndDrop: { - type: Boolean, - label: 'Left sidebar allows thumbnail drag and drop. If false, images will be loaded on single click.', - defaultValue: true - }, - displaySetNavigationLoopOverSeries: { - type: Boolean, - label: 'The UP/DOWN display set navigation buttons will start over when reach the last display set in viewport?', - defaultValue: true - }, - displaySetNavigationMultipleViewports: { - type: Boolean, - label: 'The UP/DOWN display set navigation buttons will iterate over all the viewports at once?', - defaultValue: false - }, - displayEchoUltrasoundWorkflow: { - type: Boolean, - label: 'Enable cine dialog enhancements for multiframe images.', - defaultValue: false - }, - autoPositionMeasurementsTextCallOuts: { - type: String, - label: 'Auto position text call-outs for measurements when creating them.', - defaultValue: 'TRBL' - }, - studyListDateFilterNumDays: { - type: Number, - label: 'Number of days to be used on Study List date filter', - min: 1 - }, - showStackLoadingProgressBar: { - type: Boolean, - label: 'Show a progress bar closest to the thumbnail showing how much the stack has loaded', - defaultValue: true - }, - cornerstoneRenderer: { - type: String, - label: 'Cornerstone default image renderer', - defaultValue: 'webgl' - }, - sortSeriesByIncomingOrder: { - type: Boolean, - label: 'Define if the series\' images shall be sorted by incoming order. Sort by Instance Number by default.', - defaultValue: false - }, - useMiddleSeriesInstanceAsThumbnail: { - type: Boolean, - label: 'Define if the middle instance of a series will be used as thumbnail. If not, the first instance will be used.', - defaultValue: true - } -}); - -export const PrefetchSchema = new SimpleSchema({ - order: { - type: String, - label: 'Prefetch Order', - allowedValues: ['topdown', 'downward', 'closest'], - optional: false - }, - displaySetCount: { - type: Number, - label: 'Display Set Count', - min: 1, - defaultValue: 1 - } -}); - -export const MouseButtonToolSchema = new SimpleSchema({ - left: { - type: String, - label: 'Left Mouse Button', - allowedValues: availableMouseButtonTools, - optional: true - }, - right: { - type: String, - label: 'Right Mouse Button', - allowedValues: availableMouseButtonTools, - optional: true - }, - middle: { - type: String, - label: 'Middle Mouse Button', - allowedValues: availableMouseButtonTools, - optional: true - } -}); - -export const PublicServerConfig = new SimpleSchema({ - verifyEmail: { - type: Boolean, - label: 'Verify Email', - defaultValue: false - }, - demoUserEnabled: { - type: Boolean, - label: 'Creates demo user on startup and show TestDrive button', - defaultValue: true - }, - userAuthenticationRoutesEnabled: { - type: Boolean, - label: 'Enables routing to /login page.', - defaultValue: false, - }, - ui: { - type: UISettings, - label: 'UI Settings' - }, - prefetch: { - type: PrefetchSchema, - label: 'Prefetch settings' - }, - defaultMouseButtonTools: { - type: MouseButtonToolSchema, - label: 'Default Mouse Button Tools' - } -}); - -export const Servers = new SimpleSchema({ - dicomWeb: { - type: [DICOMWebServer], - label: 'DICOMWeb Servers', - optional: true - }, - dimse: { - type: [DIMSEServer], - label: 'DIMSE Servers', - optional: true - } -}); - -export const ServerConfiguration = new SimpleSchema({ - servers: { - type: Servers, - label: 'Servers' - }, - defaultServiceType: { - type: String, - label: 'Default Service Type', - defaultValue: 'dicomWeb' - }, - dropCollections: { - type: Boolean, - label: 'Drop database collections', - defaultValue: false - }, - public: { - type: PublicServerConfig, - label: 'Public Server Configuration', - }, - origin: { - type: String, - label: 'Origin', - optional: true - } -}); diff --git a/Packages/ohif-core/client/services/index.js b/Packages/ohif-core/client/services/index.js deleted file mode 100644 index 7b42f9006..000000000 --- a/Packages/ohif-core/client/services/index.js +++ /dev/null @@ -1,15 +0,0 @@ -// DICOMWeb instance, study, and metadata retrieval -import Instances from './qido/instances.js'; -import Studies from './qido/studies.js'; -import RetrieveMetadata from './wado/retrieveMetadata.js'; - -const WADO = { - RetrieveMetadata -}; - -const QIDO = { - Studies, - Instances -}; - -export { QIDO, WADO }; diff --git a/Packages/ohif-core/client/services/qido/instances.js b/Packages/ohif-core/client/services/qido/instances.js deleted file mode 100644 index 86d977d32..000000000 --- a/Packages/ohif-core/client/services/qido/instances.js +++ /dev/null @@ -1,92 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import DICOMwebClient from 'dicomweb-client'; - -const { DICOMWeb } = OHIF; - -/** - * Parses data returned from a QIDO search and transforms it into - * an array of series that are present in the study - * - * @param server The DICOM server - * @param studyInstanceUid - * @param resultData - * @returns {Array} Series List - */ -function resultDataToStudyMetadata(server, studyInstanceUid, resultData) { - const { DICOMWeb } = OHIF; - - var seriesMap = {}; - var seriesList = []; - - resultData.forEach(function(instance) { - // Use seriesMap to cache series data - // If the series instance UID has already been used to - // process series data, continue using that series - var seriesInstanceUid = DICOMWeb.getString(instance['0020000E']); - var series = seriesMap[seriesInstanceUid]; - - // If no series data exists in the seriesMap cache variable, - // process any available series data - if (!series) { - series = { - seriesInstanceUid: seriesInstanceUid, - seriesNumber: DICOMWeb.getString(instance['00200011']), - instances: [] - }; - - // Save this data in the seriesMap cache variable - seriesMap[seriesInstanceUid] = series; - seriesList.push(series); - } - - // The uri for the dicomweb - // NOTE: DCM4CHEE seems to return the data zipped - // NOTE: Orthanc returns the data with multi-part mime which cornerstoneWADOImageLoader doesn't - // know how to parse yet - //var uri = DICOMWeb.getString(instance['00081190']); - //uri = uri.replace('wado-rs', 'dicom-web'); - - // manually create a WADO-URI from the UIDs - // NOTE: Haven't been able to get Orthanc's WADO-URI to work yet - maybe its not configured? - var sopInstanceUid = DICOMWeb.getString(instance['00080018']); - var uri = server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + '&contentType=application%2Fdicom'; - - // Add this instance to the current series - series.instances.push({ - sopClassUid: DICOMWeb.getString(instance['00080016']), - sopInstanceUid: sopInstanceUid, - uri: uri, - instanceNumber: DICOMWeb.getString(instance['00200013']) - }); - }); - return seriesList; -} - -/** - * Retrieve a set of instances using a QIDO call - * @param server - * @param studyInstanceUid - * @throws ECONNREFUSED - * @returns {{wadoUriRoot: String, studyInstanceUid: String, seriesList: Array}} - */ -export default function Instances(server, studyInstanceUid) { - // TODO: Are we using this function anywhere?? Can we remove it? - - const config = { - url: server.qidoRoot, - headers: OHIF.DICOMWeb.getAuthorizationHeader() - }; - const dicomWeb = new DICOMwebClient.api.DICOMwebClient(config); - const queryParams = getQIDOQueryParams(filter, server.qidoSupportsIncludeField); - const options = { - studyInstanceUID: studyInstanceUid - }; - - return dicomWeb.searchForInstances(options).then(result => { - return { - wadoUriRoot: server.wadoUriRoot, - studyInstanceUid: studyInstanceUid, - seriesList: resultDataToStudyMetadata(server, studyInstanceUid, result.data) - }; - }); -}; diff --git a/Packages/ohif-core/client/services/qido/studies.js b/Packages/ohif-core/client/services/qido/studies.js deleted file mode 100644 index 09bb61fd9..000000000 --- a/Packages/ohif-core/client/services/qido/studies.js +++ /dev/null @@ -1,134 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import DICOMwebClient from 'dicomweb-client'; - -const { DICOMWeb } = OHIF; - -// TODO: Is there an easier way to do this? -if (Meteor.isServer) { - var XMLHttpRequest = require('xhr2'); - - global.XMLHttpRequest = XMLHttpRequest; -} - -/** - * Creates a QIDO date string for a date range query - * Assumes the year is positive, at most 4 digits long. - * - * @param date The Date object to be formatted - * @returns {string} The formatted date string - */ -function dateToString(date) { - if (!date) return ''; - let year = date.getFullYear().toString(); - let month = (date.getMonth() + 1).toString(); - let day = date.getDate().toString(); - year = '0'.repeat(4 - year.length).concat(year); - month = '0'.repeat(2 - month.length).concat(month); - day = '0'.repeat(2 - day.length).concat(day); - return ''.concat(year, month, day); -} - -/** - * Produces a QIDO URL given server details and a set of specified search filter - * items - * - * @param filter - * @param serverSupportsQIDOIncludeField - * @returns {string} The URL with encoded filter query data - */ -function getQIDOQueryParams(filter, serverSupportsQIDOIncludeField) { - const commaSeparatedFields = [ - '00081030', // Study Description - '00080060' //Modality - // Add more fields here if you want them in the result - ].join(','); - - const parameters = { - PatientName: filter.patientName, - PatientID: filter.patientId, - AccessionNumber: filter.accessionNumber, - StudyDescription: filter.studyDescription, - ModalitiesInStudy: filter.modalitiesInStudy, - limit: filter.limit, - offset: filter.offset, - includefield: serverSupportsQIDOIncludeField ? commaSeparatedFields : 'all' - }; - - // build the StudyDate range parameter - if (filter.studyDateFrom || filter.studyDateTo) { - const dateFrom = dateToString(new Date(filter.studyDateFrom)); - const dateTo = dateToString(new Date(filter.studyDateTo)); - parameters.StudyDate = `${dateFrom}-${dateTo}`; - } - - // Build the StudyInstanceUID parameter - if (filter.studyInstanceUid) { - let studyUids = filter.studyInstanceUid; - studyUids = Array.isArray(studyUids) ? studyUids.join() : studyUids; - studyUids = studyUids.replace(/[^0-9.]+/g, '\\'); - parameters.StudyInstanceUID = studyUids; - } - - // Clean query params of undefined values. - const params = {}; - Object.keys(parameters).forEach(key => { - if (parameters[key] !== undefined && - parameters[key] !== "") { - params[key] = parameters[key]; - } - }); - - return params; -} - -/** - * Parses resulting data from a QIDO call into a set of Study MetaData - * - * @param resultData - * @returns {Array} An array of Study MetaData objects - */ -function resultDataToStudies(resultData) { - const { DICOMWeb } = OHIF; - - const studies = []; - - if (!resultData || !resultData.length) return; - - resultData.forEach(study => studies.push({ - studyInstanceUid: DICOMWeb.getString(study['0020000D']), - // 00080005 = SpecificCharacterSet - studyDate: DICOMWeb.getString(study['00080020']), - studyTime: DICOMWeb.getString(study['00080030']), - accessionNumber: DICOMWeb.getString(study['00080050']), - referringPhysicianName: DICOMWeb.getString(study['00080090']), - // 00081190 = URL - patientName: DICOMWeb.getName(study['00100010']), - patientId: DICOMWeb.getString(study['00100020']), - patientBirthdate: DICOMWeb.getString(study['00100030']), - patientSex: DICOMWeb.getString(study['00100040']), - studyId: DICOMWeb.getString(study['00200010']), - numberOfStudyRelatedSeries: DICOMWeb.getString(study['00201206']), - numberOfStudyRelatedInstances: DICOMWeb.getString(study['00201208']), - studyDescription: DICOMWeb.getString(study['00081030']), - // modality: DICOMWeb.getString(study['00080060']), - // modalitiesInStudy: DICOMWeb.getString(study['00080061']), - modalities: DICOMWeb.getString(DICOMWeb.getModalities(study['00080060'], study['00080061'])) - })); - - return studies; -} - -export default function Studies(server, filter) { - const config = { - url: server.qidoRoot, - headers: OHIF.DICOMWeb.getAuthorizationHeader() - }; - - const dicomWeb = new DICOMwebClient.api.DICOMwebClient(config); - const queryParams = getQIDOQueryParams(filter, server.qidoSupportsIncludeField); - const options = { - queryParams - }; - - return dicomWeb.searchForStudies(options).then(resultDataToStudies); -}; diff --git a/Packages/ohif-core/client/services/wado/retrieveMetadata.js b/Packages/ohif-core/client/services/wado/retrieveMetadata.js deleted file mode 100644 index 5c777c555..000000000 --- a/Packages/ohif-core/client/services/wado/retrieveMetadata.js +++ /dev/null @@ -1,391 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import DICOMwebClient from 'dicomweb-client'; - -import { parseFloatArray } from '../../lib/parseFloatArray'; - -WADOProxy = { - convertURL: (url, server) => { - // TODO: Remove all WADOProxy stuff from this file - return url; - } -} - -/** - * Simple cache schema for retrieved color palettes. - */ -const paletteColorCache = { - count: 0, - maxAge: 24 * 60 * 60 * 1000, // 24h cache? - entries: {}, - isValidUID: function (paletteUID) { - return typeof paletteUID === 'string' && paletteUID.length > 0; - }, - get: function (paletteUID) { - let entry = null; - if (this.entries.hasOwnProperty(paletteUID)) { - entry = this.entries[paletteUID]; - // check how the entry is... - if ((Date.now() - entry.time) > this.maxAge) { - // entry is too old... remove entry. - delete this.entries[paletteUID]; - this.count--; - entry = null; - } - } - return entry; - }, - add: function (entry) { - if (this.isValidUID(entry.uid)) { - let paletteUID = entry.uid; - if (this.entries.hasOwnProperty(paletteUID) !== true) { - this.count++; // increment cache entry count... - } - entry.time = Date.now(); - this.entries[paletteUID] = entry; - // @TODO: Add logic to get rid of old entries and reduce memory usage... - } - } -}; - -/** Returns a WADO url for an instance - * - * @param studyInstanceUid - * @param seriesInstanceUid - * @param sopInstanceUid - * @returns {string} - */ -function buildInstanceWadoUrl(server, studyInstanceUid, seriesInstanceUid, sopInstanceUid) { - // TODO: This can be removed, since DICOMWebClient has the same function. Not urgent, though - const params = []; - - params.push('requestType=WADO'); - params.push(`studyUID=${studyInstanceUid}`); - params.push(`seriesUID=${seriesInstanceUid}`); - params.push(`objectUID=${sopInstanceUid}`); - params.push('contentType=application/dicom'); - params.push('transferSyntax=*'); - - const paramString = params.join('&'); - - return `${server.wadoUriRoot}?${paramString}`; -} - -function buildInstanceWadoRsUri(server, studyInstanceUid, seriesInstanceUid, sopInstanceUid) { - return `${server.wadoRoot}/studies/${studyInstanceUid}/series/${seriesInstanceUid}/instances/${sopInstanceUid}` -} - -function buildInstanceFrameWadoRsUri(server, studyInstanceUid, seriesInstanceUid, sopInstanceUid, frame) { - const baseWadoRsUri = buildInstanceWadoRsUri(server, studyInstanceUid, seriesInstanceUid, sopInstanceUid); - frame = frame != null || 1; - - return `${baseWadoRsUri}/frames/${frame}` -} - -/** - * Parses the SourceImageSequence, if it exists, in order - * to return a ReferenceSOPInstanceUID. The ReferenceSOPInstanceUID - * is used to refer to this image in any accompanying DICOM-SR documents. - * - * @param instance - * @returns {String} The ReferenceSOPInstanceUID - */ -function getSourceImageInstanceUid(instance) { - // TODO= Parse the whole Source Image Sequence - // This is a really poor workaround for now. - // Later we should probably parse the whole sequence. - var SourceImageSequence = instance['00082112']; - if (SourceImageSequence && SourceImageSequence.Value && SourceImageSequence.Value.length) { - return SourceImageSequence.Value[0]['00081155'].Value[0]; - } -} - -function getPaletteColor(server, instance, tag, lutDescriptor) { - const numLutEntries = lutDescriptor[0]; - const bits = lutDescriptor[2]; - - let uri = WADOProxy.convertURL(instance[tag].BulkDataURI, server) - - // TODO: Workaround for dcm4chee behind SSL-terminating proxy returning - // incorrect bulk data URIs - if (server.wadoRoot.indexOf('https') === 0 && - !uri.includes('https')) { - uri = uri.replace('http', 'https'); - } - - const config = { - url: server.wadoRoot, //BulkDataURI is absolute, so this isn't used - headers: OHIF.DICOMWeb.getAuthorizationHeader() - }; - const dicomWeb = new DICOMwebClient.api.DICOMwebClient(config); - const options = { - BulkDataURI: uri - }; - - const readUInt16 = (byteArray, position) => { - return byteArray[position] + (byteArray[position + 1] * 256); - } - - const arrayBufferToPaletteColorLUT = (arraybuffer) =>{ - const byteArray = new Uint8Array(arraybuffer); - const lut = []; - - for (let i = 0; i < numLutEntries; i++) { - if (bits === 16) { - lut[i] = readUInt16(byteArray, i * 2); - } else { - lut[i] = byteArray[i]; - } - } - - return lut; - } - - return dicomWeb.retrieveBulkData(options).then(arrayBufferToPaletteColorLUT) -} - -/** - * Fetch palette colors for instances with "PALETTE COLOR" photometricInterpretation. - * - * @param server {Object} Current server; - * @param instance {Object} The retrieved instance metadata; - * @returns {String} The ReferenceSOPInstanceUID - */ -async function getPaletteColors(server, instance, lutDescriptor) { - const { DICOMWeb } = OHIF; - - let paletteUID = DICOMWeb.getString(instance['00281199']); - - return new Promise((resolve, reject) => { - if (paletteColorCache.isValidUID(paletteUID)) { - const entry = paletteColorCache.get(paletteUID); - - if (entry) { - return resolve(entry); - } - } - - // no entry in cache... Fetch remote data. - const r = getPaletteColor(server, instance, '00281201', lutDescriptor); - const g = getPaletteColor(server, instance, '00281202', lutDescriptor);; - const b = getPaletteColor(server, instance, '00281203', lutDescriptor);; - - const promises = [r, g, b]; - - Promise.all(promises).then((args) => { - entry = { - red: args[0], - green: args[1], - blue: args[2] - }; - - // when paletteUID is present, the entry can be cached... - entry.uid = paletteUID; - paletteColorCache.add(entry); - - resolve(entry); - }); - }); -} - -function getFrameIncrementPointer(element) { - const frameIncrementPointerNames = { - '00181065': 'frameTimeVector', - '00181063': 'frameTime' - }; - - if(!element || !element.Value || !element.Value.length) { - return; - } - - const value = element.Value[0]; - return frameIncrementPointerNames[value]; -} - -function getRadiopharmaceuticalInfo(instance) { - const { DICOMWeb } = OHIF; - - const modality = DICOMWeb.getString(instance['00080060']); - - if (modality !== 'PT') { - return; - } - - const radiopharmaceuticalInfo = instance['00540016']; - if ((radiopharmaceuticalInfo === undefined) || !radiopharmaceuticalInfo.Value || !radiopharmaceuticalInfo.Value.length) { - return; - } - - const firstPetRadiopharmaceuticalInfo = radiopharmaceuticalInfo.Value[0]; - return { - radiopharmaceuticalStartTime: DICOMWeb.getString(firstPetRadiopharmaceuticalInfo['00181072']), - radionuclideTotalDose: DICOMWeb.getNumber(firstPetRadiopharmaceuticalInfo['00181074']), - radionuclideHalfLife: DICOMWeb.getNumber(firstPetRadiopharmaceuticalInfo['00181075']) - }; -} - -/** - * Parses result data from a WADO search into Study MetaData - * Returns an object populated with study metadata, including the - * series list. - * - * @param server - * @param studyInstanceUid - * @param resultData - * @returns {{seriesList: Array, patientName: *, patientId: *, accessionNumber: *, studyDate: *, modalities: *, studyDescription: *, imageCount: *, studyInstanceUid: *}} - */ -async function resultDataToStudyMetadata(server, studyInstanceUid, resultData) { - const { DICOMWeb } = OHIF; - - if (!resultData.length) { - return; - } - - const anInstance = resultData[0]; - if (!anInstance) { - return; - } - - const studyData = { - seriesList: [], - studyInstanceUid, - wadoUriRoot: server.wadoUriRoot, - patientName: DICOMWeb.getName(anInstance['00100010']), - patientId: DICOMWeb.getString(anInstance['00100020']), - patientAge: DICOMWeb.getNumber(anInstance['00101010']), - patientSize: DICOMWeb.getNumber(anInstance['00101020']), - patientWeight: DICOMWeb.getNumber(anInstance['00101030']), - accessionNumber: DICOMWeb.getString(anInstance['00080050']), - studyDate: DICOMWeb.getString(anInstance['00080020']), - modalities: DICOMWeb.getString(anInstance['00080061']), - studyDescription: DICOMWeb.getString(anInstance['00081030']), - imageCount: DICOMWeb.getString(anInstance['00201208']), - studyInstanceUid: DICOMWeb.getString(anInstance['0020000D']), - institutionName: DICOMWeb.getString(anInstance['00080080']) - }; - - const seriesMap = {}; - - await Promise.all(resultData.map(async function(instance) { - const seriesInstanceUid = DICOMWeb.getString(instance['0020000E']); - let series = seriesMap[seriesInstanceUid]; - - if (!series) { - series = { - seriesDescription: DICOMWeb.getString(instance['0008103E']), - modality: DICOMWeb.getString(instance['00080060']), - seriesInstanceUid: seriesInstanceUid, - seriesNumber: DICOMWeb.getNumber(instance['00200011']), - seriesDate: DICOMWeb.getString(instance['00080021']), - seriesTime: DICOMWeb.getString(instance['00080031']), - instances: [] - }; - seriesMap[seriesInstanceUid] = series; - studyData.seriesList.push(series); - } - - const sopInstanceUid = DICOMWeb.getString(instance['00080018']); - const wadouri = buildInstanceWadoUrl(server, studyInstanceUid, seriesInstanceUid, sopInstanceUid); - const baseWadoRsUri = buildInstanceWadoRsUri(server, studyInstanceUid, seriesInstanceUid, sopInstanceUid); - const wadorsuri = buildInstanceFrameWadoRsUri(server, studyInstanceUid, seriesInstanceUid, sopInstanceUid); - - const instanceSummary = { - imageType: DICOMWeb.getString(instance['00080008']), - sopClassUid: DICOMWeb.getString(instance['00080016']), - modality: DICOMWeb.getString(instance['00080060']), - sopInstanceUid, - instanceNumber: DICOMWeb.getNumber(instance['00200013']), - imagePositionPatient: DICOMWeb.getString(instance['00200032']), - imageOrientationPatient: DICOMWeb.getString(instance['00200037']), - frameOfReferenceUID: DICOMWeb.getString(instance['00200052']), - sliceLocation: DICOMWeb.getNumber(instance['00201041']), - samplesPerPixel: DICOMWeb.getNumber(instance['00280002']), - photometricInterpretation: DICOMWeb.getString(instance['00280004']), - planarConfiguration: DICOMWeb.getNumber(instance['00280006']), - rows: DICOMWeb.getNumber(instance['00280010']), - columns: DICOMWeb.getNumber(instance['00280011']), - pixelSpacing: DICOMWeb.getString(instance['00280030']), - pixelAspectRatio: DICOMWeb.getString(instance['00280034']), - bitsAllocated: DICOMWeb.getNumber(instance['00280100']), - bitsStored: DICOMWeb.getNumber(instance['00280101']), - highBit: DICOMWeb.getNumber(instance['00280102']), - pixelRepresentation: DICOMWeb.getNumber(instance['00280103']), - smallestPixelValue: DICOMWeb.getNumber(instance['00280106']), - largestPixelValue: DICOMWeb.getNumber(instance['00280107']), - windowCenter: DICOMWeb.getString(instance['00281050']), - windowWidth: DICOMWeb.getString(instance['00281051']), - rescaleIntercept: DICOMWeb.getNumber(instance['00281052']), - rescaleSlope: DICOMWeb.getNumber(instance['00281053']), - rescaleType: DICOMWeb.getNumber(instance['00281054']), - sourceImageInstanceUid: getSourceImageInstanceUid(instance), - laterality: DICOMWeb.getString(instance['00200062']), - viewPosition: DICOMWeb.getString(instance['00185101']), - acquisitionDateTime: DICOMWeb.getString(instance['0008002A']), - numberOfFrames: DICOMWeb.getNumber(instance['00280008']), - frameIncrementPointer: getFrameIncrementPointer(instance['00280009']), - frameTime: DICOMWeb.getNumber(instance['00181063']), - frameTimeVector: parseFloatArray(DICOMWeb.getString(instance['00181065'])), - sliceThickness: DICOMWeb.getNumber(instance['00180050']), - lossyImageCompression: DICOMWeb.getString(instance['00282110']), - derivationDescription: DICOMWeb.getString(instance['00282111']), - lossyImageCompressionRatio: DICOMWeb.getString(instance['00282112']), - lossyImageCompressionMethod: DICOMWeb.getString(instance['00282114']), - echoNumber: DICOMWeb.getString(instance['00180086']), - contrastBolusAgent: DICOMWeb.getString(instance['00180010']), - radiopharmaceuticalInfo: getRadiopharmaceuticalInfo(instance), - baseWadoRsUri: baseWadoRsUri, - wadouri: WADOProxy.convertURL(wadouri, server), - wadorsuri: WADOProxy.convertURL(wadorsuri, server), - imageRendering: server.imageRendering, - thumbnailRendering: server.thumbnailRendering - }; - - // Get additional information if the instance uses "PALETTE COLOR" photometric interpretation - if (instanceSummary.photometricInterpretation === 'PALETTE COLOR') { - const redPaletteColorLookupTableDescriptor = parseFloatArray(DICOMWeb.getString(instance['00281101'])); - const greenPaletteColorLookupTableDescriptor = parseFloatArray(DICOMWeb.getString(instance['00281102'])); - const bluePaletteColorLookupTableDescriptor = parseFloatArray(DICOMWeb.getString(instance['00281103'])); - const palettes = await getPaletteColors(server, instance, redPaletteColorLookupTableDescriptor); - - if (palettes) { - if (palettes.uid) { - instanceSummary.paletteColorLookupTableUID = palettes.uid; - } - - instanceSummary.redPaletteColorLookupTableData = palettes.red; - instanceSummary.greenPaletteColorLookupTableData = palettes.green; - instanceSummary.bluePaletteColorLookupTableData = palettes.blue; - instanceSummary.redPaletteColorLookupTableDescriptor = redPaletteColorLookupTableDescriptor; - instanceSummary.greenPaletteColorLookupTableDescriptor = greenPaletteColorLookupTableDescriptor; - instanceSummary.bluePaletteColorLookupTableDescriptor = bluePaletteColorLookupTableDescriptor; - } - } - - series.instances.push(instanceSummary); - })); - - return studyData; -} - -/** - * Retrieve Study MetaData from a DICOM server using a WADO call - * - * @param server - * @param studyInstanceUid - * @returns {Promise} - */ -async function RetrieveMetadata (server, studyInstanceUid) { - const config = { - url: server.wadoRoot, - headers: OHIF.DICOMWeb.getAuthorizationHeader() - }; - const dicomWeb = new DICOMwebClient.api.DICOMwebClient(config); - const options = { - studyInstanceUID: studyInstanceUid - }; - - return dicomWeb.retrieveStudyMetadata(options).then(result => { - return resultDataToStudyMetadata(server, studyInstanceUid, result); - }); -}; - -export default RetrieveMetadata; diff --git a/Packages/ohif-core/client/startup.js b/Packages/ohif-core/client/startup.js deleted file mode 100644 index bbdbe7d5a..000000000 --- a/Packages/ohif-core/client/startup.js +++ /dev/null @@ -1,22 +0,0 @@ -// Check the servers on meteor startup -import { Meteor } from "meteor/meteor"; -import { Servers, CurrentServer } from './collections'; - -const servers = Meteor.settings.public.servers; - -Object.keys(servers).forEach((serverType) => { - const endpoints = servers[serverType]; - endpoints.forEach((endpoint) => { - const server = Object.assign({}, endpoint); - server.type = serverType; - - Servers.insert(server); - }); -}); - -const newServer = Servers.findOne(); - -CurrentServer.insert({ - serverId: newServer._id -}); - diff --git a/Packages/ohif-core/client/studies.js b/Packages/ohif-core/client/studies.js deleted file mode 100644 index 68c8c4fca..000000000 --- a/Packages/ohif-core/client/studies.js +++ /dev/null @@ -1,9 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; -import { QIDO, WADO } from './services/'; - -OHIF.studies = { - services: { - QIDO, - WADO - } -}; diff --git a/Packages/ohif-core/client/ui/bounded/bounded.js b/Packages/ohif-core/client/ui/bounded/bounded.js deleted file mode 100644 index cca73c382..000000000 --- a/Packages/ohif-core/client/ui/bounded/bounded.js +++ /dev/null @@ -1,240 +0,0 @@ -import $ from 'jquery'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -// Allow attaching to jQuery selectors -$.fn.bounded = function(options) { - _.each(this, element => { - const boundedInstance = $(element).data('boundedInstance'); - if (options === 'destroy' && boundedInstance) { - $(element).removeData('boundedInstance'); - boundedInstance.destroy(); - } else { - if (boundedInstance) { - boundedInstance.options(options); - } else { - $(element).data('boundedInstance', new Bounded(element, options)); - } - } - }); - - return this; -}; - -/** - * This class makes an element bounded to other element's borders. - */ -class Bounded { - - // Initialize the instance with the given element and options - constructor(element, options={}) { - this.element = element; - this.$element = $(element); - this.options(options); - this.setBoundedFlag(false); - - // Force to hardware acceleration to move element if browser supports translate property - this.useTransform = OHIF.ui.styleProperty.check('transform', 'translate(1px, 1px)'); - } - - // Set or change the instance options - options(options={}) { - // Process the given options and store it in the instance - const { boundingElement, positionElement, dimensionElement, allowResizing } = options; - this.positionElement = positionElement || this.element; - this.$positionElement = $(this.positionElement); - this.dimensionElement = dimensionElement || this.element; - this.$dimensionElement = $(this.dimensionElement); - this.boundingElement = boundingElement; - this.$boundingElement = $(this.boundingElement); - this.allowResizing = allowResizing; - - // Check for fixed positioning - if (this.$positionElement.css('position') === 'fixed') { - this.boundingElement = window; - } - - // Destroy and initialize again the instance - this.destroy(); - this.init(); - } - - // Initialize the bounding behaviour - init() { - // Create the event handlers - this.defineEventHandlers(); - - // Attach the created event handlers to the component - this.attachEventHandlers(); - - // Add the bounded class to the element - this.$element.addClass('bounded'); - - // Handle the positioning on window resize - const $window = $(window); - const windowResizeHandler = () => { - // Check if the element is still in DOM and remove the handler if it is not - if (!this.$element.closest(document.documentElement).length) { - $window.off('resize', windowResizeHandler); - } - - this.$element.trigger('spatialChanged'); - }; - - $window.on('resize', windowResizeHandler); - - // Trigger the bounding check for the first timepoint - setTimeout(() => this.$element.trigger('spatialChanged')); - } - - // Destroy this instance, returning the element to its previous state - destroy() { - // Detach the event handlers - this.detachEventHandlers(); - - // Remove the bounded class from the element - this.$element.removeClass('bounded'); - } - - static spatialInfo(positionElement, dimensionElement) { - // Create the result object - const result = {}; - - // Check if the element is the window - if (!dimensionElement || dimensionElement === window) { - const $window = $(window); - const width = $window.outerWidth(); - const height = $window.outerHeight(); - return { - width, - height, - x0: 0, - y0: 0, - x1: width, - y1: height - }; - } - - // Get the jQuery object for the elements - const $dimensionElement = $(dimensionElement); - const $positionElement = $(positionElement); - - // Get the integer numbers for element's width - result.width = $dimensionElement.outerWidth(); - - // Get the integer numbers for element's height - result.height = $dimensionElement.outerHeight(); - - // Get the position property based on the element position CSS attribute - const elementPosition = $positionElement.css('position'); - const positionProperty = elementPosition === 'fixed' ? 'position' : 'offset'; - - // Get the element's start position - const position = $positionElement[positionProperty](); - result.x0 = position.left; - result.y0 = position.top; - - // Get the element's end position - result.x1 = result.x0 + result.width; - result.y1 = result.y0 + result.height; - - // Return the result object - return result; - } - - // Define the event handlers for this class - defineEventHandlers() { - this.cssPositionHandler = (elementInfo, boundingInfo) => { - // Fix element's x positioning and width - if (this.allowResizing && elementInfo.width > boundingInfo.width) { - this.$dimensionElement.width(boundingInfo.width); - this.$positionElement.css('left', boundingInfo.x0); - this.setBoundedFlag(true); - } else if (elementInfo.x0 < boundingInfo.x0) { - this.$positionElement.css('left', boundingInfo.x0); - this.setBoundedFlag(true); - } else if (elementInfo.x1 > boundingInfo.x1) { - this.$positionElement.css('left', boundingInfo.x1 - elementInfo.width); - this.setBoundedFlag(true); - } - - // Fix element's y positioning and height - if (this.allowResizing && elementInfo.height > boundingInfo.height) { - this.$dimensionElement.height(boundingInfo.height); - this.$positionElement.css('top', boundingInfo.y0); - this.setBoundedFlag(true); - } else if (elementInfo.y0 < boundingInfo.y0) { - this.$positionElement.css('top', boundingInfo.y0); - this.setBoundedFlag(true); - } else if (elementInfo.y1 > boundingInfo.y1) { - this.$positionElement.css('top', boundingInfo.y1 - elementInfo.height); - this.setBoundedFlag(true); - } - }; - - this.getCSSTranslate = () => { - const matrixToArray = str => str.match(/(-?[0-9\.]+)/g); - const transformMatrix = matrixToArray(this.$positionElement.css('transform')) || []; - return { - x: parseFloat(transformMatrix[4]) || 0, - y: parseFloat(transformMatrix[5]) || 0 - }; - }; - - this.cssTransformHandler = (elementInfo, boundingInfo, translate) => { - if (elementInfo.x1 > boundingInfo.x1) { - translate.x -= elementInfo.x1 - boundingInfo.x1; - } - - if (elementInfo.y1 > boundingInfo.y1) { - translate.y -= elementInfo.y1 - boundingInfo.y1; - } - - if (elementInfo.x0 < boundingInfo.x0) { - translate.x += boundingInfo.x0 - elementInfo.x0; - } - - if (elementInfo.y0 < boundingInfo.y0) { - translate.y += boundingInfo.y0 - elementInfo.y0; - } - - const translation = `translate(${translate.x}px, ${translate.y}px)`; - OHIF.ui.styleProperty.set(this.positionElement, 'transform', translation); - }; - - this.spatialChangedHandler = event => { - // Get the spatial information for element and its bounding element - const { positionElement, dimensionElement, boundingElement, useTransform } = this; - const elementInfo = Bounded.spatialInfo(positionElement, dimensionElement); - const boundingInfo = Bounded.spatialInfo(boundingElement, boundingElement); - - // Check if CSS positioning or transform will be used - const translate = this.getCSSTranslate(); - if (useTransform && (translate.x || translate.y)) { - this.cssTransformHandler(elementInfo, boundingInfo, translate); - } else { - this.cssPositionHandler(elementInfo, boundingInfo); - } - }; - } - - // Attach the event handlers to the element in order to bound it - attachEventHandlers() { - this.$element.on('spatialChanged', this.spatialChangedHandler); - this.$boundingElement.on('resize', this.spatialChangedHandler); - } - - // Detach the event handlers from the element - detachEventHandlers() { - this.$element.off('spatialChanged', this.spatialChangedHandler); - this.$boundingElement.off('resize', this.spatialChangedHandler); - } - - // This is a means to let outside world know that the element in question has been moved - setBoundedFlag(value) { - this.$element.data('wasBounded', value); - } - -} - -OHIF.ui.Bounded = Bounded; diff --git a/Packages/ohif-core/client/ui/dialog/display.js b/Packages/ohif-core/client/ui/dialog/display.js deleted file mode 100644 index 1b4ec1a09..000000000 --- a/Packages/ohif-core/client/ui/dialog/display.js +++ /dev/null @@ -1,94 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Blaze } from 'meteor/blaze'; -import _ from 'underscore'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; - -let zIndexBackdrop = 1060; -let zIndexModal = 1061; - -OHIF.ui.showDialog = (templateName, dialogData={}) => { - // Check if the given template exists - const template = Template[templateName]; - if (!template) { - throw { - name: 'TEMPLATE_NOT_FOUND', - message: `Template ${templateName} not found.` - }; - } - - let promise; - let templateData; - if (dialogData && dialogData.promise instanceof Promise) { - // Use the given promise to control the modal - promise = dialogData.promise; - templateData = dialogData; - } else { - // Create a new promise to control the modal and store its resolve and reject callbacks - let promiseResolve; - let promiseReject; - promise = new Promise((resolve, reject) => { - promiseResolve = resolve; - promiseReject = reject; - }); - - // Render the dialog with the given template passing the promise object and callbacks - templateData = _.extend({}, dialogData, { - promise, - promiseResolve, - promiseReject - }); - } - - const view = Blaze.renderWithData(template, templateData, document.body); - - const node = view.firstNode(); - const $node = node && $(node); - - let $modal; - if ($node && $node.hasClass('modal')) { - $modal = $node; - } else if ($node && $node.has('.modal')) { - $modal = $node.find('.modal:first'); - } - - $modal.one('show.bs.modal', function() { - setTimeout(() => { - const $modal = $(this); - const modal = $modal.data('bs.modal'); - if (!modal) return; - const { $backdrop } = modal; - if (!$backdrop) return; - $backdrop.css('z-index', zIndexBackdrop); - $modal.css('z-index', zIndexModal); - zIndexBackdrop += 2; - zIndexModal += 2; - }); - }); - - // Destroy the created dialog view when the promise is either resolved or rejected - const dismissModal = (hideFirst=false) => { - if (hideFirst || (dialogData && dialogData.promise && $modal)) { - $modal.one('hidden.bs.modal', () => Blaze.remove(view)).modal('hide'); - } else { - Blaze.remove(view); - } - }; - - // Create a handler to dismiss the modal on navigation - const $body = $(document.body); - const navigationHandler = () => { - dismissModal(true); - $body.off('ohif.navigated', navigationHandler); - }; - - promise.then(() => dismissModal(false)).catch(() => dismissModal(false)); - - // Dismiss the modal if navigation occurs and it should not be kept opened - if (!dialogData.keepOpenOnNavigation) { - $body.on('ohif.navigated', navigationHandler); - } - - // Return the promise to allow callbacks stacking from outside - return promise; -}; diff --git a/Packages/ohif-core/client/ui/dialog/spatial.js b/Packages/ohif-core/client/ui/dialog/spatial.js deleted file mode 100644 index 94919bec4..000000000 --- a/Packages/ohif-core/client/ui/dialog/spatial.js +++ /dev/null @@ -1,30 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -OHIF.ui.repositionDialog = ($modal, x, y) => { - const $dialog = $modal.find('.modal-dialog'); - - // Remove the margins and set its position as fixed - $dialog.css({ - margin: 0, - position: 'fixed' - }).bounded(); - - // Temporarily show the modal - const isVisible = $modal.is(':visible'); - $modal.show(); - - // Calculate the center position on screen - const height = $dialog.outerHeight(); - const width = $dialog.outerWidth(); - const left = parseInt(x - (width / 2)); - const top = parseInt(y - (height / 2)); - - // Reposition the modal and readjust it to the window boundaries if needed - $dialog.css({ - left, - top - }).trigger('spatialChanged').one('transitionend', () => $dialog.trigger('spatialChanged')); - - // Switch the modal to its previous visibility state - $modal.toggle(isVisible); -}; diff --git a/Packages/ohif-core/client/ui/dialog/unsavedChangesDialog.js b/Packages/ohif-core/client/ui/dialog/unsavedChangesDialog.js deleted file mode 100644 index 7a8b01f00..000000000 --- a/Packages/ohif-core/client/ui/dialog/unsavedChangesDialog.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Blaze } from 'meteor/blaze'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -OHIF.ui.unsavedChangesDialog = function(callback, options) { - - // Render the dialog with the given template passing the promise object and callbacks - const templateData = _.extend({}, options, { - callback: callback - }); - Blaze.renderWithData(Template.unsavedChangesDialog, templateData, document.body); - -}; diff --git a/Packages/ohif-core/client/ui/dimensional/dimensional.js b/Packages/ohif-core/client/ui/dimensional/dimensional.js deleted file mode 100644 index ac5081d2e..000000000 --- a/Packages/ohif-core/client/ui/dimensional/dimensional.js +++ /dev/null @@ -1,50 +0,0 @@ -import $ from 'jquery'; - -// Temporarily show and hide the element to enable dimension calculations -$.fn.tempShow = function(callback) { - const elementsToHide = []; - let current = this; - - // Temporarily show all parent invisible elements until body - while (this.is(':hidden')) { - const $element = $(current); - if (!$element.length || $element.is(':visible')) { - break; - } - - $element.addClass('visible'); - elementsToHide.push(current); - current = $element[0].parentElement; - } - - if (typeof callback === 'function') { - callback(this); - } - - $(elementsToHide).removeClass('visible'); - - return this; -}; - -// Adjust the max width/height to enable CSS3 transitions -$.fn.adjustMax = function(dimension, modifierFn) { - const $element = $(this); - - // Temporarily make the element visible to allow getting its dimensions - $element.tempShow(() => { - const maxProperty = `max-${dimension}`; - - // Remove the current max restriction - $element.each((i, e) => e.style.setProperty(maxProperty, 'none', 'important')); - - // Get the dimension function to obtain the outer dimension - const dimensionFn = 'outer' + dimension.charAt(0).toUpperCase() + dimension.slice(1); - const value = $element[dimensionFn](); - - // Remove the property (needed for IE) - $element.each((i, e) => e.style.removeProperty(maxProperty)); - - // Set the new max restriction - $element.css(maxProperty, value); - }); -}; diff --git a/Packages/ohif-core/client/ui/dimensional/dimensional.styl b/Packages/ohif-core/client/ui/dimensional/dimensional.styl deleted file mode 100644 index 13ff4c84a..000000000 --- a/Packages/ohif-core/client/ui/dimensional/dimensional.styl +++ /dev/null @@ -1,2 +0,0 @@ -body *.visible - display: block !important diff --git a/Packages/ohif-core/client/ui/draggable/draggable.js b/Packages/ohif-core/client/ui/draggable/draggable.js deleted file mode 100644 index a896dd9be..000000000 --- a/Packages/ohif-core/client/ui/draggable/draggable.js +++ /dev/null @@ -1,229 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -// Allow attaching to jQuery selectors -$.fn.draggable = function(options) { - makeDraggable(this, options); - return this; -}; - -/** - * This function makes an element movable around the page. - * It supports mouse and touch input and allows whichever element - * is specified to be moved to any arbitrary position. - * - * @param element - */ -function makeDraggable(element, options={}) { - const $element = element; - const $document = $(document); - const $body = $(document.body); - - // Force to hardware acceleration to move element if browser supports translate property - const { styleProperty } = OHIF.ui; - const useTransform = styleProperty.check('transform', 'translate(1px, 1px)'); - - const $container = $(options.container || window); - let diffX; - let diffY; - let wasNotDragged = true; - let dragging = false; - - let lastCursor, lastOffset; - let lastTranslateX = 0; - let lastTranslateY = 0; - - let initialCursor; - - // initialize dragged flag - $element.data('wasDragged', false); - - function matrixToArray(str) { - return str.match(/(-?[0-9\.]+)/g); - } - - function getCursorCoords(e) { - const cursor = { - x: e.clientX, - y: e.clientY - }; - - // Handle touchMove cases - if (cursor.x === undefined) { - cursor.x = e.originalEvent.touches[0].pageX; - } - - if (cursor.y === undefined) { - cursor.y = e.originalEvent.touches[0].pageY; - } - - return cursor; - } - - function reposition(elementLeft, elementTop) { - if (useTransform) { - const translation = `translate(${elementLeft}px, ${elementTop}px)`; - styleProperty.set($element[0], 'transform', translation); - } else { - $element.css({ - left: elementLeft + 'px', - top: elementTop + 'px', - bottom: 'auto', // Setting these to empty doesn't seem to work in Firefox or Safari - right: 'auto' - }); - } - } - - function startMoving(e) { - // Prevent dragging dialog by clicking on slider - // (could be extended for buttons, not sure it's necessary - if (e.target.type && e.target.type === 'range') { - return; - } - - // Stop the dragging if it's not the primary button - if (e.button !== 0) return; - - // Stop the dragging if the element is being resized - if ($element.hasClass('resizing')) { - return; - } - - let elementLeft = parseFloat($element.offset().left); - let elementTop = parseFloat($element.offset().top); - - const cursor = getCursorCoords(e); - if (useTransform) { - lastCursor = cursor; - lastOffset = $element.offset(); - const transformMatrix = matrixToArray($element.css('transform')) || []; - lastTranslateX = parseFloat(transformMatrix[4]) || 0; - lastTranslateY = parseFloat(transformMatrix[5]) || 0; - elementLeft = lastTranslateX; - elementTop = lastTranslateY; - } else { - diffX = cursor.x - elementLeft; - diffY = cursor.y - elementTop; - } - - reposition(elementLeft, elementTop); - - $document.on('mousemove', moveHandler); - $document.on('mouseup', stopMoving); - - $document.on('touchmove', moveHandler); - $document.on('touchend', stopMoving); - } - - function stopMoving() { - $body.css('cursor', ''); - $container.css('cursor', ''); - $element.css('cursor', ''); - - if (dragging) { - setTimeout(() => $element.removeClass('dragging')); - dragging = false; - } - - $document.off('mousemove', moveHandler); - $document.off('touchmove', moveHandler); - } - - function moveHandler(e) { - if (!dragging) { - $body.css('cursor', 'move'); - $container.css('cursor', 'move'); - $element.css('cursor', 'move'); - $element.addClass('dragging'); - dragging = true; - } - - // let outside world know that the element in question has been dragged - if (wasNotDragged) { - $element.data('wasDragged', true); - wasNotDragged = false; - } - - // Prevent dialog box dragging whole page in iOS - e.preventDefault(); - - const elementWidth = parseFloat($element.outerWidth()); - const elementHeight = parseFloat($element.outerHeight()); - const containerWidth = parseFloat($container.width()); - const containerHeight = parseFloat($container.height()); - - const cursor = getCursorCoords(e); - - let elementLeft, elementTop; - if (useTransform) { - elementLeft = lastTranslateX - (lastCursor.x - cursor.x); - elementTop = lastTranslateY - (lastCursor.y - cursor.y); - - const limitX = containerWidth - elementWidth; - const limitY = containerHeight - elementHeight; - const sumX = lastOffset.left + (elementLeft - lastTranslateX); - const sumY = lastOffset.top + (elementTop - lastTranslateY); - - if (sumX > limitX) { - elementLeft -= sumX - limitX; - } - - if (sumY > limitY) { - elementTop -= sumY - limitY; - } - - if (sumX < 0) { - elementLeft += 0 - sumX; - } - - if (sumY < 0) { - elementTop += 0 - sumY; - } - } else { - elementLeft = cursor.x - diffX; - elementTop = cursor.y - diffY; - - elementLeft = Math.max(elementLeft, 0); - elementTop = Math.max(elementTop, 0); - - if (elementLeft + elementWidth > containerWidth) { - elementLeft = containerWidth - elementWidth; - } - - if (elementTop + elementHeight > containerHeight) { - elementTop = containerHeight - elementHeight; - } - } - - reposition(elementLeft, elementTop); - } - - function mouseDownHandler(e) { - initialCursor = getCursorCoords(e); - $document.on('mousemove', moveDetectHandler); - $document.on('touchmove', moveDetectHandler); - } - - function mouseUpHandler() { - $document.off('mousemove', moveDetectHandler); - $document.off('touchmove', moveDetectHandler); - } - - function moveDetectHandler(e) { - const currentCursor = getCursorCoords(e); - - const c1 = initialCursor; - const c2 = currentCursor; - const distance = Math.hypot(c2.x - c1.x, c2.y - c1.y); - - if (distance > 5) { - mouseUpHandler(); - startMoving(e); - } - } - - $element.on('mousedown', mouseDownHandler); - $element.on('touchstart', mouseDownHandler); - - $element.on('mouseup', mouseUpHandler); - $element.on('touchend', mouseUpHandler); -} diff --git a/Packages/ohif-core/client/ui/dropdown/class.js b/Packages/ohif-core/client/ui/dropdown/class.js deleted file mode 100644 index 9025287a7..000000000 --- a/Packages/ohif-core/client/ui/dropdown/class.js +++ /dev/null @@ -1,38 +0,0 @@ -import { Tracker } from 'meteor/tracker'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -class Dropdown { - constructor() { - this.observer = new Tracker.Dependency(); - this._items = []; - this.observer.changed(); - } - - clearItems() { - this._items = []; - this.observer.changed(); - } - - setItems(items) { - this._items = items; - this.observer.changed(); - } - - addItem(item) { - this._items.push(item); - this.observer.changed(); - } - - removeItem(item) { - this._items = _.without(this._items, item); - this.observer.changed(); - } - - getItems() { - this.observer.depend(); - return this._items; - } -} - -OHIF.ui.Dropdown = Dropdown; diff --git a/Packages/ohif-core/client/ui/dropdown/display.js b/Packages/ohif-core/client/ui/dropdown/display.js deleted file mode 100644 index 277f24447..000000000 --- a/Packages/ohif-core/client/ui/dropdown/display.js +++ /dev/null @@ -1,43 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Blaze } from 'meteor/blaze'; -import { OHIF } from 'meteor/ohif:core'; - -OHIF.ui.showDropdown = (items=[], options={}) => { - let promiseResolve; - let promiseReject; - const promise = new Promise((resolve, reject) => { - promiseResolve = resolve; - promiseReject = reject; - }); - - // Prepare the method to destroy the view - let view; - const destroyView = () => Blaze.remove(view); - - // Create the data object that the dropdown will receive - const templateData = { - items, - options, - destroyView, - promise, - promiseResolve, - promiseReject - }; - - // Render the dialog with the given template and data - const parentElement = options.parentElement || document.body; - view = Blaze.renderWithData(Template.dropdownForm, templateData, parentElement); - - // Create a handler to dismiss the dropdown on navigation - const $body = $(document.body); - const navigationHandler = () => { - promiseReject(); - $body.off('ohif.navigated', navigationHandler); - }; - - // Dismiss the dropdown if navigation occurs - $body.on('ohif.navigated', navigationHandler); - - // Return the promise to allow callbacks stacking from outside - return promise; -}; diff --git a/Packages/ohif-core/client/ui/handleError.js b/Packages/ohif-core/client/ui/handleError.js deleted file mode 100644 index 7d09d2a91..000000000 --- a/Packages/ohif-core/client/ui/handleError.js +++ /dev/null @@ -1,35 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { OHIF } from 'meteor/ohif:core'; - -OHIF.ui.handleError = error => { - let { title, message } = error; - - if (!title) { - if (error instanceof Meteor.Error) { - title = error.error; - } else if (error instanceof Error) { - title = error.name; - } - } - - if (!message) { - if (error instanceof Meteor.Error) { - message = error.reason; - } else if (error instanceof Error) { - message = error.message; - } - } - - const data = Object.assign({ - title, - message, - class: 'themed', - hideConfirm: true, - cancelLabel: 'Dismiss', - cancelClass: 'btn-secondary' - }, error || {}); - - OHIF.log.error(error); - // TODO: Find a better way to handle errors instead of displaying a dialog for all of them. - // OHIF.ui.showDialog('dialogForm', data); -}; diff --git a/Packages/ohif-core/client/ui/index.js b/Packages/ohif-core/client/ui/index.js deleted file mode 100644 index 88b79fd10..000000000 --- a/Packages/ohif-core/client/ui/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import './bounded/bounded.js'; -import './dimensional/dimensional.js'; -import './dialog/display.js'; -import './dialog/spatial.js'; -import './dialog/unsavedChangesDialog.js'; -import './draggable/draggable.js'; -import './dropdown/class.js'; -import './dropdown/display.js'; -import './notifications/notifications.js'; -import './popover/display.js'; -import './resizable/resizable.js'; -import './unsavedChanges/unsavedChanges.js'; -import './handleError.js'; -import './styleProperty.js'; diff --git a/Packages/ohif-core/client/ui/notifications/notifications.js b/Packages/ohif-core/client/ui/notifications/notifications.js deleted file mode 100644 index b3ef80db0..000000000 --- a/Packages/ohif-core/client/ui/notifications/notifications.js +++ /dev/null @@ -1,112 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import { Blaze } from 'meteor/blaze'; -import $ from 'jquery'; -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -const Notifications = { - currentId: 0, - views: new Map() -}; - -// Remove the view object from DOM and from views Map -const removeView = (id, view) => { - Notifications.views.delete(id); - Blaze.remove(view); -}; - -// Dismiss a single notification note by its id -Notifications.dismiss = id => { - const view = Notifications.views.get(id); - if (!view || view.isDestroyed) { - return Notifications.views.delete(id); - } - - const node = view.firstNode(); - const $note = node && $(node); - - if ($note.length) { - $note.addClass('out').one('transitionend', () => removeView(id, view)); - } else { - removeView(id, view); - } -}; - -// Dismiss all notification notes -Notifications.clear = () => Array.from(Notifications.views.keys()).forEach(Notifications.dismiss); - -// Display a notification note -Notifications.show = ({ template, data, text, style, timeout=5000, promise }) => { - // Check if the given template exists - const templateObject = Template[template]; - if (template && !templateObject) { - throw new Meteor.Error('TEMPLATE_NOT_FOUND', `Template ${template} not found.`); - } - - // Check if there is a notification area container - const $area = $('#notificationArea'); - if (!$area.length) { - throw new Meteor.Error('NOTIFICATION_AREA_NOT_FOUND', `Notification area not found.`); - } - - let notificationPromise; - let templateData = { - template, - data, - text, - style, - timeout, - id: Notifications.currentId++ - }; - - if (promise instanceof Promise) { - // Use the given promise to control the notification - notificationPromise = templateData.promise = promise; - } else { - // Create a new promise to control the modal and store its resolve and reject callbacks - let promiseResolve; - let promiseReject; - notificationPromise = new Promise((resolve, reject) => { - promiseResolve = resolve; - promiseReject = reject; - }); - - // Render the notification passing the promise object and callbacks - _.extend({}, templateData, { - promise: notificationPromise, - promiseResolve, - promiseReject - }); - } - - const view = Blaze.renderWithData(Template.notificationNote, templateData, $area[0]); - const dismissNotification = () => Notifications.dismiss(templateData.id); - - // Add the current view to the list of views to allow clearing all notifications - Notifications.views.set(templateData.id, view); - - // Destroy the created notification view when the promise is either resolved or rejected - notificationPromise.then(dismissNotification).catch(dismissNotification); - - // Destroy the created notification view if the given timeout time has passed - if (timeout > 0) { - Meteor.setTimeout(() => { - if (templateData.promiseResolve) { - templateData.promiseResolve(); - } else { - dismissNotification(); - } - }, timeout); - } - - // Return the promise to allow callbacks stacking from outside - return notificationPromise; -}; - -Notifications.info = o => Notifications.show(Object.assign({}, o, { style: 'info' })); -Notifications.success = o => Notifications.show(Object.assign({}, o, { style: 'success' })); -Notifications.warning = o => Notifications.show(Object.assign({}, o, { style: 'warning' })); -Notifications.danger = o => Notifications.show(Object.assign({}, o, { style: 'danger' })); - -OHIF.ui.notifications = Notifications; diff --git a/Packages/ohif-core/client/ui/popover/display.js b/Packages/ohif-core/client/ui/popover/display.js deleted file mode 100644 index 2bd5bd9c4..000000000 --- a/Packages/ohif-core/client/ui/popover/display.js +++ /dev/null @@ -1,88 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Blaze } from 'meteor/blaze'; -import { OHIF } from 'meteor/ohif:core'; - -OHIF.ui.showPopover = (templateName, popoverData, options={}) => { - // Check if the given template exists - const template = Template[templateName]; - if (!template) { - throw { - name: 'TEMPLATE_NOT_FOUND', - message: `Template ${templateName} not found.` - }; - } - - let promise; - let templateData; - if (popoverData && popoverData.promise instanceof Promise) { - // Use the given promise to control the modal - promise = popoverData.promise; - templateData = popoverData; - } else { - // Create a new promise to control the modal and store its resolve and reject callbacks - let promiseResolve; - let promiseReject; - promise = new Promise((resolve, reject) => { - promiseResolve = resolve; - promiseReject = reject; - }); - - // Render the dialog with the given template passing the promise object and callbacks - templateData = Object.assign({}, popoverData, { - promise, - promiseResolve, - promiseReject - }); - } - - const { element, event } = options; - const $element = $(element || event.currentTarget); - - const defaults = { - content: '', - html: true, - trigger: 'manual', - placement: 'auto', - delay: { - show: 300, - hide: 300 - } - }; - - const popoverOptions = Object.assign({} , defaults, options); - popoverOptions.content = Blaze.toHTMLWithData(template, popoverData); - - if (popoverOptions.hideOnClick) { - $element.click(function() { - $(this).popover('hide'); - }); - } - - $element.popover(popoverOptions); - - if (popoverOptions.trigger !== 'hover') { - $element.one('shown.bs.popover', function(event) { - const popoverId = $element.attr('aria-describedby'); - const popover = document.getElementById(popoverId); - const $popover = $(popover); - const $popoverContent = $popover.find('.popover-content'); - const dismissPopover = () => $element.popover('hide'); - - $popoverContent.html(''); - - const view = Blaze.renderWithData(template, templateData, $popoverContent[0]); - $element.one('hidden.bs.popover', () => { - Blaze.remove(view); - $element.popover('destroy'); - }); - - promise.then(dismissPopover).catch(dismissPopover); - }); - } - - if (popoverOptions.trigger === 'manual') { - $element.popover('show'); - } - - return promise; -}; diff --git a/Packages/ohif-core/client/ui/resizable/resizable.js b/Packages/ohif-core/client/ui/resizable/resizable.js deleted file mode 100644 index cb46ea221..000000000 --- a/Packages/ohif-core/client/ui/resizable/resizable.js +++ /dev/null @@ -1,182 +0,0 @@ -import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; - -// Allow attaching to jQuery selectors -$.fn.resizable = function(options) { - _.each(this, element => { - const resizableInstance = $(element).data('resizableInstance'); - if (options === 'destroy' && resizableInstance) { - $(element).removeData('resizableInstance'); - resizableInstance.destroy(); - } else { - if (resizableInstance) { - resizableInstance.options(options); - } else { - $(element).data('resizableInstance', new Resizable(element, options)); - } - } - }); - - return this; -}; - -/** - * This class makes an element resizable. - */ -class Resizable { - - constructor(element, options={}) { - this.element = element; - this.$element = $(element); - this.options(options); - } - - options(options={}) { - const { boundSize, minWidth, minHeight } = options; - this.minWidth = minWidth || this.$element.width() || 16; - this.minHeight = minHeight || this.$element.height() || 16; - this.boundSize = boundSize || 8; - - this.destroy(); - this.init(); - } - - init() { - this.defineEventHandlers(); - - for (let x = -1; x <= 1; x++) { - for (let y = -1; y <= 1; y++) { - this.createBound(x, y); - } - } - - this.$element.addClass('resizable'); - } - - destroy() { - // Remove the instance added classes - this.$element.removeClass('resizable resizing'); - - // Get the bound borders - const $bound = this.$element.find('resize-bound'); - - // Remove the bound borders - $bound.remove(); - - // Detach the event handlers - this.detachEventHandlers($bound); - } - - defineEventHandlers() { - this.initResizeHandler = event => { - const $window = $(window); - - this.width = this.initialWidth = this.$element.width(); - this.height = this.initialHeight = this.$element.height(); - this.startWidth = this.width; - this.startHeight = this.height; - - this.posX = parseInt(this.$element.css('left')); - this.posY = parseInt(this.$element.css('top')); - this.startPosX = this.posX; - this.startPosY = this.posY; - - this.startX = event.clientX; - this.startY = event.clientY; - - this.$element.addClass('resizing'); - - $window.on('mousemove', event.data, this.resizeHandler); - $window.on('mouseup', event.data, this.endResizeHandler); - }; - - this.resizeHandler = event => { - const { xDirection, yDirection } = event.data; - let x, y; - x = event.clientX < 0 ? 0 : event.clientX; - x = x > window.innerWidth ? window.innerWidth : x; - y = event.clientY < 0 ? 0 : event.clientY; - y = y > window.innerHeight ? window.innerHeight : y; - - const xDistance = (x - this.startX) * xDirection; - const yDistance = (y - this.startY) * yDirection; - - const width = xDistance + this.startWidth; - const height = yDistance + this.startHeight; - this.width = width < this.minWidth ? this.minWidth : width; - this.height = height < this.minHeight ? this.minHeight : height; - this.$element.width(this.width); - this.$element.height(this.height); - - if (xDirection < 0) { - this.posX = this.startPosX - xDistance; - if (width < this.minWidth) { - this.posX = this.startPosX + (this.startWidth - this.minWidth); - } - - this.$element.css('left', `${this.posX}px`); - } - - if (yDirection < 0) { - this.posY = this.startPosY - yDistance; - if (height < this.minHeight) { - this.posY = this.startPosY + (this.startHeight - this.minHeight); - } - - this.$element.css('top', `${this.posY}px`); - } - }; - - this.endResizeHandler = event => { - const $window = $(window); - - $window.off('mousemove', this.resizeHandler); - $window.off('mouseup', this.endResizeHandler); - - this.$element.removeClass('resizing'); - - // Let the listeners know that this element was resized - this.$element.trigger('resize'); - }; - } - - attachEventHandlers($bound, xDirection, yDirection) { - const eventData = { - xDirection, - yDirection - }; - $bound.on('mousedown', eventData, this.initResizeHandler); - } - - detachEventHandlers($bound) { - const $window = $(window); - - $bound.off('mousedown', this.initResizeHandler); - $window.off('mousemove', this.resizeHandler); - $window.off('mouseup', this.endResizeHandler); - } - - createBound(xDirection, yDirection) { - if (xDirection === 0 && xDirection === yDirection) { - return; - } - - const $bound = $('
'); - - $bound[0].onselectstart = () => false; - - $bound.css('font-size', `${this.boundSize}px`); - - const mapX = ['left', 'center', 'right']; - const mapY = ['top', 'middle', 'bottom']; - $bound.addClass('bound-' + mapX[xDirection + 1]); - $bound.addClass('bound-' + mapY[yDirection + 1]); - - $bound.appendTo(this.$element); - - this.attachEventHandlers($bound, xDirection, yDirection); - } - -} - -OHIF.ui.Resizable = Resizable; diff --git a/Packages/ohif-core/client/ui/resizable/resizable.styl b/Packages/ohif-core/client/ui/resizable/resizable.styl deleted file mode 100644 index 4849f4e4e..000000000 --- a/Packages/ohif-core/client/ui/resizable/resizable.styl +++ /dev/null @@ -1,58 +0,0 @@ -@import "{ohif:viewerbase}/app" - -.resizable - transform(scale(1)) - - &.resizing, .resize-bound - user-select: none - -webkit-touch-callout: none - -webkit-user-select: none - -khtml-user-select: none - -moz-user-select: none - -ms-user-select: none - - &.resizing iframe - pointer-events: none - - .resize-bound - content: '' - line-height: 1em - position: fixed - - .bound-left - left: 0 - width: 1em - - .bound-center - left: 1em - height: 1em - right: 1em - - .bound-right - right: 0 - width: 1em - - .bound-top - top: 0 - height: 1em - - .bound-middle - top: 1em - width: 1em - bottom: 1em - - .bound-bottom - bottom: 0 - height: 1em - - .bound-left.bound-top, .bound-right.bound-bottom - cursor: nwse-resize - - .bound-left.bound-bottom, .bound-right.bound-top - cursor: nesw-resize - - .bound-left.bound-middle, .bound-right.bound-middle - cursor: ew-resize - - .bound-center.bound-top, .bound-center.bound-bottom - cursor: ns-resize diff --git a/Packages/ohif-core/client/ui/styleProperty.js b/Packages/ohif-core/client/ui/styleProperty.js deleted file mode 100644 index 5dcca1d64..000000000 --- a/Packages/ohif-core/client/ui/styleProperty.js +++ /dev/null @@ -1,68 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -/* - * https://github.com/swederik/dragula/blob/ccc15d75186f5168e7abadbe3077cf12dab09f8b/styleProperty.js - */ -(function() { - 'use strict'; - - const browserProps = {}; - - function eachVendor(prop, fn) { - const prefixes = ['Webkit', 'Moz', 'ms', 'O']; - fn(prop); - for (let i = 0; i < prefixes.length; i++) { - fn(prefixes[i] + prop.charAt(0).toUpperCase() + prop.slice(1)); - } - } - - function check(property, testValue) { - const sandbox = document.createElement('iframe'); - const element = document.createElement('p'); - - document.body.appendChild(sandbox); - sandbox.contentDocument.body.appendChild(element); - const support = set(element, property, testValue); - - // We have to do this because remove() is not supported by IE11 and below - sandbox.parentElement.removeChild(sandbox); - return support; - } - - function checkComputed(el, prop) { - const computed = window.getComputedStyle(el).getPropertyValue(prop); - return ((computed !== void 0) && computed.length > 0 && computed !== 'none'); - } - - function set(el, prop, value) { - let match = false; - - if (browserProps[prop] === void 0) { - eachVendor(prop, function(vendorProp) { - if (el.style[vendorProp] !== void 0 && match === false) { - el.style[vendorProp] = value; - if (checkComputed(el, vendorProp)) { - match = true; - browserProps[prop] = vendorProp; - } - } - }); - } else { - el.style[browserProps[prop]] = value; - return true; - } - - return match; - } - - const styleProperty = { - check, - set - }; - - OHIF.ui.styleProperty = styleProperty; -}()); - -const { styleProperty } = OHIF.ui; - -export { styleProperty }; diff --git a/Packages/ohif-core/client/ui/unsavedChanges/unsavedChanges.js b/Packages/ohif-core/client/ui/unsavedChanges/unsavedChanges.js deleted file mode 100644 index deb88a7bd..000000000 --- a/Packages/ohif-core/client/ui/unsavedChanges/unsavedChanges.js +++ /dev/null @@ -1,555 +0,0 @@ -import { Tracker } from 'meteor/tracker'; -import { OHIF } from 'meteor/ohif:core'; -import _ from 'underscore'; - -const FUNCTION = 'function'; -const STRING = 'string'; -const UNDEFINED = 'undefined'; -const WILDCARD = '*'; // "*" is a special name which means "all children". -const SEPARATOR = '.'; - -/** - * Main Namespace Component Class - */ - -class Node { - - constructor() { - this.value = 0; - this.children = {}; - this.handlers = {}; - } - - getPathComponents(path) { - return typeof path === STRING ? path.split(SEPARATOR) : null; - } - - getNodeUpToIndex(path, index) { - - let node = this; - - for (let i = 0; i < index; ++i) { - let item = path[i]; - if (node.children.hasOwnProperty(item)) { - node = node.children[item]; - } else { - node = null; - break; - } - } - - return node; - - } - - append(name, value) { - - const children = this.children; - let node = null; - - if (children.hasOwnProperty(name)) { - node = children[name]; - } else if (typeof name === STRING && name !== WILDCARD) { - node = new Node(); - children[name] = node; - } - - if (node !== null) { - node.value += value > 0 ? parseInt(value) : 0; - } - - return node; - - } - - probe(recursively) { - - let value = this.value; - - // Calculate entire tree value recursively? - if (recursively === true) { - const children = this.children; - for (let item in children) { - if (children.hasOwnProperty(item)) { - value += children[item].probe(recursively); - } - } - } - - return value; - - } - - clear(recursively) { - - this.value = 0; - - // Clear entire tree recursively? - if (recursively === true) { - const children = this.children; - for (let item in children) { - if (children.hasOwnProperty(item)) { - children[item].clear(recursively); - } - } - } - - } - - appendPath(path, value) { - - path = this.getPathComponents(path); - - if (path !== null) { - const last = path.length - 1; - let node = this; - for (let i = 0; i < last; ++i) { - node = node.append(path[i], 0); - if (node === null) { - return false; - } - } - - return (node.append(path[last], value) !== null); - } - - return false; - - } - - clearPath(path, recursively) { - - path = this.getPathComponents(path); - - if (path !== null) { - const last = path.length - 1; - let node = this.getNodeUpToIndex(path, last); - if (node !== null) { - let item = path[last]; - if (item !== WILDCARD) { - if (node.children.hasOwnProperty(item)) { - node.children[item].clear(recursively); - return true; - } - } else { - const children = node.children; - for (item in children) { - if (children.hasOwnProperty(item)) { - children[item].clear(recursively); - } - } - - return true; - } - } - } - - return false; - - } - - probePath(path, recursively) { - - path = this.getPathComponents(path); - - if (path !== null) { - const last = path.length - 1; - let node = this.getNodeUpToIndex(path, last); - if (node !== null) { - let item = path[last]; - if (item !== WILDCARD) { - if (node.children.hasOwnProperty(item)) { - return node.children[item].probe(recursively); - } - } else { - const children = node.children; - let value = 0; - for (item in children) { - if (children.hasOwnProperty(item)) { - value += children[item].probe(recursively); - } - } - - return value; - } - } - } - - return 0; - - } - - attachHandler(type, handler) { - - let result = false; - - if (typeof type === STRING && typeof handler === FUNCTION) { - - const handlers = this.handlers; - const list = handlers.hasOwnProperty(type) ? handlers[type] : (handlers[type] = []); - const length = list.length; - - let notFound = true; - - for (let i = 0; i < length; ++i) { - if (handler === list[i]) { - notFound = false; - break; - } - } - - if (notFound) { - list[length] = handler; - result = true; - } - - } - - return result; - - } - - removeHandler(type, handler) { - - let result = false; - - if (typeof type === STRING && typeof handler === FUNCTION) { - - const handlers = this.handlers; - if (handlers.hasOwnProperty(type)) { - const list = handlers[type]; - const length = list.length; - for (let i = 0; i < length; ++i) { - if (handler === list[i]) { - list.splice(i, 1); - result = true; - break; - } - } - } - - } - - return result; - - } - - trigger(type, nonRecursively) { - - if (typeof type === STRING) { - - const handlers = this.handlers; - - if (handlers.hasOwnProperty(type)) { - const list = handlers[type]; - const length = list.length; - for (let i = 0; i < length; ++i) { - list[i].call(null); - } - } - - if (nonRecursively !== true) { - const children = this.children; - for (let item in children) { - if (children.hasOwnProperty(item)) { - children[item].trigger(type); - } - } - } - - } - - } - - attachHandlerForPath(path, type, handler) { - - path = this.getPathComponents(path); - - if (path !== null) { - let node = this.getNodeUpToIndex(path, path.length); - if (node !== null) { - return node.attachHandler(type, handler); - } - } - - return false; - - } - - removeHandlerForPath(path, type, handler) { - - path = this.getPathComponents(path); - - if (path !== null) { - let node = this.getNodeUpToIndex(path, path.length); - if (node !== null) { - return node.removeHandler(type, handler); - } - } - - return false; - - } - - triggerHandlersForPath(path, type, nonRecursively) { - - path = this.getPathComponents(path); - - if (path !== null) { - let node = this.getNodeUpToIndex(path, path.length); - if (node !== null) { - node.trigger(type, nonRecursively); - } - } - - } - -} - -/** - * Root Namespace Node and API - */ - -const rootNode = new Node(); - -export const unsavedChanges = { - - rootNode: rootNode, - - observer: new Tracker.Dependency(), - - hooks: new Map(), - - /** - * Register a reactive dependency on every change any path suffers - */ - depend: function() { - return this.observer.depend(); - }, - - /** - * Signal an unsaved change for a given namespace. - * @param {String} path A string (e.g., "viewer.studyViewer.measurements.targets") that identifies the namespace of the signaled changes. - * @return {Boolean} Returns false if the signal could not be saved or the supplied namespace is invalid. Otherwise, true is returned. - */ - set: function(path) { - const result = rootNode.appendPath(path, 1); - this.observer.changed(); - return result; - }, - - /** - * Clear all signaled unsaved changes for a given namespace. If the supplied namespace is a wildcard, all signals below that namespace - * are cleared. - * @param {String} path A string that identifies the namespace of the signaled changes (e.g., "viewer.studyViewer.measurements.targets" - * for clearing the "targets" item of the "viewer.studyViewer.measurements" namespace or "viewer.studyViewer.*" to specify all signaled - * changes for the "viewer.studyViewer" namespace). - * @param {Boolean} recursively Clear node and all its children recursively. If not specified defaults to true. - * @return {Boolean} Returns false if the signal could not be removed or the supplied namespace is invalid. Otherwise, true is returned. - */ - clear: function(path, recursively) { - const result = rootNode.clearPath(path, typeof recursively === UNDEFINED ? true : recursively); - this.observer.changed(); - return result; - }, - - /** - * Count the amount of signaled unsaved changes for a given namespace. If the supplied namespace is a wildcard, all signals below that - * namespace will also be accounted. - * @param {String} path A string that identifies the namespace of the signaled changes (e.g., "viewer.studyViewer.measurements.targets" - * for counting the amount of signals for the "targets" item of the "viewer.studyViewer.measurements" namespace or "viewer.studyViewer.*" - * to count all signaled changes for the "viewer.studyViewer" namespace). - * @param {Boolean} recursively Probe node and all its children recursively. If not specified defaults to true. - * @return {Number} Returns the amount of signaled changes for a given namespace. If the supplied namespace is a wildcard, the sum of all - * changes for that namespace are returned. - */ - probe: function(path, recursively) { - return rootNode.probePath(path, typeof recursively === UNDEFINED ? true : recursively); - }, - - /** - * Attach an event handler to the specified namespace. - * @param {String} name A string that identifies the namespace to which the event handler will be attached (e.g., - * "viewer.studyViewer.measurements" to attach an event handler for that namespace). - * @param {String} type A string that identifies the event type to which the event handler will be attached. - * @param {Function} handler The handler that will be executed when the specifed event is triggered. - * @return {Boolean} Returns true on success and false on failure. - */ - attachHandler: function(path, type, handler) { - return (rootNode.appendPath(path, 0) && rootNode.attachHandlerForPath(path, type, handler)); - }, - - /** - * Detach an event handler from the specified namespace. - * @param {String} name A string that identifies the namespace from which the event handler will be detached (e.g., - * "viewer.studyViewer.measurements" to remove an event handler from that namespace). - * @param {String} type A string that identifies the event type to which the event handler was attached. - * @param {Function} handler The handler that will be removed from execution list. - * @return {Boolean} Returns true on success and false on failure. - */ - removeHandler: function(path, type, handler) { - return rootNode.removeHandlerForPath(path, type, handler); - }, - - /** - * Trigger all event handlers for the specified namespace and type. - * @param {String} name A string that identifies the namespace from which the event handler will be detached (e.g., - * "viewer.studyViewer.measurements" to remove an event handler from that namespace). - * @param {String} type A string that identifies the event type which will be triggered. - * @param {Boolean} nonRecursively If set to true, prevents triggering event handlers from descending tree. - * @return {Void} No value is returned. - */ - trigger: function(path, type, nonRecursively) { - rootNode.triggerHandlersForPath(path, type, nonRecursively); - }, - - /** - * UI utility that presents a confirmation dialog to the user if any unsaved changes where signaled for the given namespace. - * @param {String} path A string that identifies the namespace of the signaled changes (e.g., "viewer.studyViewer.measurements.targets" - * for considering only the signals for the "targets" item of the "viewer.studyViewer.measurements" namespace or "viewer.studyViewer.*" - * to consider all signaled changes for the "viewer.studyViewer" namespace). - * @param {Function} callback A callback function (e.g, function(shouldProceed, hasChanges) { ... }) that will be executed after assessment. - * Upon execution, the callback will receive two boolean arguments (shouldProceed and hasChanges) indicating if the action can be performed - * or not and if changes that need to be cleared exist. - * @param {Object} options (Optional) An object with UI presentation options. - * @param {String} options.title The string that will be used as a title for confirmation dialog. - * @param {String} options.message The string that will be used as a message for confirmation dialog. - * @return {void} No value is returned. - */ - checkBeforeAction: function(path, callback, options) { - - let probe, hasChanges, shouldProceed; - - if (typeof callback !== 'function') { - // nothing to do if no callback function is supplied... - return; - } - - probe = this.probe(path); - if (probe > 0) { - // Unsaved changes exist... - hasChanges = true; - let dialogOptions = _.extend({ - title: 'You have unsaved changes!', - message: "Your changes will be lost if you don't save them before leaving the current page... Are you sure you want to proceed?" - }, options); - OHIF.ui.showDialog('dialogConfirm', dialogOptions).then(function() { - // Unsaved changes exist but user confirms action... - shouldProceed = true; - callback.call(null, shouldProceed, hasChanges); - }, function() { - // Unsaved changes exist and user does NOT confirm action... - shouldProceed = false; - callback.call(null, shouldProceed, hasChanges); - }); - } else { - // No unsaved changes, action can be performed... - hasChanges = false; - shouldProceed = true; - callback.call(null, shouldProceed, hasChanges); - } - - }, - - /** - * UI utility that presents a "proactive" dialog (with three options: stay, abandon-changes, save-changes) to the user if any unsaved changes where signaled for the given namespace. - * @param {String} path A string that identifies the namespace of the signaled changes (e.g., "viewer.studyViewer.measurements.targets" - * for considering only the signals for the "targets" item of the "viewer.studyViewer.measurements" namespace or "viewer.studyViewer.*" - * to consider all signaled changes for the "viewer.studyViewer" namespace). - * @param {Function} callback A callback function (e.g, function(hasChanges, userChoice) { ... }) that will be executed after assessment. - * Upon execution, the callback will receive two arguments: one boolean (hasChanges) indicating that unsaved changes exist and one string with the ID of the - * option picked by the user on the dialog ('abort-action', 'abandon-changes' and 'save-changes'). If no unsaved changes exist, the second argument is null. - * @param {Object} options (Optional) An object with UI presentation options. - * @param {Object} options.position An object with optimal position (e.g., { x: ..., y: ... }) for the dialog. - * @return {void} No value is returned. - */ - presentProactiveDialog: function(path, callback, options) { - - let probe, hasChanges; - - if (typeof callback !== 'function') { - // nothing to do if no callback function is supplied... - return; - } - - probe = this.probe(path, true); - if (probe > 0) { - // Unsaved changes exist... - hasChanges = true; - OHIF.ui.unsavedChangesDialog(function(choice) { - callback.call(null, hasChanges, choice); - }, options); - } else { - // No unsaved changes, action can be performed... - hasChanges = false; - callback.call(null, hasChanges, null); - } - - }, - - addHook(saveCallback, options={}) { - _.defaults(options, { - path: '*', - message: 'There are unsaved changes' - }); - - this.hooks.set(saveCallback, options); - }, - - removeHook(saveCallback) { - this.hooks.delete(saveCallback); - }, - - confirmNavigation(navigateCallback, event) { - let dialogPresented = false; - Array.from(this.hooks.keys()).every(saveCallback => { - const options = this.hooks.get(saveCallback); - const probe = this.probe(options.path, true); - if (!probe) return true; - - const dialogOptions = Object.assign({ class: 'themed' }, options); - if (event) { - dialogOptions.position = { - x: event.clientX + 15, - y: event.clientY + 15 - }; - } - - OHIF.ui.unsavedChanges.presentProactiveDialog(options.path, (hasChanges, userChoice) => { - if (!hasChanges) return; - - const clear = () => this.clear(options.path, true); - switch (userChoice) { - case 'abort-action': - return; - case 'save-changes': - const result = saveCallback(); - if (result instanceof Promise) { - return result.then(() => { - clear(); - this.confirmNavigation(navigateCallback, event); - }); - } - - clear(); - return this.confirmNavigation(navigateCallback, event); - case 'abandon-changes': - clear(); - break; - } - - navigateCallback(); - }, dialogOptions); - - dialogPresented = true; - return false; - }); - - if (!dialogPresented) { - navigateCallback(); - } - } - -}; - -OHIF.ui.unsavedChanges = unsavedChanges; diff --git a/Packages/ohif-core/client/utils/absoluteUrl.js b/Packages/ohif-core/client/utils/absoluteUrl.js deleted file mode 100644 index e2239f7ea..000000000 --- a/Packages/ohif-core/client/utils/absoluteUrl.js +++ /dev/null @@ -1,19 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -// Return an absolute URL with the page domain using sub path of ROOT_URL -// to let multiple domains directed to the same server work -OHIF.utils.absoluteUrl = function(path) { - let absolutePath = '/'; - - const absoluteUrl = Meteor.absoluteUrl(); - const absoluteUrlParts = absoluteUrl.split('/'); - - if (absoluteUrlParts.length > 4) { - const rootUrlPrefixIndex = absoluteUrl.indexOf(absoluteUrlParts[3]); - absolutePath += absoluteUrl.substring(rootUrlPrefixIndex) + path; - } else { - absolutePath += path; - } - - return absolutePath.replace(/\/\/+/g, '/'); -}; diff --git a/Packages/ohif-core/client/utils/guid.js b/Packages/ohif-core/client/utils/guid.js deleted file mode 100644 index fcbc97008..000000000 --- a/Packages/ohif-core/client/utils/guid.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Create a random GUID - * - * @return {string} - */ -export default function guid() { - function s4() { - return Math.floor((1 + Math.random()) * 0x10000) - .toString(16) - .substring(1); - } - return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); -} diff --git a/Packages/ohif-core/client/utils/index.js b/Packages/ohif-core/client/utils/index.js deleted file mode 100644 index cdce7aa48..000000000 --- a/Packages/ohif-core/client/utils/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -import './absoluteUrl'; -import './objectPath'; -import guid from './guid'; - -OHIF.utils = OHIF.utils || {} -OHIF.utils.guid = guid; diff --git a/Packages/ohif-core/client/utils/objectPath.js b/Packages/ohif-core/client/utils/objectPath.js deleted file mode 100644 index bde1b3994..000000000 --- a/Packages/ohif-core/client/utils/objectPath.js +++ /dev/null @@ -1,116 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -class ObjectPath { - - /** - * Set an object property based on "path" (namespace) supplied creating - * ... intermediary objects if they do not exist. - * @param object {Object} An object where the properties specified on path should be set. - * @param path {String} A string representing the property to be set, e.g. "user.study.series.timepoint". - * @param value {Any} The value of the property that will be set. - * @return {Boolean} Returns "true" on success, "false" if any intermediate component of the supplied path - * ... is not a valid Object, in which case the property cannot be set. No excpetions are thrown. - */ - static set(object, path, value) { - - let components = ObjectPath.getPathComponents(path), - length = components !== null ? components.length : 0, - result = false; - - if (length > 0 && ObjectPath.isValidObject(object)) { - - let i = 0, - last = length - 1, - currentObject = object; - - while (i < last) { - - let field = components[i]; - - if (field in currentObject) { - if (!ObjectPath.isValidObject(currentObject[field])) { - break; - } - } else { - currentObject[field] = {}; - } - - currentObject = currentObject[field]; - i++; - - } - - if (i === last) { - currentObject[components[last]] = value; - result = true; - } - - } - - return result; - - } - - /** - * Get an object property based on "path" (namespace) supplied traversing the object - * ... tree as necessary. - * @param object {Object} An object where the properties specified might exist. - * @param path {String} A string representing the property to be searched for, e.g. "user.study.series.timepoint". - * @return {Any} The value of the property if found. By default, returns the special type "undefined". - */ - static get(object, path) { - - let found, // undefined by default - components = ObjectPath.getPathComponents(path), - length = components !== null ? components.length : 0; - - if (length > 0 && ObjectPath.isValidObject(object)) { - - let i = 0, - last = length - 1, - currentObject = object; - - while (i < last) { - - let field = components[i]; - - const isValid = ObjectPath.isValidObject(currentObject[field]); - if (field in currentObject && isValid) { - currentObject = currentObject[field]; - i++; - } else { - break; - } - - } - - if (i === last && components[last] in currentObject) { - found = currentObject[components[last]]; - } - - } - - return found; - - } - - /** - * Check if the supplied argument is a real JavaScript Object instance. - * @param object {Any} The subject to be tested. - * @return {Boolean} Returns "true" if the object is a real Object instance and "false" otherwise. - */ - static isValidObject(object) { - return ( - typeof object === 'object' && - object !== null && - object instanceof Object - ); - } - - static getPathComponents(path) { - return (typeof path === 'string' ? path.split('.') : null); - } - -} - -OHIF.utils.ObjectPath = ObjectPath; diff --git a/Packages/ohif-core/main.js b/Packages/ohif-core/main.js deleted file mode 100644 index 86b1609f4..000000000 --- a/Packages/ohif-core/main.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import log from './log.js'; - -/* - * Defines the base OHIF object - */ - -const OHIF = { - log, - ui: {}, - utils: {}, - viewer: {}, - cornerstone: {}, - user: {}, - DICOMWeb: {}, // Temporarily added -}; - -export { OHIF }; diff --git a/Packages/ohif-core/package.js b/Packages/ohif-core/package.js deleted file mode 100644 index c2a52b970..000000000 --- a/Packages/ohif-core/package.js +++ /dev/null @@ -1,51 +0,0 @@ -Npm.depends({ - 'isomorphic-base64': '1.0.2', - 'jquery.hotkeys': '0.1.0', - loglevel: '1.4.1', - jquery: '3.3.1', - underscore: "1.9.1", - 'dicomweb-client': '0.3.2', - 'xhr2': '0.1.4' -}); - -Package.describe({ - name: 'ohif:core', - summary: 'OHIF core components, helpers and UI functions', - version: '0.0.1' -}); - -Package.onUse(function(api) { - api.versionsFrom('1.7'); - - api.use('ecmascript'); - api.use('stylus'); - api.use('templating'); - api.use('reactive-var'); - api.use('session'); - - api.use('ohif:cornerstone'); - - // Component's library dependencies - api.use('natestrauser:select2@4.0.1', 'client'); - api.use('aldeed:simple-schema'); - - // UI Styles - api.addFiles([ - 'client/ui/dimensional/dimensional.styl', - 'client/ui/resizable/resizable.styl', - 'client/components/bootstrap/dialog/bootstrap.styl', - 'client/components/bootstrap/dialog/loading.styl', - 'client/components/bootstrap/dialog/progress.styl', - 'client/components/bootstrap/dialog/unsavedChangesDialog.styl', - 'client/components/bootstrap/dropdown/dropdown.styl' - ], 'client'); - - api.mainModule('main.js', ['client', 'server']); - - // Assets to be imported dynamically - api.addAssets('public/js/svgxuse.min.js', 'client'); - - - // Client imports and routes - api.addFiles('client/index.js', 'client'); -}); diff --git a/Packages/ohif-core/public/js/svgxuse.min.js b/Packages/ohif-core/public/js/svgxuse.min.js deleted file mode 100644 index ce2099f32..000000000 --- a/Packages/ohif-core/public/js/svgxuse.min.js +++ /dev/null @@ -1,12 +0,0 @@ -/*! - * @copyright Copyright (c) 2017 IcoMoon.io - * @license Licensed under MIT license - * See https://github.com/Keyamoon/svgxuse - * @version 1.2.6 - */ -(function(){if("undefined"!==typeof window&&window.addEventListener){var e=Object.create(null),l,d=function(){clearTimeout(l);l=setTimeout(n,100)},m=function(){},t=function(){window.addEventListener("resize",d,!1);window.addEventListener("orientationchange",d,!1);if(window.MutationObserver){var k=new MutationObserver(d);k.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0});m=function(){try{k.disconnect(),window.removeEventListener("resize",d,!1),window.removeEventListener("orientationchange", -d,!1)}catch(v){}}}else document.documentElement.addEventListener("DOMSubtreeModified",d,!1),m=function(){document.documentElement.removeEventListener("DOMSubtreeModified",d,!1);window.removeEventListener("resize",d,!1);window.removeEventListener("orientationchange",d,!1)}},u=function(k){function e(a){if(void 0!==a.protocol)var c=a;else c=document.createElement("a"),c.href=a;return c.protocol.replace(/:/g,"")+c.host}if(window.XMLHttpRequest){var d=new XMLHttpRequest;var m=e(location);k=e(k);d=void 0=== -d.withCredentials&&""!==k&&k!==m?XDomainRequest||void 0:XMLHttpRequest}return d};var n=function(){function d(){--q;0===q&&(m(),t())}function l(a){return function(){!0!==e[a.base]&&(a.useEl.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href","#"+a.hash),a.useEl.hasAttribute("href")&&a.useEl.setAttribute("href","#"+a.hash))}}function p(a){return function(){var c=document.body,b=document.createElement("x");a.onload=null;b.innerHTML=a.responseText;if(b=b.getElementsByTagName("svg")[0])b.setAttribute("aria-hidden", -"true"),b.style.position="absolute",b.style.width=0,b.style.height=0,b.style.overflow="hidden",c.insertBefore(b,c.firstChild);d()}}function n(a){return function(){a.onerror=null;a.ontimeout=null;d()}}var a,c,q=0;m();var f=document.getElementsByTagName("use");for(c=0;c { diff --git a/Packages/ohif-measurement-table/package.js b/Packages/ohif-measurement-table/package.js index d05b3192a..38baf9075 100644 --- a/Packages/ohif-measurement-table/package.js +++ b/Packages/ohif-measurement-table/package.js @@ -6,7 +6,8 @@ Package.describe({ Npm.depends({ 'dicomweb-client': '0.3.2', - 'xhr2': '0.1.4' + 'xhr2': '0.1.4', + 'simpl-schema': '1.5.3' }); Package.onUse(function(api) { diff --git a/Packages/ohif-measurements/package.js b/Packages/ohif-measurements/package.js index 181d60015..ea2bac066 100644 --- a/Packages/ohif-measurements/package.js +++ b/Packages/ohif-measurements/package.js @@ -17,7 +17,6 @@ Package.onUse(function(api) { api.use('ecmascript'); api.use('stylus'); - api.use('random'); // Schema for Data Models api.use('aldeed:simple-schema'); diff --git a/Packages/ohif-measurements/src/base.js b/Packages/ohif-measurements/src/base.js index 41b388766..cfe9ff8e6 100644 --- a/Packages/ohif-measurements/src/base.js +++ b/Packages/ohif-measurements/src/base.js @@ -1,3 +1,3 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.measurements = {}; diff --git a/Packages/ohif-measurements/src/configuration/measurements.js b/Packages/ohif-measurements/src/configuration/measurements.js index f799c311c..488bcdf58 100644 --- a/Packages/ohif-measurements/src/configuration/measurements.js +++ b/Packages/ohif-measurements/src/configuration/measurements.js @@ -1,7 +1,7 @@ import { Mongo } from 'meteor/mongo'; import { Tracker } from 'meteor/tracker'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstoneTools } from 'meteor/ohif:cornerstone'; let configuration = {}; @@ -36,13 +36,13 @@ class MeasurementApi { configuration.measurementTools.forEach(toolGroup => { const groupCollection = new Mongo.Collection(null); groupCollection._debugName = toolGroup.name; - groupCollection.attachSchema(toolGroup.schema); + //groupCollection.attachSchema(toolGroup.schema); this.toolGroups[toolGroup.id] = groupCollection; toolGroup.childTools.forEach(tool => { const collection = new Mongo.Collection(null); collection._debugName = tool.name; - collection.attachSchema(tool.schema); + //collection.attachSchema(tool.schema); this.tools[tool.id] = collection; const addedHandler = measurement => { diff --git a/Packages/ohif-measurements/src/configuration/timepoints.js b/Packages/ohif-measurements/src/configuration/timepoints.js index f7ef0349b..129d8716f 100644 --- a/Packages/ohif-measurements/src/configuration/timepoints.js +++ b/Packages/ohif-measurements/src/configuration/timepoints.js @@ -1,7 +1,7 @@ import { Mongo } from 'meteor/mongo'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { schema as TimepointSchema } from '../schema/timepoints'; @@ -23,7 +23,7 @@ class TimepointApi { this.options = options; this.timepoints = new Mongo.Collection(null); - this.timepoints.attachSchema(TimepointSchema); + //this.timepoints.attachSchema(TimepointSchema); this.timepoints._debugName = 'Timepoints'; } diff --git a/Packages/ohif-measurements/src/conformance/ConformanceCriteria.js b/Packages/ohif-measurements/src/conformance/ConformanceCriteria.js index 537a13a95..550f6a89b 100644 --- a/Packages/ohif-measurements/src/conformance/ConformanceCriteria.js +++ b/Packages/ohif-measurements/src/conformance/ConformanceCriteria.js @@ -1,7 +1,7 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import 'meteor/ohif:viewerbase'; import { CriteriaEvaluator } from './CriteriaEvaluator'; import * as evaluations from './evaluations'; diff --git a/Packages/ohif-measurements/src/helpers/measurements.js b/Packages/ohif-measurements/src/helpers/measurements.js index 1e1f1724b..b482724ba 100644 --- a/Packages/ohif-measurements/src/helpers/measurements.js +++ b/Packages/ohif-measurements/src/helpers/measurements.js @@ -1,6 +1,6 @@ import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; // Get the current measurement API configuration with information about tools, data exchange // and data validation. diff --git a/Packages/ohif-measurements/src/lib/MeasurementHandlers/MeasurementHandlers.js b/Packages/ohif-measurements/src/lib/MeasurementHandlers/MeasurementHandlers.js index 4b59dea43..99360bc09 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementHandlers/MeasurementHandlers.js +++ b/Packages/ohif-measurements/src/lib/MeasurementHandlers/MeasurementHandlers.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import handleSingleMeasurementAdded from './handleSingleMeasurementAdded'; import handleChildMeasurementAdded from './handleChildMeasurementAdded'; import handleSingleMeasurementModified from './handleSingleMeasurementModified'; diff --git a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementAdded.js b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementAdded.js index 1a3d69996..c6fb1fa8b 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementAdded.js +++ b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementAdded.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; import getImageAttributes from './getImageAttributes'; diff --git a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementModified.js b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementModified.js index 9770a5f99..d1e8ada72 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementModified.js +++ b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementModified.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) { diff --git a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementRemoved.js b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementRemoved.js index e8ccdea92..ee03a984a 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementRemoved.js +++ b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleChildMeasurementRemoved.js @@ -1,6 +1,6 @@ import _ from 'underscore'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) { diff --git a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementAdded.js b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementAdded.js index 303399dd2..604740ef7 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementAdded.js +++ b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementAdded.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; import getImageAttributes from './getImageAttributes'; diff --git a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementModified.js b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementModified.js index 78d47e057..266e8fe48 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementModified.js +++ b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementModified.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) { diff --git a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js index 56819ccd8..8a59f83c7 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js +++ b/Packages/ohif-measurements/src/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js @@ -1,6 +1,6 @@ import _ from 'underscore'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; export default function({ instance, eventData, tool, toolGroupId, toolGroup }) { diff --git a/Packages/ohif-measurements/src/lib/MeasurementManager.js b/Packages/ohif-measurements/src/lib/MeasurementManager.js index 738b95b92..c0deb283a 100644 --- a/Packages/ohif-measurements/src/lib/MeasurementManager.js +++ b/Packages/ohif-measurements/src/lib/MeasurementManager.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; class MeasurementManager { diff --git a/Packages/ohif-measurements/src/lib/activateMeasurements.js b/Packages/ohif-measurements/src/lib/activateMeasurements.js index 96d00c156..86a7ce0a6 100644 --- a/Packages/ohif-measurements/src/lib/activateMeasurements.js +++ b/Packages/ohif-measurements/src/lib/activateMeasurements.js @@ -1,6 +1,6 @@ import $ from 'jquery'; import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; const scrollToIndex = cornerstoneTools.import('util/scrollToIndex'); diff --git a/Packages/ohif-measurements/src/lib/clearCornerstoneToolState.js b/Packages/ohif-measurements/src/lib/clearCornerstoneToolState.js index 3ba308818..cc9cb0f5a 100644 --- a/Packages/ohif-measurements/src/lib/clearCornerstoneToolState.js +++ b/Packages/ohif-measurements/src/lib/clearCornerstoneToolState.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstoneTools } from 'meteor/ohif:cornerstone'; OHIF.measurements.clearCornerstoneToolState = () => { diff --git a/Packages/ohif-measurements/src/lib/deactivateAllToolData.js b/Packages/ohif-measurements/src/lib/deactivateAllToolData.js index 9a85e5275..e485feb6b 100644 --- a/Packages/ohif-measurements/src/lib/deactivateAllToolData.js +++ b/Packages/ohif-measurements/src/lib/deactivateAllToolData.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core' +import { OHIF } from 'ohif-core' /** * Sets all tool data entries value for 'active' to false diff --git a/Packages/ohif-measurements/src/lib/exportPdf.js b/Packages/ohif-measurements/src/lib/exportPdf.js index bcb7a4084..2377e0162 100644 --- a/Packages/ohif-measurements/src/lib/exportPdf.js +++ b/Packages/ohif-measurements/src/lib/exportPdf.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { MeasurementReport } from '../reports/measurement'; OHIF.measurements.exportPdf = (measurementApi, timepointApi) => { diff --git a/Packages/ohif-measurements/src/lib/exportToCsv.js b/Packages/ohif-measurements/src/lib/exportToCsv.js index 0a6c5799c..898bba3da 100644 --- a/Packages/ohif-measurements/src/lib/exportToCsv.js +++ b/Packages/ohif-measurements/src/lib/exportToCsv.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { getCSVMeasurementData } from '../reports/reportMeasurementDataToCSV'; const downloadCSV = (csvData, args = {}) => { diff --git a/Packages/ohif-measurements/src/lib/findAndRenderDisplaySet.js b/Packages/ohif-measurements/src/lib/findAndRenderDisplaySet.js index 8ec80a6c3..4e4848d57 100644 --- a/Packages/ohif-measurements/src/lib/findAndRenderDisplaySet.js +++ b/Packages/ohif-measurements/src/lib/findAndRenderDisplaySet.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.measurements.findAndRenderDisplaySet = (displaySets, viewportIndex, studyInstanceUid, seriesInstanceUid, sopInstanceUid, renderedCallback) => { // Find the proper stack to display @@ -23,5 +23,5 @@ OHIF.measurements.findAndRenderDisplaySet = (displaySets, viewportIndex, studyIn displaySetData.renderedCallback = renderedCallback; } - OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, displaySetData); + OHIF.viewer.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, displaySetData); }; diff --git a/Packages/ohif-measurements/src/lib/getActiveTimepoint.js b/Packages/ohif-measurements/src/lib/getActiveTimepoint.js index ca7cf5fba..a3954d8fe 100644 --- a/Packages/ohif-measurements/src/lib/getActiveTimepoint.js +++ b/Packages/ohif-measurements/src/lib/getActiveTimepoint.js @@ -1,5 +1,4 @@ -import { Session } from 'meteor/session'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Extensible method to get the timepoint of the active viewport @@ -8,6 +7,6 @@ import { OHIF } from 'meteor/ohif:core'; */ OHIF.measurements.getActiveTimepoint = () => { const activeViewportIndex = window.store.getState().viewports.activeViewport; - const { studyInstanceUid } = OHIF.viewerbase.layoutManager.viewportData[activeViewportIndex]; + const { studyInstanceUid } = OHIF.viewer.layoutManager.viewportData[activeViewportIndex]; return OHIF.viewer.timepointApi.study(studyInstanceUid)[0]; }; diff --git a/Packages/ohif-measurements/src/lib/getImageDataUrl.js b/Packages/ohif-measurements/src/lib/getImageDataUrl.js index f9f847775..cc484678b 100644 --- a/Packages/ohif-measurements/src/lib/getImageDataUrl.js +++ b/Packages/ohif-measurements/src/lib/getImageDataUrl.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import $ from 'jquery'; import { cornerstone, cornerstoneMath, cornerstoneTools } from 'meteor/ohif:cornerstone'; diff --git a/Packages/ohif-measurements/src/lib/getLocationLabel.js b/Packages/ohif-measurements/src/lib/getLocationLabel.js index 65b175cd9..4f5af512c 100644 --- a/Packages/ohif-measurements/src/lib/getLocationLabel.js +++ b/Packages/ohif-measurements/src/lib/getLocationLabel.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Extensible method to translate the location and return a string containing its label diff --git a/Packages/ohif-measurements/src/lib/getMeasurementsGroupedByNumber.js b/Packages/ohif-measurements/src/lib/getMeasurementsGroupedByNumber.js index fd0db83c1..35d8fbc81 100644 --- a/Packages/ohif-measurements/src/lib/getMeasurementsGroupedByNumber.js +++ b/Packages/ohif-measurements/src/lib/getMeasurementsGroupedByNumber.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import _ from 'underscore'; // TODO: change this to a const after refactoring newMeasurements code on measurementTableView.js diff --git a/Packages/ohif-measurements/src/lib/getParentToolData.js b/Packages/ohif-measurements/src/lib/getParentToolData.js index 5059d37cb..9154258ff 100644 --- a/Packages/ohif-measurements/src/lib/getParentToolData.js +++ b/Packages/ohif-measurements/src/lib/getParentToolData.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Return the parent tool data if it's a child tool or the tool data itself if not diff --git a/Packages/ohif-measurements/src/lib/getTimepointName.js b/Packages/ohif-measurements/src/lib/getTimepointName.js index 9a61651d9..bd675a922 100644 --- a/Packages/ohif-measurements/src/lib/getTimepointName.js +++ b/Packages/ohif-measurements/src/lib/getTimepointName.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Calculates a Timepoint's name based on how many timepoints exist between it diff --git a/Packages/ohif-measurements/src/lib/getToolConfiguration.js b/Packages/ohif-measurements/src/lib/getToolConfiguration.js index a069c0d9b..91c5dac8e 100644 --- a/Packages/ohif-measurements/src/lib/getToolConfiguration.js +++ b/Packages/ohif-measurements/src/lib/getToolConfiguration.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Return the tool configuration of a given tool type diff --git a/Packages/ohif-measurements/src/lib/hangingProtocolCustomizations.js b/Packages/ohif-measurements/src/lib/hangingProtocolCustomizations.js index 7216a0511..7587a41cc 100644 --- a/Packages/ohif-measurements/src/lib/hangingProtocolCustomizations.js +++ b/Packages/ohif-measurements/src/lib/hangingProtocolCustomizations.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { Viewerbase } from 'meteor/ohif:viewerbase'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; const { InstanceMetadata, StudySummary } = Viewerbase.metadata; diff --git a/Packages/ohif-measurements/src/lib/isNewLesionsMeasurement.js b/Packages/ohif-measurements/src/lib/isNewLesionsMeasurement.js index cf8f3a1e7..3e62dc1e8 100644 --- a/Packages/ohif-measurements/src/lib/isNewLesionsMeasurement.js +++ b/Packages/ohif-measurements/src/lib/isNewLesionsMeasurement.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import _ from 'underscore'; /** diff --git a/Packages/ohif-measurements/src/lib/isSaveDisabled.js b/Packages/ohif-measurements/src/lib/isSaveDisabled.js index 687425074..8e4e3730c 100644 --- a/Packages/ohif-measurements/src/lib/isSaveDisabled.js +++ b/Packages/ohif-measurements/src/lib/isSaveDisabled.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.measurements.isSaveDisabled = timepointId => { const basePath = `viewer.studyViewer.measurements.${timepointId}`; diff --git a/Packages/ohif-measurements/src/lib/jumpToRowItem.js b/Packages/ohif-measurements/src/lib/jumpToRowItem.js index 306c8d810..b4680a0d8 100644 --- a/Packages/ohif-measurements/src/lib/jumpToRowItem.js +++ b/Packages/ohif-measurements/src/lib/jumpToRowItem.js @@ -1,6 +1,6 @@ import $ from 'jquery'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; // Flag that can be changed to disable automatic stack scroll linking when jumping over lesions @@ -85,7 +85,7 @@ let lastActivatedRowItem; * @param measurementId The unique key for a specific Measurement */ OHIF.measurements.jumpToRowItem = (rowItem, timepoints, childToolKey) => { - const { isZoomed, zoomedViewportIndex } = OHIF.viewerbase.layoutManager; + const { isZoomed, zoomedViewportIndex } = OHIF.viewer.layoutManager; lastActivatedRowItem = rowItem; diff --git a/Packages/ohif-measurements/src/lib/navigateOverLesions.js b/Packages/ohif-measurements/src/lib/navigateOverLesions.js index f41863ec5..15b3f7967 100644 --- a/Packages/ohif-measurements/src/lib/navigateOverLesions.js +++ b/Packages/ohif-measurements/src/lib/navigateOverLesions.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Method to go select the next or previous lesion on measurements table diff --git a/Packages/ohif-measurements/src/lib/openLocationModal.js b/Packages/ohif-measurements/src/lib/openLocationModal.js index 062f0eaa0..dd804e563 100644 --- a/Packages/ohif-measurements/src/lib/openLocationModal.js +++ b/Packages/ohif-measurements/src/lib/openLocationModal.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { Blaze } from 'meteor/blaze'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.measurements.openLocationModal = options => { let { toolType } = options.measurement; diff --git a/Packages/ohif-measurements/src/lib/saveMeasurements.js b/Packages/ohif-measurements/src/lib/saveMeasurements.js index 996da8a60..0840b03e4 100644 --- a/Packages/ohif-measurements/src/lib/saveMeasurements.js +++ b/Packages/ohif-measurements/src/lib/saveMeasurements.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.measurements.saveMeasurements = (measurementApi, timepointId) => { const { unsavedChanges, notifications, showDialog } = OHIF.ui; diff --git a/Packages/ohif-measurements/src/lib/syncMeasurementAndToolData.js b/Packages/ohif-measurements/src/lib/syncMeasurementAndToolData.js index c61e18dbd..ec7ee119c 100644 --- a/Packages/ohif-measurements/src/lib/syncMeasurementAndToolData.js +++ b/Packages/ohif-measurements/src/lib/syncMeasurementAndToolData.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstoneTools } from 'meteor/ohif:cornerstone'; OHIF.measurements.syncMeasurementAndToolData = measurement => { diff --git a/Packages/ohif-measurements/src/lib/toggleLabelButton.js b/Packages/ohif-measurements/src/lib/toggleLabelButton.js index 58a880c0d..1c0ba164f 100644 --- a/Packages/ohif-measurements/src/lib/toggleLabelButton.js +++ b/Packages/ohif-measurements/src/lib/toggleLabelButton.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { Blaze } from 'meteor/blaze'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.measurements.toggleLabelButton = options => { let { toolType } = options.measurement; diff --git a/Packages/ohif-measurements/src/lib/triggerTimepointUnsavedChanges.js b/Packages/ohif-measurements/src/lib/triggerTimepointUnsavedChanges.js index c14375431..7fbfe33ca 100644 --- a/Packages/ohif-measurements/src/lib/triggerTimepointUnsavedChanges.js +++ b/Packages/ohif-measurements/src/lib/triggerTimepointUnsavedChanges.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Extensible method to trigger unsaved changes on the active timepoint diff --git a/Packages/ohif-measurements/src/lib/updateMeasurementsDescription.js b/Packages/ohif-measurements/src/lib/updateMeasurementsDescription.js index cf14ff837..65fcd92d2 100644 --- a/Packages/ohif-measurements/src/lib/updateMeasurementsDescription.js +++ b/Packages/ohif-measurements/src/lib/updateMeasurementsDescription.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Updates the measurements' description for a measurement number across all timepoints diff --git a/Packages/ohif-measurements/src/reports/reportMeasurementData.js b/Packages/ohif-measurements/src/reports/reportMeasurementData.js index 05e7f80ae..e0cc5da9f 100644 --- a/Packages/ohif-measurements/src/reports/reportMeasurementData.js +++ b/Packages/ohif-measurements/src/reports/reportMeasurementData.js @@ -1,5 +1,5 @@ import moment from 'moment'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; export const getExportMeasurementData = async (measurementApi, timepointApi) => { const currentTimepoint = timepointApi.current(); diff --git a/Packages/ohif-measurements/src/schema/measurements.js b/Packages/ohif-measurements/src/schema/measurements.js index 001b539d1..cf667e20d 100644 --- a/Packages/ohif-measurements/src/schema/measurements.js +++ b/Packages/ohif-measurements/src/schema/measurements.js @@ -1,4 +1,5 @@ -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +//import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +import SimpleSchema from 'simpl-schema' const Measurement = new SimpleSchema({ additionalData: { diff --git a/Packages/ohif-measurements/src/schema/timepoints.js b/Packages/ohif-measurements/src/schema/timepoints.js index c1828b64c..741a44915 100644 --- a/Packages/ohif-measurements/src/schema/timepoints.js +++ b/Packages/ohif-measurements/src/schema/timepoints.js @@ -1,4 +1,5 @@ -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +//import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +import SimpleSchema from 'simpl-schema' export const schema = new SimpleSchema({ patientId: { diff --git a/Packages/ohif-study-list/client/base.js b/Packages/ohif-study-list/client/base.js index 752c2ec9a..7e42cf6f3 100644 --- a/Packages/ohif-study-list/client/base.js +++ b/Packages/ohif-study-list/client/base.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.studylist = { actions: {}, diff --git a/Packages/ohif-study-list/client/collections/studies.js b/Packages/ohif-study-list/client/collections/studies.js index 98e893ed0..3835dc142 100644 --- a/Packages/ohif-study-list/client/collections/studies.js +++ b/Packages/ohif-study-list/client/collections/studies.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; // Define the Studies Collection. This is a client-side only Collection which stores the list of // studies in the StudyList diff --git a/Packages/ohif-study-list/client/components/StudyList.js b/Packages/ohif-study-list/client/components/StudyList.js index 696a03669..8f18baa32 100644 --- a/Packages/ohif-study-list/client/components/StudyList.js +++ b/Packages/ohif-study-list/client/components/StudyList.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Blaze from 'meteor/gadicc:blaze-react-component'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import './StudyList.css'; class StudyList extends Component { diff --git a/Packages/ohif-study-list/client/components/seriesDetailsModal/seriesDetailsTable/seriesDetailsTable.js b/Packages/ohif-study-list/client/components/seriesDetailsModal/seriesDetailsTable/seriesDetailsTable.js index 0ee0b81a6..d58234da4 100644 --- a/Packages/ohif-study-list/client/components/seriesDetailsModal/seriesDetailsTable/seriesDetailsTable.js +++ b/Packages/ohif-study-list/client/components/seriesDetailsModal/seriesDetailsTable/seriesDetailsTable.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { ReactiveDict } from 'meteor/reactive-dict'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.seriesDetailsTable.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-study-list/client/components/studylist/studylist.js b/Packages/ohif-study-list/client/components/studylist/studylist.js index 91c8579ae..b5b66d400 100644 --- a/Packages/ohif-study-list/client/components/studylist/studylist.js +++ b/Packages/ohif-study-list/client/components/studylist/studylist.js @@ -1,5 +1,5 @@ import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.studylist.onCreated(() => { // Set the current context diff --git a/Packages/ohif-study-list/client/components/studylist/studylistResult/studylistResult.js b/Packages/ohif-study-list/client/components/studylist/studylistResult/studylistResult.js index 8e4b840a3..d4402460b 100644 --- a/Packages/ohif-study-list/client/components/studylist/studylistResult/studylistResult.js +++ b/Packages/ohif-study-list/client/components/studylist/studylistResult/studylistResult.js @@ -4,7 +4,7 @@ import { Session } from 'meteor/session'; import { ReactiveVar } from 'meteor/reactive-var'; import { ReactiveDict } from 'meteor/reactive-dict'; import moment from 'moment'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Session.setDefault('showLoadingText', true); Session.setDefault('serverError', false); diff --git a/Packages/ohif-study-list/client/components/studylist/studylistStudy/studylistStudy.js b/Packages/ohif-study-list/client/components/studylist/studylistStudy/studylistStudy.js index 6a4a9756a..f8b8773ff 100644 --- a/Packages/ohif-study-list/client/components/studylist/studylistStudy/studylistStudy.js +++ b/Packages/ohif-study-list/client/components/studylist/studylistStudy/studylistStudy.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { Blaze } from 'meteor/blaze'; import Hammer from 'hammerjs'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; // Clear all selected studies function doClearStudySelections() { diff --git a/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js b/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js index bae47dcb4..834f6d1f4 100644 --- a/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js +++ b/Packages/ohif-study-list/client/components/studylist/studylistToolbar/studylistToolbar.js @@ -1,17 +1,16 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { Template } from 'meteor/templating'; -import { Meteor } from 'meteor/meteor'; import { Session } from 'meteor/session'; import $ from 'jquery'; Template.studylistToolbar.onCreated(() => { - Meteor.call('importSupported', (error, result) => { + /*Meteor.call('importSupported', (error, result) => { if (error || !result) { Session.set('importSupported', false); } else { Session.set('importSupported', true); } - }); + });*/ }); Template.studylistToolbar.events({ diff --git a/Packages/ohif-study-list/client/dropdown.js b/Packages/ohif-study-list/client/dropdown.js index 972c620be..9fc701d5a 100644 --- a/Packages/ohif-study-list/client/dropdown.js +++ b/Packages/ohif-study-list/client/dropdown.js @@ -1,5 +1,5 @@ import { Meteor } from 'meteor/meteor'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Meteor.startup(() => { OHIF.studylist.dropdown = new OHIF.ui.Dropdown(); diff --git a/Packages/ohif-study-list/client/lib/exportSelectedStudies.js b/Packages/ohif-study-list/client/lib/exportSelectedStudies.js index 732539c34..bf9978aac 100644 --- a/Packages/ohif-study-list/client/lib/exportSelectedStudies.js +++ b/Packages/ohif-study-list/client/lib/exportSelectedStudies.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Exports all selected studies on the studylist diff --git a/Packages/ohif-study-list/client/lib/exportStudies.js b/Packages/ohif-study-list/client/lib/exportStudies.js index ff5eee2a7..0faac6321 100644 --- a/Packages/ohif-study-list/client/lib/exportStudies.js +++ b/Packages/ohif-study-list/client/lib/exportStudies.js @@ -1,5 +1,5 @@ import { JSZip } from 'meteor/silentcicero:jszip'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; const getNumberOfFilesToExport = function(studiesToExport) { let numberOfFilesToExport = 0; diff --git a/Packages/ohif-study-list/client/lib/getSelectedStudies.js b/Packages/ohif-study-list/client/lib/getSelectedStudies.js index 65f00d483..84190daf9 100644 --- a/Packages/ohif-study-list/client/lib/getSelectedStudies.js +++ b/Packages/ohif-study-list/client/lib/getSelectedStudies.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; OHIF.studylist.getSelectedStudies = () => { return OHIF.studylist.collections.Studies.find({ selected: true }, { diff --git a/Packages/ohif-study-list/client/lib/getStudyPriors.js b/Packages/ohif-study-list/client/lib/getStudyPriors.js index 3dea6bd07..2158f2c39 100644 --- a/Packages/ohif-study-list/client/lib/getStudyPriors.js +++ b/Packages/ohif-study-list/client/lib/getStudyPriors.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; const { StudyMetadata, StudySummary } = OHIF.metadata; const PATIENT_ID = 'x00100020'; diff --git a/Packages/ohif-study-list/client/lib/getStudyPriorsMap.js b/Packages/ohif-study-list/client/lib/getStudyPriorsMap.js index 184b023e7..c867caf9f 100644 --- a/Packages/ohif-study-list/client/lib/getStudyPriorsMap.js +++ b/Packages/ohif-study-list/client/lib/getStudyPriorsMap.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import 'meteor/ohif:viewerbase'; // Local Dependencies import { getStudyPriors } from './getStudyPriors'; diff --git a/Packages/ohif-study-list/client/lib/queryStudies.js b/Packages/ohif-study-list/client/lib/queryStudies.js index efec40158..7a224288b 100644 --- a/Packages/ohif-study-list/client/lib/queryStudies.js +++ b/Packages/ohif-study-list/client/lib/queryStudies.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Queries requested studies to get their metadata from PACS diff --git a/Packages/ohif-study-list/client/lib/studylist.js b/Packages/ohif-study-list/client/lib/studylist.js index 4728b1756..375c783c9 100644 --- a/Packages/ohif-study-list/client/lib/studylist.js +++ b/Packages/ohif-study-list/client/lib/studylist.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; // Functions /*import { getStudyPriors } from './getStudyPriors'; @@ -10,7 +10,8 @@ OHIF.studylist.functions = { };*/ const dblClickOnStudy = data => { - //Router.go('viewerStudies', { studyInstanceUids: data.studyInstanceUid }); + // TODO: Switch to more appropriate routing + window.router.history.push(`/viewer/${data.studyInstanceUid}`); console.log('dblClickOnStudy'); }; diff --git a/Packages/ohif-study-list/client/lib/viewSeriesDetails.js b/Packages/ohif-study-list/client/lib/viewSeriesDetails.js index df2a359cf..b398b4051 100644 --- a/Packages/ohif-study-list/client/lib/viewSeriesDetails.js +++ b/Packages/ohif-study-list/client/lib/viewSeriesDetails.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Display series details of study in a modal diff --git a/Packages/ohif-study-list/client/lib/viewStudies.js b/Packages/ohif-study-list/client/lib/viewStudies.js index 3e40b407a..a3679fc77 100644 --- a/Packages/ohif-study-list/client/lib/viewStudies.js +++ b/Packages/ohif-study-list/client/lib/viewStudies.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Loads multiple unassociated studies in the Viewer diff --git a/Packages/ohif-study-list/package.js b/Packages/ohif-study-list/package.js index 2bd73b86f..c7b7d0865 100644 --- a/Packages/ohif-study-list/package.js +++ b/Packages/ohif-study-list/package.js @@ -2,7 +2,8 @@ Npm.depends({ daterangepicker: '3.0.3', hammerjs: '2.0.8', moment: '2.22.2', - jquery: '3.3.1' + jquery: '3.3.1', + 'ohif-core': 'file:///Users/Erik/Projects/OHIF/ohif-core/' }); Package.describe({ @@ -18,13 +19,11 @@ Package.onUse(function(api) { api.use('templating', 'client'); api.use('stylus', 'client'); api.use('http', 'client'); - api.use('random', 'client'); api.use('aldeed:simple-schema', 'client'); api.use('aldeed:collection2', 'client'); api.use('gadicc:blaze-react-component', 'client'); // Our custom packages - api.use('ohif:core', 'client'); api.use('ohif:viewerbase', 'client'); // Client imports diff --git a/Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.js b/Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.js deleted file mode 100644 index a7b88abf3..000000000 --- a/Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.js +++ /dev/null @@ -1,412 +0,0 @@ -var dialogPolyfill = (function() { - - var supportCustomEvent = window.CustomEvent; - if (!supportCustomEvent || typeof supportCustomEvent == "object") { - supportCustomEvent = function CustomEvent(event, x) { - x = x || {}; - var ev = document.createEvent('CustomEvent'); - ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null); - return ev; - }; - supportCustomEvent.prototype = window.Event.prototype; - } - - /** - * Finds the nearest from the passed element. - * - * @param {Element} el to search from - * @param {HTMLDialogElement} dialog found - */ - function findNearestDialog(el) { - while (el) { - if (el.nodeName == 'DIALOG') { - return el; - } - el = el.parentElement; - } - return null; - } - - var dialogPolyfill = {}; - - dialogPolyfill.reposition = function(element) { - var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; - var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2; - element.style.top = Math.max(0, topValue) + 'px'; - element.dialogPolyfillInfo.isTopOverridden = true; - }; - - dialogPolyfill.inNodeList = function(nodeList, node) { - for (var i = 0; i < nodeList.length; ++i) { - if (nodeList[i] == node) - return true; - } - return false; - }; - - dialogPolyfill.isInlinePositionSetByStylesheet = function(element) { - for (var i = 0; i < document.styleSheets.length; ++i) { - var styleSheet = document.styleSheets[i]; - var cssRules = null; - // Some browsers throw on cssRules. - try { - cssRules = styleSheet.cssRules; - } catch (e) {} - if (!cssRules) - continue; - for (var j = 0; j < cssRules.length; ++j) { - var rule = cssRules[j]; - var selectedNodes = null; - // Ignore errors on invalid selector texts. - try { - selectedNodes = document.querySelectorAll(rule.selectorText); - } catch(e) {} - if (!selectedNodes || !dialogPolyfill.inNodeList(selectedNodes, element)) - continue; - var cssTop = rule.style.getPropertyValue('top'); - var cssBottom = rule.style.getPropertyValue('bottom'); - if ((cssTop && cssTop != 'auto') || (cssBottom && cssBottom != 'auto')) - return true; - } - } - return false; - }; - - dialogPolyfill.needsCentering = function(dialog) { - var computedStyle = window.getComputedStyle(dialog); - if (computedStyle.position != 'absolute') { - return false; - } - - // We must determine whether the top/bottom specified value is non-auto. In - // WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but - // Firefox returns the used value. So we do this crazy thing instead: check - // the inline style and then go through CSS rules. - if ((dialog.style.top != 'auto' && dialog.style.top != '') || - (dialog.style.bottom != 'auto' && dialog.style.bottom != '')) - return false; - return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog); - }; - - dialogPolyfill.showDialog = function(isModal) { - if (this.open) { - throw 'InvalidStateError: showDialog called on open dialog'; - } - this.open = true; // TODO: should be a getter mapped to attribute - this.setAttribute('open', 'open'); - - if (isModal) { - // Find element with `autofocus` attribute or first form control - var first_form_ctrl = null; - var autofocus = null; - var findElementToFocus = function(root) { - if (!root.children) { - return; - } - for (var i = 0; i < root.children.length; i++) { - var elem = root.children[i]; - if (first_form_ctrl === null && !elem.disabled && ( - elem.nodeName == 'BUTTON' || - elem.nodeName == 'INPUT' || - elem.nodeName == 'KEYGEN' || - elem.nodeName == 'SELECT' || - elem.nodeName == 'TEXTAREA')) { - first_form_ctrl = elem; - } - if (elem.autofocus) { - autofocus = elem; - return; - } - findElementToFocus(elem); - if (autofocus !== null) return; - } - }; - - findElementToFocus(this); - - if (autofocus !== null) { - autofocus.focus(); - } else if (first_form_ctrl !== null) { - first_form_ctrl.focus(); - } - } - - if (dialogPolyfill.needsCentering(this)) - dialogPolyfill.reposition(this); - if (isModal) { - this.dialogPolyfillInfo.modal = true; - dialogPolyfill.dm.pushDialog(this); - } - - // IE sometimes complains when calling .focus() that it - // "Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus." - try { - if (autofocus !== null) { - autofocus.focus(); - } else if (first_form_ctrl !== null) { - first_form_ctrl.focus(); - } - } catch(e) {} - this.style.zoom = 1; - }; - - dialogPolyfill.close = function(retval) { - if (!this.open && !window.HTMLDialogElement) { - // Native implementations will set .open to false, so ignore this error. - throw 'InvalidStateError: close called on closed dialog'; - } - this.open = false; - this.removeAttribute('open'); - - // Leave returnValue untouched in case it was set directly on the element - if (typeof retval != 'undefined') { - this.returnValue = retval; - } - - // This won't match the native exactly because if the user sets top - // on a centered polyfill dialog, that top gets thrown away when the dialog is - // closed. Not sure it's possible to polyfill this perfectly. - if (this.dialogPolyfillInfo.isTopOverridden) { - this.style.top = 'auto'; - } - - if (this.dialogPolyfillInfo.modal) { - dialogPolyfill.dm.removeDialog(this); - } - - // Triggering "close" event for any attached listeners on the - var event; - if (document.createEvent) { - event = document.createEvent('HTMLEvents'); - event.initEvent('close', true, true); - } else { - event = new Event('close'); - } - this.dispatchEvent(event); - - return this.returnValue; - }; - - dialogPolyfill.registerDialog = function(element) { - if (element.show) { - // console.warn("This browser already supports , the polyfill " + - // "may not work correctly."); - } - element.show = dialogPolyfill.showDialog.bind(element, false); - element.showModal = dialogPolyfill.showDialog.bind(element, true); - element.close = dialogPolyfill.close.bind(element); - element.dialogPolyfillInfo = {}; - element.open = false; - }; - - // The overlay is used to simulate how a modal dialog blocks the document. The - // blocking dialog is positioned on top of the overlay, and the rest of the - // dialogs on the pending dialog stack are positioned below it. In the actual - // implementation, the modal dialog stacking is controlled by the top layer, - // where z-index has no effect. - var TOP_LAYER_ZINDEX = 100000; - var MAX_PENDING_DIALOGS = 100000; - - dialogPolyfill.DialogManager = function() { - this.pendingDialogStack = []; - this.overlay = document.createElement('div'); - this.overlay.style.width = '100%'; - this.overlay.style.height = '100%'; - this.overlay.style.position = 'fixed'; - this.overlay.style.left = '0px'; - this.overlay.style.top = '0px'; - this.overlay.style.backgroundColor = 'rgba(0,0,0,0.0)'; - - this.focusPageLast = this.createFocusable(); - this.overlay.appendChild(this.focusPageLast); - - this.overlay.addEventListener('click', function(e) { - var redirectedEvent = document.createEvent('MouseEvents'); - redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window, - e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, - e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); - document.body.dispatchEvent(redirectedEvent); - }); - - // TODO: Only install when any dialogs are open. - document.addEventListener('submit', function(ev) { - var method = ev.target.getAttribute('method'); - method = method ? method.toLowerCase() : ''; - if (method != 'dialog') { return; } - ev.preventDefault(); - - var dialog = findNearestDialog(ev.target); - if (!dialog) { return; } - - // FIXME: The original event doesn't contain the INPUT element used to - // submit the form (if any). Look in some possible places. - var returnValue; - var cands = [document.activeElement, ev.explicitOriginalTarget]; - cands.some(function(cand) { - if (cand && cand.nodeName == 'INPUT' && cand.form == ev.target) { - returnValue = cand.value; - return true; - } - }); - dialog.close(returnValue); - }, true); - }; - - dialogPolyfill.DialogManager.prototype.createFocusable = function(tabIndex) { - var span = document.createElement('span'); - span.tabIndex = tabIndex || 0; - span.style.opacity = 0; - span.style.position = 'static'; - return span; - }; - - dialogPolyfill.DialogManager.prototype.blockDocument = function() { - if (!document.body.contains(this.overlay)) { - document.body.appendChild(this.overlay); - - // On Safari/Mac (and possibly other browsers), the documentElement is - // not focusable. This is required for modal dialogs as it is the first - // element to be hit by a tab event, and further tabs are redirected to - // the most visible dialog. - if (this.needsDocumentElementFocus === undefined) { - document.documentElement.focus(); - this.needsDocumentElementFocus = - (document.activeElement != document.documentElement); - } - if (this.needsDocumentElementFocus) { - document.documentElement.tabIndex = 1; - } - } - }; - - dialogPolyfill.DialogManager.prototype.unblockDocument = function() { - document.body.removeChild(this.overlay); - if (this.needsDocumentElementFocus) { - // TODO: Restore the previous tabIndex, rather than clearing it. - document.documentElement.tabIndex = ''; - } - }; - - dialogPolyfill.DialogManager.prototype.updateStacking = function() { - if (this.pendingDialogStack.length == 0) { - this.unblockDocument(); - return; - } - this.blockDocument(); - - var zIndex = TOP_LAYER_ZINDEX; - for (var i = 0; i < this.pendingDialogStack.length; i++) { - if (i == this.pendingDialogStack.length - 1) - this.overlay.style.zIndex = zIndex++; - var dialog = this.pendingDialogStack[i]; - dialog.dialogPolyfillInfo.backdrop.style.zIndex = zIndex++; - dialog.style.zIndex = zIndex++; - } - }; - - dialogPolyfill.DialogManager.prototype.handleKey = function(event) { - var dialogCount = this.pendingDialogStack.length; - if (dialogCount == 0) { - return; - } - var dialog = this.pendingDialogStack[dialogCount - 1]; - var pfi = dialog.dialogPolyfillInfo; - - switch (event.keyCode) { - case 9: /* tab */ - var activeElement = document.activeElement; - var forward = !event.shiftKey; - if (forward) { - // Tab forward, so look for document or fake last focus element. - if (activeElement == document.documentElement || - activeElement == document.body || - activeElement == pfi.backdrop) { - pfi.focusFirst.focus(); - } else if (activeElement == pfi.focusLast) { - // TODO: Instead of wrapping to focusFirst, escape to browser chrome. - pfi.focusFirst.focus(); - } - } else { - // Tab backwards, so look for fake first focus element. - if (activeElement == pfi.focusFirst) { - // TODO: Instead of wrapping to focusLast, escape to browser chrome. - pfi.focusLast.focus(); - } else if (activeElement == this.focusPageLast) { - // The focus element is at the end of the page (e.g., shift-tab from - // the window chrome): move current focus to the last element in the - // dialog instead. - pfi.focusLast.focus(); - } - } - break; - - case 27: /* esc */ - event.preventDefault(); - event.stopPropagation(); - var cancelEvent = new supportCustomEvent('cancel', { - bubbles: false, - cancelable: true - }); - if (dialog.dispatchEvent(cancelEvent)) { - dialog.close(); - } - break; - - } - }; - - dialogPolyfill.DialogManager.prototype.pushDialog = function(dialog) { - if (this.pendingDialogStack.length >= MAX_PENDING_DIALOGS) { - throw "Too many modal dialogs"; - } - - var backdrop = document.createElement('div'); - backdrop.className = 'backdrop'; - var clickEventListener = function(e) { - var redirectedEvent = document.createEvent('MouseEvents'); - redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window, - e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, - e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); - dialog.dispatchEvent(redirectedEvent); - }; - backdrop.addEventListener('click', clickEventListener); - dialog.parentNode.insertBefore(backdrop, dialog.nextSibling); - dialog.dialogPolyfillInfo.backdrop = backdrop; - dialog.dialogPolyfillInfo.clickEventListener = clickEventListener; - this.pendingDialogStack.push(dialog); - this.updateStacking(); - - dialog.dialogPolyfillInfo.focusFirst = this.createFocusable(); - dialog.dialogPolyfillInfo.focusLast = this.createFocusable(); - dialog.appendChild(dialog.dialogPolyfillInfo.focusLast); - dialog.insertBefore( - dialog.dialogPolyfillInfo.focusFirst, dialog.firstChild); - }; - - dialogPolyfill.DialogManager.prototype.removeDialog = function(dialog) { - var index = this.pendingDialogStack.indexOf(dialog); - if (index == -1) { - return; - } - this.pendingDialogStack.splice(index, 1); - var backdrop = dialog.dialogPolyfillInfo.backdrop; - var clickEventListener = dialog.dialogPolyfillInfo.clickEventListener; - backdrop.removeEventListener('click', clickEventListener); - backdrop.parentNode.removeChild(backdrop); - dialog.dialogPolyfillInfo.backdrop = null; - dialog.dialogPolyfillInfo.clickEventListener = null; - this.updateStacking(); - - dialog.removeChild(dialog.dialogPolyfillInfo.focusFirst); - dialog.removeChild(dialog.dialogPolyfillInfo.focusLast); - dialog.dialogPolyfillInfo.focusFirst = null; - dialog.dialogPolyfillInfo.focusLast = null; - }; - - dialogPolyfill.dm = new dialogPolyfill.DialogManager(); - - document.addEventListener('keydown', - dialogPolyfill.dm.handleKey.bind(dialogPolyfill.dm)); - - return dialogPolyfill; -})(); diff --git a/Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.styl b/Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.styl deleted file mode 100644 index fc571789a..000000000 --- a/Packages/ohif-viewerbase/client/compatibility/dialogPolyfill.styl +++ /dev/null @@ -1,34 +0,0 @@ -dialog - position: absolute - left: 0 - right: 0 - width: -moz-fit-content - width: -webkit-fit-content - width: fit-content - height: -moz-fit-content - height: -webkit-fit-content - height: fit-content - margin: auto - border: solid - padding: 1em - background: white - color: black - display: none - -dialog[open] - display: block - -dialog + .backdrop - position: fixed - top: 0 - right: 0 - bottom: 0 - left: 0 - background: rgba(0,0,0,0.1) - -/* for small devices, modal dialogs go full-screen */ -@media screen and (max-width: 540px) - dialog[_polyfill_modal] - top: 0 - width: auto - margin: 1em \ No newline at end of file diff --git a/Packages/ohif-viewerbase/client/components/basic/aboutModal/aboutModal.js b/Packages/ohif-viewerbase/client/components/basic/aboutModal/aboutModal.js index e8d6bf2fd..83b66dd03 100644 --- a/Packages/ohif-viewerbase/client/components/basic/aboutModal/aboutModal.js +++ b/Packages/ohif-viewerbase/client/components/basic/aboutModal/aboutModal.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.aboutModal.helpers({ githubUrl() { diff --git a/Packages/ohif-viewerbase/client/components/basic/layout/layout.html b/Packages/ohif-viewerbase/client/components/basic/layout/layout.html deleted file mode 100644 index b023d9c9a..000000000 --- a/Packages/ohif-viewerbase/client/components/basic/layout/layout.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/Packages/ohif-viewerbase/client/components/browser/item.js b/Packages/ohif-viewerbase/client/components/browser/item.js index 395bd6952..1db7d6d0b 100644 --- a/Packages/ohif-viewerbase/client/components/browser/item.js +++ b/Packages/ohif-viewerbase/client/components/browser/item.js @@ -3,7 +3,7 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; import $ from 'jquery'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.studyBrowserItem.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/browser/quickSwitch.js b/Packages/ohif-viewerbase/client/components/browser/quickSwitch.js index 25cf327bb..391dc8350 100644 --- a/Packages/ohif-viewerbase/client/components/browser/quickSwitch.js +++ b/Packages/ohif-viewerbase/client/components/browser/quickSwitch.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.studyBrowserQuickSwitch.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/browser/series.js b/Packages/ohif-viewerbase/client/components/browser/series.js index 9772f8379..f58709be2 100644 --- a/Packages/ohif-viewerbase/client/components/browser/series.js +++ b/Packages/ohif-viewerbase/client/components/browser/series.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.studyBrowserSeries.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/associationModal.js b/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/associationModal.js index ba47c1127..4e57ee0ee 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/associationModal.js +++ b/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/associationModal.js @@ -1,10 +1,9 @@ -import { Meteor } from 'meteor/meteor'; import { Template } from 'meteor/templating'; import { Blaze } from 'meteor/blaze'; import moment from 'moment'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.dialogStudyAssociation.onCreated(() => { diff --git a/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/studyAssociationTable/studyAssociationTable.js b/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/studyAssociationTable/studyAssociationTable.js index b3fe0d05f..2d3161a4f 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/studyAssociationTable/studyAssociationTable.js +++ b/Packages/ohif-viewerbase/client/components/measurements/association/associationModal/studyAssociationTable/studyAssociationTable.js @@ -1,6 +1,6 @@ import { Template } from 'meteor/templating'; import moment from 'moment'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Finds related studies within defined time window of =/- 14 days of selected studies diff --git a/Packages/ohif-viewerbase/client/components/measurements/caseProgress/caseProgress.js b/Packages/ohif-viewerbase/client/components/measurements/caseProgress/caseProgress.js index e0d9f25dd..4e0b54669 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/caseProgress/caseProgress.js +++ b/Packages/ohif-viewerbase/client/components/measurements/caseProgress/caseProgress.js @@ -1,6 +1,6 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.caseProgress.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementEditDescription/measurementEditDescription.js b/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementEditDescription/measurementEditDescription.js index 5b7fb3183..e3b96d0e7 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementEditDescription/measurementEditDescription.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementEditDescription/measurementEditDescription.js @@ -1,5 +1,5 @@ import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.measurementEditDescription.onRendered(() => { diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableRow/measurementLightTableRow.js b/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableRow/measurementLightTableRow.js index 71b367337..ce99952c4 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableRow/measurementLightTableRow.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableRow/measurementLightTableRow.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import _ from 'underscore'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; const getPosition = event => { diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableView/measurementLightTableView.js b/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableView/measurementLightTableView.js index 8c7d91ceb..c3832b269 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableView/measurementLightTableView.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementLightTable/measurementLightTableView/measurementLightTableView.js @@ -1,6 +1,6 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.measurementLightTableView.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/index.js b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/index.js index 0b85914e2..889ac7a82 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/index.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/index.js @@ -7,10 +7,6 @@ import './measurementTableView/measurementTableView.html'; import './measurementTableView/measurementTableView.styl'; import './measurementTableView/measurementTableView.js'; -import './measurementTableHUD/measurementTableHUD.html'; -import './measurementTableHUD/measurementTableHUD.styl'; -import './measurementTableHUD/measurementTableHUD.js'; - import './measurementTableRow/measurementTableRow.html'; import './measurementTableRow/measurementTableRow.styl'; import './measurementTableRow/measurementTableRow.js'; diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTable.js b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTable.js index eac29beb7..d57f75ef0 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTable.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTable.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.measurementTable.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.html b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.html deleted file mode 100644 index fb2a9e7f3..000000000 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.html +++ /dev/null @@ -1,20 +0,0 @@ - diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.js b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.js deleted file mode 100644 index e2a517e0a..000000000 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.js +++ /dev/null @@ -1,72 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Session } from 'meteor/session'; -import { ReactiveVar } from 'meteor/reactive-var'; - -Template.measurementTableHUD.onCreated(() => { - const instance = Template.instance(); - const timepointApi = instance.data.timepointApi; - - instance.isRemoved = true; - if (timepointApi) { - instance.data.timepoints = new ReactiveVar(timepointApi.currentAndPrior()); - } -}); - -Template.measurementTableHUD.onDestroyed(() => { - const instance = Template.instance(); - - instance.isRemoved = true; - Session.set('measurementTableHudOpen', false); -}); - -Template.measurementTableHUD.onRendered(() => { - const instance = Template.instance(); - instance.$('#measurementTableHUD').resizable().draggable().bounded(); -}); - -Template.measurementTableHUD.events({ - 'click .buttonClose'(event, instance) { - Session.set('measurementTableHudOpen', false); - } -}); - -Template.measurementTableHUD.helpers({ - hudHidden() { - let instance = Template.instance(), - isOpen = Session.get('measurementTableHudOpen'); - - if (isOpen) { - instance.isRemoved = false; - return 'dialog-animated dialog-open'; - } - - return instance.isRemoved !== true ? 'dialog-animated dialog-closed' : 'hidden'; - }, - - toolbarButtons() { - let buttonData = []; - - buttonData.push({ - id: 'bidirectional', - title: 'Target', - classes: 'imageViewerTool toolbarSectionButton', - svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-target' - }); - - buttonData.push({ - id: 'nonTarget', - title: 'Non-Target', - classes: 'imageViewerTool toolbarSectionButton', - svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-non-target' - }); - - buttonData.push({ - id: 'length', - title: 'Temp', - classes: 'imageViewerTool toolbarSectionButton', - svgLink: '/packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-temp' - }); - - return buttonData; - } -}); diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.styl b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.styl deleted file mode 100644 index 1e2ec34ed..000000000 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHUD/measurementTableHUD.styl +++ /dev/null @@ -1,95 +0,0 @@ -@require '{ohif:viewerbase}/app' - -$borderColor = rgba(77, 99, 110, 0.81) - -#measurementTableHUD - background: rgba(0, 0, 0, 0.95) - border-radius: 8px - border: solid 1px $borderColor; - bottom: 3px - height: 326px - left: auto - overflow: hidden - position: absolute - right: 3px - top: auto - width: 318px - z-index: 1 - - .measurementTableView .scrollable - margin-left: 0 - padding-left: 0 - - .header - theme('background', '$uiGrayDarkest') - theme('color', '$textSecondaryColor') - border-bottom: $uiBorderThickness solid $borderColor - font-weight: 300 - font-size: 20px - height: 55px - line-height: 55px - position: relative - text-align: center - width: 100% - - svg.buttonClose - theme('color', '$defaultColor') - cursor: pointer - height: 14px - position: absolute - right: 14px - theme('stroke', '$defaultColor') - top: 20px - width: 14px - - .measurementTableView - height: calc(100% - 55px - 70px) - padding-bottom: 20px - - .footer - theme('background', '$uiGrayDarkest') - border-top: $uiBorderThickness solid $borderColor - height: 70px - padding: 10px - - .toolbarSectionButton - display: inline-block - theme('color', '$defaultColor') - theme('fill', '$defaultColor') - theme('stroke', '$defaultColor') - padding: 0 10px - height: $toolbarHeight - min-width: 30px - cursor: pointer - text-align: center - - &.disabled - opacity: 0.5 - cursor: not-allowed - - .buttonLabel - font-size: 12px - - .svgContainer - margin: 0 auto - text-align: center - - svg - background-color: transparent - margin: 2px - width: 21px - height: 21px - - &:active, &.active - theme('color', '$activeColor') - - svg - theme('fill', '$activeColor') - theme('stroke', '$activeColor') - - &:hover - theme('color', '$hoverColor') - - svg - theme('fill', '$hoverColor') - theme('stroke', '$hoverColor') diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHeaderRow/measurementTableHeaderRow.js b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHeaderRow/measurementTableHeaderRow.js index 5021418a2..76095bd5d 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHeaderRow/measurementTableHeaderRow.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableHeaderRow/measurementTableHeaderRow.js @@ -1,5 +1,5 @@ import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { Viewerbase } from 'meteor/ohif:viewerbase'; Template.measurementTableHeaderRow.helpers({ diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableRow/measurementTableRow.js b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableRow/measurementTableRow.js index 9da396b50..37dee749f 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableRow/measurementTableRow.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableRow/measurementTableRow.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import _ from 'underscore'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; Template.measurementTableRow.onCreated(() => { diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableTimepointCell/measurementTableTimepointCell.js b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableTimepointCell/measurementTableTimepointCell.js index a9cdceaf1..9b33726e3 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableTimepointCell/measurementTableTimepointCell.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableTimepointCell/measurementTableTimepointCell.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import _ from 'underscore'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; Template.measurementTableTimepointCell.helpers({ diff --git a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableView/measurementTableView.js b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableView/measurementTableView.js index 7f9fe5ff7..0a141506f 100644 --- a/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableView/measurementTableView.js +++ b/Packages/ohif-viewerbase/client/components/measurements/measurementTable/measurementTableView/measurementTableView.js @@ -2,7 +2,7 @@ import { Template } from 'meteor/templating'; import { Tracker } from 'meteor/tracker'; import { ReactiveVar } from 'meteor/reactive-var'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.measurementTableView.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/selectTree/mixin.js b/Packages/ohif-viewerbase/client/components/selectTree/mixin.js index e648f7f6b..5a75ea4ed 100644 --- a/Packages/ohif-viewerbase/client/components/selectTree/mixin.js +++ b/Packages/ohif-viewerbase/client/components/selectTree/mixin.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import _ from 'underscore'; diff --git a/Packages/ohif-viewerbase/client/components/selectTree/selectTree/selectTree.js b/Packages/ohif-viewerbase/client/components/selectTree/selectTree/selectTree.js index 854899225..b637a627d 100644 --- a/Packages/ohif-viewerbase/client/components/selectTree/selectTree/selectTree.js +++ b/Packages/ohif-viewerbase/client/components/selectTree/selectTree/selectTree.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { Meteor } from 'meteor/meteor'; import { Template } from 'meteor/templating'; import { Tracker } from 'meteor/tracker'; @@ -7,7 +7,7 @@ import _ from 'underscore'; import $ from 'jquery'; // TODO: use npm dependency -import transition from 'meteor/ohif:core/client/lib/third-party/transition-to-from-auto'; +import transition from 'ohif-core/client/lib/third-party/transition-to-from-auto'; Template.selectTree.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/serverInformation/index.js b/Packages/ohif-viewerbase/client/components/serverInformation/index.js index 21269878e..daf0893bf 100644 --- a/Packages/ohif-viewerbase/client/components/serverInformation/index.js +++ b/Packages/ohif-viewerbase/client/components/serverInformation/index.js @@ -10,6 +10,6 @@ import './serverInformationForm/serverInformationForm.js'; import './serverInformationList/serverInformationList.html'; import './serverInformationList/serverInformationList.js'; -import './serverInformationModal/serverInformationModal.html'; +/*import './serverInformationModal/serverInformationModal.html'; import './serverInformationModal/serverInformationModal.styl'; -import './serverInformationModal/serverInformationModal.js'; +import './serverInformationModal/serverInformationModal.js';*/ \ No newline at end of file diff --git a/Packages/ohif-viewerbase/client/components/serverInformation/serverInformationForm/serverInformationForm.js b/Packages/ohif-viewerbase/client/components/serverInformation/serverInformationForm/serverInformationForm.js index a3fec1a77..e68ea1540 100644 --- a/Packages/ohif-viewerbase/client/components/serverInformation/serverInformationForm/serverInformationForm.js +++ b/Packages/ohif-viewerbase/client/components/serverInformation/serverInformationForm/serverInformationForm.js @@ -1,7 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { DICOMWebServer as dicomSchema } from 'meteor/ohif:servers/both/schema/servers.js'; import { DIMSEServer as dimseSchema } from 'meteor/ohif:servers/both/schema/servers.js'; diff --git a/Packages/ohif-viewerbase/client/components/viewer/GridLayout/GridLayout.js b/Packages/ohif-viewerbase/client/components/viewer/GridLayout/GridLayout.js index bd0b392eb..6cbf2be48 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/GridLayout/GridLayout.js +++ b/Packages/ohif-viewerbase/client/components/viewer/GridLayout/GridLayout.js @@ -1,7 +1,7 @@ import { Component } from 'react'; import React from 'react'; import PropTypes from 'prop-types'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; import ConnectedCornerstoneViewport from '../ConnectedCornerstoneViewport.js'; import './GridLayout.styl'; diff --git a/Packages/ohif-viewerbase/client/components/viewer/ToolContextMenu/toolContextMenu-blz.js b/Packages/ohif-viewerbase/client/components/viewer/ToolContextMenu/toolContextMenu-blz.js index 351d2be72..257ae1337 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/ToolContextMenu/toolContextMenu-blz.js +++ b/Packages/ohif-viewerbase/client/components/viewer/ToolContextMenu/toolContextMenu-blz.js @@ -1,5 +1,5 @@ import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; import { toolManager } from '../../../lib/toolManager'; diff --git a/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.js b/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.js index 42d5fa0b9..bb90e7b40 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.js +++ b/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.js @@ -1,37 +1,54 @@ -import { Meteor } from 'meteor/meteor'; -import { Session } from 'meteor/session'; -import { OHIF } from 'meteor/ohif:core'; +import { Component } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; + +import { LayoutManager } from 'react-viewerbase'; +import { OHIF } from 'ohif-core'; + // Local Modules import { unloadHandlers } from '../../../lib/unloadHandlers'; -import { LayoutManager } from '../../../lib/classes/LayoutManager'; +import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; +import ConnectedCornerstoneViewport from '../ConnectedCornerstoneViewport.js'; +import StackManager from '../../../lib/StackManager.js'; const { StudyLoadingListener, StudyPrefetcher, ResizeViewportManager } = OHIF.classes; import './ViewerMain.styl'; -import { Component } from 'react'; -import React from 'react'; -import PropTypes from 'prop-types'; +window.ResizeViewportManager = window.ResizeViewportManager || new ResizeViewportManager(); -Meteor.startup(() => { - window.ResizeViewportManager = window.ResizeViewportManager || new ResizeViewportManager(); +function getCornerstoneStack(viewportData) { + const { + displaySetInstanceUid, + studyInstanceUid, + } = viewportData; - // Set initial value for OHIFViewerMainRendered - // session variable. This can used in viewer main template - Session.set('OHIFViewerMainRendered', false); -}); + // Create shortcut to displaySet + const study = OHIF.viewer.Studies.findBy({ + studyInstanceUid, + }); -import { connect } from 'react-redux'; + const displaySet = study.displaySets.find((set) => { + return set.displaySetInstanceUid === displaySetInstanceUid; + }); + + // Get stack from Stack Manager + const stack = StackManager.findOrCreateStack(study, displaySet); + stack.currentImageIdIndex = 0; + + return stack; +} class ViewerMain extends Component { constructor(props) { super(props); this.state = { - contents: '' + displaySets: [] }; - this.setContents = this.setContents.bind(this); + this.getCornerstoneViewport = this.getCornerstoneViewport.bind(this); } componentDidMount() { @@ -46,9 +63,6 @@ class ViewerMain extends Component { // Add beforeUnload event handler to check for unsaved changes window.addEventListener('beforeunload', unloadHandlers.beforeUnload); - // Set the current context - OHIF.context.set('viewer'); - const { studies } = this.props; this.studyPrefetcher = StudyPrefetcher.getInstance(); this.studyPrefetcher.setStudies(studies); @@ -56,42 +70,47 @@ class ViewerMain extends Component { this.studyLoadingListener.clear(); this.studyLoadingListener.addStudies(studies); - OHIF.viewerbase.layoutManager = new LayoutManager(this.setContents, studies); - - Session.set('OHIFViewerMainRendered', Math.random()); - } - - setContents(Component, props) { - // TODO[react] Not sure I like this piece much - const mapStateToProps = state => { - return { - activeViewportIndex: state.viewports.activeViewportIndex, - }; - }; - - const ConnectedComponent = connect( - mapStateToProps, - null - )(Component); - - const contents = (); + // Get all the display sets for the viewer studies + const displaySets = []; + studies.forEach((study) => { + study.displaySets.forEach(dSet => dSet.images.length && displaySets.push(dSet)); + }); this.setState({ - contents + displaySets }); } + getCornerstoneViewport(data, index) { + const stack = getCornerstoneStack(data) + const viewportData = { + stack, + ...data + }; + + return (); + }; + render() { + // TODO: re-add plugins back in + const viewportData = this.state.displaySets.map((dSet, index) => { + return this.getCornerstoneViewport(dSet, index); + }) + + // TODO: Connect LayoutManager to redux return ( -
- {this.state.contents} -
+
+ +
); } componentWillUnmount() { - OHIF.log.info('viewerMain onDestroyed'); - // Remove the Window resize listener window.removeEventListener('resize', window.ResizeViewportManager.getResizeHandler()); @@ -101,11 +120,8 @@ class ViewerMain extends Component { // Destroy the synchronizer used to update reference lines OHIF.viewer.updateImageSynchronizer.destroy(); - delete OHIF.viewerbase.layoutManager; ProtocolEngine = null; - Session.set('OHIFViewerMainRendered', false); - // Stop prefetching when we close the viewer this.studyPrefetcher.destroy(); @@ -122,9 +138,6 @@ class ViewerMain extends Component { // @TypeSafeStudies // Clears OHIF.viewer.StudyMetadataList collection OHIF.viewer.StudyMetadataList.removeAll(); - - // Reset the current context - OHIF.context.set(null); } } diff --git a/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.styl b/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.styl index 8b69e8576..50c6ab265 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.styl +++ b/Packages/ohif-viewerbase/client/components/viewer/ViewerMain/ViewerMain.styl @@ -9,7 +9,7 @@ height: 100% line-height: "calc(100% - %s)" % $topBarHeight -.viewerMain +.ViewerMain width: 100% height: 100% transition(all 0.3s ease) diff --git a/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.html b/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.html deleted file mode 100644 index d808fb045..000000000 --- a/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.html +++ /dev/null @@ -1,50 +0,0 @@ - diff --git a/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.js b/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.js deleted file mode 100644 index 89a29e40c..000000000 --- a/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.js +++ /dev/null @@ -1,310 +0,0 @@ -import { Template } from 'meteor/templating'; -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; -import { Session } from 'meteor/session'; -import { Tracker } from 'meteor/tracker'; -import _ from 'underscore'; -import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; -import { cornerstoneTools } from 'meteor/ohif:cornerstone'; -import { viewportUtils } from '../../../lib/viewportUtils'; -import { switchToImageRelative } from '../../../lib/switchToImageRelative'; -import { switchToImageByIndex } from '../../../lib/switchToImageByIndex'; - -Template.cineDialog.onCreated(() => { - const instance = Template.instance(); - - // Create the data schema for CINE controls - instance.schema = new SimpleSchema({ - intervalId: { - type: Number, - optional: true - }, - loop: { - type: Boolean, - label: 'Loop', - defaultValue: true - }, - framesPerSecond: { - type: Number, - label: '', - defaultValue: 24, - min: 1, - max: 90, - optional: true - } - }); - - // Update the current viewport frame rate - instance.updateFramerate = rate => { - OHIF.viewer.cine.framesPerSecond = rate; - - // Update playClip toolData for this imageId - const element = viewportUtils.getActiveViewportElement(); - if (!element) { - return; - } - - let playClipData = cornerstoneTools.getToolState(element, 'playClip'); - if (!playClipData || !playClipData.data || !playClipData.data.length) { - return; - } - - // A valid playClip data object is available. - playClipData = playClipData.data[0]; - - // If the movie is playing, stop/start to update the framerate - if (playClipData.intervalId !== void 0) { - cornerstoneTools.stopClip(element); - cornerstoneTools.playClip(element, OHIF.viewer.cine.framesPerSecond); - } else { - playClipData.framesPerSecond = OHIF.viewer.cine.framesPerSecond; - } - - Session.set('UpdateCINE', Math.random()); - }; - - // Define the actions API - instance.api = { - displaySetPrevious: () => OHIF.viewerbase.layoutManager.moveDisplaySets(false), - displaySetNext: () => OHIF.viewerbase.layoutManager.moveDisplaySets(true), - cineToggle: () => viewportUtils.toggleCinePlay(), - cineFirst: () => switchToImageByIndex(0), - cineLast: () => switchToImageByIndex(-1), - cinePrevious: () => switchToImageRelative(-1), - cineNext: () => switchToImageRelative(1), - cineSlowDown: () => { - const newValue = OHIF.viewer.cine.framesPerSecond - 1; - if (newValue > 0) { - instance.updateFramerate(newValue); - } - }, - cineSpeedUp: () => { - const newValue = OHIF.viewer.cine.framesPerSecond + 1; - if (newValue <= 90) { - instance.updateFramerate(newValue); - } - } - }; - - // Run this computation every time the active viewport is changed - instance.autorun(() => { - window.store.getState().viewports.activeViewport; - - Tracker.afterFlush(() => { - // Get the active viewportElement - const element = viewportUtils.getActiveViewportElement(); - if (!element) { - return; - } - - // check if playClip tool has been initialized... - const playClipData = cornerstoneTools.getToolState(element, 'playClip'); - if (!playClipData) { - return; - } - - // Get the cornerstone playClip tool data - const toolData = playClipData.data[0]; - - // Get the cine object - const cine = OHIF.viewer.cine; - - // replace the cine values with the tool data - _.extend(cine, toolData); - - // Set the defaults - cine.framesPerSecond = cine.framesPerSecond || 24; - cine.loop = _.isUndefined(cine.loop) ? true : cine.loop; - - // Set the updated data on the form inputs - const elementComponent = instance.$('form:first').data('component'); - if (elementComponent) { - elementComponent.value(cine); - } - - // Update the session to refresh the framerate text - Session.set('UpdateCINE', Math.random()); - }); - }); - - /** - * Set/Reset Window resize handler. This function is a replacement for - * ... jQuery's on('resize', func) version which, for some unkown reason - * ... is currently not working for this portion of code. - * ... Further investigation is necessary. - * - * This happens because when an event is attached using jQuery's - * you can't get it using vanilla JavaScript, it returns null. - * You need to use jQuery for that. So, either you use vanilla JS or jQuery - * to get an element's event handler. See viewerMain for more details. - */ - - instance.setResizeHandler = handler => { - if (typeof handler === 'function') { - const origHandler = window.onresize; - instance.origWindowResizeHandler = typeof origHandler === 'function' ? origHandler : null; - window.onresize = event => { - if (typeof origHandler === 'function') { - origHandler.call(window, event); - } - - handler.call(window, event); - }; - } else { - window.onresize = instance.origWindowResizeHandler || null; - window.origWindowResizeHandler = null; - } - }; - - /** - * Set optimal position for Cine dialog. - */ - - instance.setOptimalPosition = (event, options) => { - const $viewer = $('#viewer'); - const $toolbarElement = $('.toolbarSection .toolbarSectionTools:first'); - const $cineDialog = $('#cineDialog'); - $cineDialog.width($('#cineDialogForm').outerWidth()); - - if ($toolbarElement.length < 1 || $cineDialog.length < 1) { - return; - } - - if ($cineDialog.data('wasDragged') || $cineDialog.data('wasBounded')) { - // restore original handler... - instance.setResizeHandler(null); - return; - } - - const cineDialogSize = { - width: $cineDialog.outerWidth() || 0, - height: $cineDialog.outerHeight() || 0 - }; - - const topLeftCoords = { - top: 0, - left: 0 - }; - - const toolbarRect = { - offset: $toolbarElement.offset() || topLeftCoords, - width: $toolbarElement.outerWidth() || 0, - height: $toolbarElement.outerHeight() || 0 - }; - - const cineDialogCoords = { - left: toolbarRect.offset.left + toolbarRect.width + 20, - top: toolbarRect.offset.top + toolbarRect.height - cineDialogSize.height - }; - - if (options) { - if (options.left) { - cineDialogCoords.left = options.left; - } - - if (options.top) { - cineDialogCoords.top = options.top; - } - } - - // Check if it is out of screen - if (cineDialogCoords.top < 0) { - cineDialogCoords.top = 0; - } else if (cineDialogCoords.top + cineDialogSize.height > $viewer.height()) { - cineDialogCoords.top -= (cineDialogCoords.top + cineDialogSize.height) - $viewer.height(); - } - - if (cineDialogCoords.left < 0) { - cineDialogCoords.left = 0; - } else if (cineDialogCoords.left + cineDialogSize.width > $viewer.width()) { - cineDialogCoords.left -= (cineDialogCoords.left + cineDialogSize.width) - $viewer.width(); - } - - $cineDialog.css(cineDialogCoords); - }; -}); - -Template.cineDialog.onRendered(() => { - const instance = Template.instance(); - const $dialog = instance.$('#cineDialog'); - const singleRowLayout = OHIF.uiSettings.displayEchoUltrasoundWorkflow; - - // set dialog in optimal position and make sure it continues in a optimal position... - // ... when the window has been resized - instance.setOptimalPosition(null, { top: singleRowLayout ? 47 : 26 }); - - // The jQuery method does not seem to be working... - // ... $(window).resize(instance.setOptimalPosition) - // This requires additional investigation. - instance.setResizeHandler(instance.setOptimalPosition); - - // Make the CINE dialog bounded and draggable - $dialog.draggable({ defaultElementCursor: 'move' }).bounded(); - - // Polyfill for older browsers - window.dialogPolyfill.registerDialog($dialog.get(0)); - - // Prevent dialog from being dragged when user clicks any button - const $controls = $dialog.find('.cine-navigation, .cine-controls, .cine-options'); - $controls.on('mousedown touchstart', event => event.stopPropagation()); -}); - -Template.cineDialog.onDestroyed(() => { - const instance = Template.instance(); - // remove resize handler... - instance.setResizeHandler(null); -}); - -Template.cineDialog.events({ - 'change [data-key=loop] input'(event, instance) { - const element = viewportUtils.getActiveViewportElement(); - OHIF.viewer.cine.loop = $(event.currentTarget).is(':checked'); - // Update playClip tool data if available. - let playClipData = cornerstoneTools.getToolState(element, 'playClip'); - if (playClipData && playClipData.data && playClipData.data.length > 0) { - playClipData.data[0].loop = OHIF.viewer.cine.loop; - } - }, - - 'input [data-key=framesPerSecond] input, change [data-key=framesPerSecond] input'(event, instance) { - // Update the FPS text onscreen - const rate = parseFloat($(event.currentTarget).val()); - instance.updateFramerate(rate); - }, - - 'click .button-close'(event, instance) { - OHIF.commands.run('toggleCineDialog'); - } -}); - -Template.cineDialog.helpers({ - isPlaying() { - return viewportUtils.isPlaying(); - }, - - framerate() { - Session.get('UpdateCINE'); - return OHIF.viewer.cine.framesPerSecond.toFixed(1); - }, - - displaySetDisabled(isNext) { - Session.get('LayoutManagerUpdated'); - - // @TODO: Investigate why this is running while OHIF.viewerbase.layoutManager is undefined - if (!OHIF.viewerbase.layoutManager) { - return; - } - - return !OHIF.viewerbase.layoutManager.canMoveDisplaySets(isNext) ? 'disabled' : ''; - }, - - buttonDisabled() { - return viewportUtils.hasMultipleFrames(); - }, - - getClassNames(baseClass) { - const style = OHIF.uiSettings.displayEchoUltrasoundWorkflow ? 'single' : 'double'; - return `${baseClass} ${style}-row-style`; - } - -}); diff --git a/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.styl b/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.styl deleted file mode 100644 index 053136afb..000000000 --- a/Packages/ohif-viewerbase/client/components/viewer/cineDialog/cineDialog.styl +++ /dev/null @@ -1,162 +0,0 @@ -@require '{ohif:viewerbase}/app' - -#cineDialog - theme('background', '$uiGrayDarkest', 0.85) - theme('color', '$textSecondaryColor') - filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.85)) - border: none - border-radius: 8px - cursor: move - padding: 0 - position: absolute - z-index: 1000 - - .button-close-container - theme('background', '$uiGrayDarkest') - border-radius(16px) - cursor: pointer - height: 32px - position: absolute - right: -8px - top: -10px - width: 32px - - .button-close - left: 50% - position: absolute - top: 50% - transform(translateX(-50%) translateY(-50%)) - - h5 - font-size: 20px - line-height: 35px - margin: 0 - - h5, label - font-weight: 400 - - .btn - theme('color', '$textSecondaryColor') - background-color: transparent - - &:hover - theme('color', '$hoverColor') - - &:active, &.active - theme('color', '$activeColor') - - &[disabled] - &:hover - color: inherit - &:active - theme('color', '$textSecondaryColor') - - .cine-navigation, .cine-controls, .cine-options - cursor: default - - .fps-section - input[type="range"] - background-color: transparent - border: 0 none - outline: 0 none - - &::-ms-tooltip - display: none - - .double-row-style - box-sizing: border-box - width: 290px - height: 80px - padding: 10px - top: 2% - left: 35% - - .cine-navigation - position: absolute - right: 16px - top: 10px - - .btn - padding: 0 4px - - i - font-size: 32px - line-height: 32px - - .cine-controls - left: 0px - - .cine-options - padding: 0px 0 - - .fps-section - width: 175px - float: left - - #fps - float: right - margin: 5px 20px 0 0 - - - .single-row-style - box-sizing: content-box - width: 425px - height: 45px - padding: 4px 8px - top: 2% - left: 35% - - .cine-navigation - float: right - overflow: hidden - padding-right: 12px - position: relative - - .btn - padding: 0 2px - margin: 0 0 0 2px - border: 0 none - &:first-of-type - margin-left: 0 - - i - font-size: 32px - line-height: 45px - - .cine-controls - position: relative - float: left - overflow: hidden - .btn - font-size: 22px - line-height: 45px - min-width: 28px - padding: 0 0px - margin: 0 4px - border: 0 none - - .cine-options - display: block - position: relative - width: 150px - float: left - overflow: hidden - padding: 0 - margin: 0 0 0 10px - - .fps-section - display: block - float: left - width: 80px - input[type="range"] - line-height: 45px - height: 45px - - #fps - display: block - width: 68px - float: left - padding: 0 - margin: 0 0 0 2px - text-align: center - line-height: 45px diff --git a/Packages/ohif-viewerbase/client/components/viewer/downloadDialog/downloadDialog.js b/Packages/ohif-viewerbase/client/components/viewer/downloadDialog/downloadDialog.js index b864dd433..3e97ffce0 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/downloadDialog/downloadDialog.js +++ b/Packages/ohif-viewerbase/client/components/viewer/downloadDialog/downloadDialog.js @@ -3,8 +3,8 @@ import { Tracker } from 'meteor/tracker'; import { ReactiveVar } from 'meteor/reactive-var'; import { Session } from 'meteor/session'; import $ from 'jquery'; -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; -import { OHIF } from 'meteor/ohif:core'; +//import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +import { OHIF } from 'ohif-core'; import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; OHIF.viewerbase.getImageDownloadDialogAnnotationTools = () => { diff --git a/Packages/ohif-viewerbase/client/components/viewer/layoutChooser/layoutChooser.js b/Packages/ohif-viewerbase/client/components/viewer/layoutChooser/layoutChooser.js index 892cf296c..e33338ea0 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/layoutChooser/layoutChooser.js +++ b/Packages/ohif-viewerbase/client/components/viewer/layoutChooser/layoutChooser.js @@ -1,6 +1,6 @@ import { Template } from 'meteor/templating'; import { Session } from 'meteor/session'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import 'meteor/ohif:viewerbase'; import { viewportUtils } from '../../../lib/viewportUtils'; @@ -41,12 +41,12 @@ Template.layoutChooser.onRendered(() => { // Refresh layout chooser highlighting based on current viewports state instance.refreshHighlights = () => { // Stop here if layoutManager is not defined yet - if (!OHIF.viewerbase.layoutManager) { + if (!OHIF.viewer.layoutManager) { return; } // Get the layout rows and columns amount - const info = OHIF.viewerbase.layoutManager.layoutProps; + const info = OHIF.viewer.layoutManager.layoutProps; // get the limiter cell const cell = instance.$('tr').eq(info.rows - 1).children().eq(info.columns - 1); @@ -57,8 +57,7 @@ Template.layoutChooser.onRendered(() => { instance.autorun(() => { // Run this computation every time the viewer layout is changed - Session.get('LayoutManagerUpdated'); - + instance.refreshHighlights(); }); }); @@ -83,9 +82,9 @@ Template.layoutChooser.events({ columns: columnIndex + 1 }; - OHIF.viewerbase.layoutManager.layoutTemplateName = 'gridLayout'; - OHIF.viewerbase.layoutManager.layoutProps = layoutProps; - OHIF.viewerbase.layoutManager.updateViewports(); + OHIF.viewer.layoutManager.layoutTemplateName = 'gridLayout'; + OHIF.viewer.layoutManager.layoutProps = layoutProps; + OHIF.viewer.layoutManager.updateViewports(); const $dropdown = instance.$('.layoutChooser'); viewportUtils.toggleDialog($dropdown); diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js index fe1976ec0..4ec178651 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js +++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.seriesQuickSwitch.onCreated(() => { const instance = Template.instance(); @@ -11,7 +11,7 @@ Template.seriesQuickSwitch.onCreated(() => { // Gets the viewport data for the given viewport index instance.getViewportData = viewportIndex => { - const layoutManager = OHIF.viewerbase.layoutManager; + const layoutManager = OHIF.viewer.layoutManager; return layoutManager && layoutManager.viewportData && layoutManager.viewportData[viewportIndex]; }; @@ -22,7 +22,7 @@ Template.seriesQuickSwitch.onCreated(() => { instance.lastStudy = {}; instance.autorun(() => { - OHIF.viewerbase.layoutManager.observer.depend(); + OHIF.viewer.layoutManager.observer.depend(); const viewportData = instance.getViewportData(viewportIndex); @@ -68,9 +68,9 @@ Template.seriesQuickSwitch.helpers({ seriesItems() { const instance = Template.instance(); - OHIF.viewerbase.layoutManager.observer.depend(); + OHIF.viewer.layoutManager.observer.depend(); const { viewportIndex } = instance.data; - const viewportData = OHIF.viewerbase.layoutManager.viewportData[viewportIndex]; + const viewportData = OHIF.viewer.layoutManager.viewportData[viewportIndex]; const study = instance.currentStudy.get(); const seriesItems = []; diff --git a/Packages/ohif-viewerbase/client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.js b/Packages/ohif-viewerbase/client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.js index 93b724000..3de62b7d2 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.js +++ b/Packages/ohif-viewerbase/client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.js @@ -3,7 +3,7 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Session } from 'meteor/session'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.studySeriesQuickSwitch.onCreated(() => { const instance = Template.instance(); @@ -13,7 +13,7 @@ Template.studySeriesQuickSwitch.onCreated(() => { // Gets the viewport data for the given viewport index instance.getViewportData = viewportIndex => { - const layoutManager = OHIF.viewerbase.layoutManager; + const layoutManager = OHIF.viewer.layoutManager; return layoutManager && layoutManager.viewportData && layoutManager.viewportData[viewportIndex]; }; @@ -24,7 +24,6 @@ Template.studySeriesQuickSwitch.onCreated(() => { instance.lastStudy = {}; instance.autorun(() => { - Session.get('LayoutManagerUpdated'); const viewportData = instance.getViewportData(viewportIndex); diff --git a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepoint.js b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepoint.js index eab6cf0b5..e690885e6 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepoint.js +++ b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepoint.js @@ -1,5 +1,5 @@ import { Template } from 'meteor/templating'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.studyTimepoint.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js index c09a3217d..8e3136fbe 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js +++ b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js @@ -2,7 +2,7 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { OHIFError } from '../../../lib/classes/OHIFError'; Template.studyTimepointBrowser.onCreated(() => { diff --git a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js index b841fc376..28305b2c1 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js +++ b/Packages/ohif-viewerbase/client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js @@ -3,7 +3,7 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import _ from 'underscore'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.studyTimepointStudy.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/components/viewer/toolbarSectionButton/toolbarSectionButton.js b/Packages/ohif-viewerbase/client/components/viewer/toolbarSectionButton/toolbarSectionButton.js index a3e39de8c..7c0e52255 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/toolbarSectionButton/toolbarSectionButton.js +++ b/Packages/ohif-viewerbase/client/components/viewer/toolbarSectionButton/toolbarSectionButton.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { Template } from 'meteor/templating'; import { Session } from 'meteor/session'; import _ from 'underscore'; @@ -101,7 +101,6 @@ Template.toolbarSectionButton.helpers({ disableButton() { window.store.getState().viewports.activeViewport; - Session.get('LayoutManagerUpdated'); const instance = Template.instance(); const isCommandDisabled = OHIF.commands.isDisabled(instance.data.id); const isFunctionDisabled = instance.data.disableFunction && instance.data.disableFunction(); diff --git a/Packages/ohif-viewerbase/client/components/viewer/windowLevelPresets/form.js b/Packages/ohif-viewerbase/client/components/viewer/windowLevelPresets/form.js index e3ff85d65..b8e3081b3 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/windowLevelPresets/form.js +++ b/Packages/ohif-viewerbase/client/components/viewer/windowLevelPresets/form.js @@ -1,6 +1,6 @@ import { Template } from 'meteor/templating'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; Template.windowLevelPresetsForm.onCreated(() => { const instance = Template.instance(); diff --git a/Packages/ohif-viewerbase/client/index.js b/Packages/ohif-viewerbase/client/index.js index 6932872a5..30516c160 100644 --- a/Packages/ohif-viewerbase/client/index.js +++ b/Packages/ohif-viewerbase/client/index.js @@ -177,7 +177,4 @@ Viewerbase.helpers = helpers; // sopClassDictionary import { sopClassDictionary } from './lib/sopClassDictionary'; -Viewerbase.sopClassDictionary = sopClassDictionary; - -import redux from './lib/redux/'; -Viewerbase.redux = redux; +Viewerbase.sopClassDictionary = sopClassDictionary; \ No newline at end of file diff --git a/Packages/ohif-viewerbase/client/lib/StackManager.js b/Packages/ohif-viewerbase/client/lib/StackManager.js index 85d77a388..2dccef36e 100644 --- a/Packages/ohif-viewerbase/client/lib/StackManager.js +++ b/Packages/ohif-viewerbase/client/lib/StackManager.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { getImageId } from './getImageId'; let stackMap = {}; diff --git a/Packages/ohif-viewerbase/client/lib/WLPresets.js b/Packages/ohif-viewerbase/client/lib/WLPresets.js index dd8dee09e..4f23bb7d3 100644 --- a/Packages/ohif-viewerbase/client/lib/WLPresets.js +++ b/Packages/ohif-viewerbase/client/lib/WLPresets.js @@ -2,7 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { Session } from 'meteor/session'; import { Tracker } from 'meteor/tracker'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone } from 'meteor/ohif:cornerstone'; import { viewportUtils } from './viewportUtils'; diff --git a/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js b/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js index e83eec11f..616414f0e 100644 --- a/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js +++ b/Packages/ohif-viewerbase/client/lib/classes/LayoutManager.js @@ -6,7 +6,7 @@ import { Template } from 'meteor/templating'; import _ from 'underscore'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import viewerComponents from '../../components/viewer/index.js'; @@ -44,17 +44,6 @@ export class LayoutManager { }; this.isZoomed = false; - - const updateSessionFn = () => { - const random = Math.random(); - Session.set('LayoutManagerUpdated', random); - this.observer.changed(); - }; - - this.updateSession = _.throttle(updateSessionFn, 300, { - leading: true, - trailing: false - }); } /** @@ -183,8 +172,6 @@ export class LayoutManager { const component = viewerComponents.GridLayout; this.setContents(component, data); - this.updateSession(); - this.isZoomed = false; } @@ -228,8 +215,6 @@ export class LayoutManager { }; this.setContents(component, data); - - this.updateSession(); } /** @@ -264,8 +249,6 @@ export class LayoutManager { this.isZoomed = true; this.zoomedViewportIndex = viewportIndex; this.viewportData = data.viewportData; - - this.updateSession(); } /** diff --git a/Packages/ohif-viewerbase/client/lib/createStacks.js b/Packages/ohif-viewerbase/client/lib/createStacks.js index 6d1dbf886..6412b4245 100644 --- a/Packages/ohif-viewerbase/client/lib/createStacks.js +++ b/Packages/ohif-viewerbase/client/lib/createStacks.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { isImage } from './isImage'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; const isMultiFrame = instance => { // NumberOfFrames (0028,0008) diff --git a/Packages/ohif-viewerbase/client/lib/debugReactivity.js b/Packages/ohif-viewerbase/client/lib/debugReactivity.js deleted file mode 100644 index 25e1e6d79..000000000 --- a/Packages/ohif-viewerbase/client/lib/debugReactivity.js +++ /dev/null @@ -1,70 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -Meteor.startup(function() { - var debug = false; - - if (debug === true) { - // http://www.meteorpedia.com/read/Debugging_Reactivity - - Meteor.autorun(function(computation) { - computation.onInvalidate(function() { - console.trace(); - }); - }); - - var wrappedFind = Meteor.Collection.prototype.find; - - Meteor.Collection.prototype.find = function() { - var cursor = wrappedFind.apply(this, arguments); - var collectionName = this._name || this._debugName; - - /*cursor.observeChanges({ - added: function(id, fields) { - console.log(collectionName, 'added', id, fields); - }, - changed: function(id, fields) { - console.log(collectionName, 'changed', id, fields); - }, - movedBefore: function(id, before) { - console.log(collectionName, 'movedBefore', id, before); - }, - removed: function(id) { - console.log(collectionName, 'removed', id); - } - });*/ - - cursor.observe({ - added: function(data) { - console.log(collectionName, 'added', data); - }, - changed: function(data) { - console.log(collectionName, 'changed', data); - }, - removed: function(data) { - console.log(collectionName, 'removed', data); - } - }); - - return cursor; - }; - - function logRenders() { - Object.keys(Template).forEach(function(name) { - if (name.indexOf('_') > -1) { - return; - } - - var template = Template[name]; - var oldRender = template.rendered; - var counter = 0; - - template.rendered = function() { - console.log(name, 'render count: ', ++counter); - oldRender && oldRender.apply(this, arguments); - }; - }); - } - - logRenders(); - } -}); diff --git a/Packages/ohif-viewerbase/client/lib/displayReferenceLines.js b/Packages/ohif-viewerbase/client/lib/displayReferenceLines.js index f8cc43305..1f8f4ba10 100644 --- a/Packages/ohif-viewerbase/client/lib/displayReferenceLines.js +++ b/Packages/ohif-viewerbase/client/lib/displayReferenceLines.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; /** diff --git a/Packages/ohif-viewerbase/client/lib/getImageIdForImagePath.js b/Packages/ohif-viewerbase/client/lib/getImageIdForImagePath.js index 4c02c7cbd..33bde2eff 100644 --- a/Packages/ohif-viewerbase/client/lib/getImageIdForImagePath.js +++ b/Packages/ohif-viewerbase/client/lib/getImageIdForImagePath.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Obtain an imageId for the given imagePath diff --git a/Packages/ohif-viewerbase/client/lib/getStudyMetadata.js b/Packages/ohif-viewerbase/client/lib/getStudyMetadata.js index 5419bc179..9ef896f26 100644 --- a/Packages/ohif-viewerbase/client/lib/getStudyMetadata.js +++ b/Packages/ohif-viewerbase/client/lib/getStudyMetadata.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; const getStudyMetadata = study => { let studyMetadata = study; diff --git a/Packages/ohif-viewerbase/client/lib/getWADORSImageId.js b/Packages/ohif-viewerbase/client/lib/getWADORSImageId.js index 646a0358d..af95cca3c 100644 --- a/Packages/ohif-viewerbase/client/lib/getWADORSImageId.js +++ b/Packages/ohif-viewerbase/client/lib/getWADORSImageId.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; function getWADORSImageUrl(instance, frame) { let wadorsuri = instance.wadorsuri; diff --git a/Packages/ohif-viewerbase/client/lib/helpers/capitalizeFirstLetter.js b/Packages/ohif-viewerbase/client/lib/helpers/capitalizeFirstLetter.js deleted file mode 100644 index 3e7378898..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/capitalizeFirstLetter.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -/** - * A global Blaze UI helper to capitalizes the first letter of an input String - * - * Credit to: - * - * http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript - */ -Blaze.registerHelper('capitalizeFirstLetter', function (context) { - if (!context) { - return; - } - - return context.charAt(0).toUpperCase() + context.slice(1); -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/formatDA.js b/Packages/ohif-viewerbase/client/lib/helpers/formatDA.js deleted file mode 100644 index 7d4b4aa77..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/formatDA.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import moment from 'moment'; - -/** - * A global Blaze UI helper function to format DICOM Dates using the Moment library - */ - -const formatDA = (context, format, options) => { - if (!context) { - return undefined; - } - var dateAsMoment = moment(context, "YYYYMMDD"); - var strFormat = "MMM D, YYYY"; - if (options) { - strFormat = format; - } - return dateAsMoment.format(strFormat); -}; - -// Check if global helper already exists to not override it -if (!Blaze._getGlobalHelper('formatDA')) { - Blaze.registerHelper('formatDA', formatDA); -} - -export { formatDA }; diff --git a/Packages/ohif-viewerbase/client/lib/helpers/formatJSDate.js b/Packages/ohif-viewerbase/client/lib/helpers/formatJSDate.js deleted file mode 100644 index 378e5681b..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/formatJSDate.js +++ /dev/null @@ -1,19 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import moment from 'moment'; - -/** - * A global Blaze UI helper function to format JavaScript Dates using the Moment library - */ -Blaze.registerHelper('formatJSDate', function(context, format, options) { - if (!context) { - return; - } - - var dateAsMoment = moment(new Date(context)); - var strFormat = 'MMM D, YYYY'; - if (options) { - strFormat = format; - } - - return dateAsMoment.format(strFormat); -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/formatNumberPrecision.js b/Packages/ohif-viewerbase/client/lib/helpers/formatNumberPrecision.js deleted file mode 100644 index ba46bbe8b..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/formatNumberPrecision.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -function formatNumberPrecision(number, precision) { - if (number !== null) { - return parseFloat(number).toFixed(precision); - } -} - -/** - * A global Blaze UI helper to format a float value to a specified precision - */ -Blaze.registerHelper('formatNumberPrecision', formatNumberPrecision); - -export default formatNumberPrecision; diff --git a/Packages/ohif-viewerbase/client/lib/helpers/formatPN.js b/Packages/ohif-viewerbase/client/lib/helpers/formatPN.js deleted file mode 100644 index e7ee7c7b9..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/formatPN.js +++ /dev/null @@ -1,30 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -/** - * Formats a patient name for display purposes - */ -const formatPN = context => { - if (!context) { - return; - } - - // Convert the first ^ to a ', '. String.replace() only affects - // the first appearance of the character. - const commaBetweenFirstAndLast = context.replace('^', ', '); - - // Replace any remaining '^' characters with spaces - const cleaned = commaBetweenFirstAndLast.replace(/\^/g, ' '); - - // Trim any extraneous whitespace - return cleaned.trim(); -}; - -/** - * A global Blaze UI helper to format a patient name for display purposes - */ - -// Check if global helper already exists to not override it -if (!Blaze._getGlobalHelper('formatPN')) { - Blaze.registerHelper('formatPN', formatPN); -} - -export { formatPN }; diff --git a/Packages/ohif-viewerbase/client/lib/helpers/formatTM.js b/Packages/ohif-viewerbase/client/lib/helpers/formatTM.js deleted file mode 100644 index f0dbd8cf1..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/formatTM.js +++ /dev/null @@ -1,35 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import moment from 'moment'; - -/** - * A global Blaze UI helper to format a DICOM Time for display using the Moment library - */ - -const formatTM = (context, options) => { - if (!context) { - return; - } - - // DICOM Time is stored as HHmmss.SSS, where: - // HH 24 hour time: - // m mm 0..59 Minutes - // s ss 0..59 Seconds - // S SS SSS 0..999 Fractional seconds - // - // See MomentJS: http://momentjs.com/docs/#/parsing/string-format/ - var dateTime = moment(context, 'HHmmss.SSS'); - - var format = "HH:mm:ss"; - if (options && options.format) { - format = options.format; - } - - return dateTime.format(format); -}; - -// Check if global helper already exists to not override it -if (!Blaze._getGlobalHelper('formatTM')) { - Blaze.registerHelper('formatTM', formatTM); -} - -export { formatTM }; diff --git a/Packages/ohif-viewerbase/client/lib/helpers/getUsername.js b/Packages/ohif-viewerbase/client/lib/helpers/getUsername.js deleted file mode 100644 index 6140398c6..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/getUsername.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Blaze } from 'meteor/blaze'; - -/** - * Helper for retrieving username given userId - */ -Blaze.registerHelper('getUsername', function(userId) { - var user = Meteor.users.findOne({ - userId: userId - }); - - if (user && user.name) { - return user.name; - } -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/ifTypeIs.js b/Packages/ohif-viewerbase/client/lib/helpers/ifTypeIs.js deleted file mode 100644 index 8637da5e8..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/ifTypeIs.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -/** - * Helper for checking datatype of a variable - */ -Blaze.registerHelper('ifTypeIs', function(value, match, attributeName) { - if (typeof(value) === match) { - return attributeName; - } - - return ''; -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/inc.js b/Packages/ohif-viewerbase/client/lib/helpers/inc.js deleted file mode 100644 index 00330094b..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/inc.js +++ /dev/null @@ -1,5 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -Blaze.registerHelper('inc', function(value) { - return parseInt(value) + 1; -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/index.js b/Packages/ohif-viewerbase/client/lib/helpers/index.js deleted file mode 100644 index 3761040cc..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/index.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Helpers with exposed symbols... - */ - -import { isTouchDevice } from './isTouchDevice'; -import { formatPN } from './formatPN'; -import { formatDA } from './formatDA'; -import { formatTM } from './formatTM'; -import isValidNumber from './isValidNumber'; - -/** - * Helpers with side effects only... - */ - -import './formatJSDate'; -import './jsDateFromNow'; -import formatNumberPrecision from './formatNumberPrecision'; -import './inc'; -import './isDisplaySetActive'; -import './getUsername'; -import './capitalizeFirstLetter'; -import './objectToPairs'; -import './objectEach'; -import './ifTypeIs'; -import './prettyPrintStringify'; -import './sorting'; -import './studyThumbnails'; - -/** - * Exposed interface... - */ - -const helpers = { - isTouchDevice, - formatPN, - formatDA, - formatTM, - formatNumberPrecision, - isValidNumber, -}; - -export { helpers }; diff --git a/Packages/ohif-viewerbase/client/lib/helpers/isDisplaySetActive.js b/Packages/ohif-viewerbase/client/lib/helpers/isDisplaySetActive.js deleted file mode 100644 index 119c282b7..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/isDisplaySetActive.js +++ /dev/null @@ -1,57 +0,0 @@ -import { Template } from 'meteor/templating'; -import { Session } from 'meteor/session'; -import $ from 'jquery'; -import _ from 'underscore'; - -import { OHIF } from 'meteor/ohif:core'; -import 'meteor/ohif:viewerbase'; - -/** - * Boolean helper to identify if a series instance is active in some viewport - */ -Template.registerHelper('isDisplaySetActive', (displaySetInstanceUid, viewportIndex) => { - // Run this computation every time the viewports are updated - Session.get('LayoutManagerUpdated'); - - // Stop here if layoutManager is not defined yet - if (!OHIF.viewerbase.layoutManager) { - return; - } - - // Check if the display set is current visible in any of the layout - // manager's displayed viewports. Note that we have to check the - // onscreen number of viewports here, since the layout manager will - // keep the viewport data of old viewports, even after the layout is changed. - // - // This behaviour is intentional. If the user displays four viewports, then assigns - // display sets to them, and then switches to / from another layout configuration, - // we don't want them to lose their specified viewports. - let result = false; - if (_.isUndefined(viewportIndex)) { - // Get the number of viewports that are currently displayed - // (Note, viewportData may have more entries!) - const currentNumberOfViewports = OHIF.viewerbase.layoutManager.getNumberOfViewports(); - - // Loop through the viewport data up until the currently displayed - // number of viewports - const viewportData = OHIF.viewerbase.layoutManager.viewportData; - for (let i = 0; i < currentNumberOfViewports; i++) { - const data = viewportData[i]; - - // If the display set is displayed in this viewport and is active, stop here - if (data && data.displaySetInstanceUid === displaySetInstanceUid) { - result = true; - break; - } - } - } else { - const data = OHIF.viewerbase.layoutManager.viewportData[viewportIndex]; - - // If the display set is displayed in this viewport, stop here - if (data && data.displaySetInstanceUid === displaySetInstanceUid) { - result = true; - } - } - - return result; -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/isTouchDevice.js b/Packages/ohif-viewerbase/client/lib/helpers/isTouchDevice.js deleted file mode 100644 index 4711f6137..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/isTouchDevice.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -/** - * Helper function to determine if the current client devices - * is touch-capable. This can be used to modify certain aspects of the UI. - * - * The check may not work on all devices! - * - * @returns {boolean} true if the client device is touch-capable, false otherwise - */ -const isTouchDevice = () => { - return (('ontouchstart' in window) || - (navigator.MaxTouchPoints > 0) || - (navigator.msMaxTouchPoints > 0)); -}; - -/** - * Blaze helper for checking if the current device is touch capable - * - * @returns {boolean} true if the client device is touch-capable, false otherwise - */ -Blaze.registerHelper('isTouchDevice', isTouchDevice); - -export { isTouchDevice }; diff --git a/Packages/ohif-viewerbase/client/lib/helpers/isValidNumber.js b/Packages/ohif-viewerbase/client/lib/helpers/isValidNumber.js deleted file mode 100644 index df8947fff..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/isValidNumber.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function isValidNumber(value) { - return typeof value === 'number' && !isNaN(value); -} diff --git a/Packages/ohif-viewerbase/client/lib/helpers/jsDateFromNow.js b/Packages/ohif-viewerbase/client/lib/helpers/jsDateFromNow.js deleted file mode 100644 index 5573c53d2..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/jsDateFromNow.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import { Session } from 'meteor/session'; -import moment from 'moment'; - -/** - * A global Blaze UI helper function to format JavaScript Dates using the Moment library - */ -Blaze.registerHelper('jsDateFromNow', function(context, format, options) { - if (!context) { - return; - } - - Session.get('timeAgoVariable'); - - var dateAsMoment = moment(new Date(context)); - return dateAsMoment.fromNow(); -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/objectEach.js b/Packages/ohif-viewerbase/client/lib/helpers/objectEach.js deleted file mode 100644 index 3f907d126..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/objectEach.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import _ from 'underscore'; - -Blaze.registerHelper('objectEach', function(object) { - // http://stackoverflow.com/questions/30234732/how-to-print-key-and-values-in-meteor-template - return _.map(object, function(value, key) { - return _.extend({key: key}, value); - }); -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/objectToPairs.js b/Packages/ohif-viewerbase/client/lib/helpers/objectToPairs.js deleted file mode 100644 index beef32c2f..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/objectToPairs.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import _ from 'underscore'; - -Blaze.registerHelper('objectToPairs', function(object) { - // http://stackoverflow.com/questions/30234732/how-to-print-key-and-values-in-meteor-template - return _.map(object, function(value, key) { - return { - key: key, - value: value - }; - }); -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/prettyPrintStringify.js b/Packages/ohif-viewerbase/client/lib/helpers/prettyPrintStringify.js deleted file mode 100644 index b2a65229b..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/prettyPrintStringify.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -/** - * A global Blaze UI helper to Stringify a JavaScript object - * - * Credit to: - * - * http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript - */ -Blaze.registerHelper('prettyPrintStringify', function(context) { - if (!context) { - return; - } - - var string = JSON.stringify(context, null, 2); - string = string.replace(/['"]+/g, ''); - string = string.replace('{', ''); - string = string.replace('}', ''); - string = string.replace(',', '\n'); - return string; -}); diff --git a/Packages/ohif-viewerbase/client/lib/helpers/sorting.js b/Packages/ohif-viewerbase/client/lib/helpers/sorting.js deleted file mode 100644 index 3e5d59a13..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/sorting.js +++ /dev/null @@ -1,57 +0,0 @@ -import { Template } from 'meteor/templating'; -import _ from 'underscore'; - -/** - * Global Blaze UI helper to sort array elements - * by an array element's property (property) or deep object property (property.childProperty) - * Sorts ascending as default - */ -Template.registerHelper('sort', (array, sortBy, sortType) => { - if (!sortBy) { - return array; - } - - // To keep the order for the same values of the field which is used to sort: - // 1. Group the array by the field - // 2. Sort the grouped array - // 3. Ungroup the sorted array - - const groupedArray = _.groupBy(array, (element) => { - if (sortBy) { - var groupingElement = getKeyValue(element, sortBy); - if (groupingElement) { - return groupingElement; - } - } - return element; - }); - - const sortedArray = _.sortBy(groupedArray, (element) => { - if (sortBy) { - var sortingElement = getKeyValue(element[0], sortBy); - if (sortingElement) { - return sortingElement; - } - } - return element; - }); - - if (sortType === 'desc') { - return _.flatten(sortedArray.reverse(), true); - } - - return _.flatten(sortedArray, true); -}); - -function getKeyValue(object, keyPath) { - keyPath = keyPath.split('.'); - for (var i = 0; i < keyPath.length; i++) { - if (object && _.has(object, keyPath[i])) { - object = object[keyPath[i]]; - } - else { - return undefined; - } - } - return object; -} diff --git a/Packages/ohif-viewerbase/client/lib/helpers/studyThumbnails.js b/Packages/ohif-viewerbase/client/lib/helpers/studyThumbnails.js deleted file mode 100644 index 27348c314..000000000 --- a/Packages/ohif-viewerbase/client/lib/helpers/studyThumbnails.js +++ /dev/null @@ -1,27 +0,0 @@ -import { Template } from 'meteor/templating'; -import _ from 'underscore'; - -/** - * A global Blaze UI helper to get the thumbnails for the given study - */ -Template.registerHelper('studyThumbnails', study => { - if (!study) { - return; - } - - // Find the study's stacks - const stacks = study.displaySets; - - // Defines the resulting thumbnails list - const thumbnails = []; - - // Iterate over the stacks and add one by one with its index - _.each(stacks, (stack, thumbnailIndex) => { - thumbnails.push({ - thumbnailIndex, - stack - }); - }); - - return thumbnails; -}); diff --git a/Packages/ohif-viewerbase/client/lib/hotkeyUtils.js b/Packages/ohif-viewerbase/client/lib/hotkeyUtils.js index cbf9c503f..9a3b52f76 100644 --- a/Packages/ohif-viewerbase/client/lib/hotkeyUtils.js +++ b/Packages/ohif-viewerbase/client/lib/hotkeyUtils.js @@ -1,8 +1,7 @@ import { Meteor } from 'meteor/meteor'; -import { Session } from 'meteor/session'; import $ from 'jquery'; import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { toolManager } from './toolManager'; import { switchToImageRelative } from './switchToImageRelative'; import { switchToImageByIndex } from './switchToImageByIndex'; @@ -163,10 +162,10 @@ Meteor.startup(function() { // Check if display sets can be moved const canMoveDisplaySets = isNext => { - if (!OHIF.viewerbase.layoutManager) { + if (!OHIF.viewer.layoutManager) { return false; } else { - return OHIF.viewerbase.layoutManager.canMoveDisplaySets(isNext); + return OHIF.viewer.layoutManager.canMoveDisplaySets(isNext); } }; @@ -190,12 +189,12 @@ Meteor.startup(function() { }, previousDisplaySet: { name: 'Previous Series', - action: () => OHIF.viewerbase.layoutManager.moveDisplaySets(false), + action: () => OHIF.viewer.layoutManager.moveDisplaySets(false), disabled: () => !canMoveDisplaySets(false) }, nextDisplaySet: { name: 'Next Series', - action: () => OHIF.viewerbase.layoutManager.moveDisplaySets(true), + action: () => OHIF.viewer.layoutManager.moveDisplaySets(true), disabled: () => !canMoveDisplaySets(true) }, nextPanel: { diff --git a/Packages/ohif-viewerbase/client/lib/panelNavigation.js b/Packages/ohif-viewerbase/client/lib/panelNavigation.js index 3706524b4..ccf7f693a 100644 --- a/Packages/ohif-viewerbase/client/lib/panelNavigation.js +++ b/Packages/ohif-viewerbase/client/lib/panelNavigation.js @@ -1,6 +1,6 @@ import { Session } from 'meteor/session'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { setActiveViewport } from './setActiveViewport'; const loadPreviousActivePanel = () => { diff --git a/Packages/ohif-viewerbase/client/lib/prepareViewerData.js b/Packages/ohif-viewerbase/client/lib/prepareViewerData.js index f5437e7b3..b6da439f0 100644 --- a/Packages/ohif-viewerbase/client/lib/prepareViewerData.js +++ b/Packages/ohif-viewerbase/client/lib/prepareViewerData.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Prepare the studies data to render the viewer template diff --git a/Packages/ohif-viewerbase/client/lib/redux/actions.js b/Packages/ohif-viewerbase/client/lib/redux/actions.js deleted file mode 100644 index 4ab017db9..000000000 --- a/Packages/ohif-viewerbase/client/lib/redux/actions.js +++ /dev/null @@ -1,9 +0,0 @@ -export const setToolActive = tool => ({ - type: 'SET_TOOL_ACTIVE', - tool -}); - -export const setViewportActive = viewportIndex => ({ - type: 'SET_VIEWPORT_ACTIVE', - viewportIndex -}); diff --git a/Packages/ohif-viewerbase/client/lib/redux/index.js b/Packages/ohif-viewerbase/client/lib/redux/index.js deleted file mode 100644 index 406e27d3b..000000000 --- a/Packages/ohif-viewerbase/client/lib/redux/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import './actions.js'; -import combinedReducer from './reducers'; - -const redux = { - combinedReducer -}; - -export default redux; diff --git a/Packages/ohif-viewerbase/client/lib/redux/reducers/index.js b/Packages/ohif-viewerbase/client/lib/redux/reducers/index.js deleted file mode 100644 index 68f7ae11c..000000000 --- a/Packages/ohif-viewerbase/client/lib/redux/reducers/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { combineReducers } from 'redux'; -import tools from './tools.js'; -import viewports from './viewports.js'; - -const combinedReducer = combineReducers({ - tools, - viewports -}); - -export default combinedReducer; diff --git a/Packages/ohif-viewerbase/client/lib/redux/reducers/tools.js b/Packages/ohif-viewerbase/client/lib/redux/reducers/tools.js deleted file mode 100644 index 626801442..000000000 --- a/Packages/ohif-viewerbase/client/lib/redux/reducers/tools.js +++ /dev/null @@ -1,101 +0,0 @@ -const defaultButtons = [ - { - command: 'Pan', - type: 'tool', - text: 'Pan', - svgUrl: '/icons.svg#icon-tools-pan', - active: false - }, - { - command: 'Zoom', - type: 'tool', - text: 'Zoom', - svgUrl: '/icons.svg#icon-tools-zoom', - active: false - }, - { - command: 'Bidirectional', - type: 'tool', - text: 'Bidirectional', - svgUrl: '/icons.svg#icon-tools-measure-target', - active: false - }, - { - command: 'StackScroll', - type: 'tool', - text: 'Stack Scroll', - svgUrl: '/icons.svg#icon-tools-stack-scroll', - active: false - }, - { - command: 'reset', - type: 'command', - text: 'Reset', - svgUrl: '/icons.svg#icon-tools-reset', - active: false - }, - { - command: 'Wwwc', - type: 'tool', - text: 'Manual', - svgUrl: '/icons.svg#icon-tools-levels', - active: true - }, - { - command: 'setWLPresetSoftTissue', - type: 'command', - text: 'Soft Tissue', - svgUrl: '/icons.svg#icon-wl-soft-tissue', - active: false - }, - { - command: 'setWLPresetLung', - type: 'command', - text: 'Lung', - svgUrl: '/icons.svg#icon-wl-lung', - active: false - }, - { - command: 'setWLPresetLiver', - type: 'command', - text: 'Liver', - svgUrl: '/icons.svg#icon-wl-liver', - active: false - }, - { - command: 'setWLPresetBrain', - type: 'command', - text: 'Brain', - svgUrl: '/icons.svg#icon-wl-brain', - active: false - } -]; - -const tools = (state = { buttons: defaultButtons }, action) => { - switch (action.type) { - case 'SET_TOOL_ACTIVE': - const item = state.buttons.find(button => button.command === action.tool); - - let buttons = []; - - if (item.type === 'tool') { - buttons = state.buttons.map(button => { - if (button.command === action.tool) { - button.active = true; - } else if (button.type === 'tool') { - button.active = false; - } - - return button; - }); - } - - return { - buttons - }; - default: - return state; - } -}; - -export default tools; diff --git a/Packages/ohif-viewerbase/client/lib/redux/reducers/viewports.js b/Packages/ohif-viewerbase/client/lib/redux/reducers/viewports.js deleted file mode 100644 index 8b591c8bd..000000000 --- a/Packages/ohif-viewerbase/client/lib/redux/reducers/viewports.js +++ /dev/null @@ -1,15 +0,0 @@ -const defaultState = { - activeViewportIndex: 0 -} - -const viewports = (state = defaultState, action) => { - console.warn(action); - switch (action.type) { - case 'SET_VIEWPORT_ACTIVE': - return Object.assign({}, state, { activeViewportIndex: action.viewportIndex }); - default: - return state; - } -}; - -export default viewports; diff --git a/Packages/ohif-viewerbase/client/lib/renderViewer.js b/Packages/ohif-viewerbase/client/lib/renderViewer.js deleted file mode 100644 index 7276e46ae..000000000 --- a/Packages/ohif-viewerbase/client/lib/renderViewer.js +++ /dev/null @@ -1,33 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -/** - * Render the viewer with the given routing context and parameters - * - * @param {Context} context Context of the router - * @param {Object} params Parameters that will be used to prepare the viewer data - */ -export const renderViewer = (context, params, layoutTemplate='app') => { - // Wait until the viewer data is ready to render it - const promise = OHIF.viewerbase.prepareViewerData(params); - - // Show loading state while preparing the viewer data - OHIF.ui.showDialog('dialogLoading', { promise }); - - // Render the viewer when the data is ready - promise.then(({ studies, viewerData }) => { - OHIF.viewer.data = viewerData; - context.render(layoutTemplate, { - data: { - template: 'viewer', - studies - } - }); - }).catch(error => { - context.render(layoutTemplate, { - data: { - template: 'errorText', - error - } - }); - }); -}; diff --git a/Packages/ohif-viewerbase/client/lib/setActiveViewport.js b/Packages/ohif-viewerbase/client/lib/setActiveViewport.js index 518e96448..31a815db0 100644 --- a/Packages/ohif-viewerbase/client/lib/setActiveViewport.js +++ b/Packages/ohif-viewerbase/client/lib/setActiveViewport.js @@ -1,8 +1,5 @@ -import { Session } from 'meteor/session'; import $ from 'jquery'; -import { Random } from 'meteor/random'; - -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; //import { StudyPrefetcher } from './classes/StudyPrefetcher'; import { displayReferenceLines } from './displayReferenceLines'; diff --git a/Packages/ohif-viewerbase/client/lib/setMammogramViewportAlignment.js b/Packages/ohif-viewerbase/client/lib/setMammogramViewportAlignment.js index 2b8b352e7..28ffcc36d 100644 --- a/Packages/ohif-viewerbase/client/lib/setMammogramViewportAlignment.js +++ b/Packages/ohif-viewerbase/client/lib/setMammogramViewportAlignment.js @@ -1,7 +1,7 @@ import { Meteor } from 'meteor/meteor'; import $ from 'jquery'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { setInstanceClassDefaultViewportFunction } from './instanceClassSpecificViewport'; const setMammogramViewportAlignment = (series, enabledElement, imageId) => { diff --git a/Packages/ohif-viewerbase/client/lib/sortStudy.js b/Packages/ohif-viewerbase/client/lib/sortStudy.js index b697466b5..998541087 100644 --- a/Packages/ohif-viewerbase/client/lib/sortStudy.js +++ b/Packages/ohif-viewerbase/client/lib/sortStudy.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; const { OHIFError } = OHIF.classes; diff --git a/Packages/ohif-viewerbase/client/lib/textMarkerUtils.js b/Packages/ohif-viewerbase/client/lib/textMarkerUtils.js deleted file mode 100644 index 6efc29e8a..000000000 --- a/Packages/ohif-viewerbase/client/lib/textMarkerUtils.js +++ /dev/null @@ -1,87 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -import { toolManager } from './toolManager'; -import { viewportUtils } from './viewportUtils'; - -const changeTextCallback = (data, eventData, doneChangingTextCallback) => { - // This handles the double-click/long-press event on Spine text marker labels - const keyPressHandler = e => { - // If Enter or Esc are pressed, close the dialog - if (e.which === 13 || e.which === 27) { - closeHandler(); - } - }; - - // Deactivate textMarker tool after editing a spine label & if spine is not active tool - const deactivateAfterEdit = () => { - if (toolManager.getActiveTool() !== 'spine') { - const element = viewportUtils.getActiveViewportElement(); - cornerstoneTools.textMarker.deactivate(element, 1); - } - }; - - const closeHandler = () => { - dialog.get(0).close(); - doneChangingTextCallback(data, select.val()); - deactivateAfterEdit(); - // Reset the focus to the active viewport element - // This makes the mobile Safari keyboard close - const element = viewportUtils.getActiveViewportElement(); - $(element).focus(); - }; - - const dialog = $('#textMarkerRelabelDialog'); - - // Is necessary to use Blaze object to not create - // circular depencency with helper object (./helpers) - if (Blaze._globalHelpers.isTouchDevice()) { - // Center the dialog on screen on touch devices - dialog.css({ - top: 0, - left: 0, - right: 0, - bottom: 0, - margin: 'auto' - }); - dialog.find('.dialog.arrow').hide(); - } else { - // Place the dialog above the tool that is being relabelled - // TODO = Switch this to the tool coordinates, but put back into - // page coordinates. - dialog.css({ - top: eventData.currentPoints.page.y - dialog.outerHeight() - 20, - left: eventData.currentPoints.page.x - dialog.outerWidth() / 2 - }); - dialog.find('.dialog.arrow').show(); - } - - const select = dialog.find('.relabelSelect'); - const confirm = dialog.find('.relabelConfirm'); - const remove = dialog.find('.relabelRemove'); - - // If the remove button is clicked, delete this marker - remove.off('click'); - remove.on('click', () => { - dialog.get(0).close(); - doneChangingTextCallback(data, undefined, true); - deactivateAfterEdit(); - }); - - dialog.get(0).showModal(); - $('.relabelSelect').val(data.text).trigger('change'); //Update selector to the current - - confirm.off('click'); - confirm.on('click', () => { - closeHandler(); - }); - - // Use keydown since keypress doesn't handle ESC in Chrome - dialog.off('keydown'); - dialog.on('keydown', keyPressHandler); -}; - -const textMarkerUtils = { - changeTextCallback -}; - -export { textMarkerUtils }; \ No newline at end of file diff --git a/Packages/ohif-viewerbase/client/lib/toolManager.js b/Packages/ohif-viewerbase/client/lib/toolManager.js index e04f48c3b..3471f8963 100644 --- a/Packages/ohif-viewerbase/client/lib/toolManager.js +++ b/Packages/ohif-viewerbase/client/lib/toolManager.js @@ -1,5 +1,5 @@ import { Session } from 'meteor/session'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; let activeTool; @@ -168,9 +168,6 @@ export const toolManager = { cornerstoneTools.setToolActive(toolName, options); activeTool[button] = toolName; - - // Enable reactivity - Session.set('ToolManagerActiveToolUpdated', OHIF.utils.guid()); }, instantiateTools(element) { diff --git a/Packages/ohif-viewerbase/client/lib/unloadHandlers.js b/Packages/ohif-viewerbase/client/lib/unloadHandlers.js index f84f21b2c..8e9a2bb37 100644 --- a/Packages/ohif-viewerbase/client/lib/unloadHandlers.js +++ b/Packages/ohif-viewerbase/client/lib/unloadHandlers.js @@ -1,4 +1,4 @@ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; export const unloadHandlers = { beforeUnload: function(event) { diff --git a/Packages/ohif-viewerbase/client/lib/updateMetaDataManager.js b/Packages/ohif-viewerbase/client/lib/updateMetaDataManager.js index c3e4854fa..f166843fc 100644 --- a/Packages/ohif-viewerbase/client/lib/updateMetaDataManager.js +++ b/Packages/ohif-viewerbase/client/lib/updateMetaDataManager.js @@ -1,5 +1,5 @@ import _ from 'underscore'; -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { getWADORSImageId } from './getWADORSImageId'; function getRadiopharmaceuticalInfoMetaData(instance) { diff --git a/Packages/ohif-viewerbase/client/lib/viewportUtils.js b/Packages/ohif-viewerbase/client/lib/viewportUtils.js index 0c2878e0b..964a14d52 100644 --- a/Packages/ohif-viewerbase/client/lib/viewportUtils.js +++ b/Packages/ohif-viewerbase/client/lib/viewportUtils.js @@ -1,8 +1,7 @@ -import { Session } from 'meteor/session'; import $ from 'jquery'; import _ from 'underscore'; // Local Modules -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone'; import { updateOrientationMarkers } from './updateOrientationMarkers'; import { getInstanceClassDefaultViewport } from './instanceClassSpecificViewport'; @@ -211,9 +210,6 @@ const toggleCinePlay = () => { } else { cornerstoneTools.playClip(element); } - - // Update the UpdateCINE session property - Session.set('UpdateCINE', Math.random()); }; // Show/hide the CINE dialog @@ -221,7 +217,6 @@ const toggleCineDialog = () => { const dialog = document.getElementById('cineDialog'); toggleDialog(dialog, stopAllClips); - Session.set('UpdateCINE', Math.random()); }; const toggleDownloadDialog = () => { @@ -242,10 +237,6 @@ const isDownloadEnabled = () => { // Check if the clip is playing on the active viewport const isPlaying = () => { - // Create a dependency on LayoutManagerUpdated and UpdateCINE session - Session.get('UpdateCINE'); - Session.get('LayoutManagerUpdated'); - // Get the viewport element and its current playClip tool state const element = getActiveViewportElement(); // Empty Elements throws cornerstore exception @@ -275,7 +266,6 @@ const isPlaying = () => { const hasMultipleFrames = () => { // Its called everytime active viewport and/or layout change window.store.getState().viewports.activeViewport; - Session.get('LayoutManagerUpdated'); const activeViewport = getActiveViewportElement(); @@ -327,7 +317,6 @@ const isStackScrollLinkingDisabled = () => { // Its called everytime active viewport and/or layout change window.store.getState().viewports.activeViewport; - Session.get('LayoutManagerUpdated'); const synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer; if (synchronizer) { @@ -340,10 +329,6 @@ const isStackScrollLinkingDisabled = () => { const isStackScrollLinkingActive = () => { let isActive = true; - - // Its called everytime active viewport layout changes - Session.get('LayoutManagerUpdated'); - const synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer; if (!synchronizer) { return; } @@ -361,7 +346,7 @@ const isStackScrollLinkingActive = () => { // Create an event listener to update playing state when a clip stops playing window.addEventListener('cornerstonetoolsclipstopped', () => { - Session.set('UpdateCINE', Math.random()); + console.log('cornerstonetoolsclipstopped'); }); /** diff --git a/Packages/ohif-viewerbase/main.js b/Packages/ohif-viewerbase/main.js index 1d43f543d..593365c8e 100644 --- a/Packages/ohif-viewerbase/main.js +++ b/Packages/ohif-viewerbase/main.js @@ -20,14 +20,14 @@ import './client/'; // which is actually: import './client/index.js'; * * Which is equivalent to: * - * import { OHIF } from 'meteor/ohif:core'; + * import { OHIF } from 'ohif-core'; * import 'meteor/ohif:viewerbase'; * * The second (extended) format should be used when other OHIF packages are also to be used within * the current module. This makes it explicit that the following imports will populate their * respective namespaces within the to "OHIF" namespace. Example: * - * import { OHIF } from 'meteor/ohif:core'; + * import { OHIF } from 'ohif-core'; * import 'meteor/ohif:viewerbase'; * import 'meteor/ohif:hanging-protocols'; * [ ... ] diff --git a/Packages/ohif-viewerbase/namespace.js b/Packages/ohif-viewerbase/namespace.js index 21e3568a0..359d32d4f 100644 --- a/Packages/ohif-viewerbase/namespace.js +++ b/Packages/ohif-viewerbase/namespace.js @@ -2,7 +2,7 @@ * Import main dependency */ -import { OHIF } from 'meteor/ohif:core'; +import { OHIF } from 'ohif-core'; /** * Create Viewerbase namespace diff --git a/Packages/ohif-viewerbase/package.js b/Packages/ohif-viewerbase/package.js index bdca4ef7e..922de1d45 100644 --- a/Packages/ohif-viewerbase/package.js +++ b/Packages/ohif-viewerbase/package.js @@ -5,8 +5,8 @@ Package.describe({ }); Npm.depends({ - 'react-cornerstone-viewport': 'git://github.com:cornerstonejs/react-cornerstone-viewport.git', - 'react-viewerbase': 'git://github.com:OHIF/react-viewerbase.git', + 'react-cornerstone-viewport': '0.1.1', //'git://github.com:cornerstonejs/react-cornerstone-viewport.git', + 'react-viewerbase': 'git://github.com:OHIF/react-viewerbase.git', //'0.1.2', //'git://github.com:OHIF/react-viewerbase.git', hammerjs: '2.0.8', 'cornerstone-core': '2.2.8', 'cornerstone-tools': '3.0.0-b.1471', @@ -14,7 +14,8 @@ Npm.depends({ 'dicom-parser': '1.8.3', 'cornerstone-wado-image-loader': '2.2.3', 'react-redux': '6.0.0', - jquery: '3.3.1' + jquery: '3.3.1', + 'ohif-core': 'file:///Users/Erik/Projects/OHIF/ohif-core/' }); Package.onUse(function(api) { @@ -29,7 +30,6 @@ Package.onUse(function(api) { // OHIF dependencies api.use([ 'ohif:cornerstone', - 'ohif:core', 'ohif:themes' ]); @@ -92,15 +92,7 @@ Package.onUse(function(api) { api.addAssets(assets, 'client'); - api.addFiles('client/compatibility/dialogPolyfill.js', 'client', { - bare: true - }); - api.addFiles('client/compatibility/dialogPolyfill.styl', 'client'); - - // ---------- Components ---------- - // Basic components - api.addFiles('client/components/basic/layout/layout.html', 'client'); api.addFiles('client/components/basic/layout/layout.styl', 'client'); api.addFiles('client/components/basic/loadingText/loadingText.html', 'client'); api.addFiles('client/components/basic/loadingText/loadingText.styl', 'client'); @@ -126,10 +118,6 @@ Package.onUse(function(api) { api.addFiles('client/components/viewer/layoutChooser/layoutChooser.js', 'client'); api.addFiles('client/components/viewer/layoutChooser/layoutChooser.styl', 'client'); - api.addFiles('client/components/viewer/cineDialog/cineDialog.html', 'client'); - api.addFiles('client/components/viewer/cineDialog/cineDialog.js', 'client'); - api.addFiles('client/components/viewer/cineDialog/cineDialog.styl', 'client'); - api.addFiles('client/components/viewer/downloadDialog/downloadDialog.html', 'client'); api.addFiles('client/components/viewer/downloadDialog/downloadDialog.js', 'client'); api.addFiles('client/components/viewer/downloadDialog/downloadDialog.styl', 'client'); diff --git a/Packages/ohif-viewerbase/tests/client/components/viewer/gridLayout/gridLayout.tests.js b/Packages/ohif-viewerbase/tests/client/components/viewer/gridLayout/gridLayout.tests.js index 047df3c52..22208722b 100644 --- a/Packages/ohif-viewerbase/tests/client/components/viewer/gridLayout/gridLayout.tests.js +++ b/Packages/ohif-viewerbase/tests/client/components/viewer/gridLayout/gridLayout.tests.js @@ -1,8 +1,6 @@ import { Template } from 'meteor/templating'; import '../../../../../client/components/viewer/gridLayout/gridLayout.html'; import '../../../../../client/components/viewer/gridLayout/gridLayout.js'; -import { Session } from 'meteor/session'; -import { sinon } from 'meteor/practicalmeteor:sinon'; chai.should(); describe('GridLayout', function() { @@ -38,13 +36,11 @@ describe('GridLayout', function() { // describe('Testing getClass() Helper', function () { // it('should return priorDropdown', function () { - // Session.set('isPrior', true); // Template.priorDropdown.__helpers.get('getClass')() // .should.equal('priorDropdown'); // }); // it('should return empty string', function () { - // Session.set('isPrior', false); // Template.priorDropdown.__helpers.get('getClass')() // .should.equal(''); // }); diff --git a/Packages/ohif-viewerbase/tests/coverage/exportCoverageReport.js b/Packages/ohif-viewerbase/tests/coverage/exportCoverageReport.js index ef72d2199..1095e7f2c 100644 --- a/Packages/ohif-viewerbase/tests/coverage/exportCoverageReport.js +++ b/Packages/ohif-viewerbase/tests/coverage/exportCoverageReport.js @@ -1,4 +1,3 @@ -import { Meteor } from 'meteor/meteor'; import { chai } from 'meteor/practicalmeteor:chai'; import ReportService from 'meteor/lmieulet:meteor-coverage' diff --git a/StandaloneViewer/SampleClientOnlyBuild/00a3252f025c3b436cda09bf88f5ead9f975d4be.js b/StandaloneViewer/SampleClientOnlyBuild/00a3252f025c3b436cda09bf88f5ead9f975d4be.js index 063f1cad4..befd99ef1 100644 --- a/StandaloneViewer/SampleClientOnlyBuild/00a3252f025c3b436cda09bf88f5ead9f975d4be.js +++ b/StandaloneViewer/SampleClientOnlyBuild/00a3252f025c3b436cda09bf88f5ead9f975d4be.js @@ -14,7 +14,7 @@ !function(){var n=Package.meteor.Meteor,e=Package.meteor.global,r=Package.meteor.meteorEnv,t,o,i;t=function(n){"use strict";function e(n,e){return o(n)&&(p(A,n,e),i(k)&&k(B)),B}function r(n){this.id=n,this.children=[],this.childrenById={}}function t(n,e){return O.call(n,e)&&n[e]}function o(n){return"object"==typeof n&&null!==n}function i(n){return"function"==typeof n}function u(n){return"string"==typeof n}function c(n){return new Error("Cannot find module '"+n+"'")}function s(n){function e(e){var r=w(n,e);if(r)return l(r,n.module);var t=c(e);if(i(E))return E(e,n.module.id,t);throw t}return i(x)&&(e=x(e,n.module)),e.extensions=h(n).slice(0),e.resolve=function(e){var r=w(n,e);if(r)return r.module.id;var t=c(e);if(E&&i(E.resolve))return E.resolve(e,n.module.id,t);throw t},e}function f(n,e){var t=this;t.parent=e=e||null,t.module=new r(n),q[n]=t,t.contents=null,t.deps={}}function l(n,e){var r=n.module;if(!O.call(r,"exports")){var t=n.contents;if(!t){if(n.stub)return n.stub;throw c(r.id)}if(e){r.parent=e;var o=e.children;Array.isArray(o)&&o.push(r)}i(r.useNode)&&r.useNode()||t(r.require=r.require||s(n),r.exports=n.stub||{},r,n.module.id,n.parent.module.id),r.loaded=!0}var u=r.runSetters||r.runModuleSetters;return i(u)&&u.call(r),r.exports}function a(n){return n&&o(n.contents)}function d(n){return n&&null===n.contents}function p(n,e,r){Array.isArray(e)?(e.forEach(function(r){u(r)?n.deps[r]=n.module.id:i(r)?e=r:o(r)&&(n.stub=n.stub||{},v(r,function(e,r){n.stub[r]=e}))}),i(e)||(e=null)):i(e)||u(e)||o(e)||(e=null),e&&(n.contents=n.contents||(o(e)?{}:e),o(e)&&a(n)&&v(e,function(e,o){if(".."===o)i=n.parent;else{var i=t(n.contents,o);i||((i=n.contents[o]=new f(n.module.id.replace(/\/*$/,"/")+o,n)).options=r)}p(i,e,r)}))}function v(n,e,r){Object.keys(n).forEach(function(r){e.call(this,n[r],r)},r)}function h(n){return n.options&&n.options.extensions||P}function m(n,e,r){for(;n&&!a(n);)n=n.parent;if(!n||!e||"."===e)return n;if(".."===e)return n.parent;var o=t(n.contents,e);if(r&&(!o||a(o)))for(var i=0;i=0&&t.splice(n,1),t}function a(e,t){var n=!1;d.getESModule(e.exports)||(e.namespace.default=e.exports,n=!0),d.isObjectLike(e.exports)&&((void 0===t||t.indexOf("*")>=0)&&(t=Object.keys(e.exports)),t.forEach(function(t){g.call(e.getters,t)||n&&"default"===t||!g.call(e.exports,t)||d.copyKey(t,e.namespace,e.exports)}))}function s(e,t,n,r){function o(t,n){var r=n;return r!==r?r=h:void 0===r&&(r=m),e.last[t]!==r&&(e.last[t]=r,!0)}if("__esModule"!==t){var a=!1;if(void 0===e.last&&(e.last=Object.create(null),a=!0),"*"===t)for(var s=i(n),u=s.length,c=0;c0&&m.constant&&delete u[p]}}}function c(e,t){if("*"===t)return e.namespace;if(g.call(e.namespace,t))return e.namespace[t];var n=e.exports;if("default"===t&&!(d.getESModule(n)&&"default"in n))return n;if(null!=n)return n[t]}function l(){return Math.random().toString(36).replace("0.",++v+"$")}function f(e,t){var n=e.getters[t];try{var r=n();return++n.runCount,r}catch(e){}return p}var d=e("./utils.js"),p={},h={},m={},g=Object.prototype.hasOwnProperty,v=0,y=d.setPrototypeOf(r.prototype,null),b="function"==typeof WeakMap?new WeakMap:new function e(){var t=[],n=[];this.get=function(e){var r=t.indexOf(e);if(r>=0)return n[r]},this.set=function(e,r){var o=t.indexOf(e);o>=0?n[o]=r:(t.push(e),n.push(r))}};r.get=function(e){if(d.isObjectLike(e)){var t=b.get(e);if(void 0!==t)return t}return null},r.getOrCreate=function(e,t){var n=o(e);return d.isObject(t)&&(n.ownerModules[t.id]=t),n},y.addGetters=function(e,t){var n=i(e),r=n.length;t=!!t;for(var o=0;o=0)&&(e=Object.keys(this.getters));for(var t=e.length,n=0;n1&&void 0!==arguments[1]&&arguments[1],n=(0,r.getEnabledElement)(e);if(void 0===n.image)throw new Error("updateImage: image has not been loaded yet");(0,o.default)(n,t)};var r=n(0),o=function(e){return e&&e.__esModule?e:{default:e}}(n(2))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){e.needsRedraw=!0,t&&(e.invalid=!0)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){if(void 0===e)throw new Error("getDefaultViewport: parameter canvas must not be undefined");if(void 0===t)throw new Error("getDefaultViewport: parameter image must not be undefined");var n={scale:1,translation:{x:0,y:0},voi:{windowWidth:t.windowWidth,windowCenter:t.windowCenter},invert:t.invert,pixelReplication:!1,rotation:0,hflip:!1,vflip:!1,modalityLUT:t.modalityLUT,voiLUT:t.voiLUT},r=e.height/t.rows,o=e.width/t.columns;return n.scale=Math.min(o,r),n}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n,o,i,a){if(i||a)return(0,r.default)(e,t,n,o,i,a);if(void 0===e.cachedLut){var s=e.maxPixelValue-Math.min(e.minPixelValue,0)+1;e.cachedLut={},e.cachedLut.lutArray=new Uint8ClampedArray(s)}var u=e.cachedLut.lutArray,c=e.maxPixelValue,l=e.minPixelValue,f=e.slope,d=e.intercept,p=void 0,h=void 0,m=0;if(l<0&&(m=l),!0===o)for(var g=e.minPixelValue;g<=c;g++)p=g*f+d,h=255*((p-n)/t+.5),u[g+-m]=255-h;else for(var v=e.minPixelValue;v<=c;v++)p=v*f+d,h=255*((p-n)/t+.5),u[v+-m]=h;return u};var r=function(e){return e&&e.__esModule?e:{default:e}}(n(11))},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e,t){var n=e.renderingTools.colorRenderCanvas;n.width=t.width,n.height=t.height;var r=n.getContext("2d");r.fillStyle="white",r.fillRect(0,0,n.width,n.height);var o=r.getImageData(0,0,t.width,t.height);e.renderingTools.colorRenderCanvasContext=r,e.renderingTools.colorRenderCanvasData=o}function i(e,t){return void 0!==e.cachedLut&&e.cachedLut.windowCenter===t.voi.windowCenter&&e.cachedLut.windowWidth===t.voi.windowWidth&&e.cachedLut.invert===t.invert?e.cachedLut.lutArray:((0,c.default)(e,t.voi.windowWidth,t.voi.windowCenter,t.invert),e.cachedLut.windowWidth=t.voi.windowWidth,e.cachedLut.windowCenter=t.voi.windowCenter,e.cachedLut.invert=t.invert,e.cachedLut.lutArray)}function a(e,t){var n=e.renderingTools.lastRenderedImageId,r=e.renderingTools.lastRenderedViewport;return t.imageId!==n||r.windowCenter!==e.viewport.voi.windowCenter||r.windowWidth!==e.viewport.voi.windowWidth||r.invert!==e.viewport.invert||r.rotation!==e.viewport.rotation||r.hflip!==e.viewport.hflip||r.vflip!==e.viewport.vflip}function s(e,t,n){e.renderingTools.colorRenderCanvas||(e.renderingTools.colorRenderCanvas=document.createElement("canvas"));var r=e.renderingTools.colorRenderCanvas;if(255===e.viewport.voi.windowWidth&&128===e.viewport.voi.windowCenter&&!1===e.viewport.invert&&t.getCanvas&&t.getCanvas())return t.getCanvas();if(!1===a(e,t)&&!0!==n)return r;r.width===t.width&&r.height===t.height||o(e,t);var s=window.performance?performance.now():Date.now(),u=i(t,e.viewport);t.stats.lastLutGenerateTime=(window.performance?performance.now():Date.now())-s;var c=e.renderingTools.colorRenderCanvasData,f=e.renderingTools.colorRenderCanvasContext;return(0,l.default)(t,u,c.data),s=window.performance?performance.now():Date.now(),f.putImageData(c,0,0),t.stats.lastPutImageDataTime=(window.performance?performance.now():Date.now())-s,r}function u(e,t){if(void 0===e)throw new Error("drawImage: enabledElement parameter must not be undefined");var n=e.image;if(void 0===n)throw new Error("drawImage: image must be loaded before it can be drawn");var r=e.canvas.getContext("2d");r.setTransform(1,0,0,1,0,0),r.fillStyle="black",r.fillRect(0,0,e.canvas.width,e.canvas.height),!0===e.viewport.pixelReplication?(r.imageSmoothingEnabled=!1,r.mozImageSmoothingEnabled=!1):(r.imageSmoothingEnabled=!0,r.mozImageSmoothingEnabled=!0),r.save(),(0,f.default)(e,r),e.renderingTools||(e.renderingTools={});var o=void 0;o=e.options&&e.options.renderer&&"webgl"===e.options.renderer.toLowerCase()?d.default.renderer.render(e):s(e,n,t),r.drawImage(o,0,0,n.width,n.height,0,0,n.width,n.height),r.restore(),e.renderingTools.lastRenderedImageId=n.imageId;var i={};i.windowCenter=e.viewport.voi.windowCenter,i.windowWidth=e.viewport.voi.windowWidth,i.invert=e.viewport.invert,i.rotation=e.viewport.rotation,i.hflip=e.viewport.hflip,i.vflip=e.viewport.vflip,e.renderingTools.lastRenderedViewport=i}Object.defineProperty(t,"__esModule",{value:!0}),t.renderColorImage=u;var c=r(n(4)),l=r(n(13)),f=r(n(6)),d=r(n(7))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n){if(void 0===e)throw new Error("setToPixelCoordinateSystem: parameter enabledElement must not be undefined");if(void 0===t)throw new Error("setToPixelCoordinateSystem: parameter context must not be undefined");var o=(0,r.default)(e,n);t.setTransform(o.m[0],o.m[1],o.m[2],o.m[3],o.m[4],o.m[5])};var r=function(e){return e&&e.__esModule?e:{default:e}}(n(16))},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var o=n(54),i=r(n(28)),a=r(n(29));t.default={createProgramFromString:i.default,renderer:{render:o.render,initRenderer:o.initRenderer,getRenderCanvas:o.getRenderCanvas,isWebGLAvailable:o.isWebGLAvailable},textureCache:a.default,isWebGLInitialized:o.isWebGLInitialized}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return(0,r.default)(e)};var r=function(e){return e&&e.__esModule?e:{default:e}}(n(16))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){return window.performance?performance.now():Date.now()}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r={name:"cornerstone-core"};t.default=r},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n,r,a,s){if(void 0===e.cachedLut){var u=e.maxPixelValue-Math.min(e.minPixelValue,0)+1;e.cachedLut={},e.cachedLut.lutArray=new Uint8ClampedArray(u)}var c=e.cachedLut.lutArray,l=e.maxPixelValue,f=e.minPixelValue,d=(0,o.default)(e.slope,e.intercept,a),p=(0,i.default)(t,n,s),h=0;if(f<0&&(h=f),!0===r)for(var m=e.minPixelValue;m<=l;m++)c[m+-h]=255-p(d(m));else for(var g=e.minPixelValue;g<=l;g++)c[g+-h]=p(d(g));return c};var o=r(n(26)),i=r(n(53))},function(e,t,n){"use strict";function r(e){window.setTimeout(e,1e3/60)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return window.requestAnimationFrame(e)||window.webkitRequestAnimationFrame(e)||window.mozRequestAnimationFrame(e)||window.oRequestAnimationFrame(e)||window.msRequestAnimationFrame(e)||r(e)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n){var o=(0,r.default)(),i=e.getPixelData();e.stats.lastGetPixelDataTime=(0,r.default)()-o;var a=e.minPixelValue,s=0,u=0,c=i.length;if(o=(0,r.default)(),a<0)for(;ut.timeStamp?-1:e.timeStampp;){var t=g[g.length-1].imageId;s(t),$(d.default).trigger("CornerstoneImageCachePromiseRemoved",{imageId:t})}var n=u();$(d.default).trigger("CornerstoneImageCacheFull",n)}}function i(e,t){if(void 0===e)throw new Error("getImagePromise: imageId must not be undefined");if(void 0===t)throw new Error("getImagePromise: imagePromise must not be undefined");if(!0===m.hasOwnProperty(e))throw new Error("putImagePromise: imageId already in cache");var n={loaded:!1,imageId:e,sharedCacheKey:void 0,imagePromise:t,timeStamp:new Date,sizeInBytes:0};m[e]=n,g.push(n),t.then(function(e){if(n.loaded=!0,n.image=e,void 0===e.sizeInBytes)throw new Error("putImagePromise: sizeInBytes must not be undefined");if(void 0===e.sizeInBytes.toFixed)throw new Error("putImagePromise: image.sizeInBytes is not a number");n.sizeInBytes=e.sizeInBytes,h+=n.sizeInBytes,n.sharedCacheKey=e.sharedCacheKey,o()})}function a(e){if(void 0===e)throw new Error("getImagePromise: imageId must not be undefined");var t=m[e];if(void 0!==t)return t.timeStamp=new Date,t.imagePromise}function s(e){if(void 0===e)throw new Error("removeImagePromise: imageId must not be undefined");var t=m[e];if(void 0===t)throw new Error("removeImagePromise: imageId was not present in imageCache");t.imagePromise.reject(),g.splice(g.indexOf(t),1),h-=t.sizeInBytes,c(t.imagePromise,t.imageId),delete m[e]}function u(){return{maximumSizeInBytes:p,cacheSizeInBytes:h,numberOfImagesCached:g.length}}function c(e,t){e.then(function(e){e.decache&&e.decache()}).always(function(){delete m[t]})}function l(){for(;g.length>0;)s(g[0].imageId)}function f(e,t){var n=m[e];n&&n.imagePromise.then(function(e){var r=t-e.sizeInBytes;e.sizeInBytes=t,n.sizeInBytes=t,h+=r})}Object.defineProperty(t,"__esModule",{value:!0}),t.cachedImages=void 0,t.setMaximumSizeBytes=r,t.putImagePromise=i,t.getImagePromise=a,t.removeImagePromise=s,t.getCacheInfo=u,t.purgeCache=l,t.changeImageIdCacheSize=f;var d=function(e){return e&&e.__esModule?e:{default:e}}(n(10)),p=1073741824,h=0,m={},g=t.cachedImages=[];t.default={imageCache:m,cachedImages:g,setMaximumSizeBytes:r,putImagePromise:i,getImagePromise:a,removeImagePromise:s,getCacheInfo:u,purgeCache:l,changeImageIdCacheSize:f}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){if(e.color&&!e.falseColor)throw new Error("Color transforms are not implemented yet");var n=e.minPixelValue,o=0,i=0,a=e.width*e.height,s=e.origPixelData||e.getPixelData(),u=new Uint8Array(4*a),c=t,l=void 0,f=void 0;if(e.color=!0,e.falseColor=!0,e.origPixelData=s,t instanceof r.default.LookupTable)for(t.build();i0;)o.push(e),e+=r;return o[o.length-1]=t,o}function o(e,t){for(var n=0,r=e.length-1;n<=r;){var o=n+Math.floor((r-n)/2),i=e[o];if(i===t)return o;t=0&&e1)throw new Error("HSVToRGB expects hue < 1");var r=[];if(0===t)return r[0]=n,r[1]=n,r[2]=n,r;var o=Math.floor(6*e),i=6*e-o,a=n*(1-t),s=n*(1-t*i),u=n*(1-t*(1-i));switch(o){case 0:case 6:r[0]=n,r[1]=u,r[2]=a;break;case 1:r[0]=s,r[1]=n,r[2]=a;break;case 2:r[0]=a,r[1]=n,r[2]=u;break;case 3:r[0]=a,r[1]=s,r[2]=n;break;case 4:r[0]=u,r[1]=a,r[2]=n;break;case 5:r[0]=n,r[1]=a,r[2]=s}return r},this.build=function(e){if(!(this.Table.length>1)||e){this.Table=[];var t=this.NumberOfColors-1,n=void 0,r=void 0,o=void 0,i=void 0;t?(n=(this.HueRange[1]-this.HueRange[0])/t,r=(this.SaturationRange[1]-this.SaturationRange[0])/t,o=(this.ValueRange[1]-this.ValueRange[0])/t,i=(this.AlphaRange[1]-this.AlphaRange[0])/t):n=r=o=i=0;for(var a=0;a<=t;a++){var s=this.HueRange[0]+a*n,u=this.SaturationRange[0]+a*r,c=this.ValueRange[0]+a*o,l=this.AlphaRange[0]+a*i,f=this.HSVToRGB(s,u,c),d=[];switch(this.Ramp){case"scurve":d[0]=Math.floor(127.5*(1+Math.cos((1-f[0])*Math.PI))),d[1]=Math.floor(127.5*(1+Math.cos((1-f[1])*Math.PI))),d[2]=Math.floor(127.5*(1+Math.cos((1-f[2])*Math.PI))),d[3]=Math.floor(255*l);break;case"linear":d[0]=Math.floor(255*f[0]+.5),d[1]=Math.floor(255*f[1]+.5),d[2]=Math.floor(255*f[2]+.5),d[3]=Math.floor(255*l+.5);break;case"sqrt":d[0]=Math.floor(255*Math.sqrt(f[0])+.5),d[1]=Math.floor(255*Math.sqrt(f[1])+.5),d[2]=Math.floor(255*Math.sqrt(f[2])+.5),d[3]=Math.floor(255*Math.sqrt(l)+.5);break;default:throw new Error("Invalid Ramp value ("+this.Ramp+")")}this.Table.push(d)}this.buildSpecialColors()}},this.buildSpecialColors=function(){var e=this.NumberOfColors,t=e+o,n=e+i,r=e+a;this.UseBelowRangeColor||0===e?this.Table[t]=this.BelowRangeColor:this.Table[t]=this.Table[0],this.UseAboveRangeColor||0===e?this.Table[n]=this.AboveRangeColor:this.Table[n]=this.Table[e-1],this.Table[r]=this.NaNColor},this.mapValue=function(e){var t=this.getIndex(e);if(t<0)return this.NaNColor;if(0===t){if(this.UseBelowRangeColor&&ethis.TableRange[1])return this.AboveRangeColor;return this.Table[t]},this.linearIndexLookupMain=function(e,t){var n=void 0;return n=et.Range[1]?t.MaxIndex+i+1.5:(e+t.Shift)*t.Scale,Math.round(n)},this.getIndex=function(e){var t={};if(t.Range=[],t.MaxIndex=this.NumberOfColors-1,t.Shift=-this.TableRange[0],this.TableRange[1]<=this.TableRange[0]?t.Scale=Number.MAX_VALUE:t.Scale=t.MaxIndex/(this.TableRange[1]-this.TableRange[0]),t.Range[0]=this.TableRange[0],t.Range[1]=this.TableRange[1],isNaN(e))return-1;var n=this.linearIndexLookupMain(e,t);return n===this.NumberOfColors+o?n=0:n===this.NumberOfColors+i&&(n=this.NumberOfColors-1),n},this.setTableValue=function(e,t){if(5===arguments.length&&(t=Array.prototype.slice.call(arguments,1)),e<0)throw new Error("Can't set the table value for negative index ("+e+")");e>=this.NumberOfColors&&new Error("Index "+e+" is greater than the number of colors "+this.NumberOfColors),this.Table[e]=t,0!==e&&e!==this.NumberOfColors-1||this.buildSpecialColors()}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var o=0,i=1,a=2},function(e,t,n){"use strict";function r(e,t){var n=e,r=t;return function(e){return e*n+r}}function o(e){var t=e.lut[0],n=e.lut[e.lut.length-1],r=e.firstValueMapped+e.lut.length;return function(o){return o=r?n:e.lut[o]}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n){return n?o(n):r(e,t)}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;nt.timeStamp?-1:e.timeStampd;){var t=f[f.length-1];p-=t.sizeInBytes,delete l[t.imageId],f.pop(),$(cornerstone).trigger("CornerstoneWebGLTextureRemoved",{imageId:t.imageId})}var n=r();$(cornerstone).trigger("CornerstoneWebGLTextureCacheFull",n)}}function i(e){if(void 0===e)throw new Error("setMaximumSizeBytes: parameter numBytes must not be undefined");if(void 0===e.toFixed)throw new Error("setMaximumSizeBytes: parameter numBytes must be a number");d=e,o()}function a(e,t){var n=e.imageId;if(void 0===e)throw new Error("putImageTexture: image must not be undefined");if(void 0===n)throw new Error("putImageTexture: imageId must not be undefined");if(void 0===t)throw new Error("putImageTexture: imageTexture must not be undefined");if(!0===Object.prototype.hasOwnProperty.call(l,n))throw new Error("putImageTexture: imageId already in cache");var r={imageId:n,imageTexture:t,timeStamp:new Date,sizeInBytes:t.sizeInBytes};if(l[n]=r,f.push(r),void 0===t.sizeInBytes)throw new Error("putImageTexture: imageTexture.sizeInBytes must not be undefined");if(void 0===t.sizeInBytes.toFixed)throw new Error("putImageTexture: imageTexture.sizeInBytes is not a number");p+=r.sizeInBytes,o()}function s(e){if(void 0===e)throw new Error("getImageTexture: imageId must not be undefined");var t=l[e];if(void 0!==t)return t.timeStamp=new Date,t.imageTexture}function u(e){if(void 0===e)throw new Error("removeImageTexture: imageId must not be undefined");var t=l[e];if(void 0===t)throw new Error("removeImageTexture: imageId must not be undefined");return f.splice(f.indexOf(t),1),p-=t.sizeInBytes,delete l[e],t.imageTexture}function c(){for(;f.length>0;){var e=f.pop();delete l[e.imageId]}p=0}Object.defineProperty(t,"__esModule",{value:!0});var l={},f=[],d=268435456,p=0;t.default={purgeCache:c,getImageTexture:s,putImageTexture:a,removeImageTexture:u,setMaximumSizeBytes:i}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n=(0,r.getEnabledElement)(e),i=(0,o.default)(n);return i.invert(),i.transformPoint(t.x,t.y)};var r=n(0),o=function(e){return e&&e.__esModule?e:{default:e}}(n(8))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){if(void 0===e)throw new Error("disable: element must not be undefined");for(var t=(0,r.getEnabledElements)(),n=0;no?n:o;return{minPixelValue:t,maxPixelValue:n}}function i(e){if(e.restore)return e.restore;var t=e.color,n=e.rgba,r=e.lut,o=e.slope,i=e.windowWidth,a=e.windowCenter,s=e.minPixelValue,u=e.maxPixelValue;return function(){if(e.color=t,e.rgba=n,e.lut=r,e.slope=o,e.windowWidth=i,e.windowCenter=a,e.minPixelValue=s,e.maxPixelValue=u,e.origPixelData){var c=e.origPixelData;e.getPixelData=function(){return c}}delete e.origPixelData,delete e.colormapId,delete e.falseColor}}function a(e){return e&&"string"==typeof e&&(e=(0,p.getColormap)(e)),e}function s(e){return!(!e.restore||"function"!=typeof e.restore||(e.restore(),0))}function u(e,t){if(e.color&&!e.falseColor)throw new Error("Color transforms are not implemented yet");var n=(t=a(t)).getId();if(e.colormapId===n)return!1;if(s(e),n){var r=e.minPixelValue||0,u=e.maxPixelValue||255;e.restore=i(e);var c=t.createLookupTable();c.setTableRange(r,u),(0,d.default)(e,c);var l=o(e.getPixelData());e.minPixelValue=l.minPixelValue,e.maxPixelValue=l.maxPixelValue,e.colormapId=n}return!0}function c(e,t){u((0,l.getEnabledElement)(e).image,t)&&(0,f.default)(e,!0)}Object.defineProperty(t,"__esModule",{value:!0}),t.restoreImage=t.convertToFalseColorImage=t.convertImageToFalseColorImage=void 0;var l=n(0),f=r(n(1)),d=r(n(21)),p=n(24);t.convertImageToFalseColorImage=u,t.convertToFalseColorImage=c,t.restoreImage=s},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n=(0,r.getEnabledElement)(e);return(0,o.default)(n.canvas,t)};var r=n(0),o=function(e){return e&&e.__esModule?e:{default:e}}(n(3))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return(0,r.getEnabledElement)(e).image};var r=n(0)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n,r,s){var u=(0,i.default)(e,t,n,r,s),c=(0,o.getEnabledElement)(e),l=(0,a.default)(c.image.slope,c.image.intercept,c.viewport.modalityLUT);return u.map(l)};var o=n(0),i=r(n(19)),a=r(n(26))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=(0,r.getEnabledElement)(e).viewport;if(void 0!==t)return{scale:t.scale,translation:{x:t.translation.x,y:t.translation.y},voi:{windowWidth:t.voi.windowWidth,windowCenter:t.voi.windowCenter},invert:t.invert,pixelReplication:t.pixelReplication,rotation:t.rotation,hflip:t.hflip,vflip:t.vflip,modalityLUT:t.modalityLUT,voiLUT:t.voiLUT}};var r=n(0)},function(e,t,n){"use strict";function r(e,t){var n=e.indexOf(":"),r=e.substring(0,n),o=l[r],i=void 0;if(void 0===o||null===o){if(void 0!==f)return i=f(e);throw new Error("loadImageFromImageLoader: no image loader for imageId")}return(i=o(e,t)).then(function(e){$(c.default).trigger("CornerstoneImageLoaded",{image:e})}),i}function o(e,t){if(void 0===e)throw new Error("loadImage: parameter imageId must not be undefined");var n=(0,u.getImagePromise)(e);return void 0!==n?n:n=r(e,t)}function i(e,t){if(void 0===e)throw new Error("loadAndCacheImage: parameter imageId must not be undefined");var n=(0,u.getImagePromise)(e);return void 0!==n?n:(n=r(e,t),(0,u.putImagePromise)(e,n),n)}function a(e,t){l[e]=t}function s(e){var t=f;return f=e,t}Object.defineProperty(t,"__esModule",{value:!0}),t.loadImage=o,t.loadAndCacheImage=i,t.registerImageLoader=a,t.registerUnknownImageLoader=s;var u=n(20),c=function(e){return e&&e.__esModule?e:{default:e}}(n(10)),l={},f=void 0},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var o=r(n(2)),i=r(n(4)),a=r(n(11)),s=r(n(3)),u=r(n(12)),c=r(n(14)),l=r(n(13)),f=r(n(8)),d=r(n(16)),p=n(27);t.default={drawImage:o.default,generateLut:i.default,generateLutNew:a.default,getDefaultViewport:s.default,requestAnimationFrame:u.default,storedPixelDataToCanvasImageData:c.default,storedColorPixelDataToCanvasImageData:l.default,getTransform:f.default,calculateTransform:d.default,Transform:p.Transform}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=(0,r.getEnabledElement)(e);t.invalid=!0,t.needsRedraw=!0;var n={element:e};$(e).trigger("CornerstoneInvalidated",n)};var r=n(0)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){(0,r.getEnabledElementsByImageId)(e).forEach(function(e){(0,o.default)(e,!0)})};var r=n(0),o=function(e){return e&&e.__esModule?e:{default:e}}(n(2))},function(e,t,n){"use strict";function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=void 0;for(n=0;n>t,r=e.lut[e.lut.length-1]>>t,o=e.firstValueMapped+e.lut.length-1;return function(i){return i=o?r:e.lut[i-e.firstValueMapped]>>t}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n){return n?o(n):r(e,t)}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){return j}function i(){for(var e in b.shaders){var t=b.shaders[e];t.attributes={},t.uniforms={},t.vert=_.vertexShader,t.program=(0,x.default)(E,t.vert,t.frag),t.attributes.texCoordLocation=E.getAttribLocation(t.program,"a_texCoord"),E.enableVertexAttribArray(t.attributes.texCoordLocation),t.attributes.positionLocation=E.getAttribLocation(t.program,"a_position"),E.enableVertexAttribArray(t.attributes.positionLocation),t.uniforms.resolutionLocation=E.getUniformLocation(t.program,"u_resolution")}}function a(){!0!==C&&l(j)&&(m(),i(),t.isWebGLInitialized=C=!0)}function s(e,t,n){e.bufferData(e.ARRAY_BUFFER,new Float32Array([t,n,0,n,t,0,0,0]),e.STATIC_DRAW)}function u(e){e.preventDefault(),console.warn("WebGL Context Lost!")}function c(e){e.preventDefault(),t.isWebGLInitialized=C=!1,w.default.purgeCache(),a()}function l(e){E=null;try{var t={preserveDrawingBuffer:!0};E=e.getContext("webgl",t)||e.getContext("experimental-webgl",t),e.removeEventListener("webglcontextlost",u,!1),e.addEventListener("webglcontextlost",u,!1),e.removeEventListener("webglcontextrestored",c,!1),e.addEventListener("webglcontextrestored",c,!1)}catch(e){throw new Error("Error creating WebGL context")}return E||(console.error("Unable to initialize WebGL. Your browser may not support it."),E=null),E}function f(e){if(e.color)return"rgb";var t="int";return e.minPixelValue>=0&&(t="u"+t),e.maxPixelValue>255?t+="16":t+="8",t}function d(e){var t=f(e);return b.shaders.hasOwnProperty(t)?b.shaders[t]:b.shaders.rgb}function p(e){var t={uint8:E.LUMINANCE,int8:E.LUMINANCE_ALPHA,uint16:E.LUMINANCE_ALPHA,int16:E.RGB,rgb:E.RGB},n={int8:1,uint16:2,int16:3,rgb:3},r=f(e),o=t[r],i=E.createTexture();E.bindTexture(E.TEXTURE_2D,i),E.texParameteri(E.TEXTURE_2D,E.TEXTURE_MIN_FILTER,E.NEAREST),E.texParameteri(E.TEXTURE_2D,E.TEXTURE_MAG_FILTER,E.NEAREST),E.texParameteri(E.TEXTURE_2D,E.TEXTURE_WRAP_S,E.CLAMP_TO_EDGE),E.texParameteri(E.TEXTURE_2D,E.TEXTURE_WRAP_T,E.CLAMP_TO_EDGE),E.pixelStorei(E.UNPACK_ALIGNMENT,1);var a=b.dataUtilities[r].storedPixelDataToImageData(e,e.width,e.height);return E.texImage2D(E.TEXTURE_2D,0,o,e.width,e.height,0,o,E.UNSIGNED_BYTE,a),{texture:i,sizeInBytes:e.width*e.height*n[r]}}function h(e){var t=w.default.getImageTexture(e.imageId);return t||(t=p(e),w.default.putImageTexture(e,t)),t.texture}function m(){S=E.createBuffer(),E.bindBuffer(E.ARRAY_BUFFER,S),E.bufferData(E.ARRAY_BUFFER,new Float32Array([1,1,0,1,1,0,0,0]),E.STATIC_DRAW),T=E.createBuffer(),E.bindBuffer(E.ARRAY_BUFFER,T),E.bufferData(E.ARRAY_BUFFER,new Float32Array([1,1,0,1,1,0,0,0]),E.STATIC_DRAW)}function g(e,t,n,r,o){E.clearColor(1,0,0,1),E.viewport(0,0,r,o),E.clear(E.COLOR_BUFFER_BIT|E.DEPTH_BUFFER_BIT),E.useProgram(e.program),E.bindBuffer(E.ARRAY_BUFFER,T),E.vertexAttribPointer(e.attributes.texCoordLocation,2,E.FLOAT,!1,0,0),E.bindBuffer(E.ARRAY_BUFFER,S),E.vertexAttribPointer(e.attributes.positionLocation,2,E.FLOAT,!1,0,0);for(var i in t){var a=E.getUniformLocation(e.program,i);if(a){var u=t[i],c=u.type,l=u.value;"i"===c?E.uniform1i(a,l):"f"===c?E.uniform1f(a,l):"2f"===c&&E.uniform2f(a,l[0],l[1])}}s(E,r,o),E.activeTexture(E.TEXTURE0),E.bindTexture(E.TEXTURE_2D,n),E.drawArrays(E.TRIANGLE_STRIP,0,4)}function v(e){var t=e.image;j.width=t.width,j.height=t.height;var n=e.viewport,r=d(t),o=h(t);return g(r,{u_resolution:{type:"2f",value:[t.width,t.height]},wc:{type:"f",value:n.voi.windowCenter},ww:{type:"f",value:n.voi.windowWidth},slope:{type:"f",value:t.slope},intercept:{type:"f",value:t.intercept},minPixelValue:{type:"f",value:t.minPixelValue},invert:{type:"i",value:n.invert?1:0}},o,t.width,t.height),j}function y(){var e={failIfMajorPerformanceCaveat:!0};try{var t=document.createElement("canvas");return Boolean(window.WebGLRenderingContext)&&(t.getContext("webgl",e)||t.getContext("experimental-webgl",e))}catch(e){return!1}}Object.defineProperty(t,"__esModule",{value:!0}),t.isWebGLInitialized=void 0,t.getRenderCanvas=o,t.initRenderer=a,t.render=v,t.isWebGLAvailable=y;var b=n(55),_=n(61),w=r(n(29)),x=r(n(28)),j=document.createElement("canvas"),E=void 0,T=void 0,S=void 0,C=!1;t.isWebGLInitialized=C},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.dataUtilities=t.shaders=void 0;var r=n(56),o=n(57),i=n(58),a=n(59),s=n(60),u={int16:r.int16Shader,int8:o.int8Shader,rgb:i.rgbShader,uint16:a.uint16Shader,uint8:s.uint8Shader},c={int16:r.int16DataUtilities,int8:o.int8DataUtilities,rgb:i.rgbDataUtilities,uint16:a.uint16DataUtilities,uint8:s.uint8DataUtilities};t.shaders=u,t.dataUtilities=c},function(e,t,n){"use strict";function r(e){for(var t=e.getPixelData(),n=new Uint8Array(e.width*e.height*3),r=0,o=0;o>8,10),n[r++]=t[o]<0?0:1}return n}Object.defineProperty(t,"__esModule",{value:!0});var o={};t.int16DataUtilities={storedPixelDataToImageData:r},o.frag="precision mediump float;uniform sampler2D u_image;uniform float ww;uniform float wc;uniform float slope;uniform float intercept;uniform int invert;varying vec2 v_texCoord;void main() {vec4 color = texture2D(u_image, v_texCoord);float intensity = color.r*256.0 + color.g*65536.0;if (color.b == 0.0)intensity = -intensity;intensity = intensity * slope + intercept;float center0 = wc - 0.5;float width0 = max(ww, 1.0);intensity = (intensity - center0) / width0 + 0.5;intensity = clamp(intensity, 0.0, 1.0);gl_FragColor = vec4(intensity, intensity, intensity, 1.0);if (invert == 1)gl_FragColor.rgb = 1.0 - gl_FragColor.rgb;}",t.int16Shader=o},function(e,t,n){"use strict";function r(e){for(var t=e.getPixelData(),n=new Uint8Array(e.width*e.height*2),r=0,o=0;o>8,10)}return n}Object.defineProperty(t,"__esModule",{value:!0});var o={};t.uint16DataUtilities={storedPixelDataToImageData:r},o.frag="precision mediump float;uniform sampler2D u_image;uniform float ww;uniform float wc;uniform float slope;uniform float intercept;uniform int invert;varying vec2 v_texCoord;void main() {vec4 color = texture2D(u_image, v_texCoord);float intensity = color.r*256.0 + color.a*65536.0;intensity = intensity * slope + intercept;float center0 = wc - 0.5;float width0 = max(ww, 1.0);intensity = (intensity - center0) / width0 + 0.5;intensity = clamp(intensity, 0.0, 1.0);gl_FragColor = vec4(intensity, intensity, intensity, 1.0);if (invert == 1)gl_FragColor.rgb = 1.0 - gl_FragColor.rgb;}",t.uint16Shader=o},function(e,t,n){"use strict";function r(e){for(var t=e.getPixelData(),n=new Uint8Array(t.length),r=0;r1)for(var n=1;n0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!o(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,i,s;if(!o(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],i=n.length,r=-1,n===t||o(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(a(n)){for(s=i;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(r<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],o(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?o(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(o(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}}},"tty-browserify":{"package.json":function(e,t){t.name="tty-browserify",t.version="0.0.0",t.main="index.js"},"index.js":function(e,t){function n(){throw new Error("tty.ReadStream is not implemented")}function r(){throw new Error("tty.ReadStream is not implemented")}t.isatty=function(){return!1},t.ReadStream=n,t.WriteStream=r}}}},"babel-runtime":{regenerator:{"index.js":function(e,t,n){n.exports=e("regenerator-runtime")}},helpers:{"typeof.js":function(e,t){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var r=n(e("../core-js/symbol/iterator")),o=n(e("../core-js/symbol")),i="function"==typeof o.default&&"symbol"==typeof r.default?function(e){return typeof e}:function(e){return e&&"function"==typeof o.default&&e.constructor===o.default&&e!==o.default.prototype?"symbol":typeof e};t.default="function"==typeof o.default&&"symbol"===i(r.default)?function(e){return void 0===e?"undefined":i(e)}:function(e){return e&&"function"==typeof o.default&&e.constructor===o.default&&e!==o.default.prototype?"symbol":void 0===e?"undefined":i(e)}},"toConsumableArray.js":function(e,t){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var r=n(e("../core-js/array/from"));t.default=function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t=0,a=i&&o.regeneratorRuntime;if(o.regeneratorRuntime=void 0,r.exports=e("./runtime"),i)o.regeneratorRuntime=a;else try{delete o.regeneratorRuntime}catch(e){o.regeneratorRuntime=void 0}},"runtime.js":function(e,n,r){!function(e){"use strict";function t(e,t,n,r){var i=t&&t.prototype instanceof o?t:o,a=Object.create(i.prototype),s=new p(r||[]);return a._invoke=c(e,n,s),a}function n(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}function o(){}function i(){}function a(){}function s(e){["next","throw","return"].forEach(function(t){e[t]=function(e){return this._invoke(t,e)}})}function u(t){function r(e,o,i,a){var s=n(t[e],t,o);if("throw"!==s.type){var u=s.arg,c=u.value;return c&&"object"==typeof c&&v.call(c,"__await")?Promise.resolve(c.__await).then(function(e){r("next",e,i,a)},function(e){r("throw",e,i,a)}):Promise.resolve(c).then(function(e){u.value=e,i(u)},a)}a(s.arg)}function o(e,t){function n(){return new Promise(function(n,o){r(e,t,n,o)})}return i=i?i.then(n,n):n()}"object"==typeof e.process&&e.process.domain&&(r=e.process.domain.bind(r));var i;this._invoke=o}function c(e,t,r){var o=T;return function i(a,s){if(o===C)throw new Error("Generator is already running");if(o===O){if("throw"===a)throw s;return m()}for(r.method=a,r.arg=s;;){var u=r.delegate;if(u){var c=l(u,r);if(c){if(c===P)continue;return c}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if(o===T)throw o=O,r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);o=C;var f=n(e,t,r);if("normal"===f.type){if(o=r.done?O:S,f.arg===P)continue;return{value:f.arg,done:r.done}}"throw"===f.type&&(o=O,r.method="throw",r.arg=f.arg)}}}function l(e,t){var r=e.iterator[t.method];if(r===y){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=y,l(e,t),"throw"===t.method))return P;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return P}var o=n(r,e.iterator,t.arg);if("throw"===o.type)return t.method="throw",t.arg=o.arg,t.delegate=null,P;var i=o.arg;return i?i.done?(t[e.resultName]=i.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=y),t.delegate=null,P):i:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,P)}function f(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function d(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function p(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(f,this),this.reset(!0)}function h(e){if(e){var t=e[_];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var n=-1,r=function t(){for(;++n=0;--r){var o=this.tryEntries[r],i=o.completion;if("root"===o.tryLoc)return t("end");if(o.tryLoc<=this.prev){var a=v.call(o,"catchLoc"),s=v.call(o,"finallyLoc");if(a&&s){if(this.prev=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&v.call(r,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),d(n),P}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var o=r.arg;d(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:h(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=y),P}}}}("object"==typeof t?t:"object"==typeof window?window:"object"==typeof self?self:this)}},"core-js":{modules:{"es6.symbol.js":function(e){"use strict";var t=e("./_global"),n=e("./_has"),r=e("./_descriptors"),o=e("./_export"),i=e("./_redefine"),a=e("./_meta").KEY,s=e("./_fails"),u=e("./_shared"),c=e("./_set-to-string-tag"),l=e("./_uid"),f=e("./_wks"),d=e("./_wks-ext"),p=e("./_wks-define"),h=e("./_keyof"),m=e("./_enum-keys"),g=e("./_is-array"),v=e("./_an-object"),y=e("./_to-iobject"),b=e("./_to-primitive"),_=e("./_property-desc"),w=e("./_object-create"),x=e("./_object-gopn-ext"),j=e("./_object-gopd"),E=e("./_object-dp"),T=e("./_object-keys"),S=j.f,C=E.f,O=x.f,P=t.Symbol,k=t.JSON,I=k&&k.stringify,M="prototype",A=f("_hidden"),L=f("toPrimitive"),R={}.propertyIsEnumerable,D=u("symbol-registry"),N=u("symbols"),F=u("op-symbols"),W=Object[M],q="function"==typeof P,B=t.QObject,U=!B||!B[M]||!B[M].findChild,H=r&&s(function(){return 7!=w(C({},"a",{get:function(){return C(this,"a",{value:7}).a}})).a})?function(e,t,n){var r=S(W,t);r&&delete W[t],C(e,t,n),r&&e!==W&&C(W,t,r)}:C,z=function(e){var t=N[e]=w(P[M]);return t._k=e,t},V=q&&"symbol"==typeof P.iterator?function(e){return"symbol"==typeof e}:function(e){return e instanceof P},G=function e(t,r,o){return t===W&&G(F,r,o),v(t),r=b(r,!0),v(o),n(N,r)?(o.enumerable?(n(t,A)&&t[A][r]&&(t[A][r]=!1),o=w(o,{enumerable:_(0,!1)})):(n(t,A)||C(t,A,_(1,{})),t[A][r]=!0),H(t,r,o)):C(t,r,o)},$=function e(t,n){v(t);for(var r=m(n=y(n)),o=0,i=r.length,a;i>o;)G(t,a=r[o++],n[a]);return t},X=function e(t,n){return void 0===n?w(t):$(w(t),n)},Y=function e(t){var r=R.call(this,t=b(t,!0));return!(this===W&&n(N,t)&&!n(F,t))&&(!(r||!n(this,t)||!n(N,t)||n(this,A)&&this[A][t])||r)},K=function e(t,r){if(t=y(t),r=b(r,!0),t!==W||!n(N,r)||n(F,r)){var o=S(t,r);return!o||!n(N,r)||n(t,A)&&t[A][r]||(o.enumerable=!0),o}},J=function e(t){for(var r=O(y(t)),o=[],i=0,s;r.length>i;)n(N,s=r[i++])||s==A||s==a||o.push(s);return o},Q=function e(t){for(var r=t===W,o=O(r?F:y(t)),i=[],a=0,s;o.length>a;)!n(N,s=o[a++])||r&&!n(W,s)||i.push(N[s]);return i};q||(i((P=function e(){if(this instanceof P)throw TypeError("Symbol is not a constructor!");var t=l(arguments.length>0?arguments[0]:void 0),o=function(e){this===W&&o.call(F,e),n(this,A)&&n(this[A],t)&&(this[A][t]=!1),H(this,t,_(1,e))};return r&&U&&H(W,t,{configurable:!0,set:o}),z(t)})[M],"toString",function e(){return this._k}),j.f=K,E.f=G,e("./_object-gopn").f=x.f=J,e("./_object-pie").f=Y,e("./_object-gops").f=Q,r&&!e("./_library")&&i(W,"propertyIsEnumerable",Y,!0),d.f=function(e){return z(f(e))}),o(o.G+o.W+o.F*!q,{Symbol:P});for(var Z="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),ee=0;Z.length>ee;)f(Z[ee++]);for(var Z=T(f.store),ee=0;Z.length>ee;)p(Z[ee++]);o(o.S+o.F*!q,"Symbol",{for:function(e){return n(D,e+="")?D[e]:D[e]=P(e)},keyFor:function e(t){if(V(t))return h(D,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){U=!0},useSimple:function(){U=!1}}),o(o.S+o.F*!q,"Object",{create:X,defineProperty:G,defineProperties:$,getOwnPropertyDescriptor:K,getOwnPropertyNames:J,getOwnPropertySymbols:Q}),k&&o(o.S+o.F*(!q||s(function(){var e=P();return"[null]"!=I([e])||"{}"!=I({a:e})||"{}"!=I(Object(e))})),"JSON",{stringify:function e(t){if(void 0!==t&&!V(t)){for(var n=[t],r=1,o,i;arguments.length>r;)n.push(arguments[r++]);return"function"==typeof(o=n[1])&&(i=o),!i&&g(o)||(o=function(e,t){if(i&&(t=i.call(this,e,t)),!V(t))return t}),n[1]=o,I.apply(k,n)}}}),P[M][L]||e("./_hide")(P[M],L,P[M].valueOf),c(P,"Symbol"),c(Math,"Math",!0),c(t.JSON,"JSON",!0)},"_global.js":function(e,t,n){var r=n.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},"_has.js":function(e,t,n){var r={}.hasOwnProperty;n.exports=function(e,t){return r.call(e,t)}},"_descriptors.js":function(e,t,n){n.exports=!e("./_fails")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},"_fails.js":function(e,t,n){n.exports=function(e){try{return!!e()}catch(e){return!0}}},"_export.js":function(e,t,n){var r=e("./_global"),o=e("./_core"),i=e("./_hide"),a=e("./_redefine"),s=e("./_ctx"),u="prototype",c=function(e,t,n){var l=e&c.F,f=e&c.G,d=e&c.S,p=e&c.P,h=e&c.B,m=f?r:d?r[t]||(r[t]={}):(r[t]||{})[u],g=f?o:o[t]||(o[t]={}),v=g[u]||(g[u]={}),y,b,_,w;f&&(n=t);for(y in n)_=((b=!l&&m&&void 0!==m[y])?m:n)[y],w=h&&b?s(_,r):p&&"function"==typeof _?s(Function.call,_):_,m&&a(m,y,_,e&c.U),g[y]!=_&&i(g,y,w),p&&v[y]!=_&&(v[y]=_)};r.core=o,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,n.exports=c},"_core.js":function(e,t,n){var r=n.exports={version:"2.4.0"};"number"==typeof __e&&(__e=r)},"_hide.js":function(e,t,n){var r=e("./_object-dp"),o=e("./_property-desc");n.exports=e("./_descriptors")?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},"_object-dp.js":function(e,t){var n=e("./_an-object"),r=e("./_ie8-dom-define"),o=e("./_to-primitive"),i=Object.defineProperty;t.f=e("./_descriptors")?Object.defineProperty:function e(t,a,s){if(n(t),a=o(a,!0),n(s),r)try{return i(t,a,s)}catch(e){}if("get"in s||"set"in s)throw TypeError("Accessors not supported!");return"value"in s&&(t[a]=s.value),t}},"_an-object.js":function(e,t,n){var r=e("./_is-object");n.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},"_is-object.js":function(e,t,n){n.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},"_ie8-dom-define.js":function(e,t,n){n.exports=!e("./_descriptors")&&!e("./_fails")(function(){return 7!=Object.defineProperty(e("./_dom-create")("div"),"a",{get:function(){return 7}}).a})},"_dom-create.js":function(e,t,n){var r=e("./_is-object"),o=e("./_global").document,i=r(o)&&r(o.createElement);n.exports=function(e){return i?o.createElement(e):{}}},"_to-primitive.js":function(e,t,n){var r=e("./_is-object");n.exports=function(e,t){if(!r(e))return e;var n,o;if(t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;if("function"==typeof(n=e.valueOf)&&!r(o=n.call(e)))return o;if(!t&&"function"==typeof(n=e.toString)&&!r(o=n.call(e)))return o;throw TypeError("Can't convert object to primitive value")}},"_property-desc.js":function(e,t,n){n.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},"_redefine.js":function(e,t,n){var r=e("./_global"),o=e("./_hide"),i=e("./_has"),a=e("./_uid")("src"),s="toString",u=Function[s],c=(""+u).split(s);e("./_core").inspectSource=function(e){return u.call(e)},(n.exports=function(e,t,n,s){var u="function"==typeof n;u&&(i(n,"name")||o(n,"name",t)),e[t]!==n&&(u&&(i(n,a)||o(n,a,e[t]?""+e[t]:c.join(String(t)))),e===r?e[t]=n:s?e[t]?e[t]=n:o(e,t,n):(delete e[t],o(e,t,n)))})(Function.prototype,s,function e(){return"function"==typeof this&&this[a]||u.call(this)})},"_uid.js":function(e,t,n){var r=0,o=Math.random();n.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++r+o).toString(36))}},"_ctx.js":function(e,t,n){var r=e("./_a-function");n.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,o){return e.call(t,n,r,o)}}return function(){return e.apply(t,arguments)}}},"_a-function.js":function(e,t,n){n.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},"_meta.js":function(e,t,n){var r=e("./_uid")("meta"),o=e("./_is-object"),i=e("./_has"),a=e("./_object-dp").f,s=0,u=Object.isExtensible||function(){return!0},c=!e("./_fails")(function(){return u(Object.preventExtensions({}))}),l=function(e){a(e,r,{value:{i:"O"+ ++s,w:{}}})},f=function(e,t){if(!o(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!i(e,r)){if(!u(e))return"F";if(!t)return"E";l(e)}return e[r].i},d=function(e,t){if(!i(e,r)){if(!u(e))return!0;if(!t)return!1;l(e)}return e[r].w},p=function(e){return c&&h.NEED&&u(e)&&!i(e,r)&&l(e),e},h=n.exports={KEY:r,NEED:!1,fastKey:f,getWeak:d,onFreeze:p}},"_shared.js":function(e,t,n){var r=e("./_global"),o="__core-js_shared__",i=r[o]||(r[o]={});n.exports=function(e){return i[e]||(i[e]={})}},"_set-to-string-tag.js":function(e,t,n){var r=e("./_object-dp").f,o=e("./_has"),i=e("./_wks")("toStringTag");n.exports=function(e,t,n){e&&!o(e=n?e:e.prototype,i)&&r(e,i,{configurable:!0,value:t})}},"_wks.js":function(e,t,n){var r=e("./_shared")("wks"),o=e("./_uid"),i=e("./_global").Symbol,a="function"==typeof i;(n.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}).store=r},"_wks-ext.js":function(e,t){t.f=e("./_wks")},"_wks-define.js":function(e,t,n){var r=e("./_global"),o=e("./_core"),i=e("./_library"),a=e("./_wks-ext"),s=e("./_object-dp").f;n.exports=function(e){var t=o.Symbol||(o.Symbol=i?{}:r.Symbol||{});"_"==e.charAt(0)||e in t||s(t,e,{value:a.f(e)})}},"_library.js":function(e,t,n){n.exports=!1},"_keyof.js":function(e,t,n){var r=e("./_object-keys"),o=e("./_to-iobject");n.exports=function(e,t){for(var n=o(e),i=r(n),a=i.length,s=0,u;a>s;)if(n[u=i[s++]]===t)return u}},"_object-keys.js":function(e,t,n){var r=e("./_object-keys-internal"),o=e("./_enum-bug-keys");n.exports=Object.keys||function e(t){return r(t,o)}},"_object-keys-internal.js":function(e,t,n){var r=e("./_has"),o=e("./_to-iobject"),i=e("./_array-includes")(!1),a=e("./_shared-key")("IE_PROTO");n.exports=function(e,t){var n=o(e),s=0,u=[],c;for(c in n)c!=a&&r(n,c)&&u.push(c);for(;t.length>s;)r(n,c=t[s++])&&(~i(u,c)||u.push(c));return u}},"_to-iobject.js":function(e,t,n){var r=e("./_iobject"),o=e("./_defined");n.exports=function(e){return r(o(e))}},"_iobject.js":function(e,t,n){var r=e("./_cof");n.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==r(e)?e.split(""):Object(e)}},"_cof.js":function(e,t,n){var r={}.toString;n.exports=function(e){return r.call(e).slice(8,-1)}},"_defined.js":function(e,t,n){n.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},"_array-includes.js":function(e,t,n){var r=e("./_to-iobject"),o=e("./_to-length"),i=e("./_to-index");n.exports=function(e){return function(t,n,a){var s=r(t),u=o(s.length),c=i(a,u),l;if(e&&n!=n){for(;u>c;)if((l=s[c++])!=l)return!0}else for(;u>c;c++)if((e||c in s)&&s[c]===n)return e||c||0;return!e&&-1}}},"_to-length.js":function(e,t,n){var r=e("./_to-integer"),o=Math.min;n.exports=function(e){return e>0?o(r(e),9007199254740991):0}},"_to-integer.js":function(e,t,n){var r=Math.ceil,o=Math.floor;n.exports=function(e){return isNaN(e=+e)?0:(e>0?o:r)(e)}},"_to-index.js":function(e,t,n){var r=e("./_to-integer"),o=Math.max,i=Math.min;n.exports=function(e,t){return(e=r(e))<0?o(e+t,0):i(e,t)}},"_shared-key.js":function(e,t,n){var r=e("./_shared")("keys"),o=e("./_uid");n.exports=function(e){return r[e]||(r[e]=o(e))}},"_enum-bug-keys.js":function(e,t,n){n.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},"_enum-keys.js":function(e,t,n){var r=e("./_object-keys"),o=e("./_object-gops"),i=e("./_object-pie");n.exports=function(e){var t=r(e),n=o.f;if(n)for(var a=n(e),s=i.f,u=0,c;a.length>u;)s.call(e,c=a[u++])&&t.push(c);return t}},"_object-gops.js":function(e,t){t.f=Object.getOwnPropertySymbols},"_object-pie.js":function(e,t){t.f={}.propertyIsEnumerable},"_is-array.js":function(e,t,n){var r=e("./_cof");n.exports=Array.isArray||function e(t){return"Array"==r(t)}},"_object-create.js":function(e,t,n){var r=e("./_an-object"),o=e("./_object-dps"),i=e("./_enum-bug-keys"),a=e("./_shared-key")("IE_PROTO"),s=function(){},u="prototype",c=function(){var t=e("./_dom-create")("iframe"),n=i.length,r="<",o=">",a;for(t.style.display="none",e("./_html").appendChild(t),t.src="javascript:",(a=t.contentWindow.document).open(),a.write("