@3cr/viewer-browser 0.0.200 → 0.0.220
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +46 -22
- package/.prettierrc +6 -0
- package/components.d.ts +23 -10
- package/dist/Viewer3CR.js +37 -46
- package/dist/Viewer3CR.mjs +22625 -20892
- package/dist/Viewer3CR.umd.js +37 -46
- package/dist/android-chrome-192x192.png +0 -0
- package/dist/android-chrome-512x512.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/browserconfig.xml +9 -0
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/mstile-144x144.png +0 -0
- package/dist/mstile-150x150.png +0 -0
- package/dist/mstile-310x150.png +0 -0
- package/dist/mstile-310x310.png +0 -0
- package/dist/mstile-70x70.png +0 -0
- package/dist/safari-pinned-tab.svg +50 -0
- package/dist/site.webmanifest +19 -0
- package/index.html +34 -41
- package/package.json +23 -20
- package/playground/android-chrome-192x192.png +0 -0
- package/playground/android-chrome-512x512.png +0 -0
- package/playground/apple-touch-icon.png +0 -0
- package/playground/browserconfig.xml +9 -0
- package/playground/favicon-16x16.png +0 -0
- package/playground/favicon-32x32.png +0 -0
- package/playground/favicon.ico +0 -0
- package/playground/index.html +26 -29
- package/playground/mstile-144x144.png +0 -0
- package/playground/mstile-150x150.png +0 -0
- package/playground/mstile-310x150.png +0 -0
- package/playground/mstile-310x310.png +0 -0
- package/playground/mstile-70x70.png +0 -0
- package/playground/safari-pinned-tab.svg +50 -0
- package/playground/site.webmanifest +19 -0
- package/playground/sw.js +15 -1
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/browserconfig.xml +9 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/mstile-144x144.png +0 -0
- package/public/mstile-150x150.png +0 -0
- package/public/mstile-310x150.png +0 -0
- package/public/mstile-310x310.png +0 -0
- package/public/mstile-70x70.png +0 -0
- package/public/safari-pinned-tab.svg +50 -0
- package/public/site.webmanifest +19 -0
- package/src/App.vue +35 -45
- package/src/__tests__/app.spec.ts +7 -8
- package/{__tests__/index.spec.ts → src/__tests__/main.spec.ts} +5 -6
- package/src/assets/logos/3dicom/white-mini.svg +20 -0
- package/src/assets/logos/3dicom/white.svg +30 -0
- package/src/assets/styles.scss +14 -4
- package/src/components/demo/__tests__/DemoModal.spec.ts +9 -8
- package/src/components/demo/__tests__/DemoPatientModal.spec.ts +11 -10
- package/src/components/demo/__tests__/options.spec.ts +1 -1
- package/src/components/demo/licence/__tests__/DemoLicenceEnableCloudStorageModal.spec.ts +11 -10
- package/src/components/demo/licence/__tests__/DemoLicenceInfoModal.spec.ts +21 -11
- package/src/components/demo/licence/__tests__/DemoLicenceSendToPartyModal.spec.ts +10 -10
- package/src/components/demo/licence/__tests__/DemoLicenceShareToMobileModal.spec.ts +14 -13
- package/src/components/demo/options.ts +54 -59
- package/src/components/demo/patient/__tests__/DemoPatientEnableCloudStorageModal.spec.ts +11 -10
- package/src/components/demo/patient/__tests__/DemoPatientInfoModal.spec.ts +12 -11
- package/src/components/demo/patient/__tests__/DemoPatientSendToPartyModal.spec.ts +10 -10
- package/src/components/demo/patient/__tests__/DemoPatientShareToMobileModal.spec.ts +14 -13
- package/src/components/modal/ActionRail.vue +7 -11
- package/src/components/modal/AskAI.vue +35 -50
- package/src/components/modal/CloseViewerModal.vue +22 -57
- package/src/components/modal/MftpWebGL3DRModal.vue +152 -570
- package/src/components/modal/ViewerActionRail.vue +50 -39
- package/src/components/modal/ViewerNavigationDrawer.vue +10 -8
- package/src/components/modal/ViewerNavigationDrawerContent.vue +82 -49
- package/src/components/modal/ViewerNavigationDrawerFooter.vue +57 -60
- package/src/components/modal/ViewerNavigationDrawerHeader.vue +13 -48
- package/src/components/modal/ViewerScanView.vue +114 -0
- package/src/components/modal/WebGL3DR.vue +84 -0
- package/src/components/modal/__tests__/ActionRail.spec.ts +10 -0
- package/src/components/modal/__tests__/AskAI.spec.ts +33 -0
- package/src/components/modal/__tests__/CloseViewerModal.spec.ts +24 -14
- package/src/components/modal/__tests__/MftpWebGL3DRModal.spec.ts +147 -176
- package/src/components/modal/__tests__/ViewerActionRail.spec.ts +11 -0
- package/src/components/modal/__tests__/ViewerNavigationDrawer.spec.ts +10 -12
- package/src/components/modal/__tests__/ViewerNavigationDrawerContent.spec.ts +4 -22
- package/src/components/modal/__tests__/ViewerNavigationDrawerFooter.spec.ts +35 -32
- package/src/components/modal/__tests__/ViewerNavigationDrawerHeader.spec.ts +11 -9
- package/src/components/modal/__tests__/ViewerScanView.spec.ts +60 -0
- package/src/components/modal/__tests__/WebGL3DR.spec.ts +57 -0
- package/src/components/modal/actions/Flip3dAction.vue +1 -1
- package/src/components/modal/actions/FlipHorizontalAction.vue +5 -10
- package/src/components/modal/actions/FlipVerticalAction.vue +5 -10
- package/src/components/modal/actions/FullscreenAction.vue +6 -11
- package/src/components/modal/actions/HideViewAction.vue +38 -0
- package/src/components/modal/actions/NavigationCubeAction.vue +7 -14
- package/src/components/modal/actions/PanAction.vue +4 -4
- package/src/components/modal/actions/ResetViewAction.vue +1 -1
- package/src/components/modal/actions/Rotate2dAction.vue +8 -20
- package/src/components/modal/actions/Slice3dAction.vue +10 -32
- package/src/components/modal/actions/ZoomAction.vue +1 -1
- package/src/components/modal/actions/__tests__/Action.spec.ts +8 -9
- package/src/components/modal/actions/__tests__/Flip3dAction.spec.ts +6 -8
- package/src/components/modal/actions/__tests__/FlipHorizontalAction.spec.ts +6 -7
- package/src/components/modal/actions/__tests__/FlipVerticalAction.spec.ts +6 -7
- package/src/components/modal/actions/__tests__/FullscreenAction.spec.ts +9 -10
- package/src/components/modal/actions/__tests__/NavigationCubeAction.spec.ts +11 -11
- package/src/components/modal/actions/__tests__/PanAction.spec.ts +9 -10
- package/src/components/modal/actions/__tests__/ResetViewAction.spec.ts +7 -7
- package/src/components/modal/actions/__tests__/Rotate2dAction.spec.ts +6 -8
- package/src/components/modal/actions/__tests__/Slice3dAction.spec.ts +23 -5
- package/src/components/modal/actions/__tests__/ZoomAction.spec.ts +8 -10
- package/src/components/modal/buttons/AutoAnnotateBtn.vue +29 -0
- package/src/components/modal/buttons/__tests__/AutoAnnotateBtn.spec.ts +28 -0
- package/src/components/modal/menus/FileMenu.vue +80 -0
- package/src/components/modal/menus/SettingsMenu.vue +111 -0
- package/src/components/modal/menus/__tests__/FileMenu.spec.ts +110 -0
- package/src/components/modal/menus/__tests__/SettingsMenu.spec.ts +71 -0
- package/src/components/shared/DoubleSliderSelector.vue +142 -0
- package/src/components/shared/UpdateSnackbar.vue +72 -0
- package/src/components/{selectors → shared}/ValueSelector.vue +9 -12
- package/src/components/shared/__tests__/DoubleSliderSelector.spec.ts +83 -0
- package/src/components/shared/__tests__/LoadingSpinner.spec.ts +9 -0
- package/src/components/shared/__tests__/UpdateSnackbar.spec.ts +116 -0
- package/src/components/shared/__tests__/ValueSelector.spec.ts +39 -0
- package/src/components/shared/__tests__/VerticalSliderSelector.spec.ts +50 -0
- package/src/components/views/AnnotationTreeView.vue +234 -0
- package/src/components/{modal/ViewerDisplaySettings.vue → views/DisplaySettings.vue} +7 -15
- package/src/components/views/MarkupTreeView.vue +199 -0
- package/src/components/views/McadObjectTreeView.vue +119 -0
- package/src/components/views/__tests__/AnnotationTreeView.spec.ts +62 -0
- package/src/components/{modal/__tests__/ViewerDisplaySettings.spec.ts → views/__tests__/DisplaySettings.spec.ts} +24 -20
- package/src/components/views/__tests__/MarkupTreeView.spec.ts +41 -0
- package/src/components/views/__tests__/McadObjectTreeView.spec.ts +47 -0
- package/src/components/views/modals/DataOverlayModal.vue +89 -0
- package/src/components/views/modals/DataOverlayModalManager.vue +104 -0
- package/src/components/views/modals/__tests__/DataOverlayModal.spec.ts +33 -0
- package/src/components/views/modals/__tests__/DataOverlayModalManager.spec.ts +93 -0
- package/src/components/views/shared/MaskIcon.vue +44 -0
- package/src/components/views/shared/ObjectColor.vue +31 -0
- package/src/components/views/shared/ObjectLabel.vue +30 -0
- package/src/components/views/shared/Opacity.vue +66 -0
- package/src/components/views/shared/VisibilityBtn.vue +25 -0
- package/src/components/views/shared/__tests__/MaskIcon.spec.ts +10 -0
- package/src/components/views/shared/__tests__/ObjectColor.spec.ts +10 -0
- package/src/components/views/shared/__tests__/ObjectLabel.spec.ts +10 -0
- package/src/components/views/shared/__tests__/Opacity.spec.ts +24 -0
- package/src/components/views/shared/__tests__/VisibilityBtn.spec.ts +11 -0
- package/src/components/views/types/annotation-tree-view-item-child-action.ts +6 -0
- package/src/components/views/types/annotation-tree-view-item-child.ts +9 -0
- package/src/components/views/types/annotation-tree-view-item.ts +13 -0
- package/src/components/views/types/markup-tree-view-item-child.ts +6 -0
- package/src/components/views/types/markup-tree-view-item.ts +14 -0
- package/src/components/views/types/mcad-object-tree-view-item.ts +13 -0
- package/src/composables/__tests__/useAnnotations.spec.ts +35 -0
- package/src/composables/__tests__/useEventListener.spec.ts +32 -0
- package/src/composables/__tests__/useIntroJs.spec.ts +51 -0
- package/src/composables/__tests__/useMarkups.spec.ts +39 -0
- package/src/composables/__tests__/useMcadObjects.spec.ts +36 -0
- package/src/composables/__tests__/useMouse.spec.ts +20 -0
- package/src/{components/modal/composables → composables}/__tests__/useNavigationCubeObserver.spec.ts +17 -12
- package/src/{dataLayer → composables}/__tests__/useViewer3cr.spec.ts +1 -2
- package/src/composables/useAnnotations.ts +37 -0
- package/src/composables/useEventListener.ts +25 -0
- package/src/composables/useIntroJs.ts +125 -0
- package/src/composables/useMarkups.ts +41 -0
- package/src/composables/useMcadObjects.ts +32 -0
- package/src/composables/useMouse.ts +14 -0
- package/src/{components/modal/composables → composables}/useNavigationCubeObserver.ts +35 -25
- package/src/composables/useScanMovement.ts +25 -0
- package/src/composables/useScanSliders.ts +36 -0
- package/src/composables/useVersion3cr.ts +7 -0
- package/src/composables/useViewer3cr.ts +7 -0
- package/src/composables/useViewerOptions.ts +35 -0
- package/src/{dataLayer → functions}/__tests__/clamp.spec.ts +1 -2
- package/src/functions/__tests__/layoutOverlayStyle.spec.ts +325 -0
- package/src/{helpers/__tests__/model-helper.spec.ts → functions/__tests__/modelHelper.spec.ts} +77 -40
- package/src/{notifications → functions}/__tests__/notification.spec.ts +19 -29
- package/src/functions/__tests__/parseAction.spec.ts +9 -0
- package/src/functions/__tests__/parseCallToAction.spec.ts +11 -0
- package/src/functions/__tests__/parseDataOverlay.spec.ts +15 -0
- package/src/functions/__tests__/parseDataOverlayData.spec.ts +9 -0
- package/src/functions/__tests__/parseDataOverlayEvent.spec.ts +10 -0
- package/src/functions/__tests__/parseMcadEvent.spec.ts +10 -0
- package/src/functions/layoutOverlayStyle.ts +84 -0
- package/src/{helpers → functions}/modelHelper.ts +79 -18
- package/src/{notifications → functions}/notification.ts +12 -14
- package/src/functions/parseAction.ts +9 -0
- package/src/functions/parseCallToAction.ts +9 -0
- package/src/functions/parseDataOverlay.ts +10 -0
- package/src/functions/parseDataOverlayData.ts +10 -0
- package/src/functions/parseDataOverlayEvent.ts +17 -0
- package/src/functions/parseMcadEvent.ts +10 -0
- package/src/functions/rgbaToCss.ts +13 -0
- package/src/main.ts +48 -9
- package/src/{dataLayer → models}/__tests__/eventHandlers.spec.ts +2 -3
- package/src/models/__tests__/loadViewerOptions.spec.ts +72 -0
- package/src/models/__tests__/loadViewerPayload.spec.ts +10 -0
- package/src/models/__tests__/scanState.spec.ts +190 -0
- package/src/models/callbacks.ts +4 -0
- package/src/models/loadViewerOptions.ts +40 -0
- package/src/models/loadViewerPayload.ts +24 -0
- package/src/{dataLayer → models}/scanState.ts +63 -74
- package/src/plugins/__tests__/usePlugins.spec.ts +12 -0
- package/src/plugins/__tests__/vuetify.spec.ts +3 -4
- package/src/plugins/usePlugins.ts +8 -0
- package/src/plugins/vuetify.ts +31 -65
- package/src/services/{gpt/__tests__ → __tests__}/gpt.service.spec.ts +2 -2
- package/src/services/__tests__/service-worker.service.spec.ts +32 -0
- package/src/{dataLayer/__tests__/viewer3cr.spec.ts → services/__tests__/viewer-3cr.service.spec.ts} +97 -36
- package/src/services/gpt.service.ts +17 -0
- package/src/services/service-worker.service.ts +16 -0
- package/src/{dataLayer/viewer3cr.ts → services/viewer-3cr.service.ts} +269 -150
- package/src/types/action.ts +13 -0
- package/src/types/call-to-action.ts +9 -0
- package/src/types/colour.ts +6 -0
- package/src/types/data-overlay-angle.ts +16 -0
- package/src/types/data-overlay-annotation.ts +18 -0
- package/src/types/data-overlay-data.ts +15 -0
- package/src/types/data-overlay-info.ts +14 -0
- package/src/types/data-overlay-interaction.ts +15 -0
- package/src/types/data-overlay-length.ts +16 -0
- package/src/types/data-overlay-markup.ts +7 -0
- package/src/types/data-overlay-mcad.ts +20 -0
- package/src/types/data-overlay-polygon.ts +18 -0
- package/src/types/data-overlay.ts +16 -0
- package/src/types/gpt-question.ts +4 -0
- package/src/types/gpt-response-payload.ts +6 -0
- package/src/types/mcad-object-interaction.ts +15 -0
- package/src/types/segment-angle.ts +5 -0
- package/src/types/vector2.ts +4 -0
- package/src/types/vector3.ts +5 -0
- package/test/fakers/action-data.faker.ts +11 -0
- package/test/fakers/action.faker.ts +19 -0
- package/test/fakers/call-to-action.faker.ts +17 -0
- package/test/fakers/colour.faker.ts +17 -0
- package/test/fakers/data-overlay-angle.faker.ts +37 -0
- package/test/fakers/data-overlay-annotation.faker.ts +41 -0
- package/test/fakers/data-overlay-data.faker.ts +97 -0
- package/test/fakers/data-overlay-info.faker.ts +29 -0
- package/test/fakers/data-overlay-interaction.faker.ts +62 -0
- package/test/fakers/data-overlay-length.faker.ts +37 -0
- package/test/fakers/data-overlay-mcad.faker.ts +40 -0
- package/test/fakers/data-overlay-polygon.faker.ts +39 -0
- package/test/fakers/gpt-question.faker.ts +11 -0
- package/test/fakers/gpt-response.faker.ts +12 -0
- package/test/fakers/invert-transform.faker.ts +16 -0
- package/test/fakers/mcad-object-interaction.faker.ts +22 -0
- package/test/fakers/orientation.faker.ts +17 -0
- package/test/fakers/segment-angle.faker.ts +12 -0
- package/test/fakers/vector2.faker.ts +12 -0
- package/test/fakers/vector3.faker.ts +16 -0
- package/test/plugins/findByTestId.ts +25 -0
- package/test/plugins/vuetify.ts +16 -0
- package/test/setup.ts +16 -5
- package/tsconfig.json +4 -15
- package/vite.config.mts +20 -46
- package/vitest.config.mts +24 -43
- package/index.ts +0 -72
- package/src/assets/images/dark/3DICOM.png +0 -0
- package/src/assets/images/dark/3dicom-logo.svg +0 -1
- package/src/assets/images/light/3DICOM.png +0 -0
- package/src/assets/images/light/3dicom-logo.svg +0 -1
- package/src/assets/logo.png +0 -0
- package/src/assets/logo.svg +0 -6
- package/src/components/WebGL3DR.vue +0 -102
- package/src/components/__tests__/webgl3dr.spec.ts +0 -37
- package/src/components/icons/liver.vue +0 -21
- package/src/components/loading/__tests__/loading-spinner.spec.ts +0 -11
- package/src/components/modal/ViewerAnnotationModal.vue +0 -111
- package/src/components/modal/ViewerAnnotations.vue +0 -289
- package/src/components/modal/__tests__/ViewerAnnotationModal.spec.ts +0 -79
- package/src/components/modal/composables/useEventListener.ts +0 -22
- package/src/components/selectors/__tests__/value-selector.spec.ts +0 -53
- package/src/components/sliders/DoubleSliderSelector.vue +0 -141
- package/src/components/sliders/__tests__/double-slider-selector.spec.ts +0 -104
- package/src/components/sliders/__tests__/vertical-slider-selector.spec.ts +0 -61
- package/src/dataLayer/__tests__/getIconForPreset.spec.ts +0 -40
- package/src/dataLayer/__tests__/patchDataOverlay.spec.ts +0 -88
- package/src/dataLayer/__tests__/scanState.spec.ts +0 -93
- package/src/dataLayer/getIconForPreset.ts +0 -11
- package/src/dataLayer/patchDataOverlay.ts +0 -101
- package/src/dataLayer/useViewer3cr.ts +0 -7
- package/src/helpers/__tests__/layout-overlay-style.spec.ts +0 -290
- package/src/helpers/__tests__/utils.spec.ts +0 -70
- package/src/helpers/layoutOverlayStyle.ts +0 -96
- package/src/helpers/utils.ts +0 -16
- package/src/models/Callbacks.ts +0 -2
- package/src/models/LoadViewerOptions.ts +0 -31
- package/src/models/LoadViewerPayload.ts +0 -9
- package/src/models/__tests__/load-viewer-options.spec.ts +0 -22
- package/src/plugins/__tests__/index.spec.ts +0 -19
- package/src/plugins/index.ts +0 -17
- package/src/services/gpt/gpt.service.ts +0 -35
- package/static/3cr-types-browser/index.ts +0 -74
- package/static/3cr-types-browser/types/Action.ts +0 -6
- package/static/3cr-types-browser/types/AlphaKeys.ts +0 -5
- package/static/3cr-types-browser/types/AnchorPoint.ts +0 -12
- package/static/3cr-types-browser/types/CallToAction.ts +0 -5
- package/static/3cr-types-browser/types/ColourData.ts +0 -7
- package/static/3cr-types-browser/types/ColourPresetData.ts +0 -9
- package/static/3cr-types-browser/types/CurrentDataOverlayState.ts +0 -6
- package/static/3cr-types-browser/types/CurrentScanState.ts +0 -22
- package/static/3cr-types-browser/types/DataOverlay.ts +0 -22
- package/static/3cr-types-browser/types/DataOverlayActions.ts +0 -14
- package/static/3cr-types-browser/types/DataOverlayData.ts +0 -8
- package/static/3cr-types-browser/types/DataOverlayEvent.ts +0 -8
- package/static/3cr-types-browser/types/DecryptionKey.ts +0 -4
- package/static/3cr-types-browser/types/DisplaySettings.ts +0 -10
- package/static/3cr-types-browser/types/EmptyPayload.ts +0 -3
- package/static/3cr-types-browser/types/EnumPayload.ts +0 -4
- package/static/3cr-types-browser/types/FileManagementActions.ts +0 -11
- package/static/3cr-types-browser/types/FlipValue.ts +0 -7
- package/static/3cr-types-browser/types/FrontEndInterfaces.ts +0 -14
- package/static/3cr-types-browser/types/GradientKeys.ts +0 -7
- package/static/3cr-types-browser/types/GreyscalePresetData.ts +0 -6
- package/static/3cr-types-browser/types/InitialDataOverlayState.ts +0 -6
- package/static/3cr-types-browser/types/InitialScanState.ts +0 -19
- package/static/3cr-types-browser/types/InteractionType.ts +0 -8
- package/static/3cr-types-browser/types/InteractivityActions.ts +0 -6
- package/static/3cr-types-browser/types/InteractivityState.ts +0 -4
- package/static/3cr-types-browser/types/InvertTransformData.ts +0 -6
- package/static/3cr-types-browser/types/LayoutActions.ts +0 -6
- package/static/3cr-types-browser/types/LayoutData.ts +0 -7
- package/static/3cr-types-browser/types/LoadDataSet.ts +0 -6
- package/static/3cr-types-browser/types/LoadSessionState.ts +0 -4
- package/static/3cr-types-browser/types/LocalLoadDataset.ts +0 -3
- package/static/3cr-types-browser/types/MovementData.ts +0 -7
- package/static/3cr-types-browser/types/NavigationCubeActions.ts +0 -8
- package/static/3cr-types-browser/types/NavigationCubeData.ts +0 -12
- package/static/3cr-types-browser/types/NavigationCubeTransform.ts +0 -9
- package/static/3cr-types-browser/types/NotificationPayload.ts +0 -7
- package/static/3cr-types-browser/types/NotificationsActions.ts +0 -6
- package/static/3cr-types-browser/types/Object.ts +0 -1
- package/static/3cr-types-browser/types/ObjectColour.ts +0 -7
- package/static/3cr-types-browser/types/ObjectIcon.ts +0 -5
- package/static/3cr-types-browser/types/ObjectInvert.ts +0 -7
- package/static/3cr-types-browser/types/ObjectSize.ts +0 -7
- package/static/3cr-types-browser/types/ObjectSize2D.ts +0 -7
- package/static/3cr-types-browser/types/ObjectVisible.ts +0 -5
- package/static/3cr-types-browser/types/PositionData.ts +0 -14
- package/static/3cr-types-browser/types/PresetsActions.ts +0 -4
- package/static/3cr-types-browser/types/RotationValue.ts +0 -7
- package/static/3cr-types-browser/types/ScanMovementActions.ts +0 -27
- package/static/3cr-types-browser/types/ScanMovementData.ts +0 -3
- package/static/3cr-types-browser/types/ScanOrientationActions.ts +0 -6
- package/static/3cr-types-browser/types/ScanStateActions.ts +0 -4
- package/static/3cr-types-browser/types/ScanView.ts +0 -6
- package/static/3cr-types-browser/types/SettingsData.ts +0 -12
- package/static/3cr-types-browser/types/SlicerData.ts +0 -9
- package/static/3cr-types-browser/types/SliderValue.ts +0 -4
- package/static/3cr-types-browser/types/SlidersActions.ts +0 -18
- package/static/3cr-types-browser/types/Vector2Data.ts +0 -5
- package/static/3cr-types-browser/types/Vector3Data.ts +0 -6
- package/static/3cr-types-browser/types/VectorMovementData.ts +0 -8
- package/static/3cr-types-browser/types/ViewInteractiveMode.ts +0 -5
- package/static/3cr-types-browser/types/ViewOrientation.ts +0 -8
- package/static/3cr-types-browser/types/ViewOrientations.ts +0 -10
- package/static/3cr-types-browser/types/ViewSelectionActions.ts +0 -9
- package/static/3cr-types-browser/types/ViewToggleData.ts +0 -7
- package/static/3cr-types-browser/types/VolumeOrientation.ts +0 -7
- package/test/helper.ts +0 -44
- /package/src/components/{loading → shared}/LoadingSpinner.vue +0 -0
- /package/src/components/{sliders → shared}/VerticalSliderSelector.vue +0 -0
- /package/{config.ts → src/config.ts} +0 -0
- /package/src/{dataLayer → functions}/clamp.ts +0 -0
- /package/src/{dataLayer → models}/eventHandlers.ts +0 -0
- /package/{static/3cr-types-browser/types/ActionData.ts → src/types/action-data.ts} +0 -0
|
@@ -1,195 +1,50 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
<DemoLicenceSendToPartyModal v-model:modal="m_demoLicenceSendToParty" />
|
|
5
|
-
<DemoLicenceEnableCloudStorageModal v-model:modal="m_demoLicenseEnableCloudStorage" />
|
|
6
|
-
<DemoPatientInfoModal v-model:modal="m_demoPatient" :is-modal-open="value" />
|
|
7
|
-
<DemoPatientShareToMobileModal v-model:modal="m_demoPatientShareToMobile" />
|
|
8
|
-
<DemoPatientSendToPartyModal v-model:modal="m_demoPatientSendToParty" />
|
|
9
|
-
<DemoPatientEnableCloudStorageModal v-model:modal="m_demoPatientEnableCloudStorage" />
|
|
10
|
-
<CloseViewerModal v-model:modal="m_closeDialog" :options="opts" @close="value = false"/>
|
|
11
|
-
<v-dialog
|
|
12
|
-
data-vuetify
|
|
13
|
-
:model-value="value"
|
|
14
|
-
:no-click-animation="true"
|
|
15
|
-
fullscreen
|
|
16
|
-
persistent
|
|
17
|
-
>
|
|
18
|
-
<v-card
|
|
19
|
-
id="invoice-table-modal"
|
|
20
|
-
class="pa-0 ma-0 position-relative motif-background overflow-y-hidden rounded-0"
|
|
21
|
-
height="100vh"
|
|
22
|
-
>
|
|
2
|
+
<v-dialog :model-value="value" :no-click-animation="true" fullscreen persistent>
|
|
3
|
+
<v-card class="pa-0 ma-0 position-relative motif-background overflow-y-hidden rounded-0" height="100vh">
|
|
23
4
|
<v-app-bar density="compact">
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
>
|
|
33
|
-
File
|
|
34
|
-
</v-btn>
|
|
35
|
-
</template>
|
|
36
|
-
<v-list>
|
|
37
|
-
<v-list-item
|
|
38
|
-
v-if="showOption('OnLoadNewDicomSeries')"
|
|
39
|
-
@click="executeOption('OnLoadNewDicomSeries')"
|
|
40
|
-
prepend-icon="upload"
|
|
41
|
-
>
|
|
42
|
-
<v-list-item-title>Load New DICOM Series</v-list-item-title>
|
|
43
|
-
</v-list-item>
|
|
44
|
-
<v-list-item
|
|
45
|
-
v-if="showOption('OnDownloadDicomSeries')"
|
|
46
|
-
@click="executeOption('OnDownloadDicomSeries')"
|
|
47
|
-
prepend-icon="download"
|
|
48
|
-
>
|
|
49
|
-
<v-list-item-title>Download DICOM Series</v-list-item-title>
|
|
50
|
-
</v-list-item>
|
|
51
|
-
<v-list-item
|
|
52
|
-
v-if="showOption('OnLoadSavedSession')"
|
|
53
|
-
@click="executeOption('OnLoadSavedSession')"
|
|
54
|
-
prepend-icon="sync"
|
|
55
|
-
>
|
|
56
|
-
<v-list-item-title> Load Saved Session </v-list-item-title>
|
|
57
|
-
</v-list-item>
|
|
58
|
-
<v-list-item
|
|
59
|
-
v-if="showOption('OnSendTo3rdParty')"
|
|
60
|
-
@click="executeOption('OnSendTo3rdParty')"
|
|
61
|
-
prepend-icon="send"
|
|
62
|
-
>
|
|
63
|
-
<v-list-item-title>Send to 3rd Party</v-list-item-title>
|
|
64
|
-
</v-list-item>
|
|
65
|
-
<v-list-item
|
|
66
|
-
v-if="showOption('OnShareToMobile')"
|
|
67
|
-
@click="executeOption('OnShareToMobile')"
|
|
68
|
-
prepend-icon="share"
|
|
69
|
-
>
|
|
70
|
-
<v-list-item-title>Share to Mobile / VR</v-list-item-title>
|
|
71
|
-
</v-list-item>
|
|
72
|
-
|
|
73
|
-
<v-list-item
|
|
74
|
-
@click="
|
|
75
|
-
executeOption('OnClosePopup');
|
|
76
|
-
alterValue(false);
|
|
77
|
-
"
|
|
78
|
-
prepend-icon="close"
|
|
79
|
-
>
|
|
80
|
-
<v-list-item-title>Close Viewer</v-list-item-title>
|
|
81
|
-
</v-list-item>
|
|
82
|
-
</v-list>
|
|
83
|
-
</v-menu>
|
|
84
|
-
<v-menu
|
|
85
|
-
v-model:model-value="introJsOpenMenu"
|
|
86
|
-
:persistent="introJsDisableMenu"
|
|
87
|
-
:no-click-animation="introJsDisableMenu"
|
|
88
|
-
:close-on-content-click="false"
|
|
89
|
-
>
|
|
90
|
-
<template #activator="{ props, isActive }">
|
|
91
|
-
<v-btn
|
|
92
|
-
v-bind="props"
|
|
93
|
-
:color="isActive ? 'secondary' : 'primary'"
|
|
94
|
-
:disabled="introJsDisableMenu"
|
|
95
|
-
prepend-icon="settings"
|
|
96
|
-
variant="flat"
|
|
97
|
-
>
|
|
98
|
-
Settings
|
|
99
|
-
</v-btn>
|
|
100
|
-
</template>
|
|
101
|
-
<v-card id="settings-card" width="350" class="pa-4">
|
|
102
|
-
<ValueSelector
|
|
103
|
-
v-model:value="scanState.Display.Brightness"
|
|
104
|
-
label="Adjust Brightness"
|
|
105
|
-
prepend="percent"
|
|
106
|
-
/>
|
|
107
|
-
<ValueSelector
|
|
108
|
-
v-model:value="scanState.Display.Contrast"
|
|
109
|
-
label="Adjust Contrast"
|
|
110
|
-
prepend="percent"
|
|
111
|
-
/>
|
|
112
|
-
<ValueSelector
|
|
113
|
-
v-model:value="scanState.Display.Opacity"
|
|
114
|
-
label="Adjust Opacity"
|
|
115
|
-
prepend="percent"
|
|
116
|
-
/>
|
|
117
|
-
<v-divider class="my-4" />
|
|
118
|
-
<ValueSelector
|
|
119
|
-
v-model:value="scanState.InteractionSettings.PanSensivitity"
|
|
120
|
-
:min="0"
|
|
121
|
-
:max="100"
|
|
122
|
-
label="Pan Sensitivity"
|
|
123
|
-
prepend="percent"
|
|
124
|
-
/>
|
|
125
|
-
<ValueSelector
|
|
126
|
-
v-model:value="scanState.InteractionSettings.ZoomSensitivity"
|
|
127
|
-
:min="0"
|
|
128
|
-
:max="100"
|
|
129
|
-
label="Zoom Sensitivity"
|
|
130
|
-
prepend="percent"
|
|
131
|
-
/>
|
|
132
|
-
<ValueSelector
|
|
133
|
-
v-model:value="scanState.InteractionSettings.RotateSensitivity"
|
|
134
|
-
:min="0"
|
|
135
|
-
:max="100"
|
|
136
|
-
label="Rotate Sensitivity"
|
|
137
|
-
prepend="percent"
|
|
138
|
-
/>
|
|
139
|
-
<ValueSelector
|
|
140
|
-
v-model:value="
|
|
141
|
-
scanState.InteractionSettings.CameraRotateSensitivity
|
|
142
|
-
"
|
|
143
|
-
:min="0"
|
|
144
|
-
:max="100"
|
|
145
|
-
label="Camera Rotate Sensitivity"
|
|
146
|
-
prepend="percent"
|
|
147
|
-
/>
|
|
148
|
-
<v-divider class="my-4" />
|
|
149
|
-
<NavigationCubeAction />
|
|
150
|
-
</v-card>
|
|
151
|
-
</v-menu>
|
|
5
|
+
<file-menu @close="alterValue(false)" />
|
|
6
|
+
<settings-menu
|
|
7
|
+
v-model="introJsMenu"
|
|
8
|
+
:activator-props="{ disabled: introJsMenuDisabled }"
|
|
9
|
+
:persistent="introJsMenuDisabled"
|
|
10
|
+
:no-click-animation="introJsMenuDisabled"
|
|
11
|
+
/>
|
|
12
|
+
<auto-annotate-btn class="mr-2 transparent" />
|
|
152
13
|
<v-spacer />
|
|
153
14
|
<div class="font-weight-bold">
|
|
154
|
-
<span v-if="isDemo" class="text-capitalize">
|
|
155
|
-
|
|
156
|
-
</span>
|
|
157
|
-
<span v-else class="text-capitalize">
|
|
158
|
-
3DICOM Patient Viewer |
|
|
159
|
-
</span>
|
|
15
|
+
<span v-if="isDemo" class="text-capitalize">3DICOM {{ demoType }} DEMO |</span>
|
|
16
|
+
<span v-else class="text-capitalize">3DICOM Patient Viewer |</span>
|
|
160
17
|
Not for Diagnostic Use
|
|
161
18
|
</div>
|
|
162
19
|
<v-spacer />
|
|
163
20
|
<v-btn
|
|
164
21
|
class="ma-1 mr-0 pa-1"
|
|
22
|
+
data-testid="layout-2x2"
|
|
165
23
|
height="36"
|
|
166
24
|
style="min-width: 36px !important"
|
|
167
25
|
:color="isLayout2x2 ? 'secondary' : 'primary'"
|
|
168
26
|
@click="viewer3cr.layouts(LayoutActions.lo02)"
|
|
169
|
-
|
|
170
|
-
<v-
|
|
171
|
-
|
|
172
|
-
</v-tooltip>
|
|
27
|
+
>
|
|
28
|
+
<v-icon>grid_view</v-icon>
|
|
29
|
+
<v-tooltip location="bottom" activator="parent"> Change Layout to 2:2 </v-tooltip>
|
|
173
30
|
</v-btn>
|
|
174
31
|
<v-btn
|
|
175
32
|
class="ma-1 mr-1 pa-1"
|
|
33
|
+
data-testid="layout-1x3"
|
|
176
34
|
height="36"
|
|
177
35
|
style="min-width: 36px !important"
|
|
178
36
|
:color="isLayout1x3 ? 'secondary' : 'primary'"
|
|
179
37
|
@click="viewer3cr.layouts(LayoutActions.lo03)"
|
|
180
|
-
><v-icon style="rotate: -90deg">view_comfy</v-icon>
|
|
181
|
-
<v-tooltip location="bottom" activator="parent">
|
|
182
|
-
Change Layout to 1:3
|
|
183
|
-
</v-tooltip></v-btn
|
|
184
38
|
>
|
|
185
|
-
|
|
186
|
-
|
|
39
|
+
<v-icon style="rotate: -90deg">view_comfy</v-icon>
|
|
40
|
+
<v-tooltip location="bottom" activator="parent"> Change Layout to 1:3 </v-tooltip>
|
|
187
41
|
</v-btn>
|
|
42
|
+
<v-btn variant="flat" color="red" @click="alterValue(false)"> Close Viewer </v-btn>
|
|
188
43
|
</v-app-bar>
|
|
189
|
-
<ViewerNavigationDrawer v-model:drawer="drawer"
|
|
44
|
+
<ViewerNavigationDrawer v-model:drawer="drawer" @update:expanded="expanded = $event" />
|
|
190
45
|
<v-main>
|
|
191
46
|
<WebGL3DR
|
|
192
|
-
v-show="value &&
|
|
47
|
+
v-show="value && !scanLoading"
|
|
193
48
|
ref="webGl3dr"
|
|
194
49
|
@instance_loaded="load"
|
|
195
50
|
@dblclick="viewer3cr.viewSelection(ViewSelectionActions.vs05)"
|
|
@@ -197,108 +52,42 @@
|
|
|
197
52
|
@mouseleave="onMouseLeave"
|
|
198
53
|
>
|
|
199
54
|
<div
|
|
200
|
-
v-for="
|
|
55
|
+
v-for="layout in scanState.Layout.PositionData"
|
|
201
56
|
:key="getCurrentView(layout)"
|
|
202
|
-
:id="`view-${getCurrentView(layout)}`"
|
|
203
|
-
:ref="(el) => (elements[index] = el)"
|
|
204
|
-
class="bordered-event-window"
|
|
205
57
|
:style="generateDivStyleForLayout(layout, webGl3dr!.canvas)"
|
|
206
58
|
>
|
|
207
|
-
<
|
|
208
|
-
<template #default="{ isHovering, props }">
|
|
209
|
-
<v-row v-bind="props" class="flex-nowrap h-100" no-gutters>
|
|
210
|
-
<v-col style="min-width: 0">
|
|
211
|
-
<v-row class="flex-column h-100" no-gutters>
|
|
212
|
-
<v-col class="flex-grow-0">
|
|
213
|
-
<div class="d-flex pa-2 pl-3 align-center">
|
|
214
|
-
<span style="color: white">{{ getViewName(getCurrentView(layout)) }}</span>
|
|
215
|
-
<v-tooltip v-if="isHorizontalFlip(getCurrentView(layout))" location="bottom">
|
|
216
|
-
<template #activator="{ props }">
|
|
217
|
-
<v-icon
|
|
218
|
-
v-bind="props"
|
|
219
|
-
icon="swap_horiz"
|
|
220
|
-
color="blue-darken-1"
|
|
221
|
-
class="ml-2"
|
|
222
|
-
/>
|
|
223
|
-
</template>
|
|
224
|
-
<span>This view has been flipped horizontally</span>
|
|
225
|
-
</v-tooltip>
|
|
226
|
-
<v-tooltip v-if="isVerticalFlip(getCurrentView(layout))" location="bottom">
|
|
227
|
-
<template #activator="{ props }">
|
|
228
|
-
<v-icon
|
|
229
|
-
v-bind="props"
|
|
230
|
-
icon="swap_vert"
|
|
231
|
-
color="blue-darken-1"
|
|
232
|
-
class="ml-2"
|
|
233
|
-
/>
|
|
234
|
-
</template>
|
|
235
|
-
<span>This view has been flipped vertically</span>
|
|
236
|
-
</v-tooltip>
|
|
237
|
-
</div>
|
|
238
|
-
</v-col>
|
|
239
|
-
<v-spacer />
|
|
240
|
-
<v-col class="flex-grow-0">
|
|
241
|
-
<Transition>
|
|
242
|
-
<div v-show="isHovering || modals[getCurrentView(layout)]">
|
|
243
|
-
<ViewerActionRail
|
|
244
|
-
:view="getCurrentView(layout)"
|
|
245
|
-
:element="elements[index]"
|
|
246
|
-
@modal="onActionModal"
|
|
247
|
-
/>
|
|
248
|
-
</div>
|
|
249
|
-
</Transition>
|
|
250
|
-
</v-col>
|
|
251
|
-
</v-row>
|
|
252
|
-
</v-col>
|
|
253
|
-
<v-col class="flex-grow-0">
|
|
254
|
-
<VerticalSliderSelector
|
|
255
|
-
class="h-100 my-0 pa-2 pr-3"
|
|
256
|
-
v-if="getCurrentView(layout) === ScanView.Transverse"
|
|
257
|
-
v-model:value="scanState.Orientations.Transverse.Slice"
|
|
258
|
-
v-bind="tMinMax"
|
|
259
|
-
/>
|
|
260
|
-
<VerticalSliderSelector
|
|
261
|
-
class="h-100 my-0 pa-2 pr-3"
|
|
262
|
-
v-if="getCurrentView(layout) === ScanView.Coronal"
|
|
263
|
-
v-model:value="scanState.Orientations.Coronal.Slice"
|
|
264
|
-
v-bind="cMinMax"
|
|
265
|
-
/>
|
|
266
|
-
<VerticalSliderSelector
|
|
267
|
-
class="h-100 my-0 pa-2 pr-3"
|
|
268
|
-
v-if="getCurrentView(layout) === ScanView.Sagittal"
|
|
269
|
-
v-model:value="scanState.Orientations.Sagittal.Slice"
|
|
270
|
-
v-bind="sMinMax"
|
|
271
|
-
/>
|
|
272
|
-
</v-col>
|
|
273
|
-
</v-row>
|
|
274
|
-
</template>
|
|
275
|
-
</v-hover>
|
|
59
|
+
<ViewerScanView class="w-100 h-100" :view="getCurrentView(layout)" />
|
|
276
60
|
</div>
|
|
277
61
|
</WebGL3DR>
|
|
278
|
-
<
|
|
62
|
+
<data-overlay-modal-manager />
|
|
279
63
|
</v-main>
|
|
280
|
-
<LoadingSpinner v-if="!instanceLoaded" />
|
|
281
64
|
<LoadingSpinner v-if="scanLoading" text="Rendering your scan in 3D" />
|
|
282
65
|
</v-card>
|
|
283
66
|
</v-dialog>
|
|
67
|
+
<DemoLicenceInfoModal v-model:modal="m_demo" :is-modal-open="value" />
|
|
68
|
+
<DemoLicenceShareToMobileModal v-model:modal="m_demoLicenceShareToMobile" />
|
|
69
|
+
<DemoLicenceSendToPartyModal v-model:modal="m_demoLicenceSendToParty" />
|
|
70
|
+
<DemoLicenceEnableCloudStorageModal v-model:modal="m_demoLicenseEnableCloudStorage" />
|
|
71
|
+
<DemoPatientInfoModal v-model:modal="m_demoPatient" :is-modal-open="value" />
|
|
72
|
+
<DemoPatientShareToMobileModal v-model:modal="m_demoPatientShareToMobile" />
|
|
73
|
+
<DemoPatientSendToPartyModal v-model:modal="m_demoPatientSendToParty" />
|
|
74
|
+
<DemoPatientEnableCloudStorageModal v-model:modal="m_demoPatientEnableCloudStorage" />
|
|
75
|
+
<CloseViewerModal v-model:modal="m_closeDialog" @close="value = false" />
|
|
284
76
|
</template>
|
|
285
77
|
|
|
286
|
-
<!-- /* c8 ignore stop */ -->
|
|
287
78
|
<script setup lang="ts">
|
|
288
|
-
import { generateDivStyleForLayout } from
|
|
79
|
+
import { generateDivStyleForLayout } from '@/functions/layoutOverlayStyle';
|
|
289
80
|
import {
|
|
290
|
-
|
|
81
|
+
DataOverlaysActions,
|
|
291
82
|
FileManagementActions,
|
|
292
83
|
FrontEndInterfaces,
|
|
293
84
|
LayoutActions,
|
|
85
|
+
McadActions,
|
|
294
86
|
NotificationsActions,
|
|
295
|
-
ScanMovementActions,
|
|
296
87
|
ScanStateActions,
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
} from "@3cr/types-ts";
|
|
301
|
-
import {ComponentInstance, computed, nextTick, onBeforeUnmount, onMounted, ref, unref, watch, WatchSource} from "vue";
|
|
88
|
+
ViewSelectionActions
|
|
89
|
+
} from '@3cr/types-ts';
|
|
90
|
+
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
302
91
|
import {
|
|
303
92
|
checkIsDemo,
|
|
304
93
|
demoOptions,
|
|
@@ -311,92 +100,85 @@ import {
|
|
|
311
100
|
m_demoPatient,
|
|
312
101
|
m_demoPatientEnableCloudStorage,
|
|
313
102
|
m_demoPatientSendToParty,
|
|
314
|
-
m_demoPatientShareToMobile
|
|
315
|
-
} from
|
|
316
|
-
import { handleNotification } from
|
|
317
|
-
import { LoadViewerPayload } from
|
|
318
|
-
import {
|
|
319
|
-
defaultLoadViewerOptions,
|
|
320
|
-
LoadViewerOptions,
|
|
321
|
-
} from "@/models/LoadViewerOptions";
|
|
103
|
+
m_demoPatientShareToMobile
|
|
104
|
+
} from '@/components/demo/options';
|
|
105
|
+
import { handleNotification } from '@/functions/notification';
|
|
106
|
+
import { defaultLoadViewerPayload, LoadViewerPayload } from '@/models/loadViewerPayload';
|
|
107
|
+
import { defaultLoadViewerOptions, LoadViewerOptions } from '@/models/loadViewerOptions';
|
|
322
108
|
import {
|
|
323
|
-
cMinMax,
|
|
324
109
|
getCurrentView,
|
|
325
|
-
getViewName,
|
|
326
|
-
initialScanState,
|
|
327
|
-
isFullscreen,
|
|
328
|
-
isHorizontalFlip,
|
|
329
110
|
isLayout1x3,
|
|
330
111
|
isLayout2x2,
|
|
331
|
-
isVerticalFlip,
|
|
332
|
-
previousLayout,
|
|
333
112
|
scanState,
|
|
334
|
-
|
|
113
|
+
setDataOverlayEvent,
|
|
335
114
|
setDataOverlayState,
|
|
336
115
|
setInitialDataOverlayState,
|
|
116
|
+
setInitialMcadState,
|
|
337
117
|
setInitialScanStateFromPayload,
|
|
118
|
+
setMcadEvent,
|
|
119
|
+
setMcadState,
|
|
338
120
|
setScanStateFromPayload,
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
} from
|
|
345
|
-
import
|
|
346
|
-
import
|
|
347
|
-
import
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
import { useNavigationCubeObserver } from "@/components/modal/composables/useNavigationCubeObserver";
|
|
351
|
-
|
|
352
|
-
export interface Props {
|
|
121
|
+
transactionStarted
|
|
122
|
+
} from '@/models/scanState';
|
|
123
|
+
import { useViewer3cr } from '@/composables/useViewer3cr';
|
|
124
|
+
import { useNavigationCubeObserver } from '@/composables/useNavigationCubeObserver';
|
|
125
|
+
import { mockDemoViewerStlDecimator, useViewerOptions } from '@/composables/useViewerOptions';
|
|
126
|
+
import { useScanMovement } from '@/composables/useScanMovement';
|
|
127
|
+
import { useScanSliders } from '@/composables/useScanSliders';
|
|
128
|
+
import { useIntroJs } from '@/composables/useIntroJs';
|
|
129
|
+
import WebGL3DR from '@/components/modal/WebGL3DR.vue';
|
|
130
|
+
|
|
131
|
+
interface Props {
|
|
353
132
|
payload?: LoadViewerPayload;
|
|
354
133
|
options?: LoadViewerOptions;
|
|
355
134
|
}
|
|
356
135
|
|
|
357
|
-
const emit = defineEmits<{
|
|
358
|
-
instanceLoaded: [void];
|
|
359
|
-
}>();
|
|
360
|
-
|
|
361
136
|
const props = withDefaults(defineProps<Props>(), {
|
|
362
|
-
payload: () =>
|
|
363
|
-
|
|
364
|
-
DecryptionKey: {
|
|
365
|
-
Iv: "x856FgjpYDsRhIa3BFj5cg==",
|
|
366
|
-
Key: "OWjSMiL/ewUV1V6fGybhKcTyiysTPsIMp2DjdVoOUGI=",
|
|
367
|
-
},
|
|
368
|
-
}),
|
|
369
|
-
options: () => defaultLoadViewerOptions,
|
|
137
|
+
payload: () => defaultLoadViewerPayload,
|
|
138
|
+
options: () => defaultLoadViewerOptions
|
|
370
139
|
});
|
|
371
140
|
|
|
141
|
+
useScanMovement();
|
|
142
|
+
useScanSliders();
|
|
372
143
|
const viewer3cr = useViewer3cr();
|
|
144
|
+
const opts = useViewerOptions();
|
|
145
|
+
const { intro } = useIntroJs();
|
|
373
146
|
const webGl3dr = ref<typeof WebGL3DR>();
|
|
374
147
|
const observer = ref<ResizeObserver>();
|
|
375
148
|
const value = ref<boolean>(false);
|
|
376
149
|
const drawer = ref<boolean>(false);
|
|
377
150
|
const expanded = ref<number | undefined>();
|
|
378
151
|
const scanLoading = ref<boolean>(true);
|
|
379
|
-
const instanceLoaded = ref<boolean>(true);
|
|
380
|
-
const elements = ref<ComponentInstance<any>[]>([]);
|
|
381
152
|
const m_closeDialog = ref<boolean>(false);
|
|
382
|
-
const
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
153
|
+
const introJsMenu = ref<boolean>(false);
|
|
154
|
+
const introJsMenuDisabled = ref<boolean>(false);
|
|
155
|
+
|
|
156
|
+
watch(
|
|
157
|
+
() => props.options,
|
|
158
|
+
(value: LoadViewerOptions) => {
|
|
159
|
+
opts.value = isDemo.value ? demoOptions.value : value;
|
|
160
|
+
},
|
|
161
|
+
{ immediate: true }
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
watch(isDemo, (demo: boolean) => {
|
|
165
|
+
opts.value = demo ? demoOptions.value : props.options;
|
|
394
166
|
});
|
|
395
167
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
168
|
+
/* istanbul ignore next -- @preserve */
|
|
169
|
+
watch(
|
|
170
|
+
() => intro.value.getCurrentStep(),
|
|
171
|
+
(step) => {
|
|
172
|
+
const lock = step === 4;
|
|
173
|
+
introJsMenu.value = lock;
|
|
174
|
+
introJsMenuDisabled.value = lock;
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
intro.value.refresh(true);
|
|
177
|
+
}, 400);
|
|
178
|
+
}
|
|
179
|
+
);
|
|
399
180
|
|
|
181
|
+
/* istanbul ignore next -- @preserve */
|
|
400
182
|
onMounted(() => {
|
|
401
183
|
viewer3cr.addInterfaceHandler(FrontEndInterfaces.notifications, async (message: string, action: string) => {
|
|
402
184
|
await handleNotification(action as NotificationsActions, message);
|
|
@@ -404,17 +186,32 @@ onMounted(() => {
|
|
|
404
186
|
|
|
405
187
|
viewer3cr.addActionHandler(FileManagementActions.fm02, async (message: string) => {
|
|
406
188
|
setInitialScanStateFromPayload(message);
|
|
189
|
+
if (opts.value.OnScanLoaded) {
|
|
190
|
+
await opts.value.OnScanLoaded(scanState.value);
|
|
191
|
+
}
|
|
192
|
+
|
|
407
193
|
await nextTick();
|
|
408
194
|
transactionStarted.value = false;
|
|
409
195
|
scanLoading.value = false;
|
|
410
196
|
drawer.value = true;
|
|
411
|
-
if (unref(isDemo)) {
|
|
412
|
-
await viewer3cr.loadDataOverlay("https://webgl-3dr.singular.health/test_scans/sample_annotations.json");
|
|
413
|
-
}
|
|
414
197
|
observer.value = useNavigationCubeObserver(webGl3dr.value!.canvas);
|
|
415
|
-
await
|
|
198
|
+
await loadDemoData();
|
|
199
|
+
await intro.value.start();
|
|
416
200
|
});
|
|
417
201
|
|
|
202
|
+
viewer3cr.addActionHandler(
|
|
203
|
+
FileManagementActions.fm09,
|
|
204
|
+
async (_1: string, returnChannel: string, returnTo: string) => {
|
|
205
|
+
if (opts.value.OnResolveUrls) {
|
|
206
|
+
const keys = JSON.parse(returnChannel) as string[];
|
|
207
|
+
const urls = await opts.value.OnResolveUrls(keys);
|
|
208
|
+
await viewer3cr.loadMcadObjects(undefined, urls, returnTo);
|
|
209
|
+
} else {
|
|
210
|
+
throw new Error('OnResolveUrls has not been defined in LoadViewerOptions');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
|
|
418
215
|
viewer3cr.addActionHandler(ScanStateActions.ss01, async (message: string) => {
|
|
419
216
|
await setScanStateFromPayload(message);
|
|
420
217
|
});
|
|
@@ -423,16 +220,36 @@ onMounted(() => {
|
|
|
423
220
|
setDataOverlayState(message);
|
|
424
221
|
});
|
|
425
222
|
|
|
426
|
-
viewer3cr.addActionHandler(
|
|
223
|
+
viewer3cr.addActionHandler(ScanStateActions.ss03, (message: string) => {
|
|
224
|
+
setMcadState(message);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
viewer3cr.addActionHandler(DataOverlaysActions.do01, (message: string) => {
|
|
427
228
|
setInitialDataOverlayState(message);
|
|
428
229
|
});
|
|
429
230
|
|
|
430
|
-
viewer3cr.addActionHandler(
|
|
431
|
-
|
|
231
|
+
viewer3cr.addActionHandler(DataOverlaysActions.do02, (message: string) => {
|
|
232
|
+
setDataOverlayEvent(message);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
viewer3cr.addActionHandler(DataOverlaysActions.do07, (message: string) => {
|
|
236
|
+
setDataOverlayEvent(message);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
viewer3cr.addActionHandler('mu_17', (message: string) => {
|
|
240
|
+
setDataOverlayEvent(message);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
viewer3cr.addActionHandler('mu_18', (message: string) => {
|
|
244
|
+
setDataOverlayEvent(message);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
viewer3cr.addActionHandler(McadActions.mc01, (message: string) => {
|
|
248
|
+
setInitialMcadState(message);
|
|
432
249
|
});
|
|
433
250
|
|
|
434
|
-
viewer3cr.addActionHandler(
|
|
435
|
-
|
|
251
|
+
viewer3cr.addActionHandler(McadActions.mc02, (message: string) => {
|
|
252
|
+
setMcadEvent(message);
|
|
436
253
|
});
|
|
437
254
|
});
|
|
438
255
|
|
|
@@ -442,78 +259,6 @@ onBeforeUnmount(() => {
|
|
|
442
259
|
}
|
|
443
260
|
});
|
|
444
261
|
|
|
445
|
-
function showOption(key: keyof LoadViewerOptions): boolean {
|
|
446
|
-
return opts.value[key] !== undefined;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
async function executeOption(key: keyof LoadViewerOptions) {
|
|
450
|
-
const functionToExecute = opts.value[key];
|
|
451
|
-
if (functionToExecute !== undefined) {
|
|
452
|
-
await functionToExecute();
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
function onActionModal(value: boolean, view: ScanView): void {
|
|
457
|
-
modals.value[view] = value;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
type WatchSlidersType = { [key in SlidersActions]: WatchSource<number> };
|
|
461
|
-
const watchSliders: WatchSlidersType = {
|
|
462
|
-
[SlidersActions.sl01]: () => scanState.value.Display.Brightness,
|
|
463
|
-
[SlidersActions.sl02]: () => scanState.value.Display.Contrast,
|
|
464
|
-
[SlidersActions.sl03]: () => scanState.value.Display.Opacity,
|
|
465
|
-
[SlidersActions.sl04]: () => scanState.value.Display.WindowLower,
|
|
466
|
-
[SlidersActions.sl05]: () => scanState.value.Display.WindowUpper,
|
|
467
|
-
[SlidersActions.sl06]: () => scanState.value.Display.ThresholdLower,
|
|
468
|
-
[SlidersActions.sl07]: () => scanState.value.Display.ThresholdUpper,
|
|
469
|
-
[SlidersActions.sl08]: () => scanState.value.Slice.TransverseLower,
|
|
470
|
-
[SlidersActions.sl09]: () => scanState.value.Orientations.Transverse.Slice,
|
|
471
|
-
[SlidersActions.sl10]: () => scanState.value.Slice.TransverseUpper,
|
|
472
|
-
[SlidersActions.sl11]: () => scanState.value.Slice.SagittalLower,
|
|
473
|
-
[SlidersActions.sl12]: () => scanState.value.Orientations.Sagittal.Slice,
|
|
474
|
-
[SlidersActions.sl13]: () => scanState.value.Slice.SagittalUpper,
|
|
475
|
-
[SlidersActions.sl14]: () => scanState.value.Slice.CoronalLower,
|
|
476
|
-
[SlidersActions.sl15]: () => scanState.value.Orientations.Coronal.Slice,
|
|
477
|
-
[SlidersActions.sl16]: () => scanState.value.Slice.CoronalUpper,
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
for (const slider of Object.keys(watchSliders)) {
|
|
481
|
-
watch(
|
|
482
|
-
watchSliders[slider as keyof WatchSlidersType],
|
|
483
|
-
async (value: number) => {
|
|
484
|
-
await viewer3cr.sliderHandler(slider as SlidersActions, value);
|
|
485
|
-
}
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
type WatchScanMovementType = {
|
|
490
|
-
[key in ScanMovementActions]: WatchSource<number>;
|
|
491
|
-
};
|
|
492
|
-
|
|
493
|
-
//@ts-ignore
|
|
494
|
-
const watchScanMovement: WatchScanMovementType = {
|
|
495
|
-
[ScanMovementActions.sm05]: () =>
|
|
496
|
-
scanState.value.InteractionSettings.PanSensivitity,
|
|
497
|
-
[ScanMovementActions.sm08]: () =>
|
|
498
|
-
scanState.value.InteractionSettings.ZoomSensitivity,
|
|
499
|
-
[ScanMovementActions.sm10]: () =>
|
|
500
|
-
scanState.value.InteractionSettings.RotateSensitivity,
|
|
501
|
-
[ScanMovementActions.sm12]: () =>
|
|
502
|
-
scanState.value.InteractionSettings.CameraRotateSensitivity,
|
|
503
|
-
};
|
|
504
|
-
|
|
505
|
-
for (const scanMovement of Object.keys(watchScanMovement)) {
|
|
506
|
-
watch(
|
|
507
|
-
watchScanMovement[scanMovement as keyof typeof watchScanMovement],
|
|
508
|
-
async (value: number) => {
|
|
509
|
-
await viewer3cr.scanMovementHandler(
|
|
510
|
-
scanMovement as ScanMovementActions,
|
|
511
|
-
value
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
262
|
function alterValue(val: boolean) {
|
|
518
263
|
if (!val) {
|
|
519
264
|
m_closeDialog.value = true;
|
|
@@ -524,20 +269,20 @@ function alterValue(val: boolean) {
|
|
|
524
269
|
value.value = val;
|
|
525
270
|
}
|
|
526
271
|
|
|
272
|
+
/* istanbul ignore next -- @preserve */
|
|
527
273
|
async function loadSession(url: string): Promise<void> {
|
|
528
|
-
if (url.includes('
|
|
529
|
-
await viewer3cr.
|
|
274
|
+
if (url.includes('3crs')) {
|
|
275
|
+
await viewer3cr.loadScanSession({ Url: url });
|
|
276
|
+
} else if (url.includes('3crds')) {
|
|
277
|
+
await viewer3cr.setDataOverlaySession({ Url: url });
|
|
530
278
|
} else if (url.includes('3crms')) {
|
|
531
|
-
await viewer3cr.
|
|
532
|
-
} else if (url.includes('3crs')) {
|
|
533
|
-
await viewer3cr.loadScanSession(url);
|
|
279
|
+
await viewer3cr.loadMcadObjects({ Url: url });
|
|
534
280
|
} else {
|
|
535
281
|
throw new Error('Invalid URL type');
|
|
536
282
|
}
|
|
537
283
|
}
|
|
538
284
|
|
|
539
285
|
async function load(): Promise<void> {
|
|
540
|
-
instanceLoaded.value = true;
|
|
541
286
|
scanLoading.value = true;
|
|
542
287
|
await viewer3cr.loadScan(props.payload);
|
|
543
288
|
}
|
|
@@ -550,192 +295,29 @@ async function onMouseLeave(): Promise<void> {
|
|
|
550
295
|
await viewer3cr.hoverOverCanvas(false);
|
|
551
296
|
}
|
|
552
297
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
const expandHandle = watch(expanded, async () => {
|
|
564
|
-
// For some reason introjs refresh by itself doesn't work here
|
|
565
|
-
if (intro && intro.currentStep() === 1) {
|
|
566
|
-
await sleep(400);
|
|
567
|
-
const skinToBone = document.getElementById('skin-to-bone');
|
|
568
|
-
const floatingElement = document.querySelector('.introjsFloatingElement') as HTMLElement | null;
|
|
569
|
-
intro._introItems[1].element = skinToBone ?? floatingElement;
|
|
570
|
-
intro.refresh(true);
|
|
571
|
-
}
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
const blurActiveElement = () => {
|
|
575
|
-
(document.activeElement as HTMLElement).blur();
|
|
576
|
-
};
|
|
577
|
-
|
|
578
|
-
intro = await introJs()
|
|
579
|
-
.setOptions({
|
|
580
|
-
exitOnOverlayClick: false,
|
|
581
|
-
keyboardNavigation: false,
|
|
582
|
-
dontShowAgain: true,
|
|
583
|
-
steps: [
|
|
584
|
-
{
|
|
585
|
-
title: "Take the Viewer Tour",
|
|
586
|
-
intro:
|
|
587
|
-
`Welcome to the ${tier.value} Online DICOM Viewer.` +
|
|
588
|
-
"<br/><br/>Take the short interative tour to better visualize your medical images in 2D and 3D.",
|
|
589
|
-
position: "floating",
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
title: "Density Slider",
|
|
593
|
-
intro:
|
|
594
|
-
"Move the <em>lower density slider</em> to the right to hide softer tissue like skin and view internal organs." +
|
|
595
|
-
"<br/><br/>For more precise control, change the numbers in the boxes above or use the <em>Fine Adjustment</em> slider below.",
|
|
596
|
-
element: "#skin-to-bone",
|
|
597
|
-
position: "right",
|
|
598
|
-
},
|
|
599
|
-
{
|
|
600
|
-
title: "3D Viewing Controls",
|
|
601
|
-
intro:
|
|
602
|
-
"With your cursor placed in the 3D view, <b>scroll to zoom</b> & <b>click and drag to rotate</b>." +
|
|
603
|
-
"<br/><br/>You can also view the 3D view in full screen, reset the view, and cut into the 3D model from each side using the <em>3D slicing tool</em>.",
|
|
604
|
-
element: `#view-${ScanView.Volume}`,
|
|
605
|
-
},
|
|
606
|
-
{
|
|
607
|
-
title: "2D Viewing Controls",
|
|
608
|
-
intro:
|
|
609
|
-
"With your mouse in the 2D views, <b>scroll to navigate through the 2D images</b>, and use <b>Shift + Arrows to Pan and Zoom</b>." +
|
|
610
|
-
"<br/><br/>Use the icons to <em>Fullscreen</em>, <em>Reset</em>, <em>Rotate</em>, and <em>Flip</em> each individual 2D view.",
|
|
611
|
-
element: `#view-${ScanView.Sagittal}`,
|
|
612
|
-
},
|
|
613
|
-
{
|
|
614
|
-
title: "Global settings",
|
|
615
|
-
intro:
|
|
616
|
-
"Accurately change the <b>brightness</b>, <b>contrast</b>, and <b>opacity</b> to enhance the appearance of your medical images." +
|
|
617
|
-
"<br/><br/>Adjust the sensitivity of mouse and keyboard inputs to suit your preferences.",
|
|
618
|
-
element: "#settings-card",
|
|
619
|
-
position: "right",
|
|
620
|
-
},
|
|
621
|
-
{
|
|
622
|
-
title: "Stay Tuned for Updates",
|
|
623
|
-
intro:
|
|
624
|
-
'<img src="https://c.tenor.com/S4Sz_yvlLn4AAAAC/cats-cat.gif" alt="cat" width="260" height="260">' +
|
|
625
|
-
"<br/>Us working hard on new features",
|
|
626
|
-
position: "floating",
|
|
627
|
-
},
|
|
628
|
-
],
|
|
629
|
-
})
|
|
630
|
-
.onbeforechange(function (
|
|
631
|
-
el: HTMLElement,
|
|
632
|
-
step: number,
|
|
633
|
-
direction: "forward" | "backward"
|
|
634
|
-
) {
|
|
635
|
-
// Focus on volume view if moving to step 2
|
|
636
|
-
modals.value[ScanView.Volume] = step === 2;
|
|
637
|
-
|
|
638
|
-
// Focus on sagittal view if moving to step 3
|
|
639
|
-
modals.value[ScanView.Sagittal] = step === 3;
|
|
640
|
-
|
|
641
|
-
// If the user has enabled full-screen, turn it off for steps 2 and 3
|
|
642
|
-
if (isFullscreen.value && (step === 2 || step === 3)) {
|
|
643
|
-
viewer3cr
|
|
644
|
-
.layouts(previousLayout.value)
|
|
645
|
-
.then(() => nextTick())
|
|
646
|
-
.then(() => this.refresh(true))
|
|
647
|
-
.then(() => direction === "forward" ? this.nextStep() : this.previousStep());
|
|
648
|
-
return false;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// Wait for menu animation before focusing if moving to step 4
|
|
652
|
-
if (!introJsOpenMenu.value && step === 4) {
|
|
653
|
-
introJsOpenMenu.value = true;
|
|
654
|
-
introJsDisableMenu.value = true;
|
|
655
|
-
sleep(400)
|
|
656
|
-
.then(() => this.refresh(true))
|
|
657
|
-
.then(() => direction === "forward" ? this.nextStep() : this.previousStep());
|
|
658
|
-
return false;
|
|
659
|
-
} else if (introJsOpenMenu.value && step !== 4) {
|
|
660
|
-
introJsOpenMenu.value = false;
|
|
661
|
-
introJsDisableMenu.value = false;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// Only show Don't Show Again on last step
|
|
665
|
-
const introjsDontShowAgain = document.querySelector(".introjs-dontShowAgain") as HTMLElement | null;
|
|
666
|
-
if (introjsDontShowAgain) {
|
|
667
|
-
const lastStep = this._options.steps.length - 1;
|
|
668
|
-
introjsDontShowAgain.style.display = step !== lastStep ? "none" : "block";
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
return true;
|
|
672
|
-
})
|
|
673
|
-
.onchange(() => {
|
|
674
|
-
setTimeout(() => blurActiveElement(), 500);
|
|
675
|
-
})
|
|
676
|
-
.onexit(() => {
|
|
677
|
-
introJsOpenMenu.value = false;
|
|
678
|
-
introJsDisableMenu.value = false;
|
|
679
|
-
setTimeout(() => blurActiveElement(), 500);
|
|
680
|
-
refreshHandle();
|
|
681
|
-
expandHandle();
|
|
682
|
-
})
|
|
683
|
-
.start();
|
|
298
|
+
/* istanbul ignore next -- @preserve */
|
|
299
|
+
async function loadDemoData(): Promise<void> {
|
|
300
|
+
if (isDemo.value) {
|
|
301
|
+
const BASE_STATE_URL = 'https://webgl-3dr.singular.health/demo';
|
|
302
|
+
mockDemoViewerStlDecimator();
|
|
303
|
+
await viewer3cr.addDataOverlaySession({ Url: `${BASE_STATE_URL}/state/data_overlay.3crds` });
|
|
304
|
+
await viewer3cr.addDataOverlaySession({ Url: `${BASE_STATE_URL}/state/markups.3crds` });
|
|
305
|
+
// await viewer3cr.loadMcadObjects({ Url: `${BASE_STATE_URL}/state/mcad.3crms` });
|
|
306
|
+
}
|
|
684
307
|
}
|
|
685
308
|
|
|
686
309
|
defineExpose({
|
|
687
310
|
alterValue,
|
|
688
311
|
loadSession,
|
|
689
312
|
load,
|
|
690
|
-
startIntro,
|
|
691
|
-
thresholdSlider,
|
|
692
|
-
windowSlider,
|
|
693
313
|
m_closeDialog,
|
|
694
|
-
|
|
695
|
-
initialScanState,
|
|
696
|
-
value,
|
|
697
|
-
transactionStarted,
|
|
314
|
+
value
|
|
698
315
|
});
|
|
699
316
|
</script>
|
|
700
317
|
|
|
701
318
|
<style>
|
|
702
|
-
#view-0 {
|
|
703
|
-
cursor: grab;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
.bordered-event-window {
|
|
707
|
-
position: absolute;
|
|
708
|
-
border: 1px rgba(128, 128, 128, 0.56) solid;
|
|
709
|
-
transition: border 0.5s;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
.bordered-event-window:hover {
|
|
713
|
-
border: 1px dashed rgb(0, 152, 253);
|
|
714
|
-
}
|
|
715
|
-
|
|
716
319
|
.motif-background {
|
|
717
320
|
background: url("data:image/svg+xml,%3Csvg width='992' height='560' viewBox='15 7 992 560' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='15' y='1' width='992' height='567' fill='url(%23paint0_linear_504_579)'/%3E%3Cg filter='url(%23filter0_i_504_579)'%3E%3Cpath d='M567.029 291.5C574.21 421.339 748.15 561 825.931 561H12L12.0001 0C153.713 0 580.363 0 580.363 0C684.258 142 560.918 181 567.029 291.5Z' fill='%231B2E43' fill-opacity='0.9'/%3E%3C/g%3E%3Cg filter='url(%23filter1_i_504_579)'%3E%3Cpath d='M435.911 260.5C462.579 433.5 652.034 561 729.815 561H12L12.0001 0C233.678 0 409.954 92.1126 435.911 260.5Z' fill='%231B2E43' fill-opacity='0.9'/%3E%3C/g%3E%3Cg filter='url(%23filter2_i_504_579)'%3E%3Ccircle cx='46' cy='521' r='93' fill='%231B2E43' fill-opacity='0.3'/%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='filter0_i_504_579' x='12' y='0' width='858.931' height='606' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='BackgroundImageFix' result='shape'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0' result='hardAlpha'/%3E%3CfeOffset dx='45' dy='45'/%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComposite in2='hardAlpha' operator='arithmetic' k2='-1' k3='1'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.653125 0 0 0 0 0.761642 0 0 0 0 0.916667 0 0 0 0.15 0'/%3E%3CfeBlend mode='normal' in2='shape' result='effect1_innerShadow_504_579'/%3E%3C/filter%3E%3Cfilter id='filter1_i_504_579' x='12' y='0' width='762.815' height='606' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='BackgroundImageFix' result='shape'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0' result='hardAlpha'/%3E%3CfeOffset dx='45' dy='45'/%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComposite in2='hardAlpha' operator='arithmetic' k2='-1' k3='1'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.653125 0 0 0 0 0.761642 0 0 0 0 0.916667 0 0 0 0.25 0'/%3E%3CfeBlend mode='normal' in2='shape' result='effect1_innerShadow_504_579'/%3E%3C/filter%3E%3Cfilter id='filter2_i_504_579' x='-47' y='428' width='231' height='231' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeBlend mode='normal' in='SourceGraphic' in2='BackgroundImageFix' result='shape'/%3E%3CfeColorMatrix in='SourceAlpha' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0' result='hardAlpha'/%3E%3CfeOffset dx='45' dy='45'/%3E%3CfeGaussianBlur stdDeviation='50'/%3E%3CfeComposite in2='hardAlpha' operator='arithmetic' k2='-1' k3='1'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.653125 0 0 0 0 0.761642 0 0 0 0 0.916667 0 0 0 0.15 0'/%3E%3CfeBlend mode='normal' in2='shape' result='effect1_innerShadow_504_579'/%3E%3C/filter%3E%3ClinearGradient id='paint0_linear_504_579' x1='1251.04' y1='696.83' x2='21.486' y2='-10.2783' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%230E141D'/%3E%3Cstop offset='1' stop-color='%2323405E'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E%0A") !important;
|
|
718
321
|
background-size: cover !important;
|
|
719
322
|
}
|
|
720
|
-
|
|
721
|
-
.introjs-tooltipReferenceLayer {
|
|
722
|
-
z-index: 2401;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
.introjs-overlay, .introjs-helperLayer {
|
|
726
|
-
pointer-events: none;
|
|
727
|
-
z-index: 2401;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
.introjs-dontShowAgain {
|
|
731
|
-
display: none;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
.v-enter-active, .v-leave-active {
|
|
735
|
-
transition: opacity 0.5s ease;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
.v-enter-from, .v-leave-to {
|
|
739
|
-
opacity: 0;
|
|
740
|
-
}
|
|
741
323
|
</style>
|