UNPKG

our-medical

Version:

medical image vue component

1 lines 3.9 MB
{"version":3,"file":"index.umd.cjs","sources":["../../src/components/medical/AxisSelect.vue","../../src/components/medical/constant.ts","../../src/components/medical/scripts/public_methods.ts","../../src/components/medical/managers/axis_state_manager.ts","../../src/components/medical/managers/density_state_manager.ts","../../node_modules/@doodle3d/clipper-lib/clipper.js","../../node_modules/@doodle3d/clipper-js/module/index.js","../../src/components/medical/utilities/capture_image.ts","../../src/components/medical/utilities/convert_opacity_to_vtk_opacity.ts","../../src/components/medical/utilities/couch_in_slice.ts","../../src/components/medical/utilities/create_default_frame.ts","../../src/components/medical/utilities/distance_of_point_to_line.ts","../../src/components/medical/utilities/draw_image.ts","../../src/components/medical/utilities/draw_path.ts","../../src/components/medical/utilities/fill_segmentation_hole.ts","../../src/components/medical/utilities/get_paths_from_slice.ts","../../src/components/medical/utilities/get_canvas_pixels_in_viewport.ts","../../src/components/medical/utilities/get_couch_boundary_in_world.ts","../../src/components/medical/utilities/get_density_relative_to_water.ts","../../src/components/medical/scripts/get_pt_instance_meta_data.ts","../../src/components/medical/scripts/pt_scaling_meta_data_provider.ts","../../src/components/medical/utilities/get_meta_data.ts","../../src/components/medical/utilities/get_slice_from_volume.ts","../../src/components/medical/utilities/get_text_box.ts","../../src/components/medical/utilities/get_viewport_index.ts","../../src/components/medical/utilities/index_to_world.ts","../../src/components/medical/utilities/middle_priority_sort.ts","../../src/components/medical/utilities/point_in_segmentation.ts","../../src/components/medical/utilities/point_on_viewport_plane.ts","../../src/components/medical/utilities/reset_viewports.ts","../../src/components/medical/utilities/thread_pool.ts","../../src/components/medical/utilities/id_generator.ts","../../src/components/medical/utilities/viewports_findor.ts","../../src/components/medical/utilities/device_pixel_ratio.ts","../../src/components/medical/utilities/get_viewport_direction_from_camera.ts","../../src/components/medical/utilities/get_bounding_box.ts","../../src/components/medical/utilities/point_in_shape.ts","../../src/components/medical/utilities/prop_series_check.ts","../../src/components/medical/utilities/drag_add/hanlders.ts","../../src/components/medical/utilities/drag_add/index.ts","../../src/components/medical/tools/advance_brush/strategies/pointInCapsule.ts","../../src/components/medical/tools/advance_brush/strategies/fillCircle.ts","../../src/components/medical/tools/advance_brush/AdvanceBrushTool.ts","../../src/components/medical/tools/simple_pencil/fillPath.ts","../../src/components/medical/tools/simple_pencil/SimplePencilTool.ts","../../src/components/medical/tools/ContourDeleteTool.ts","../../src/components/medical/managers/series_state_manager.ts","../../src/components/medical/managers/volume_state_manager.ts","../../src/components/medical/tools/ManualRegistrationTool.ts","../../src/components/medical/tools/MeasuringScaleTool.ts","../../src/components/medical/tools/OrientationMarkTool.ts","../../src/components/medical/tools/SliceInfoTool.ts","../../src/components/medical/tools/WWWCTool.ts","../../src/components/medical/tools/dose_tool/draw_legend.ts","../../src/components/medical/tools/dose_tool/DoseDisplayTool.ts","../../src/components/medical/tools/draggable_element/DraggableTool.ts","../../src/components/medical/tools/draggable_element/DraggableDisplayTool.ts","../../src/components/medical/tools/draggable_element/draggable_element_add/dose_point_add.ts","../../src/components/medical/tools/draggable_element/draggable_element_add/fiducial_add.ts","../../src/components/medical/tools/draggable_element/draggable_element_add/nail_add.ts","../../src/components/medical/tools/draggable_element/draggable_element_add/shot_add.ts","../../src/components/medical/tools/draggable_element/draggable_element_add/index.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/dose_point_near_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/fiducial_near_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/frame_extracted_near_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/image_center_near_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/nail_near_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/origin_near_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/shot_near_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near/index.ts","../../src/components/medical/tools/draggable_element/draggable_element_near_tool/frame_extracted_near_tool_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near_tool/couch_near_tool_handlor.ts","../../src/components/medical/tools/draggable_element/draggable_element_near_tool/index.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/couch_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/dose_point_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/fiducial_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/frame_extracted_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/frame_fitting_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/frame_physics_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/image_center_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/nail_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/origin_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/shot_render.ts","../../src/components/medical/tools/draggable_element/draggable_element_renders/index.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/dose_point_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/fiducial_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/frame_extracted_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/image_center_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/nail_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/origin_ctrl_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/shot_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected/index.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected_tool/frame_extracted_tool_selected.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected_tool/couch_tool_selected_tool.ts","../../src/components/medical/tools/draggable_element/draggable_element_selected_tool/index.ts","../../src/components/medical/tools/draggable_element/index.ts","../../src/components/medical/tools/index.ts","../../src/components/medical/utilities/render_3d.ts","../../src/components/medical/utilities/index.ts","../../src/components/medical/managers/managers_plan/dose_manager.ts","../../src/components/medical/managers/managers_plan/plan_manager.ts","../../src/components/medical/managers/managers_plan/shot_manager.ts","../../src/components/medical/managers/managers_draggable/couch_manager.ts","../../src/components/medical/managers/managers_draggable/dose_point_manager.ts","../../src/components/medical/managers/managers_draggable/draggable_manager.ts","../../src/components/medical/managers/managers_draggable/fiducial_manage.ts","../../src/components/medical/managers/managers_draggable/frame_manager.ts","../../src/components/medical/managers/managers_draggable/image_center_manager.ts","../../src/components/medical/managers/managers_draggable/nail_manager.ts","../../src/components/medical/managers/managers_draggable/origin_manager.ts","../../src/components/medical/managers/managers_draggable/regist_manager.ts","../../src/components/medical/managers/managers_draggable/shot_manager.ts","../../src/components/medical/managers/managers_draggable/index.ts","../../src/components/medical/managers/grayscale_state_manager.ts","../../src/components/medical/managers/global_rendering_engine.ts","../../src/components/medical/managers/tools_state_manager.ts","../../src/components/medical/managers/segmentation_state_manager.ts","../../src/components/medical/managers/slice_state_manager.ts","../../src/components/medical/managers/index.ts","../../src/components/medical/scripts/create_header_node.ts","../../src/components/medical/scripts/cornerstone_init.ts","../../src/components/medical/scripts/orientation_human.ts","../../src/components/medical/scripts/viewports_resize.ts","../../src/components/medical/scripts/render_series.ts","../../src/components/medical/scripts/element_event_handlors.ts","../../src/components/medical/SeriesDisplay.vue","../../src/components/medical/MedicalImage.vue","../../src/components/medical/index.ts","../../src/components/medical/assets/Human.vtp"],"sourcesContent":["<template>\n <div class=\"title\" ref=\"titleNode\" @click=\"titleClickHandle\">\n {{ `${prefixMark ? prefixMark + ' - ' : ''}${titleText}` }}\n </div>\n\n <teleport to=\"body\">\n <ul\n v-if=\"visible\"\n class=\"list frosted-glass\"\n ref=\"listNode\"\n :style=\"listPosition\"\n @mouseleave=\"visible = false\"\n >\n <li\n v-for=\"item in list\"\n :class=\"[item.key === select ? 'select' : '', item.disabled ? 'disabled' : '']\"\n :key=\"item.key\"\n :style=\"{ background: color && item.key === select ? color : undefined }\"\n @click=\"listClickHandle(item)\"\n >\n {{ item.text }}\n </li>\n </ul>\n </teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue'\n\nimport type { PropType } from 'vue'\nimport type { AxisSelectItem } from './types'\n\nconst props = defineProps({\n select: { type: String, required: true },\n color: { type: String },\n i18n: { type: String as PropType<'en' | 'zh'>, required: true },\n prefixMark: { type: String },\n list: { type: Array as PropType<AxisSelectItem[]>, required: true },\n onUpdateSelect: { type: Function as PropType<(value: AxisSelectItem['key']) => void> }\n})\n\nconst emits = defineEmits({ 'update:select': (value: AxisSelectItem['key']) => value || true })\n\nconst listNode = ref()\nconst titleNode = ref()\nconst visible = ref(false)\nconst position = reactive({ x: 0, y: 0 })\nconst listPosition = computed(() => ({ left: position.x + 'px', top: position.y + 'px' }))\n\nconst titleText = computed(() => {\n for (const iterator of props.list) {\n if (iterator.key === props.select) {\n return iterator.text\n }\n }\n return props.i18n === 'en' ? 'Viewport' : '视口'\n})\n\nonMounted(() => {\n document.addEventListener('click', isTitleNode)\n})\n\nonBeforeUnmount(() => {\n document.removeEventListener('click', isTitleNode)\n})\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 10/03/2022\n * @export\n * @param {MouseEvent} e\n */\nfunction isTitleNode(e: MouseEvent) {\n if (e.target !== titleNode.value && !listNode.value?.contains(e.target)) {\n visible.value = false\n }\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 30/11/2021\n * @export\n * @param {MouseEvent} e\n */\nasync function titleClickHandle(e: MouseEvent): Promise<void> {\n if (visible.value) {\n visible.value = false\n } else {\n visible.value = true\n\n nextTick(() => {\n const target = e.target as HTMLElement\n const parent = target.parentElement as HTMLElement\n const { offsetHeight, offsetWidth } = parent\n const { offsetX, offsetY } = e\n\n listNode.value.style.width = parent.offsetWidth + 'px'\n\n const listWidth = listNode.value.offsetWidth\n position.x = e.clientX - offsetX + offsetWidth - listWidth - 5\n position.y = e.clientY - offsetY + offsetHeight\n })\n }\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 30/11/2021\n * @export\n * @param {AxisSelectItem} item\n */\nfunction listClickHandle(item: AxisSelectItem): void {\n if (item.disabled) return\n emits('update:select', item.key)\n props.onUpdateSelect && props.onUpdateSelect(item.key)\n visible.value = false\n}\n</script>\n\n<style scoped>\n@import url('./style.css');\n\n.title {\n font-size: 15px;\n font-weight: bold;\n cursor: pointer;\n margin: 3px 5px;\n float: left;\n}\n\n.list {\n position: fixed;\n list-style: none;\n margin: 0;\n padding: 5px 0;\n z-index: 999;\n color: #efefef;\n}\n\n.list li {\n padding: 0 10px;\n cursor: default;\n}\n\n.list li.select {\n background: rgba(255, 255, 255, 0.3);\n}\n\n.list li.disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.list li:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n</style>\n","import { Enums, utilities } from '@cornerstonejs/core'\nimport { AngleTool, CrosshairsTool, LengthTool, PanTool, ZoomTool } from '@cornerstonejs/tools'\n\nexport enum Events {\n CONTOUR_DATA_MODIFIED = 'contour_data_modified',\n VOI_MODIFIED_FROM_TOOL = 'voi_modified_from_tool',\n\n ORIGIN_MODIFIED_FROM_DRAG = 'origin_modified_from_drag',\n ORIGIN_DRAG_END = 'origin_drag_end',\n\n SHOT_MODIFIED_FROM_DRAG = 'shot_modified_from_drag',\n SHOT_REMOVED_FROM_DRAG = 'shot_removed_from_drag',\n NEW_SHOT_FROM_DRAG = 'new_shot_from_drag',\n CURR_SHOT_ID_MODIFIED = 'current_shot_id_modified',\n\n CURR_FRAME_VERTICE_INFO_MODIFIED = 'current_frame_vertice_infor_modified',\n FRAME_VERTICE_MOVED = 'frame_vertice_moved',\n FRAME_MOVED = 'frame_moved',\n FRAME_DRAG_END = 'frame_drag_end',\n\n NAIL_MODIFIED_FROM_DRAG = 'nail_modified_from_drag',\n NEW_NAIL_FROM_DRAG = 'new_nail_from_drag',\n CURR_NAIL_MODIFIED = 'current_nail_modified',\n\n IMAGE_CENTER_MODIFIED = 'image_center_modified',\n IMAGE_CENTER_DRAG_END = 'image_center_drag_end',\n IMGAE_CENTER_REMOVED_FROM_DRAG = 'image_center_removed_from_drag',\n\n COUCH_MODIFIED_FROM_DRAG = 'couch_modified_from_drag',\n COUCH_DRAG_END = 'couch_drag_end',\n\n FIDUCIAL_MODIFIED_FROM_DRAG = 'fiducial_modified_from_drag',\n FIDUCIAL_REMOVED_FROM_DRAG = 'fiducial_removed_from_drag',\n NEW_FIDUCIAL_FROM_DRAG = 'new_fiducial_from_drag',\n\n DOSE_PT_MODIFIED_FROM_DRAG = 'dose_point_modified_from_drag',\n DOSE_PT_REMOVED_FROM_DRAG = 'dose_point_removed_from_drag',\n DOSE_PT_UPDATE_DOSE = 'dose_point_update_dose',\n NEW_DOSE_PT_FROM_DRAG = 'new_dose_point_from_drag',\n\n VIEWPORT_VOLUMES_SETTED = 'viewport_reference_volumes_setted',\n ACCESS_3D = 'access_to_3d_display',\n Exit_3D = 'exit_3d_display',\n\n DOSE_DRAWED = 'dose_path_draw_end',\n\n VOLUME_TRANSFORM = 'volume_transform'\n}\n\nexport enum Grid {\n C = 'core',\n S = 'south',\n N = 'north'\n}\n\nexport enum Layout {\n Primary = 'P',\n Secondary = 'S',\n SideBySide = 'P&S',\n Fusion = 'P+S'\n}\n\nexport enum AxisLayout {\n Horizontal = 'horizontal',\n Vertical = 'vertical'\n}\n\nexport enum ToolsName {\n AdvanceBrush = 'AdvanceBrush',\n ContourDelete = 'ContourDelete',\n Draggable = 'Draggable',\n DraggableDisplay = 'DraggableDisplay',\n DoseDisplay = 'DoseDisplay',\n ManualRegistration = 'ManualRegistration',\n MeasuringScale = 'MeasuringScale',\n OrientationMark = 'OrientationMark',\n SimplePencil = 'SimplePencil',\n SliceInfo = 'SliceInfo',\n WWWC = 'WWWC'\n}\n\nexport enum TOOL_GROUP_TYPE {\n P = 'primary',\n S = 'secondary'\n}\n\nexport enum DOSE_LEGENDS {\n A = 'absolute',\n R = 'relative'\n}\n\nexport enum DOSE_DISPLAY_TYPES {\n F = 'fill',\n L = 'line'\n}\n\nexport const TEXT_WHITE_IN_VIEWPORT = '#efefef'\nexport const MODALITY = '00080060'\nexport const RENDERING_ENGINE_ID = 'our-medial-rendering-engin ' + utilities.uuidv4()\nexport const SERIES_INSTANCE_UID = '0020000E'\nexport const SOP_INSTANCE_UID = '00080018'\nexport const SEGMENTATION_PREFIX = 'segmentation'\nexport const STREAMING_LOADER_NAME = 'cornerstoneStreamingImageVolume'\n\nexport const AxisNameI18n = {\n [Enums.OrientationAxis.AXIAL]: { en: 'Axial', zh: '轴状位' },\n [Enums.OrientationAxis.SAGITTAL]: { en: 'Sagittal', zh: '矢状位' },\n [Enums.OrientationAxis.CORONAL]: { en: 'Coronal', zh: '冠状位' },\n [Enums.ViewportType.VOLUME_3D]: { en: '3D', zh: '三\\xa0\\xa0\\xa0维' }\n}\nObject.freeze(AxisNameI18n)\n\nexport /** @description 依赖SVG渲染需要进行排序的工具 */\nconst ToolsOrder: string[] = [\n ToolsName.DoseDisplay,\n ToolsName.DraggableDisplay,\n ToolsName.MeasuringScale,\n ToolsName.OrientationMark,\n ToolsName.SliceInfo\n]\nObject.freeze(ToolsOrder)\n\nexport /** @type {*} 头框点半径 */\nconst FRAME_PT_R = 4\n\nexport /** @type {*} 3D渲染中segmentation体积的透明度 */\nconst VOLUME_OPACITY_IN_3D = 0.2\n\nexport /** @type {*} 3D渲染中dose体积的透明度 */\nconst DOSE_OPACITY_IN_3D = 0.4\n\n// export const HU_RANGE = [-1000, 1000]\n\nexport const HeaderIconPaths = {\n fullIn: [\n 'M382 828H204c-4.4 0-8-3.6-8-8V665c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v195c0 17.7 14.3 32 32 32h218c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM884 657h-48c-4.4 0-8 3.6-8 8v155c0 4.4-3.6 8-8 8H642c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h218c17.7 0 32-14.3 32-32V665c0-4.4-3.6-8-8-8zM642 196h178c4.4 0 8 3.6 8 8v155c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V164c0-17.7-14.3-32-32-32H642c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zM140 367h48c4.4 0 8-3.6 8-8V204c0-4.4 3.6-8 8-8h178c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H164c-17.7 0-32 14.3-32 32v195c0 4.4 3.6 8 8 8z'\n ],\n fullOut: [\n 'M358 657c17.7 0 32 14.3 32 32v195c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V729c0-4.4-3.6-8-8-8H140c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h218z m526 0c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8H706c-4.4 0-8 3.6-8 8v155c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V689c0-17.7 14.3-32 32-32h218zM690 132c4.4 0 8 3.6 8 8v155c0 4.4 3.6 8 8 8h178c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8H666c-17.7 0-32-14.3-32-32V140c0-4.4 3.6-8 8-8h48z m-308 0c4.4 0 8 3.6 8 8v195c0 17.7-14.3 32-32 32H140c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h178c4.4 0 8-3.6 8-8V140c0-4.4 3.6-8 8-8h48z'\n ],\n pointer: [\n 'M836.54 429.526667l-498.833333-288-91.946667-53.086667c-10-5.78-18.553333-2.1-21.76-0.246667A21.333333 21.333333 0 0 0 213.333333 106.666667v682.666666a21.333333 21.333333 0 0 0 36.113334 15.386667l154.666666-148.586667 130.38 225.826667A53.333333 53.333333 0 0 0 607.333333 901.486667l129.333334-74.666667a53.333333 53.333333 0 0 0 19.526666-72.86L625.8 528.133333l206-59.64a21.333333 21.333333 0 0 0 4.733333-38.966666z'\n ],\n reset: [\n 'M921.728 654.4a428.352 428.352 0 1 0-647.04 203.264c3.2 2.24 7.488 1.856 10.24-0.896l43.2-43.2a8 8 0 0 0-1.28-12.352 352.256 352.256 0 1 1 462.592-67.968l-70.4-69.76a8 8 0 0 0-13.632 4.608l-27.904 219.776a8 8 0 0 0 9.024 8.96l219.52-29.952a8 8 0 0 0 4.48-13.632l-67.008-66.368a431.36 431.36 0 0 0 78.208-132.48z'\n ],\n [AngleTool.toolName]: [\n 'M968 736.96h-315.84c11.52-202.56-82.24-304.96-153.28-352.64l132.8-147.84c20.8-23.04 18.88-58.24-4.16-079.04-23.04-20.8-58.56-18.88-79.04 4.16L14.4 755.52c-14.72 16.32-18.56 40-9.6 60.16 8.96 20.16 29.12 33.28 51.2 33.28h912c31.04 0 56-24.96 56-56s-24.96-56-56-56z m-544.32-269.12c45.76 25.92 127.68 96.64 116.16 269.12H181.76l241.92-269.12z'\n ],\n [LengthTool.toolName]: [\n 'M964.693333 300.8L725.333333 59.306667a42.666667 42.666667 0 0 0-30.293333-12.373334 42.666667 42.666667 0 0 0-29.866667 12.373334L59.306667 663.04a42.666667 42.666667 0 0 0 0 60.16l241.493333 241.493333a42.666667 42.666667 0 0 0 30.293333 12.373334 42.666667 42.666667 0 0 0 29.866667-12.373334l120.746667-120.746666 362.24-362.24 120.746666-120.746667a42.666667 42.666667 0 0 0 0-60.16z m-151.04 90.453333l-30.293333-30.293333a42.666667 42.666667 0 0 0-60.16 0 42.666667 42.666667 0 0 0 0 60.586667l30.293333 30.293333L692.906667 512l-90.453334-90.453333a42.666667 42.666667 0 0 0-60.16 60.16l90.453334 90.453333-60.586667 60.586667-29.866667-30.293334a42.666667 42.666667 0 1 0-60.586666 60.586667l30.293333 29.866667-60.16 60.586666-90.88-90.453333a42.666667 42.666667 0 0 0-60.16 0 42.666667 42.666667 0 0 0 0 60.16l90.453333 90.453333-60.16 60.586667-181.333333-181.333333L692.906667 149.76l181.333333 181.333333z'\n ],\n [PanTool.toolName]: [\n 'M510.7 896.2c-15.3 0-28.7-11.3-31.4-26.6-0.7-4-0.6-7.9 0.1-11.7 1.7-43.3 0.6-444.5-0.6-710.7-0.1-17.5 14-31.7 31.5-31.8h0.1c17.4 0 31.6 14.1 31.7 31.5 0 0 0.8 179.3 1.3 358.7 0.2 89.7 0.3 179.4 0.2 246.8-0.3 141-0.3 141-30.2 143.7-0.9 0.1-1.8 0.1-2.7 0.1z',\n 'M510.7 896.2c-15.3 0-28.7-11.3-31.4-26.6-0.7-4-0.6-7.9 0.1-11.7 1.7-43.3 0.6-444.5-0.6-710.7-0.1-17.5 14-31.7 31.5-31.8h0.1c17.4 0 31.6 14.1 31.7 31.5 0 0 0.8 179.3 1.3 358.7 0.2 89.7 0.3 179.4 0.2 246.8-0.3 141-0.3 141-30.2 143.7-0.9 0.1-1.8 0.1-2.7 0.1z',\n 'M330.2 538.2h-65.5c-141-0.3-141-0.3-143.7-30.2-1.5-16.4 10.3-31.3 26.5-34.1 4-0.7 8-0.6 11.7 0.1 43.3 1.8 444.4 0.6 710.7-0.6h0.1c17.4 0 31.6 14.1 31.7 31.5 0.1 17.5-14 31.7-31.5 31.8 0 0-179.3 0.8-358.7 1.3-63 0.1-126 0.2-181.3 0.2zM614.8 250c-8.1 0-16.2-3.1-22.4-9.3L512 160.4l-80.4 80.4c-12.4 12.4-32.4 12.4-44.8 0-12.4-12.4-12.4-32.4 0-44.8L489.6 93.2c12.4-12.4 32.4-12.4 44.8 0L637.2 196c12.4 12.4 12.4 32.4 0 44.8-6.2 6.1-14.3 9.2-22.4 9.2zM512 920.5c-8.1 0-16.2-3.1-22.4-9.3L386.8 808.4c-12.4-12.4-12.4-32.4 0-44.8 12.4-12.4 32.4-12.4 44.8 0L512 844l80.4-80.4c12.4-12.4 32.4-12.4 44.8 0 12.4 12.4 12.4 32.4 0 44.8L534.4 911.2c-6.2 6.2-14.3 9.3-22.4 9.3z',\n 'M795.8 636.6c-8.1 0-16.2-3.1-22.4-9.3-12.4-12.4-12.4-32.4 0-44.8l80.4-80.4-80.4-80.4c-12.4-12.4-12.4-32.4 0-44.8 12.4-12.4 32.4-12.4 44.8 0L921 479.8c12.4 12.4 12.4 32.4 0 44.8L818.2 627.4c-6.2 6.1-14.3 9.2-22.4 9.2zM228.2 636.6c-8.1 0-16.2-3.1-22.4-9.3L103 524.6c-12.4-12.4-12.4-32.4 0-44.8L205.8 377c12.4-12.4 32.4-12.4 44.8 0 12.4 12.4 12.4 32.4 0 44.8l-80.4 80.4 80.4 80.4c12.4 12.4 12.4 32.4 0 44.8-6.2 6.1-14.3 9.2-22.4 9.2z'\n ],\n [ToolsName.WWWC]: [\n 'M512 142.849636c49.823744 0 98.131965 9.747516 143.585504 28.972526 43.924636 18.579149 83.382979 45.184734 117.277915 79.080887 33.894936 33.894936 60.501738 73.353279 79.080887 117.277915 19.22501 45.452323 28.972526 93.76176 28.972526 143.585504s-9.747516 98.131965-28.972526 143.585504c-18.579149 43.924636-45.184734 83.382979-79.080887 117.277916-33.894936 33.894936-73.353279 60.501738-117.277915 79.080887-45.452323 19.22501-93.76176 28.972526-143.585504 28.972526s-98.131965-9.747516-143.585504-28.972526c-43.924636-18.579149-83.382979-45.184734-117.277915-79.080887-33.894936-33.894936-60.501738-73.353279-79.080887-117.277916-19.22501-45.452323-28.972526-93.76176-28.972526-143.585504s9.747516-98.131965 28.972526-143.585504c18.579149-43.924636 45.184734-83.382979 79.080887-117.277915s73.353279-60.501738 117.277915-79.080887c45.453539-19.223794 93.762976-28.972526 143.585504-28.972526m0-44.821057c-228.501035 0-413.736673 185.236855-413.736673 413.736673S283.500182 925.503142 512 925.503142s413.736673-185.236855 413.736673-413.736674S740.501035 98.028579 512 98.028579z',\n 'M488.542228 115.289247h44.821057v780.948238h-44.821057z',\n 'M661.647598 143.001675l31.693413 31.69463-166.01671 166.015493-31.692197-31.693413zM767.461782 217.801147l31.693414 31.693414L527.326734 521.323023l-31.693414-31.693413zM850.471354 319.054166l31.693413 31.693414-353.25318 353.25318-31.693414-31.693413zM891.520631 458.61733l31.692197 31.693414-401.358277 401.358277-31.693414-31.693414z'\n ],\n [ZoomTool.toolName]: [\n 'M637 443H519V309c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v134H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h118v134c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V519h118c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z',\n 'M921 867L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z'\n ],\n [CrosshairsTool.toolName]: [\n 'M62.016 474.016h900v76H62.016v-76zM474.016 62.016h76v900h-76V62.016z'\n ]\n}\nObject.freeze(HeaderIconPaths)\n\nexport const ViewportContainerGridAreaClassName = {\n full: 'viewport-container-full',\n halfL: 'viewport-container-half-left',\n halfR: 'viewport-container-half-right',\n on: 'viewport-container-on'\n}\nObject.freeze(ViewportContainerGridAreaClassName)\n\nexport /** @type {*} 用在vtkImageReslice.setResliceAxes获取不同方向上切面的基本数据格式 */\nconst AXIS_AXES = [\n [0, 1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, null, 0, 0, 1], //sagittal\n [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, null, 0, 1], //coronal\n [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, null, 1] //axial\n]\n\nexport const CUSTOM_CURSOR = {\n [ToolsName.SimplePencil]: {\n iconContent: `\n <g xmlns=\"http://www.w3.org/2000/svg\" transform=\"scale(0.04116214)\">\n <path style=\"fill: {{color}};\" d=\"m 503.46668,777.41329 a 17.03253,17.03253 0 0 1 -12.15147,-5.08587 a 17.064088,17.064088 0 1 1 24.13227,24.13226 l -48.60587,48.60587 47.83787,48.52053 a 17.0496,17.0496 0 0 1 -12.15147,29.04747 z m -230.4,-145.92 H 102.40001 A 17.06667,17.06667 0 0 1 85.33335,614.42662 V 546.15996 H 17.06668 a 17.06667,17.06667 0 1 1 0,-34.13334 H 74.78615 L 1.80908,366.05542 a 17.06667,17.06667 0 0 1 0,-15.27466 L 172.39041,9.61809 a 16.896,16.896 0 0 1 10.82027,-8.99413 16.9472,16.9472 0 0 1 11.81013,1.00693 l 0.85334,0.42667 a 17.03253,17.03253 0 0 1 7.18506,7.50933 l 170.5984,341.17973 a 17.06667,17.06667 0 0 1 0,15.27467 l -72.97706,145.9712 h 57.71946 a 17.06667,17.06667 0 1 1 0,34.13333 h -68.26666 v 68.26667 a 17.06667,17.06667 0 0 1 -17.06667,17.1008 z m -153.6,-34.13333 h 136.53333 v -51.2 H 119.46668 Z m -6.51947,-85.33334 h 149.57227 l 76.8,-153.6 L 204.80001,89.38769 v 126.8224 c 8.78934,2.7648 16.5376,7.4752 23.15947,14.11413 a 58.5728,58.5728 0 0 1 17.80053,42.78614 c 0,16.57173 -6.2976,31.21493 -18.21013,42.3424 -10.30827,11.09333 -24.9344,17.39093 -41.5232,17.39093 a 58.5728,58.5728 0 0 1 -42.78613,-17.80053 c -11.24694,-11.22987 -16.9472,-25.344 -16.9472,-41.9328 0,-16.36694 5.56373,-30.6176 16.55466,-42.35947 8.46507,-7.95307 17.69814,-13.07307 27.81867,-15.5648 V 89.40476 L 36.14721,358.42662 Z m 73.07947,-264.53333 c -7.64587,0 -13.70453,2.33813 -19.06347,7.35573 -4.1984,4.5568 -6.53653,10.61547 -6.53653,18.24427 0,7.40693 2.2016,13.056 6.94613,17.78347 5.3248,5.3248 11.264,7.81653 18.65387,7.81653 7.2704,0 12.62933,-2.26987 17.39093,-7.38987 5.9392,-5.59786 8.20907,-10.9568 8.20907,-18.21013 a 24.91733,24.91733 0 0 0 -7.79947,-18.65387 c -4.31786,-4.31786 -9.59146,-6.53653 -16.55466,-6.94613 z\"/>\n </g>\n `,\n iconSize: 32,\n viewBox: { x: 32, y: 32 },\n mousePoint: { x: 8, y: 8 },\n mousePointerGroupString:\n '<path stroke=\"{{color}}\" d=\"M8 16L8 0\"></path><path stroke=\"{{color}}\" d=\"M16 8L0 8\"></path>'\n },\n\n Fiducial: {\n iconContent: `\n <g xmlns=\"http://www.w3.org/2000/svg\" transform=\"translate(0,0)\">\n <path style=\"fill:RED;fill-rule:evenodd;stroke-width:0.279359;fill-opacity:1\" d=\"m 0,-4 a 4,4 0 0 1 -4,4 4,4 0 0 1 -4,-4 4,4 0 0 1 4,-4 4,4 0 0 1 4,4 z\"/>\n </g>\n `,\n iconSize: 32,\n viewBox: { x: 16, y: 16 },\n mousePoint: { x: 8, y: 8 },\n mousePointerGroupString: ''\n },\n\n Nail: {\n iconContent: '',\n iconSize: 32,\n viewBox: { x: 16, y: 16 },\n mousePoint: { x: 8, y: 8 },\n mousePointerGroupString:\n '<path stroke=\"{{color}}\" d=\"M8 16L8 0\"></path><path stroke=\"{{color}}\" d=\"M16 8L0 8\"></path>'\n },\n\n [ToolsName.ContourDelete]: {\n iconContent: `\n <g xmlns=\"http://www.w3.org/2000/svg\" transform=\"scale(0.04116214)\">\n <path style=\"fill: {{color}};\" d=\"m 503.46668,777.41329 a 17.03253,17.03253 0 0 1 -12.15147,-5.08587 l -47.6672,-48.34986 -47.58186,47.58186 a 17.064088,17.064088 0 1 1 -24.13227,-24.13226 l 47.58187,-47.58187 -48.34987,-47.6672 a 17.06667,17.06667 0 1 1 23.9616,-24.30293 l 48.52053,47.83786 48.60587,-48.60586 a 17.064088,17.064088 0 1 1 24.13227,24.13226 l -48.60587,48.60587 47.83787,48.52053 a 17.0496,17.0496 0 0 1 -12.15147,29.04747 z m -230.4,-145.92 H 102.40001 A 17.06667,17.06667 0 0 1 85.33335,614.42662 V 546.15996 H 17.06668 a 17.06667,17.06667 0 1 1 0,-34.13334 H 74.78615 L 1.80908,366.05542 a 17.06667,17.06667 0 0 1 0,-15.27466 L 172.39041,9.61809 a 16.896,16.896 0 0 1 10.82027,-8.99413 16.9472,16.9472 0 0 1 11.81013,1.00693 l 0.85334,0.42667 a 17.03253,17.03253 0 0 1 7.18506,7.50933 l 170.5984,341.17973 a 17.06667,17.06667 0 0 1 0,15.27467 l -72.97706,145.9712 h 57.71946 a 17.06667,17.06667 0 1 1 0,34.13333 h -68.26666 v 68.26667 a 17.06667,17.06667 0 0 1 -17.06667,17.1008 z m -153.6,-34.13333 h 136.53333 v -51.2 H 119.46668 Z m -6.51947,-85.33334 h 149.57227 l 76.8,-153.6 L 204.80001,89.38769 v 126.8224 c 8.78934,2.7648 16.5376,7.4752 23.15947,14.11413 a 58.5728,58.5728 0 0 1 17.80053,42.78614 c 0,16.57173 -6.2976,31.21493 -18.21013,42.3424 -10.30827,11.09333 -24.9344,17.39093 -41.5232,17.39093 a 58.5728,58.5728 0 0 1 -42.78613,-17.80053 c -11.24694,-11.22987 -16.9472,-25.344 -16.9472,-41.9328 0,-16.36694 5.56373,-30.6176 16.55466,-42.35947 8.46507,-7.95307 17.69814,-13.07307 27.81867,-15.5648 V 89.40476 L 36.14721,358.42662 Z m 73.07947,-264.53333 c -7.64587,0 -13.70453,2.33813 -19.06347,7.35573 -4.1984,4.5568 -6.53653,10.61547 -6.53653,18.24427 0,7.40693 2.2016,13.056 6.94613,17.78347 5.3248,5.3248 11.264,7.81653 18.65387,7.81653 7.2704,0 12.62933,-2.26987 17.39093,-7.38987 5.9392,-5.59786 8.20907,-10.9568 8.20907,-18.21013 a 24.91733,24.91733 0 0 0 -7.79947,-18.65387 c -4.31786,-4.31786 -9.59146,-6.53653 -16.55466,-6.94613 z\"/>\n </g>\n `,\n iconSize: 32,\n viewBox: { x: 32, y: 32 },\n mousePoint: { x: 8, y: 8 },\n mousePointerGroupString:\n '<path stroke=\"{{color}}\" d=\"M8 16L8 0\"></path><path stroke=\"{{color}}\" d=\"M16 8L0 8\"></path>'\n },\n\n ContourDeleteDisabled: {\n iconContent: `\n <g xmlns=\"http://www.w3.org/2000/svg\" transform=\"scale(0.04116214)\">\n <path style=\"fill: {{color}};\" d=\"m 503.46668,777.41329 a 17.03253,17.03253 0 0 1 -12.15147,-5.08587 l -47.6672,-48.34986 -47.58186,47.58186 a 17.064088,17.064088 0 1 1 -24.13227,-24.13226 l 47.58187,-47.58187 -48.34987,-47.6672 a 17.06667,17.06667 0 1 1 23.9616,-24.30293 l 48.52053,47.83786 48.60587,-48.60586 a 17.064088,17.064088 0 1 1 24.13227,24.13226 l -48.60587,48.60587 47.83787,48.52053 a 17.0496,17.0496 0 0 1 -12.15147,29.04747 z m -230.4,-145.92 H 102.40001 A 17.06667,17.06667 0 0 1 85.33335,614.42662 V 546.15996 H 17.06668 a 17.06667,17.06667 0 1 1 0,-34.13334 H 74.78615 L 1.80908,366.05542 a 17.06667,17.06667 0 0 1 0,-15.27466 L 172.39041,9.61809 a 16.896,16.896 0 0 1 10.82027,-8.99413 16.9472,16.9472 0 0 1 11.81013,1.00693 l 0.85334,0.42667 a 17.03253,17.03253 0 0 1 7.18506,7.50933 l 170.5984,341.17973 a 17.06667,17.06667 0 0 1 0,15.27467 l -72.97706,145.9712 h 57.71946 a 17.06667,17.06667 0 1 1 0,34.13333 h -68.26666 v 68.26667 a 17.06667,17.06667 0 0 1 -17.06667,17.1008 z m -153.6,-34.13333 h 136.53333 v -51.2 H 119.46668 Z m -6.51947,-85.33334 h 149.57227 l 76.8,-153.6 L 204.80001,89.38769 v 126.8224 c 8.78934,2.7648 16.5376,7.4752 23.15947,14.11413 a 58.5728,58.5728 0 0 1 17.80053,42.78614 c 0,16.57173 -6.2976,31.21493 -18.21013,42.3424 -10.30827,11.09333 -24.9344,17.39093 -41.5232,17.39093 a 58.5728,58.5728 0 0 1 -42.78613,-17.80053 c -11.24694,-11.22987 -16.9472,-25.344 -16.9472,-41.9328 0,-16.36694 5.56373,-30.6176 16.55466,-42.35947 8.46507,-7.95307 17.69814,-13.07307 27.81867,-15.5648 V 89.40476 L 36.14721,358.42662 Z m 73.07947,-264.53333 c -7.64587,0 -13.70453,2.33813 -19.06347,7.35573 -4.1984,4.5568 -6.53653,10.61547 -6.53653,18.24427 0,7.40693 2.2016,13.056 6.94613,17.78347 5.3248,5.3248 11.264,7.81653 18.65387,7.81653 7.2704,0 12.62933,-2.26987 17.39093,-7.38987 5.9392,-5.59786 8.20907,-10.9568 8.20907,-18.21013 a 24.91733,24.91733 0 0 0 -7.79947,-18.65387 c -4.31786,-4.31786 -9.59146,-6.53653 -16.55466,-6.94613 z\"/>\n <line stroke=\"{{color}}\" stroke-width=\"60\" fill=\"none\" x1=\"32\" y1=\"727.93518\" x2=\"489\" y2=\"49.064789\" stroke-linejoin=\"undefined\" stroke-linecap=\"undefined\"/>\n <circle stroke-width=\"30\" cy=\"728\" cx=\"32\" stroke=\"{{color}}\" fill=\"none\" r=\"15\"/>\n <circle stroke-width=\"30\" cy=\"49\" cx=\"489\" stroke=\"{{color}}\" fill=\"none\" r=\"15\"/>\n </g>\n `,\n iconSize: 32,\n viewBox: { x: 32, y: 32 },\n mousePoint: { x: 8, y: 8 },\n mousePointerGroupString:\n '<path stroke=\"{{color}}\" d=\"M8 16L8 0\"></path><path stroke=\"{{color}}\" d=\"M16 8L0 8\"></path>'\n }\n}\n","import { STREAMING_LOADER_NAME } from '../constant'\nimport type { Types } from '@cornerstonejs/core'\n\n/**\n * @description 将 medicalComponentId|seriesType 格式的字符串分割出组件ID和主次序列ID\n * @author jiannan.jiao\n * @date 06/09/2023\n * @export\n * @param {string} id\n * @returns {*}\n */\nexport function splitComponentIdStr(id: string) {\n const [medicalComponentId, seriesType] = id.split('|')\n return { medicalComponentId, seriesType }\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 12/09/2023\n * @export\n * @param {string} id\n * @returns {*}\n */\nexport function getViewporSeriesType(id: string) {\n const [, seriesType] = splitWithPipe(id)\n return seriesType\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 12/09/2023\n * @export\n * @param {...string[]} args\n * @returns {*}\n */\nexport function connectWithPipe(...args: string[]) {\n return args.length ? args.join('|') : ''\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 12/09/2023\n * @export\n * @param {string} id\n * @returns {*}\n * @example const [medicalComponentId, seriesType, orientation] = splitWithPipe(id)\n */\nexport function splitWithPipe(id: string) {\n return id.split('|')\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 11/05/2024\n * @export\n * @param {Types.IViewport} viewport\n * @returns {*}\n */\nexport function viewportHasSeriesVolume(viewport: Types.IViewport) {\n const defaultActor = viewport.getDefaultActor()\n return defaultActor?.uid.startsWith(STREAMING_LOADER_NAME)\n}\n","/**\n * @description 用于记录轴位对应的DOM元素、布局位置对应的轴位、轴位的全铺状态信息\n * @author jiannan.jiao\n */\n\n/* Import References */\nimport { Enums } from '@cornerstonejs/core'\nimport { reactive, ref } from 'vue'\nimport { splitComponentIdStr } from '../scripts/public_methods'\n\n/* Import Types */\nimport type { UnwrapNestedRefs } from 'vue'\nimport type { TOOL_GROUP_TYPE } from '../constant'\nimport type {\n AxisElements,\n AxisOrientations,\n AxisViewportIds,\n FullScreen,\n DisplayComponentID,\n MedicalComponentID,\n State3D\n} from '../types'\n\n/**\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n */\n\n/** @type {*} 组件主次序列视口不同轴位对应的DOM状态存储 */\nconst axisElmentState: Map<\n MedicalComponentID,\n { primary: AxisElements | null; secondary: AxisElements | null }\n> = new Map()\n\n/**\n * @description 初始化组件主次序列视口不同轴位对应的DOM状态\n * @author jiannan.jiao\n * @date 06/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @returns {*} {AxisElements}\n */\nexport function initAxisElementRef(id: DisplayComponentID): AxisElements {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n\n let medicalComponentMap = axisElmentState.get(medicalComponentId)\n if (!medicalComponentMap) {\n medicalComponentMap = { primary: null, secondary: null }\n axisElmentState.set(medicalComponentId, medicalComponentMap)\n }\n\n const elements = {\n [Enums.OrientationAxis.AXIAL]: ref(),\n [Enums.OrientationAxis.SAGITTAL]: ref(),\n [Enums.OrientationAxis.CORONAL]: ref()\n }\n\n Reflect.set(medicalComponentMap, <TOOL_GROUP_TYPE>seriesType, elements)\n\n return elements\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @returns {*} {(AxisElements | null)}\n */\nexport function getAxisElementRef(id: DisplayComponentID): AxisElements | null {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n const medicalComponentMap = axisElmentState.get(medicalComponentId)\n if (medicalComponentMap) {\n return Reflect.get(medicalComponentMap, seriesType)\n }\n return null\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {MedicalComponentID} id\n * @returns {*} {({ primary: AxisElements | null; secondary: AxisElements | null } | null)}\n */\nexport function getComponentAxisElementRef(\n id: MedicalComponentID\n): { primary: AxisElements | null; secondary: AxisElements | null } | null {\n const medicalComponentMap = axisElmentState.get(id)\n if (medicalComponentMap) {\n return medicalComponentMap\n }\n return null\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 11/09/2023\n * @export\n * @param {DisplayComponentID } id\n */\nexport function deleteAxisElementRef(id: DisplayComponentID) {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n\n const medicalComponentMap = axisElmentState.get(medicalComponentId)\n if (medicalComponentMap) {\n Reflect.set(medicalComponentMap, <TOOL_GROUP_TYPE>seriesType, null)\n }\n}\n\n/**\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n */\n\n/** @type {*} 组件主次序列视口不同布局位置对应的轴位状态存储 */\nconst axisOrientationState: Map<\n MedicalComponentID,\n {\n primary: UnwrapNestedRefs<AxisOrientations | null>\n secondary: UnwrapNestedRefs<AxisOrientations | null>\n }\n> = new Map()\n\n/**\n * @description 初始化组件主次序列视口不同布局位置对应的轴位状态\n * @author jiannan.jiao\n * @date 06/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @returns {*} {AxisOrientations}\n */\nexport function initAxisOrientation(id: DisplayComponentID): AxisOrientations {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n\n let medicalComponentMap = axisOrientationState.get(medicalComponentId)\n if (!medicalComponentMap) {\n medicalComponentMap = { primary: null, secondary: null }\n axisOrientationState.set(medicalComponentId, medicalComponentMap)\n }\n\n const orientations = reactive({\n core: Enums.OrientationAxis.AXIAL,\n south: Enums.OrientationAxis.SAGITTAL,\n north: Enums.OrientationAxis.CORONAL\n })\n\n Reflect.set(medicalComponentMap, <TOOL_GROUP_TYPE>seriesType, orientations)\n\n return orientations\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @returns {*} {(AxisOrientations | null)}\n */\nexport function getAxisOrientation(id: DisplayComponentID): AxisOrientations | null {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n const medicalComponentMap = axisOrientationState.get(medicalComponentId)\n if (medicalComponentMap) {\n return Reflect.get(medicalComponentMap, seriesType)\n }\n return null\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {MedicalComponentID} id\n * @returns {*} {({ primary: AxisOrientations | null; secondary: AxisOrientations | null } | null)}\n */\nexport function getComponentAxisOrientation(\n id: MedicalComponentID\n): { primary: AxisOrientations | null; secondary: AxisOrientations | null } | null {\n const medicalComponentMap = axisOrientationState.get(id)\n if (medicalComponentMap) {\n return medicalComponentMap\n }\n return null\n}\n\n/**\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n */\n\n/** @type {*} 组件中主次序列视口全铺状态存储 */\nconst axisFullScreenState: Map<\n MedicalComponentID,\n { primary: FullScreen | null; secondary: FullScreen | null }\n> = new Map()\n\n/**\n * @description 初始化组件主次序列视口全铺状态\n * @author jiannan.jiao\n * @date 06/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @returns {*} {FullScreen}\n */\nexport function initAxisFullScreen(id: DisplayComponentID): FullScreen {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n\n let medicalComponentMap = axisFullScreenState.get(medicalComponentId)\n if (!medicalComponentMap) {\n medicalComponentMap = { primary: null, secondary: null }\n axisFullScreenState.set(medicalComponentId, medicalComponentMap)\n }\n\n const fullScreen = reactive({ core: false, south: false, north: false })\n\n Reflect.set(medicalComponentMap, <TOOL_GROUP_TYPE>seriesType, fullScreen)\n\n return fullScreen\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @returns {*} {(FullScreen | null)}\n */\nexport function getAxisFullScreen(id: DisplayComponentID): FullScreen | null {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n const medicalComponentMap = axisFullScreenState.get(medicalComponentId)\n if (medicalComponentMap) {\n return Reflect.get(medicalComponentMap, seriesType)\n }\n return null\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {MedicalComponentID} id\n * @returns {*} {({ primary: FullScreen | null; secondary: FullScreen | null } | null)}\n */\nexport function getComponentAxisFullScreen(id: MedicalComponentID) {\n const medicalComponentMap = axisFullScreenState.get(id)\n if (medicalComponentMap) {\n return medicalComponentMap\n }\n return null\n}\n\n/**\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n */\n\n/** @type {*} 组件中主次序列的视口ID存储 */\nconst viewportIdsState: Map<\n MedicalComponentID,\n { primary: AxisViewportIds | null; secondary: AxisViewportIds | null }\n> = new Map()\n\n/**\n * @description 保存组件主序列或次序列的视口ID\n * @author jiannan.jiao\n * @date 06/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @param {AxisViewportIds} viewportIds\n * @returns {*} {boolean}\n */\nexport function setAxisViewportIds(id: DisplayComponentID, viewportIds: AxisViewportIds) {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n\n let medicalComponentMap = viewportIdsState.get(medicalComponentId)\n if (!medicalComponentMap) {\n medicalComponentMap = { primary: null, secondary: null }\n viewportIdsState.set(medicalComponentId, medicalComponentMap)\n }\n\n Reflect.set(medicalComponentMap, <TOOL_GROUP_TYPE>seriesType, viewportIds)\n\n return viewportIds\n}\n\n/**\n * @description 获取组件中主序列或次序列的视口ID\n * @author jiannan.jiao\n * @date 06/09/2023\n * @export\n * @param {DisplayComponentID } id\n * @returns {*} {(AxisViewportIds | null)}\n */\nexport function getAxixViewportIds(id: DisplayComponentID): AxisViewportIds | null {\n const { medicalComponentId, seriesType } = splitComponentIdStr(id)\n const medicalComponentMap = getComponentViewportIds(medicalComponentId)\n\n if (medicalComponentMap && seriesType) {\n return medicalComponentMap[<TOOL_GROUP_TYPE>seriesType]\n } else {\n return null\n }\n}\n\n/**\n * @description 获取组件中的全部视口ID,包含主次序列\n * @author jiannan.jiao\n * @date 06/09/2023\n * @export\n * @param {MedicalComponentID} id\n * @returns {*} {({ primary: AxisViewportIds | null; secondary: AxisViewportIds | null } | null)}\n */\nexport function getComponentViewportIds(\n id: MedicalComponentID\n): { primary: AxisViewportIds | null; secondary: AxisViewportIds | null } | null {\n const medicalComponentMap = viewportIdsState.get(id)\n if (medicalComponentMap && (medicalComponentMap.primary || medicalComponentMap.secondary)) {\n return medicalComponentMap\n }\n return null\n}\n\n/**\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n * ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------\n */\n\nconst _3DViewStateMap: Map<MedicalComponentID, UnwrapNestedRefs<State3D>> = new Map()\n\nexport function init3DViewState(id: MedicalComponentID) {\n let state = _3DViewStateMap.get(id)\n if (!state) {\n state = reactive({ componentId: null, initOrientation: null, visible: false })\n _3DViewStateMap.set(id, state)\n }\n\n return state\n}\n\nexport function get3DViewState(id: MedicalComponentID | DisplayComponentID) {\n const { medicalComponentId } = splitComponentIdStr(id)\n return _3DViewStateMap.get(medicalComponentId)\n}\n","/**\n * @description 存储电子密度配置\n * @author jiannan.jiao\n */\n\nimport type { ElectronDensity } from '../types'\n\nconst state: { [id: string]: ElectronDensity } = {}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {string} id\n * @param {ElectronDensity} data\n */\nexport function setElectronDensity(id: string, data: ElectronDensity) {\n if (isValid(data)) {\n Reflect.set(state, id, data)\n } else {\n throw TypeError('Input parameter type error.')\n }\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @export\n * @param {string} id\n * @returns {*} {(ElectronDensity | undefined)}\n */\nexport function getElectronDensity(id: string): ElectronDensity | undefined {\n return Reflect.get(state, id)\n}\n\n/**\n * @description\n * @author jiannan.jiao\n * @date 07/09/2023\n * @param {*} data\n * @returns {*} {boolean}\n */\nfunction isValid(data: any): boolean {\n if (Array.isArray(data)) {\n if (isNaN(data[0].hu) || isNaN(data[0].ed)) {\n return false\n }\n\n return true\n } else {\n return false\n }\n}\n","/*******************************************************************************\n * *\n * Author : Angus Johnson *\n * Version : 6.4.2 *\n * Date : 27 February 2017 *\n * Website : http://www.angusj.com *\n * Copyright : Angus Johnson 2010-2017 *\n * *\n * License: *\n * Use, modification & distribution is subject to Boost Software License Ver 1. *\n * http://www.boost.org/LICENSE_1_0.txt *\n * *\n * Attributions: *\n * The code in this library is an extension of Bala Vatti's clipping algorithm: *\n * \"A generic solution to polygon clipping\" *\n * Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *\n * http://portal.acm.org/citation.cfm?id=129906 *\n * *\n * Computer graphics and geometric modeling: implementation and algorithms *\n * By Max K. Agoston *\n * Springer; 1 edition (January 4, 2005) *\n * http://books.google.com/books?q=vatti+clipping+agoston *\n * *\n * See also: *\n * \"Polygon Offsetting by Computing Winding Numbers\" *\n * Paper no. DETC2005-85513 pp. 565-575 *\n * ASME 2005 International Design Engineering Technical Conferences *\n * and Computers and Information in Engineering Conference (IDETC/CIE2005) *\n * September 24-28, 2005 , Long Beach, California, USA *\n * http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *\n * *\n *******************************************************************************/\n/*******************************************************************************\n * *\n * Au