From f2a52bed23800b75b21bf9111ab7cc17473fb00e Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 1 Jun 2026 11:11:02 +0100 Subject: [PATCH] start new viva view and add window/level sensitivy to dv3d --- atlas/templates/atlas/collection_detail.html | 1 + atlas/templates/atlas/collection_headers.html | 1 + .../atlas/collection_viva_local.html | 348 ++++++++++++++++++ .../atlas/linked_cases_overview.html | 22 +- .../atlas/partials/_linked_case_card.html | 4 +- .../atlas/viewer_local_progressive.html | 274 ++++++++++++++ atlas/tests/test_cases.py | 50 +++ atlas/urls.py | 2 + atlas/views.py | 88 ++++- rad/static/dv3d/index.js | 2 +- 10 files changed, 778 insertions(+), 14 deletions(-) create mode 100644 atlas/templates/atlas/collection_viva_local.html create mode 100644 atlas/templates/atlas/viewer_local_progressive.html diff --git a/atlas/templates/atlas/collection_detail.html b/atlas/templates/atlas/collection_detail.html index d158313a..04999d3a 100644 --- a/atlas/templates/atlas/collection_detail.html +++ b/atlas/templates/atlas/collection_detail.html @@ -61,6 +61,7 @@
{% if collection.collection_type == "VIV" %} Start Viva + Start Viva (Local) {% else %}
Open diff --git a/atlas/templates/atlas/collection_headers.html b/atlas/templates/atlas/collection_headers.html index 23cdd076..33302979 100644 --- a/atlas/templates/atlas/collection_headers.html +++ b/atlas/templates/atlas/collection_headers.html @@ -30,6 +30,7 @@
  • Delete
  • View as viva
  • +
  • View as viva (local)
  • {% if request.user.is_superuser %}
  • Admin Edit
  • diff --git a/atlas/templates/atlas/collection_viva_local.html b/atlas/templates/atlas/collection_viva_local.html new file mode 100644 index 00000000..f1d8845b --- /dev/null +++ b/atlas/templates/atlas/collection_viva_local.html @@ -0,0 +1,348 @@ +{% extends 'atlas/exams.html' %} + +{% block content %} +
    + Help +

    This set up is designed to allow you to project/share cases in a seperate window whilst controlling/tracking their display from this page.

    +

    First you will need to open the linked viewer window by clicking the 'Open Viewer Local' button. This will open a new window/tab with the viewer in it. You will probably need to detach this from your current window.

    +

    If you are sharing the window you can maximise the screen area by hiding the tab/bookmark bar and the address bar. In Microsoft Edge this can be done by installing as an app, in Chrome you can use an extension such as Open-as-Popup.

    +

    Click on the 'Load' button to open the case in a the linked window. Loading subsequent cases/series will replace the first case in the window.

    +

    It is also possible to open a single series by clicking on the 'Load' button next to the individual series.

    +

    Once opened the case details will be show on the right hand side of the page.

    + +
    + +
    +
    +
    +
    +
    +

    Cases

    + + +
      + {% for casedetail in casedetails %} + {% with case=casedetail.case %} +
    1. +
      + Case {{forloop.counter}}: {{case.title}}   + + + + +
      +
      +
      Series: + {% for series in case.series.all %} + + + Series {{ forloop.counter }}:
      + test + {{series.get_block}} +
      + + + +
      +
      +
      + {% endfor %} +
      +
      + {# Hidden per-case question snippet to inject when case is loaded #} + + {# Attached resources for this case: allow loading into the shared viewer #} + {% if case.caseresource_set.exists %} +
      + Resources: +
      + {% for cr in case.caseresource_set.all %} + {% with res=cr.resource %} +
      + {{ res.name }} + +
      + {% endwith %} + {% endfor %} +
      +
      + {% endif %} + {% if case.display_sets.all %} +
      Display Sets: + {% for ds in case.display_sets.all %} +
      + + {{ ds.name }} + {% if ds.description %} + ({{ ds.description }}) + {% endif %} + + + + +
      + {% empty %} + No display sets for this case. + {% endfor %} +
      + {% endif %} +
      +
    2. + {% endwith %} + {% endfor %} +
    +
    +
    + +
    +

    Current Case

    +
    +
    Waiting for case to load in linked window.
    If you are seeing this message you probably need to open the viewer window and reload the case.
    +
    None
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +{% endblock %} + + +{% block js %} + + + {{ form.media }} +{% endblock %} + +{% block css %} + + + + +{% endblock css %} \ No newline at end of file diff --git a/atlas/templates/atlas/linked_cases_overview.html b/atlas/templates/atlas/linked_cases_overview.html index dbaef944..a0c87c8e 100644 --- a/atlas/templates/atlas/linked_cases_overview.html +++ b/atlas/templates/atlas/linked_cases_overview.html @@ -22,10 +22,16 @@ {% if show_case_editor %} Hide case series editor {% endif %} + {% if can_edit_chain and not show_study_dates_editor %} + Open study dates editor + {% endif %} + {% if show_study_dates_editor %} + Hide study dates editor + {% endif %}
    - {% if can_edit_chain %} + {% if can_edit_chain and show_study_dates_editor %}
    @@ -68,14 +74,8 @@ > - {% if row.relative_days is not None %} - {% if row.relative_days == 0 %} - Day 0 - {% elif row.relative_days > 0 %} - +{{ row.relative_days }} day{{ row.relative_days|pluralize }} - {% else %} - {{ row.relative_days }} day{{ row.relative_days|pluralize }} - {% endif %} + {% if row.relative_label %} + {{ row.relative_label.text }} {% else %} No anchor {% endif %} @@ -244,7 +244,7 @@ {% if previous_cases %}
    {% for linked_case in previous_cases %} - {% include "atlas/partials/_linked_case_card.html" with relation_label="Earlier in the linked chain" is_current=False %} + {% include "atlas/partials/_linked_case_card.html" with relation_label="Earlier in the linked chain" relative_label=linked_case.relative_label is_current=False %} {% endfor %}
    {% else %} @@ -262,7 +262,7 @@ {% if next_cases %}
    {% for linked_case in next_cases %} - {% include "atlas/partials/_linked_case_card.html" with relation_label="Later in the linked chain" is_current=False %} + {% include "atlas/partials/_linked_case_card.html" with relation_label="Later in the linked chain" relative_label=linked_case.relative_label is_current=False %} {% endfor %}
    {% else %} diff --git a/atlas/templates/atlas/partials/_linked_case_card.html b/atlas/templates/atlas/partials/_linked_case_card.html index 08882be1..16946183 100644 --- a/atlas/templates/atlas/partials/_linked_case_card.html +++ b/atlas/templates/atlas/partials/_linked_case_card.html @@ -29,7 +29,9 @@ {% endif %}
    - {% if linked_case.get_effective_study_date %} + {% if relative_label %} +
    Timeline {{ relative_label.text }}
    + {% elif linked_case.get_effective_study_date %}
    Study date {{ linked_case.get_effective_study_date|date:"Y-m-d" }}
    {% elif linked_case.published_date %}
    Published {{ linked_case.published_date|date:"Y-m-d" }}
    diff --git a/atlas/templates/atlas/viewer_local_progressive.html b/atlas/templates/atlas/viewer_local_progressive.html new file mode 100644 index 00000000..8483479f --- /dev/null +++ b/atlas/templates/atlas/viewer_local_progressive.html @@ -0,0 +1,274 @@ +{% load static %} + + + + Viewer + + + + + + +
    +
    + Share this screen +

    Awaiting Load Request

    +

    This page will display a DICOM series when loaded from another page.

    +
      +
    • Return to the previous page and select a series to view.
    • +
    • This viewer will update automatically when a series is loaded.
    • +
    • Keep this tab open to receive data.
    • +
    +
    +
    +
    + + + + + + + + \ No newline at end of file diff --git a/atlas/tests/test_cases.py b/atlas/tests/test_cases.py index 0bfc8bb6..61c9031a 100644 --- a/atlas/tests/test_cases.py +++ b/atlas/tests/test_cases.py @@ -233,3 +233,53 @@ def test_linked_cases_editor_is_hidden_until_requested(client, create_user, make ) assert response_with_editor.status_code == 200 assertContains(response_with_editor, "Case Series Editor") + + +@pytest.mark.django_db +def test_linked_cases_study_dates_editor_is_hidden_until_requested(client, create_user, make_case): + user = create_user + case1 = make_case(title="Case 1") + case2 = make_case(title="Case 2") + case2.previous_case = case1 + case2.save(update_fields=["previous_case"]) + + case1.author.add(user) + case2.author.add(user) + + client.force_login(user) + + response_default = client.get( + reverse("atlas:linked_cases_overview", kwargs={"case_id": case1.pk}) + ) + assert response_default.status_code == 200 + assertContains(response_default, "Open study dates editor") + assert "Study Dates" not in response_default.content.decode("utf-8") + + response_with_editor = client.get( + reverse("atlas:linked_cases_overview", kwargs={"case_id": case1.pk}) + "?show_dates=1" + ) + assert response_with_editor.status_code == 200 + assertContains(response_with_editor, "Study Dates") + + +@pytest.mark.django_db +def test_linked_case_card_shows_scaled_relative_timeline_label(client, create_user, make_case): + user = create_user + case1 = make_case(title="Case 1") + case2 = make_case(title="Case 2") + case2.previous_case = case1 + case2.study_date = datetime.date(2028, 1, 1) + case2.save(update_fields=["previous_case", "study_date"]) + case1.study_date = datetime.date(2026, 1, 1) + case1.save(update_fields=["study_date"]) + + case1.author.add(user) + case2.author.add(user) + + client.force_login(user) + + response = client.get( + reverse("atlas:linked_cases_overview", kwargs={"case_id": case1.pk}) + ) + assert response.status_code == 200 + assertContains(response, "Timeline +2 years") diff --git a/atlas/urls.py b/atlas/urls.py index 423f2ced..39c84d75 100755 --- a/atlas/urls.py +++ b/atlas/urls.py @@ -97,8 +97,10 @@ urlpatterns = [ ), path("collection/viewer", TemplateView.as_view(template_name="atlas/viewer.html"), name="collection_viewer"), path("collection/viewer_local", TemplateView.as_view(template_name="atlas/viewer_local.html"), name="collection_viewer_local"), + path("collection/viewer_local_progressive", TemplateView.as_view(template_name="atlas/viewer_local_progressive.html"), name="collection_viewer_local_progressive"), path("collection/", views.collection_detail, name="collection_detail"), path("collection//viva", views.collection_viva, name="collection_viva"), + path("collection//viva-local", views.collection_viva_local, name="collection_viva_local"), path("collection//viva/", views.collection_viva_case, name="collection_viva_case"), path("collection//viva//series", views.collection_viva_series, name="collection_viva_series"), path( diff --git a/atlas/views.py b/atlas/views.py index c6168690..3b0e8a8f 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -195,6 +195,37 @@ def _extract_study_date_from_dicoms(dicoms): return study_date return None + +def _format_relative_date_offset(days_delta): + if days_delta is None: + return None + + if days_delta == 0: + return {"text": "Day 0", "unit": "day", "value": 0} + + sign_prefix = "+" if days_delta > 0 else "-" + absolute_days = abs(days_delta) + + if absolute_days >= 365: + value = round(absolute_days / 365.25, 1) + unit = "year" + elif absolute_days >= 30: + value = round(absolute_days / 30.4375, 1) + unit = "month" + else: + value = absolute_days + unit = "day" + + if isinstance(value, float) and value.is_integer(): + value = int(value) + + suffix = "s" if value != 1 else "" + return { + "text": f"{sign_prefix}{value} {unit}{suffix}", + "unit": unit, + "value": value, + } + from .tasks import push_case_to_cimar_task, series_downsample_task, series_reconstruct_task try: from django_tasks import TaskResultStatus @@ -5724,6 +5755,49 @@ def collection_viva(request, pk): ) +@user_is_collection_author_or_atlas_editor +def collection_viva_local(request, pk): + """ + Local-only viva controller view. + + Scope: + - Mirrors `collection_viva` functionality for case/series/displayset loading. + - Uses only the embedded local DV3D viewer workflow. + - Keeps the original viva route intact for side-by-side rollout. + """ + collection = get_object_or_404(CaseCollection, pk=pk) + + from django.db.models import Prefetch as _Prefetch + + series_images_qs = SeriesImage.objects.filter(removed=False).order_by("position") + series_qs = Series.objects.order_by("seriesdetail__sort_order").prefetch_related( + _Prefetch("images", queryset=series_images_qs) + ) + + casedetails = ( + CaseDetail.objects + .filter(collection=collection) + .select_related("case") + .order_by("sort_order") + .prefetch_related( + _Prefetch("case__series", queryset=series_qs), + _Prefetch("case__series__modality"), + _Prefetch("case__series__examination"), + _Prefetch("case__series__plane"), + _Prefetch("case__series__contrast"), + _Prefetch("case__caseresource_set"), + _Prefetch("case__display_sets"), + ) + .annotate(series_count=Count("case__seriesdetail")) + ) + + return render( + request, + "atlas/collection_viva_local.html", + {"collection": collection, "casedetails": casedetails, "can_edit": True}, + ) + + @user_is_collection_author_or_atlas_editor def collection_viva_case(request, pk, case_number): collection = get_object_or_404(CaseCollection, pk=pk) @@ -9584,6 +9658,7 @@ def linked_cases_overview(request, case_id): direct_next = next_cases[0] if next_cases else None case_editor_prefix = "case_series_editor" + show_study_dates_editor = request.GET.get("show_dates") == "1" show_case_editor = request.GET.get("show_editor") == "1" case_editor_selected_field = "" case_editor_selected_source = "" @@ -9692,6 +9767,8 @@ def linked_cases_overview(request, case_id): if not case.check_user_can_edit(request.user): raise PermissionDenied("You do not have permission to edit this case chain.") + show_study_dates_editor = True + apply_to_all_from = request.POST.get("apply_to_all_from") updated_cases = 0 @@ -9722,12 +9799,13 @@ def linked_cases_overview(request, case_id): updated_cases += 1 messages.success(request, f"Updated {updated_cases} linked case date(s).") - return redirect("atlas:linked_cases_overview", case_id=case.pk) + return redirect(f"{reverse('atlas:linked_cases_overview', kwargs={'case_id': case.pk})}?show_dates=1") if show_case_editor and editable_chain_case_ids: case_editor_formset, case_editor_rows = build_case_editor_formset() linked_case_rows = [] + case_relative_labels = {} anchor_date = next( (linked_case.get_effective_study_date() for linked_case in chain_cases if linked_case.get_effective_study_date()), None, @@ -9735,13 +9813,19 @@ def linked_cases_overview(request, case_id): for linked_case in chain_cases: study_date = linked_case.get_effective_study_date() relative_days = None + relative_label = None if anchor_date and study_date: relative_days = (study_date - anchor_date).days + relative_label = _format_relative_date_offset(relative_days) + + case_relative_labels[linked_case.pk] = relative_label + linked_case.relative_label = relative_label linked_case_rows.append( { "case": linked_case, "study_date": study_date, "relative_days": relative_days, + "relative_label": relative_label, "can_edit": linked_case.check_user_can_edit(request.user), "is_current": linked_case.pk == case.pk, } @@ -9762,6 +9846,7 @@ def linked_cases_overview(request, case_id): "current_index": len(previous_cases) + 1, "direct_previous": direct_previous, "direct_next": direct_next, + "show_study_dates_editor": show_study_dates_editor, "show_case_editor": show_case_editor, "case_editor_formset": case_editor_formset, "case_editor_rows": case_editor_rows, @@ -9771,6 +9856,7 @@ def linked_cases_overview(request, case_id): "case_editor_prefix": case_editor_prefix, "editable_case_count": len(editable_chain_case_ids), "locked_case_count": len(chain_case_ids) - len(editable_chain_case_ids), + "case_relative_labels": case_relative_labels, }, ) diff --git a/rad/static/dv3d/index.js b/rad/static/dv3d/index.js index 84de8263..956e69cd 100644 --- a/rad/static/dv3d/index.js +++ b/rad/static/dv3d/index.js @@ -3857,4 +3857,4 @@ throwBindingError('function `+$+" called with ' + arguments.length + ' arguments `,Wt.push(bn+"_dtor"),Mn.push(K[Le].destructorFunction))}Fe&&(It+=`var ret = retType.fromWireType(rv); return ret; `),It+=`} -`,Wt.push(It);var ar=Ms(Function,Wt).apply(null,Mn);return ar}function so($,K,R,U,X,he){T(K>0);var xe=Di(K,R);X=Cr(U,X),Ni([],[$],function(be){be=be[0];var Le="constructor "+be.name;if(be.registeredClass.constructor_body===void 0&&(be.registeredClass.constructor_body=[]),be.registeredClass.constructor_body[K-1]!==void 0)throw new Mo("Cannot register multiple constructors with identical number of parameters ("+(K-1)+") for class '"+be.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!");return be.registeredClass.constructor_body[K-1]=()=>{dn("Cannot construct "+be.name+" due to unbound types",xe)},Ni([],xe,function(Fe){return Fe.splice(1,0,null),be.registeredClass.constructor_body[K-1]=mr(Le,Fe,null,X,he),[]}),[]})}function No($,K,R,U,X,he,xe,be){var Le=Di(R,U);K=Tr(K),he=Cr(X,he),Ni([],[$],function(Fe){Fe=Fe[0];var He=Fe.name+"."+K;K.startsWith("@@")&&(K=Symbol[K.substring(2)]),be&&Fe.registeredClass.pureVirtualFunctions.push(K);function ft(){dn("Cannot call "+He+" due to unbound types",Le)}var It=Fe.registeredClass.instancePrototype,Jt=It[K];return Jt===void 0||Jt.overloadTable===void 0&&Jt.className!==Fe.name&&Jt.argCount===R-2?(ft.argCount=R-2,ft.className=Fe.name,It[K]=ft):(oo(It,K,He),It[K].overloadTable[R-2]=ft),Ni([],Le,function(Wt){var Mn=mr(He,Wt,Fe,he,xe);return It[K].overloadTable===void 0?(Mn.argCount=R-2,It[K]=Mn):It[K].overloadTable[R-2]=Mn,[]}),[]})}var fa=[],Jr=[{},{value:void 0},{value:null},{value:!0},{value:!1}];function nc($){$>4&&--Jr[$].refcount===0&&(Jr[$]=void 0,fa.push($))}function Ul(){for(var $=0,K=5;K($||Bn("Cannot use deleted val. handle = "+$),Jr[$].value),toHandle:$=>{switch($){case void 0:return 1;case null:return 2;case!0:return 3;case!1:return 4;default:{var K=fa.length?fa.pop():Jr.length;return Jr[K]={refcount:1,value:$},K}}}};function os($,K){K=Tr(K),fi($,{name:K,fromWireType:function(R){var U=is.toValue(R);return nc(R),U},toWireType:function(R,U){return is.toHandle(U)},argPackAdvance:8,readValueFromPointer:dr,destructorFunction:null})}function rc($){if($===null)return"null";var K=typeof $;return K==="object"||K==="array"||K==="function"?$.toString():""+$}function jc($,K){switch(K){case 2:return function(R){return this.fromWireType(Q[R>>2])};case 3:return function(R){return this.fromWireType(oe[R>>3])};default:throw new TypeError("Unknown float type: "+$)}}function ic($,K,R){var U=ro(R);K=Tr(K),fi($,{name:K,fromWireType:function(X){return X},toWireType:function(X,he){return he},argPackAdvance:8,readValueFromPointer:jc(K,U),destructorFunction:null})}function Bl($,K,R,U,X,he){var xe=Di(K,R);$=Tr($),X=Cr(U,X),di($,function(){dn("Cannot call "+$+" due to unbound types",xe)},K-1),Ni([],xe,function(be){var Le=[be[0],null].concat(be.slice(1));return rs($,mr($,Le,null,X,he),K-1),[]})}function Gl($,K,R){switch(K){case 0:return R?function(X){return V[X]}:function(X){return W[X]};case 1:return R?function(X){return A[X>>1]}:function(X){return k[X>>1]};case 2:return R?function(X){return F[X>>2]}:function(X){return H[X>>2]};default:throw new TypeError("Unknown integer type: "+$)}}function Hc($,K,R,U,X){K=Tr(K);var he=ro(R),xe=ft=>ft;if(U===0){var be=32-8*R;xe=ft=>ft<>>be}var Le=K.includes("unsigned"),Fe=(ft,It)=>{},He;Le?He=function(ft,It){return Fe(It,this.name),It>>>0}:He=function(ft,It){return Fe(It,this.name),It},fi($,{name:K,fromWireType:xe,toWireType:He,argPackAdvance:8,readValueFromPointer:Gl(K,he,U!==0),destructorFunction:null})}function oc($,K,R){var U=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],X=U[K];function he(xe){xe=xe>>2;var be=H,Le=be[xe],Fe=be[xe+1];return new X(L,Fe,Le)}R=Tr(R),fi($,{name:R,fromWireType:he,argPackAdvance:8,readValueFromPointer:he},{ignoreDuplicateRegistrations:!0})}function Kc($,K){K=Tr(K);var R=K==="std::string";fi($,{name:K,fromWireType:function(U){var X=H[U>>2],he=U+4,xe;if(R)for(var be=he,Le=0;Le<=X;++Le){var Fe=he+Le;if(Le==X||W[Fe]==0){var He=Fe-be,ft=D(be,He);xe===void 0?xe=ft:(xe+="\0",xe+=ft),be=Fe+1}}else{for(var It=new Array(X),Le=0;Le>2]=he,R&&xe)P(X,Le,he+1);else if(xe)for(var Fe=0;Fe255&&(Ee(Le),Bn("String has UTF-16 code units that do not fit in 8 bits")),W[Le+Fe]=He}else for(var Fe=0;Fe>1,X=U+K/2;!(U>=X)&&k[U];)++U;if(R=U<<1,R-$>32&&Ps)return Ps.decode(W.subarray($,R));for(var he="",xe=0;!(xe>=K/2);++xe){var be=A[$+xe*2>>1];if(be==0)break;he+=String.fromCharCode(be)}return he}function ac($,K,R){if(R===void 0&&(R=2147483647),R<2)return 0;R-=2;for(var U=K,X=R<$.length*2?R/2:$.length,he=0;he>1]=xe,K+=2}return A[K>>1]=0,K-U}function Rs($){return $.length*2}function sc($,K){for(var R=0,U="";!(R>=K/4);){var X=F[$+R*4>>2];if(X==0)break;if(++R,X>=65536){var he=X-65536;U+=String.fromCharCode(55296|he>>10,56320|he&1023)}else U+=String.fromCharCode(X)}return U}function Ls($,K,R){if(R===void 0&&(R=2147483647),R<4)return 0;for(var U=K,X=U+R-4,he=0;he<$.length;++he){var xe=$.charCodeAt(he);if(xe>=55296&&xe<=57343){var be=$.charCodeAt(++he);xe=65536+((xe&1023)<<10)|be&1023}if(F[K>>2]=xe,K+=4,K+4>X)break}return F[K>>2]=0,K-U}function da($){for(var K=0,R=0;R<$.length;++R){var U=$.charCodeAt(R);U>=55296&&U<=57343&&++R,K+=4}return K}function qc($,K,R){R=Tr(R);var U,X,he,xe,be;K===2?(U=as,X=ac,xe=Rs,he=()=>k,be=1):K===4&&(U=sc,X=Ls,xe=da,he=()=>H,be=2),fi($,{name:R,fromWireType:function(Le){for(var Fe=H[Le>>2],He=he(),ft,It=Le+4,Jt=0;Jt<=Fe;++Jt){var Wt=Le+4+Jt*K;if(Jt==Fe||He[Wt>>be]==0){var Mn=Wt-It,bn=U(It,Mn);ft===void 0?ft=bn:(ft+="\0",ft+=bn),It=Wt+K}}return Ee(Le),ft},toWireType:function(Le,Fe){typeof Fe!="string"&&Bn("Cannot pass non-string to C++ string type "+R);var He=xe(Fe),ft=ne(4+He+K);return H[ft>>2]=He>>be,X(Fe,ft+4,He+K),Le!==null&&Le.push(Ee,ft),ft},argPackAdvance:8,readValueFromPointer:dr,destructorFunction:function(Le){Ee(Le)}})}function cc($,K,R,U,X,he){En[$]={name:Tr(K),rawConstructor:Cr(R,U),rawDestructor:Cr(X,he),fields:[]}}function Xc($,K,R,U,X,he,xe,be,Le,Fe){En[$].fields.push({fieldName:Tr(K),getterReturnType:R,getter:Cr(U,X),getterContext:he,setterArgumentType:xe,setter:Cr(be,Le),setterContext:Fe})}function Yc($,K){K=Tr(K),fi($,{isVoid:!0,name:K,argPackAdvance:0,fromWireType:function(){},toWireType:function(R,U){}})}function As($){$>4&&(Jr[$].refcount+=1)}function ss($,K){var R=Et[$];return R===void 0&&Bn(K+" has unknown type "+hi($)),R}function Wl($,K){$=ss($,"_emval_take_value");var R=$.readValueFromPointer(K);return is.toHandle(R)}function br(){Xe("")}function lc($,K,R){W.copyWithin($,K,K+R)}function uc(){return 2147483648}function ha($){try{return S.grow($-L.byteLength+65535>>>16),ve(S.buffer),1}catch{}}function fc($){var K=W.length;$=$>>>0;var R=uc();if($>R)return!1;let U=(Le,Fe)=>Le+(Fe-Le%Fe)%Fe;for(var X=1;X<=4;X*=2){var he=K*(1+.2/X);he=Math.min(he,$+100663296);var xe=Math.min(R,U(Math.max($,he),65536)),be=ha(xe);if(be)return!0}return!1}function Ko($){return 52}function Ui($,K,R,U,X){return 70}var Co=[null,[],[]];function Jc($,K){var R=Co[$];K===0||K===10?(($===1?w:x)(b(R,0)),R.length=0):R.push(K)}function ga($,K,R,U){for(var X=0,he=0;he>2],be=H[K+4>>2];K+=8;for(var Le=0;Le>2]=X,0}function dc($){return $}function Zc($){var K=o["_"+$];return K}function cs($,K){V.set($,K)}function Qc($,K,R,U,X){var he={string:Wt=>{var Mn=0;if(Wt!=null&&Wt!==0){var bn=(Wt.length<<2)+1;Mn=yt(bn),P(Wt,Mn,bn)}return Mn},array:Wt=>{var Mn=yt(Wt.length);return cs(Wt,Mn),Mn}};function xe(Wt){return K==="string"?D(Wt):K==="boolean"?!!Wt:Wt}var be=Zc($),Le=[],Fe=0;if(U)for(var He=0;He0||(Pe(),ee>0))return;function K(){mt||(mt=!0,o.calledRun=!0,!_&&(G(),a(o),o.onRuntimeInitialized&&o.onRuntimeInitialized(),O()))}o.setStatus?(o.setStatus("Running..."),setTimeout(function(){setTimeout(function(){o.setStatus("")},1),K()},1)):K()}if(o.preInit)for(typeof o.preInit=="function"&&(o.preInit=[o.preInit]);o.preInit.length>0;)o.preInit.pop()();return lt(),o.ready}})();t.exports=r})(UW);var fSe=UW.exports;const dSe=Nl(fSe),hSe=new URL("/static/dv3d/openjphjs.wasm",import.meta.url),pp={codec:void 0,decoder:void 0,decodeConfig:{}};function gSe(t,e,r){const n={width:e,height:r};for(;t>0;)n.width=Math.ceil(n.width/2),n.height=Math.ceil(n.height/2),t--;return n}function pSe(t){if(pp.decodeConfig=t,pp.codec)return Promise.resolve();const e=dSe({locateFile:r=>r.endsWith(".wasm")?hSe.toString():r});return new Promise((r,n)=>{e.then(i=>{pp.codec=i,pp.decoder=new i.HTJ2KDecoder,r()},n)})}async function mSe(t,e){await pSe();const r=new pp.codec.HTJ2KDecoder,n=r.getEncodedBuffer(t.length);n.set(t);const i=e.decodeLevel||0;r.decodeSubResolution(i);const o=r.getFrameInfo();if(e.decodeLevel>0){const{width:E,height:b}=gSe(e.decodeLevel,o.width,o.height);o.width=E,o.height=b}const a=r.getDecodedBuffer();new Uint8Array(a.length).set(a);const c=`x: ${r.getImageOffset().x}, y: ${r.getImageOffset().y}`,l=r.getNumDecompositions(),f=r.getNumLayers(),u=["unknown","LRCP","RLCP","RPCL","PCRL","CPRL"][r.getProgressionOrder()+1],d=r.getIsReversible(),h=`${r.getBlockDimensions().width} x ${r.getBlockDimensions().height}`,g=`${r.getTileSize().width} x ${r.getTileSize().height}`,p=`${r.getTileOffset().x}, ${r.getTileOffset().y}`,v=`${a.length.toLocaleString()} bytes`,y=`${(a.length/n.length).toFixed(2)}:1`,m={columns:o.width,rows:o.height,bitsPerPixel:o.bitsPerSample,signed:o.isSigned,bytesPerPixel:e.bytesPerPixel,componentsPerPixel:o.componentCount};let w=vSe(o,a);const{buffer:x,byteOffset:C,byteLength:S}=w,_=x.slice(C,C+S);w=new w.constructor(_);const T={imageOffset:c,numDecompositions:l,numLayers:f,progessionOrder:u,reversible:d,blockDimensions:h,tileSize:g,tileOffset:p,decodedSize:v,compressionRatio:y};return{...e,pixelData:w,imageInfo:m,encodeOptions:T,...T,...m}}function vSe(t,e){return t.bitsPerSample>8?t.isSigned?new Int16Array(e.buffer,e.byteOffset,e.byteLength/2):new Uint16Array(e.buffer,e.byteOffset,e.byteLength/2):t.isSigned?new Int8Array(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}function ySe(t,e){const r=t.length,{rescaleSlope:n,rescaleIntercept:i,suvbw:o,doseGridScaling:a}=e;if(e.modality==="PT"&&typeof o=="number"&&!isNaN(o))for(let s=0;s>o;let a=t.pixelData;t.pixelDataLength=t.pixelData.length;const{min:s,max:c}=Yw(t.pixelData),l=typeof e.allowFloatRendering<"u"?e.allowFloatRendering:!0;let f=v8(t.photometricInterpretation)&&((m=e.targetBuffer)==null?void 0:m.offset)===void 0;const d=((w=e.preScale)==null?void 0:w.enabled)&&Object.values(e.preScale.scalingParameters).some(C=>typeof C=="number"&&!Number.isInteger(C)),h=!e.preScale.enabled||!l&&d,g=(x=e.targetBuffer)==null?void 0:x.type;if(g&&e.preScale.enabled&&!h){const C=e.preScale.scalingParameters,S=u_(s,c,C);f=!ZCe(S.min,S.max,e7[g])}g&&!f?a=SSe(e,t,e7,a):e.preScale.enabled&&!h?a=_Se(e,s,c,t):a=BW(s,c,t);let p=s,v=c;if(e.preScale.enabled&&!h){const C=e.preScale.scalingParameters;if(GW(C),CSe(C)){ySe(a,C),t.preScale={...e.preScale,scaled:!0};const _=u_(s,c,C);p=_.min,v=_.max}}else h&&(t.preScale={enabled:!0,scaled:!1},p=s,v=c);t.pixelData=a,t.smallestPixelValue=p,t.largestPixelValue=v;const y=new Date().getTime();return t.decodeTimeInMS=y-r,t}function CSe(t){const{rescaleSlope:e,rescaleIntercept:r,modality:n,doseGridScaling:i,suvbw:o}=t;return typeof e=="number"&&typeof r=="number"||n==="RTDOSE"&&typeof i=="number"||n==="PT"&&typeof o=="number"}function SSe(t,e,r,n){const{arrayBuffer:i,type:o,offset:a=0,length:s,rows:c}=t.targetBuffer,l=r[o];if(!l)throw new Error(`target array ${o} is not supported, or doesn't exist.`);c&&c!=e.rows&&ESe(e,t.targetBuffer,l);const f=e.pixelDataLength,u=a,d=s??f-u,h=e.pixelData;if(d!==h.length)throw new Error(`target array for image does not have the same length (${d}) as the decoded image length (${h.length}).`);const g=i?new l(i,u,d):new l(d);return g.set(h,0),n=g,n}function _Se(t,e,r,n){const i=t.preScale.scalingParameters;GW(i);const o=u_(e,r,i);return BW(o.min,o.max,n)}function BW(t,e,r){const n=y8(t,e),i=new n(r.pixelData.length);return i.set(r.pixelData,0),i}function u_(t,e,r){const{rescaleSlope:n,rescaleIntercept:i,modality:o,doseGridScaling:a,suvbw:s}=r;return o==="PT"&&typeof s=="number"&&!isNaN(s)?{min:s*(t*n+i),max:s*(e*n+i)}:o==="RTDOSE"&&typeof a=="number"&&!isNaN(a)?{min:t*a,max:e*a}:typeof n=="number"&&typeof i=="number"?{min:n*t+i,max:n*e+i}:{min:t,max:e}}function GW(t){if(!t)throw new Error("options.preScale.scalingParameters must be defined if preScale.enabled is true, and scalingParameters cannot be derived from the metadata providers.")}function TSe(t,e,r){const{samplesPerPixel:n}=t,{rows:i,columns:o}=e,a=i*o*n,s=new r(a),c=s.byteLength/a;return{pixelData:s,rows:i,columns:o,frameInfo:{...t.frameInfo,rows:i,columns:o},imageInfo:{...t.imageInfo,rows:i,columns:o,bytesPerPixel:c}}}function ESe(t,e,r){const n=TSe(t,e,r),{scalingType:i="replicate"}=e;return wSe[i](t,n),Object.assign(t,n),t.pixelDataLength=t.pixelData.length,t}async function WW(t,e,r,n,i,o){const a=new Date().getTime();let s=null,c;switch(e){case"1.2.840.10008.1.2":case"1.2.840.10008.1.2.1":s=XI(t,r);break;case"1.2.840.10008.1.2.2":s=F3e(t,r);break;case"1.2.840.10008.1.2.1.99":s=XI(t,r);break;case"1.2.840.10008.1.2.5":s=U3e(t,r);break;case"1.2.840.10008.1.2.4.50":c={...t},s=K3e(r,c);break;case"1.2.840.10008.1.2.4.51":s=Z3e(t,r);break;case"1.2.840.10008.1.2.4.57":s=JI(t,r);break;case"1.2.840.10008.1.2.4.70":s=JI(t,r);break;case"1.2.840.10008.1.2.4.80":c={signed:t.pixelRepresentation===1,bytesPerPixel:t.bitsAllocated<=8?1:2,...t},s=ZI(r,c);break;case"1.2.840.10008.1.2.4.81":c={signed:t.pixelRepresentation===1,bytesPerPixel:t.bitsAllocated<=8?1:2,...t},s=ZI(r,c);break;case"1.2.840.10008.1.2.4.90":c={...t},s=QI(r,c);break;case"1.2.840.10008.1.2.4.91":c={...t},s=QI(r,c);break;case"3.2.840.10008.1.2.4.96":case"1.2.840.10008.1.2.4.201":case"1.2.840.10008.1.2.4.202":case"1.2.840.10008.1.2.4.203":c={...t},s=mSe(r,c);break;default:throw new Error(`no decoder for transfer syntax ${e}`)}if(!s)throw new Error("decodePromise not defined");const l=await s,f=xSe(l,i,a);return o==null||o(f),f}const bSe={decodeTask({imageFrame:t,transferSyntax:e,decodeConfig:r,options:n,pixelData:i,callbackFn:o}){return WW(t,e,i,r,n,o)}};l4(bSe);const $u={constants:A3e,convertRGBColorByPixel:JG,convertRGBColorByPlane:ZG,convertYBRFullByPixel:QG,convertYBRFullByPlane:eW,convertPALETTECOLOR:tW,wadouri:r3e,wadors:I3e,init:AW,convertColorSpace:xW,createImage:Jw,decodeJPEGBaseline8BitColor:CW,getImageFrame:SW,getPixelData:S8,getMinMax:Yw,isColorImage:v8,isJPEGBaseline8BitColor:R3e,internal:yCe,decodeImageFrame:WW},t7={debug:0,info:1,warn:2,error:3,silent:4},_8={minLevel:"warn",format:"compact",namespace:"dv3d",dedupeWindowMs:1200};let qs={..._8};const n7=new Map;function zW(){return new Date().toISOString()}function r7(t){return t==="debug"?console.debug.bind(console):t==="info"?console.info.bind(console):t==="warn"?console.warn.bind(console):console.error.bind(console)}function $W(t){return t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t}function DSe(t){return t7[t]>=t7[qs.minLevel]}function ISe(t){return t==="debug"||t==="info"}function OSe(t,e,r){const n=(r==null?void 0:r.dedupeKey)||`${(r==null?void 0:r.namespace)||qs.namespace}:${t}`,i=e.map(o=>{if(typeof o=="string")return o;try{return JSON.stringify($W(o))}catch{return String(o)}}).join("|");return`${n}:${i}`}function MSe(t,e,r){if(!ISe(t)||qs.dedupeWindowMs<=0)return!1;const n=OSe(t,e,r),i=Date.now(),o=n7.get(n);return n7.set(n,i),o===void 0?!1:i-oju("debug",t),info:(...t)=>ju("info",t),warn:(...t)=>ju("warn",t),error:(...t)=>ju("error",t),child:t=>({debug:(...e)=>ju("debug",e,{namespace:t}),info:(...e)=>ju("info",e,{namespace:t}),warn:(...e)=>ju("warn",e,{namespace:t}),error:(...e)=>ju("error",e,{namespace:t})})};class $h extends Wf{}r6($h,"toolName","NoLabelArrowAnnotate");const K2=gu.prototype;if(!K2._mouseSensitivityPatched){const t=K2.getNewRange;K2.getNewRange=function({deltaPointsCanvas:e,...r}){var o;const n=typeof((o=this==null?void 0:this.configuration)==null?void 0:o.mouseSensitivity)=="number"?this.configuration.mouseSensitivity:1,i=Array.isArray(e)?[e[0]*n,e[1]*n]:e;return t.call(this,{...r,deltaPointsCanvas:i})},K2._mouseSensitivityPatched=!0}function i7(t,e){const r=xt("imagePlaneModule",t);if(!r)return;const{rowCosines:n,columnCosines:i,imagePositionPatient:o,rowPixelSpacing:a,columnPixelSpacing:s}=r;if(!n||!i||!o)return;const c=s||1,l=a||1;return{x:o[0]+n[0]*e.y*l+i[0]*e.x*c,y:o[1]+n[1]*e.y*l+i[1]*e.x*c,z:o[2]+n[2]*e.y*l+i[2]*e.x*c}}const{MouseBindings:qg,KeyboardBindings:o7}=Lk,{IMAGE_RENDERED:Xg}=ct,RSe=[{name:"Soft Tissue",center:40,width:400},{name:"Lung",center:-600,width:1500},{name:"Bone",center:300,width:1500},{name:"Brain",center:40,width:80},{name:"Abdomen",center:60,width:400}],a7=t=>{const e=(t||"").toUpperCase(),r=[{name:"Reset to default",action:"reset"},{name:"Auto level",action:"autolevel"}];return e!=="CT"?r:[...r,...RSe.map(n=>({name:n.name,action:"preset",center:n.center,width:n.width}))]},md=[{label:"Window/Level",value:gu.toolName,icon:"🌓"},{label:"Pan",value:Ec.toolName,icon:"✋"},{label:"Zoom",value:gl.toolName,icon:"🔍"},{label:"Stack Scroll",value:bf.toolName,icon:"📚"},{label:"Rotate",value:Bh.toolName,icon:"↺"},{label:"Length",value:Gf.toolName,icon:"📏"},{label:"Probe",value:Iu.toolName,icon:"🔎"},{label:"Arrow (No Label)",value:$h.toolName,icon:"➡️"},{label:"Arrow Annotate",value:Wf.toolName,icon:"✈️"},{label:"Rectangle ROI",value:Du.toolName,icon:"▭"},{label:"Ellipse ROI",value:e0.toolName,icon:"◯"},{label:"Freehand ROI",value:Bf.toolName,icon:"✏️"},{label:"Freehand Contour Segmentation",value:Ll.toolName,icon:"🖊️"},{label:"Sculptor",value:Gh.toolName,icon:"🔧"},{label:"Reference Cursors",value:gs.toolName,icon:"⦿"}],LSe=3,ASe=220,s7="dv3d_logging",NSe=[{label:"Compact",value:"compact"},{label:"Verbose",value:"verbose"},{label:"JSON",value:"json"}],kSe=[{label:"Off",value:"silent"},{label:"Error",value:"error"},{label:"Warn",value:"warn"},{label:"Info",value:"info"},{label:"Debug",value:"debug"}],c7="dv3d_grouping",mp=[{id:"dwiBValue",label:"DWI b-value",description:"DiffusionBValue (0018,9087) + known private fallbacks",defaultEnabled:!0},{id:"dwiDirection",label:"DWI direction",description:"Diffusion Gradient Direction (0018,9089)",defaultEnabled:!0},{id:"temporalPosition",label:"Temporal position",description:"Temporal Position Identifier (0020,0100)",defaultEnabled:!0},{id:"triggerTime",label:"Trigger time",description:"Trigger Time (0018,1060)",defaultEnabled:!0},{id:"contentTime",label:"Content/Acquisition time",description:"Content Time (0008,0033) / Acquisition Time (0008,0032)",defaultEnabled:!1},{id:"echoTime",label:"Echo time",description:"Echo Time (0018,0081)",defaultEnabled:!0},{id:"echoNumber",label:"Echo number",description:"Echo Number (0018,0086)",defaultEnabled:!0}];function l7(){return mp.reduce((t,e)=>(t[e.id]=e.defaultEnabled,t),{})}const kt=jW.child("app");function u7(t){if(!t)return"🔖";const e=md.find(r=>r.value===t||r.label===t);return(e==null?void 0:e.icon)||"🔖"}function il(t){return t?t.startsWith("wadouri:")?t.replace(/^wadouri:+/,"").replace(/^:+/,""):t:""}function d_(t){return/([?&])frame=\d+/i.test(t)}function f7(t,e){const r=Math.max(1,Math.floor(e));return d_(t)?t.replace(/([?&])frame=\d+/i,`$1frame=${r}`):`${t}&frame=${r}`}function d7(t){const e=t.match(/[?&]frame=(\d+)/i);if(!e)return null;const r=Number(e[1]);return Number.isFinite(r)&&r>0?Math.floor(r):null}function _5(t){return t?t.split(/\\|,/).map(e=>Number(e.trim())).filter(e=>Number.isFinite(e)):[]}function AC(t){if(!t||typeof t!="object")return[];const e=o=>{if(typeof t.string=="function"){const a=t.string(o);if(a!=null&&a!==""){const s=_5(a);if(s.length>0&&Number.isFinite(s[0])&&s[0]>=0)return s[0]}}if(typeof t.double=="function")try{const a=t.double(o);if(Number.isFinite(a)&&a>=0)return a}catch{}if(typeof t.float=="function")try{const a=t.float(o);if(Number.isFinite(a)&&a>=0)return a}catch{}return null},r=e("x00189087");if(r!==null)return[r];const n=e("x0019100c");if(n!==null)return[n];if(typeof t.string=="function"){const o=t.string("x00431039");if(o){const a=_5(o);if(a.length>0&&Number.isFinite(a[0])&&a[0]>=0)return[a[0]]}}const i=e("x20011003");return i!==null?[i]:[]}function va(t){return t.startsWith("wadouri:")||t.startsWith("external:")?t:`wadouri:${t}`}function So(t){const e=new Set,r=[];for(const n of t)!n||e.has(n)||(e.add(n),r.push(n));return r}function VSe(t){try{const e=t.getContext("2d",{willReadFrequently:!0});if(!e)return!0;const r=t.width||160,n=t.height||160,o=e.getImageData(0,0,r,n).data;let a=255,s=0,c=0,l=0;for(let d=0;d0&&w>12&&(c+=1),a=Math.min(a,w),s=Math.max(s,w),l+=1}if(l===0)return!0;const f=c/l,u=s-a;return f>.015||u>8}catch{return!0}}const h7=[{label:"Left",value:"Primary"},{label:"Middle",value:"Auxiliary"},{label:"Right",value:"Secondary"}],q2=[{label:"Left",value:"Primary",mask:1},{label:"Middle",value:"Auxiliary",mask:4},{label:"Right",value:"Secondary",mask:2},{label:"Left + Right",value:"Primary_and_Secondary",mask:3},{label:"Left + Middle",value:"Primary_and_Auxiliary",mask:5},{label:"Right + Middle",value:"Secondary_and_Auxiliary",mask:6},{label:"Left + Right + Middle",value:"Primary_and_Secondary_and_Auxiliary",mask:7},{label:"Fourth Button",value:"Fourth_Button",mask:8},{label:"Fifth Button",value:"Fifth_Button",mask:16},{label:"Mouse Wheel",value:"Wheel",mask:524288},{label:"Mouse Wheel + Left",value:"Wheel_Primary",mask:524289}];function FSe({container_id:t,imageStacks:e,autoCacheStack:r,annotationJson:n,viewerState:i,initialLoggerConfig:o}){var hn,Z,J,ye,Be,Ze,Ct,mt,lt,$,K,R,U,X,he,xe,be,Le,Fe,He,ft,It,Jt,Wt,Mn,bn,ar,ai,gi,el,pa,Zf,Au,xg,Cg,z8,$8,j8,H8,K8,q8,X8,Y8,J8,Z8;const a=it.useRef(null),s=it.useRef(null),c=it.useRef(!1),l="dv3d_mouseToolBindings",f="dv3d_ctrlMouseToolBindings",u="dv3d_windowLevelMouseSensitivity",d=(o==null?void 0:o.minLevel)??((o==null?void 0:o.debug)!==void 0?o.debug?"debug":"warn":void 0)??C5().minLevel,h=jp((o==null?void 0:o.format)??C5().format),[g,p]=it.useState(d),[v,y]=it.useState(h),[m,w]=it.useState(!0),[x,C]=it.useState(()=>l7()),[S,_]=it.useState(!1),[T,E]=it.useState(!1),[b,D]=it.useState(320),I=`dv3d_stackPanelWidth_${t||"default"}`,P=it.useRef({resizing:!1,startX:0,startWidth:320}),M=240,L=720,V=220,W=40,A=14,k=it.useRef(null),[F,H]=it.useState(null),[Q,oe]=it.useState(null),[ve,fe]=it.useState(!1),[Se,Ae]=it.useState(!1),[Ue,Pe]=it.useState(!1),[G,O]=it.useState(null),[j,z]=it.useState(!0),[q,ee]=it.useState(null),[ie,Oe]=it.useState("center"),[ke,Xe]=it.useState(null),Qe=it.useRef(0),Y=9,ce="renderingEngine_"+t,De="TOOL_GROUP_"+t,ae=it.useRef(null),_e=it.useRef(!1),[tt,le]=it.useState(!0),[Ot,Vt]=it.useState(!1),[_t,Ne]=it.useState([]),[je,ht]=it.useState(0),[wt,Dt]=it.useState(null),[an,Bt]=it.useState(!1),[rn,sn]=it.useState(null),[Yt,or]=it.useState(()=>Array(Y).fill(null).map(()=>[])),en=B=>{typeof B=="function"?or(ue=>{const Te=B(ue);return kt.debug("setViewportImageIds (fn):",Te),Te}):(kt.debug("setViewportImageIds:",B),or(B))},[En,_r]=it.useState(()=>Array(Y).fill(0)),[dr,Ke]=it.useState(()=>Array(Y).fill(null).map(()=>[])),[Et,qt]=it.useState(()=>Array(Y).fill(0)),[Nn,Ai]=it.useState(()=>Array(Y).fill(!1)),[cn,Jn]=it.useState(()=>Array(Y).fill(12)),[Sn,_n]=it.useState(()=>Array(Y).fill(!1)),oi=it.useRef({}),Ni=it.useRef({}),[no,Ya]=it.useState({}),ro=it.useRef({}),io=it.useRef({}),bi=it.useCallback((B,ue)=>{Ya(Te=>{const Ce=Te[B];if(Ce&&Ce!==ue&&Ce.startsWith("blob:"))try{URL.revokeObjectURL(Ce)}catch{}const me={...Te,[B]:ue};return ro.current=me,me})},[]);it.useEffect(()=>{ro.current=no},[no]),it.useEffect(()=>()=>{Object.values(ro.current).forEach(B=>{if(typeof B=="string"&&B.startsWith("blob:"))try{URL.revokeObjectURL(B)}catch{}})},[]),it.useEffect(()=>{try{const B=localStorage.getItem(I);if(B){const ue=Number(B);Number.isNaN(ue)||D(Math.max(M,Math.min(L,Math.round(ue))))}}catch{}},[I]),it.useEffect(()=>{try{localStorage.setItem(I,String(Math.round(b)))}catch{}},[I,b]);function Tr(B){if(!B)return null;try{if(B.tagName&&B.tagName.toLowerCase()==="canvas")return B}catch{}try{const ue=B.querySelector&&B.querySelector("canvas");if(ue)return ue}catch{}try{const ue=B.children||[];for(let Te=0;TeMath.min(Ft,Math.max(Ut,bt)),nt=()=>{ue.style.transform=`translate(${se}px, ${ge}px) scale(${we})`};let dt=!0,et=!0;const gt=bt=>{if(!et)return;bt.preventDefault();const Ut=ue.getBoundingClientRect(),Ft=bt.clientX-Ut.left,qn=bt.clientY-Ut.top,yr=-bt.deltaY,Zr=1+(yr>0?.1:-.1)*Math.min(4,Math.abs(yr)/100),Dr=Me(we*Zr,.1,10);se=(se-Ft)*(Dr/we)+Ft,ge=(ge-qn)*(Dr/we)+qn,we=Dr,nt()},ut=bt=>{bt.button===0&&dt&&(pe=!0,de=bt.clientX,Ve=bt.clientY,ue.style.cursor="grabbing",bt.preventDefault())},qe=bt=>{if(!pe)return;const Ut=bt.clientX-de,Ft=bt.clientY-Ve;se+=Ut,ge+=Ft,de=bt.clientX,Ve=bt.clientY,nt()},Tt=bt=>{pe&&(pe=!1,ue.style.cursor="grab")},Lt=bt=>{we=1,se=0,ge=0,nt()};let st=0;const Rt=(bt,Ut)=>Math.hypot(Ut.clientX-bt.clientX,Ut.clientY-bt.clientY),Nt=bt=>{bt.touches.length===1?dt&&(pe=!0,de=bt.touches[0].clientX,Ve=bt.touches[0].clientY):bt.touches.length===2&&(st=Rt(bt.touches[0],bt.touches[1]))},Mt=bt=>{if(bt.touches.length===1&&pe){const Ut=bt.touches[0].clientX-de,Ft=bt.touches[0].clientY-Ve;se+=Ut,ge+=Ft,de=bt.touches[0].clientX,Ve=bt.touches[0].clientY,nt()}else if(bt.touches.length===2&&et){const Ut=Rt(bt.touches[0],bt.touches[1]);if(st>0){const Ft=Ut/st,qn=ue.getBoundingClientRect(),yr=(bt.touches[0].clientX+bt.touches[1].clientX)/2-qn.left,Zr=(bt.touches[0].clientY+bt.touches[1].clientY)/2-qn.top,Dr=Me(we*Ft,.1,10);se=(se-yr)*(Dr/we)+yr,ge=(ge-Zr)*(Dr/we)+Zr,we=Dr,nt()}st=Ut}bt.preventDefault()},Gt=bt=>{bt.touches.length===0&&(pe=!1,st=0)};return B.addEventListener("wheel",gt,{passive:!1}),B.addEventListener("mousedown",ut),window.addEventListener("mousemove",qe),window.addEventListener("mouseup",Tt),ue.addEventListener("dblclick",Lt),B.addEventListener("touchstart",Nt,{passive:!1}),B.addEventListener("touchmove",Mt,{passive:!1}),B.addEventListener("touchend",Gt),{cleanup:()=>{B.removeEventListener("wheel",gt),B.removeEventListener("mousedown",ut),window.removeEventListener("mousemove",qe),window.removeEventListener("mouseup",Tt),ue.removeEventListener("dblclick",Lt),B.removeEventListener("touchstart",Nt),B.removeEventListener("touchmove",Mt),B.removeEventListener("touchend",Gt),ue.style.transform="",ue.style.cursor="",ue.style.willChange=""},setAllowPan:bt=>{dt=bt},setAllowZoom:bt=>{et=bt}}}const[fi,Ja]=it.useState(!1),[ji,Er]=it.useState(null),[Po,ki]=it.useState(!1),[Zs,Ma]=it.useState(null);it.useEffect(()=>{const B=Te=>{try{const Ce=Te&&Te.message?String(Te.message):"";(Ce.includes("releaseGraphicsResources")||Ce.includes("openGLTexture")||Ce.includes("getDefaultActor")||Ce.includes("setColormapGPU")||Ce.includes(`can't access property "actor"`)||Ce.toLowerCase().includes("webgl")||Ce.toLowerCase().includes("colormap"))&&(kt.error("Detected graphics/rendering error:",Te),Ma(Ce||null),ki(!0))}catch{}},ue=Te=>{try{const Ce=Te&&Te.reason||"",me=typeof Ce=="string"?Ce:Ce&&Ce.message?Ce.message:String(Ce);(me.includes("releaseGraphicsResources")||me.includes("openGLTexture")||me.includes("getDefaultActor")||me.includes("setColormapGPU")||me.includes(`can't access property "actor"`)||me.toLowerCase().includes("webgl")||me.toLowerCase().includes("colormap"))&&(kt.error("Detected graphics/rendering rejection:",Te),Ma(me||null),ki(!0))}catch{}};return window.addEventListener("error",B),window.addEventListener("unhandledrejection",ue),()=>{window.removeEventListener("error",B),window.removeEventListener("unhandledrejection",ue)}},[]),it.useEffect(()=>{let B=!1;if(n||i){Er(n?"annotations":"viewerState");const ue=setTimeout(()=>{if(B)return;const Te=t||"default";if(n)try{const Ce=window[`importAnnotations_${Te}`]||window.importAnnotations;typeof Ce=="function"&&Ce(n)}catch(Ce){kt.error("Failed to import annotations from prop:",Ce)}if(i)try{const Ce=window[`importViewerState_${Te}`]||window.importViewerState;typeof Ce=="function"&&Ce(i)}catch(Ce){kt.error("Failed to import viewer state from prop:",Ce)}Er(null)},2e3);return()=>{B=!0,clearTimeout(ue),Er(null)}}},[n,i,t]),it.useEffect(()=>{let B=!0;return e().then(async ue=>{var me;if(!B)return;const Te=Array.isArray(ue)?ue:[],Ce=[];for(const we of Te){const se=Array.isArray(we),ge=se?we:Array.isArray(we.imageIds)?we.imageIds:Array.isArray(we.i)?we.i:[],pe=se?{}:{studyId:we.studyId,name:we.name,caseId:we.caseId,studyInstanceUID:we.studyInstanceUID};if(!se&&Array.isArray(we.series)){const Ve=we.series.map((Me,nt)=>{const dt=Array.isArray(Me==null?void 0:Me.imageIds)?Me.imageIds:Array.isArray(Me==null?void 0:Me.i)?Me.i:[],et=So(dt.map(va)),ut=(typeof(Me==null?void 0:Me.label)=="string"?Me.label:typeof(Me==null?void 0:Me.name)=="string"?Me.name:"").trim()||`Series ${nt+1}`;return{key:String((Me==null?void 0:Me.key)||(Me==null?void 0:Me.seriesInstanceUID)||(Me==null?void 0:Me.seriesId)||`SERIES_${nt}`),label:ut,imageIds:et,seriesInstanceUID:Me==null?void 0:Me.seriesInstanceUID,bValue:Number.isFinite(Number(Me==null?void 0:Me.bValue))?Number(Me.bValue):null,groupValues:Me==null?void 0:Me.groupValues}}).filter(Me=>Me.imageIds.length>0);if(Ve.length>0){Ce.push({imageIds:So(Ve.flatMap(Me=>Me.imageIds)),seriesGroups:Ve,groupingSource:"declared",...pe});continue}}const de=So(ge.map(va));de.length>0&&Ce.push({imageIds:de,seriesGroups:[],groupingSource:"derived",...pe})}if(Ne(Ce),Ce[0]){const we=Ce[0];let se=we.seriesGroups||[],ge=we.imageIds;se.length===0&&(r?(kt.debug("[init] autoCacheStack true: expanding multiframe and fetching metadata"),ge=await Lo(we.imageIds),await Zn(ge,{force:!0}),se=await Ao(ge),Ce[0]={...we,imageIds:ge,seriesGroups:se,groupingSource:"derived"},Ne([...Ce])):kt.debug("[init] autoCacheStack false: skipping all probes/expansion, relying on server grouping"));const pe=((me=se[0])==null?void 0:me.imageIds)||ge;r?await Zn(pe,{force:!0}):kt.debug("[init] autoCacheStack false: not fetching metadata for firstSeries"),en(Array(Y).fill(null).map((de,Ve)=>Ve===0?pe||[]:[])),Ke(Array(Y).fill(null).map(()=>se)),qt(Array(Y).fill(0))}else en(Array(Y).fill(null).map(()=>[])),Ke(Array(Y).fill(null).map(()=>[])),qt(Array(Y).fill(0))}).catch(ue=>{kt.error("Failed to load imageStacks:",ue),Ne([]),en(Array(Y).fill(null).map(()=>[]))}),()=>{B=!1}},[]);const Vi=async(B,ue)=>{var pe,de,Ve,Me,nt;const Te=_t[ue];if(!Te)return;const Ce=Te.groupingSource==="declared"&&(Te.seriesGroups||[]).length>0;if(!r&&Ce&&(Te.imageIds||[]).length>1){kt.debug("[handleLoadStack] autoCacheStack false & declared groups: skipping all probes/expansion, using server grouping only");const dt=So((Te.imageIds||[]).map(va)),et=Te.seriesGroups||[];Ne(ut=>{const qe=[...ut];return qe[ue]?(qe[ue]={...qe[ue],seriesGroups:et,imageIds:dt,groupingSource:"declared"},qe):ut});const gt=((pe=et[0])==null?void 0:pe.imageIds)||dt;Er("displayset");try{ao(ut=>{const qe=[...ut];return qe[B]="stack",qe}),en(ut=>{const qe=[...ut];return qe[B]=gt,qe}),_r(ut=>{const qe=[...ut];return qe[B]=ue,qe}),Ke(ut=>{const qe=[...ut];return qe[B]=et||[],qe}),qt(ut=>{const qe=[...ut];return qe[B]=0,qe}),kt.debug("[handleLoadStack] autoCacheStack false: not fetching metadata for primarySeries")}finally{Er(null)}return}const we=!(Ce&&(Te.imageIds||[]).length>1)?await Lo(Te.imageIds||[]):So((Te.imageIds||[]).map(va));kt.debug("[handleLoadStack] Loading stack:",we.length,"ids. First:",(de=we[0])==null?void 0:de.slice(0,80)),await Zn(we,{force:!!r});const se=Ce?Te.seriesGroups||[]:await Ao(we);kt.debug("[handleLoadStack] Derived series groups:",se.length,"groups. First group has",(Ve=se[0])==null?void 0:Ve.imageIds.length,"images"),Ne(dt=>{const et=[...dt];return et[ue]?(et[ue]={...et[ue],seriesGroups:se,imageIds:we,groupingSource:Ce?"declared":"derived"},et):dt});const ge=((Me=se[0])==null?void 0:Me.imageIds)||we;kt.debug("[handleLoadStack] Setting viewport to primarySeries with",ge.length,"ids. First:",(nt=ge[0])==null?void 0:nt.slice(0,80)),Er("displayset");try{ao(dt=>{const et=[...dt];return et[B]="stack",et}),en(dt=>{const et=[...dt];return et[B]=ge,et}),_r(dt=>{const et=[...dt];return et[B]=ue,et}),Ke(dt=>{const et=[...dt];return et[B]=se||[],et}),qt(dt=>{const et=[...dt];return et[B]=0,et}),await Zn(ge)}finally{Er(null)}},[Za,Ro]=it.useState(!1),[zo,Qa]=it.useState(!0),[wo,Qs]=it.useState(!1),[Pa,$o]=it.useState(!1),ec=()=>{kt.debug("Sorting viewport imageIds by slice location"),en(B=>{const ue=B.map((Te,Ce)=>{if(!Te||Te.length===0)return Te;const se=[...Te.map(ge=>{const pe=xt("imagePlaneModule",ge);let de=null;return pe&&(pe.sliceLocation!==void 0?de=Number(pe.sliceLocation):pe.imagePositionPatient&&Array.isArray(pe.imagePositionPatient)&&pe.imagePositionPatient.length===3&&(de=Number(pe.imagePositionPatient[2]))),{imageId:ge,sortKey:de}})].sort((ge,pe)=>ge.sortKey!==null&&pe.sortKey!==null?ge.sortKey-pe.sortKey:ge.imageId.localeCompare(pe.imageId)).map(ge=>ge.imageId);return JSON.stringify(se)===JSON.stringify(Te)?Te:se});return Ja(!0),ue})},qr=it.useCallback(async(B,ue,Te=0)=>{if(!ue||no[B]||io.current[B])return;if(Mo(ue)){try{const se=new Image;se.crossOrigin="anonymous";const ge=ue.replace(/^external:/,"");se.src=ge,await new Promise((Me,nt)=>{se.onload=()=>Me(!0),se.onerror=dt=>nt(dt)});const pe=document.createElement("canvas"),de=160;pe.width=de,pe.height=de;const Ve=pe.getContext("2d");if(Ve){const Me=Math.min(de/se.width,de/se.height),nt=se.width*Me,dt=se.height*Me,et=(de-nt)/2,gt=(de-dt)/2;Ve.fillStyle="#000",Ve.fillRect(0,0,de,de),Ve.drawImage(se,et,gt,nt,dt),bi(B,pe.toDataURL("image/png"))}else bi(B,"BROKEN")}catch{bi(B,"BROKEN")}return}const Ce=ae.current;if(!Ce)return;io.current[B]=!0;const me=`THUMB_${t||"main"}_${B}`,we=document.createElement("div");we.style.width="160px",we.style.height="160px",we.style.position="absolute",we.style.left="-9999px",we.style.top="0",document.body.appendChild(we);try{Ce.enableElement({viewportId:me,type:Lr.STACK,element:we});const se=Ce.getViewport(me);if(!se)return;try{se.setStack([ue])}catch{}await new Promise(pe=>{let de=!1;const Ve=setTimeout(()=>{de||(de=!0,pe(!1))},2e3),Me=()=>{de||(de=!0,clearTimeout(Ve),pe(!0))};try{if(se&&se.element&&se.element.addEventListener(Xg,Me,{once:!0}),typeof se.render=="function")try{const nt=se.render();nt&&typeof nt.then=="function"&&nt.catch(()=>{})}catch{}}catch{clearTimeout(Ve),pe(!1)}});let ge=Tr(we)||(se&&se.element?Tr(se.element):null);if(ge||(await new Promise(pe=>setTimeout(pe,150)),ge=Tr(we)||(se&&se.element?Tr(se.element):null)),ge){if(!VSe(ge)&&Te{qr(B,ue,Te+1)},de);return}try{if(typeof ge.toBlob=="function"){const de=await new Promise(Ve=>{ge.toBlob(Me=>{if(!Me){Ve(null);return}Ve(URL.createObjectURL(Me))},"image/png")});de?bi(B,de):bi(B,ge.toDataURL("image/png"))}else bi(B,ge.toDataURL("image/png"))}catch{bi(B,"BROKEN")}}else bi(B,"BROKEN")}catch{try{bi(B,"BROKEN")}catch{}}finally{try{Ce.disableElement(me)}catch{}we&&we.parentNode&&we.parentNode.removeChild(we)}},[t,no,bi]);it.useEffect(()=>{!T||!_t||_t.length===0||!ae.current||_t.slice(0,12).forEach((ue,Te)=>{const Ce=Array.isArray(ue.imageIds)?ue.imageIds:[],me=Math.floor(Ce.length/2),we=Ce[me]||Ce[0]||null;!no[Te]&&!io.current[Te]&&qr(Te,we)})},[_t,qr,T,no]);const Zn=async(B,ue)=>{kt.debug("Setting loaded imageIds:",B),kt.debug("autoCacheStack:",r);const Te=[];if(!!(r||ue!=null&&ue.force)){const me=new Set;for(const we of B)if(we.startsWith("wadouri:"))try{const se=il(we).replace(/[?&]frame=\d+/gi,"");se&&me.add(se)}catch(se){kt.warn(`Failed to cache metadata for ${we}:`,se)}for(const we of me)if($u.wadouri.dataSetCacheManager){const se=$u.wadouri.dataSetCacheManager.load(we);se&&typeof se.then=="function"&&Te.push(se)}else kt.warn("MetaDataManager not found. Unable to cache metadata.");await Promise.all(Te),Aa&&(kt.debug("Sorting viewport imageIds by slice location"),ec())}},es=it.useCallback(async B=>{var ge;if(!B.startsWith("wadouri:")||d_(B))return 1;const ue=va(B),Te=il(ue),Ce=`wadouri:${Te}`,me=oi.current[Ce];if(me!==void 0)return me;const we=pe=>{if(!pe||typeof pe.intString!="function")return 1;const de=Number(pe.intString("x00280008"));return Number.isFinite(de)&&de>1?Math.floor(de):1},se=pe=>{try{const de=Vr.parseDicom(pe);return we(de)}catch(de){if(de!=null&&de.dataSet){const Ve=we(de.dataSet);if(Ve>1)return Ve}return 1}};try{const pe=xt("multiframeModule",ue),de=Number(pe==null?void 0:pe.numberOfFrames);if(Number.isFinite(de)&&de>1)return oi.current[Ce]=Math.floor(de),Math.floor(de)}catch{}try{const pe=(ge=$u==null?void 0:$u.wadouri)==null?void 0:ge.dataSetCacheManager;if(pe!=null&&pe.get){const de=pe.get(Te);if(de){const Ve=we(de);return oi.current[Ce]=Ve,Ve}}}catch{}try{const pe=await fetch(Te,{headers:{Range:"bytes=0-262143"}});if(pe.ok||pe.status===206){const de=await pe.arrayBuffer(),Ve=se(new Uint8Array(de));return oi.current[Ce]=Ve,Ve}}catch{}return oi.current[Ce]=1,1},[]),ts=it.useCallback(async B=>{var Ce;const ue=[],Te=[];for(const me of B||[]){const we=va(me);if(!we.startsWith("wadouri:")||d_(we)){ue.push(we);continue}const se=await es(we);if(se<=1)ue.push(we);else{const ge=Array.from({length:se},(pe,de)=>f7(we,de+1));Te.push({baseImageId:we,frameIds:ge}),kt.debug("[splitMultiframeToStacks]",((Ce=il(we).split("/").pop())==null?void 0:Ce.split("?")[0])??we,"->",se,"frames (separate stack)")}}return{singleFrameIds:So(ue),multiframeGroups:Te}},[es]),Lo=it.useCallback(async B=>{if(kt.debug("[expandMultiframeImageIds] Input:",B.length,"imageIds"),!r){const me=So((B||[]).map(va));return kt.debug("[expandMultiframeImageIds] autoCacheStack false: skipping multiframe probe/expansion"),kt.debug("[expandMultiframeImageIds] Output:",me.length,"total imageIds"),me}const{singleFrameIds:ue,multiframeGroups:Te}=await ts(B),Ce=So([...ue,...Te.flatMap(me=>me.frameIds)]);return kt.debug("[expandMultiframeImageIds] Output:",Ce.length,"total imageIds"),Ce},[r,ts]),jo=it.useCallback(async B=>{var we;if(!r)return[];if(!B.startsWith("wadouri:"))return[];const ue=va(B),Te=il(ue).replace(/[?&]frame=\d+/i,""),Ce=Ni.current[Te];if(Ce)return Ce;try{const se=(we=$u==null?void 0:$u.wadouri)==null?void 0:we.dataSetCacheManager;if(se!=null&&se.get){const ge=se.get(Te),pe=AC(ge);if(pe.length>0)return Ni.current[Te]=pe,pe}}catch{}const me=se=>{try{return AC(Vr.parseDicom(se))}catch(ge){if(ge!=null&&ge.dataSet){const pe=AC(ge.dataSet);if(pe.length>0)return pe}return[]}};try{const se=await fetch(Te,{headers:{Range:"bytes=0-65535"}});if(se.ok||se.status===206){const ge=await se.arrayBuffer(),pe=me(new Uint8Array(ge));if(pe.length>0||se.status===200)return Ni.current[Te]=pe,pe}}catch{}try{const ge=await(await fetch(Te)).arrayBuffer(),pe=me(new Uint8Array(ge));return Ni.current[Te]=pe,pe}catch{return Ni.current[Te]=[],[]}},[r]),Ao=it.useCallback(async B=>{if(!Array.isArray(B)||B.length===0)return[];if(!r)return[{key:"SERIES_0",label:"Series 1",imageIds:So(B),bValue:null,groupValues:{}}];const ue=st=>!Array.isArray(st)||st.length===0?"":st.map(Rt=>{const Nt=Number(Rt);return Number.isFinite(Nt)?Nt.toFixed(3):"0.000"}).join(","),Te=st=>{if(Array.isArray(st)&&st.length>0){const Rt=st.map(Nt=>Number(Nt)).filter(Nt=>Number.isFinite(Nt));if(Rt.length>=3)return ue(Rt.slice(0,3))}if(typeof st=="string"){const Rt=_5(st);if(Rt.length>=3)return ue(Rt.slice(0,3));const Nt=st.trim();if(Nt)return Nt}if(st&&typeof st=="object"){const Rt=[st.x,st.y,st.z].map(Nt=>Number(Nt)).filter(Nt=>Number.isFinite(Nt));if(Rt.length>=3)return ue(Rt.slice(0,3))}return""},Ce=st=>{if(st==null)return"";const Rt=String(st).trim();if(!Rt)return"";const Nt=Number(Rt);return Number.isFinite(Nt)?Nt.toFixed(1):Rt},me=st=>{const Rt=xt("imagePlaneModule",st)||{},Nt=xt("generalImageModule",st)||{},Mt=Array.isArray(Rt==null?void 0:Rt.rowCosines)?Rt.rowCosines:null,Gt=Array.isArray(Rt==null?void 0:Rt.columnCosines)?Rt.columnCosines:null,yn=Mt&&Gt?`${ue(Mt)}|${ue(Gt)}`:"";if(yn)return yn;const bt=Nt==null?void 0:Nt.imageOrientationPatient;if(Array.isArray(bt)&&bt.length>=6)return`${ue(bt.slice(0,3))}|${ue(bt.slice(3,6))}`;if(typeof bt=="string"){const Ut=_5(bt);if(Ut.length>=6)return`${ue(Ut.slice(0,3))}|${ue(Ut.slice(3,6))}`}return"ORI_UNKNOWN"},we=new Map;B.forEach(st=>{const Rt=il(va(st)).replace(/[?&]frame=\d+/i,""),Nt=we.get(Rt)||[];Nt.push(st),we.set(Rt,Nt)}),we.forEach((st,Rt)=>{st.sort((Nt,Mt)=>{const Gt=d7(Nt)||1,yn=d7(Mt)||1;return Gt-yn}),we.set(Rt,st)});const se=new Map;await Promise.all(Array.from(we.keys()).map(async st=>{const Rt=`wadouri:${st}`,Nt=await jo(Rt);se.set(st,Nt)}));const ge=st=>{const Rt=xt("imagePlaneModule",st)||{},Nt=Array.isArray(Rt==null?void 0:Rt.imagePositionPatient)?Rt.imagePositionPatient:null;if(Nt&&Nt.length>=3){const Gt=Nt.slice(0,3).map(yn=>Number(yn));if(Gt.every(yn=>Number.isFinite(yn)))return`IPP:${Gt.map(yn=>yn.toFixed(3)).join(",")}`}const Mt=Number(Rt==null?void 0:Rt.sliceLocation);return Number.isFinite(Mt)?`SL:${Mt.toFixed(3)}`:""},pe=B.map(st=>{const Rt=xt("generalSeriesModule",st)||{},Nt=xt("generalImageModule",st)||{},Mt=xt("mrImageModule",st)||{},Gt=(Rt.seriesInstanceUID||"").trim()||void 0,yn=(Rt.seriesDescription||"").trim()||void 0,bt=Number(Rt.seriesNumber),Ut=Number(Nt.instanceNumber),Ft=me(st),qn=ge(st);let yr=Number(Mt.diffusionBValue??Mt.diffusionbValue??Mt.bValue),Zr=Number.isFinite(yr)?yr:null;if(Zr===null){const t6=il(va(st)).replace(/[?&]frame=\d+/i,""),Ns=se.get(t6)||[];if(Ns.length>0){const n6=we.get(t6)||[st],Qw=Math.max(0,n6.indexOf(st)),F1=Math.max(1,n6.length);if(Ns.length===1)Zr=Ns[0];else if(Ns.length===F1)Zr=Ns[Math.min(Ns.length-1,Qw)];else if(Ns.length===2&&F1%2===0)Zr=Qwx[st.id]).map(st=>st.id).filter(st=>{const Rt=pe.map(Gt=>Gt.ruleValues[st]).filter(Gt=>!!Gt),Nt=new Set(Rt),Mt=Rt.length/pe.length;return Nt.size>1&&Nt.size=.7}):[],Me=pe.filter(st=>!!st.seriesInstanceUID).lengthst.seriesInstanceUID).filter(st=>!!st)).size,dt=!Me,gt=pe.filter(st=>st.orientationKey!=="ORI_UNKNOWN").lengthst.orientationKey).filter(st=>st&&st!=="ORI_UNKNOWN")).size,qe=!gt;(nt>1&&!dt||ut>1&&!qe)&&kt.debug("[deriveSeriesGroupsFromImageIds] partial metadata detected; suppressing base-key grouping",{candidates:pe.length,distinctSeriesUidCount:nt,distinctOrientationCount:ut,hasMissingSeriesUid:Me,hasUnknownOrientation:gt});const Tt=new Map;if(pe.forEach(st=>{const Rt=[dt?st.seriesInstanceUID||"NO_UID":"SERIES_ANY",qe?st.orientationKey:"ORI_ANY"].join("|"),Nt=de.map(Gt=>{const yn=st.ruleValues[Gt];return yn?`${Gt}:${yn}`:""}).filter(Boolean).join("|"),Mt=Nt?`${Rt}|${Nt}`:Rt;if(!Tt.has(Mt)){const Gt={};de.forEach(yn=>{const bt=st.ruleValues[yn];bt&&(Gt[yn]=bt)}),Tt.set(Mt,{imageIds:[],seriesInstanceUID:st.seriesInstanceUID,seriesDescription:st.seriesDescription,seriesNumber:st.seriesNumber,bValue:st.bValue,groupValues:Gt})}Tt.get(Mt).imageIds.push(st.id)}),Tt.size<=1){if(de.length===0&&pe.length>=4){if(pe.filter(Gt=>!!Gt.sliceKey).length/pe.length<.9)return[{key:"SERIES_0",label:"Series 1",imageIds:So(B)}];const Nt=new Map;pe.forEach(Gt=>{Gt.sliceKey&&Nt.set(Gt.sliceKey,(Nt.get(Gt.sliceKey)||0)+1)});const Mt=Nt.size;if(Mt>=2&&Mt=2&&yn<=8&&Array.from(Nt.values()).every(Ft=>Ft===yn)){const Ft=Array.from({length:yn},()=>[]),qn=new Map;[...pe].map((Dr,ls)=>({c:Dr,idx:ls})).sort((Dr,ls)=>{const Qf=Dr.c.instanceNumber,V1=ls.c.instanceNumber;return Number.isFinite(Qf)&&Number.isFinite(V1)?Qf-V1:Dr.idx-ls.idx}).forEach(({c:Dr})=>{if(!Dr.sliceKey)return;const ls=qn.get(Dr.sliceKey)||0,Qf=Math.min(yn-1,ls);Ft[Qf].push(Dr.id),qn.set(Dr.sliceKey,ls+1)});const Zr=Ft.filter(Dr=>Dr.length>0);if(Zr.length>1)return Zr.map((Dr,ls)=>({key:`SERIES_FALLBACK_${ls}`,label:`Series ${ls+1}`,imageIds:So(Dr)}))}}}return[{key:"SERIES_0",label:"Series 1",imageIds:So(B)}]}return Array.from(Tt.entries()).map(([st,Rt],Nt)=>{const Mt=[];Rt.seriesDescription&&Mt.push(Rt.seriesDescription),Rt.seriesNumber!==void 0&&Mt.push(`#${Rt.seriesNumber}`),Rt.groupValues&&mp.forEach(yn=>{var Ut;const bt=(Ut=Rt.groupValues)==null?void 0:Ut[yn.id];bt&&(yn.id==="dwiBValue"?Mt.push(`b=${bt}`):yn.id==="dwiDirection"?Mt.push(`dir=${bt}`):yn.id==="temporalPosition"?Mt.push(`tp=${bt}`):yn.id==="triggerTime"?Mt.push(`tr=${bt}`):yn.id==="contentTime"?Mt.push(`t=${bt}`):yn.id==="echoTime"?Mt.push(`TE=${bt}`):yn.id==="echoNumber"&&Mt.push(`echo=${bt}`))}),Mt.length===0&&Rt.bValue!==null&&Rt.bValue!==void 0&&Mt.push(`b=${Math.round(Rt.bValue)}`);const Gt=Mt.length>0?Mt.join(" • "):`Series ${Nt+1}`;return{key:st,label:Gt,imageIds:So(Rt.imageIds),seriesInstanceUID:Rt.seriesInstanceUID,bValue:Rt.bValue,groupValues:Rt.groupValues}})},[m,r,jo,x]),[tn,Ra]=it.useState({rows:1,cols:1}),[La,Fi]=it.useState(!1),Xr=it.useRef([]),oo=it.useRef({}),di=it.useRef({}),[Aa,la]=it.useState(!1),[Ho,Yr]=it.useState(!0),ns=it.useCallback(B=>{const ue=B.currentTarget.getBoundingClientRect(),Te=B.clientX-ue.left,Ce=B.clientY-ue.top,me=ue.width,we=ue.height,se=Math.min(me,we)*.24,ge=[{zone:"left",distance:Te},{zone:"right",distance:me-Te},{zone:"top",distance:Ce},{zone:"bottom",distance:we-Ce}];return ge.sort((pe,de)=>pe.distance-de.distance),ge[0].distance<=se?ge[0].zone:"center"},[]),Hi=it.useCallback((B,ue,Te)=>{const Ce=ue-B.left,me=Te-B.top,we=B.width,se=B.height,ge=Math.min(we,se)*.24,pe=[{zone:"left",distance:Ce},{zone:"right",distance:we-Ce},{zone:"top",distance:me},{zone:"bottom",distance:se-me}];return pe.sort((de,Ve)=>de.distance-Ve.distance),pe[0].distance<=ge?pe[0].zone:"center"},[]),Nr=it.useCallback(B=>B==="left"||B==="right"?tn.cols<3?B:"center":(B==="top"||B==="bottom")&&tn.rows<3?B:"center",[tn]),Os=[];for(let B=1;B<=3;B++)for(let ue=1;ue<=3;ue++)Os.push({rows:B,cols:ue});const[fn,Ki]=it.useState(()=>Array(tn.rows*tn.cols).fill({index:0,total:0,windowCenter:"",windowWidth:"",slicePosition:"",modality:"",orientation:"",resolution:"",spacing:"",focalPoint:""})),[rs,Wc]=it.useState({}),tc=it.useRef(Array(Y).fill("")),xo=it.useRef(Array(Y).fill(null)),Cr=it.useRef(Array(Y).fill(null)),ua=it.useRef(Array(Y).fill(null)),hi=it.useRef(Array(Y).fill(0)),[dn,ao]=it.useState(()=>Array(Y).fill("stack")),[Di,Ms]=it.useState(()=>Array(tn.rows*tn.cols).fill(!1)),[mr,so]=it.useState({Primary:bf.toolName,Auxiliary:Ec.toolName,Secondary:gu.toolName,Primary_and_Secondary:gl.toolName,Fourth_Button:Bh.toolName,Wheel:bf.toolName}),[No,fa]=it.useState({Primary:Gf.toolName,Auxiliary:Iu.toolName,Secondary:$h.toolName}),[Jr,nc]=it.useState(1),[Ul,zc]=it.useState(!1);it.useEffect(()=>{const B=Te=>{Te.ctrlKey&&zc(!0)},ue=Te=>{Te.ctrlKey||zc(!1)};return window.addEventListener("keydown",B),window.addEventListener("keyup",ue),()=>{window.removeEventListener("keydown",B),window.removeEventListener("keyup",ue)}},[]),it.useEffect(()=>{const B=window.matchMedia("(max-width: 768px), (pointer: coarse)"),ue=()=>{const Te=B.matches;Ae(Te),Te||(Pe(!1),O(null))};return ue(),typeof B.addEventListener=="function"?(B.addEventListener("change",ue),()=>B.removeEventListener("change",ue)):(B.addListener(ue),()=>B.removeListener(ue))},[]);const $c=it.useCallback(B=>{if(!Se)return;ht(B),O(B),Pe(!0),z(!0),E(!1);const ue=a.current;if(ue&&document.fullscreenElement!==ue){const Te=ue.requestFullscreen||ue.webkitRequestFullscreen||ue.msRequestFullscreen;if(Te)try{const Ce=Te.call(ue);Ce&&typeof Ce.catch=="function"&&Ce.catch(()=>{})}catch{}}},[Se]);it.useEffect(()=>{!Se||!Ue||!j||je!==null&&O(je)},[je,Se,Ue,j]);const[is,os]=it.useState(!1),[rc,jc]=it.useState(null),ic=(B,ue)=>{_a&&_a(ue),pt(Te=>{const Ce=[...Te];return Ce[B]=ue,Ce})},Bl=(B,ue,Te)=>{const Ce=Rr.getAllAnnotations()||[];Ce.forEach(we=>{we.annotationUID===ue&&(we.isSelected=!1)}),Rr.removeAnnotation(ue),ae.current.render();const me=Te.filter(we=>we.annotationUID!==ue);pt(we=>{const se=[...we],ge=me.length>0?me[0].annotationUID:null;return se[B]=ge,Ce.forEach(pe=>{pe.isSelected=pe.annotationUID===ge}),_a(ge),ae.current.render(),se})},Gl=()=>{const B=Yt.findIndex(me=>me&&me.length>0);if(B===-1){jc("No images loaded."),os(!0);return}const ue=Yt[B][0],Te=["imagePlaneModule","generalSeriesModule","generalStudyModule","patientModule","imagePixelModule","voiLutModule","modalityLutModule","sopCommonModule","petIsotopeModule","multiframeModule","cineModule","overlayPlaneModule","generalImageModule","stackModule","voiLutModule","modalityLutModule","petSeriesModule","petImageModule","petIsotopeModule","petSeriesModule","petImageModule","petIsotopeModule","petSeriesModule","petImageModule","petIsotopeModule","petSeriesModule","petImageModule","petIsotopeModule"],Ce={};Te.forEach(me=>{const we=xt(me,ue);we!==void 0&&(Ce[me]=we)}),jc(Re.jsx("pre",{style:{maxHeight:600,overflow:"auto",fontSize:13,color:"#fff"},children:JSON.stringify(Ce,null,2)})),os(!0)};it.useEffect(()=>{try{const B=localStorage.getItem(l),ue=localStorage.getItem(f);B&&so(JSON.parse(B)),ue&&fa(JSON.parse(ue));const Te=localStorage.getItem(u);if(Te){const we=JSON.parse(Te);typeof(we==null?void 0:we.mouseSensitivity)=="number"&&nc(we.mouseSensitivity)}const Ce=localStorage.getItem(s7);if(Ce){const we=JSON.parse(Ce);typeof(we==null?void 0:we.minLevel)=="string"?p(S5(we.minLevel)):typeof(we==null?void 0:we.debug)=="boolean"&&p(we.debug?"debug":"warn"),typeof(we==null?void 0:we.format)=="string"&&y(jp(we.format))}const me=localStorage.getItem(c7);if(me){const we=JSON.parse(me);if(typeof(we==null?void 0:we.advancedGroupingEnabled)=="boolean"&&w(we.advancedGroupingEnabled),we!=null&&we.groupingRuleEnabled&&typeof we.groupingRuleEnabled=="object"){const se=l7();mp.forEach(ge=>{typeof we.groupingRuleEnabled[ge.id]=="boolean"&&(se[ge.id]=we.groupingRuleEnabled[ge.id])}),C(se)}}}catch{}},[]),it.useEffect(()=>{try{localStorage.setItem(l,JSON.stringify(mr))}catch{}},[mr]),it.useEffect(()=>{try{localStorage.setItem(f,JSON.stringify(No))}catch{}},[No]),it.useEffect(()=>{try{localStorage.setItem(u,JSON.stringify({mouseSensitivity:Jr}))}catch{}},[Jr]),it.useEffect(()=>{T8({minLevel:g,format:v});try{localStorage.setItem(s7,JSON.stringify({minLevel:g,format:v}))}catch{}},[g,v]),it.useEffect(()=>{try{localStorage.setItem(c7,JSON.stringify({advancedGroupingEnabled:m,groupingRuleEnabled:x}))}catch{}},[m,x]),it.useEffect(()=>{if(_t.length===0)return;let B=!1;return(async()=>{const Te=await Promise.all(_t.map(async Ce=>{if(Ce.groupingSource==="declared"&&(Ce.seriesGroups||[]).length>0)return Ce;const me=await Ao(Ce.imageIds);return{...Ce,seriesGroups:me,groupingSource:"derived"}}));B||(Ne(Te),Ke(Ce=>{var we;const me=[...Ce];for(let se=0;se{var we;const me=[...Ce];for(let se=0;se{var we,se,ge;const me=[...Ce];for(let pe=0;pe{B=!0}},[m,x]),it.useEffect(()=>(window.loadDicomStackFromFiles=B=>{const ue=Array.from(B);ss({target:{files:ue}})},()=>{window.loadDicomStackFromFiles=void 0}),[]),it.useEffect(()=>{const B=()=>{Bt(!1),sn(null),Dt(null)};return document.addEventListener("dragend",B),()=>document.removeEventListener("dragend",B)},[]);const[Hc,oc]=it.useState(!1),[Kc,Ps]=it.useState(!1);it.useEffect(()=>{const B=xi(De);B&&["ArrowAnnotate","NoLabelArrowAnnotate","Length","RectangleROI","EllipticalROI","PlanarFreehandROI","PlanarFreehandContourSegmentation"].forEach(ue=>{B.setToolConfiguration(ue,{color:"#00e676",selectedColor:"#ffeb3b"})})},[De]),it.useEffect(()=>{const B=Ce=>{Ce.altKey&&oc(!0),Ce.shiftKey&&Ps(!0)},ue=Ce=>{Ce.altKey||oc(!1),Ce.shiftKey||Ps(!1)},Te=()=>{oc(!1),Ps(!1)};return window.addEventListener("keydown",B),window.addEventListener("keyup",ue),window.addEventListener("blur",Te),()=>{window.removeEventListener("keydown",B),window.removeEventListener("keyup",ue),window.removeEventListener("blur",Te)}},[]),it.useEffect(()=>{const B=xi(De);if(!B)return;if(Kc||Ho&&Hc){const Te=tn.rows*tn.cols;Yt.slice(0,Te).filter((me,we)=>dn[we]==="stack"&&Array.isArray(me)&&me.length>0).forEach(me=>{Zn(me,{force:!0}).catch(we=>{kt.warn("Reference cursor metadata warm-up failed:",we)})}),B.hasTool(gs.toolName)||B.addTool(gs.toolName),B.setToolEnabled(gs.toolName),B.setToolActive(gs.toolName)}else B.hasTool(gs.toolName)&&B.setToolDisabled(gs.toolName)},[Hc,Kc,Ho,tn.rows,tn.cols,Yt,dn,Zn]);const as=it.useCallback(()=>{[xi(De)].forEach(ue=>{if(ue){md.forEach(we=>{ue.setToolPassive(we.value,{removeAllBindings:!0})}),ue.setToolDisabled(gs.toolName);const Te={};Object.entries(mr).forEach(([we,se])=>{Te[se]||(Te[se]=[]);const ge=q2.find(pe=>pe.value===we);ge?Te[se].push({mouseButton:ge.mask}):qg[we]&&Te[se].push({mouseButton:qg[we]})}),Object.entries(No).forEach(([we,se])=>{if(!se)return;Te[se]||(Te[se]=[]);const ge=q2.find(pe=>pe.value===we);ge?Te[se].push({mouseButton:ge.mask,modifierKey:o7.Ctrl}):qg[we]&&Te[se].push({mouseButton:qg[we],modifierKey:o7.Ctrl})}),Object.entries(Te).forEach(([we,se])=>{ue.setToolActive(we,{bindings:se})}),typeof ue.setToolConfiguration=="function"&&ue.setToolConfiguration(gu.toolName,{mouseSensitivity:Jr});const Ce=mr.Primary;if(Ce){const we=[...Te[Ce]||[],{numTouchPoints:1}];ue.setToolActive(Ce,{bindings:we})}const me=[...Te[Ec.toolName]||[],{numTouchPoints:2}];ue.setToolActive(Ec.toolName,{bindings:me});try{const we=mr.Primary,se=mr.Wheel,ge=mr.Auxiliary,pe=we===Ec.toolName||ge===Ec.toolName,de=we===gl.toolName||se===gl.toolName||mr.Primary_and_Secondary===gl.toolName;Xr.current.forEach(Ve=>{if(!Ve)return;const Me=Ve._externalPanZoom;Me&&(typeof Me.setAllowPan=="function"&&Me.setAllowPan(!!pe),typeof Me.setAllowZoom=="function"&&Me.setAllowZoom(!!de))})}catch{}}})},[mr,No,Jr]);it.useEffect(()=>{as()},[Jr,as]);const[ac,Rs]=it.useState(!1),[sc,Ls]=it.useState("add"),da=it.useRef(null),qc=it.useCallback(B=>{T&&(B.preventDefault(),B.stopPropagation(),P.current={resizing:!0,startX:B.clientX,startWidth:b},document.body.style.cursor="col-resize",document.body.style.userSelect="none")},[T,b]);it.useEffect(()=>{const B=Te=>{if(!P.current.resizing)return;const Ce=P.current.startX-Te.clientX,me=Math.max(M,Math.min(L,P.current.startWidth+Ce));D(me)},ue=()=>{P.current.resizing&&(P.current.resizing=!1,document.body.style.cursor="",document.body.style.userSelect="")};return window.addEventListener("mousemove",B),window.addEventListener("mouseup",ue),()=>{window.removeEventListener("mousemove",B),window.removeEventListener("mouseup",ue),document.body.style.cursor="",document.body.style.userSelect=""}},[]);const cc=ac?V-W/2:-W+A;it.useEffect(()=>{try{da.current&&(da.current.setAttribute("webkitdirectory","true"),da.current.setAttribute("directory",""),da.current.setAttribute("mozdirectory",""))}catch{}},[]);async function Xc(B,ue=""){const Te=[],Ce=B.entries?B.entries():B.values();for await(const me of Ce)try{let we,se;if(Array.isArray(me)&&me.length>=2?(se=me[0],we=me[1]):(we=me,se=we.name),!we)continue;if(we.kind==="file"){const ge=await we.getFile();try{Object.defineProperty(ge,"webkitRelativePath",{value:ue+(se||we.name),configurable:!0})}catch{}Te.push(ge)}else if(we.kind==="directory"){const ge=await Xc(we,ue+(se||we.name)+"/");Te.push(...ge)}}catch(we){kt.debug("collectFilesFromDirectoryHandle: skipping entry due to error",we)}return Te}const Yc=async()=>{var B;if(window.showDirectoryPicker)try{const ue=await window.showDirectoryPicker(),Te=await Xc(ue);Te&&Te.length>0?await ss({target:{files:Te}}):alert("No files found in selected folder.");return}catch(ue){kt.warn("showDirectoryPicker failed or cancelled",ue)}(B=da.current)==null||B.click()},As=it.useRef(null),ss=async B=>{const ue=B.target.files;if(!ue||ue.length===0)return;la(!1);const Te=Array.from(ue).sort((se,ge)=>se.name.localeCompare(ge.name)),Ce=await Promise.all(Te.map(async se=>{const ge=se.type&&se.type.startsWith("image/");let pe,de,Ve,Me,nt=1,dt=!1;if(!ge)try{const gt=await se.arrayBuffer(),ut=Vr.parseDicom(new Uint8Array(gt));pe=ut.string("x0020000d"),de=ut.string("x0020000e");const qe=ut.string("x00200013");qe!=null&&qe!==""&&(Ve=parseInt(qe,10));const Tt=ut.string("x00201041")||ut.string("x00201040");Tt!=null&&Tt!==""&&(Me=parseFloat(Tt));const Lt=ut.string("x00280008");if(Lt!=null&&Lt!==""){const st=Number(Lt);Number.isFinite(st)&&st>1&&(nt=Math.floor(st))}dt=!0}catch{dt=!1}const et=ge?`external:${URL.createObjectURL(se)}`:`wadouri:${URL.createObjectURL(se)}`;return{file:se,imageId:et,studyInstanceUID:pe,seriesInstanceUID:de,instanceNumber:Ve,sliceLocation:Me,numberOfFrames:nt,isImage:ge,parsedSuccessfully:dt}})),me=new Map;for(const se of Ce){if(!se.isImage&&!se.parsedSuccessfully){kt.debug("Skipping non-DICOM/non-image file:",se.file.name);continue}const ge=se.seriesInstanceUID||se.studyInstanceUID||(se.file.webkitRelativePath?se.file.webkitRelativePath.split("/")[0]:se.file.name);me.has(ge)||me.set(ge,{entries:[],studyInstanceUID:se.studyInstanceUID,seriesInstanceUID:se.seriesInstanceUID}),me.get(ge).entries.push(se)}const we=[];for(const[se,ge]of me.entries()){const pe=ge.entries;pe.sort((Me,nt)=>Aa&&Me.sliceLocation!==void 0&&nt.sliceLocation!==void 0?Me.sliceLocation-nt.sliceLocation:Me.instanceNumber!==void 0&&nt.instanceNumber!==void 0?Me.instanceNumber-nt.instanceNumber:(Me.file.webkitRelativePath||Me.file.name).localeCompare(nt.file.webkitRelativePath||nt.file.name));const de=pe.flatMap(Me=>{if(Me.isImage||!Number.isFinite(Me.numberOfFrames)||Me.numberOfFrames<=1)return[Me.imageId];const nt=[];for(let dt=1;dt<=Me.numberOfFrames;dt++)nt.push(f7(Me.imageId,dt));return nt}),Ve=await Ao(de);we.push({imageIds:de,studyInstanceUID:ge.studyInstanceUID,seriesInstanceUID:ge.seriesInstanceUID,seriesGroups:Ve})}if(we.length!==0)if(sc==="replace"){try{const se=ae.current;if(se)for(let ge=0;ge{var ge,pe;const se=Array(Y).fill([]);for(let de=0;de{const se=Array(Y).fill(null).map(()=>[]);for(let ge=0;ge{const ge=[...se,...we];en(pe=>{var Me,nt;const de=[...pe],Ve=we[we.length-1];return de[0]=((nt=(Me=Ve.seriesGroups)==null?void 0:Me[0])==null?void 0:nt.imageIds)||Ve.imageIds,de}),_r(pe=>{const de=[...pe];return de[0]=ge.length-1,de}),Ke(pe=>{var Ve;const de=[...pe];return de[0]=((Ve=we[we.length-1])==null?void 0:Ve.seriesGroups)||[],de}),qt(pe=>{const de=[...pe];return de[0]=0,de});for(const pe of we)Zn(pe.imageIds);return ge})},Wl=(B,ue)=>{so(Te=>({...Te,[B]:ue}))},br=it.useCallback((B,ue)=>{var et,gt;if(!ue)return;let Te=0,Ce=0,me="",we="",se="",ge="",pe="",de="",Ve="",Me="",nt,dt;if(dn[B]==="stack"){Te=typeof ue.getCurrentImageIdIndex=="function"?ue.getCurrentImageIdIndex():0;const ut=typeof ue.getImageIds=="function"?ue.getImageIds():[];Ce=ut.length;const qe=ut[Te];if(qe){if(kt.debug("[updateOverlay] Current image:",qe.slice(0,80),"frameIndex status:",nt,"totalFrames:",dt),qe.includes("&frame=")){const Nt=qe.match(/&frame=(\d+)/);if(Nt){nt=parseInt(Nt[1],10),kt.debug("[updateOverlay] Frame detected:",nt);const Mt=qe.split("&frame=")[0],Gt=xt("multiframeModule",Mt);if(Gt!=null&&Gt.numberOfFrames)dt=Gt.numberOfFrames,kt.debug("[updateOverlay] Total frames from metadata:",dt);else{const yn=ut.map(bt=>{const Ut=bt.match(/&frame=(\d+)/);return Ut?parseInt(Ut[1],10):null}).filter(bt=>bt!==null&&typeof bt=="number");yn.length>0&&(dt=Math.max(...yn),kt.debug("[updateOverlay] Total frames from imageIds:",dt))}}}else kt.debug("[updateOverlay] No frame query in imageId. imageIds.length:",ut.length);const Tt=xt("generalSeriesModule",qe),Lt=xt("imagePlaneModule",qe),st=xt("imagePixelModule",qe);ge=(Tt==null?void 0:Tt.modality)||"",st!=null&&st.rows&&(st!=null&&st.columns)&&(de=`${st.columns} x ${st.rows}`);const Rt=[Lt==null?void 0:Lt.columnPixelSpacing,Lt==null?void 0:Lt.rowPixelSpacing,Lt==null?void 0:Lt.sliceThickness].filter(Nt=>Nt!=null&&Nt!=="");Rt.length>0&&(Ve=Rt.join(" x "))}if(typeof ue.getCamera=="function"){const Tt=ue.getCamera();Tt!=null&&Tt.focalPoint&&Array.isArray(Tt.focalPoint)&&(Me=Tt.focalPoint.map(Lt=>Lt.toFixed(1)).join(", "))}if(qe&&Wc(Tt=>Tt[qe]?Tt:{...Tt,[qe]:!0}),typeof ue.getProperties=="function"){const Tt=ue.getProperties();if(Tt.voiRange){const{lower:Lt,upper:st}=Tt.voiRange;me=((st+Lt)/2).toFixed(0),we=(st-Lt).toFixed(0),xo.current[B]===null&&(xo.current[B]={lower:Lt,upper:st})}}}else if(dn[B]==="volume"){if(typeof ue.getSliceIndex=="function"&&(Te=ue.getSliceIndex()),typeof ue.getNumberOfSlices=="function"&&(Ce=ue.getNumberOfSlices()),typeof ue.getProperties=="function"){let qe;if(ue.volumeIds&&ue.volumeIds.size>0){const Tt=Array.from(ue.volumeIds)[0];qe=ue.getProperties(Tt)}else qe=ue.getProperties();if(qe&&qe.voiRange){const{lower:Tt,upper:Lt}=qe.voiRange;me=((Lt+Tt)/2).toFixed(0),we=(Lt-Tt).toFixed(0),xo.current[B]===null&&(xo.current[B]={lower:Tt,upper:Lt})}}if(typeof ue.getSlicePlaneCoordinates=="function"){const qe=ue.getSlicePlaneCoordinates();qe&&typeof qe.position=="number"&&(se=qe.position.toFixed(2)+" mm")}const ut=(et=Yt[B])==null?void 0:et[0];if(ut){const qe=xt("generalSeriesModule",ut),Tt=xt("imagePlaneModule",ut),Lt=xt("imagePixelModule",ut);ge=(qe==null?void 0:qe.modality)||"",pe=String(((gt=ue.viewportProperties)==null?void 0:gt.orientation)||"").toUpperCase(),Lt!=null&&Lt.rows&&(Lt!=null&&Lt.columns)&&(de=`${Lt.columns} x ${Lt.rows}`);const st=[Tt==null?void 0:Tt.columnPixelSpacing,Tt==null?void 0:Tt.rowPixelSpacing,Tt==null?void 0:Tt.sliceThickness].filter(Rt=>Rt!=null&&Rt!=="");st.length>0&&(Ve=st.join(" x "))}if(typeof ue.getCamera=="function"){const qe=ue.getCamera();qe!=null&&qe.focalPoint&&Array.isArray(qe.focalPoint)&&(Me=qe.focalPoint.map(Tt=>Tt.toFixed(1)).join(", "))}}Ki(ut=>{const qe=[...ut];return qe[B]={index:Te+1,total:Ce,windowCenter:me,windowWidth:we,slicePosition:se,modality:ge,orientation:pe,resolution:de,spacing:Ve,focalPoint:Me,frameIndex:nt,totalFrames:dt},qe})},[dn,Yt]);it.useEffect(()=>{for(let B=0;B{var bt;const me=So(ue.map(va));if(me.length===0)return;const we=_t.findIndex(Ut=>{const Ft=So((Ut.imageIds||[]).map(va));return Ft.length===me.length&&Ft.every((qn,yr)=>qn===me[yr])});if(we!==-1){await ha(B,we,Ce),ht(B);return}const se=await Lo(me);if(se.length===0)return;await Zn(se,{force:!!r});const ge=await Ao(se),pe=((bt=ge[0])==null?void 0:bt.imageIds)||se;let de=-1;Ne(Ut=>(de=Ut.length,[...Ut,{imageIds:se,name:Te,seriesGroups:ge,groupingSource:"derived"}]));const Ve=de,Me=Nr(Ce);if(Me==="center"){Er("displayset");try{ao(Ut=>{const Ft=[...Ut];return Ft[B]="stack",Ft}),en(Ut=>{const Ft=[...Ut];return Ft[B]=pe,Ft}),_r(Ut=>{const Ft=[...Ut];return Ft[B]=Ve,Ft}),Ke(Ut=>{const Ft=[...Ut];return Ft[B]=ge,Ft}),qt(Ut=>{const Ft=[...Ut];return Ft[B]=0,Ft}),ht(B),await Zn(pe)}finally{Er(null)}return}const nt=tn.rows,dt=tn.cols,et=Math.floor(B/dt),gt=B%dt,ut=Me==="top"||Me==="bottom"?nt+1:nt,qe=Me==="left"||Me==="right"?dt+1:dt;if(ut>3||qe>3||ut*qe>Y){Er("displayset");try{ao(Ut=>{const Ft=[...Ut];return Ft[B]="stack",Ft}),en(Ut=>{const Ft=[...Ut];return Ft[B]=se,Ft}),_r(Ut=>{const Ft=[...Ut];return Ft[B]=Ve,Ft}),ht(B),await Zn(se)}finally{Er(null)}return}const Tt=Me==="top"?et:Me==="bottom"?et+1:et,Lt=Me==="left"?gt:Me==="right"?gt+1:gt,st=Tt*qe+Lt,Rt=Array(Y).fill([]),Nt=Array(Y).fill("stack"),Mt=Array(Y).fill(0),Gt=Array(Y).fill(null).map(()=>[]),yn=Array(Y).fill(0);for(let Ut=0;Utgt||Me==="left"?qn+1:qn),(Me==="top"||Me==="bottom")&&qn===gt&&(yr=Ftet||Me==="top"?Ft+1:Ft);const Dr=yr*qe+Zr;Rt[Dr]=Yt[Ut]||[],Nt[Dr]=dn[Ut]||"stack",Mt[Dr]=En[Ut]??0,Gt[Dr]=dr[Ut]||[],yn[Dr]=Et[Ut]??0}Rt[st]=pe,Nt[st]="stack",Mt[st]=de,Gt[st]=ge,yn[st]=0,Er("displayset");try{lc(),Ra({rows:ut,cols:qe}),en(Rt),ao(Nt),_r(Mt),Ke(Gt),qt(yn),ht(st),await Zn(pe)}finally{Er(null)}},ha=async(B,ue,Te)=>{var yn;const Ce=_t[ue];if(!Ce)return;let me=Ce.imageIds||[];const we=Ce.groupingSource==="declared"&&(Ce.seriesGroups||[]).length>0;me=!(we&&me.length>1)?await Lo(me):So((me||[]).map(va)),await Zn(me,{force:!!r});const pe=we?Ce.seriesGroups||[]:await Ao(me);Ne(bt=>{const Ut=[...bt];return Ut[ue]?(Ut[ue]={...Ut[ue],seriesGroups:pe,imageIds:me,groupingSource:we?"declared":"derived"},Ut):bt});const de=((yn=pe[0])==null?void 0:yn.imageIds)||me,Ve=Nr(Te);if(Ve==="center"){await Vi(B,ue),ht(B);return}const Me=tn.rows,nt=tn.cols,dt=Math.floor(B/nt),et=B%nt,gt=Ve==="top"||Ve==="bottom"?Me+1:Me,ut=Ve==="left"||Ve==="right"?nt+1:nt;if(gt>3||ut>3||gt*ut>Y){await Vi(B,ue),ht(B);return}const qe=Array(Y).fill([]),Tt=Array(Y).fill("stack"),Lt=Array(Y).fill(0),st=Array(Y).fill(null).map(()=>[]),Rt=Array(Y).fill(0),Nt=Ve==="top"?dt:Ve==="bottom"?dt+1:dt,Mt=Ve==="left"?et:Ve==="right"?et+1:et,Gt=Nt*ut+Mt;for(let bt=0;btet?yr=Ft+1:yr=Ve==="left"?Ft+1:Ft),(Ve==="top"||Ve==="bottom")&&Ft===et&&(Utdt?qn=Ut+1:qn=Ve==="top"?Ut+1:Ut);const Zr=qn*ut+yr;qe[Zr]=Yt[bt]||[],Tt[Zr]=dn[bt]||"stack",Lt[Zr]=En[bt]??0,st[Zr]=dr[bt]||[],Rt[Zr]=Et[bt]??0}qe[Gt]=de,Tt[Gt]="stack",Lt[Gt]=ue,st[Gt]=pe||[],Rt[Gt]=0,Er("displayset");try{lc(),Ra({rows:gt,cols:ut}),en(qe),ao(Tt),_r(Lt),Ke(st),qt(Rt),ht(Gt),await Zn(de)}finally{Er(null)}},fc=it.useCallback((B,ue)=>{if(!(Se&&Ue)||(ue.pointerType||"").toLowerCase()==="mouse")return;ue.preventDefault(),ue.stopPropagation(),Qe.current=Date.now()+400;const Te=tn.rows*tn.cols;let Ce=null,me="center";Xe({stackIdx:B,x:ue.clientX,y:ue.clientY,targetViewportIdx:null,zone:"center"});const we=de=>{let Ve=null,Me="center";for(let nt=0;ntet.right||de.clientYet.bottom)){Ve=nt,Me=Nr(Hi(et,de.clientX,de.clientY));break}}Ce=Ve,me=Me,Xe(nt=>nt&&{...nt,x:de.clientX,y:de.clientY,targetViewportIdx:Ve,zone:Me}),sn(Ve!==null?{viewportIdx:Ve,zone:Me}:null)},se=async()=>{if(window.removeEventListener("pointermove",we),window.removeEventListener("pointerup",ge),window.removeEventListener("pointercancel",pe),sn(null),Xe(null),Ce!==null)try{await ha(Ce,B,me),E(!1),ht(Ce),O(Ce)}catch(de){kt.error("Failed mobile pointer stack drop:",de)}Qe.current=Date.now()+400},ge=()=>{se()},pe=()=>{se()};window.addEventListener("pointermove",we,{passive:!0}),window.addEventListener("pointerup",ge,{passive:!0}),window.addEventListener("pointercancel",pe,{passive:!0})},[ha,Hi,Se,Ue,Nr,tn]);it.useEffect(()=>{const B=async()=>{var we;if(kt.debug("setup"),!c.current){c.current=!0,await _ee(),await NU(),AW();try{Lp("external",se=>({promise:(async()=>{const pe=se.replace(/^external:/,""),de=new Image;de.crossOrigin="anonymous",de.src=pe,await new Promise((ut,qe)=>{de.onload=()=>ut(!0),de.onerror=Tt=>qe(Tt)});const Ve=de.naturalWidth||de.width,Me=de.naturalHeight||de.height,nt=document.createElement("canvas");nt.width=Ve,nt.height=Me;const dt=nt.getContext("2d");if(!dt)throw new Error("Unable to create canvas context");dt.drawImage(de,0,0,Ve,Me);const et=dt.getImageData(0,0,Ve,Me);return{imageId:se,minPixelValue:0,maxPixelValue:255,slope:1,intercept:0,rows:Me,columns:Ve,height:Me,width:Ve,color:!0,rgba:!0,sizeInBytes:et.data.length,getPixelData:()=>et.data,getImageData:()=>et,getCanvas:()=>nt}})()}))}catch(se){kt.warn("Failed to register external image loader",se)}}let Te=ae.current;Te||(Te=new ZN(ce),ae.current=Te);let Ce=xi(De);Ce||(Ce=USe(De)),dn.slice(0,tn.rows*tn.cols).filter(se=>se==="volume").length,cs(Ce);for(let se=0;se{if(de.offsetWidth>0&&de.offsetHeight>0){Te.resize();const et=Te.getViewport(pe);et&&typeof et.resize=="function"&&et.resize(),et&&typeof et.render=="function"&&et.render()}});dt.observe(de),de._resizeObserver=dt}if(dn[se]==="stack"){if(ge&&ge.length>0){const dt=ge[0];if(Mo(dt))try{try{const ut=de._externalPanZoom;ut&&typeof ut.cleanup=="function"&&ut.cleanup()}catch{}de.innerHTML="";const et=document.createElement("img");et.style.width="100%",et.style.height="100%",et.style.objectFit="contain",et.style.display="block",et.src=dt.replace(/^external:/,""),et.setAttribute("draggable","false"),de.appendChild(et);const gt=Bn(de,et);de._externalPanZoom=gt,Ce.removeViewports(ce,pe)}catch(et){kt.warn("Failed to render external image in viewport",et)}else try{Me.setStack(ge)}catch(et){kt.warn("viewport.setStack failed",et)}}Za?Ce.removeViewports(ce,pe):Ce.addViewport(pe,ce)}else if(dn[se]==="volume"){Ce.addViewport(pe,ce);const dt=`myVolumeId_${se}`;if((await Ny(dt,{imageIds:ge})).load(),Me.setVolumes([{volumeId:dt}]),typeof Me.getNumberOfSlices=="function"){const ut=Me.getNumberOfSlices(),qe=hi.current[se]||0,Tt=Math.max(0,Math.min(Math.max(0,ut-1),qe));To(Me.element,{imageIndex:Tt})}Me.render(),de._overlayListener&&Me.element.removeEventListener(Xg,de._overlayListener);const gt=()=>br(se,Me);Me.element.addEventListener(Xg,gt),de._overlayListener=gt,br(se,Me);continue}if(Me.render(),!_e.current){di.current[se]!==void 0&&typeof Me.setImageIdIndex=="function"&&To(Me.element,{imageIndex:di.current[se]});const dt=oo.current[se];if(dt&&typeof Me.setProperties=="function"){const{voiRange:et,invert:gt,interpolationType:ut,VOILUTFunction:qe,colormap:Tt}=dt,Lt={};et&&et.lower!==void 0&&et.upper!==void 0&&(Lt.voiRange=et),gt!==void 0&&(Lt.invert=gt),ut!==void 0&&(Lt.interpolationType=ut),qe&&(Lt.VOILUTFunction=qe),Tt!=null&&(typeof Tt=="string"||typeof Tt=="object"&&!("actor"in Tt))&&(Lt.colormap=Tt),setTimeout(()=>{kt.debug("Restoring properties (timeout) for viewport",se,Lt),Me.setProperties(Lt),Me.render()},100)}}de._overlayListener&&Me.element.removeEventListener(Xg,de._overlayListener);const nt=()=>br(se,Me);Me.element.addEventListener(Xg,nt),de._overlayListener=nt,br(se,Me)}for(let se=0;se=2?(Ce.hasTool(fl.toolName)||Ce.addTool(fl.toolName),Ce.setToolEnabled(fl.toolName),Ce.setToolConfiguration(fl.toolName,{}),Ce.setToolActive(fl.toolName,{bindings:[{mouseButton:qg.Primary}]})):Ce.hasTool(fl.toolName)&&Ce.setToolDisabled(fl.toolName)),as()},ue=requestAnimationFrame(()=>{B()});return()=>{Xr.current.forEach(Te=>{Te&&Te._resizeObserver&&(Te._resizeObserver.disconnect(),delete Te._resizeObserver)}),cancelAnimationFrame(ue)}},[s,br,tn,dn,Yt]);const Ko=it.useCallback((B,ue,Te)=>{const Ce=`CT_${B}`;try{const me=ae.current;if(me){const we=me.getViewport(Ce);we&&typeof we.setProperties=="function"&&(kt.debug(`Applying preset to viewport ${B}: center=${ue}, width=${Te}`),we.setProperties({voiRange:{lower:ue-Te/2,upper:ue+Te/2}}),we.render(),br(B,we))}}catch{}},[br]),Ui=it.useCallback((B,ue=!1)=>{const Te=`CT_${B}`;try{const Ce=ae.current,me=Ce==null?void 0:Ce.getViewport(Te);if(!me)return!1;const we=typeof me.getImageIds=="function"?me.getImageIds():Yt[B]||[],se=typeof me.getCurrentImageIdIndex=="function"?me.getCurrentImageIdIndex():0,ge=we[se]||we[0],pe=xo.current[B],de=ge?xt("voiLutModule",ge)||{}:{},Ve=ge?xt("imagePixelModule",ge)||{}:{},Me=ge?xt("modalityLutModule",ge)||{}:{},nt=Array.isArray(de.windowCenter)?de.windowCenter[0]:de.windowCenter,dt=Array.isArray(de.windowWidth)?de.windowWidth[0]:de.windowWidth,et=Number(Ve.smallestPixelValue??Ve.smallestImagePixelValue),gt=Number(Ve.largestPixelValue??Ve.largestImagePixelValue),ut=Number(Me.rescaleSlope??1),qe=Number(Me.rescaleIntercept??0);if(pe)me.setProperties({voiRange:pe});else if(Number.isFinite(Number(nt))&&Number.isFinite(Number(dt))&&Number(dt)>0){const Tt=Number(nt),Lt=Number(dt);me.setProperties({voiRange:{lower:Tt-Lt/2,upper:Tt+Lt/2}})}else Number.isFinite(et)&&Number.isFinite(gt)&>>et?me.setProperties({voiRange:{lower:et*ut+qe,upper:gt*ut+qe}}):typeof me.resetProperties=="function"&&me.resetProperties();return ue&&typeof me.resetCamera=="function"&&me.resetCamera(),me.render(),br(B,me),!0}catch(Ce){return kt.warn("Failed to apply default window level",Ce),!1}},[br,Yt]),Co=it.useCallback(B=>{const ue=`CT_${B}`;(async()=>{const Te=ae.current;if(!Te)return;const Ce=Te.getViewport(ue);if(!Ce)return;const me=typeof Ce.getImageIds=="function"?Ce.getImageIds():Yt[B]||[],we=typeof Ce.getCurrentImageIdIndex=="function"?Ce.getCurrentImageIdIndex():0,se=me[we]||me[0];if(!se){Ui(B);return}const ge=xt("imagePixelModule",se)||{},pe=xt("modalityLutModule",se)||{},de=xt("voiLutModule",se)||{},Ve=xo.current[B];let Me=Number(ge.smallestPixelValue??ge.smallestImagePixelValue),nt=Number(ge.largestPixelValue??ge.largestImagePixelValue),dt=Number(pe.rescaleSlope??1),et=Number(pe.rescaleIntercept??0);if(!Number.isFinite(Me)||!Number.isFinite(nt)||nt<=Me)try{const qe=await Ml(se);Me=Number(qe==null?void 0:qe.minPixelValue),nt=Number(qe==null?void 0:qe.maxPixelValue),dt=Number((qe==null?void 0:qe.slope)??dt),et=Number((qe==null?void 0:qe.intercept)??et)}catch{const Tt=me.filter(Lt=>!!Lt).slice(0,6);for(const Lt of Tt)try{const st=await Ml(Lt);if(Me=Number(st==null?void 0:st.minPixelValue),nt=Number(st==null?void 0:st.maxPixelValue),dt=Number((st==null?void 0:st.slope)??dt),et=Number((st==null?void 0:st.intercept)??et),Number.isFinite(Me)&&Number.isFinite(nt)&&nt>Me)break}catch{}}const gt=Array.isArray(de.windowCenter)?de.windowCenter[0]:de.windowCenter,ut=Array.isArray(de.windowWidth)?de.windowWidth[0]:de.windowWidth;if(Number.isFinite(Me)&&Number.isFinite(nt)&&nt>Me)Ce.setProperties({voiRange:{lower:Me*dt+et,upper:nt*dt+et}});else if(Number.isFinite(Number(gt))&&Number.isFinite(Number(ut))&&Number(ut)>0){const qe=Number(gt),Tt=Number(ut);Ce.setProperties({voiRange:{lower:qe-Tt/2,upper:qe+Tt/2}})}else if(Ve)Ce.setProperties({voiRange:Ve});else{Ui(B);return}Ce.render(),br(B,Ce)})().catch(()=>{Ui(B)})},[Ui,br,Yt]),Jc=it.useCallback(B=>{const ue=`CT_${B}`,Ce=ae.current.getViewport(ue);Ce&&typeof Ce.resetCamera=="function"&&(Ce.resetCamera(),kt.debug("Restoring default window/level for viewport",B),Ui(B),Ce.render())},[Ui]),ga=it.useCallback((B,ue,Te=!0,Ce=!0)=>{if(Te&&(Cr.current[B]=ue),ue.action==="reset"){Ui(B,Ce);return}if(ue.action==="autolevel"){Co(B);return}const me=ue;Ko(B,me.center,me.width)},[Ui,Ko,Co]);it.useEffect(()=>{const B=()=>{const Te=ae.current;if(!Te)return;const Ce=tn.rows*tn.cols;for(let me=0;mewindow.clearTimeout(ue)},[ga,fn,tn,dn]),it.useEffect(()=>{const B=ue=>{var ge,pe;const Te=ue.target;if(Te){const de=(ge=Te.tagName)==null?void 0:ge.toLowerCase(),Ve=Te.getAttribute("contenteditable")==="true";if(de==="input"||de==="textarea"||de==="select"||Ve)return}if(ue.ctrlKey||ue.altKey||ue.metaKey||je===null)return;const Ce=(pe=fn[je])==null?void 0:pe.modality,me=a7(Ce);if(ue.key==="0"){const de=me.find(Ve=>Ve.action==="reset");de&&(ga(je,de),ue.preventDefault());return}if(!/^[1-9]$/.test(ue.key))return;const we=Number(ue.key)-1,se=me.filter(de=>de.action==="preset");we>=se.length||(ga(je,se[we]),ue.preventDefault())};return window.addEventListener("keydown",B),()=>window.removeEventListener("keydown",B)},[je,ga,fn]);const dc=it.useCallback((B,ue)=>{const Te=dr[B]||[];if(Te.length<=1)return;const Ce=Math.max(0,Math.min(Te.length-1,ue)),me=Te[Ce];if(!me||me.imageIds.length===0)return;const we=ae.current,se=we==null?void 0:we.getViewport(`CT_${B}`),ge=dn[B]==="volume",pe=Ve=>{if(!Ve)return null;const Me=xt("imagePlaneModule",Ve)||{},nt=Array.isArray(Me==null?void 0:Me.imagePositionPatient)?Me.imagePositionPatient:null,dt=Array.isArray(Me==null?void 0:Me.rowCosines)?Me.rowCosines:null,et=Array.isArray(Me==null?void 0:Me.columnCosines)?Me.columnCosines:null;if(nt&&dt&&et&&dt.length>=3&&et.length>=3){const ut=[dt[1]*et[2]-dt[2]*et[1],dt[2]*et[0]-dt[0]*et[2],dt[0]*et[1]-dt[1]*et[0]],qe=Math.hypot(ut[0],ut[1],ut[2]);if(qe>1e-6){const Tt=[ut[0]/qe,ut[1]/qe,ut[2]/qe];return nt[0]*Tt[0]+nt[1]*Tt[1]+nt[2]*Tt[2]}}const gt=Number(Me==null?void 0:Me.sliceLocation);return Number.isFinite(gt)?gt:null};let de=0;if(se&&typeof se.getCurrentImageIdIndex=="function"){const Ve=Yt[B]||[],Me=Ve.length,nt=se.getCurrentImageIdIndex(),dt=Ve[nt]||Ve[0],et=pe(dt);if(et!==null&&me.imageIds.length>0){let gt=0,ut=Number.POSITIVE_INFINITY;me.imageIds.forEach((qe,Tt)=>{const Lt=pe(qe);if(Lt===null)return;const st=Math.abs(Lt-et);st1?nt/(Me-1):0;de=Math.max(0,Math.min(me.imageIds.length-1,Math.round(gt*Math.max(0,me.imageIds.length-1))))}}else if(ge&&se&&typeof se.getSliceIndex=="function"&&typeof se.getNumberOfSlices=="function"){const Ve=se.getNumberOfSlices(),Me=se.getSliceIndex(),nt=Ve>1?Me/(Ve-1):0;de=Math.max(0,Math.min(me.imageIds.length-1,Math.round(nt*Math.max(0,me.imageIds.length-1))))}hi.current[B]=de,qt(Ve=>{const Me=[...Ve];return Me[B]=Ce,Me}),en(Ve=>{const Me=[...Ve];return Me[B]=me.imageIds,Me}),Zn(me.imageIds,{force:!!r}),window.setTimeout(()=>{var Me;const Ve=(Me=ae.current)==null?void 0:Me.getViewport(`CT_${B}`);if(Ve){if(dn[B]==="stack"&&typeof Ve.setImageIdIndex=="function"){To(Ve.element,{imageIndex:de}),Ve.render(),br(B,Ve);return}if(dn[B]==="volume"&&typeof Ve.getNumberOfSlices=="function"){const nt=Ve.getNumberOfSlices(),dt=Math.max(0,Math.min(Math.max(0,nt-1),de));To(Ve.element,{imageIndex:dt}),Ve.render(),br(B,Ve)}}},25)},[dr,Zn,br,Yt,dn]);it.useEffect(()=>{const B=[],ue=tn.rows*tn.cols;for(let Te=0;Te{var nt,dt;const ge=(nt=ae.current)==null?void 0:nt.getViewport(`CT_${Te}`);if(!ge||typeof ge.getCurrentImageIdIndex!="function"||typeof ge.setImageIdIndex!="function")return;const de=(((dt=ge.getImageIds)==null?void 0:dt.call(ge))||Ce).length;if(de<2)return;const Me=(ge.getCurrentImageIdIndex()+1)%de;To(ge.element,{imageIndex:Me}),ge.render()},we);B.push(se)}return()=>{B.forEach(Te=>window.clearInterval(Te))}},[cn,Nn,tn,Yt,dn]);const Zc=it.useCallback(()=>{const B=a.current;B&&(document.fullscreenElement===B?document.exitFullscreen():B.requestFullscreen?B.requestFullscreen():B.webkitRequestFullscreen?B.webkitRequestFullscreen():B.msRequestFullscreen&&B.msRequestFullscreen())},[]);it.useEffect(()=>{Ki(Array(tn.rows*tn.cols).fill({index:0,total:0,windowCenter:"",windowWidth:"",slicePosition:"",modality:"",orientation:"",resolution:"",spacing:"",focalPoint:""})),Ms(Array(tn.rows*tn.cols).fill(!1)),_n(Array(Y).fill(!1))},[tn]),it.useEffect(()=>{as()},[mr,No,Ul,as]),it.useEffect(()=>{if(!Di.some(Boolean))return;const B=ue=>{const Te=document.querySelector(".preset-menu");Te&&!Te.contains(ue.target)&&Ms(Ce=>Ce.map(()=>!1))};return document.addEventListener("mousedown",B),()=>document.removeEventListener("mousedown",B)},[Di]),it.useEffect(()=>{if(!La)return;const B=ue=>{const Te=k.current;Te&&!Te.contains(ue.target)&&(Fi(!1),fe(!1))};return document.addEventListener("mousedown",B),()=>document.removeEventListener("mousedown",B)},[La]),it.useEffect(()=>{const B=ue=>{if(ue.button===3||ue.button===4)return ue.preventDefault(),!1};return window.addEventListener("mousedown",B,!0),window.addEventListener("mouseup",B,!0),window.addEventListener("auxclick",B,!0),()=>{window.removeEventListener("mousedown",B,!0),window.removeEventListener("mouseup",B,!0),window.removeEventListener("auxclick",B,!0)}},[]),it.useEffect(()=>{const B=a.current;if(!B)return;const ue=Te=>{Te.preventDefault()};return B.addEventListener("contextmenu",ue),()=>{B.removeEventListener("contextmenu",ue)}},[]),it.useEffect(()=>{if(!zo)return;const B=xi(De);cs(B)},[je,zo]),it.useEffect(()=>{As.current&&(As.current.setAttribute("webkitdirectory","true"),As.current.setAttribute("directory","true"))},[]),it.useEffect(()=>(window.loadDicomStackFromWadouriList=async B=>{var we;if(!B||B.length===0)return;const ue=await Lo(B);await Zn(ue,{force:!!r});const Te=await Ao(ue),Ce=((we=Te[0])==null?void 0:we.imageIds)||ue;let me;try{const se=ue[0];if(r&&se&&se.startsWith("wadouri:")){const ge=il(se),de=await(await fetch(ge)).arrayBuffer();me=Vr.parseDicom(new Uint8Array(de)).string("x0020000d")}}catch{}Ne(se=>{const ge=[...se,{imageIds:ue,studyInstanceUID:me,seriesGroups:Te,groupingSource:"derived"}];return en(pe=>{const de=[...pe];return de[0]=Ce,de}),_r(pe=>{const de=[...pe];return de[0]=ge.length-1,de}),Ke(pe=>{const de=[...pe];return de[0]=Te,de}),qt(pe=>{const de=[...pe];return de[0]=0,de}),Zn(Ce),ge})},()=>{window.loadDicomStackFromWadouriList=void 0}),[Ao,Lo,Ne,Zn,_r,en]),it.useEffect(()=>{!Aa||!Yt.every(ue=>!ue||ue.length===0||ue.every(Te=>!!xt("imagePlaneModule",Te)))||en(ue=>{let Te=!1;const Ce=ue.map(me=>{if(!me||me.length===0)return me;const ge=[...me.map(pe=>({imageId:pe,sliceLoc:(()=>{const de=xt("imagePlaneModule",pe);return de&&de.sliceLocation!==void 0?Number(de.sliceLocation):null})()}))].sort((pe,de)=>pe.sliceLoc!==null&&de.sliceLoc!==null?pe.sliceLoc-de.sliceLoc:pe.imageId.localeCompare(de.imageId)).map(pe=>pe.imageId);return JSON.stringify(ge)!==JSON.stringify(me)?(Te=!0,ge):me});return Te&&Ja(!0),Ce})},[Aa,_t]);function cs(B){if(!B)return;const ue=`CT_${je}`;zo?(B.setToolEnabled(Vd.toolName),B.setToolConfiguration(Vd.toolName,{sourceViewportId:ue})):B.setToolDisabled(Vd.toolName)}function Qc(){var ue,Te,Ce;const B=ae.current;if(B)for(let me=0;me[])),_r(Array(Y).fill(0)),Ke(Array(Y).fill(null).map(()=>[])),qt(Array(Y).fill(0)),Ai(Array(Y).fill(!1)),_n(Array(Y).fill(!1)),ao(Array(Y).fill("stack")),Object.values(ro.current).forEach(ue=>{if(typeof ue=="string"&&ue.startsWith("blob:"))try{URL.revokeObjectURL(ue)}catch{}}),ro.current={},Ya({}),io.current={},Ja(!1),ht(0)}function ne(B,ue){var se,ge;if(kt.debug("Truncating stack from",B,"to",ue),kt.debug(fi),tn.rows!==1||tn.cols!==1||_t.length!==1||!Yt[0]||Yt[0].length===0||fi)return alert("Truncation is only allowed when a single stack is loaded in a single viewport (and the order has not been modified in the viewer)."),!1;const Te=_t[0],Ce=Te.imageIds;if(B<0||ue>=Ce.length||B>=ue)return alert("Invalid truncation bounds."),!1;const me=Ce.slice(B,ue+1);Ne([{...Te,imageIds:me}]),en([me]),_r([0]);const we=ae.current;if(we){const pe=we.getViewport("CT_0");pe&&typeof pe.setStack=="function"&&(pe.setStack(me),(se=pe.setImageIdIndex)==null||se.call(pe,0),(ge=pe.render)==null||ge.call(pe))}return!0}function Ee(B=0){const ue=ae.current;if(!ue)return null;const Te=ue.getViewport(`CT_${B}`);return!Te||typeof Te.getCurrentImageIdIndex!="function"?null:Te.getCurrentImageIdIndex()}it.useEffect(()=>{const B=t||"default";function ue(Ce,me){const we=ae.current;if(!we)return;const se=we.getViewport(`CT_${Ce}`);if(!se||typeof se.getImageIds!="function")return;const pe=se.getImageIds().map(Me=>il(Me)),de=il(me),Ve=pe.indexOf(de);Ve!==-1&&typeof se.setImageIdIndex=="function"&&(To(se.element,{imageIndex:Ve}),br(Ce,se))}window[`getViewport_${B}`]=Ce=>{const me=ae.current;if(me)return me.getViewport(`CT_${Ce}`)},window[`getAllViewports_${B}`]=()=>{const Ce=ae.current;return Ce?Array.from({length:Y},(me,we)=>Ce.getViewport(`CT_${we}`)).filter(Boolean):[]},window[`jumpToSliceByImageId_${B}`]=ue,window[`resetViewer_${B}`]=Qc,window[`clearViewer_${B}`]=te,window[`truncateStack_${B}`]=ne,window[`getCurrentStackPosition_${B}`]=Ee,window[`loadAdditionalStack_${B}`]=async(Ce,me,we)=>{var dt,et;if(!Array.isArray(Ce)||Ce.length===0)return;const se=So((Ce||[]).map(va)),pe=Array.isArray(we)&&we.length>0?se:await Lo(se);await Zn(pe,{force:!!r});const de=Array.isArray(we)?we.map((gt,ut)=>{const qe=Array.isArray(gt==null?void 0:gt.imageIds)?gt.imageIds:Array.isArray(gt==null?void 0:gt.i)?gt.i:[],Tt=So(qe.map(va));return Tt.length===0?null:{key:String((gt==null?void 0:gt.key)||(gt==null?void 0:gt.seriesInstanceUID)||`SERVER_SERIES_${ut}`),label:typeof(gt==null?void 0:gt.label)=="string"&>.label.trim()||typeof(gt==null?void 0:gt.name)=="string"&>.name.trim()||`Series ${ut+1}`,imageIds:Tt,seriesInstanceUID:gt==null?void 0:gt.seriesInstanceUID,bValue:Number.isFinite(Number(gt==null?void 0:gt.bValue))?Number(gt==null?void 0:gt.bValue):null,groupValues:gt==null?void 0:gt.groupValues}}).filter(gt=>!!gt):[],Ve=de.length>0?de:await Ao(pe),Me=((dt=Ve[0])==null?void 0:dt.imageIds)||pe;let nt=me;if(!nt&&r&&((et=pe[0])!=null&&et.startsWith("wadouri:")))try{const gt=il(pe[0]),qe=await(await fetch(gt)).arrayBuffer();nt=Vr.parseDicom(new Uint8Array(qe)).string("x0020000d")}catch{}Ne(gt=>[...gt,{imageIds:pe,studyInstanceUID:nt,seriesGroups:Ve,groupingSource:de.length>0?"declared":"derived"}]),en(gt=>{const ut=[...gt],qe=ut.findIndex(Tt=>!Tt||Tt.length===0);return qe!==-1&&(ut[qe]=Me,Ke(Tt=>{const Lt=[...Tt];return Lt[qe]=Ve,Lt}),qt(Tt=>{const Lt=[...Tt];return Lt[qe]=0,Lt})),ut}),Zn(Me)},window[`loadExternalStack_${B}`]=async(Ce,me)=>{!Array.isArray(Ce)||Ce.length===0||await uc(je??0,Ce,me||"Series","center")},window[`loadExternalStackNewViewport_${B}`]=async(Ce,me)=>{if(!Array.isArray(Ce)||Ce.length===0)return;await uc(je??0,Ce,me||"Series","right")},window[`exportViewerState_${B}`]=()=>{var et;const Ce=tn.rows*tn.cols,me=dn.slice(0,Ce),we=En.slice(0,Ce),se=_t.map(gt=>({i:gt.imageIds,u:gt.studyInstanceUID,g:gt.seriesGroups}));kt.debug("Exporting viewer state with",Ce,"active viewports"),kt.debug("modes",me);const ge=ae.current,pe=[],de=[],Ve=[],Me=[],nt=[];for(let gt=0;gt{try{_e.current=!0;const me=typeof Ce=="string"?JSON.parse(Ce):Ce;if(me.grid&&Ra(me.grid),me.modes&&ao(me.modes),me.stacks&&Ne(me.stacks.map(pe=>({imageIds:pe.i,studyInstanceUID:pe.u,seriesGroups:Array.isArray(pe.g)?pe.g:void 0}))),me.stackIdx&&me.stacks){const pe=me.stackIdx.map(de=>{var Ve;return((Ve=me.stacks[de])==null?void 0:Ve.i)||[]});en(pe),_r(me.stackIdx),Ke(()=>{const de=Array(Y).fill(null).map(()=>[]);for(let Ve=0;Veqn===Ut[yr])){kt.warn(`Viewport ${Mt}: importedImageIds do not match viewportImageIds`,{importedImageIds:Ut,viewportImageIds:Ft}),Ve=!1;break}}catch{Ve=!1}}if(!Ve&&se{ge()},500);return}for(let Mt=0;Mt{try{To(Gt.element,{imageIndex:me.volumeSliceIndices[Mt]})}catch{}},100)}else{try{Gt.setStack&&(Gt.setStack(Ut),Gt.render())}catch(Ft){kt.warn("Failed to set stack for viewport",Mt,Ft)}if(me.stackPos&&typeof me.stackPos[Mt]=="number"&&typeof Gt.setImageIdIndex=="function")try{Kn&&To?To(Gt.element,{imageIndex:me.stackPos[Mt]}):Gt.setImageIdIndex(me.stackPos[Mt])}catch{}}}const Me=1500;kt.debug(`Waiting ${Me}ms before applying properties/camera to viewports`),await new Promise(Mt=>setTimeout(Mt,Me));for(let Mt=0;Mt{ge()},100)}catch(me){_e.current=!1,alert("Failed to import viewer state: "+me)}},window[`exportAnnotations_${B}`]=()=>{try{let Ce=Rr.getAllAnnotations();if(kt.debug("Exporting annotations:",Ce),Array.isArray(Ce)){const me=[Gf.toolName,$h.toolName,Wf.toolName,Du.toolName,e0.toolName,Bf.toolName,Ll.toolName,Iu.toolName,Gh.toolName];Ce=Ce.filter(we=>me.includes(we.metadata.toolName))}else return"{}";return JSON.stringify(Ce,null,2)}catch(Ce){return alert("Failed to export annotations: "+Ce),"{}"}},window.__pendingImportAnnotations=window.__pendingImportAnnotations||{};const Te=Ce=>{try{const me=window.__pendingImportAnnotations&&window.__pendingImportAnnotations[Ce];if(!me||!me.length)return;const we=Rr;if(!we||typeof we.addAnnotation!="function")return;for(;(window.__pendingImportAnnotations[Ce]||[]).length;){const se=(window.__pendingImportAnnotations[Ce]||[]).shift();se&&Array.isArray(se)&&se.forEach(ge=>{try{we.addAnnotation(ge,ge.annotationUID)}catch(pe){kt.error("Failed to add queued annotation",pe,ge)}})}ae.current&&ae.current.render()}catch(me){kt.error("Error flushing pending annotations:",me)}};return window[`importAnnotations_${B}`]=Ce=>{try{const me=typeof Ce=="string"?JSON.parse(Ce):Ce,we=Rr;if(!we||typeof we.addAnnotation!="function"){window.__pendingImportAnnotations[B]=window.__pendingImportAnnotations[B]||[],window.__pendingImportAnnotations[B].push(me),kt.warn("importAnnotations: annotation state not ready, queued import",B),setTimeout(()=>Te(B),500);return}if(we.removeAllAnnotations)try{we.removeAllAnnotations()}catch(se){kt.warn("removeAllAnnotations failed",se)}Array.isArray(me)&&me.forEach(se=>{try{we.addAnnotation(se,se.annotationUID)}catch(ge){kt.error("Failed to add annotation",ge,se)}}),ae.current&&ae.current.render()}catch(me){kt.error("Failed to import annotations:",me,{apiKey:B,cornerstoneTools:!!oCe,renderingEngine:!!ae.current});try{alert("Failed to import annotations: "+me)}catch{}}try{Te(B)}catch{}},window[`importLegacyAnnotations_${B}`]=Ce=>{Rr.removeAllAnnotations&&Rr.removeAllAnnotations();let me;try{me=typeof Ce=="string"?JSON.parse(Ce):Ce}catch{alert("Invalid legacy annotation JSON");return}const we={ArrowAnnotate:"ArrowAnnotate"};Object.entries(me).forEach(([se,ge])=>{kt.debug("Importing legacy annotations for imageId:",se),Object.entries(ge).forEach(([pe,de])=>{const Ve=we[pe]||pe;de.data&&Array.isArray(de.data)&&de.data.forEach(Me=>{const nt=i7(se,{x:Me.handles.start.y,y:Me.handles.start.x}),dt=i7(se,{x:Me.handles.end.y,y:Me.handles.end.x});kt.debug("Importing legacy annotation:"),kt.debug(" Image ID:",se),kt.debug(" Start World:",nt),kt.debug(" End World:",dt);const et=xt("imagePlaneModule",se);kt.debug(AA);let gt=xt("frameOfReferenceUID",se);!gt&&et&&et.frameOfReferenceUID&&(gt=et.frameOfReferenceUID);const ut=et!=null&&et.rowCosines&&(et!=null&&et.columnCosines)?[et.rowCosines[1]*et.columnCosines[2]-et.rowCosines[2]*et.columnCosines[1],et.rowCosines[2]*et.columnCosines[0]-et.rowCosines[0]*et.columnCosines[2],et.rowCosines[0]*et.columnCosines[1]-et.rowCosines[1]*et.columnCosines[0]]:void 0;Array.isArray(ut)&&ut.length,typeof Me.rotation=="number"&&Me.rotation;const qe={annotationUID:Me.uuid,metadata:{toolName:Ve,referencedImageId:se,FrameOfReferenceUID:gt,viewPlaneNormal:ut},data:{handles:{points:[nt,dt],textBox:Me.handles.textBox},text:Me.text||""},visibility:Me.visible!==!1,active:Me.active||!1};Rr.addAnnotation(qe,qe.annotationUID)})})}),ae.current&&ae.current.render()},window[`importLegacyViewport_${B}`]=Ce=>{let me;try{me=typeof Ce=="string"?JSON.parse(Ce):Ce}catch{alert("Invalid legacy viewport JSON");return}const we=ae.current;if(!we)return;const se=`CT_${je??0}`,ge=we.getViewport(se);if(!ge)return;const pe={};if(me.voi&&(pe.voiRange={lower:me.voi.windowCenter-me.voi.windowWidth/2,upper:me.voi.windowCenter+me.voi.windowWidth/2}),typeof me.invert=="boolean"&&(pe.invert=me.invert),typeof me.pixelReplication=="boolean"&&(pe.interpolationType=me.pixelReplication?0:1),typeof me.hflip=="boolean"&&(pe.hflip=me.hflip),typeof me.vflip=="boolean"&&(pe.vflip=me.vflip),typeof ge.setProperties=="function"&&ge.setProperties(pe),me.translation||me.scale){const de=ge.getCamera?ge.getCamera():{};me.translation&&(de.translation={...de.translation,...me.translation}),me.scale&&(de.parallelScale=200/me.scale),kt.debug("Applying legacy camera properties:",de),typeof ge.setCamera=="function"&&ge.setCamera(de)}typeof me.rotation=="number"&&ge.setRotation(me.rotation),ge.render(),br(je??0,ge)},()=>{window[`exportViewerState_${B}`]=void 0,window[`importViewerState_${B}`]=void 0,window[`exportAnnotations_${B}`]=void 0,window[`importAnnotations_${B}`]=void 0,window[`importLegacyAnnotations_${B}`]=void 0,window[`importLegacyViewport_${B}`]=void 0,window[`jumpToSliceByImageId_${B}`]=void 0,window[`resetViewer_${B}`]=void 0,window[`clearViewer_${B}`]=void 0,window[`truncateStack_${B}`]=void 0,window[`getCurrentStackPosition_${B}`]=void 0,window[`loadAdditionalStack_${B}`]=void 0,window[`loadExternalStack_${B}`]=void 0,window[`loadExternalStackNewViewport_${B}`]=void 0,window[`getViewport_${B}`]=void 0,window[`getAllViewports_${B}`]=void 0}},[tn,dn,En,_t,Yt,Ra,ao,_r,Ne,en,Ne,en,Zn]),it.useEffect(()=>{const B=a.current;if(!B)return;function ue(Te){if(kt.debug("Handling arrow key navigation",Te.key),kt.debug("activeViewport",je),je===null)return;const Ce=ae.current;if(!Ce)return;const me=Ce.getViewport(`CT_${je}`);if(me){if(kt.debug(me),dn[je]==="stack"){if(typeof me.getCurrentImageIdIndex!="function"||typeof me.setImageIdIndex!="function")return;const we=Yt[je];if(!we||we.length===0)return;Te.key==="ArrowUp"||Te.key==="ArrowRight"?(Mc(me,{delta:-1}),Te.preventDefault()):(Te.key==="ArrowDown"||Te.key==="ArrowLeft")&&(Mc(me,{delta:1}),Te.preventDefault())}dn[je]==="volume"&&typeof me.getSliceIndex=="function"&&typeof me.getNumberOfSlices=="function"&&me.getNumberOfSlices()>1&&(Te.key==="ArrowUp"||Te.key==="ArrowRight"?(Mc(me,{delta:-1}),Te.preventDefault()):(Te.key==="ArrowDown"||Te.key==="ArrowLeft")&&(Mc(me,{delta:1}),Te.preventDefault()))}}return B.addEventListener("keydown",ue),()=>{B.removeEventListener("keydown",ue)}},[je,dn,Yt,br]);const ze=je!==null?En[je]:0,rt=_t[ze];rt==null||rt.studyInstanceUID;const[vt,pt]=it.useState(()=>Array(Y).fill(null)),ot=tn.rows*tn.cols,yt=[];for(let B=0;B1||(((Z=fn[B])==null?void 0:Z.totalFrames)||0)>1),me=(rn==null?void 0:rn.viewportIdx)===B?rn.zone:null,we=me?Nr(me):null;yt.push(Re.jsxs("div",{ref:se=>Xr.current[B]=se,style:{flex:1,display:ue&&Te?"flex":"none",border:ue?"1px solid #222":"none",background:"#000",minWidth:0,minHeight:0,position:"relative",overflow:"hidden",flexDirection:"column",gridRow:Math.floor(B/tn.cols)+1,gridColumn:B%tn.cols+1,height:"100%",touchAction:Se&&Ue?"none":"pan-y",boxShadow:je===B?"0 0 0 4px #1976d2, 0 0 16px 4px #1976d2cc":void 0,zIndex:je===B?10:1},onClick:()=>{if(!ke){if(Se&&!Ue){$c(B),Fi(!1),fe(!1),Rs(!1);return}if(Se&&Ue&&q!==null){ha(B,q,ie).catch(se=>{kt.error("Failed to apply mobile stack drop:",se)}),ee(null),E(!1);return}ht(B),Fi(!1)}},onDoubleClick:()=>Jc(B),onDragEnter:se=>{const ge=se.dataTransfer.types,pe=ge.includes("text/stack-idx"),de=ge.includes("text/dv3d-imageids");if(!pe&&!de)return;se.preventDefault(),de&&Bt(!0);const Ve=ns(se);sn({viewportIdx:B,zone:Ve})},onDragOver:se=>{const ge=se.dataTransfer.types,pe=ge.includes("text/stack-idx"),de=ge.includes("text/dv3d-imageids");if(!pe&&!de)return;se.preventDefault();const Ve=ns(se),Me=Nr(Ve);sn({viewportIdx:B,zone:Ve}),se.dataTransfer.dropEffect=Me===Ve?"copy":"move"},onDragLeave:se=>{if((rn==null?void 0:rn.viewportIdx)!==B)return;const ge=se.relatedTarget;ge&&se.currentTarget.contains(ge)||sn(null)},onDrop:se=>{se.preventDefault();const ge=se.dataTransfer.getData("text/dv3d-imageids");if(ge){const Ve=se.dataTransfer.getData("text/dv3d-stack-name")||"Series";try{const Me=JSON.parse(ge),nt=ns(se);uc(B,Me,Ve,nt).catch(dt=>{kt.error("Failed to apply external drop:",dt)})}catch(Me){kt.error("Invalid text/dv3d-imageids payload:",Me)}sn(null),Bt(!1);return}const pe=se.dataTransfer.getData("text/stack-idx"),de=parseInt(pe,10);if(!isNaN(de)){const Ve=ns(se);ha(B,de,Ve).catch(Me=>{kt.error("Failed to apply dropped stack:",Me)})}sn(null),Dt(null),Bt(!1)},children:[Se&&!Ue&&Re.jsx("div",{style:{position:"absolute",inset:0,zIndex:60,pointerEvents:"none",display:"flex",alignItems:"center",justifyContent:"center",background:"linear-gradient(to top, rgba(0,0,0,0.55), rgba(0,0,0,0.2))",color:"#fff",fontSize:14,fontWeight:700,letterSpacing:.2,textAlign:"center",padding:"18px"},children:"Tap to activate fullscreen interaction"}),Se&&Ue&&q!==null&&Re.jsxs("div",{style:{position:"absolute",top:8,right:8,zIndex:62,background:"rgba(25, 118, 210, 0.92)",color:"#fff",borderRadius:6,padding:"6px 8px",fontSize:11,fontWeight:700,pointerEvents:"none"},children:["Tap to drop stack (",ie,")"]}),(wt!==null||an)&&me&&Re.jsx("div",{style:{position:"absolute",inset:0,zIndex:19,pointerEvents:"none",background:"rgba(0,0,0,0.08)"},children:Re.jsx("div",{style:{position:"absolute",left:we==="left"?0:we==="right"?"50%":"20%",top:we==="top"?0:we==="bottom"?"50%":"20%",width:we==="left"||we==="right"?"50%":"60%",height:we==="top"||we==="bottom"?"50%":"60%",border:"2px solid #90caf9",boxShadow:"0 0 0 9999px rgba(17, 29, 45, 0.22)",background:"rgba(25, 118, 210, 0.28)",borderRadius:6,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:12,fontWeight:700,textTransform:"uppercase",letterSpacing:.4},children:we==="center"?"Load Here":`Split ${we}`})}),ji==="displayset"&&Re.jsx("div",{style:{position:"absolute",inset:0,zIndex:58,pointerEvents:"none",display:"flex",alignItems:"center",justifyContent:"center",color:"rgba(255,255,255,0.78)",fontSize:14,fontWeight:600,letterSpacing:.2,textShadow:"0 1px 3px rgba(0,0,0,0.55)"},children:"Loading images..."}),Re.jsx("button",{style:{position:"absolute",top:8,left:8,zIndex:20,background:"#333",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 8px",cursor:"pointer",fontSize:"12px",opacity:.85},onClick:()=>{ao(se=>{const ge=[...se];return ge[B]=se[B]==="stack"?"volume":"stack",ge})},children:dn[B]==="stack"?"Volume":"Stack"}),dn[B]==="volume"&&Re.jsxs("div",{style:{position:"absolute",top:8,left:70,zIndex:21,display:"flex",gap:"6px",background:"rgba(34,34,34,0.85)",borderRadius:"4px",padding:"2px 6px",alignItems:"center"},children:[Re.jsx("button",{style:{background:"#444",color:"#fff",border:"none",borderRadius:"3px",padding:"2px 8px",cursor:"pointer",fontSize:"12px",marginRight:"2px"},onClick:()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);ge&&ge.setOrientation&&(ge.setOrientation("axial"),ge.render())},children:"Axial"}),Re.jsx("button",{style:{background:"#444",color:"#fff",border:"none",borderRadius:"3px",padding:"2px 8px",cursor:"pointer",fontSize:"12px",marginRight:"2px"},onClick:()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);ge&&ge.setOrientation&&(ge.setOrientation("sagittal"),ge.render())},children:"Sagittal"}),Re.jsx("button",{style:{background:"#444",color:"#fff",border:"none",borderRadius:"3px",padding:"2px 8px",cursor:"pointer",fontSize:"12px"},onClick:()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);ge&&ge.setOrientation&&(ge.setOrientation("coronal"),ge.render())},children:"Coronal"})]}),Re.jsxs("button",{style:{position:"absolute",top:40,left:8,zIndex:20,background:"#111",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 8px",cursor:"pointer",fontSize:"13px",opacity:.85,marginTop:"4px",display:"flex",alignItems:"center",gap:"6px"},title:"Toggle Fullscreen",onClick:se=>{se.stopPropagation();const ge=Xr.current[B];document.fullscreenElement===ge?document.exitFullscreen():ge!=null&&ge.requestFullscreen?ge.requestFullscreen():ge!=null&&ge.webkitRequestFullscreen?ge.webkitRequestFullscreen():ge!=null&&ge.msRequestFullscreen&&ge.msRequestFullscreen()},onMouseEnter:()=>H(B),onMouseLeave:()=>H(null),children:[Re.jsx("span",{style:{fontSize:"18px",lineHeight:1},children:"⛶"}),F===B&&Re.jsx("span",{style:{marginLeft:6},children:document.fullscreenElement===Xr.current[B]?"Exit Fullscreen":"Fullscreen"})]}),Ce&&Re.jsx("button",{style:{position:"absolute",top:78,left:8,zIndex:20,background:Sn[B]?"rgba(30,120,200,0.95)":"#111",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 8px",cursor:"pointer",fontSize:"16px",lineHeight:1,opacity:.9},title:Sn[B]?"Hide cine controls":"Show cine controls",onClick:se=>{se.stopPropagation(),_n(ge=>{const pe=[...ge],de=!pe[B];return pe[B]=de,de||Ai(Ve=>{const Me=[...Ve];return Me[B]=!1,Me}),pe})},children:Re.jsx("span",{"aria-hidden":"true",children:"▶"})}),dn[B]==="stack"&&tt&&(()=>{var gt;const se=Yt[B],pe=(Rr.getAllAnnotations()||[]).filter(ut=>ut.metadata&&ut.metadata.referencedImageId&&se.includes(ut.metadata.referencedImageId)&&ut.metadata.toolName!==gs.toolName);if(!pe.length)return null;const de=ae.current,Ve=de==null?void 0:de.getViewport(`CT_${B}`),Me=((gt=Ve==null?void 0:Ve.getCurrentImageIdIndex)==null?void 0:gt.call(Ve))??0,nt=se[Me],dt=pe.filter(ut=>ut.metadata.referencedImageId===nt),et=vt[B];return Re.jsxs("div",{style:{position:"absolute",left:"50%",bottom:60,transform:"translateX(-50%)",zIndex:30,display:"flex",gap:4,pointerEvents:"auto",alignItems:"center"},children:[Re.jsx("button",{style:{background:"rgba(30,30,30,0.7)",color:"#fff",border:"none",borderRadius:"50%",width:28,height:28,fontSize:"16px",fontWeight:"bold",cursor:"pointer",opacity:.7,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 1px 4px rgba(0,0,0,0.18)",transition:"opacity 0.2s"},title:"Previous Annotation","aria-label":"Previous Annotation",onClick:()=>{const ut=ae.current,qe=ut==null?void 0:ut.getViewport(`CT_${B}`);if(!qe||typeof qe.getCurrentImageIdIndex!="function")return;const Tt=qe.getCurrentImageIdIndex(),Lt=g7(Tt,se,pe,-1);if(Lt!==null&&typeof qe.setImageIdIndex=="function"){To(qe.element,{imageIndex:Lt}),br(B,qe);const st=se[Lt],Rt=pe.filter(Nt=>Nt.metadata.referencedImageId===st);ic(B,Rt.length>0?Rt[0].annotationUID:null)}},children:Re.jsx("span",{"aria-hidden":"true",children:"◀"})}),Re.jsx("button",{style:{background:"rgba(30,30,30,0.7)",color:"#fff",border:"none",borderRadius:"50%",width:28,height:28,fontSize:"16px",fontWeight:"bold",cursor:"pointer",opacity:.7,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 1px 4px rgba(0,0,0,0.18)",transition:"opacity 0.2s"},title:"Next Annotation","aria-label":"Next Annotation",onClick:()=>{const ut=ae.current,qe=ut==null?void 0:ut.getViewport(`CT_${B}`);if(!qe||typeof qe.getCurrentImageIdIndex!="function")return;const Tt=qe.getCurrentImageIdIndex(),Lt=g7(Tt,se,pe,1);if(Lt!==null&&typeof qe.setImageIdIndex=="function"){To(qe.element,{imageIndex:Lt}),br(B,qe);const st=se[Lt],Rt=pe.filter(Nt=>Nt.metadata.referencedImageId===st);ic(B,Rt.length>0?Rt[0].annotationUID:null)}},children:Re.jsx("span",{"aria-hidden":"true",children:"▶"})}),dt.length>0&&Re.jsx("div",{style:{display:"flex",gap:2,alignItems:"center"},children:dt.map(ut=>Re.jsxs("div",{style:{display:"flex",alignItems:"center",background:et===ut.annotationUID?"rgb(4, 225, 0)":"#444",color:et===ut.annotationUID?"#222":"#fff",borderRadius:"4px",padding:"2px 6px",marginRight:2,cursor:"pointer",border:et===ut.annotationUID?"2px solid #1976d2":"none",fontWeight:et===ut.annotationUID?"bold":"normal"},onClick:()=>ic(B,ut.annotationUID),children:[Re.jsxs("span",{style:{marginRight:4},title:ut.metadata.toolName||"Annotation",children:[et===ut.annotationUID?"★ ":"",Re.jsx("span",{style:{fontSize:14,lineHeight:1},children:u7(ut.metadata.toolName)})]}),Re.jsx("button",{style:{background:"transparent",color:"#f44336",border:"1px solid #f44336",borderRadius:3,width:16,height:16,fontSize:10,lineHeight:1,cursor:"pointer",marginLeft:4,display:"flex",alignItems:"center",justifyContent:"center",opacity:.95,padding:0},title:"Delete this annotation","aria-label":"Delete annotation",onClick:qe=>{qe.stopPropagation(),Bl(B,ut.annotationUID,dt)},children:Re.jsx("span",{"aria-hidden":"true",children:"✖"})})]},ut.annotationUID))})]})})(),Re.jsx("div",{style:{position:"absolute",left:8,bottom:8,background:"rgba(0,0,0,0.7)",color:"#fff",padding:"6px 12px",borderRadius:"4px",fontSize:"14px",zIndex:10,pointerEvents:"none",minWidth:"120px",userSelect:"none"},children:dn[B]==="stack"?Re.jsxs(Re.Fragment,{children:[Re.jsxs("div",{children:["Image: ",(J=fn[B])==null?void 0:J.index," / ",(ye=fn[B])==null?void 0:ye.total,Re.jsx("div",{style:{margin:"18px 0 8px 0",fontWeight:"bold"},children:"Window/Level Mouse Sensitivity"}),Re.jsxs("label",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:12},children:[Re.jsx("span",{style:{minWidth:120},children:"Drag sensitivity"}),Re.jsx("input",{type:"range",min:.25,max:2,step:.05,value:Jr,onChange:se=>nc(Number(se.target.value)),style:{flex:1}}),Re.jsxs("span",{style:{minWidth:44,textAlign:"right"},children:[Jr.toFixed(2),"x"]})]}),(Be=fn[B])!=null&&Be.frameIndex&&((Ze=fn[B])!=null&&Ze.totalFrames)?Re.jsxs(Re.Fragment,{children:["   [Frame: ",(Ct=fn[B])==null?void 0:Ct.frameIndex," / ",(mt=fn[B])==null?void 0:mt.totalFrames,"]"]}):null]}),Re.jsxs("div",{children:["WC: ",(lt=fn[B])==null?void 0:lt.windowCenter,"   WW: ",($=fn[B])==null?void 0:$.windowWidth]}),Ot&&Re.jsxs(Re.Fragment,{children:[Re.jsxs("div",{children:["Ori: ",((K=fn[B])==null?void 0:K.orientation)||"N/A"]}),((R=fn[B])==null?void 0:R.resolution)&&Re.jsxs("div",{children:["Res: ",(U=fn[B])==null?void 0:U.resolution]}),((X=fn[B])==null?void 0:X.spacing)&&Re.jsxs("div",{children:["Spacing: ",(he=fn[B])==null?void 0:he.spacing]}),((xe=fn[B])==null?void 0:xe.focalPoint)&&Re.jsxs("div",{children:["Pos: ",(be=fn[B])==null?void 0:be.focalPoint]})]})]}):Re.jsxs("div",{children:["Slice: ",(Le=fn[B])==null?void 0:Le.index," / ",(Fe=fn[B])==null?void 0:Fe.total,((He=fn[B])==null?void 0:He.slicePosition)&&Re.jsxs("span",{children:["   (",(ft=fn[B])==null?void 0:ft.slicePosition,")"]}),Re.jsx("br",{}),"WC: ",(It=fn[B])==null?void 0:It.windowCenter,"   WW: ",(Jt=fn[B])==null?void 0:Jt.windowWidth,Ot&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Ori: ",((Wt=fn[B])==null?void 0:Wt.orientation)||"N/A",((Mn=fn[B])==null?void 0:Mn.resolution)&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Res: ",(bn=fn[B])==null?void 0:bn.resolution]}),((ar=fn[B])==null?void 0:ar.spacing)&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Spacing: ",(ai=fn[B])==null?void 0:ai.spacing]}),((gi=fn[B])==null?void 0:gi.focalPoint)&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Pos: ",(el=fn[B])==null?void 0:el.focalPoint]})]})]})}),Re.jsx("div",{style:{position:"absolute",right:8,bottom:8,zIndex:110,pointerEvents:"auto",display:"flex",alignItems:"flex-end",gap:6},children:Re.jsxs("div",{className:"preset-menu",style:{background:"rgba(0,0,0,0.7)",color:"#fff",borderRadius:"4px",fontSize:"14px",minWidth:"120px",overflow:"hidden",cursor:"pointer",position:"relative",boxShadow:Di[B]?"0 2px 8px rgba(0,0,0,0.3)":void 0,pointerEvents:"auto"},onClick:se=>se.stopPropagation(),children:[Re.jsxs("div",{style:{padding:"6px 12px",fontWeight:"bold",userSelect:"none"},onClick:se=>{se.stopPropagation(),Ms(ge=>{const pe=[...ge];return pe[B]=!pe[B],pe})},children:["Presets (",((pa=fn[B])==null?void 0:pa.modality)||"Unknown",")",Re.jsx("span",{style:{float:"right",fontWeight:"normal"},children:Di[B]?"▲":"▼"})]}),Di[B]&&Re.jsx("div",{className:"preset-menu-content",style:{background:"rgba(0,0,0,0.95)",borderRadius:"0 0 4px 4px",padding:"6px 0 6px 0",display:"flex",flexDirection:"column",zIndex:111,pointerEvents:"auto"},onClick:se=>se.stopPropagation(),children:(()=>{var pe;const se=a7((pe=fn[B])==null?void 0:pe.modality);let ge=0;return se.map(de=>{let Ve="";return de.action==="reset"?Ve="0":de.action==="preset"&&(ge+=1,Ve=String(ge)),Re.jsxs("button",{title:Ve?`Shortcut: ${Ve}`:void 0,style:{display:"block",width:"100%",margin:"2px 0",background:de.action==="preset"?"#333":"#444",color:"#fff",border:"none",borderRadius:"3px",cursor:"pointer",padding:de.action==="preset"?"4px 0":"6px 0",fontSize:"13px",opacity:.9,fontWeight:de.action==="preset"?"normal":"600"},onClick:Me=>{Me.stopPropagation(),ga(B,de),Ms(nt=>{const dt=[...nt];return dt[B]=!1,dt})},children:[de.name,Ve?` (${Ve})`:""]},de.name)})})()})]})}),Ce&&(Sn[B]||(dr[B]||[]).length>1||((Zf=fn[B])==null?void 0:Zf.frameIndex)&&((Au=fn[B])==null?void 0:Au.totalFrames))&&Re.jsxs("div",{style:{position:"absolute",left:"50%",bottom:8,transform:"translateX(-50%)",zIndex:36,background:"rgba(15,15,15,0.82)",border:"1px solid rgba(255,255,255,0.18)",borderRadius:8,padding:"6px 10px",display:"flex",alignItems:"center",gap:8,pointerEvents:"auto",minWidth:200,maxWidth:"72%"},onClick:se=>se.stopPropagation(),children:[Sn[B]&&Ce&&Re.jsxs(Re.Fragment,{children:[Re.jsx("button",{style:{background:Nn[B]?"#d32f2f":"#2e7d32",color:"#fff",border:"none",borderRadius:4,fontSize:12,padding:"4px 8px",cursor:"pointer"},title:Nn[B]?"Pause cine":"Play cine",onClick:()=>{Ai(se=>{const ge=[...se];return ge[B]=!ge[B],ge})},children:Nn[B]?"Pause":"Play"}),Re.jsxs("label",{style:{color:"#ddd",fontSize:11,display:"flex",alignItems:"center",gap:4},children:["FPS",Re.jsx("input",{type:"range",min:1,max:30,step:1,value:Math.max(1,Math.min(30,Math.round(cn[B]||12))),onChange:se=>{const ge=Number(se.target.value);Jn(pe=>{const de=[...pe];return de[B]=ge,de})}}),Re.jsx("span",{style:{minWidth:22,textAlign:"right"},children:Math.round(cn[B]||12)})]})]}),((xg=fn[B])==null?void 0:xg.frameIndex)&&((Cg=fn[B])==null?void 0:Cg.totalFrames)&&((z8=fn[B])==null?void 0:z8.totalFrames)>1&&Re.jsxs(Re.Fragment,{children:[Re.jsx("span",{style:{color:"#fff",fontSize:12,whiteSpace:"nowrap"},children:"Frame"}),Re.jsx("input",{type:"range",min:1,max:(($8=fn[B])==null?void 0:$8.totalFrames)||1,step:1,value:Math.max(1,Math.min(((j8=fn[B])==null?void 0:j8.totalFrames)||1,((H8=fn[B])==null?void 0:H8.frameIndex)||1)),onChange:se=>{var Ve;const ge=Number(se.target.value),de=(Yt[B]||[]).findIndex(Me=>{const nt=Me.match(/&frame=(\d+)/);return nt&&parseInt(nt[1],10)===ge});if(de>=0){const Me=(Ve=ae.current)==null?void 0:Ve.getViewport(`CT_${B}`);Me&&typeof To=="function"&&To(Me.element,{imageIndex:de})}},style:{width:100}}),Re.jsxs("span",{style:{color:"#e0e0e0",fontSize:11,minWidth:50,textAlign:"right"},children:[(K8=fn[B])==null?void 0:K8.frameIndex," / ",(q8=fn[B])==null?void 0:q8.totalFrames]})]}),(dr[B]||[]).length>1&&Re.jsxs(Re.Fragment,{children:[Re.jsx("span",{style:{color:"#fff",fontSize:12,whiteSpace:"nowrap"},children:"Group"}),Re.jsx("input",{type:"range",min:0,max:Math.max(0,(dr[B]||[]).length-1),step:1,value:Math.max(0,Math.min((dr[B]||[]).length-1,Et[B]||0)),onChange:se=>{dc(B,Number(se.target.value))},style:{width:140}}),Re.jsx("span",{style:{color:"#e0e0e0",fontSize:11,maxWidth:180,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:((Y8=(X8=dr[B])==null?void 0:X8[Et[B]||0])==null?void 0:Y8.label)||"Group",children:((Z8=(J8=dr[B])==null?void 0:J8[Et[B]||0])==null?void 0:Z8.label)||"Group"})]})]}),dn[B]==="stack"&&Yt[B]&&Re.jsx("div",{style:{position:"absolute",top:"10%",right:8,width:"14px",height:"80%",maxHeight:"100%",minHeight:0,zIndex:35,display:Yt[B].length>0?"flex":"none",alignItems:"flex-start",justifyContent:"center",pointerEvents:"auto",flexDirection:"column",padding:0},children:(()=>{const se=Yt[B]||[],ge=se.length;if(ge===0)return null;const pe=ae.current,de=pe==null?void 0:pe.getViewport(`CT_${B}`),Ve=de&&typeof de.getCurrentImageIdIndex=="function"?de.getCurrentImageIdIndex():-1,Me=new Set(se.map((qe,Tt)=>rs[qe]?Tt:-1).filter(qe=>qe>=0)),nt=se.map(qe=>qe.startsWith("external:")?!0:!!xt("imagePlaneModule",qe)||!!xt("generalSeriesModule",qe)),dt=nt.reduce((qe,Tt)=>qe+(Tt?1:0),0),et=se.reduce((qe,Tt,Lt)=>qe+(Me.has(Lt)?1:0),0),gt=Math.min(ge,180),ut=Array.from({length:gt},()=>({loaded:!1,viewed:!1,current:!1}));for(let qe=0;qe{var Gt;const Lt=qe.currentTarget.getBoundingClientRect(),st=Math.min(Lt.height,Math.max(0,qe.clientY-Lt.top)),Rt=Lt.height>0?st/Lt.height:0,Nt=Math.min(ge-1,Math.max(0,Math.round(Rt*(ge-1)))),Mt=(Gt=ae.current)==null?void 0:Gt.getViewport(`CT_${B}`);Mt&&typeof Mt.setImageIdIndex=="function"&&dn[B]==="stack"&&(To(Mt.element,{imageIndex:Nt}),br(B,Mt))},children:[ut.map((qe,Tt)=>{let Lt="#3f3f3f";return qe.loaded&&(Lt="#2e7d32"),qe.viewed&&(Lt="#1565c0"),qe.current&&(Lt="#fbc02d"),Re.jsx("div",{style:{width:"100%",height:`${100/gt}%`,minHeight:1,background:Lt,opacity:qe.loaded||qe.viewed||qe.current?.95:.45,borderBottom:Tt=0&&ge>gt&&Re.jsx("div",{style:{position:"absolute",left:0,right:0,top:`${Ve/Math.max(1,ge-1)*100}%`,height:2,background:"#ffeb3b",boxShadow:"0 0 4px #ffeb3b",transform:"translateY(-1px)",pointerEvents:"none"}})]})})()}),dn[B]==="volume"&&(()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);let pe=0,de=0;return ge&&typeof ge.getNumberOfSlices=="function"&&typeof ge.getSliceIndex=="function"&&(pe=ge.getNumberOfSlices(),de=ge.getSliceIndex()),pe>1?Re.jsx("div",{style:{position:"absolute",top:"10%",right:8,width:"12px",height:"80%",maxHeight:"100%",minHeight:0,zIndex:30,display:"flex",alignItems:"flex-start",justifyContent:"center",pointerEvents:"auto",flexDirection:"column",padding:0},children:Re.jsx("div",{style:{width:"8px",height:"100%",maxHeight:"100%",minHeight:0,borderRadius:"6px",background:"#222",position:"relative",display:"flex",flexDirection:"column",justifyContent:"flex-start",boxShadow:"0 0 8px #2196f3cc",overflow:"hidden",cursor:"pointer"},onClick:Ve=>{const nt=Ve.currentTarget.getBoundingClientRect(),dt=Ve.clientY-nt.top,et=Math.floor(dt/nt.height*pe),gt=ae.current,ut=gt==null?void 0:gt.getViewport(`CT_${B}`);ut&&(To(ut.element,{imageIndex:et}),ut.render(),br(B,ut))},children:Array.from({length:pe}).map((Ve,Me)=>{const nt=Me===de;return Re.jsx("div",{style:{width:"100%",height:`${100/pe}%`,minHeight:nt?1:0,background:nt?"linear-gradient(to right, #ffeb3b 60%, #ff9800 100%)":"#444",opacity:nt?.95:.4,transition:"background 0.3s, opacity 0.3s",borderBottom:Me1||!Yt[B]||Yt[B].length===0)&&Re.jsx("div",{style:{position:"absolute",left:0,right:0,bottom:Ce&&(Sn[B]||(dr[B]||[]).length>1)?56:8,zIndex:20,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"auto",width:"100%",background:"none",borderRadius:"0",padding:0},children:Re.jsxs("div",{style:{position:"relative"},children:[Re.jsxs("button",{onClick:se=>{se.stopPropagation(),oe(ge=>ge===B?null:B)},style:{padding:"6px 12px",background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",cursor:"pointer",pointerEvents:"auto",fontSize:13},title:"Choose stack",children:[(()=>{const se=Array.isArray(En)?En[B]:void 0,ge=typeof se=="number"&&_t[se]?_t[se]:void 0,pe=ge&&Array.isArray(ge.imageIds)?ge.imageIds:[],de=ge?ge.name||(ge.caseId?`Case: ${ge.caseId}`:void 0):void 0;if(de)return de;if(pe.length>0)return`Stack ${typeof se=="number"?se+1:"1"}`;const Ve=Yt[B]||[];return Ve.length>0?`Stack (${Ve.length} images)`:"No stack"})(),Re.jsx("span",{style:{marginLeft:8,opacity:.8},children:Q===B?"▲":"▼"})]}),Q===B&&Re.jsx("div",{ref:se=>{se&&se.focus()},tabIndex:0,style:{position:"absolute",left:0,bottom:"110%",background:"#222",border:"1px solid #444",borderRadius:"4px",boxShadow:"0 2px 8px rgba(0,0,0,0.3)",zIndex:100,minWidth:220,maxHeight:260,overflowY:"auto",overscrollBehavior:"contain",scrollbarWidth:"thin",padding:6},role:"listbox",onMouseDown:se=>se.stopPropagation(),onWheel:se=>{var pe;try{se.stopPropagation()}catch{}try{se.preventDefault()}catch{}const ge=se.currentTarget;if(ge){const de=se.deltaY??((pe=se.nativeEvent)==null?void 0:pe.deltaY)??0;ge.scrollTop+=de}},onBlur:se=>{const ge=se.currentTarget;setTimeout(()=>{if(!ge){oe(null);return}ge.contains(document.activeElement)||oe(null)},0)},children:(()=>{const se={};return _t.forEach((ge,pe)=>{const de=ge.studyId||ge.studyInstanceUID||"Unspecified";se[de]||(se[de]=[]),se[de].push({idx:pe,stack:ge})}),Object.keys(se).map(ge=>Re.jsxs("div",{style:{marginBottom:6},children:[Re.jsx("div",{style:{fontSize:12,color:"#aaa",padding:"4px 8px",fontWeight:700},children:ge==="Unspecified"?"Unspecified study":`Study: ${ge}`}),Re.jsx("div",{children:se[ge].map(({idx:pe,stack:de})=>{const Ve=Array.isArray(de.imageIds)?de.imageIds:[],Me=de&&(de.name||de.caseId)?de.name||`Case: ${de.caseId}`:`Stack ${pe+1}`,nt=Ve.length,dt=!Array.isArray(Ve)||nt===0;return Re.jsxs("button",{role:"option","aria-selected":!1,title:dt?"Invalid stack descriptor":`${Me} — ${nt} image${nt===1?"":"s"}${de!=null&&de.caseId?` — case ${de.caseId}`:""}`,style:{display:"flex",flexDirection:"column",alignItems:"flex-start",width:"100%",padding:"8px 12px",background:"transparent",color:"#fff",border:"none",textAlign:"left",cursor:dt?"not-allowed":"pointer"},onClick:et=>{if(et.stopPropagation(),dt){kt.warn(`Attempted to select invalid stack at index ${pe}`,de);return}Vi(B,pe).catch(gt=>kt.error("Failed to load stack:",gt)),oe(null)},children:[Re.jsx("div",{style:{fontWeight:"600",fontSize:13},children:Me}),Re.jsxs("div",{style:{fontSize:12,opacity:.7},children:[nt," image",nt===1?"":"s",de!=null&&de.caseId?` • case ${de.caseId}`:""]})]},pe)})})]},ge))})()})]})})]},B))}const Pt=[bf.toolName,gu.toolName,Ec.toolName,gl.toolName],nn=[{rows:1,cols:1},{rows:1,cols:2},{rows:2,cols:2}],Ht=Se&&Ue;return Re.jsxs("div",{ref:a,style:{position:"relative",inset:0,width:"100%",height:"100%",boxSizing:"border-box",background:Ht?"#000":"#222",padding:Ht?"0px":Se?"6px":"12px",overflow:"hidden"},children:[ji&&ji!=="displayset"&&Re.jsx("div",{style:{position:"absolute",zIndex:3e3,top:0,left:0,width:"100%",height:"100%",background:"rgba(0,0,0,0.7)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:28,fontWeight:"bold",letterSpacing:1},children:ji==="annotations"?"Loading Annotations...":"Loading Viewer State..."}),Po&&Re.jsxs("div",{style:{position:"fixed",top:12,left:12,right:12,zIndex:1e4,background:"#fff3cd",color:"#856404",border:"1px solid #ffeeba",padding:"10px 14px",borderRadius:6,display:"flex",alignItems:"center",justifyContent:"space-between",gap:12},children:[Re.jsxs("div",{style:{flex:1,fontSize:14},children:[Re.jsx("strong",{children:"Graphics error:"})," The viewer encountered a WebGL/graphics error and may be unstable. Please reload the page.",Zs?Re.jsx("div",{style:{marginTop:6,fontSize:12,color:"#6b4f00"},children:Zs}):null]}),Re.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[Re.jsx("button",{onClick:()=>window.location.reload(),style:{padding:"6px 10px"},children:"Reload"}),Re.jsx("button",{onClick:()=>ki(!1),style:{padding:"6px 10px"},children:"Dismiss"})]})]}),!T&&!Ht&&Re.jsx("button",{onClick:()=>E(!0),"aria-pressed":!1,title:"Open stacks",style:{position:"absolute",right:8,top:76,zIndex:120,width:24,height:42,background:"#1976d2",color:"#fff",border:"none",borderRadius:5,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 2px 8px rgba(0,0,0,0.3)",pointerEvents:"auto"},children:"▶"}),Ht&&Re.jsx("button",{onClick:()=>{Pe(!1),O(null),z(!1),E(!1),ee(null);const B=a.current;B&&document.fullscreenElement===B&&document.exitFullscreen&&document.exitFullscreen().catch(()=>{})},style:{position:"absolute",top:10,left:10,zIndex:3500,background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:"Exit Viewer"}),Ht&&Re.jsxs("div",{style:{position:"absolute",top:10,right:10,zIndex:3500,display:"flex",gap:8},children:[Re.jsx("button",{onClick:()=>E(B=>!B),style:{background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:"Stacks"}),Re.jsx("button",{onClick:()=>{j?z(!1):(z(!0),O(je??0))},style:{background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:j?"Grid":"Focus"}),Re.jsx("button",{onClick:()=>{Ra(B=>{const ue=nn.findIndex(Ce=>Ce.rows===B.rows&&Ce.cols===B.cols);return nn[(ue+1+nn.length)%nn.length]})},style:{background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:"Layout"})]}),ke&&Re.jsxs("div",{style:{position:"fixed",left:ke.x+14,top:ke.y-18,zIndex:5e3,background:"rgba(21,101,192,0.92)",color:"#fff",border:"1px solid rgba(255,255,255,0.35)",borderRadius:8,padding:"5px 8px",fontSize:11,fontWeight:700,pointerEvents:"none",whiteSpace:"nowrap"},children:["Drop on viewport ",ke.targetViewportIdx!==null?ke.targetViewportIdx+1:"-"," (",ke.zone,")"]}),!Ht&&Re.jsxs("div",{children:[Re.jsx("button",{style:{position:"absolute",top:"50%",transform:"translateY(-50%)",left:cc,zIndex:200,width:W,height:W,background:"#222",color:"#fff",border:"none",borderRadius:"50%",fontWeight:"bold",cursor:"pointer",fontSize:"22px",boxShadow:"0 2px 8px rgba(0,0,0,0.2)",transition:"left 0.25s cubic-bezier(.4,2,.6,1), background 0.2s"},onClick:()=>Rs(B=>!B),"aria-label":"Open menu",children:"☰"}),ac&&Re.jsx("div",{style:{position:"absolute",top:0,left:0,width:V,height:"100%",background:"#222",color:"#fff",zIndex:199,boxShadow:"2px 0 12px rgba(0,0,0,0.3)",flexDirection:"column",padding:"24px 16px 16px 16px",display:"flex",overflow:"hidden"},children:Re.jsxs("div",{style:{flex:1,minHeight:0,overflowY:"auto",display:"flex",flexDirection:"column"},children:[Re.jsxs("div",{style:{fontWeight:"bold",fontSize:18,marginBottom:24},children:["Menu",Re.jsx("button",{style:{float:"right",background:"transparent",color:"#fff",border:"none",fontSize:"22px",cursor:"pointer"},onClick:()=>Rs(!1),"aria-label":"Close menu",children:"×"})]}),Re.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",marginBottom:8},children:[Re.jsxs("label",{style:{fontSize:13},children:[Re.jsx("input",{type:"radio",name:"folderLoadMode",value:"add",checked:sc==="add",onChange:()=>Ls("add")})," Add (append)"]}),Re.jsxs("label",{style:{fontSize:13},children:[Re.jsx("input",{type:"radio",name:"folderLoadMode",value:"replace",checked:sc==="replace",onChange:()=>Ls("replace")})," Replace all"]})]}),Re.jsx("button",{style:{padding:"10px 18px",background:"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:Yc,children:"Load DICOM Folder"}),Re.jsx("input",{ref:da,type:"file",style:{display:"none"},multiple:!0,onChange:ss}),Re.jsx("input",{ref:As,type:"file",style:{display:"none"},multiple:!0,onChange:ss,accept:".dcm,application/dicom"}),Re.jsxs("div",{style:{marginBottom:"18px",display:"flex",alignItems:"center",gap:"8px"},children:[Re.jsx("input",{type:"checkbox",id:"orderBySliceLocation",checked:Aa,onChange:B=>la(B.target.checked),style:{accentColor:"#666"}}),Re.jsx("label",{htmlFor:"orderBySliceLocation",style:{fontSize:"15px",cursor:"pointer"},children:"Order by Slice Location"})]}),Re.jsx("button",{style:{padding:"10px 18px",background:"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:Gl,children:"Show DICOM Metadata"}),Re.jsxs("button",{style:{padding:"10px 18px",background:Za?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Ro(B=>!B),children:[Za?"Disable":"Enable"," Cross Reference Lines"]}),Re.jsxs("button",{style:{padding:"10px 18px",background:zo?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Qa(B=>!B),children:[zo?"Disable":"Enable"," Reference Lines"]}),Re.jsx("button",{onClick:ec,style:{margin:8,padding:8},children:"Sort All Viewports by Slice Location"}),Re.jsx("button",{style:{padding:"10px 18px",background:Ho?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Yr(B=>!B),children:Ho?"Disable Alt Key for Reference Cursors (Shift always works)":"Enable Alt Key for Reference Cursors (Shift always works)"}),Re.jsxs("button",{style:{padding:"10px 18px",background:tt?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>le(B=>!B),children:[tt?"Hide":"Show"," Annotation Navigation"]}),Re.jsxs("button",{style:{padding:"10px 18px",background:Ot?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Vt(B=>!B),children:[Ot?"Disable":"Enable"," Volume Diagnostics"]})]})})]}),!Ht&&Re.jsxs("div",{ref:k,className:"grid-menu-hover-container",style:{position:"absolute",top:La||ve?8:-18,left:"50%",transform:"translateX(-50%)",zIndex:100,display:"flex",flexDirection:"row",alignItems:"flex-start",gap:8,width:"auto",pointerEvents:"auto",transition:"top 180ms ease",paddingTop:28,marginTop:-28,paddingBottom:12},onMouseEnter:()=>fe(!0),onMouseLeave:()=>{La||fe(!1)},children:[Re.jsxs("button",{style:{height:40,padding:"6px 12px 6px 10px",background:"#222",color:"#fff",border:"none",borderRadius:"0 0 4px 4px",fontWeight:"bold",cursor:"pointer",fontSize:"14px",boxShadow:"0 2px 8px rgba(0,0,0,0.2)",display:"inline-flex",alignItems:"center",gap:8},title:"Toggle viewer fullscreen",onFocus:()=>fe(!0),onClick:()=>{fe(!0),Zc()},children:[Re.jsx("span",{style:{fontSize:16,lineHeight:1},children:"⛶"}),Re.jsx("span",{children:"Fullscreen"})]}),Re.jsxs("div",{style:{position:"relative",display:"flex",flexDirection:"column",alignItems:"stretch"},children:[Re.jsxs("button",{className:"grid-menu-btn",style:{height:40,padding:"6px 14px 6px 10px",background:"#222",color:"#fff",border:"none",borderRadius:"0 0 4px 4px",fontWeight:"bold",cursor:"pointer",fontSize:"14px",boxShadow:"0 2px 8px rgba(0,0,0,0.2)",display:"inline-flex",alignItems:"center",gap:10,justifyContent:"space-between",minWidth:136},onFocus:()=>fe(!0),onClick:()=>{fe(!0),Fi(B=>!B)},tabIndex:0,children:[Re.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:8},children:[Re.jsx("span",{style:{display:"grid",gridTemplateColumns:`repeat(${tn.cols}, 5px)`,gridTemplateRows:`repeat(${tn.rows}, 5px)`,gap:2,padding:1},children:Array.from({length:tn.rows*tn.cols}).map((B,ue)=>Re.jsx("span",{style:{width:5,height:5,borderRadius:1,background:"#90caf9",display:"block"}},ue))}),Re.jsxs("span",{children:[tn.rows,"x",tn.cols]})]}),Re.jsx("span",{style:{opacity:.8},children:La?"▲":"▼"})]}),La&&Re.jsx("div",{style:{position:"absolute",top:"calc(100% + 8px)",right:0,background:"#222",color:"#fff",borderRadius:"6px",boxShadow:"0 2px 12px rgba(0,0,0,0.4)",padding:"12px",display:"grid",gridTemplateColumns:"repeat(3, minmax(68px, 1fr))",gap:"8px",zIndex:200,pointerEvents:"auto"},onMouseDown:B=>B.stopPropagation(),children:Os.map(B=>Re.jsxs("button",{style:{minWidth:"68px",height:"54px",background:B.rows===tn.rows&&B.cols===tn.cols?"#444":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"13px",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:6},onClick:()=>{lc(),Ra({rows:B.rows,cols:B.cols}),Fi(!1),fe(!1)},children:[Re.jsx("span",{style:{display:"grid",gridTemplateColumns:`repeat(${B.cols}, 6px)`,gridTemplateRows:`repeat(${B.rows}, 6px)`,gap:2},children:Array.from({length:B.rows*B.cols}).map((ue,Te)=>Re.jsx("span",{style:{width:6,height:6,borderRadius:1,background:"#90caf9",display:"block"}},Te))}),Re.jsxs("span",{children:[B.rows,"x",B.cols]})]},`${B.rows}x${B.cols}`))})]})]}),Re.jsxs("div",{style:{display:"flex",flexDirection:"row",height:Ht?"100%":"calc(100% - 48px)",gap:Ht?0:8},children:[Re.jsxs("div",{style:{flex:1,display:"grid",margin:Ht?0:3,gridTemplateRows:`repeat(${tn.rows}, 1fr)`,gridTemplateColumns:`repeat(${tn.cols}, 1fr)`,gap:"5px",minHeight:0,minWidth:0,zIndex:1,position:"relative"},children:[yt,!Ht&&Re.jsx("button",{style:{position:"absolute",top:8,right:8,zIndex:2600,padding:"6px 12px",background:"#222",color:"#fff",border:"none",borderRadius:"4px",cursor:"pointer",opacity:.85,userSelect:"none"},onClick:()=>_(!0),children:"Settings"}),Ht&&Re.jsx("div",{style:{position:"absolute",left:0,right:0,bottom:10,zIndex:3200,display:"flex",justifyContent:"center",pointerEvents:"none"},children:Re.jsx("div",{style:{pointerEvents:"auto",display:"flex",alignItems:"center",gap:6,background:"rgba(0,0,0,0.74)",border:"1px solid rgba(255,255,255,0.2)",borderRadius:10,padding:"8px 8px",maxWidth:"95%",overflowX:"auto"},children:Pt.map(B=>{var Ce;const ue=mr.Primary===B,Te=((Ce=md.find(me=>me.value===B))==null?void 0:Ce.label)||B;return Re.jsx("button",{title:Te,onClick:()=>Wl("Primary",B),style:{minWidth:46,height:42,borderRadius:8,border:ue?"1px solid #90caf9":"1px solid rgba(255,255,255,0.22)",background:ue?"#1565c0":"#1f1f1f",color:"#fff",fontSize:18,fontWeight:700,padding:"0 8px"},children:u7(B)},B)})})})]}),Re.jsxs("div",{style:Ht?{position:"absolute",left:8,right:8,bottom:T?62:-420,height:"min(48vh, 420px)",transition:"bottom 220ms ease",display:"flex",flexDirection:"column",pointerEvents:T?"auto":"none",overflow:"hidden",zIndex:3450,borderRadius:12,border:"1px solid #2f3336",boxShadow:"0 6px 24px rgba(0,0,0,0.45)",background:"#1f2428"}:{width:T?b:0,transition:"width 220ms ease",display:"flex",flexDirection:"column",pointerEvents:T?"auto":"none",overflow:"hidden",position:"relative"},children:[T&&!Ht&&Re.jsx("div",{onMouseDown:qc,title:"Resize stacks panel",style:{position:"absolute",left:0,top:0,width:8,height:"100%",cursor:"col-resize",zIndex:2800,background:"linear-gradient(to right, rgba(100,181,246,0.25), rgba(100,181,246,0))"}}),Re.jsx("div",{style:{pointerEvents:"auto",width:"100%",height:"100%"},children:Re.jsxs("div",{style:{height:"100%",width:"100%",background:"#1f2428",color:"#fff",boxShadow:"0 2px 14px rgba(0,0,0,0.45)",borderLeft:"1px solid #2f3336",transform:"translateX(0)",transition:"transform 220ms ease",display:"flex",flexDirection:"column",overflow:"hidden"},children:[Re.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 12px",borderBottom:"1px solid #2b2f31"},children:[Re.jsx("div",{style:{fontWeight:700},children:"Stacks"}),Re.jsxs("div",{style:{fontSize:12,color:"#9bb4c8"},children:["Active VP: ",je!==null?je+1:"-"]}),Re.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[Ht&&Re.jsxs("button",{title:"Toggle stack drop mode",onClick:()=>{Oe(B=>B==="center"?"right":B==="right"?"bottom":"center")},style:{background:"transparent",color:"#90caf9",border:"1px solid #335",borderRadius:6,padding:"4px 8px",cursor:"pointer",fontSize:12},children:["Drop: ",ie]}),Re.jsx("button",{title:"Close",onClick:()=>{E(!1)},style:{background:"transparent",color:"#fff",border:"none",cursor:"pointer",fontSize:16},children:"×"})]})]}),Re.jsx("div",{style:{overflowY:"auto",padding:8,flex:1},children:_t.length===0?Re.jsx("div",{style:{color:"#999",padding:12},children:"No stacks available"}):Re.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6},children:_t.map((B,ue)=>{const Te=Array.isArray(B.imageIds)?B.imageIds:[],Ce=B.name||(B.caseId?`Case: ${B.caseId}`:`Stack ${ue+1}`),me=Te.length,we=!Array.isArray(Te)||me===0,se=En.includes(ue),ge=je!==null&&En[je]===ue,pe=Math.floor(Te.length/2);return Te[pe]||Te[0],Re.jsxs("div",{draggable:!we,onDragStart:de=>{we||(Dt(ue),sn(null),de.dataTransfer.setData("text/stack-idx",String(ue)),de.dataTransfer.effectAllowed="copy")},onDragEnd:()=>{Dt(null),sn(null)},onClick:()=>{if(Date.now(){if(we||no[ue]||io.current[ue])return;const de=Math.floor(Te.length/2),Ve=Te[de]||Te[0]||null;Ve&&qr(ue,Ve)},onMouseEnter:()=>{if(we||no[ue]||io.current[ue])return;const de=Math.floor(Te.length/2),Ve=Te[de]||Te[0]||null;Ve&&qr(ue,Ve)},style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 10px",background:ge?"#0d47a1":se?"#1976d2":"transparent",color:se?"#fff":"#ddd",border:ge?"1px solid #64b5f6":"1px solid transparent",borderRadius:6,cursor:we?"not-allowed":"pointer"},children:[Re.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(()=>{const de=no[ue],Me=(de&&de!=="BROKEN"?de:null)||null;return Me?Re.jsx("img",{"data-thumb-stack":ue,src:Me,alt:Ce,style:{width:56,height:56,objectFit:"cover",borderRadius:4,background:"#111"},onError:()=>{kt.warn("Thumbnail failed to load for stack",ue,Me),bi(ue,"BROKEN")}}):Re.jsx("div",{style:{width:56,height:56,borderRadius:4,background:"#111",display:"flex",alignItems:"center",justifyContent:"center",color:"#777"},children:"No Img"})})(),Re.jsxs("div",{style:{display:"flex",flexDirection:"column"},children:[Re.jsx("div",{style:{fontWeight:600},children:Ce}),Re.jsxs("div",{style:{fontSize:12,opacity:.7},children:[me," img",me===1?"":"s"]})]})]}),Re.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:4},children:[Re.jsx("div",{style:{fontSize:12,opacity:.8},children:B.studyId||""}),ge&&Re.jsx("div",{style:{fontSize:11,color:"#bbdefb",fontWeight:700},children:"ACTIVE"}),Ht&&!we&&Re.jsxs("div",{style:{display:"flex",gap:6},children:[Re.jsx("button",{onClick:de=>{de.stopPropagation(),Vi(je??0,ue),E(!1)},style:{background:"#1565c0",color:"#fff",border:"none",borderRadius:4,padding:"3px 7px",fontSize:11,cursor:"pointer"},children:"Load"}),Re.jsx("button",{onClick:de=>{de.stopPropagation(),!(Date.now(){fc(ue,de)},style:{background:q===ue?"#2e7d32":"#444",color:"#fff",border:"none",borderRadius:4,padding:"3px 7px",fontSize:11,cursor:"pointer"},children:q===ue?"Armed":"Drag"})]})]})]},ue)})})})]})})]})]}),S&&Re.jsx("div",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",background:"rgba(0,0,0,0.4)",zIndex:1e3,display:"flex",alignItems:"flex-start",justifyContent:"center",overflowY:"auto",padding:"16px 12px"},onClick:()=>_(!1),children:Re.jsxs("div",{style:{background:"#222",color:"#fff",borderRadius:"8px",minWidth:"320px",minHeight:"180px",maxWidth:"min(960px, 96vw)",maxHeight:"calc(100vh - 32px)",padding:"24px",boxShadow:"0 4px 24px rgba(0,0,0,0.4)",position:"relative",overflowY:"auto",margin:"0 auto"},onClick:B=>B.stopPropagation(),children:[Re.jsx("div",{style:{fontSize:"20px",marginBottom:"16px"},children:"Settings"}),Re.jsxs("div",{style:{marginBottom:"24px"},children:[Re.jsx("div",{style:{marginBottom:12,fontWeight:"bold"},children:"Mouse Button Tool Bindings"}),h7.map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label," Button:"]}),Re.jsx("select",{value:mr[B.value],onChange:ue=>so(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))})]},B.value)),Re.jsxs("div",{style:{margin:"12px 0"},children:[Re.jsxs("button",{style:{background:"#333",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 12px",cursor:"pointer",fontSize:"14px",marginBottom:"8px"},onClick:()=>Qs(B=>!B),children:[wo?"Hide":"Show"," Advanced Mouse Bindings"]}),wo&&Re.jsx("div",{style:{marginTop:8},children:q2.slice(3).map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label,":"]}),Re.jsxs("select",{value:mr[B.value]||"",onChange:ue=>so(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:[Re.jsx("option",{value:"",children:"(None)"}),md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))]})]},B.value))})]}),Re.jsx("div",{style:{margin:"18px 0 8px 0",fontWeight:"bold"},children:"Ctrl + Mouse Button Tool Bindings"}),h7.map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label," + Ctrl:"]}),Re.jsxs("select",{value:No[B.value]||"",onChange:ue=>fa(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:[Re.jsx("option",{value:"",children:"(None)"}),md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))]})]},B.value+"_ctrl")),Re.jsxs("div",{style:{margin:"12px 0"},children:[Re.jsxs("button",{style:{background:"#333",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 12px",cursor:"pointer",fontSize:"14px",marginBottom:"8px"},onClick:()=>$o(B=>!B),children:[Pa?"Hide":"Show"," Advanced Ctrl + Mouse Bindings"]}),Pa&&Re.jsx("div",{style:{marginTop:8},children:q2.slice(3).map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label," + Ctrl:"]}),Re.jsxs("select",{value:No[B.value]||"",onChange:ue=>fa(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:[Re.jsx("option",{value:"",children:"(None)"}),md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))]})]},B.value+"_ctrl"))})]})]}),Re.jsxs("div",{style:{marginTop:8,paddingTop:16,borderTop:"1px solid #333"},children:[Re.jsx("div",{style:{marginBottom:10,fontWeight:"bold"},children:"Stack Grouping"}),Re.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,cursor:"pointer",marginBottom:10},children:[Re.jsx("input",{type:"checkbox",checked:m,onChange:B=>w(B.target.checked)}),"Enable advanced DWI/time/echo grouping"]}),Re.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6,opacity:m?1:.6},children:mp.map(B=>Re.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,cursor:m?"pointer":"default"},title:B.description,children:[Re.jsx("input",{type:"checkbox",disabled:!m,checked:!!x[B.id],onChange:ue=>{const Te=ue.target.checked;C(Ce=>({...Ce,[B.id]:Te}))}}),B.label]},B.id))})]}),Re.jsxs("div",{style:{marginTop:8,paddingTop:16,borderTop:"1px solid #333"},children:[Re.jsx("div",{style:{marginBottom:10,fontWeight:"bold"},children:"Logging"}),Re.jsxs("div",{style:{display:"flex",alignItems:"center",gap:16,marginBottom:10,flexWrap:"wrap"},children:[Re.jsxs("div",{children:[Re.jsx("label",{style:{marginRight:8},children:"Level:"}),Re.jsx("select",{value:g,onChange:B=>p(S5(B.target.value)),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:kSe.map(B=>Re.jsx("option",{value:B.value,children:B.label},B.value))})]}),Re.jsxs("div",{children:[Re.jsx("label",{style:{marginRight:8},children:"Format:"}),Re.jsx("select",{value:v,onChange:B=>y(jp(B.target.value)),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:NSe.map(B=>Re.jsx("option",{value:B.value,children:B.label},B.value))})]})]})]}),Re.jsx("button",{style:{position:"absolute",top:12,right:12,background:"transparent",color:"#fff",border:"none",fontSize:"20px",cursor:"pointer"},onClick:()=>_(!1),"aria-label":"Close",children:"×"})]})}),is&&Re.jsx("div",{style:{position:"fixed",top:0,left:0,width:"100vw",height:"100vh",background:"rgba(0,0,0,0.5)",zIndex:2e3,display:"flex",alignItems:"center",justifyContent:"center"},onClick:()=>os(!1),children:Re.jsxs("div",{style:{background:"#222",color:"#fff",borderRadius:"8px",minWidth:"320px",maxWidth:"80vw",maxHeight:"80vh",padding:"24px",boxShadow:"0 4px 24px rgba(0,0,0,0.4)",position:"relative",overflow:"auto"},onClick:B=>B.stopPropagation(),children:[Re.jsx("div",{style:{fontSize:"20px",marginBottom:"16px"},children:"DICOM Metadata"}),rc,Re.jsx("button",{style:{position:"absolute",top:12,right:12,background:"transparent",color:"#fff",border:"none",fontSize:"20px",cursor:"pointer"},onClick:()=>os(!1),"aria-label":"Close",children:"×"})]})})]})}function USe(t){kt.debug("Setting up tools...",t),Yi(Ec),Yi(gu),Yi(bf),Yi(gl),Yi(Bh),Yi(Gf),Yi(Iu),Yi(Wf),Yi(Du),Yi(e0),Yi(Bf),Yi(Ll),Yi(Gh),Yi(gs),Yi(fl),Yi(Vd),Yi($h);let e=xi(t);return e||(e=$k(t),e.addTool(gu.toolName),e.addTool(Ec.toolName),e.addTool(gl.toolName),e.addTool(bf.toolName,{loop:!1}),e.addTool(Bh.toolName),e.addTool(Gf.toolName),e.addTool($h.toolName,{getTextCallback:()=>""}),e.addTool(Wf.toolName),e.addTool(Iu.toolName,{statsCalculator:()=>null}),e.addTool(Du.toolName,{calculateStats:!1,getTextCallback:()=>""}),e.addTool(e0.toolName,{getTextCallback:()=>""}),e.addTool(Bf.toolName,{calculateStats:!1}),e.addTool(Ll.toolName,{}),e.addTool(Gh.toolName,{}),e.addTool(Vd.toolName),e.addTool(gs.toolName)),e}function g7(t,e,r,n){if(!r.length||!e.length)return null;const i=r.map(o=>e.findIndex(a=>a===o.metadata.referencedImageId)).filter(o=>o!==-1).sort((o,a)=>o-a);if(!i.length)return null;if(n===1){for(let o of i)if(o>t)return o;return i[0]}else{for(let o=i.length-1;o>=0;o--)if(i[o]`wadouri:/test_images/stack2/IMG${r+1}.dcm`),Array.from({length:25},(e,r)=>`wadouri:/test_images/stack5/IMG${r+1}.dcm`),Array.from({length:26},(e,r)=>`wadouri:/test_images/stack3/IMG${r+1}.dcm`)]}const NC=new WeakMap,Hp=jW.child("main"),GSe=t=>{const e=t.trim();return!e||e.startsWith("external:")||e.startsWith("wadors:")?e:e.startsWith("wadouri:")?`wadouri:${e.slice(8).replace(/^:+/,"")}`:`wadouri:${e.replace(/^:+/,"")}`},Ym=t=>t.map(GSe),p7=t=>t?{imageIds:Ym(t)}:{imageIds:[]},WSe=t=>{if(!t)return[];if(Array.isArray(t)&&t.length>0&&typeof t[0]=="string")return[p7(t)];if(!Array.isArray(t))return[];const e=[];return t.forEach((r,n)=>{if(r&&typeof r=="object"&&Array.isArray(r.stacks)){const i=r.caseId||r.caseUID||r.case||void 0,o=r.studyId||r.studyUID||r.studyInstanceUID||void 0;r.stacks.forEach((a,s)=>{let c=[];if(Array.isArray(a)?c=a:Array.isArray(a.imageIds)?c=a.imageIds:Array.isArray(a.i)&&(c=a.i),!Array.isArray(c)||c.length===0||!c.every(l=>typeof l=="string")){Hp.warn(`data-named-stacks: skipping invalid nested stack at parsed[${n}].stacks[${s}]`,a);return}e.push({imageIds:Ym(c),name:a.name||a.label||void 0,caseId:i,studyId:a.studyId||o,series:Array.isArray(a.series)?a.series:void 0})});return}if(r&&typeof r=="object"&&(Array.isArray(r.imageIds)||Array.isArray(r.i))){const i=Array.isArray(r.imageIds)?r.imageIds:r.i;if(!Array.isArray(i)||i.length===0||!i.every(o=>typeof o=="string")){Hp.warn(`data-named-stacks: skipping invalid stack object at parsed[${n}]`,r);return}e.push({imageIds:Ym(i),name:r.name||r.label||void 0,caseId:r.caseId||r.caseUID||void 0,studyId:r.studyId||r.studyUID||r.studyInstanceUID||void 0,series:Array.isArray(r.series)?r.series:void 0});return}if(Array.isArray(r)&&r.length>0&&typeof r[0]=="string"){e.push(p7(r));return}Hp.warn(`data-named-stacks: unknown or invalid entry at parsed[${n}] - skipping`,r)}),e},zSe=t=>JSON.stringify({id:t.id||"",empty:t.getAttribute("data-empty")||"",namedStacks:t.getAttribute("data-named-stacks")||"",images:t.getAttribute("data-images")||"",autoCache:t.getAttribute("data-auto-cache-stack")||"",annotation:t.getAttribute("data-annotationjson")||"",viewerState:t.getAttribute("data-viewerstate")||""}),m7=(t,e)=>!(e!=null&&e.containerIds)||e.containerIds.length===0?!0:e.containerIds.includes(t.id||""),$Se=(t,e)=>{var s,c,l;const r=t.getAttribute("data-log-level"),n=t.getAttribute("data-log-debug"),i=t.getAttribute("data-log-format");let o;r!==null?o=S5(r):(s=e==null?void 0:e.logging)!=null&&s.minLevel?o=e.logging.minLevel:n!==null?o=f_(n):((c=e==null?void 0:e.logging)==null?void 0:c.debug)!==void 0?o=f_(e.logging.debug):o="warn";const a=jp(i??((l=e==null?void 0:e.logging)==null?void 0:l.format));return{minLevel:o,format:a}},v7=(t,e,r)=>{const n=zSe(t),i=NC.get(t),o=$Se(t,r);if(i&&!(r!=null&&r.force)&&i.signature===n)return;i&&(i.root.unmount(),NC.delete(t)),T8(o);const a=MM(t);a.render(Re.jsx(FSe,{container_id:t.id||"",imageStacks:e,autoCacheStack:t.getAttribute("data-auto-cache-stack")==="true"||t.getAttribute("data-auto-cache-stack")==="1",annotationJson:t.getAttribute("data-annotationjson")||void 0,viewerState:t.getAttribute("data-viewerstate")||void 0,initialLoggerConfig:o})),NC.set(t,{root:a,signature:n})};function E8(t){document.querySelectorAll(".dicom-viewer-test-root").forEach(n=>{if(!m7(n,t))return;v7(n,()=>BSe(),t)}),document.querySelectorAll(".dicom-viewer-root").forEach(n=>{if(!m7(n,t))return;let i;const o=n.getAttribute("data-empty")==="true",a=n.getAttribute("data-named-stacks"),s=n.getAttribute("data-images");if(o)i=()=>Promise.resolve([]);else if(a){let c;try{c=JSON.parse(a)}catch(f){Hp.error("Invalid data-named-stacks JSON:",f),c=[]}const l=WSe(c);i=()=>Promise.resolve(l)}else if(s){let c;try{c=JSON.parse(s)}catch(l){Hp.error("Invalid data-images JSON:",l),c=[]}Array.isArray(c)&&c.length>0&&typeof c[0]=="string"?i=()=>Promise.resolve([Ym(c)]):Array.isArray(c)?i=()=>Promise.resolve(c.map(l=>Array.isArray(l)?Ym(l):[])):i=()=>Promise.resolve([[]])}else i=()=>Promise.resolve([]);v7(n,i,t)})}E8();window.mountDicomViewers=E8;window.remountDicomViewer=t=>{E8({force:!0,containerIds:[t]})};window.setDicomViewerLogging=t=>{const e=t.minLevel?S5(t.minLevel):t.debug!==void 0?f_(t.debug):void 0;T8({minLevel:e,format:t.format?jp(t.format):void 0})};window.getDicomViewerLogging=()=>C5(); +`,Wt.push(It);var ar=Ms(Function,Wt).apply(null,Mn);return ar}function so($,K,R,U,X,he){T(K>0);var xe=Di(K,R);X=Cr(U,X),Ni([],[$],function(be){be=be[0];var Le="constructor "+be.name;if(be.registeredClass.constructor_body===void 0&&(be.registeredClass.constructor_body=[]),be.registeredClass.constructor_body[K-1]!==void 0)throw new Mo("Cannot register multiple constructors with identical number of parameters ("+(K-1)+") for class '"+be.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!");return be.registeredClass.constructor_body[K-1]=()=>{dn("Cannot construct "+be.name+" due to unbound types",xe)},Ni([],xe,function(Fe){return Fe.splice(1,0,null),be.registeredClass.constructor_body[K-1]=mr(Le,Fe,null,X,he),[]}),[]})}function No($,K,R,U,X,he,xe,be){var Le=Di(R,U);K=Tr(K),he=Cr(X,he),Ni([],[$],function(Fe){Fe=Fe[0];var He=Fe.name+"."+K;K.startsWith("@@")&&(K=Symbol[K.substring(2)]),be&&Fe.registeredClass.pureVirtualFunctions.push(K);function ft(){dn("Cannot call "+He+" due to unbound types",Le)}var It=Fe.registeredClass.instancePrototype,Jt=It[K];return Jt===void 0||Jt.overloadTable===void 0&&Jt.className!==Fe.name&&Jt.argCount===R-2?(ft.argCount=R-2,ft.className=Fe.name,It[K]=ft):(oo(It,K,He),It[K].overloadTable[R-2]=ft),Ni([],Le,function(Wt){var Mn=mr(He,Wt,Fe,he,xe);return It[K].overloadTable===void 0?(Mn.argCount=R-2,It[K]=Mn):It[K].overloadTable[R-2]=Mn,[]}),[]})}var fa=[],Jr=[{},{value:void 0},{value:null},{value:!0},{value:!1}];function nc($){$>4&&--Jr[$].refcount===0&&(Jr[$]=void 0,fa.push($))}function Ul(){for(var $=0,K=5;K($||Bn("Cannot use deleted val. handle = "+$),Jr[$].value),toHandle:$=>{switch($){case void 0:return 1;case null:return 2;case!0:return 3;case!1:return 4;default:{var K=fa.length?fa.pop():Jr.length;return Jr[K]={refcount:1,value:$},K}}}};function os($,K){K=Tr(K),fi($,{name:K,fromWireType:function(R){var U=is.toValue(R);return nc(R),U},toWireType:function(R,U){return is.toHandle(U)},argPackAdvance:8,readValueFromPointer:dr,destructorFunction:null})}function rc($){if($===null)return"null";var K=typeof $;return K==="object"||K==="array"||K==="function"?$.toString():""+$}function jc($,K){switch(K){case 2:return function(R){return this.fromWireType(Q[R>>2])};case 3:return function(R){return this.fromWireType(oe[R>>3])};default:throw new TypeError("Unknown float type: "+$)}}function ic($,K,R){var U=ro(R);K=Tr(K),fi($,{name:K,fromWireType:function(X){return X},toWireType:function(X,he){return he},argPackAdvance:8,readValueFromPointer:jc(K,U),destructorFunction:null})}function Bl($,K,R,U,X,he){var xe=Di(K,R);$=Tr($),X=Cr(U,X),di($,function(){dn("Cannot call "+$+" due to unbound types",xe)},K-1),Ni([],xe,function(be){var Le=[be[0],null].concat(be.slice(1));return rs($,mr($,Le,null,X,he),K-1),[]})}function Gl($,K,R){switch(K){case 0:return R?function(X){return V[X]}:function(X){return W[X]};case 1:return R?function(X){return A[X>>1]}:function(X){return k[X>>1]};case 2:return R?function(X){return F[X>>2]}:function(X){return H[X>>2]};default:throw new TypeError("Unknown integer type: "+$)}}function Hc($,K,R,U,X){K=Tr(K);var he=ro(R),xe=ft=>ft;if(U===0){var be=32-8*R;xe=ft=>ft<>>be}var Le=K.includes("unsigned"),Fe=(ft,It)=>{},He;Le?He=function(ft,It){return Fe(It,this.name),It>>>0}:He=function(ft,It){return Fe(It,this.name),It},fi($,{name:K,fromWireType:xe,toWireType:He,argPackAdvance:8,readValueFromPointer:Gl(K,he,U!==0),destructorFunction:null})}function oc($,K,R){var U=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],X=U[K];function he(xe){xe=xe>>2;var be=H,Le=be[xe],Fe=be[xe+1];return new X(L,Fe,Le)}R=Tr(R),fi($,{name:R,fromWireType:he,argPackAdvance:8,readValueFromPointer:he},{ignoreDuplicateRegistrations:!0})}function Kc($,K){K=Tr(K);var R=K==="std::string";fi($,{name:K,fromWireType:function(U){var X=H[U>>2],he=U+4,xe;if(R)for(var be=he,Le=0;Le<=X;++Le){var Fe=he+Le;if(Le==X||W[Fe]==0){var He=Fe-be,ft=D(be,He);xe===void 0?xe=ft:(xe+="\0",xe+=ft),be=Fe+1}}else{for(var It=new Array(X),Le=0;Le>2]=he,R&&xe)P(X,Le,he+1);else if(xe)for(var Fe=0;Fe255&&(Ee(Le),Bn("String has UTF-16 code units that do not fit in 8 bits")),W[Le+Fe]=He}else for(var Fe=0;Fe>1,X=U+K/2;!(U>=X)&&k[U];)++U;if(R=U<<1,R-$>32&&Ps)return Ps.decode(W.subarray($,R));for(var he="",xe=0;!(xe>=K/2);++xe){var be=A[$+xe*2>>1];if(be==0)break;he+=String.fromCharCode(be)}return he}function ac($,K,R){if(R===void 0&&(R=2147483647),R<2)return 0;R-=2;for(var U=K,X=R<$.length*2?R/2:$.length,he=0;he>1]=xe,K+=2}return A[K>>1]=0,K-U}function Rs($){return $.length*2}function sc($,K){for(var R=0,U="";!(R>=K/4);){var X=F[$+R*4>>2];if(X==0)break;if(++R,X>=65536){var he=X-65536;U+=String.fromCharCode(55296|he>>10,56320|he&1023)}else U+=String.fromCharCode(X)}return U}function Ls($,K,R){if(R===void 0&&(R=2147483647),R<4)return 0;for(var U=K,X=U+R-4,he=0;he<$.length;++he){var xe=$.charCodeAt(he);if(xe>=55296&&xe<=57343){var be=$.charCodeAt(++he);xe=65536+((xe&1023)<<10)|be&1023}if(F[K>>2]=xe,K+=4,K+4>X)break}return F[K>>2]=0,K-U}function da($){for(var K=0,R=0;R<$.length;++R){var U=$.charCodeAt(R);U>=55296&&U<=57343&&++R,K+=4}return K}function qc($,K,R){R=Tr(R);var U,X,he,xe,be;K===2?(U=as,X=ac,xe=Rs,he=()=>k,be=1):K===4&&(U=sc,X=Ls,xe=da,he=()=>H,be=2),fi($,{name:R,fromWireType:function(Le){for(var Fe=H[Le>>2],He=he(),ft,It=Le+4,Jt=0;Jt<=Fe;++Jt){var Wt=Le+4+Jt*K;if(Jt==Fe||He[Wt>>be]==0){var Mn=Wt-It,bn=U(It,Mn);ft===void 0?ft=bn:(ft+="\0",ft+=bn),It=Wt+K}}return Ee(Le),ft},toWireType:function(Le,Fe){typeof Fe!="string"&&Bn("Cannot pass non-string to C++ string type "+R);var He=xe(Fe),ft=ne(4+He+K);return H[ft>>2]=He>>be,X(Fe,ft+4,He+K),Le!==null&&Le.push(Ee,ft),ft},argPackAdvance:8,readValueFromPointer:dr,destructorFunction:function(Le){Ee(Le)}})}function cc($,K,R,U,X,he){En[$]={name:Tr(K),rawConstructor:Cr(R,U),rawDestructor:Cr(X,he),fields:[]}}function Xc($,K,R,U,X,he,xe,be,Le,Fe){En[$].fields.push({fieldName:Tr(K),getterReturnType:R,getter:Cr(U,X),getterContext:he,setterArgumentType:xe,setter:Cr(be,Le),setterContext:Fe})}function Yc($,K){K=Tr(K),fi($,{isVoid:!0,name:K,argPackAdvance:0,fromWireType:function(){},toWireType:function(R,U){}})}function As($){$>4&&(Jr[$].refcount+=1)}function ss($,K){var R=Et[$];return R===void 0&&Bn(K+" has unknown type "+hi($)),R}function Wl($,K){$=ss($,"_emval_take_value");var R=$.readValueFromPointer(K);return is.toHandle(R)}function br(){Xe("")}function lc($,K,R){W.copyWithin($,K,K+R)}function uc(){return 2147483648}function ha($){try{return S.grow($-L.byteLength+65535>>>16),ve(S.buffer),1}catch{}}function fc($){var K=W.length;$=$>>>0;var R=uc();if($>R)return!1;let U=(Le,Fe)=>Le+(Fe-Le%Fe)%Fe;for(var X=1;X<=4;X*=2){var he=K*(1+.2/X);he=Math.min(he,$+100663296);var xe=Math.min(R,U(Math.max($,he),65536)),be=ha(xe);if(be)return!0}return!1}function Ko($){return 52}function Ui($,K,R,U,X){return 70}var Co=[null,[],[]];function Jc($,K){var R=Co[$];K===0||K===10?(($===1?w:x)(b(R,0)),R.length=0):R.push(K)}function ga($,K,R,U){for(var X=0,he=0;he>2],be=H[K+4>>2];K+=8;for(var Le=0;Le>2]=X,0}function dc($){return $}function Zc($){var K=o["_"+$];return K}function cs($,K){V.set($,K)}function Qc($,K,R,U,X){var he={string:Wt=>{var Mn=0;if(Wt!=null&&Wt!==0){var bn=(Wt.length<<2)+1;Mn=yt(bn),P(Wt,Mn,bn)}return Mn},array:Wt=>{var Mn=yt(Wt.length);return cs(Wt,Mn),Mn}};function xe(Wt){return K==="string"?D(Wt):K==="boolean"?!!Wt:Wt}var be=Zc($),Le=[],Fe=0;if(U)for(var He=0;He0||(Pe(),ee>0))return;function K(){mt||(mt=!0,o.calledRun=!0,!_&&(G(),a(o),o.onRuntimeInitialized&&o.onRuntimeInitialized(),O()))}o.setStatus?(o.setStatus("Running..."),setTimeout(function(){setTimeout(function(){o.setStatus("")},1),K()},1)):K()}if(o.preInit)for(typeof o.preInit=="function"&&(o.preInit=[o.preInit]);o.preInit.length>0;)o.preInit.pop()();return lt(),o.ready}})();t.exports=r})(UW);var fSe=UW.exports;const dSe=Nl(fSe),hSe=new URL("/static/dv3d/openjphjs.wasm",import.meta.url),pp={codec:void 0,decoder:void 0,decodeConfig:{}};function gSe(t,e,r){const n={width:e,height:r};for(;t>0;)n.width=Math.ceil(n.width/2),n.height=Math.ceil(n.height/2),t--;return n}function pSe(t){if(pp.decodeConfig=t,pp.codec)return Promise.resolve();const e=dSe({locateFile:r=>r.endsWith(".wasm")?hSe.toString():r});return new Promise((r,n)=>{e.then(i=>{pp.codec=i,pp.decoder=new i.HTJ2KDecoder,r()},n)})}async function mSe(t,e){await pSe();const r=new pp.codec.HTJ2KDecoder,n=r.getEncodedBuffer(t.length);n.set(t);const i=e.decodeLevel||0;r.decodeSubResolution(i);const o=r.getFrameInfo();if(e.decodeLevel>0){const{width:E,height:b}=gSe(e.decodeLevel,o.width,o.height);o.width=E,o.height=b}const a=r.getDecodedBuffer();new Uint8Array(a.length).set(a);const c=`x: ${r.getImageOffset().x}, y: ${r.getImageOffset().y}`,l=r.getNumDecompositions(),f=r.getNumLayers(),u=["unknown","LRCP","RLCP","RPCL","PCRL","CPRL"][r.getProgressionOrder()+1],d=r.getIsReversible(),h=`${r.getBlockDimensions().width} x ${r.getBlockDimensions().height}`,g=`${r.getTileSize().width} x ${r.getTileSize().height}`,p=`${r.getTileOffset().x}, ${r.getTileOffset().y}`,v=`${a.length.toLocaleString()} bytes`,y=`${(a.length/n.length).toFixed(2)}:1`,m={columns:o.width,rows:o.height,bitsPerPixel:o.bitsPerSample,signed:o.isSigned,bytesPerPixel:e.bytesPerPixel,componentsPerPixel:o.componentCount};let w=vSe(o,a);const{buffer:x,byteOffset:C,byteLength:S}=w,_=x.slice(C,C+S);w=new w.constructor(_);const T={imageOffset:c,numDecompositions:l,numLayers:f,progessionOrder:u,reversible:d,blockDimensions:h,tileSize:g,tileOffset:p,decodedSize:v,compressionRatio:y};return{...e,pixelData:w,imageInfo:m,encodeOptions:T,...T,...m}}function vSe(t,e){return t.bitsPerSample>8?t.isSigned?new Int16Array(e.buffer,e.byteOffset,e.byteLength/2):new Uint16Array(e.buffer,e.byteOffset,e.byteLength/2):t.isSigned?new Int8Array(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}function ySe(t,e){const r=t.length,{rescaleSlope:n,rescaleIntercept:i,suvbw:o,doseGridScaling:a}=e;if(e.modality==="PT"&&typeof o=="number"&&!isNaN(o))for(let s=0;s>o;let a=t.pixelData;t.pixelDataLength=t.pixelData.length;const{min:s,max:c}=Yw(t.pixelData),l=typeof e.allowFloatRendering<"u"?e.allowFloatRendering:!0;let f=v8(t.photometricInterpretation)&&((m=e.targetBuffer)==null?void 0:m.offset)===void 0;const d=((w=e.preScale)==null?void 0:w.enabled)&&Object.values(e.preScale.scalingParameters).some(C=>typeof C=="number"&&!Number.isInteger(C)),h=!e.preScale.enabled||!l&&d,g=(x=e.targetBuffer)==null?void 0:x.type;if(g&&e.preScale.enabled&&!h){const C=e.preScale.scalingParameters,S=u_(s,c,C);f=!ZCe(S.min,S.max,e7[g])}g&&!f?a=SSe(e,t,e7,a):e.preScale.enabled&&!h?a=_Se(e,s,c,t):a=BW(s,c,t);let p=s,v=c;if(e.preScale.enabled&&!h){const C=e.preScale.scalingParameters;if(GW(C),CSe(C)){ySe(a,C),t.preScale={...e.preScale,scaled:!0};const _=u_(s,c,C);p=_.min,v=_.max}}else h&&(t.preScale={enabled:!0,scaled:!1},p=s,v=c);t.pixelData=a,t.smallestPixelValue=p,t.largestPixelValue=v;const y=new Date().getTime();return t.decodeTimeInMS=y-r,t}function CSe(t){const{rescaleSlope:e,rescaleIntercept:r,modality:n,doseGridScaling:i,suvbw:o}=t;return typeof e=="number"&&typeof r=="number"||n==="RTDOSE"&&typeof i=="number"||n==="PT"&&typeof o=="number"}function SSe(t,e,r,n){const{arrayBuffer:i,type:o,offset:a=0,length:s,rows:c}=t.targetBuffer,l=r[o];if(!l)throw new Error(`target array ${o} is not supported, or doesn't exist.`);c&&c!=e.rows&&ESe(e,t.targetBuffer,l);const f=e.pixelDataLength,u=a,d=s??f-u,h=e.pixelData;if(d!==h.length)throw new Error(`target array for image does not have the same length (${d}) as the decoded image length (${h.length}).`);const g=i?new l(i,u,d):new l(d);return g.set(h,0),n=g,n}function _Se(t,e,r,n){const i=t.preScale.scalingParameters;GW(i);const o=u_(e,r,i);return BW(o.min,o.max,n)}function BW(t,e,r){const n=y8(t,e),i=new n(r.pixelData.length);return i.set(r.pixelData,0),i}function u_(t,e,r){const{rescaleSlope:n,rescaleIntercept:i,modality:o,doseGridScaling:a,suvbw:s}=r;return o==="PT"&&typeof s=="number"&&!isNaN(s)?{min:s*(t*n+i),max:s*(e*n+i)}:o==="RTDOSE"&&typeof a=="number"&&!isNaN(a)?{min:t*a,max:e*a}:typeof n=="number"&&typeof i=="number"?{min:n*t+i,max:n*e+i}:{min:t,max:e}}function GW(t){if(!t)throw new Error("options.preScale.scalingParameters must be defined if preScale.enabled is true, and scalingParameters cannot be derived from the metadata providers.")}function TSe(t,e,r){const{samplesPerPixel:n}=t,{rows:i,columns:o}=e,a=i*o*n,s=new r(a),c=s.byteLength/a;return{pixelData:s,rows:i,columns:o,frameInfo:{...t.frameInfo,rows:i,columns:o},imageInfo:{...t.imageInfo,rows:i,columns:o,bytesPerPixel:c}}}function ESe(t,e,r){const n=TSe(t,e,r),{scalingType:i="replicate"}=e;return wSe[i](t,n),Object.assign(t,n),t.pixelDataLength=t.pixelData.length,t}async function WW(t,e,r,n,i,o){const a=new Date().getTime();let s=null,c;switch(e){case"1.2.840.10008.1.2":case"1.2.840.10008.1.2.1":s=XI(t,r);break;case"1.2.840.10008.1.2.2":s=F3e(t,r);break;case"1.2.840.10008.1.2.1.99":s=XI(t,r);break;case"1.2.840.10008.1.2.5":s=U3e(t,r);break;case"1.2.840.10008.1.2.4.50":c={...t},s=K3e(r,c);break;case"1.2.840.10008.1.2.4.51":s=Z3e(t,r);break;case"1.2.840.10008.1.2.4.57":s=JI(t,r);break;case"1.2.840.10008.1.2.4.70":s=JI(t,r);break;case"1.2.840.10008.1.2.4.80":c={signed:t.pixelRepresentation===1,bytesPerPixel:t.bitsAllocated<=8?1:2,...t},s=ZI(r,c);break;case"1.2.840.10008.1.2.4.81":c={signed:t.pixelRepresentation===1,bytesPerPixel:t.bitsAllocated<=8?1:2,...t},s=ZI(r,c);break;case"1.2.840.10008.1.2.4.90":c={...t},s=QI(r,c);break;case"1.2.840.10008.1.2.4.91":c={...t},s=QI(r,c);break;case"3.2.840.10008.1.2.4.96":case"1.2.840.10008.1.2.4.201":case"1.2.840.10008.1.2.4.202":case"1.2.840.10008.1.2.4.203":c={...t},s=mSe(r,c);break;default:throw new Error(`no decoder for transfer syntax ${e}`)}if(!s)throw new Error("decodePromise not defined");const l=await s,f=xSe(l,i,a);return o==null||o(f),f}const bSe={decodeTask({imageFrame:t,transferSyntax:e,decodeConfig:r,options:n,pixelData:i,callbackFn:o}){return WW(t,e,i,r,n,o)}};l4(bSe);const $u={constants:A3e,convertRGBColorByPixel:JG,convertRGBColorByPlane:ZG,convertYBRFullByPixel:QG,convertYBRFullByPlane:eW,convertPALETTECOLOR:tW,wadouri:r3e,wadors:I3e,init:AW,convertColorSpace:xW,createImage:Jw,decodeJPEGBaseline8BitColor:CW,getImageFrame:SW,getPixelData:S8,getMinMax:Yw,isColorImage:v8,isJPEGBaseline8BitColor:R3e,internal:yCe,decodeImageFrame:WW},t7={debug:0,info:1,warn:2,error:3,silent:4},_8={minLevel:"warn",format:"compact",namespace:"dv3d",dedupeWindowMs:1200};let qs={..._8};const n7=new Map;function zW(){return new Date().toISOString()}function r7(t){return t==="debug"?console.debug.bind(console):t==="info"?console.info.bind(console):t==="warn"?console.warn.bind(console):console.error.bind(console)}function $W(t){return t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t}function DSe(t){return t7[t]>=t7[qs.minLevel]}function ISe(t){return t==="debug"||t==="info"}function OSe(t,e,r){const n=(r==null?void 0:r.dedupeKey)||`${(r==null?void 0:r.namespace)||qs.namespace}:${t}`,i=e.map(o=>{if(typeof o=="string")return o;try{return JSON.stringify($W(o))}catch{return String(o)}}).join("|");return`${n}:${i}`}function MSe(t,e,r){if(!ISe(t)||qs.dedupeWindowMs<=0)return!1;const n=OSe(t,e,r),i=Date.now(),o=n7.get(n);return n7.set(n,i),o===void 0?!1:i-oju("debug",t),info:(...t)=>ju("info",t),warn:(...t)=>ju("warn",t),error:(...t)=>ju("error",t),child:t=>({debug:(...e)=>ju("debug",e,{namespace:t}),info:(...e)=>ju("info",e,{namespace:t}),warn:(...e)=>ju("warn",e,{namespace:t}),error:(...e)=>ju("error",e,{namespace:t})})};class $h extends Wf{}r6($h,"toolName","NoLabelArrowAnnotate");const K2=gu.prototype;if(!K2._mouseSensitivityPatched){const t=K2.getNewRange;K2.getNewRange=function({deltaPointsCanvas:e,...r}){var o;const n=typeof((o=this==null?void 0:this.configuration)==null?void 0:o.mouseSensitivity)=="number"?this.configuration.mouseSensitivity:1,i=Array.isArray(e)?[e[0]*n,e[1]*n]:e;return t.call(this,{...r,deltaPointsCanvas:i})},K2._mouseSensitivityPatched=!0}function i7(t,e){const r=xt("imagePlaneModule",t);if(!r)return;const{rowCosines:n,columnCosines:i,imagePositionPatient:o,rowPixelSpacing:a,columnPixelSpacing:s}=r;if(!n||!i||!o)return;const c=s||1,l=a||1;return{x:o[0]+n[0]*e.y*l+i[0]*e.x*c,y:o[1]+n[1]*e.y*l+i[1]*e.x*c,z:o[2]+n[2]*e.y*l+i[2]*e.x*c}}const{MouseBindings:qg,KeyboardBindings:o7}=Lk,{IMAGE_RENDERED:Xg}=ct,RSe=[{name:"Soft Tissue",center:40,width:400},{name:"Lung",center:-600,width:1500},{name:"Bone",center:300,width:1500},{name:"Brain",center:40,width:80},{name:"Abdomen",center:60,width:400}],a7=t=>{const e=(t||"").toUpperCase(),r=[{name:"Reset to default",action:"reset"},{name:"Auto level",action:"autolevel"}];return e!=="CT"?r:[...r,...RSe.map(n=>({name:n.name,action:"preset",center:n.center,width:n.width}))]},md=[{label:"Window/Level",value:gu.toolName,icon:"🌓"},{label:"Pan",value:Ec.toolName,icon:"✋"},{label:"Zoom",value:gl.toolName,icon:"🔍"},{label:"Stack Scroll",value:bf.toolName,icon:"📚"},{label:"Rotate",value:Bh.toolName,icon:"↺"},{label:"Length",value:Gf.toolName,icon:"📏"},{label:"Probe",value:Iu.toolName,icon:"🔎"},{label:"Arrow (No Label)",value:$h.toolName,icon:"➡️"},{label:"Arrow Annotate",value:Wf.toolName,icon:"✈️"},{label:"Rectangle ROI",value:Du.toolName,icon:"▭"},{label:"Ellipse ROI",value:e0.toolName,icon:"◯"},{label:"Freehand ROI",value:Bf.toolName,icon:"✏️"},{label:"Freehand Contour Segmentation",value:Ll.toolName,icon:"🖊️"},{label:"Sculptor",value:Gh.toolName,icon:"🔧"},{label:"Reference Cursors",value:gs.toolName,icon:"⦿"}],LSe=3,ASe=220,s7="dv3d_logging",NSe=[{label:"Compact",value:"compact"},{label:"Verbose",value:"verbose"},{label:"JSON",value:"json"}],kSe=[{label:"Off",value:"silent"},{label:"Error",value:"error"},{label:"Warn",value:"warn"},{label:"Info",value:"info"},{label:"Debug",value:"debug"}],c7="dv3d_grouping",mp=[{id:"dwiBValue",label:"DWI b-value",description:"DiffusionBValue (0018,9087) + known private fallbacks",defaultEnabled:!0},{id:"dwiDirection",label:"DWI direction",description:"Diffusion Gradient Direction (0018,9089)",defaultEnabled:!0},{id:"temporalPosition",label:"Temporal position",description:"Temporal Position Identifier (0020,0100)",defaultEnabled:!0},{id:"triggerTime",label:"Trigger time",description:"Trigger Time (0018,1060)",defaultEnabled:!0},{id:"contentTime",label:"Content/Acquisition time",description:"Content Time (0008,0033) / Acquisition Time (0008,0032)",defaultEnabled:!1},{id:"echoTime",label:"Echo time",description:"Echo Time (0018,0081)",defaultEnabled:!0},{id:"echoNumber",label:"Echo number",description:"Echo Number (0018,0086)",defaultEnabled:!0}];function l7(){return mp.reduce((t,e)=>(t[e.id]=e.defaultEnabled,t),{})}const kt=jW.child("app");function u7(t){if(!t)return"🔖";const e=md.find(r=>r.value===t||r.label===t);return(e==null?void 0:e.icon)||"🔖"}function il(t){return t?t.startsWith("wadouri:")?t.replace(/^wadouri:+/,"").replace(/^:+/,""):t:""}function d_(t){return/([?&])frame=\d+/i.test(t)}function f7(t,e){const r=Math.max(1,Math.floor(e));return d_(t)?t.replace(/([?&])frame=\d+/i,`$1frame=${r}`):`${t}&frame=${r}`}function d7(t){const e=t.match(/[?&]frame=(\d+)/i);if(!e)return null;const r=Number(e[1]);return Number.isFinite(r)&&r>0?Math.floor(r):null}function _5(t){return t?t.split(/\\|,/).map(e=>Number(e.trim())).filter(e=>Number.isFinite(e)):[]}function AC(t){if(!t||typeof t!="object")return[];const e=o=>{if(typeof t.string=="function"){const a=t.string(o);if(a!=null&&a!==""){const s=_5(a);if(s.length>0&&Number.isFinite(s[0])&&s[0]>=0)return s[0]}}if(typeof t.double=="function")try{const a=t.double(o);if(Number.isFinite(a)&&a>=0)return a}catch{}if(typeof t.float=="function")try{const a=t.float(o);if(Number.isFinite(a)&&a>=0)return a}catch{}return null},r=e("x00189087");if(r!==null)return[r];const n=e("x0019100c");if(n!==null)return[n];if(typeof t.string=="function"){const o=t.string("x00431039");if(o){const a=_5(o);if(a.length>0&&Number.isFinite(a[0])&&a[0]>=0)return[a[0]]}}const i=e("x20011003");return i!==null?[i]:[]}function va(t){return t.startsWith("wadouri:")||t.startsWith("external:")?t:`wadouri:${t}`}function So(t){const e=new Set,r=[];for(const n of t)!n||e.has(n)||(e.add(n),r.push(n));return r}function VSe(t){try{const e=t.getContext("2d",{willReadFrequently:!0});if(!e)return!0;const r=t.width||160,n=t.height||160,o=e.getImageData(0,0,r,n).data;let a=255,s=0,c=0,l=0;for(let d=0;d0&&w>12&&(c+=1),a=Math.min(a,w),s=Math.max(s,w),l+=1}if(l===0)return!0;const f=c/l,u=s-a;return f>.015||u>8}catch{return!0}}const h7=[{label:"Left",value:"Primary"},{label:"Middle",value:"Auxiliary"},{label:"Right",value:"Secondary"}],q2=[{label:"Left",value:"Primary",mask:1},{label:"Middle",value:"Auxiliary",mask:4},{label:"Right",value:"Secondary",mask:2},{label:"Left + Right",value:"Primary_and_Secondary",mask:3},{label:"Left + Middle",value:"Primary_and_Auxiliary",mask:5},{label:"Right + Middle",value:"Secondary_and_Auxiliary",mask:6},{label:"Left + Right + Middle",value:"Primary_and_Secondary_and_Auxiliary",mask:7},{label:"Fourth Button",value:"Fourth_Button",mask:8},{label:"Fifth Button",value:"Fifth_Button",mask:16},{label:"Mouse Wheel",value:"Wheel",mask:524288},{label:"Mouse Wheel + Left",value:"Wheel_Primary",mask:524289}];function FSe({container_id:t,imageStacks:e,autoCacheStack:r,annotationJson:n,viewerState:i,initialLoggerConfig:o}){var hn,Z,J,ye,Be,Ze,Ct,mt,lt,$,K,R,U,X,he,xe,be,Le,Fe,He,ft,It,Jt,Wt,Mn,bn,ar,ai,gi,el,pa,Zf,Au,xg,Cg,z8,$8,j8,H8,K8,q8,X8,Y8,J8,Z8;const a=it.useRef(null),s=it.useRef(null),c=it.useRef(!1),l="dv3d_mouseToolBindings",f="dv3d_ctrlMouseToolBindings",u="dv3d_windowLevelMouseSensitivity",d=(o==null?void 0:o.minLevel)??((o==null?void 0:o.debug)!==void 0?o.debug?"debug":"warn":void 0)??C5().minLevel,h=jp((o==null?void 0:o.format)??C5().format),[g,p]=it.useState(d),[v,y]=it.useState(h),[m,w]=it.useState(!0),[x,C]=it.useState(()=>l7()),[S,_]=it.useState(!1),[T,E]=it.useState(!1),[b,D]=it.useState(320),I=`dv3d_stackPanelWidth_${t||"default"}`,P=it.useRef({resizing:!1,startX:0,startWidth:320}),M=240,L=720,V=220,W=40,A=14,k=it.useRef(null),[F,H]=it.useState(null),[Q,oe]=it.useState(null),[ve,fe]=it.useState(!1),[Se,Ae]=it.useState(!1),[Ue,Pe]=it.useState(!1),[G,O]=it.useState(null),[j,z]=it.useState(!0),[q,ee]=it.useState(null),[ie,Oe]=it.useState("center"),[ke,Xe]=it.useState(null),Qe=it.useRef(0),Y=9,ce="renderingEngine_"+t,De="TOOL_GROUP_"+t,ae=it.useRef(null),_e=it.useRef(!1),[tt,le]=it.useState(!0),[Ot,Vt]=it.useState(!1),[_t,Ne]=it.useState([]),[je,ht]=it.useState(0),[wt,Dt]=it.useState(null),[an,Bt]=it.useState(!1),[rn,sn]=it.useState(null),[Yt,or]=it.useState(()=>Array(Y).fill(null).map(()=>[])),en=B=>{typeof B=="function"?or(ue=>{const Te=B(ue);return kt.debug("setViewportImageIds (fn):",Te),Te}):(kt.debug("setViewportImageIds:",B),or(B))},[En,_r]=it.useState(()=>Array(Y).fill(0)),[dr,Ke]=it.useState(()=>Array(Y).fill(null).map(()=>[])),[Et,qt]=it.useState(()=>Array(Y).fill(0)),[Nn,Ai]=it.useState(()=>Array(Y).fill(!1)),[cn,Jn]=it.useState(()=>Array(Y).fill(12)),[Sn,_n]=it.useState(()=>Array(Y).fill(!1)),oi=it.useRef({}),Ni=it.useRef({}),[no,Ya]=it.useState({}),ro=it.useRef({}),io=it.useRef({}),bi=it.useCallback((B,ue)=>{Ya(Te=>{const Ce=Te[B];if(Ce&&Ce!==ue&&Ce.startsWith("blob:"))try{URL.revokeObjectURL(Ce)}catch{}const me={...Te,[B]:ue};return ro.current=me,me})},[]);it.useEffect(()=>{ro.current=no},[no]),it.useEffect(()=>()=>{Object.values(ro.current).forEach(B=>{if(typeof B=="string"&&B.startsWith("blob:"))try{URL.revokeObjectURL(B)}catch{}})},[]),it.useEffect(()=>{try{const B=localStorage.getItem(I);if(B){const ue=Number(B);Number.isNaN(ue)||D(Math.max(M,Math.min(L,Math.round(ue))))}}catch{}},[I]),it.useEffect(()=>{try{localStorage.setItem(I,String(Math.round(b)))}catch{}},[I,b]);function Tr(B){if(!B)return null;try{if(B.tagName&&B.tagName.toLowerCase()==="canvas")return B}catch{}try{const ue=B.querySelector&&B.querySelector("canvas");if(ue)return ue}catch{}try{const ue=B.children||[];for(let Te=0;TeMath.min(Ft,Math.max(Ut,bt)),nt=()=>{ue.style.transform=`translate(${se}px, ${ge}px) scale(${we})`};let dt=!0,et=!0;const gt=bt=>{if(!et)return;bt.preventDefault();const Ut=ue.getBoundingClientRect(),Ft=bt.clientX-Ut.left,qn=bt.clientY-Ut.top,yr=-bt.deltaY,Zr=1+(yr>0?.1:-.1)*Math.min(4,Math.abs(yr)/100),Dr=Me(we*Zr,.1,10);se=(se-Ft)*(Dr/we)+Ft,ge=(ge-qn)*(Dr/we)+qn,we=Dr,nt()},ut=bt=>{bt.button===0&&dt&&(pe=!0,de=bt.clientX,Ve=bt.clientY,ue.style.cursor="grabbing",bt.preventDefault())},qe=bt=>{if(!pe)return;const Ut=bt.clientX-de,Ft=bt.clientY-Ve;se+=Ut,ge+=Ft,de=bt.clientX,Ve=bt.clientY,nt()},Tt=bt=>{pe&&(pe=!1,ue.style.cursor="grab")},Lt=bt=>{we=1,se=0,ge=0,nt()};let st=0;const Rt=(bt,Ut)=>Math.hypot(Ut.clientX-bt.clientX,Ut.clientY-bt.clientY),Nt=bt=>{bt.touches.length===1?dt&&(pe=!0,de=bt.touches[0].clientX,Ve=bt.touches[0].clientY):bt.touches.length===2&&(st=Rt(bt.touches[0],bt.touches[1]))},Mt=bt=>{if(bt.touches.length===1&&pe){const Ut=bt.touches[0].clientX-de,Ft=bt.touches[0].clientY-Ve;se+=Ut,ge+=Ft,de=bt.touches[0].clientX,Ve=bt.touches[0].clientY,nt()}else if(bt.touches.length===2&&et){const Ut=Rt(bt.touches[0],bt.touches[1]);if(st>0){const Ft=Ut/st,qn=ue.getBoundingClientRect(),yr=(bt.touches[0].clientX+bt.touches[1].clientX)/2-qn.left,Zr=(bt.touches[0].clientY+bt.touches[1].clientY)/2-qn.top,Dr=Me(we*Ft,.1,10);se=(se-yr)*(Dr/we)+yr,ge=(ge-Zr)*(Dr/we)+Zr,we=Dr,nt()}st=Ut}bt.preventDefault()},Gt=bt=>{bt.touches.length===0&&(pe=!1,st=0)};return B.addEventListener("wheel",gt,{passive:!1}),B.addEventListener("mousedown",ut),window.addEventListener("mousemove",qe),window.addEventListener("mouseup",Tt),ue.addEventListener("dblclick",Lt),B.addEventListener("touchstart",Nt,{passive:!1}),B.addEventListener("touchmove",Mt,{passive:!1}),B.addEventListener("touchend",Gt),{cleanup:()=>{B.removeEventListener("wheel",gt),B.removeEventListener("mousedown",ut),window.removeEventListener("mousemove",qe),window.removeEventListener("mouseup",Tt),ue.removeEventListener("dblclick",Lt),B.removeEventListener("touchstart",Nt),B.removeEventListener("touchmove",Mt),B.removeEventListener("touchend",Gt),ue.style.transform="",ue.style.cursor="",ue.style.willChange=""},setAllowPan:bt=>{dt=bt},setAllowZoom:bt=>{et=bt}}}const[fi,Ja]=it.useState(!1),[ji,Er]=it.useState(null),[Po,ki]=it.useState(!1),[Zs,Ma]=it.useState(null);it.useEffect(()=>{const B=Te=>{try{const Ce=Te&&Te.message?String(Te.message):"";(Ce.includes("releaseGraphicsResources")||Ce.includes("openGLTexture")||Ce.includes("getDefaultActor")||Ce.includes("setColormapGPU")||Ce.includes(`can't access property "actor"`)||Ce.toLowerCase().includes("webgl")||Ce.toLowerCase().includes("colormap"))&&(kt.error("Detected graphics/rendering error:",Te),Ma(Ce||null),ki(!0))}catch{}},ue=Te=>{try{const Ce=Te&&Te.reason||"",me=typeof Ce=="string"?Ce:Ce&&Ce.message?Ce.message:String(Ce);(me.includes("releaseGraphicsResources")||me.includes("openGLTexture")||me.includes("getDefaultActor")||me.includes("setColormapGPU")||me.includes(`can't access property "actor"`)||me.toLowerCase().includes("webgl")||me.toLowerCase().includes("colormap"))&&(kt.error("Detected graphics/rendering rejection:",Te),Ma(me||null),ki(!0))}catch{}};return window.addEventListener("error",B),window.addEventListener("unhandledrejection",ue),()=>{window.removeEventListener("error",B),window.removeEventListener("unhandledrejection",ue)}},[]),it.useEffect(()=>{let B=!1;if(n||i){Er(n?"annotations":"viewerState");const ue=setTimeout(()=>{if(B)return;const Te=t||"default";if(n)try{const Ce=window[`importAnnotations_${Te}`]||window.importAnnotations;typeof Ce=="function"&&Ce(n)}catch(Ce){kt.error("Failed to import annotations from prop:",Ce)}if(i)try{const Ce=window[`importViewerState_${Te}`]||window.importViewerState;typeof Ce=="function"&&Ce(i)}catch(Ce){kt.error("Failed to import viewer state from prop:",Ce)}Er(null)},2e3);return()=>{B=!0,clearTimeout(ue),Er(null)}}},[n,i,t]),it.useEffect(()=>{let B=!0;return e().then(async ue=>{var me;if(!B)return;const Te=Array.isArray(ue)?ue:[],Ce=[];for(const we of Te){const se=Array.isArray(we),ge=se?we:Array.isArray(we.imageIds)?we.imageIds:Array.isArray(we.i)?we.i:[],pe=se?{}:{studyId:we.studyId,name:we.name,caseId:we.caseId,studyInstanceUID:we.studyInstanceUID};if(!se&&Array.isArray(we.series)){const Ve=we.series.map((Me,nt)=>{const dt=Array.isArray(Me==null?void 0:Me.imageIds)?Me.imageIds:Array.isArray(Me==null?void 0:Me.i)?Me.i:[],et=So(dt.map(va)),ut=(typeof(Me==null?void 0:Me.label)=="string"?Me.label:typeof(Me==null?void 0:Me.name)=="string"?Me.name:"").trim()||`Series ${nt+1}`;return{key:String((Me==null?void 0:Me.key)||(Me==null?void 0:Me.seriesInstanceUID)||(Me==null?void 0:Me.seriesId)||`SERIES_${nt}`),label:ut,imageIds:et,seriesInstanceUID:Me==null?void 0:Me.seriesInstanceUID,bValue:Number.isFinite(Number(Me==null?void 0:Me.bValue))?Number(Me.bValue):null,groupValues:Me==null?void 0:Me.groupValues}}).filter(Me=>Me.imageIds.length>0);if(Ve.length>0){Ce.push({imageIds:So(Ve.flatMap(Me=>Me.imageIds)),seriesGroups:Ve,groupingSource:"declared",...pe});continue}}const de=So(ge.map(va));de.length>0&&Ce.push({imageIds:de,seriesGroups:[],groupingSource:"derived",...pe})}if(Ne(Ce),Ce[0]){const we=Ce[0];let se=we.seriesGroups||[],ge=we.imageIds;se.length===0&&(r?(kt.debug("[init] autoCacheStack true: expanding multiframe and fetching metadata"),ge=await Lo(we.imageIds),await Zn(ge,{force:!0}),se=await Ao(ge),Ce[0]={...we,imageIds:ge,seriesGroups:se,groupingSource:"derived"},Ne([...Ce])):kt.debug("[init] autoCacheStack false: skipping all probes/expansion, relying on server grouping"));const pe=((me=se[0])==null?void 0:me.imageIds)||ge;r?await Zn(pe,{force:!0}):kt.debug("[init] autoCacheStack false: not fetching metadata for firstSeries"),en(Array(Y).fill(null).map((de,Ve)=>Ve===0?pe||[]:[])),Ke(Array(Y).fill(null).map(()=>se)),qt(Array(Y).fill(0))}else en(Array(Y).fill(null).map(()=>[])),Ke(Array(Y).fill(null).map(()=>[])),qt(Array(Y).fill(0))}).catch(ue=>{kt.error("Failed to load imageStacks:",ue),Ne([]),en(Array(Y).fill(null).map(()=>[]))}),()=>{B=!1}},[]);const Vi=async(B,ue)=>{var pe,de,Ve,Me,nt;const Te=_t[ue];if(!Te)return;const Ce=Te.groupingSource==="declared"&&(Te.seriesGroups||[]).length>0;if(!r&&Ce&&(Te.imageIds||[]).length>1){kt.debug("[handleLoadStack] autoCacheStack false & declared groups: skipping all probes/expansion, using server grouping only");const dt=So((Te.imageIds||[]).map(va)),et=Te.seriesGroups||[];Ne(ut=>{const qe=[...ut];return qe[ue]?(qe[ue]={...qe[ue],seriesGroups:et,imageIds:dt,groupingSource:"declared"},qe):ut});const gt=((pe=et[0])==null?void 0:pe.imageIds)||dt;Er("displayset");try{ao(ut=>{const qe=[...ut];return qe[B]="stack",qe}),en(ut=>{const qe=[...ut];return qe[B]=gt,qe}),_r(ut=>{const qe=[...ut];return qe[B]=ue,qe}),Ke(ut=>{const qe=[...ut];return qe[B]=et||[],qe}),qt(ut=>{const qe=[...ut];return qe[B]=0,qe}),kt.debug("[handleLoadStack] autoCacheStack false: not fetching metadata for primarySeries")}finally{Er(null)}return}const we=!(Ce&&(Te.imageIds||[]).length>1)?await Lo(Te.imageIds||[]):So((Te.imageIds||[]).map(va));kt.debug("[handleLoadStack] Loading stack:",we.length,"ids. First:",(de=we[0])==null?void 0:de.slice(0,80)),await Zn(we,{force:!!r});const se=Ce?Te.seriesGroups||[]:await Ao(we);kt.debug("[handleLoadStack] Derived series groups:",se.length,"groups. First group has",(Ve=se[0])==null?void 0:Ve.imageIds.length,"images"),Ne(dt=>{const et=[...dt];return et[ue]?(et[ue]={...et[ue],seriesGroups:se,imageIds:we,groupingSource:Ce?"declared":"derived"},et):dt});const ge=((Me=se[0])==null?void 0:Me.imageIds)||we;kt.debug("[handleLoadStack] Setting viewport to primarySeries with",ge.length,"ids. First:",(nt=ge[0])==null?void 0:nt.slice(0,80)),Er("displayset");try{ao(dt=>{const et=[...dt];return et[B]="stack",et}),en(dt=>{const et=[...dt];return et[B]=ge,et}),_r(dt=>{const et=[...dt];return et[B]=ue,et}),Ke(dt=>{const et=[...dt];return et[B]=se||[],et}),qt(dt=>{const et=[...dt];return et[B]=0,et}),await Zn(ge)}finally{Er(null)}},[Za,Ro]=it.useState(!1),[zo,Qa]=it.useState(!0),[wo,Qs]=it.useState(!1),[Pa,$o]=it.useState(!1),ec=()=>{kt.debug("Sorting viewport imageIds by slice location"),en(B=>{const ue=B.map((Te,Ce)=>{if(!Te||Te.length===0)return Te;const se=[...Te.map(ge=>{const pe=xt("imagePlaneModule",ge);let de=null;return pe&&(pe.sliceLocation!==void 0?de=Number(pe.sliceLocation):pe.imagePositionPatient&&Array.isArray(pe.imagePositionPatient)&&pe.imagePositionPatient.length===3&&(de=Number(pe.imagePositionPatient[2]))),{imageId:ge,sortKey:de}})].sort((ge,pe)=>ge.sortKey!==null&&pe.sortKey!==null?ge.sortKey-pe.sortKey:ge.imageId.localeCompare(pe.imageId)).map(ge=>ge.imageId);return JSON.stringify(se)===JSON.stringify(Te)?Te:se});return Ja(!0),ue})},qr=it.useCallback(async(B,ue,Te=0)=>{if(!ue||no[B]||io.current[B])return;if(Mo(ue)){try{const se=new Image;se.crossOrigin="anonymous";const ge=ue.replace(/^external:/,"");se.src=ge,await new Promise((Me,nt)=>{se.onload=()=>Me(!0),se.onerror=dt=>nt(dt)});const pe=document.createElement("canvas"),de=160;pe.width=de,pe.height=de;const Ve=pe.getContext("2d");if(Ve){const Me=Math.min(de/se.width,de/se.height),nt=se.width*Me,dt=se.height*Me,et=(de-nt)/2,gt=(de-dt)/2;Ve.fillStyle="#000",Ve.fillRect(0,0,de,de),Ve.drawImage(se,et,gt,nt,dt),bi(B,pe.toDataURL("image/png"))}else bi(B,"BROKEN")}catch{bi(B,"BROKEN")}return}const Ce=ae.current;if(!Ce)return;io.current[B]=!0;const me=`THUMB_${t||"main"}_${B}`,we=document.createElement("div");we.style.width="160px",we.style.height="160px",we.style.position="absolute",we.style.left="-9999px",we.style.top="0",document.body.appendChild(we);try{Ce.enableElement({viewportId:me,type:Lr.STACK,element:we});const se=Ce.getViewport(me);if(!se)return;try{se.setStack([ue])}catch{}await new Promise(pe=>{let de=!1;const Ve=setTimeout(()=>{de||(de=!0,pe(!1))},2e3),Me=()=>{de||(de=!0,clearTimeout(Ve),pe(!0))};try{if(se&&se.element&&se.element.addEventListener(Xg,Me,{once:!0}),typeof se.render=="function")try{const nt=se.render();nt&&typeof nt.then=="function"&&nt.catch(()=>{})}catch{}}catch{clearTimeout(Ve),pe(!1)}});let ge=Tr(we)||(se&&se.element?Tr(se.element):null);if(ge||(await new Promise(pe=>setTimeout(pe,150)),ge=Tr(we)||(se&&se.element?Tr(se.element):null)),ge){if(!VSe(ge)&&Te{qr(B,ue,Te+1)},de);return}try{if(typeof ge.toBlob=="function"){const de=await new Promise(Ve=>{ge.toBlob(Me=>{if(!Me){Ve(null);return}Ve(URL.createObjectURL(Me))},"image/png")});de?bi(B,de):bi(B,ge.toDataURL("image/png"))}else bi(B,ge.toDataURL("image/png"))}catch{bi(B,"BROKEN")}}else bi(B,"BROKEN")}catch{try{bi(B,"BROKEN")}catch{}}finally{try{Ce.disableElement(me)}catch{}we&&we.parentNode&&we.parentNode.removeChild(we)}},[t,no,bi]);it.useEffect(()=>{!T||!_t||_t.length===0||!ae.current||_t.slice(0,12).forEach((ue,Te)=>{const Ce=Array.isArray(ue.imageIds)?ue.imageIds:[],me=Math.floor(Ce.length/2),we=Ce[me]||Ce[0]||null;!no[Te]&&!io.current[Te]&&qr(Te,we)})},[_t,qr,T,no]);const Zn=async(B,ue)=>{kt.debug("Setting loaded imageIds:",B),kt.debug("autoCacheStack:",r);const Te=[];if(!!(r||ue!=null&&ue.force)){const me=new Set;for(const we of B)if(we.startsWith("wadouri:"))try{const se=il(we).replace(/[?&]frame=\d+/gi,"");se&&me.add(se)}catch(se){kt.warn(`Failed to cache metadata for ${we}:`,se)}for(const we of me)if($u.wadouri.dataSetCacheManager){const se=$u.wadouri.dataSetCacheManager.load(we);se&&typeof se.then=="function"&&Te.push(se)}else kt.warn("MetaDataManager not found. Unable to cache metadata.");await Promise.all(Te),Aa&&(kt.debug("Sorting viewport imageIds by slice location"),ec())}},es=it.useCallback(async B=>{var ge;if(!B.startsWith("wadouri:")||d_(B))return 1;const ue=va(B),Te=il(ue),Ce=`wadouri:${Te}`,me=oi.current[Ce];if(me!==void 0)return me;const we=pe=>{if(!pe||typeof pe.intString!="function")return 1;const de=Number(pe.intString("x00280008"));return Number.isFinite(de)&&de>1?Math.floor(de):1},se=pe=>{try{const de=Vr.parseDicom(pe);return we(de)}catch(de){if(de!=null&&de.dataSet){const Ve=we(de.dataSet);if(Ve>1)return Ve}return 1}};try{const pe=xt("multiframeModule",ue),de=Number(pe==null?void 0:pe.numberOfFrames);if(Number.isFinite(de)&&de>1)return oi.current[Ce]=Math.floor(de),Math.floor(de)}catch{}try{const pe=(ge=$u==null?void 0:$u.wadouri)==null?void 0:ge.dataSetCacheManager;if(pe!=null&&pe.get){const de=pe.get(Te);if(de){const Ve=we(de);return oi.current[Ce]=Ve,Ve}}}catch{}try{const pe=await fetch(Te,{headers:{Range:"bytes=0-262143"}});if(pe.ok||pe.status===206){const de=await pe.arrayBuffer(),Ve=se(new Uint8Array(de));return oi.current[Ce]=Ve,Ve}}catch{}return oi.current[Ce]=1,1},[]),ts=it.useCallback(async B=>{var Ce;const ue=[],Te=[];for(const me of B||[]){const we=va(me);if(!we.startsWith("wadouri:")||d_(we)){ue.push(we);continue}const se=await es(we);if(se<=1)ue.push(we);else{const ge=Array.from({length:se},(pe,de)=>f7(we,de+1));Te.push({baseImageId:we,frameIds:ge}),kt.debug("[splitMultiframeToStacks]",((Ce=il(we).split("/").pop())==null?void 0:Ce.split("?")[0])??we,"->",se,"frames (separate stack)")}}return{singleFrameIds:So(ue),multiframeGroups:Te}},[es]),Lo=it.useCallback(async B=>{if(kt.debug("[expandMultiframeImageIds] Input:",B.length,"imageIds"),!r){const me=So((B||[]).map(va));return kt.debug("[expandMultiframeImageIds] autoCacheStack false: skipping multiframe probe/expansion"),kt.debug("[expandMultiframeImageIds] Output:",me.length,"total imageIds"),me}const{singleFrameIds:ue,multiframeGroups:Te}=await ts(B),Ce=So([...ue,...Te.flatMap(me=>me.frameIds)]);return kt.debug("[expandMultiframeImageIds] Output:",Ce.length,"total imageIds"),Ce},[r,ts]),jo=it.useCallback(async B=>{var we;if(!r)return[];if(!B.startsWith("wadouri:"))return[];const ue=va(B),Te=il(ue).replace(/[?&]frame=\d+/i,""),Ce=Ni.current[Te];if(Ce)return Ce;try{const se=(we=$u==null?void 0:$u.wadouri)==null?void 0:we.dataSetCacheManager;if(se!=null&&se.get){const ge=se.get(Te),pe=AC(ge);if(pe.length>0)return Ni.current[Te]=pe,pe}}catch{}const me=se=>{try{return AC(Vr.parseDicom(se))}catch(ge){if(ge!=null&&ge.dataSet){const pe=AC(ge.dataSet);if(pe.length>0)return pe}return[]}};try{const se=await fetch(Te,{headers:{Range:"bytes=0-65535"}});if(se.ok||se.status===206){const ge=await se.arrayBuffer(),pe=me(new Uint8Array(ge));if(pe.length>0||se.status===200)return Ni.current[Te]=pe,pe}}catch{}try{const ge=await(await fetch(Te)).arrayBuffer(),pe=me(new Uint8Array(ge));return Ni.current[Te]=pe,pe}catch{return Ni.current[Te]=[],[]}},[r]),Ao=it.useCallback(async B=>{if(!Array.isArray(B)||B.length===0)return[];if(!r)return[{key:"SERIES_0",label:"Series 1",imageIds:So(B),bValue:null,groupValues:{}}];const ue=st=>!Array.isArray(st)||st.length===0?"":st.map(Rt=>{const Nt=Number(Rt);return Number.isFinite(Nt)?Nt.toFixed(3):"0.000"}).join(","),Te=st=>{if(Array.isArray(st)&&st.length>0){const Rt=st.map(Nt=>Number(Nt)).filter(Nt=>Number.isFinite(Nt));if(Rt.length>=3)return ue(Rt.slice(0,3))}if(typeof st=="string"){const Rt=_5(st);if(Rt.length>=3)return ue(Rt.slice(0,3));const Nt=st.trim();if(Nt)return Nt}if(st&&typeof st=="object"){const Rt=[st.x,st.y,st.z].map(Nt=>Number(Nt)).filter(Nt=>Number.isFinite(Nt));if(Rt.length>=3)return ue(Rt.slice(0,3))}return""},Ce=st=>{if(st==null)return"";const Rt=String(st).trim();if(!Rt)return"";const Nt=Number(Rt);return Number.isFinite(Nt)?Nt.toFixed(1):Rt},me=st=>{const Rt=xt("imagePlaneModule",st)||{},Nt=xt("generalImageModule",st)||{},Mt=Array.isArray(Rt==null?void 0:Rt.rowCosines)?Rt.rowCosines:null,Gt=Array.isArray(Rt==null?void 0:Rt.columnCosines)?Rt.columnCosines:null,yn=Mt&&Gt?`${ue(Mt)}|${ue(Gt)}`:"";if(yn)return yn;const bt=Nt==null?void 0:Nt.imageOrientationPatient;if(Array.isArray(bt)&&bt.length>=6)return`${ue(bt.slice(0,3))}|${ue(bt.slice(3,6))}`;if(typeof bt=="string"){const Ut=_5(bt);if(Ut.length>=6)return`${ue(Ut.slice(0,3))}|${ue(Ut.slice(3,6))}`}return"ORI_UNKNOWN"},we=new Map;B.forEach(st=>{const Rt=il(va(st)).replace(/[?&]frame=\d+/i,""),Nt=we.get(Rt)||[];Nt.push(st),we.set(Rt,Nt)}),we.forEach((st,Rt)=>{st.sort((Nt,Mt)=>{const Gt=d7(Nt)||1,yn=d7(Mt)||1;return Gt-yn}),we.set(Rt,st)});const se=new Map;await Promise.all(Array.from(we.keys()).map(async st=>{const Rt=`wadouri:${st}`,Nt=await jo(Rt);se.set(st,Nt)}));const ge=st=>{const Rt=xt("imagePlaneModule",st)||{},Nt=Array.isArray(Rt==null?void 0:Rt.imagePositionPatient)?Rt.imagePositionPatient:null;if(Nt&&Nt.length>=3){const Gt=Nt.slice(0,3).map(yn=>Number(yn));if(Gt.every(yn=>Number.isFinite(yn)))return`IPP:${Gt.map(yn=>yn.toFixed(3)).join(",")}`}const Mt=Number(Rt==null?void 0:Rt.sliceLocation);return Number.isFinite(Mt)?`SL:${Mt.toFixed(3)}`:""},pe=B.map(st=>{const Rt=xt("generalSeriesModule",st)||{},Nt=xt("generalImageModule",st)||{},Mt=xt("mrImageModule",st)||{},Gt=(Rt.seriesInstanceUID||"").trim()||void 0,yn=(Rt.seriesDescription||"").trim()||void 0,bt=Number(Rt.seriesNumber),Ut=Number(Nt.instanceNumber),Ft=me(st),qn=ge(st);let yr=Number(Mt.diffusionBValue??Mt.diffusionbValue??Mt.bValue),Zr=Number.isFinite(yr)?yr:null;if(Zr===null){const t6=il(va(st)).replace(/[?&]frame=\d+/i,""),Ns=se.get(t6)||[];if(Ns.length>0){const n6=we.get(t6)||[st],Qw=Math.max(0,n6.indexOf(st)),F1=Math.max(1,n6.length);if(Ns.length===1)Zr=Ns[0];else if(Ns.length===F1)Zr=Ns[Math.min(Ns.length-1,Qw)];else if(Ns.length===2&&F1%2===0)Zr=Qwx[st.id]).map(st=>st.id).filter(st=>{const Rt=pe.map(Gt=>Gt.ruleValues[st]).filter(Gt=>!!Gt),Nt=new Set(Rt),Mt=Rt.length/pe.length;return Nt.size>1&&Nt.size=.7}):[],Me=pe.filter(st=>!!st.seriesInstanceUID).lengthst.seriesInstanceUID).filter(st=>!!st)).size,dt=!Me,gt=pe.filter(st=>st.orientationKey!=="ORI_UNKNOWN").lengthst.orientationKey).filter(st=>st&&st!=="ORI_UNKNOWN")).size,qe=!gt;(nt>1&&!dt||ut>1&&!qe)&&kt.debug("[deriveSeriesGroupsFromImageIds] partial metadata detected; suppressing base-key grouping",{candidates:pe.length,distinctSeriesUidCount:nt,distinctOrientationCount:ut,hasMissingSeriesUid:Me,hasUnknownOrientation:gt});const Tt=new Map;if(pe.forEach(st=>{const Rt=[dt?st.seriesInstanceUID||"NO_UID":"SERIES_ANY",qe?st.orientationKey:"ORI_ANY"].join("|"),Nt=de.map(Gt=>{const yn=st.ruleValues[Gt];return yn?`${Gt}:${yn}`:""}).filter(Boolean).join("|"),Mt=Nt?`${Rt}|${Nt}`:Rt;if(!Tt.has(Mt)){const Gt={};de.forEach(yn=>{const bt=st.ruleValues[yn];bt&&(Gt[yn]=bt)}),Tt.set(Mt,{imageIds:[],seriesInstanceUID:st.seriesInstanceUID,seriesDescription:st.seriesDescription,seriesNumber:st.seriesNumber,bValue:st.bValue,groupValues:Gt})}Tt.get(Mt).imageIds.push(st.id)}),Tt.size<=1){if(de.length===0&&pe.length>=4){if(pe.filter(Gt=>!!Gt.sliceKey).length/pe.length<.9)return[{key:"SERIES_0",label:"Series 1",imageIds:So(B)}];const Nt=new Map;pe.forEach(Gt=>{Gt.sliceKey&&Nt.set(Gt.sliceKey,(Nt.get(Gt.sliceKey)||0)+1)});const Mt=Nt.size;if(Mt>=2&&Mt=2&&yn<=8&&Array.from(Nt.values()).every(Ft=>Ft===yn)){const Ft=Array.from({length:yn},()=>[]),qn=new Map;[...pe].map((Dr,ls)=>({c:Dr,idx:ls})).sort((Dr,ls)=>{const Qf=Dr.c.instanceNumber,V1=ls.c.instanceNumber;return Number.isFinite(Qf)&&Number.isFinite(V1)?Qf-V1:Dr.idx-ls.idx}).forEach(({c:Dr})=>{if(!Dr.sliceKey)return;const ls=qn.get(Dr.sliceKey)||0,Qf=Math.min(yn-1,ls);Ft[Qf].push(Dr.id),qn.set(Dr.sliceKey,ls+1)});const Zr=Ft.filter(Dr=>Dr.length>0);if(Zr.length>1)return Zr.map((Dr,ls)=>({key:`SERIES_FALLBACK_${ls}`,label:`Series ${ls+1}`,imageIds:So(Dr)}))}}}return[{key:"SERIES_0",label:"Series 1",imageIds:So(B)}]}return Array.from(Tt.entries()).map(([st,Rt],Nt)=>{const Mt=[];Rt.seriesDescription&&Mt.push(Rt.seriesDescription),Rt.seriesNumber!==void 0&&Mt.push(`#${Rt.seriesNumber}`),Rt.groupValues&&mp.forEach(yn=>{var Ut;const bt=(Ut=Rt.groupValues)==null?void 0:Ut[yn.id];bt&&(yn.id==="dwiBValue"?Mt.push(`b=${bt}`):yn.id==="dwiDirection"?Mt.push(`dir=${bt}`):yn.id==="temporalPosition"?Mt.push(`tp=${bt}`):yn.id==="triggerTime"?Mt.push(`tr=${bt}`):yn.id==="contentTime"?Mt.push(`t=${bt}`):yn.id==="echoTime"?Mt.push(`TE=${bt}`):yn.id==="echoNumber"&&Mt.push(`echo=${bt}`))}),Mt.length===0&&Rt.bValue!==null&&Rt.bValue!==void 0&&Mt.push(`b=${Math.round(Rt.bValue)}`);const Gt=Mt.length>0?Mt.join(" • "):`Series ${Nt+1}`;return{key:st,label:Gt,imageIds:So(Rt.imageIds),seriesInstanceUID:Rt.seriesInstanceUID,bValue:Rt.bValue,groupValues:Rt.groupValues}})},[m,r,jo,x]),[tn,Ra]=it.useState({rows:1,cols:1}),[La,Fi]=it.useState(!1),Xr=it.useRef([]),oo=it.useRef({}),di=it.useRef({}),[Aa,la]=it.useState(!1),[Ho,Yr]=it.useState(!0),ns=it.useCallback(B=>{const ue=B.currentTarget.getBoundingClientRect(),Te=B.clientX-ue.left,Ce=B.clientY-ue.top,me=ue.width,we=ue.height,se=Math.min(me,we)*.24,ge=[{zone:"left",distance:Te},{zone:"right",distance:me-Te},{zone:"top",distance:Ce},{zone:"bottom",distance:we-Ce}];return ge.sort((pe,de)=>pe.distance-de.distance),ge[0].distance<=se?ge[0].zone:"center"},[]),Hi=it.useCallback((B,ue,Te)=>{const Ce=ue-B.left,me=Te-B.top,we=B.width,se=B.height,ge=Math.min(we,se)*.24,pe=[{zone:"left",distance:Ce},{zone:"right",distance:we-Ce},{zone:"top",distance:me},{zone:"bottom",distance:se-me}];return pe.sort((de,Ve)=>de.distance-Ve.distance),pe[0].distance<=ge?pe[0].zone:"center"},[]),Nr=it.useCallback(B=>B==="left"||B==="right"?tn.cols<3?B:"center":(B==="top"||B==="bottom")&&tn.rows<3?B:"center",[tn]),Os=[];for(let B=1;B<=3;B++)for(let ue=1;ue<=3;ue++)Os.push({rows:B,cols:ue});const[fn,Ki]=it.useState(()=>Array(tn.rows*tn.cols).fill({index:0,total:0,windowCenter:"",windowWidth:"",slicePosition:"",modality:"",orientation:"",resolution:"",spacing:"",focalPoint:""})),[rs,Wc]=it.useState({}),tc=it.useRef(Array(Y).fill("")),xo=it.useRef(Array(Y).fill(null)),Cr=it.useRef(Array(Y).fill(null)),ua=it.useRef(Array(Y).fill(null)),hi=it.useRef(Array(Y).fill(0)),[dn,ao]=it.useState(()=>Array(Y).fill("stack")),[Di,Ms]=it.useState(()=>Array(tn.rows*tn.cols).fill(!1)),[mr,so]=it.useState({Primary:bf.toolName,Auxiliary:Ec.toolName,Secondary:gu.toolName,Primary_and_Secondary:gl.toolName,Fourth_Button:Bh.toolName,Wheel:bf.toolName}),[No,fa]=it.useState({Primary:Gf.toolName,Auxiliary:Iu.toolName,Secondary:$h.toolName}),[Jr,nc]=it.useState(1),[Ul,zc]=it.useState(!1);it.useEffect(()=>{const B=Te=>{Te.ctrlKey&&zc(!0)},ue=Te=>{Te.ctrlKey||zc(!1)};return window.addEventListener("keydown",B),window.addEventListener("keyup",ue),()=>{window.removeEventListener("keydown",B),window.removeEventListener("keyup",ue)}},[]),it.useEffect(()=>{const B=window.matchMedia("(max-width: 768px), (pointer: coarse)"),ue=()=>{const Te=B.matches;Ae(Te),Te||(Pe(!1),O(null))};return ue(),typeof B.addEventListener=="function"?(B.addEventListener("change",ue),()=>B.removeEventListener("change",ue)):(B.addListener(ue),()=>B.removeListener(ue))},[]);const $c=it.useCallback(B=>{if(!Se)return;ht(B),O(B),Pe(!0),z(!0),E(!1);const ue=a.current;if(ue&&document.fullscreenElement!==ue){const Te=ue.requestFullscreen||ue.webkitRequestFullscreen||ue.msRequestFullscreen;if(Te)try{const Ce=Te.call(ue);Ce&&typeof Ce.catch=="function"&&Ce.catch(()=>{})}catch{}}},[Se]);it.useEffect(()=>{!Se||!Ue||!j||je!==null&&O(je)},[je,Se,Ue,j]);const[is,os]=it.useState(!1),[rc,jc]=it.useState(null),ic=(B,ue)=>{_a&&_a(ue),pt(Te=>{const Ce=[...Te];return Ce[B]=ue,Ce})},Bl=(B,ue,Te)=>{const Ce=Rr.getAllAnnotations()||[];Ce.forEach(we=>{we.annotationUID===ue&&(we.isSelected=!1)}),Rr.removeAnnotation(ue),ae.current.render();const me=Te.filter(we=>we.annotationUID!==ue);pt(we=>{const se=[...we],ge=me.length>0?me[0].annotationUID:null;return se[B]=ge,Ce.forEach(pe=>{pe.isSelected=pe.annotationUID===ge}),_a(ge),ae.current.render(),se})},Gl=()=>{const B=Yt.findIndex(me=>me&&me.length>0);if(B===-1){jc("No images loaded."),os(!0);return}const ue=Yt[B][0],Te=["imagePlaneModule","generalSeriesModule","generalStudyModule","patientModule","imagePixelModule","voiLutModule","modalityLutModule","sopCommonModule","petIsotopeModule","multiframeModule","cineModule","overlayPlaneModule","generalImageModule","stackModule","voiLutModule","modalityLutModule","petSeriesModule","petImageModule","petIsotopeModule","petSeriesModule","petImageModule","petIsotopeModule","petSeriesModule","petImageModule","petIsotopeModule","petSeriesModule","petImageModule","petIsotopeModule"],Ce={};Te.forEach(me=>{const we=xt(me,ue);we!==void 0&&(Ce[me]=we)}),jc(Re.jsx("pre",{style:{maxHeight:600,overflow:"auto",fontSize:13,color:"#fff"},children:JSON.stringify(Ce,null,2)})),os(!0)};it.useEffect(()=>{try{const B=localStorage.getItem(l),ue=localStorage.getItem(f);B&&so(JSON.parse(B)),ue&&fa(JSON.parse(ue));const Te=localStorage.getItem(u);if(Te){const we=JSON.parse(Te);typeof(we==null?void 0:we.mouseSensitivity)=="number"&&nc(we.mouseSensitivity)}const Ce=localStorage.getItem(s7);if(Ce){const we=JSON.parse(Ce);typeof(we==null?void 0:we.minLevel)=="string"?p(S5(we.minLevel)):typeof(we==null?void 0:we.debug)=="boolean"&&p(we.debug?"debug":"warn"),typeof(we==null?void 0:we.format)=="string"&&y(jp(we.format))}const me=localStorage.getItem(c7);if(me){const we=JSON.parse(me);if(typeof(we==null?void 0:we.advancedGroupingEnabled)=="boolean"&&w(we.advancedGroupingEnabled),we!=null&&we.groupingRuleEnabled&&typeof we.groupingRuleEnabled=="object"){const se=l7();mp.forEach(ge=>{typeof we.groupingRuleEnabled[ge.id]=="boolean"&&(se[ge.id]=we.groupingRuleEnabled[ge.id])}),C(se)}}}catch{}},[]),it.useEffect(()=>{try{localStorage.setItem(l,JSON.stringify(mr))}catch{}},[mr]),it.useEffect(()=>{try{localStorage.setItem(f,JSON.stringify(No))}catch{}},[No]),it.useEffect(()=>{try{localStorage.setItem(u,JSON.stringify({mouseSensitivity:Jr}))}catch{}},[Jr]),it.useEffect(()=>{T8({minLevel:g,format:v});try{localStorage.setItem(s7,JSON.stringify({minLevel:g,format:v}))}catch{}},[g,v]),it.useEffect(()=>{try{localStorage.setItem(c7,JSON.stringify({advancedGroupingEnabled:m,groupingRuleEnabled:x}))}catch{}},[m,x]),it.useEffect(()=>{if(_t.length===0)return;let B=!1;return(async()=>{const Te=await Promise.all(_t.map(async Ce=>{if(Ce.groupingSource==="declared"&&(Ce.seriesGroups||[]).length>0)return Ce;const me=await Ao(Ce.imageIds);return{...Ce,seriesGroups:me,groupingSource:"derived"}}));B||(Ne(Te),Ke(Ce=>{var we;const me=[...Ce];for(let se=0;se{var we;const me=[...Ce];for(let se=0;se{var we,se,ge;const me=[...Ce];for(let pe=0;pe{B=!0}},[m,x]),it.useEffect(()=>(window.loadDicomStackFromFiles=B=>{const ue=Array.from(B);ss({target:{files:ue}})},()=>{window.loadDicomStackFromFiles=void 0}),[]),it.useEffect(()=>{const B=()=>{Bt(!1),sn(null),Dt(null)};return document.addEventListener("dragend",B),()=>document.removeEventListener("dragend",B)},[]);const[Hc,oc]=it.useState(!1),[Kc,Ps]=it.useState(!1);it.useEffect(()=>{const B=xi(De);B&&["ArrowAnnotate","NoLabelArrowAnnotate","Length","RectangleROI","EllipticalROI","PlanarFreehandROI","PlanarFreehandContourSegmentation"].forEach(ue=>{B.setToolConfiguration(ue,{color:"#00e676",selectedColor:"#ffeb3b"})})},[De]),it.useEffect(()=>{const B=Ce=>{Ce.altKey&&oc(!0),Ce.shiftKey&&Ps(!0)},ue=Ce=>{Ce.altKey||oc(!1),Ce.shiftKey||Ps(!1)},Te=()=>{oc(!1),Ps(!1)};return window.addEventListener("keydown",B),window.addEventListener("keyup",ue),window.addEventListener("blur",Te),()=>{window.removeEventListener("keydown",B),window.removeEventListener("keyup",ue),window.removeEventListener("blur",Te)}},[]),it.useEffect(()=>{const B=xi(De);if(!B)return;if(Kc||Ho&&Hc){const Te=tn.rows*tn.cols;Yt.slice(0,Te).filter((me,we)=>dn[we]==="stack"&&Array.isArray(me)&&me.length>0).forEach(me=>{Zn(me,{force:!0}).catch(we=>{kt.warn("Reference cursor metadata warm-up failed:",we)})}),B.hasTool(gs.toolName)||B.addTool(gs.toolName),B.setToolEnabled(gs.toolName),B.setToolActive(gs.toolName)}else B.hasTool(gs.toolName)&&B.setToolDisabled(gs.toolName)},[Hc,Kc,Ho,tn.rows,tn.cols,Yt,dn,Zn]);const as=it.useCallback(()=>{[xi(De)].forEach(ue=>{if(ue){md.forEach(we=>{ue.setToolPassive(we.value,{removeAllBindings:!0})}),ue.setToolDisabled(gs.toolName);const Te={};Object.entries(mr).forEach(([we,se])=>{Te[se]||(Te[se]=[]);const ge=q2.find(pe=>pe.value===we);ge?Te[se].push({mouseButton:ge.mask}):qg[we]&&Te[se].push({mouseButton:qg[we]})}),Object.entries(No).forEach(([we,se])=>{if(!se)return;Te[se]||(Te[se]=[]);const ge=q2.find(pe=>pe.value===we);ge?Te[se].push({mouseButton:ge.mask,modifierKey:o7.Ctrl}):qg[we]&&Te[se].push({mouseButton:qg[we],modifierKey:o7.Ctrl})}),Object.entries(Te).forEach(([we,se])=>{ue.setToolActive(we,{bindings:se})}),typeof ue.setToolConfiguration=="function"&&ue.setToolConfiguration(gu.toolName,{mouseSensitivity:Jr});const Ce=mr.Primary;if(Ce){const we=[...Te[Ce]||[],{numTouchPoints:1}];ue.setToolActive(Ce,{bindings:we})}const me=[...Te[Ec.toolName]||[],{numTouchPoints:2}];ue.setToolActive(Ec.toolName,{bindings:me});try{const we=mr.Primary,se=mr.Wheel,ge=mr.Auxiliary,pe=we===Ec.toolName||ge===Ec.toolName,de=we===gl.toolName||se===gl.toolName||mr.Primary_and_Secondary===gl.toolName;Xr.current.forEach(Ve=>{if(!Ve)return;const Me=Ve._externalPanZoom;Me&&(typeof Me.setAllowPan=="function"&&Me.setAllowPan(!!pe),typeof Me.setAllowZoom=="function"&&Me.setAllowZoom(!!de))})}catch{}}})},[mr,No,Jr]);it.useEffect(()=>{as()},[Jr,as]);const[ac,Rs]=it.useState(!1),[sc,Ls]=it.useState("add"),da=it.useRef(null),qc=it.useCallback(B=>{T&&(B.preventDefault(),B.stopPropagation(),P.current={resizing:!0,startX:B.clientX,startWidth:b},document.body.style.cursor="col-resize",document.body.style.userSelect="none")},[T,b]);it.useEffect(()=>{const B=Te=>{if(!P.current.resizing)return;const Ce=P.current.startX-Te.clientX,me=Math.max(M,Math.min(L,P.current.startWidth+Ce));D(me)},ue=()=>{P.current.resizing&&(P.current.resizing=!1,document.body.style.cursor="",document.body.style.userSelect="")};return window.addEventListener("mousemove",B),window.addEventListener("mouseup",ue),()=>{window.removeEventListener("mousemove",B),window.removeEventListener("mouseup",ue),document.body.style.cursor="",document.body.style.userSelect=""}},[]);const cc=ac?V-W/2:-W+A;it.useEffect(()=>{try{da.current&&(da.current.setAttribute("webkitdirectory","true"),da.current.setAttribute("directory",""),da.current.setAttribute("mozdirectory",""))}catch{}},[]);async function Xc(B,ue=""){const Te=[],Ce=B.entries?B.entries():B.values();for await(const me of Ce)try{let we,se;if(Array.isArray(me)&&me.length>=2?(se=me[0],we=me[1]):(we=me,se=we.name),!we)continue;if(we.kind==="file"){const ge=await we.getFile();try{Object.defineProperty(ge,"webkitRelativePath",{value:ue+(se||we.name),configurable:!0})}catch{}Te.push(ge)}else if(we.kind==="directory"){const ge=await Xc(we,ue+(se||we.name)+"/");Te.push(...ge)}}catch(we){kt.debug("collectFilesFromDirectoryHandle: skipping entry due to error",we)}return Te}const Yc=async()=>{var B;if(window.showDirectoryPicker)try{const ue=await window.showDirectoryPicker(),Te=await Xc(ue);Te&&Te.length>0?await ss({target:{files:Te}}):alert("No files found in selected folder.");return}catch(ue){kt.warn("showDirectoryPicker failed or cancelled",ue)}(B=da.current)==null||B.click()},As=it.useRef(null),ss=async B=>{const ue=B.target.files;if(!ue||ue.length===0)return;la(!1);const Te=Array.from(ue).sort((se,ge)=>se.name.localeCompare(ge.name)),Ce=await Promise.all(Te.map(async se=>{const ge=se.type&&se.type.startsWith("image/");let pe,de,Ve,Me,nt=1,dt=!1;if(!ge)try{const gt=await se.arrayBuffer(),ut=Vr.parseDicom(new Uint8Array(gt));pe=ut.string("x0020000d"),de=ut.string("x0020000e");const qe=ut.string("x00200013");qe!=null&&qe!==""&&(Ve=parseInt(qe,10));const Tt=ut.string("x00201041")||ut.string("x00201040");Tt!=null&&Tt!==""&&(Me=parseFloat(Tt));const Lt=ut.string("x00280008");if(Lt!=null&&Lt!==""){const st=Number(Lt);Number.isFinite(st)&&st>1&&(nt=Math.floor(st))}dt=!0}catch{dt=!1}const et=ge?`external:${URL.createObjectURL(se)}`:`wadouri:${URL.createObjectURL(se)}`;return{file:se,imageId:et,studyInstanceUID:pe,seriesInstanceUID:de,instanceNumber:Ve,sliceLocation:Me,numberOfFrames:nt,isImage:ge,parsedSuccessfully:dt}})),me=new Map;for(const se of Ce){if(!se.isImage&&!se.parsedSuccessfully){kt.debug("Skipping non-DICOM/non-image file:",se.file.name);continue}const ge=se.seriesInstanceUID||se.studyInstanceUID||(se.file.webkitRelativePath?se.file.webkitRelativePath.split("/")[0]:se.file.name);me.has(ge)||me.set(ge,{entries:[],studyInstanceUID:se.studyInstanceUID,seriesInstanceUID:se.seriesInstanceUID}),me.get(ge).entries.push(se)}const we=[];for(const[se,ge]of me.entries()){const pe=ge.entries;pe.sort((Me,nt)=>Aa&&Me.sliceLocation!==void 0&&nt.sliceLocation!==void 0?Me.sliceLocation-nt.sliceLocation:Me.instanceNumber!==void 0&&nt.instanceNumber!==void 0?Me.instanceNumber-nt.instanceNumber:(Me.file.webkitRelativePath||Me.file.name).localeCompare(nt.file.webkitRelativePath||nt.file.name));const de=pe.flatMap(Me=>{if(Me.isImage||!Number.isFinite(Me.numberOfFrames)||Me.numberOfFrames<=1)return[Me.imageId];const nt=[];for(let dt=1;dt<=Me.numberOfFrames;dt++)nt.push(f7(Me.imageId,dt));return nt}),Ve=await Ao(de);we.push({imageIds:de,studyInstanceUID:ge.studyInstanceUID,seriesInstanceUID:ge.seriesInstanceUID,seriesGroups:Ve})}if(we.length!==0)if(sc==="replace"){try{const se=ae.current;if(se)for(let ge=0;ge{var ge,pe;const se=Array(Y).fill([]);for(let de=0;de{const se=Array(Y).fill(null).map(()=>[]);for(let ge=0;ge{const ge=[...se,...we];en(pe=>{var Me,nt;const de=[...pe],Ve=we[we.length-1];return de[0]=((nt=(Me=Ve.seriesGroups)==null?void 0:Me[0])==null?void 0:nt.imageIds)||Ve.imageIds,de}),_r(pe=>{const de=[...pe];return de[0]=ge.length-1,de}),Ke(pe=>{var Ve;const de=[...pe];return de[0]=((Ve=we[we.length-1])==null?void 0:Ve.seriesGroups)||[],de}),qt(pe=>{const de=[...pe];return de[0]=0,de});for(const pe of we)Zn(pe.imageIds);return ge})},Wl=(B,ue)=>{so(Te=>({...Te,[B]:ue}))},br=it.useCallback((B,ue)=>{var et,gt;if(!ue)return;let Te=0,Ce=0,me="",we="",se="",ge="",pe="",de="",Ve="",Me="",nt,dt;if(dn[B]==="stack"){Te=typeof ue.getCurrentImageIdIndex=="function"?ue.getCurrentImageIdIndex():0;const ut=typeof ue.getImageIds=="function"?ue.getImageIds():[];Ce=ut.length;const qe=ut[Te];if(qe){if(kt.debug("[updateOverlay] Current image:",qe.slice(0,80),"frameIndex status:",nt,"totalFrames:",dt),qe.includes("&frame=")){const Nt=qe.match(/&frame=(\d+)/);if(Nt){nt=parseInt(Nt[1],10),kt.debug("[updateOverlay] Frame detected:",nt);const Mt=qe.split("&frame=")[0],Gt=xt("multiframeModule",Mt);if(Gt!=null&&Gt.numberOfFrames)dt=Gt.numberOfFrames,kt.debug("[updateOverlay] Total frames from metadata:",dt);else{const yn=ut.map(bt=>{const Ut=bt.match(/&frame=(\d+)/);return Ut?parseInt(Ut[1],10):null}).filter(bt=>bt!==null&&typeof bt=="number");yn.length>0&&(dt=Math.max(...yn),kt.debug("[updateOverlay] Total frames from imageIds:",dt))}}}else kt.debug("[updateOverlay] No frame query in imageId. imageIds.length:",ut.length);const Tt=xt("generalSeriesModule",qe),Lt=xt("imagePlaneModule",qe),st=xt("imagePixelModule",qe);ge=(Tt==null?void 0:Tt.modality)||"",st!=null&&st.rows&&(st!=null&&st.columns)&&(de=`${st.columns} x ${st.rows}`);const Rt=[Lt==null?void 0:Lt.columnPixelSpacing,Lt==null?void 0:Lt.rowPixelSpacing,Lt==null?void 0:Lt.sliceThickness].filter(Nt=>Nt!=null&&Nt!=="");Rt.length>0&&(Ve=Rt.join(" x "))}if(typeof ue.getCamera=="function"){const Tt=ue.getCamera();Tt!=null&&Tt.focalPoint&&Array.isArray(Tt.focalPoint)&&(Me=Tt.focalPoint.map(Lt=>Lt.toFixed(1)).join(", "))}if(qe&&Wc(Tt=>Tt[qe]?Tt:{...Tt,[qe]:!0}),typeof ue.getProperties=="function"){const Tt=ue.getProperties();if(Tt.voiRange){const{lower:Lt,upper:st}=Tt.voiRange;me=((st+Lt)/2).toFixed(0),we=(st-Lt).toFixed(0),xo.current[B]===null&&(xo.current[B]={lower:Lt,upper:st})}}}else if(dn[B]==="volume"){if(typeof ue.getSliceIndex=="function"&&(Te=ue.getSliceIndex()),typeof ue.getNumberOfSlices=="function"&&(Ce=ue.getNumberOfSlices()),typeof ue.getProperties=="function"){let qe;if(ue.volumeIds&&ue.volumeIds.size>0){const Tt=Array.from(ue.volumeIds)[0];qe=ue.getProperties(Tt)}else qe=ue.getProperties();if(qe&&qe.voiRange){const{lower:Tt,upper:Lt}=qe.voiRange;me=((Lt+Tt)/2).toFixed(0),we=(Lt-Tt).toFixed(0),xo.current[B]===null&&(xo.current[B]={lower:Tt,upper:Lt})}}if(typeof ue.getSlicePlaneCoordinates=="function"){const qe=ue.getSlicePlaneCoordinates();qe&&typeof qe.position=="number"&&(se=qe.position.toFixed(2)+" mm")}const ut=(et=Yt[B])==null?void 0:et[0];if(ut){const qe=xt("generalSeriesModule",ut),Tt=xt("imagePlaneModule",ut),Lt=xt("imagePixelModule",ut);ge=(qe==null?void 0:qe.modality)||"",pe=String(((gt=ue.viewportProperties)==null?void 0:gt.orientation)||"").toUpperCase(),Lt!=null&&Lt.rows&&(Lt!=null&&Lt.columns)&&(de=`${Lt.columns} x ${Lt.rows}`);const st=[Tt==null?void 0:Tt.columnPixelSpacing,Tt==null?void 0:Tt.rowPixelSpacing,Tt==null?void 0:Tt.sliceThickness].filter(Rt=>Rt!=null&&Rt!=="");st.length>0&&(Ve=st.join(" x "))}if(typeof ue.getCamera=="function"){const qe=ue.getCamera();qe!=null&&qe.focalPoint&&Array.isArray(qe.focalPoint)&&(Me=qe.focalPoint.map(Tt=>Tt.toFixed(1)).join(", "))}}Ki(ut=>{const qe=[...ut];return qe[B]={index:Te+1,total:Ce,windowCenter:me,windowWidth:we,slicePosition:se,modality:ge,orientation:pe,resolution:de,spacing:Ve,focalPoint:Me,frameIndex:nt,totalFrames:dt},qe})},[dn,Yt]);it.useEffect(()=>{for(let B=0;B{var bt;const me=So(ue.map(va));if(me.length===0)return;const we=_t.findIndex(Ut=>{const Ft=So((Ut.imageIds||[]).map(va));return Ft.length===me.length&&Ft.every((qn,yr)=>qn===me[yr])});if(we!==-1){await ha(B,we,Ce),ht(B);return}const se=await Lo(me);if(se.length===0)return;await Zn(se,{force:!!r});const ge=await Ao(se),pe=((bt=ge[0])==null?void 0:bt.imageIds)||se;let de=-1;Ne(Ut=>(de=Ut.length,[...Ut,{imageIds:se,name:Te,seriesGroups:ge,groupingSource:"derived"}]));const Ve=de,Me=Nr(Ce);if(Me==="center"){Er("displayset");try{ao(Ut=>{const Ft=[...Ut];return Ft[B]="stack",Ft}),en(Ut=>{const Ft=[...Ut];return Ft[B]=pe,Ft}),_r(Ut=>{const Ft=[...Ut];return Ft[B]=Ve,Ft}),Ke(Ut=>{const Ft=[...Ut];return Ft[B]=ge,Ft}),qt(Ut=>{const Ft=[...Ut];return Ft[B]=0,Ft}),ht(B),await Zn(pe)}finally{Er(null)}return}const nt=tn.rows,dt=tn.cols,et=Math.floor(B/dt),gt=B%dt,ut=Me==="top"||Me==="bottom"?nt+1:nt,qe=Me==="left"||Me==="right"?dt+1:dt;if(ut>3||qe>3||ut*qe>Y){Er("displayset");try{ao(Ut=>{const Ft=[...Ut];return Ft[B]="stack",Ft}),en(Ut=>{const Ft=[...Ut];return Ft[B]=se,Ft}),_r(Ut=>{const Ft=[...Ut];return Ft[B]=Ve,Ft}),ht(B),await Zn(se)}finally{Er(null)}return}const Tt=Me==="top"?et:Me==="bottom"?et+1:et,Lt=Me==="left"?gt:Me==="right"?gt+1:gt,st=Tt*qe+Lt,Rt=Array(Y).fill([]),Nt=Array(Y).fill("stack"),Mt=Array(Y).fill(0),Gt=Array(Y).fill(null).map(()=>[]),yn=Array(Y).fill(0);for(let Ut=0;Utgt||Me==="left"?qn+1:qn),(Me==="top"||Me==="bottom")&&qn===gt&&(yr=Ftet||Me==="top"?Ft+1:Ft);const Dr=yr*qe+Zr;Rt[Dr]=Yt[Ut]||[],Nt[Dr]=dn[Ut]||"stack",Mt[Dr]=En[Ut]??0,Gt[Dr]=dr[Ut]||[],yn[Dr]=Et[Ut]??0}Rt[st]=pe,Nt[st]="stack",Mt[st]=de,Gt[st]=ge,yn[st]=0,Er("displayset");try{lc(),Ra({rows:ut,cols:qe}),en(Rt),ao(Nt),_r(Mt),Ke(Gt),qt(yn),ht(st),await Zn(pe)}finally{Er(null)}},ha=async(B,ue,Te)=>{var yn;const Ce=_t[ue];if(!Ce)return;let me=Ce.imageIds||[];const we=Ce.groupingSource==="declared"&&(Ce.seriesGroups||[]).length>0;me=!(we&&me.length>1)?await Lo(me):So((me||[]).map(va)),await Zn(me,{force:!!r});const pe=we?Ce.seriesGroups||[]:await Ao(me);Ne(bt=>{const Ut=[...bt];return Ut[ue]?(Ut[ue]={...Ut[ue],seriesGroups:pe,imageIds:me,groupingSource:we?"declared":"derived"},Ut):bt});const de=((yn=pe[0])==null?void 0:yn.imageIds)||me,Ve=Nr(Te);if(Ve==="center"){await Vi(B,ue),ht(B);return}const Me=tn.rows,nt=tn.cols,dt=Math.floor(B/nt),et=B%nt,gt=Ve==="top"||Ve==="bottom"?Me+1:Me,ut=Ve==="left"||Ve==="right"?nt+1:nt;if(gt>3||ut>3||gt*ut>Y){await Vi(B,ue),ht(B);return}const qe=Array(Y).fill([]),Tt=Array(Y).fill("stack"),Lt=Array(Y).fill(0),st=Array(Y).fill(null).map(()=>[]),Rt=Array(Y).fill(0),Nt=Ve==="top"?dt:Ve==="bottom"?dt+1:dt,Mt=Ve==="left"?et:Ve==="right"?et+1:et,Gt=Nt*ut+Mt;for(let bt=0;btet?yr=Ft+1:yr=Ve==="left"?Ft+1:Ft),(Ve==="top"||Ve==="bottom")&&Ft===et&&(Utdt?qn=Ut+1:qn=Ve==="top"?Ut+1:Ut);const Zr=qn*ut+yr;qe[Zr]=Yt[bt]||[],Tt[Zr]=dn[bt]||"stack",Lt[Zr]=En[bt]??0,st[Zr]=dr[bt]||[],Rt[Zr]=Et[bt]??0}qe[Gt]=de,Tt[Gt]="stack",Lt[Gt]=ue,st[Gt]=pe||[],Rt[Gt]=0,Er("displayset");try{lc(),Ra({rows:gt,cols:ut}),en(qe),ao(Tt),_r(Lt),Ke(st),qt(Rt),ht(Gt),await Zn(de)}finally{Er(null)}},fc=it.useCallback((B,ue)=>{if(!(Se&&Ue)||(ue.pointerType||"").toLowerCase()==="mouse")return;ue.preventDefault(),ue.stopPropagation(),Qe.current=Date.now()+400;const Te=tn.rows*tn.cols;let Ce=null,me="center";Xe({stackIdx:B,x:ue.clientX,y:ue.clientY,targetViewportIdx:null,zone:"center"});const we=de=>{let Ve=null,Me="center";for(let nt=0;ntet.right||de.clientYet.bottom)){Ve=nt,Me=Nr(Hi(et,de.clientX,de.clientY));break}}Ce=Ve,me=Me,Xe(nt=>nt&&{...nt,x:de.clientX,y:de.clientY,targetViewportIdx:Ve,zone:Me}),sn(Ve!==null?{viewportIdx:Ve,zone:Me}:null)},se=async()=>{if(window.removeEventListener("pointermove",we),window.removeEventListener("pointerup",ge),window.removeEventListener("pointercancel",pe),sn(null),Xe(null),Ce!==null)try{await ha(Ce,B,me),E(!1),ht(Ce),O(Ce)}catch(de){kt.error("Failed mobile pointer stack drop:",de)}Qe.current=Date.now()+400},ge=()=>{se()},pe=()=>{se()};window.addEventListener("pointermove",we,{passive:!0}),window.addEventListener("pointerup",ge,{passive:!0}),window.addEventListener("pointercancel",pe,{passive:!0})},[ha,Hi,Se,Ue,Nr,tn]);it.useEffect(()=>{const B=async()=>{var we;if(kt.debug("setup"),!c.current){c.current=!0,await _ee(),await NU(),AW();try{Lp("external",se=>({promise:(async()=>{const pe=se.replace(/^external:/,""),de=new Image;de.crossOrigin="anonymous",de.src=pe,await new Promise((ut,qe)=>{de.onload=()=>ut(!0),de.onerror=Tt=>qe(Tt)});const Ve=de.naturalWidth||de.width,Me=de.naturalHeight||de.height,nt=document.createElement("canvas");nt.width=Ve,nt.height=Me;const dt=nt.getContext("2d");if(!dt)throw new Error("Unable to create canvas context");dt.drawImage(de,0,0,Ve,Me);const et=dt.getImageData(0,0,Ve,Me);return{imageId:se,minPixelValue:0,maxPixelValue:255,slope:1,intercept:0,rows:Me,columns:Ve,height:Me,width:Ve,color:!0,rgba:!0,sizeInBytes:et.data.length,getPixelData:()=>et.data,getImageData:()=>et,getCanvas:()=>nt}})()}))}catch(se){kt.warn("Failed to register external image loader",se)}}let Te=ae.current;Te||(Te=new ZN(ce),ae.current=Te);let Ce=xi(De);Ce||(Ce=USe(De)),dn.slice(0,tn.rows*tn.cols).filter(se=>se==="volume").length,cs(Ce);for(let se=0;se{if(de.offsetWidth>0&&de.offsetHeight>0){Te.resize();const et=Te.getViewport(pe);et&&typeof et.resize=="function"&&et.resize(),et&&typeof et.render=="function"&&et.render()}});dt.observe(de),de._resizeObserver=dt}if(dn[se]==="stack"){if(ge&&ge.length>0){const dt=ge[0];if(Mo(dt))try{try{const ut=de._externalPanZoom;ut&&typeof ut.cleanup=="function"&&ut.cleanup()}catch{}de.innerHTML="";const et=document.createElement("img");et.style.width="100%",et.style.height="100%",et.style.objectFit="contain",et.style.display="block",et.src=dt.replace(/^external:/,""),et.setAttribute("draggable","false"),de.appendChild(et);const gt=Bn(de,et);de._externalPanZoom=gt,Ce.removeViewports(ce,pe)}catch(et){kt.warn("Failed to render external image in viewport",et)}else try{Me.setStack(ge)}catch(et){kt.warn("viewport.setStack failed",et)}}Za?Ce.removeViewports(ce,pe):Ce.addViewport(pe,ce)}else if(dn[se]==="volume"){Ce.addViewport(pe,ce);const dt=`myVolumeId_${se}`;if((await Ny(dt,{imageIds:ge})).load(),Me.setVolumes([{volumeId:dt}]),typeof Me.getNumberOfSlices=="function"){const ut=Me.getNumberOfSlices(),qe=hi.current[se]||0,Tt=Math.max(0,Math.min(Math.max(0,ut-1),qe));To(Me.element,{imageIndex:Tt})}Me.render(),de._overlayListener&&Me.element.removeEventListener(Xg,de._overlayListener);const gt=()=>br(se,Me);Me.element.addEventListener(Xg,gt),de._overlayListener=gt,br(se,Me);continue}if(Me.render(),!_e.current){di.current[se]!==void 0&&typeof Me.setImageIdIndex=="function"&&To(Me.element,{imageIndex:di.current[se]});const dt=oo.current[se];if(dt&&typeof Me.setProperties=="function"){const{voiRange:et,invert:gt,interpolationType:ut,VOILUTFunction:qe,colormap:Tt}=dt,Lt={};et&&et.lower!==void 0&&et.upper!==void 0&&(Lt.voiRange=et),gt!==void 0&&(Lt.invert=gt),ut!==void 0&&(Lt.interpolationType=ut),qe&&(Lt.VOILUTFunction=qe),Tt!=null&&(typeof Tt=="string"||typeof Tt=="object"&&!("actor"in Tt))&&(Lt.colormap=Tt),setTimeout(()=>{kt.debug("Restoring properties (timeout) for viewport",se,Lt),Me.setProperties(Lt),Me.render()},100)}}de._overlayListener&&Me.element.removeEventListener(Xg,de._overlayListener);const nt=()=>br(se,Me);Me.element.addEventListener(Xg,nt),de._overlayListener=nt,br(se,Me)}for(let se=0;se=2?(Ce.hasTool(fl.toolName)||Ce.addTool(fl.toolName),Ce.setToolEnabled(fl.toolName),Ce.setToolConfiguration(fl.toolName,{}),Ce.setToolActive(fl.toolName,{bindings:[{mouseButton:qg.Primary}]})):Ce.hasTool(fl.toolName)&&Ce.setToolDisabled(fl.toolName)),as()},ue=requestAnimationFrame(()=>{B()});return()=>{Xr.current.forEach(Te=>{Te&&Te._resizeObserver&&(Te._resizeObserver.disconnect(),delete Te._resizeObserver)}),cancelAnimationFrame(ue)}},[s,br,tn,dn,Yt]);const Ko=it.useCallback((B,ue,Te)=>{const Ce=`CT_${B}`;try{const me=ae.current;if(me){const we=me.getViewport(Ce);we&&typeof we.setProperties=="function"&&(kt.debug(`Applying preset to viewport ${B}: center=${ue}, width=${Te}`),we.setProperties({voiRange:{lower:ue-Te/2,upper:ue+Te/2}}),we.render(),br(B,we))}}catch{}},[br]),Ui=it.useCallback((B,ue=!1)=>{const Te=`CT_${B}`;try{const Ce=ae.current,me=Ce==null?void 0:Ce.getViewport(Te);if(!me)return!1;const we=typeof me.getImageIds=="function"?me.getImageIds():Yt[B]||[],se=typeof me.getCurrentImageIdIndex=="function"?me.getCurrentImageIdIndex():0,ge=we[se]||we[0],pe=xo.current[B],de=ge?xt("voiLutModule",ge)||{}:{},Ve=ge?xt("imagePixelModule",ge)||{}:{},Me=ge?xt("modalityLutModule",ge)||{}:{},nt=Array.isArray(de.windowCenter)?de.windowCenter[0]:de.windowCenter,dt=Array.isArray(de.windowWidth)?de.windowWidth[0]:de.windowWidth,et=Number(Ve.smallestPixelValue??Ve.smallestImagePixelValue),gt=Number(Ve.largestPixelValue??Ve.largestImagePixelValue),ut=Number(Me.rescaleSlope??1),qe=Number(Me.rescaleIntercept??0);if(pe)me.setProperties({voiRange:pe});else if(Number.isFinite(Number(nt))&&Number.isFinite(Number(dt))&&Number(dt)>0){const Tt=Number(nt),Lt=Number(dt);me.setProperties({voiRange:{lower:Tt-Lt/2,upper:Tt+Lt/2}})}else Number.isFinite(et)&&Number.isFinite(gt)&>>et?me.setProperties({voiRange:{lower:et*ut+qe,upper:gt*ut+qe}}):typeof me.resetProperties=="function"&&me.resetProperties();return ue&&typeof me.resetCamera=="function"&&me.resetCamera(),me.render(),br(B,me),!0}catch(Ce){return kt.warn("Failed to apply default window level",Ce),!1}},[br,Yt]),Co=it.useCallback(B=>{const ue=`CT_${B}`;(async()=>{const Te=ae.current;if(!Te)return;const Ce=Te.getViewport(ue);if(!Ce)return;const me=typeof Ce.getImageIds=="function"?Ce.getImageIds():Yt[B]||[],we=typeof Ce.getCurrentImageIdIndex=="function"?Ce.getCurrentImageIdIndex():0,se=me[we]||me[0];if(!se){Ui(B);return}const ge=xt("imagePixelModule",se)||{},pe=xt("modalityLutModule",se)||{},de=xt("voiLutModule",se)||{},Ve=xo.current[B];let Me=Number(ge.smallestPixelValue??ge.smallestImagePixelValue),nt=Number(ge.largestPixelValue??ge.largestImagePixelValue),dt=Number(pe.rescaleSlope??1),et=Number(pe.rescaleIntercept??0);if(!Number.isFinite(Me)||!Number.isFinite(nt)||nt<=Me)try{const qe=await Ml(se);Me=Number(qe==null?void 0:qe.minPixelValue),nt=Number(qe==null?void 0:qe.maxPixelValue),dt=Number((qe==null?void 0:qe.slope)??dt),et=Number((qe==null?void 0:qe.intercept)??et)}catch{const Tt=me.filter(Lt=>!!Lt).slice(0,6);for(const Lt of Tt)try{const st=await Ml(Lt);if(Me=Number(st==null?void 0:st.minPixelValue),nt=Number(st==null?void 0:st.maxPixelValue),dt=Number((st==null?void 0:st.slope)??dt),et=Number((st==null?void 0:st.intercept)??et),Number.isFinite(Me)&&Number.isFinite(nt)&&nt>Me)break}catch{}}const gt=Array.isArray(de.windowCenter)?de.windowCenter[0]:de.windowCenter,ut=Array.isArray(de.windowWidth)?de.windowWidth[0]:de.windowWidth;if(Number.isFinite(Me)&&Number.isFinite(nt)&&nt>Me)Ce.setProperties({voiRange:{lower:Me*dt+et,upper:nt*dt+et}});else if(Number.isFinite(Number(gt))&&Number.isFinite(Number(ut))&&Number(ut)>0){const qe=Number(gt),Tt=Number(ut);Ce.setProperties({voiRange:{lower:qe-Tt/2,upper:qe+Tt/2}})}else if(Ve)Ce.setProperties({voiRange:Ve});else{Ui(B);return}Ce.render(),br(B,Ce)})().catch(()=>{Ui(B)})},[Ui,br,Yt]),Jc=it.useCallback(B=>{const ue=`CT_${B}`,Ce=ae.current.getViewport(ue);Ce&&typeof Ce.resetCamera=="function"&&(Ce.resetCamera(),kt.debug("Restoring default window/level for viewport",B),Ui(B),Ce.render())},[Ui]),ga=it.useCallback((B,ue,Te=!0,Ce=!0)=>{if(Te&&(Cr.current[B]=ue),ue.action==="reset"){Ui(B,Ce);return}if(ue.action==="autolevel"){Co(B);return}const me=ue;Ko(B,me.center,me.width)},[Ui,Ko,Co]);it.useEffect(()=>{const B=()=>{const Te=ae.current;if(!Te)return;const Ce=tn.rows*tn.cols;for(let me=0;mewindow.clearTimeout(ue)},[ga,fn,tn,dn]),it.useEffect(()=>{const B=ue=>{var ge,pe;const Te=ue.target;if(Te){const de=(ge=Te.tagName)==null?void 0:ge.toLowerCase(),Ve=Te.getAttribute("contenteditable")==="true";if(de==="input"||de==="textarea"||de==="select"||Ve)return}if(ue.ctrlKey||ue.altKey||ue.metaKey||je===null)return;const Ce=(pe=fn[je])==null?void 0:pe.modality,me=a7(Ce);if(ue.key==="0"){const de=me.find(Ve=>Ve.action==="reset");de&&(ga(je,de),ue.preventDefault());return}if(!/^[1-9]$/.test(ue.key))return;const we=Number(ue.key)-1,se=me.filter(de=>de.action==="preset");we>=se.length||(ga(je,se[we]),ue.preventDefault())};return window.addEventListener("keydown",B),()=>window.removeEventListener("keydown",B)},[je,ga,fn]);const dc=it.useCallback((B,ue)=>{const Te=dr[B]||[];if(Te.length<=1)return;const Ce=Math.max(0,Math.min(Te.length-1,ue)),me=Te[Ce];if(!me||me.imageIds.length===0)return;const we=ae.current,se=we==null?void 0:we.getViewport(`CT_${B}`),ge=dn[B]==="volume",pe=Ve=>{if(!Ve)return null;const Me=xt("imagePlaneModule",Ve)||{},nt=Array.isArray(Me==null?void 0:Me.imagePositionPatient)?Me.imagePositionPatient:null,dt=Array.isArray(Me==null?void 0:Me.rowCosines)?Me.rowCosines:null,et=Array.isArray(Me==null?void 0:Me.columnCosines)?Me.columnCosines:null;if(nt&&dt&&et&&dt.length>=3&&et.length>=3){const ut=[dt[1]*et[2]-dt[2]*et[1],dt[2]*et[0]-dt[0]*et[2],dt[0]*et[1]-dt[1]*et[0]],qe=Math.hypot(ut[0],ut[1],ut[2]);if(qe>1e-6){const Tt=[ut[0]/qe,ut[1]/qe,ut[2]/qe];return nt[0]*Tt[0]+nt[1]*Tt[1]+nt[2]*Tt[2]}}const gt=Number(Me==null?void 0:Me.sliceLocation);return Number.isFinite(gt)?gt:null};let de=0;if(se&&typeof se.getCurrentImageIdIndex=="function"){const Ve=Yt[B]||[],Me=Ve.length,nt=se.getCurrentImageIdIndex(),dt=Ve[nt]||Ve[0],et=pe(dt);if(et!==null&&me.imageIds.length>0){let gt=0,ut=Number.POSITIVE_INFINITY;me.imageIds.forEach((qe,Tt)=>{const Lt=pe(qe);if(Lt===null)return;const st=Math.abs(Lt-et);st1?nt/(Me-1):0;de=Math.max(0,Math.min(me.imageIds.length-1,Math.round(gt*Math.max(0,me.imageIds.length-1))))}}else if(ge&&se&&typeof se.getSliceIndex=="function"&&typeof se.getNumberOfSlices=="function"){const Ve=se.getNumberOfSlices(),Me=se.getSliceIndex(),nt=Ve>1?Me/(Ve-1):0;de=Math.max(0,Math.min(me.imageIds.length-1,Math.round(nt*Math.max(0,me.imageIds.length-1))))}hi.current[B]=de,qt(Ve=>{const Me=[...Ve];return Me[B]=Ce,Me}),en(Ve=>{const Me=[...Ve];return Me[B]=me.imageIds,Me}),Zn(me.imageIds,{force:!!r}),window.setTimeout(()=>{var Me;const Ve=(Me=ae.current)==null?void 0:Me.getViewport(`CT_${B}`);if(Ve){if(dn[B]==="stack"&&typeof Ve.setImageIdIndex=="function"){To(Ve.element,{imageIndex:de}),Ve.render(),br(B,Ve);return}if(dn[B]==="volume"&&typeof Ve.getNumberOfSlices=="function"){const nt=Ve.getNumberOfSlices(),dt=Math.max(0,Math.min(Math.max(0,nt-1),de));To(Ve.element,{imageIndex:dt}),Ve.render(),br(B,Ve)}}},25)},[dr,Zn,br,Yt,dn]);it.useEffect(()=>{const B=[],ue=tn.rows*tn.cols;for(let Te=0;Te{var nt,dt;const ge=(nt=ae.current)==null?void 0:nt.getViewport(`CT_${Te}`);if(!ge||typeof ge.getCurrentImageIdIndex!="function"||typeof ge.setImageIdIndex!="function")return;const de=(((dt=ge.getImageIds)==null?void 0:dt.call(ge))||Ce).length;if(de<2)return;const Me=(ge.getCurrentImageIdIndex()+1)%de;To(ge.element,{imageIndex:Me}),ge.render()},we);B.push(se)}return()=>{B.forEach(Te=>window.clearInterval(Te))}},[cn,Nn,tn,Yt,dn]);const Zc=it.useCallback(()=>{const B=a.current;B&&(document.fullscreenElement===B?document.exitFullscreen():B.requestFullscreen?B.requestFullscreen():B.webkitRequestFullscreen?B.webkitRequestFullscreen():B.msRequestFullscreen&&B.msRequestFullscreen())},[]);it.useEffect(()=>{Ki(Array(tn.rows*tn.cols).fill({index:0,total:0,windowCenter:"",windowWidth:"",slicePosition:"",modality:"",orientation:"",resolution:"",spacing:"",focalPoint:""})),Ms(Array(tn.rows*tn.cols).fill(!1)),_n(Array(Y).fill(!1))},[tn]),it.useEffect(()=>{as()},[mr,No,Ul,as]),it.useEffect(()=>{if(!Di.some(Boolean))return;const B=ue=>{const Te=document.querySelector(".preset-menu");Te&&!Te.contains(ue.target)&&Ms(Ce=>Ce.map(()=>!1))};return document.addEventListener("mousedown",B),()=>document.removeEventListener("mousedown",B)},[Di]),it.useEffect(()=>{if(!La)return;const B=ue=>{const Te=k.current;Te&&!Te.contains(ue.target)&&(Fi(!1),fe(!1))};return document.addEventListener("mousedown",B),()=>document.removeEventListener("mousedown",B)},[La]),it.useEffect(()=>{const B=ue=>{if(ue.button===3||ue.button===4)return ue.preventDefault(),!1};return window.addEventListener("mousedown",B,!0),window.addEventListener("mouseup",B,!0),window.addEventListener("auxclick",B,!0),()=>{window.removeEventListener("mousedown",B,!0),window.removeEventListener("mouseup",B,!0),window.removeEventListener("auxclick",B,!0)}},[]),it.useEffect(()=>{const B=a.current;if(!B)return;const ue=Te=>{Te.preventDefault()};return B.addEventListener("contextmenu",ue),()=>{B.removeEventListener("contextmenu",ue)}},[]),it.useEffect(()=>{if(!zo)return;const B=xi(De);cs(B)},[je,zo]),it.useEffect(()=>{As.current&&(As.current.setAttribute("webkitdirectory","true"),As.current.setAttribute("directory","true"))},[]),it.useEffect(()=>(window.loadDicomStackFromWadouriList=async B=>{var we;if(!B||B.length===0)return;const ue=await Lo(B);await Zn(ue,{force:!!r});const Te=await Ao(ue),Ce=((we=Te[0])==null?void 0:we.imageIds)||ue;let me;try{const se=ue[0];if(r&&se&&se.startsWith("wadouri:")){const ge=il(se),de=await(await fetch(ge)).arrayBuffer();me=Vr.parseDicom(new Uint8Array(de)).string("x0020000d")}}catch{}Ne(se=>{const ge=[...se,{imageIds:ue,studyInstanceUID:me,seriesGroups:Te,groupingSource:"derived"}];return en(pe=>{const de=[...pe];return de[0]=Ce,de}),_r(pe=>{const de=[...pe];return de[0]=ge.length-1,de}),Ke(pe=>{const de=[...pe];return de[0]=Te,de}),qt(pe=>{const de=[...pe];return de[0]=0,de}),Zn(Ce),ge})},()=>{window.loadDicomStackFromWadouriList=void 0}),[Ao,Lo,Ne,Zn,_r,en]),it.useEffect(()=>{!Aa||!Yt.every(ue=>!ue||ue.length===0||ue.every(Te=>!!xt("imagePlaneModule",Te)))||en(ue=>{let Te=!1;const Ce=ue.map(me=>{if(!me||me.length===0)return me;const ge=[...me.map(pe=>({imageId:pe,sliceLoc:(()=>{const de=xt("imagePlaneModule",pe);return de&&de.sliceLocation!==void 0?Number(de.sliceLocation):null})()}))].sort((pe,de)=>pe.sliceLoc!==null&&de.sliceLoc!==null?pe.sliceLoc-de.sliceLoc:pe.imageId.localeCompare(de.imageId)).map(pe=>pe.imageId);return JSON.stringify(ge)!==JSON.stringify(me)?(Te=!0,ge):me});return Te&&Ja(!0),Ce})},[Aa,_t]);function cs(B){if(!B)return;const ue=`CT_${je}`;zo?(B.setToolEnabled(Vd.toolName),B.setToolConfiguration(Vd.toolName,{sourceViewportId:ue})):B.setToolDisabled(Vd.toolName)}function Qc(){var ue,Te,Ce;const B=ae.current;if(B)for(let me=0;me[])),_r(Array(Y).fill(0)),Ke(Array(Y).fill(null).map(()=>[])),qt(Array(Y).fill(0)),Ai(Array(Y).fill(!1)),_n(Array(Y).fill(!1)),ao(Array(Y).fill("stack")),Object.values(ro.current).forEach(ue=>{if(typeof ue=="string"&&ue.startsWith("blob:"))try{URL.revokeObjectURL(ue)}catch{}}),ro.current={},Ya({}),io.current={},Ja(!1),ht(0)}function ne(B,ue){var se,ge;if(kt.debug("Truncating stack from",B,"to",ue),kt.debug(fi),tn.rows!==1||tn.cols!==1||_t.length!==1||!Yt[0]||Yt[0].length===0||fi)return alert("Truncation is only allowed when a single stack is loaded in a single viewport (and the order has not been modified in the viewer)."),!1;const Te=_t[0],Ce=Te.imageIds;if(B<0||ue>=Ce.length||B>=ue)return alert("Invalid truncation bounds."),!1;const me=Ce.slice(B,ue+1);Ne([{...Te,imageIds:me}]),en([me]),_r([0]);const we=ae.current;if(we){const pe=we.getViewport("CT_0");pe&&typeof pe.setStack=="function"&&(pe.setStack(me),(se=pe.setImageIdIndex)==null||se.call(pe,0),(ge=pe.render)==null||ge.call(pe))}return!0}function Ee(B=0){const ue=ae.current;if(!ue)return null;const Te=ue.getViewport(`CT_${B}`);return!Te||typeof Te.getCurrentImageIdIndex!="function"?null:Te.getCurrentImageIdIndex()}it.useEffect(()=>{const B=t||"default";function ue(Ce,me){const we=ae.current;if(!we)return;const se=we.getViewport(`CT_${Ce}`);if(!se||typeof se.getImageIds!="function")return;const pe=se.getImageIds().map(Me=>il(Me)),de=il(me),Ve=pe.indexOf(de);Ve!==-1&&typeof se.setImageIdIndex=="function"&&(To(se.element,{imageIndex:Ve}),br(Ce,se))}window[`getViewport_${B}`]=Ce=>{const me=ae.current;if(me)return me.getViewport(`CT_${Ce}`)},window[`getAllViewports_${B}`]=()=>{const Ce=ae.current;return Ce?Array.from({length:Y},(me,we)=>Ce.getViewport(`CT_${we}`)).filter(Boolean):[]},window[`jumpToSliceByImageId_${B}`]=ue,window[`resetViewer_${B}`]=Qc,window[`clearViewer_${B}`]=te,window[`truncateStack_${B}`]=ne,window[`getCurrentStackPosition_${B}`]=Ee,window[`loadAdditionalStack_${B}`]=async(Ce,me,we)=>{var dt,et;if(!Array.isArray(Ce)||Ce.length===0)return;const se=So((Ce||[]).map(va)),pe=Array.isArray(we)&&we.length>0?se:await Lo(se);await Zn(pe,{force:!!r});const de=Array.isArray(we)?we.map((gt,ut)=>{const qe=Array.isArray(gt==null?void 0:gt.imageIds)?gt.imageIds:Array.isArray(gt==null?void 0:gt.i)?gt.i:[],Tt=So(qe.map(va));return Tt.length===0?null:{key:String((gt==null?void 0:gt.key)||(gt==null?void 0:gt.seriesInstanceUID)||`SERVER_SERIES_${ut}`),label:typeof(gt==null?void 0:gt.label)=="string"&>.label.trim()||typeof(gt==null?void 0:gt.name)=="string"&>.name.trim()||`Series ${ut+1}`,imageIds:Tt,seriesInstanceUID:gt==null?void 0:gt.seriesInstanceUID,bValue:Number.isFinite(Number(gt==null?void 0:gt.bValue))?Number(gt==null?void 0:gt.bValue):null,groupValues:gt==null?void 0:gt.groupValues}}).filter(gt=>!!gt):[],Ve=de.length>0?de:await Ao(pe),Me=((dt=Ve[0])==null?void 0:dt.imageIds)||pe;let nt=me;if(!nt&&r&&((et=pe[0])!=null&&et.startsWith("wadouri:")))try{const gt=il(pe[0]),qe=await(await fetch(gt)).arrayBuffer();nt=Vr.parseDicom(new Uint8Array(qe)).string("x0020000d")}catch{}Ne(gt=>[...gt,{imageIds:pe,studyInstanceUID:nt,seriesGroups:Ve,groupingSource:de.length>0?"declared":"derived"}]),en(gt=>{const ut=[...gt],qe=ut.findIndex(Tt=>!Tt||Tt.length===0);return qe!==-1&&(ut[qe]=Me,Ke(Tt=>{const Lt=[...Tt];return Lt[qe]=Ve,Lt}),qt(Tt=>{const Lt=[...Tt];return Lt[qe]=0,Lt})),ut}),Zn(Me)},window[`loadExternalStack_${B}`]=async(Ce,me)=>{!Array.isArray(Ce)||Ce.length===0||await uc(je??0,Ce,me||"Series","center")},window[`loadExternalStackNewViewport_${B}`]=async(Ce,me)=>{if(!Array.isArray(Ce)||Ce.length===0)return;await uc(je??0,Ce,me||"Series","right")},window[`exportViewerState_${B}`]=()=>{var et;const Ce=tn.rows*tn.cols,me=dn.slice(0,Ce),we=En.slice(0,Ce),se=_t.map(gt=>({i:gt.imageIds,u:gt.studyInstanceUID,g:gt.seriesGroups}));kt.debug("Exporting viewer state with",Ce,"active viewports"),kt.debug("modes",me);const ge=ae.current,pe=[],de=[],Ve=[],Me=[],nt=[];for(let gt=0;gt{try{_e.current=!0;const me=typeof Ce=="string"?JSON.parse(Ce):Ce;if(me.grid&&Ra(me.grid),me.modes&&ao(me.modes),me.stacks&&Ne(me.stacks.map(pe=>({imageIds:pe.i,studyInstanceUID:pe.u,seriesGroups:Array.isArray(pe.g)?pe.g:void 0}))),me.stackIdx&&me.stacks){const pe=me.stackIdx.map(de=>{var Ve;return((Ve=me.stacks[de])==null?void 0:Ve.i)||[]});en(pe),_r(me.stackIdx),Ke(()=>{const de=Array(Y).fill(null).map(()=>[]);for(let Ve=0;Veqn===Ut[yr])){kt.warn(`Viewport ${Mt}: importedImageIds do not match viewportImageIds`,{importedImageIds:Ut,viewportImageIds:Ft}),Ve=!1;break}}catch{Ve=!1}}if(!Ve&&se{ge()},500);return}for(let Mt=0;Mt{try{To(Gt.element,{imageIndex:me.volumeSliceIndices[Mt]})}catch{}},100)}else{try{Gt.setStack&&(Gt.setStack(Ut),Gt.render())}catch(Ft){kt.warn("Failed to set stack for viewport",Mt,Ft)}if(me.stackPos&&typeof me.stackPos[Mt]=="number"&&typeof Gt.setImageIdIndex=="function")try{Kn&&To?To(Gt.element,{imageIndex:me.stackPos[Mt]}):Gt.setImageIdIndex(me.stackPos[Mt])}catch{}}}const Me=1500;kt.debug(`Waiting ${Me}ms before applying properties/camera to viewports`),await new Promise(Mt=>setTimeout(Mt,Me));for(let Mt=0;Mt{ge()},100)}catch(me){_e.current=!1,alert("Failed to import viewer state: "+me)}},window[`exportAnnotations_${B}`]=()=>{try{let Ce=Rr.getAllAnnotations();if(kt.debug("Exporting annotations:",Ce),Array.isArray(Ce)){const me=[Gf.toolName,$h.toolName,Wf.toolName,Du.toolName,e0.toolName,Bf.toolName,Ll.toolName,Iu.toolName,Gh.toolName];Ce=Ce.filter(we=>me.includes(we.metadata.toolName))}else return"{}";return JSON.stringify(Ce,null,2)}catch(Ce){return alert("Failed to export annotations: "+Ce),"{}"}},window.__pendingImportAnnotations=window.__pendingImportAnnotations||{};const Te=Ce=>{try{const me=window.__pendingImportAnnotations&&window.__pendingImportAnnotations[Ce];if(!me||!me.length)return;const we=Rr;if(!we||typeof we.addAnnotation!="function")return;for(;(window.__pendingImportAnnotations[Ce]||[]).length;){const se=(window.__pendingImportAnnotations[Ce]||[]).shift();se&&Array.isArray(se)&&se.forEach(ge=>{try{we.addAnnotation(ge,ge.annotationUID)}catch(pe){kt.error("Failed to add queued annotation",pe,ge)}})}ae.current&&ae.current.render()}catch(me){kt.error("Error flushing pending annotations:",me)}};return window[`importAnnotations_${B}`]=Ce=>{try{const me=typeof Ce=="string"?JSON.parse(Ce):Ce,we=Rr;if(!we||typeof we.addAnnotation!="function"){window.__pendingImportAnnotations[B]=window.__pendingImportAnnotations[B]||[],window.__pendingImportAnnotations[B].push(me),kt.warn("importAnnotations: annotation state not ready, queued import",B),setTimeout(()=>Te(B),500);return}if(we.removeAllAnnotations)try{we.removeAllAnnotations()}catch(se){kt.warn("removeAllAnnotations failed",se)}Array.isArray(me)&&me.forEach(se=>{try{we.addAnnotation(se,se.annotationUID)}catch(ge){kt.error("Failed to add annotation",ge,se)}}),ae.current&&ae.current.render()}catch(me){kt.error("Failed to import annotations:",me,{apiKey:B,cornerstoneTools:!!oCe,renderingEngine:!!ae.current});try{alert("Failed to import annotations: "+me)}catch{}}try{Te(B)}catch{}},window[`importLegacyAnnotations_${B}`]=Ce=>{Rr.removeAllAnnotations&&Rr.removeAllAnnotations();let me;try{me=typeof Ce=="string"?JSON.parse(Ce):Ce}catch{alert("Invalid legacy annotation JSON");return}const we={ArrowAnnotate:"ArrowAnnotate"};Object.entries(me).forEach(([se,ge])=>{kt.debug("Importing legacy annotations for imageId:",se),Object.entries(ge).forEach(([pe,de])=>{const Ve=we[pe]||pe;de.data&&Array.isArray(de.data)&&de.data.forEach(Me=>{const nt=i7(se,{x:Me.handles.start.y,y:Me.handles.start.x}),dt=i7(se,{x:Me.handles.end.y,y:Me.handles.end.x});kt.debug("Importing legacy annotation:"),kt.debug(" Image ID:",se),kt.debug(" Start World:",nt),kt.debug(" End World:",dt);const et=xt("imagePlaneModule",se);kt.debug(AA);let gt=xt("frameOfReferenceUID",se);!gt&&et&&et.frameOfReferenceUID&&(gt=et.frameOfReferenceUID);const ut=et!=null&&et.rowCosines&&(et!=null&&et.columnCosines)?[et.rowCosines[1]*et.columnCosines[2]-et.rowCosines[2]*et.columnCosines[1],et.rowCosines[2]*et.columnCosines[0]-et.rowCosines[0]*et.columnCosines[2],et.rowCosines[0]*et.columnCosines[1]-et.rowCosines[1]*et.columnCosines[0]]:void 0;Array.isArray(ut)&&ut.length,typeof Me.rotation=="number"&&Me.rotation;const qe={annotationUID:Me.uuid,metadata:{toolName:Ve,referencedImageId:se,FrameOfReferenceUID:gt,viewPlaneNormal:ut},data:{handles:{points:[nt,dt],textBox:Me.handles.textBox},text:Me.text||""},visibility:Me.visible!==!1,active:Me.active||!1};Rr.addAnnotation(qe,qe.annotationUID)})})}),ae.current&&ae.current.render()},window[`importLegacyViewport_${B}`]=Ce=>{let me;try{me=typeof Ce=="string"?JSON.parse(Ce):Ce}catch{alert("Invalid legacy viewport JSON");return}const we=ae.current;if(!we)return;const se=`CT_${je??0}`,ge=we.getViewport(se);if(!ge)return;const pe={};if(me.voi&&(pe.voiRange={lower:me.voi.windowCenter-me.voi.windowWidth/2,upper:me.voi.windowCenter+me.voi.windowWidth/2}),typeof me.invert=="boolean"&&(pe.invert=me.invert),typeof me.pixelReplication=="boolean"&&(pe.interpolationType=me.pixelReplication?0:1),typeof me.hflip=="boolean"&&(pe.hflip=me.hflip),typeof me.vflip=="boolean"&&(pe.vflip=me.vflip),typeof ge.setProperties=="function"&&ge.setProperties(pe),me.translation||me.scale){const de=ge.getCamera?ge.getCamera():{};me.translation&&(de.translation={...de.translation,...me.translation}),me.scale&&(de.parallelScale=200/me.scale),kt.debug("Applying legacy camera properties:",de),typeof ge.setCamera=="function"&&ge.setCamera(de)}typeof me.rotation=="number"&&ge.setRotation(me.rotation),ge.render(),br(je??0,ge)},()=>{window[`exportViewerState_${B}`]=void 0,window[`importViewerState_${B}`]=void 0,window[`exportAnnotations_${B}`]=void 0,window[`importAnnotations_${B}`]=void 0,window[`importLegacyAnnotations_${B}`]=void 0,window[`importLegacyViewport_${B}`]=void 0,window[`jumpToSliceByImageId_${B}`]=void 0,window[`resetViewer_${B}`]=void 0,window[`clearViewer_${B}`]=void 0,window[`truncateStack_${B}`]=void 0,window[`getCurrentStackPosition_${B}`]=void 0,window[`loadAdditionalStack_${B}`]=void 0,window[`loadExternalStack_${B}`]=void 0,window[`loadExternalStackNewViewport_${B}`]=void 0,window[`getViewport_${B}`]=void 0,window[`getAllViewports_${B}`]=void 0}},[tn,dn,En,_t,Yt,Ra,ao,_r,Ne,en,Ne,en,Zn]),it.useEffect(()=>{const B=a.current;if(!B)return;function ue(Te){if(kt.debug("Handling arrow key navigation",Te.key),kt.debug("activeViewport",je),je===null)return;const Ce=ae.current;if(!Ce)return;const me=Ce.getViewport(`CT_${je}`);if(me){if(kt.debug(me),dn[je]==="stack"){if(typeof me.getCurrentImageIdIndex!="function"||typeof me.setImageIdIndex!="function")return;const we=Yt[je];if(!we||we.length===0)return;Te.key==="ArrowUp"||Te.key==="ArrowRight"?(Mc(me,{delta:-1}),Te.preventDefault()):(Te.key==="ArrowDown"||Te.key==="ArrowLeft")&&(Mc(me,{delta:1}),Te.preventDefault())}dn[je]==="volume"&&typeof me.getSliceIndex=="function"&&typeof me.getNumberOfSlices=="function"&&me.getNumberOfSlices()>1&&(Te.key==="ArrowUp"||Te.key==="ArrowRight"?(Mc(me,{delta:-1}),Te.preventDefault()):(Te.key==="ArrowDown"||Te.key==="ArrowLeft")&&(Mc(me,{delta:1}),Te.preventDefault()))}}return B.addEventListener("keydown",ue),()=>{B.removeEventListener("keydown",ue)}},[je,dn,Yt,br]);const ze=je!==null?En[je]:0,rt=_t[ze];rt==null||rt.studyInstanceUID;const[vt,pt]=it.useState(()=>Array(Y).fill(null)),ot=tn.rows*tn.cols,yt=[];for(let B=0;B1||(((Z=fn[B])==null?void 0:Z.totalFrames)||0)>1),me=(rn==null?void 0:rn.viewportIdx)===B?rn.zone:null,we=me?Nr(me):null;yt.push(Re.jsxs("div",{ref:se=>Xr.current[B]=se,style:{flex:1,display:ue&&Te?"flex":"none",border:ue?"1px solid #222":"none",background:"#000",minWidth:0,minHeight:0,position:"relative",overflow:"hidden",flexDirection:"column",gridRow:Math.floor(B/tn.cols)+1,gridColumn:B%tn.cols+1,height:"100%",touchAction:Se&&Ue?"none":"pan-y",boxShadow:je===B?"0 0 0 4px #1976d2, 0 0 16px 4px #1976d2cc":void 0,zIndex:je===B?10:1},onClick:()=>{if(!ke){if(Se&&!Ue){$c(B),Fi(!1),fe(!1),Rs(!1);return}if(Se&&Ue&&q!==null){ha(B,q,ie).catch(se=>{kt.error("Failed to apply mobile stack drop:",se)}),ee(null),E(!1);return}ht(B),Fi(!1)}},onDoubleClick:()=>Jc(B),onDragEnter:se=>{const ge=se.dataTransfer.types,pe=ge.includes("text/stack-idx"),de=ge.includes("text/dv3d-imageids");if(!pe&&!de)return;se.preventDefault(),de&&Bt(!0);const Ve=ns(se);sn({viewportIdx:B,zone:Ve})},onDragOver:se=>{const ge=se.dataTransfer.types,pe=ge.includes("text/stack-idx"),de=ge.includes("text/dv3d-imageids");if(!pe&&!de)return;se.preventDefault();const Ve=ns(se),Me=Nr(Ve);sn({viewportIdx:B,zone:Ve}),se.dataTransfer.dropEffect=Me===Ve?"copy":"move"},onDragLeave:se=>{if((rn==null?void 0:rn.viewportIdx)!==B)return;const ge=se.relatedTarget;ge&&se.currentTarget.contains(ge)||sn(null)},onDrop:se=>{se.preventDefault();const ge=se.dataTransfer.getData("text/dv3d-imageids");if(ge){const Ve=se.dataTransfer.getData("text/dv3d-stack-name")||"Series";try{const Me=JSON.parse(ge),nt=ns(se);uc(B,Me,Ve,nt).catch(dt=>{kt.error("Failed to apply external drop:",dt)})}catch(Me){kt.error("Invalid text/dv3d-imageids payload:",Me)}sn(null),Bt(!1);return}const pe=se.dataTransfer.getData("text/stack-idx"),de=parseInt(pe,10);if(!isNaN(de)){const Ve=ns(se);ha(B,de,Ve).catch(Me=>{kt.error("Failed to apply dropped stack:",Me)})}sn(null),Dt(null),Bt(!1)},children:[Se&&!Ue&&Re.jsx("div",{style:{position:"absolute",inset:0,zIndex:60,pointerEvents:"none",display:"flex",alignItems:"center",justifyContent:"center",background:"linear-gradient(to top, rgba(0,0,0,0.55), rgba(0,0,0,0.2))",color:"#fff",fontSize:14,fontWeight:700,letterSpacing:.2,textAlign:"center",padding:"18px"},children:"Tap to activate fullscreen interaction"}),Se&&Ue&&q!==null&&Re.jsxs("div",{style:{position:"absolute",top:8,right:8,zIndex:62,background:"rgba(25, 118, 210, 0.92)",color:"#fff",borderRadius:6,padding:"6px 8px",fontSize:11,fontWeight:700,pointerEvents:"none"},children:["Tap to drop stack (",ie,")"]}),(wt!==null||an)&&me&&Re.jsx("div",{style:{position:"absolute",inset:0,zIndex:19,pointerEvents:"none",background:"rgba(0,0,0,0.08)"},children:Re.jsx("div",{style:{position:"absolute",left:we==="left"?0:we==="right"?"50%":"20%",top:we==="top"?0:we==="bottom"?"50%":"20%",width:we==="left"||we==="right"?"50%":"60%",height:we==="top"||we==="bottom"?"50%":"60%",border:"2px solid #90caf9",boxShadow:"0 0 0 9999px rgba(17, 29, 45, 0.22)",background:"rgba(25, 118, 210, 0.28)",borderRadius:6,display:"flex",alignItems:"center",justifyContent:"center",color:"#fff",fontSize:12,fontWeight:700,textTransform:"uppercase",letterSpacing:.4},children:we==="center"?"Load Here":`Split ${we}`})}),ji==="displayset"&&Re.jsx("div",{style:{position:"absolute",inset:0,zIndex:58,pointerEvents:"none",display:"flex",alignItems:"center",justifyContent:"center",color:"rgba(255,255,255,0.78)",fontSize:14,fontWeight:600,letterSpacing:.2,textShadow:"0 1px 3px rgba(0,0,0,0.55)"},children:"Loading images..."}),Re.jsx("button",{style:{position:"absolute",top:8,left:8,zIndex:20,background:"#333",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 8px",cursor:"pointer",fontSize:"12px",opacity:.85},onClick:()=>{ao(se=>{const ge=[...se];return ge[B]=se[B]==="stack"?"volume":"stack",ge})},children:dn[B]==="stack"?"Volume":"Stack"}),dn[B]==="volume"&&Re.jsxs("div",{style:{position:"absolute",top:8,left:70,zIndex:21,display:"flex",gap:"6px",background:"rgba(34,34,34,0.85)",borderRadius:"4px",padding:"2px 6px",alignItems:"center"},children:[Re.jsx("button",{style:{background:"#444",color:"#fff",border:"none",borderRadius:"3px",padding:"2px 8px",cursor:"pointer",fontSize:"12px",marginRight:"2px"},onClick:()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);ge&&ge.setOrientation&&(ge.setOrientation("axial"),ge.render())},children:"Axial"}),Re.jsx("button",{style:{background:"#444",color:"#fff",border:"none",borderRadius:"3px",padding:"2px 8px",cursor:"pointer",fontSize:"12px",marginRight:"2px"},onClick:()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);ge&&ge.setOrientation&&(ge.setOrientation("sagittal"),ge.render())},children:"Sagittal"}),Re.jsx("button",{style:{background:"#444",color:"#fff",border:"none",borderRadius:"3px",padding:"2px 8px",cursor:"pointer",fontSize:"12px"},onClick:()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);ge&&ge.setOrientation&&(ge.setOrientation("coronal"),ge.render())},children:"Coronal"})]}),Re.jsxs("button",{style:{position:"absolute",top:40,left:8,zIndex:20,background:"#111",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 8px",cursor:"pointer",fontSize:"13px",opacity:.85,marginTop:"4px",display:"flex",alignItems:"center",gap:"6px"},title:"Toggle Fullscreen",onClick:se=>{se.stopPropagation();const ge=Xr.current[B];document.fullscreenElement===ge?document.exitFullscreen():ge!=null&&ge.requestFullscreen?ge.requestFullscreen():ge!=null&&ge.webkitRequestFullscreen?ge.webkitRequestFullscreen():ge!=null&&ge.msRequestFullscreen&&ge.msRequestFullscreen()},onMouseEnter:()=>H(B),onMouseLeave:()=>H(null),children:[Re.jsx("span",{style:{fontSize:"18px",lineHeight:1},children:"⛶"}),F===B&&Re.jsx("span",{style:{marginLeft:6},children:document.fullscreenElement===Xr.current[B]?"Exit Fullscreen":"Fullscreen"})]}),Ce&&Re.jsx("button",{style:{position:"absolute",top:78,left:8,zIndex:20,background:Sn[B]?"rgba(30,120,200,0.95)":"#111",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 8px",cursor:"pointer",fontSize:"16px",lineHeight:1,opacity:.9},title:Sn[B]?"Hide cine controls":"Show cine controls",onClick:se=>{se.stopPropagation(),_n(ge=>{const pe=[...ge],de=!pe[B];return pe[B]=de,de||Ai(Ve=>{const Me=[...Ve];return Me[B]=!1,Me}),pe})},children:Re.jsx("span",{"aria-hidden":"true",children:"▶"})}),dn[B]==="stack"&&tt&&(()=>{var gt;const se=Yt[B],pe=(Rr.getAllAnnotations()||[]).filter(ut=>ut.metadata&&ut.metadata.referencedImageId&&se.includes(ut.metadata.referencedImageId)&&ut.metadata.toolName!==gs.toolName);if(!pe.length)return null;const de=ae.current,Ve=de==null?void 0:de.getViewport(`CT_${B}`),Me=((gt=Ve==null?void 0:Ve.getCurrentImageIdIndex)==null?void 0:gt.call(Ve))??0,nt=se[Me],dt=pe.filter(ut=>ut.metadata.referencedImageId===nt),et=vt[B];return Re.jsxs("div",{style:{position:"absolute",left:"50%",bottom:60,transform:"translateX(-50%)",zIndex:30,display:"flex",gap:4,pointerEvents:"auto",alignItems:"center"},children:[Re.jsx("button",{style:{background:"rgba(30,30,30,0.7)",color:"#fff",border:"none",borderRadius:"50%",width:28,height:28,fontSize:"16px",fontWeight:"bold",cursor:"pointer",opacity:.7,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 1px 4px rgba(0,0,0,0.18)",transition:"opacity 0.2s"},title:"Previous Annotation","aria-label":"Previous Annotation",onClick:()=>{const ut=ae.current,qe=ut==null?void 0:ut.getViewport(`CT_${B}`);if(!qe||typeof qe.getCurrentImageIdIndex!="function")return;const Tt=qe.getCurrentImageIdIndex(),Lt=g7(Tt,se,pe,-1);if(Lt!==null&&typeof qe.setImageIdIndex=="function"){To(qe.element,{imageIndex:Lt}),br(B,qe);const st=se[Lt],Rt=pe.filter(Nt=>Nt.metadata.referencedImageId===st);ic(B,Rt.length>0?Rt[0].annotationUID:null)}},children:Re.jsx("span",{"aria-hidden":"true",children:"◀"})}),Re.jsx("button",{style:{background:"rgba(30,30,30,0.7)",color:"#fff",border:"none",borderRadius:"50%",width:28,height:28,fontSize:"16px",fontWeight:"bold",cursor:"pointer",opacity:.7,display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 1px 4px rgba(0,0,0,0.18)",transition:"opacity 0.2s"},title:"Next Annotation","aria-label":"Next Annotation",onClick:()=>{const ut=ae.current,qe=ut==null?void 0:ut.getViewport(`CT_${B}`);if(!qe||typeof qe.getCurrentImageIdIndex!="function")return;const Tt=qe.getCurrentImageIdIndex(),Lt=g7(Tt,se,pe,1);if(Lt!==null&&typeof qe.setImageIdIndex=="function"){To(qe.element,{imageIndex:Lt}),br(B,qe);const st=se[Lt],Rt=pe.filter(Nt=>Nt.metadata.referencedImageId===st);ic(B,Rt.length>0?Rt[0].annotationUID:null)}},children:Re.jsx("span",{"aria-hidden":"true",children:"▶"})}),dt.length>0&&Re.jsx("div",{style:{display:"flex",gap:2,alignItems:"center"},children:dt.map(ut=>Re.jsxs("div",{style:{display:"flex",alignItems:"center",background:et===ut.annotationUID?"rgb(4, 225, 0)":"#444",color:et===ut.annotationUID?"#222":"#fff",borderRadius:"4px",padding:"2px 6px",marginRight:2,cursor:"pointer",border:et===ut.annotationUID?"2px solid #1976d2":"none",fontWeight:et===ut.annotationUID?"bold":"normal"},onClick:()=>ic(B,ut.annotationUID),children:[Re.jsxs("span",{style:{marginRight:4},title:ut.metadata.toolName||"Annotation",children:[et===ut.annotationUID?"★ ":"",Re.jsx("span",{style:{fontSize:14,lineHeight:1},children:u7(ut.metadata.toolName)})]}),Re.jsx("button",{style:{background:"transparent",color:"#f44336",border:"1px solid #f44336",borderRadius:3,width:16,height:16,fontSize:10,lineHeight:1,cursor:"pointer",marginLeft:4,display:"flex",alignItems:"center",justifyContent:"center",opacity:.95,padding:0},title:"Delete this annotation","aria-label":"Delete annotation",onClick:qe=>{qe.stopPropagation(),Bl(B,ut.annotationUID,dt)},children:Re.jsx("span",{"aria-hidden":"true",children:"✖"})})]},ut.annotationUID))})]})})(),Re.jsx("div",{style:{position:"absolute",left:8,bottom:8,background:"rgba(0,0,0,0.7)",color:"#fff",padding:"6px 12px",borderRadius:"4px",fontSize:"14px",zIndex:10,pointerEvents:"none",minWidth:"120px",userSelect:"none"},children:dn[B]==="stack"?Re.jsxs(Re.Fragment,{children:[Re.jsxs("div",{children:["Image: ",(J=fn[B])==null?void 0:J.index," / ",(ye=fn[B])==null?void 0:ye.total,(Be=fn[B])!=null&&Be.frameIndex&&((Ze=fn[B])!=null&&Ze.totalFrames)?Re.jsxs(Re.Fragment,{children:["   [Frame: ",(Ct=fn[B])==null?void 0:Ct.frameIndex," / ",(mt=fn[B])==null?void 0:mt.totalFrames,"]"]}):null]}),Re.jsxs("div",{children:["WC: ",(lt=fn[B])==null?void 0:lt.windowCenter,"   WW: ",($=fn[B])==null?void 0:$.windowWidth]}),Ot&&Re.jsxs(Re.Fragment,{children:[Re.jsxs("div",{children:["Ori: ",((K=fn[B])==null?void 0:K.orientation)||"N/A"]}),((R=fn[B])==null?void 0:R.resolution)&&Re.jsxs("div",{children:["Res: ",(U=fn[B])==null?void 0:U.resolution]}),((X=fn[B])==null?void 0:X.spacing)&&Re.jsxs("div",{children:["Spacing: ",(he=fn[B])==null?void 0:he.spacing]}),((xe=fn[B])==null?void 0:xe.focalPoint)&&Re.jsxs("div",{children:["Pos: ",(be=fn[B])==null?void 0:be.focalPoint]})]})]}):Re.jsxs("div",{children:["Slice: ",(Le=fn[B])==null?void 0:Le.index," / ",(Fe=fn[B])==null?void 0:Fe.total,((He=fn[B])==null?void 0:He.slicePosition)&&Re.jsxs("span",{children:["   (",(ft=fn[B])==null?void 0:ft.slicePosition,")"]}),Re.jsx("br",{}),"WC: ",(It=fn[B])==null?void 0:It.windowCenter,"   WW: ",(Jt=fn[B])==null?void 0:Jt.windowWidth,Ot&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Ori: ",((Wt=fn[B])==null?void 0:Wt.orientation)||"N/A",((Mn=fn[B])==null?void 0:Mn.resolution)&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Res: ",(bn=fn[B])==null?void 0:bn.resolution]}),((ar=fn[B])==null?void 0:ar.spacing)&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Spacing: ",(ai=fn[B])==null?void 0:ai.spacing]}),((gi=fn[B])==null?void 0:gi.focalPoint)&&Re.jsxs(Re.Fragment,{children:[Re.jsx("br",{}),"Pos: ",(el=fn[B])==null?void 0:el.focalPoint]})]})]})}),Re.jsx("div",{style:{position:"absolute",right:8,bottom:8,zIndex:110,pointerEvents:"auto",display:"flex",alignItems:"flex-end",gap:6},children:Re.jsxs("div",{className:"preset-menu",style:{background:"rgba(0,0,0,0.7)",color:"#fff",borderRadius:"4px",fontSize:"14px",minWidth:"120px",overflow:"hidden",cursor:"pointer",position:"relative",boxShadow:Di[B]?"0 2px 8px rgba(0,0,0,0.3)":void 0,pointerEvents:"auto"},onClick:se=>se.stopPropagation(),children:[Re.jsxs("div",{style:{padding:"6px 12px",fontWeight:"bold",userSelect:"none"},onClick:se=>{se.stopPropagation(),Ms(ge=>{const pe=[...ge];return pe[B]=!pe[B],pe})},children:["Presets (",((pa=fn[B])==null?void 0:pa.modality)||"Unknown",")",Re.jsx("span",{style:{float:"right",fontWeight:"normal"},children:Di[B]?"▲":"▼"})]}),Di[B]&&Re.jsx("div",{className:"preset-menu-content",style:{background:"rgba(0,0,0,0.95)",borderRadius:"0 0 4px 4px",padding:"6px 0 6px 0",display:"flex",flexDirection:"column",zIndex:111,pointerEvents:"auto"},onClick:se=>se.stopPropagation(),children:(()=>{var pe;const se=a7((pe=fn[B])==null?void 0:pe.modality);let ge=0;return se.map(de=>{let Ve="";return de.action==="reset"?Ve="0":de.action==="preset"&&(ge+=1,Ve=String(ge)),Re.jsxs("button",{title:Ve?`Shortcut: ${Ve}`:void 0,style:{display:"block",width:"100%",margin:"2px 0",background:de.action==="preset"?"#333":"#444",color:"#fff",border:"none",borderRadius:"3px",cursor:"pointer",padding:de.action==="preset"?"4px 0":"6px 0",fontSize:"13px",opacity:.9,fontWeight:de.action==="preset"?"normal":"600"},onClick:Me=>{Me.stopPropagation(),ga(B,de),Ms(nt=>{const dt=[...nt];return dt[B]=!1,dt})},children:[de.name,Ve?` (${Ve})`:""]},de.name)})})()})]})}),Ce&&(Sn[B]||(dr[B]||[]).length>1||((Zf=fn[B])==null?void 0:Zf.frameIndex)&&((Au=fn[B])==null?void 0:Au.totalFrames))&&Re.jsxs("div",{style:{position:"absolute",left:"50%",bottom:8,transform:"translateX(-50%)",zIndex:36,background:"rgba(15,15,15,0.82)",border:"1px solid rgba(255,255,255,0.18)",borderRadius:8,padding:"6px 10px",display:"flex",alignItems:"center",gap:8,pointerEvents:"auto",minWidth:200,maxWidth:"72%"},onClick:se=>se.stopPropagation(),children:[Sn[B]&&Ce&&Re.jsxs(Re.Fragment,{children:[Re.jsx("button",{style:{background:Nn[B]?"#d32f2f":"#2e7d32",color:"#fff",border:"none",borderRadius:4,fontSize:12,padding:"4px 8px",cursor:"pointer"},title:Nn[B]?"Pause cine":"Play cine",onClick:()=>{Ai(se=>{const ge=[...se];return ge[B]=!ge[B],ge})},children:Nn[B]?"Pause":"Play"}),Re.jsxs("label",{style:{color:"#ddd",fontSize:11,display:"flex",alignItems:"center",gap:4},children:["FPS",Re.jsx("input",{type:"range",min:1,max:30,step:1,value:Math.max(1,Math.min(30,Math.round(cn[B]||12))),onChange:se=>{const ge=Number(se.target.value);Jn(pe=>{const de=[...pe];return de[B]=ge,de})}}),Re.jsx("span",{style:{minWidth:22,textAlign:"right"},children:Math.round(cn[B]||12)})]})]}),((xg=fn[B])==null?void 0:xg.frameIndex)&&((Cg=fn[B])==null?void 0:Cg.totalFrames)&&((z8=fn[B])==null?void 0:z8.totalFrames)>1&&Re.jsxs(Re.Fragment,{children:[Re.jsx("span",{style:{color:"#fff",fontSize:12,whiteSpace:"nowrap"},children:"Frame"}),Re.jsx("input",{type:"range",min:1,max:(($8=fn[B])==null?void 0:$8.totalFrames)||1,step:1,value:Math.max(1,Math.min(((j8=fn[B])==null?void 0:j8.totalFrames)||1,((H8=fn[B])==null?void 0:H8.frameIndex)||1)),onChange:se=>{var Ve;const ge=Number(se.target.value),de=(Yt[B]||[]).findIndex(Me=>{const nt=Me.match(/&frame=(\d+)/);return nt&&parseInt(nt[1],10)===ge});if(de>=0){const Me=(Ve=ae.current)==null?void 0:Ve.getViewport(`CT_${B}`);Me&&typeof To=="function"&&To(Me.element,{imageIndex:de})}},style:{width:100}}),Re.jsxs("span",{style:{color:"#e0e0e0",fontSize:11,minWidth:50,textAlign:"right"},children:[(K8=fn[B])==null?void 0:K8.frameIndex," / ",(q8=fn[B])==null?void 0:q8.totalFrames]})]}),(dr[B]||[]).length>1&&Re.jsxs(Re.Fragment,{children:[Re.jsx("span",{style:{color:"#fff",fontSize:12,whiteSpace:"nowrap"},children:"Group"}),Re.jsx("input",{type:"range",min:0,max:Math.max(0,(dr[B]||[]).length-1),step:1,value:Math.max(0,Math.min((dr[B]||[]).length-1,Et[B]||0)),onChange:se=>{dc(B,Number(se.target.value))},style:{width:140}}),Re.jsx("span",{style:{color:"#e0e0e0",fontSize:11,maxWidth:180,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:((Y8=(X8=dr[B])==null?void 0:X8[Et[B]||0])==null?void 0:Y8.label)||"Group",children:((Z8=(J8=dr[B])==null?void 0:J8[Et[B]||0])==null?void 0:Z8.label)||"Group"})]})]}),dn[B]==="stack"&&Yt[B]&&Re.jsx("div",{style:{position:"absolute",top:"10%",right:8,width:"14px",height:"80%",maxHeight:"100%",minHeight:0,zIndex:35,display:Yt[B].length>0?"flex":"none",alignItems:"flex-start",justifyContent:"center",pointerEvents:"auto",flexDirection:"column",padding:0},children:(()=>{const se=Yt[B]||[],ge=se.length;if(ge===0)return null;const pe=ae.current,de=pe==null?void 0:pe.getViewport(`CT_${B}`),Ve=de&&typeof de.getCurrentImageIdIndex=="function"?de.getCurrentImageIdIndex():-1,Me=new Set(se.map((qe,Tt)=>rs[qe]?Tt:-1).filter(qe=>qe>=0)),nt=se.map(qe=>qe.startsWith("external:")?!0:!!xt("imagePlaneModule",qe)||!!xt("generalSeriesModule",qe)),dt=nt.reduce((qe,Tt)=>qe+(Tt?1:0),0),et=se.reduce((qe,Tt,Lt)=>qe+(Me.has(Lt)?1:0),0),gt=Math.min(ge,180),ut=Array.from({length:gt},()=>({loaded:!1,viewed:!1,current:!1}));for(let qe=0;qe{var Gt;const Lt=qe.currentTarget.getBoundingClientRect(),st=Math.min(Lt.height,Math.max(0,qe.clientY-Lt.top)),Rt=Lt.height>0?st/Lt.height:0,Nt=Math.min(ge-1,Math.max(0,Math.round(Rt*(ge-1)))),Mt=(Gt=ae.current)==null?void 0:Gt.getViewport(`CT_${B}`);Mt&&typeof Mt.setImageIdIndex=="function"&&dn[B]==="stack"&&(To(Mt.element,{imageIndex:Nt}),br(B,Mt))},children:[ut.map((qe,Tt)=>{let Lt="#3f3f3f";return qe.loaded&&(Lt="#2e7d32"),qe.viewed&&(Lt="#1565c0"),qe.current&&(Lt="#fbc02d"),Re.jsx("div",{style:{width:"100%",height:`${100/gt}%`,minHeight:1,background:Lt,opacity:qe.loaded||qe.viewed||qe.current?.95:.45,borderBottom:Tt=0&&ge>gt&&Re.jsx("div",{style:{position:"absolute",left:0,right:0,top:`${Ve/Math.max(1,ge-1)*100}%`,height:2,background:"#ffeb3b",boxShadow:"0 0 4px #ffeb3b",transform:"translateY(-1px)",pointerEvents:"none"}})]})})()}),dn[B]==="volume"&&(()=>{const se=ae.current,ge=se==null?void 0:se.getViewport(`CT_${B}`);let pe=0,de=0;return ge&&typeof ge.getNumberOfSlices=="function"&&typeof ge.getSliceIndex=="function"&&(pe=ge.getNumberOfSlices(),de=ge.getSliceIndex()),pe>1?Re.jsx("div",{style:{position:"absolute",top:"10%",right:8,width:"12px",height:"80%",maxHeight:"100%",minHeight:0,zIndex:30,display:"flex",alignItems:"flex-start",justifyContent:"center",pointerEvents:"auto",flexDirection:"column",padding:0},children:Re.jsx("div",{style:{width:"8px",height:"100%",maxHeight:"100%",minHeight:0,borderRadius:"6px",background:"#222",position:"relative",display:"flex",flexDirection:"column",justifyContent:"flex-start",boxShadow:"0 0 8px #2196f3cc",overflow:"hidden",cursor:"pointer"},onClick:Ve=>{const nt=Ve.currentTarget.getBoundingClientRect(),dt=Ve.clientY-nt.top,et=Math.floor(dt/nt.height*pe),gt=ae.current,ut=gt==null?void 0:gt.getViewport(`CT_${B}`);ut&&(To(ut.element,{imageIndex:et}),ut.render(),br(B,ut))},children:Array.from({length:pe}).map((Ve,Me)=>{const nt=Me===de;return Re.jsx("div",{style:{width:"100%",height:`${100/pe}%`,minHeight:nt?1:0,background:nt?"linear-gradient(to right, #ffeb3b 60%, #ff9800 100%)":"#444",opacity:nt?.95:.4,transition:"background 0.3s, opacity 0.3s",borderBottom:Me1||!Yt[B]||Yt[B].length===0)&&Re.jsx("div",{style:{position:"absolute",left:0,right:0,bottom:Ce&&(Sn[B]||(dr[B]||[]).length>1)?56:8,zIndex:20,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"auto",width:"100%",background:"none",borderRadius:"0",padding:0},children:Re.jsxs("div",{style:{position:"relative"},children:[Re.jsxs("button",{onClick:se=>{se.stopPropagation(),oe(ge=>ge===B?null:B)},style:{padding:"6px 12px",background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",cursor:"pointer",pointerEvents:"auto",fontSize:13},title:"Choose stack",children:[(()=>{const se=Array.isArray(En)?En[B]:void 0,ge=typeof se=="number"&&_t[se]?_t[se]:void 0,pe=ge&&Array.isArray(ge.imageIds)?ge.imageIds:[],de=ge?ge.name||(ge.caseId?`Case: ${ge.caseId}`:void 0):void 0;if(de)return de;if(pe.length>0)return`Stack ${typeof se=="number"?se+1:"1"}`;const Ve=Yt[B]||[];return Ve.length>0?`Stack (${Ve.length} images)`:"No stack"})(),Re.jsx("span",{style:{marginLeft:8,opacity:.8},children:Q===B?"▲":"▼"})]}),Q===B&&Re.jsx("div",{ref:se=>{se&&se.focus()},tabIndex:0,style:{position:"absolute",left:0,bottom:"110%",background:"#222",border:"1px solid #444",borderRadius:"4px",boxShadow:"0 2px 8px rgba(0,0,0,0.3)",zIndex:100,minWidth:220,maxHeight:260,overflowY:"auto",overscrollBehavior:"contain",scrollbarWidth:"thin",padding:6},role:"listbox",onMouseDown:se=>se.stopPropagation(),onWheel:se=>{var pe;try{se.stopPropagation()}catch{}try{se.preventDefault()}catch{}const ge=se.currentTarget;if(ge){const de=se.deltaY??((pe=se.nativeEvent)==null?void 0:pe.deltaY)??0;ge.scrollTop+=de}},onBlur:se=>{const ge=se.currentTarget;setTimeout(()=>{if(!ge){oe(null);return}ge.contains(document.activeElement)||oe(null)},0)},children:(()=>{const se={};return _t.forEach((ge,pe)=>{const de=ge.studyId||ge.studyInstanceUID||"Unspecified";se[de]||(se[de]=[]),se[de].push({idx:pe,stack:ge})}),Object.keys(se).map(ge=>Re.jsxs("div",{style:{marginBottom:6},children:[Re.jsx("div",{style:{fontSize:12,color:"#aaa",padding:"4px 8px",fontWeight:700},children:ge==="Unspecified"?"Unspecified study":`Study: ${ge}`}),Re.jsx("div",{children:se[ge].map(({idx:pe,stack:de})=>{const Ve=Array.isArray(de.imageIds)?de.imageIds:[],Me=de&&(de.name||de.caseId)?de.name||`Case: ${de.caseId}`:`Stack ${pe+1}`,nt=Ve.length,dt=!Array.isArray(Ve)||nt===0;return Re.jsxs("button",{role:"option","aria-selected":!1,title:dt?"Invalid stack descriptor":`${Me} — ${nt} image${nt===1?"":"s"}${de!=null&&de.caseId?` — case ${de.caseId}`:""}`,style:{display:"flex",flexDirection:"column",alignItems:"flex-start",width:"100%",padding:"8px 12px",background:"transparent",color:"#fff",border:"none",textAlign:"left",cursor:dt?"not-allowed":"pointer"},onClick:et=>{if(et.stopPropagation(),dt){kt.warn(`Attempted to select invalid stack at index ${pe}`,de);return}Vi(B,pe).catch(gt=>kt.error("Failed to load stack:",gt)),oe(null)},children:[Re.jsx("div",{style:{fontWeight:"600",fontSize:13},children:Me}),Re.jsxs("div",{style:{fontSize:12,opacity:.7},children:[nt," image",nt===1?"":"s",de!=null&&de.caseId?` • case ${de.caseId}`:""]})]},pe)})})]},ge))})()})]})})]},B))}const Pt=[bf.toolName,gu.toolName,Ec.toolName,gl.toolName],nn=[{rows:1,cols:1},{rows:1,cols:2},{rows:2,cols:2}],Ht=Se&&Ue;return Re.jsxs("div",{ref:a,style:{position:"relative",inset:0,width:"100%",height:"100%",boxSizing:"border-box",background:Ht?"#000":"#222",padding:Ht?"0px":Se?"6px":"12px",overflow:"hidden"},children:[ji&&ji!=="displayset"&&Re.jsx("div",{style:{position:"absolute",zIndex:3e3,top:0,left:0,width:"100%",height:"100%",background:"rgba(0,0,0,0.7)",color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:28,fontWeight:"bold",letterSpacing:1},children:ji==="annotations"?"Loading Annotations...":"Loading Viewer State..."}),Po&&Re.jsxs("div",{style:{position:"fixed",top:12,left:12,right:12,zIndex:1e4,background:"#fff3cd",color:"#856404",border:"1px solid #ffeeba",padding:"10px 14px",borderRadius:6,display:"flex",alignItems:"center",justifyContent:"space-between",gap:12},children:[Re.jsxs("div",{style:{flex:1,fontSize:14},children:[Re.jsx("strong",{children:"Graphics error:"})," The viewer encountered a WebGL/graphics error and may be unstable. Please reload the page.",Zs?Re.jsx("div",{style:{marginTop:6,fontSize:12,color:"#6b4f00"},children:Zs}):null]}),Re.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[Re.jsx("button",{onClick:()=>window.location.reload(),style:{padding:"6px 10px"},children:"Reload"}),Re.jsx("button",{onClick:()=>ki(!1),style:{padding:"6px 10px"},children:"Dismiss"})]})]}),!T&&!Ht&&Re.jsx("button",{onClick:()=>E(!0),"aria-pressed":!1,title:"Open stacks",style:{position:"absolute",right:8,top:76,zIndex:120,width:24,height:42,background:"#1976d2",color:"#fff",border:"none",borderRadius:5,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 2px 8px rgba(0,0,0,0.3)",pointerEvents:"auto"},children:"▶"}),Ht&&Re.jsx("button",{onClick:()=>{Pe(!1),O(null),z(!1),E(!1),ee(null);const B=a.current;B&&document.fullscreenElement===B&&document.exitFullscreen&&document.exitFullscreen().catch(()=>{})},style:{position:"absolute",top:10,left:10,zIndex:3500,background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:"Exit Viewer"}),Ht&&Re.jsxs("div",{style:{position:"absolute",top:10,right:10,zIndex:3500,display:"flex",gap:8},children:[Re.jsx("button",{onClick:()=>E(B=>!B),style:{background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:"Stacks"}),Re.jsx("button",{onClick:()=>{j?z(!1):(z(!0),O(je??0))},style:{background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:j?"Grid":"Focus"}),Re.jsx("button",{onClick:()=>{Ra(B=>{const ue=nn.findIndex(Ce=>Ce.rows===B.rows&&Ce.cols===B.cols);return nn[(ue+1+nn.length)%nn.length]})},style:{background:"rgba(0,0,0,0.78)",color:"#fff",border:"1px solid rgba(255,255,255,0.25)",borderRadius:8,padding:"8px 10px",fontSize:13,fontWeight:700},children:"Layout"})]}),ke&&Re.jsxs("div",{style:{position:"fixed",left:ke.x+14,top:ke.y-18,zIndex:5e3,background:"rgba(21,101,192,0.92)",color:"#fff",border:"1px solid rgba(255,255,255,0.35)",borderRadius:8,padding:"5px 8px",fontSize:11,fontWeight:700,pointerEvents:"none",whiteSpace:"nowrap"},children:["Drop on viewport ",ke.targetViewportIdx!==null?ke.targetViewportIdx+1:"-"," (",ke.zone,")"]}),!Ht&&Re.jsxs("div",{children:[Re.jsx("button",{style:{position:"absolute",top:"50%",transform:"translateY(-50%)",left:cc,zIndex:200,width:W,height:W,background:"#222",color:"#fff",border:"none",borderRadius:"50%",fontWeight:"bold",cursor:"pointer",fontSize:"22px",boxShadow:"0 2px 8px rgba(0,0,0,0.2)",transition:"left 0.25s cubic-bezier(.4,2,.6,1), background 0.2s"},onClick:()=>Rs(B=>!B),"aria-label":"Open menu",children:"☰"}),ac&&Re.jsx("div",{style:{position:"absolute",top:0,left:0,width:V,height:"100%",background:"#222",color:"#fff",zIndex:199,boxShadow:"2px 0 12px rgba(0,0,0,0.3)",flexDirection:"column",padding:"24px 16px 16px 16px",display:"flex",overflow:"hidden"},children:Re.jsxs("div",{style:{flex:1,minHeight:0,overflowY:"auto",display:"flex",flexDirection:"column"},children:[Re.jsxs("div",{style:{fontWeight:"bold",fontSize:18,marginBottom:24},children:["Menu",Re.jsx("button",{style:{float:"right",background:"transparent",color:"#fff",border:"none",fontSize:"22px",cursor:"pointer"},onClick:()=>Rs(!1),"aria-label":"Close menu",children:"×"})]}),Re.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",marginBottom:8},children:[Re.jsxs("label",{style:{fontSize:13},children:[Re.jsx("input",{type:"radio",name:"folderLoadMode",value:"add",checked:sc==="add",onChange:()=>Ls("add")})," Add (append)"]}),Re.jsxs("label",{style:{fontSize:13},children:[Re.jsx("input",{type:"radio",name:"folderLoadMode",value:"replace",checked:sc==="replace",onChange:()=>Ls("replace")})," Replace all"]})]}),Re.jsx("button",{style:{padding:"10px 18px",background:"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:Yc,children:"Load DICOM Folder"}),Re.jsx("input",{ref:da,type:"file",style:{display:"none"},multiple:!0,onChange:ss}),Re.jsx("input",{ref:As,type:"file",style:{display:"none"},multiple:!0,onChange:ss,accept:".dcm,application/dicom"}),Re.jsxs("div",{style:{marginBottom:"18px",display:"flex",alignItems:"center",gap:"8px"},children:[Re.jsx("input",{type:"checkbox",id:"orderBySliceLocation",checked:Aa,onChange:B=>la(B.target.checked),style:{accentColor:"#666"}}),Re.jsx("label",{htmlFor:"orderBySliceLocation",style:{fontSize:"15px",cursor:"pointer"},children:"Order by Slice Location"})]}),Re.jsx("button",{style:{padding:"10px 18px",background:"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:Gl,children:"Show DICOM Metadata"}),Re.jsxs("button",{style:{padding:"10px 18px",background:Za?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Ro(B=>!B),children:[Za?"Disable":"Enable"," Cross Reference Lines"]}),Re.jsxs("button",{style:{padding:"10px 18px",background:zo?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Qa(B=>!B),children:[zo?"Disable":"Enable"," Reference Lines"]}),Re.jsx("button",{onClick:ec,style:{margin:8,padding:8},children:"Sort All Viewports by Slice Location"}),Re.jsx("button",{style:{padding:"10px 18px",background:Ho?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Yr(B=>!B),children:Ho?"Disable Alt Key for Reference Cursors (Shift always works)":"Enable Alt Key for Reference Cursors (Shift always works)"}),Re.jsxs("button",{style:{padding:"10px 18px",background:tt?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>le(B=>!B),children:[tt?"Hide":"Show"," Annotation Navigation"]}),Re.jsxs("button",{style:{padding:"10px 18px",background:Ot?"#1976d2":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"15px",marginBottom:"18px",width:"100%"},onClick:()=>Vt(B=>!B),children:[Ot?"Disable":"Enable"," Volume Diagnostics"]})]})})]}),!Ht&&Re.jsxs("div",{ref:k,className:"grid-menu-hover-container",style:{position:"absolute",top:La||ve?8:-18,left:"50%",transform:"translateX(-50%)",zIndex:100,display:"flex",flexDirection:"row",alignItems:"flex-start",gap:8,width:"auto",pointerEvents:"auto",transition:"top 180ms ease",paddingTop:28,marginTop:-28,paddingBottom:12},onMouseEnter:()=>fe(!0),onMouseLeave:()=>{La||fe(!1)},children:[Re.jsxs("button",{style:{height:40,padding:"6px 12px 6px 10px",background:"#222",color:"#fff",border:"none",borderRadius:"0 0 4px 4px",fontWeight:"bold",cursor:"pointer",fontSize:"14px",boxShadow:"0 2px 8px rgba(0,0,0,0.2)",display:"inline-flex",alignItems:"center",gap:8},title:"Toggle viewer fullscreen",onFocus:()=>fe(!0),onClick:()=>{fe(!0),Zc()},children:[Re.jsx("span",{style:{fontSize:16,lineHeight:1},children:"⛶"}),Re.jsx("span",{children:"Fullscreen"})]}),Re.jsxs("div",{style:{position:"relative",display:"flex",flexDirection:"column",alignItems:"stretch"},children:[Re.jsxs("button",{className:"grid-menu-btn",style:{height:40,padding:"6px 14px 6px 10px",background:"#222",color:"#fff",border:"none",borderRadius:"0 0 4px 4px",fontWeight:"bold",cursor:"pointer",fontSize:"14px",boxShadow:"0 2px 8px rgba(0,0,0,0.2)",display:"inline-flex",alignItems:"center",gap:10,justifyContent:"space-between",minWidth:136},onFocus:()=>fe(!0),onClick:()=>{fe(!0),Fi(B=>!B)},tabIndex:0,children:[Re.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:8},children:[Re.jsx("span",{style:{display:"grid",gridTemplateColumns:`repeat(${tn.cols}, 5px)`,gridTemplateRows:`repeat(${tn.rows}, 5px)`,gap:2,padding:1},children:Array.from({length:tn.rows*tn.cols}).map((B,ue)=>Re.jsx("span",{style:{width:5,height:5,borderRadius:1,background:"#90caf9",display:"block"}},ue))}),Re.jsxs("span",{children:[tn.rows,"x",tn.cols]})]}),Re.jsx("span",{style:{opacity:.8},children:La?"▲":"▼"})]}),La&&Re.jsx("div",{style:{position:"absolute",top:"calc(100% + 8px)",right:0,background:"#222",color:"#fff",borderRadius:"6px",boxShadow:"0 2px 12px rgba(0,0,0,0.4)",padding:"12px",display:"grid",gridTemplateColumns:"repeat(3, minmax(68px, 1fr))",gap:"8px",zIndex:200,pointerEvents:"auto"},onMouseDown:B=>B.stopPropagation(),children:Os.map(B=>Re.jsxs("button",{style:{minWidth:"68px",height:"54px",background:B.rows===tn.rows&&B.cols===tn.cols?"#444":"#333",color:"#fff",border:"none",borderRadius:"4px",fontWeight:"bold",cursor:"pointer",fontSize:"13px",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:6},onClick:()=>{lc(),Ra({rows:B.rows,cols:B.cols}),Fi(!1),fe(!1)},children:[Re.jsx("span",{style:{display:"grid",gridTemplateColumns:`repeat(${B.cols}, 6px)`,gridTemplateRows:`repeat(${B.rows}, 6px)`,gap:2},children:Array.from({length:B.rows*B.cols}).map((ue,Te)=>Re.jsx("span",{style:{width:6,height:6,borderRadius:1,background:"#90caf9",display:"block"}},Te))}),Re.jsxs("span",{children:[B.rows,"x",B.cols]})]},`${B.rows}x${B.cols}`))})]})]}),Re.jsxs("div",{style:{display:"flex",flexDirection:"row",height:Ht?"100%":"calc(100% - 48px)",gap:Ht?0:8},children:[Re.jsxs("div",{style:{flex:1,display:"grid",margin:Ht?0:3,gridTemplateRows:`repeat(${tn.rows}, 1fr)`,gridTemplateColumns:`repeat(${tn.cols}, 1fr)`,gap:"5px",minHeight:0,minWidth:0,zIndex:1,position:"relative"},children:[yt,!Ht&&Re.jsx("button",{style:{position:"absolute",top:8,right:8,zIndex:2600,padding:"6px 12px",background:"#222",color:"#fff",border:"none",borderRadius:"4px",cursor:"pointer",opacity:.85,userSelect:"none"},onClick:()=>_(!0),children:"Settings"}),Ht&&Re.jsx("div",{style:{position:"absolute",left:0,right:0,bottom:10,zIndex:3200,display:"flex",justifyContent:"center",pointerEvents:"none"},children:Re.jsx("div",{style:{pointerEvents:"auto",display:"flex",alignItems:"center",gap:6,background:"rgba(0,0,0,0.74)",border:"1px solid rgba(255,255,255,0.2)",borderRadius:10,padding:"8px 8px",maxWidth:"95%",overflowX:"auto"},children:Pt.map(B=>{var Ce;const ue=mr.Primary===B,Te=((Ce=md.find(me=>me.value===B))==null?void 0:Ce.label)||B;return Re.jsx("button",{title:Te,onClick:()=>Wl("Primary",B),style:{minWidth:46,height:42,borderRadius:8,border:ue?"1px solid #90caf9":"1px solid rgba(255,255,255,0.22)",background:ue?"#1565c0":"#1f1f1f",color:"#fff",fontSize:18,fontWeight:700,padding:"0 8px"},children:u7(B)},B)})})})]}),Re.jsxs("div",{style:Ht?{position:"absolute",left:8,right:8,bottom:T?62:-420,height:"min(48vh, 420px)",transition:"bottom 220ms ease",display:"flex",flexDirection:"column",pointerEvents:T?"auto":"none",overflow:"hidden",zIndex:3450,borderRadius:12,border:"1px solid #2f3336",boxShadow:"0 6px 24px rgba(0,0,0,0.45)",background:"#1f2428"}:{width:T?b:0,transition:"width 220ms ease",display:"flex",flexDirection:"column",pointerEvents:T?"auto":"none",overflow:"hidden",position:"relative"},children:[T&&!Ht&&Re.jsx("div",{onMouseDown:qc,title:"Resize stacks panel",style:{position:"absolute",left:0,top:0,width:8,height:"100%",cursor:"col-resize",zIndex:2800,background:"linear-gradient(to right, rgba(100,181,246,0.25), rgba(100,181,246,0))"}}),Re.jsx("div",{style:{pointerEvents:"auto",width:"100%",height:"100%"},children:Re.jsxs("div",{style:{height:"100%",width:"100%",background:"#1f2428",color:"#fff",boxShadow:"0 2px 14px rgba(0,0,0,0.45)",borderLeft:"1px solid #2f3336",transform:"translateX(0)",transition:"transform 220ms ease",display:"flex",flexDirection:"column",overflow:"hidden"},children:[Re.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 12px",borderBottom:"1px solid #2b2f31"},children:[Re.jsx("div",{style:{fontWeight:700},children:"Stacks"}),Re.jsxs("div",{style:{fontSize:12,color:"#9bb4c8"},children:["Active VP: ",je!==null?je+1:"-"]}),Re.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[Ht&&Re.jsxs("button",{title:"Toggle stack drop mode",onClick:()=>{Oe(B=>B==="center"?"right":B==="right"?"bottom":"center")},style:{background:"transparent",color:"#90caf9",border:"1px solid #335",borderRadius:6,padding:"4px 8px",cursor:"pointer",fontSize:12},children:["Drop: ",ie]}),Re.jsx("button",{title:"Close",onClick:()=>{E(!1)},style:{background:"transparent",color:"#fff",border:"none",cursor:"pointer",fontSize:16},children:"×"})]})]}),Re.jsx("div",{style:{overflowY:"auto",padding:8,flex:1},children:_t.length===0?Re.jsx("div",{style:{color:"#999",padding:12},children:"No stacks available"}):Re.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6},children:_t.map((B,ue)=>{const Te=Array.isArray(B.imageIds)?B.imageIds:[],Ce=B.name||(B.caseId?`Case: ${B.caseId}`:`Stack ${ue+1}`),me=Te.length,we=!Array.isArray(Te)||me===0,se=En.includes(ue),ge=je!==null&&En[je]===ue,pe=Math.floor(Te.length/2);return Te[pe]||Te[0],Re.jsxs("div",{draggable:!we,onDragStart:de=>{we||(Dt(ue),sn(null),de.dataTransfer.setData("text/stack-idx",String(ue)),de.dataTransfer.effectAllowed="copy")},onDragEnd:()=>{Dt(null),sn(null)},onClick:()=>{if(Date.now(){if(we||no[ue]||io.current[ue])return;const de=Math.floor(Te.length/2),Ve=Te[de]||Te[0]||null;Ve&&qr(ue,Ve)},onMouseEnter:()=>{if(we||no[ue]||io.current[ue])return;const de=Math.floor(Te.length/2),Ve=Te[de]||Te[0]||null;Ve&&qr(ue,Ve)},style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 10px",background:ge?"#0d47a1":se?"#1976d2":"transparent",color:se?"#fff":"#ddd",border:ge?"1px solid #64b5f6":"1px solid transparent",borderRadius:6,cursor:we?"not-allowed":"pointer"},children:[Re.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(()=>{const de=no[ue],Me=(de&&de!=="BROKEN"?de:null)||null;return Me?Re.jsx("img",{"data-thumb-stack":ue,src:Me,alt:Ce,style:{width:56,height:56,objectFit:"cover",borderRadius:4,background:"#111"},onError:()=>{kt.warn("Thumbnail failed to load for stack",ue,Me),bi(ue,"BROKEN")}}):Re.jsx("div",{style:{width:56,height:56,borderRadius:4,background:"#111",display:"flex",alignItems:"center",justifyContent:"center",color:"#777"},children:"No Img"})})(),Re.jsxs("div",{style:{display:"flex",flexDirection:"column"},children:[Re.jsx("div",{style:{fontWeight:600},children:Ce}),Re.jsxs("div",{style:{fontSize:12,opacity:.7},children:[me," img",me===1?"":"s"]})]})]}),Re.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:4},children:[Re.jsx("div",{style:{fontSize:12,opacity:.8},children:B.studyId||""}),ge&&Re.jsx("div",{style:{fontSize:11,color:"#bbdefb",fontWeight:700},children:"ACTIVE"}),Ht&&!we&&Re.jsxs("div",{style:{display:"flex",gap:6},children:[Re.jsx("button",{onClick:de=>{de.stopPropagation(),Vi(je??0,ue),E(!1)},style:{background:"#1565c0",color:"#fff",border:"none",borderRadius:4,padding:"3px 7px",fontSize:11,cursor:"pointer"},children:"Load"}),Re.jsx("button",{onClick:de=>{de.stopPropagation(),!(Date.now(){fc(ue,de)},style:{background:q===ue?"#2e7d32":"#444",color:"#fff",border:"none",borderRadius:4,padding:"3px 7px",fontSize:11,cursor:"pointer"},children:q===ue?"Armed":"Drag"})]})]})]},ue)})})})]})})]})]}),S&&Re.jsx("div",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",background:"rgba(0,0,0,0.4)",zIndex:1e3,display:"flex",alignItems:"flex-start",justifyContent:"center",overflowY:"auto",padding:"16px 12px"},onClick:()=>_(!1),children:Re.jsxs("div",{style:{background:"#222",color:"#fff",borderRadius:"8px",minWidth:"320px",minHeight:"180px",maxWidth:"min(960px, 96vw)",maxHeight:"calc(100vh - 32px)",padding:"24px",boxShadow:"0 4px 24px rgba(0,0,0,0.4)",position:"relative",overflowY:"auto",margin:"0 auto"},onClick:B=>B.stopPropagation(),children:[Re.jsx("div",{style:{fontSize:"20px",marginBottom:"16px"},children:"Settings"}),Re.jsxs("div",{style:{marginBottom:"24px"},children:[Re.jsx("div",{style:{marginBottom:12,fontWeight:"bold"},children:"Mouse Button Tool Bindings"}),h7.map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label," Button:"]}),Re.jsx("select",{value:mr[B.value],onChange:ue=>so(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))})]},B.value)),Re.jsxs("div",{style:{margin:"12px 0"},children:[Re.jsxs("button",{style:{background:"#333",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 12px",cursor:"pointer",fontSize:"14px",marginBottom:"8px"},onClick:()=>Qs(B=>!B),children:[wo?"Hide":"Show"," Advanced Mouse Bindings"]}),wo&&Re.jsx("div",{style:{marginTop:8},children:q2.slice(3).map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label,":"]}),Re.jsxs("select",{value:mr[B.value]||"",onChange:ue=>so(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:[Re.jsx("option",{value:"",children:"(None)"}),md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))]})]},B.value))})]}),Re.jsx("div",{style:{margin:"18px 0 8px 0",fontWeight:"bold"},children:"Window/Level Mouse Sensitivity"}),Re.jsxs("label",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:12},children:[Re.jsx("span",{style:{minWidth:120},children:"Drag sensitivity"}),Re.jsx("input",{type:"range",min:.25,max:2,step:.05,value:Jr,onChange:B=>nc(Number(B.target.value)),style:{flex:1}}),Re.jsxs("span",{style:{minWidth:44,textAlign:"right"},children:[Jr.toFixed(2),"x"]})]}),Re.jsx("div",{style:{margin:"18px 0 8px 0",fontWeight:"bold"},children:"Ctrl + Mouse Button Tool Bindings"}),h7.map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label," + Ctrl:"]}),Re.jsxs("select",{value:No[B.value]||"",onChange:ue=>fa(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:[Re.jsx("option",{value:"",children:"(None)"}),md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))]})]},B.value+"_ctrl")),Re.jsxs("div",{style:{margin:"12px 0"},children:[Re.jsxs("button",{style:{background:"#333",color:"#fff",border:"none",borderRadius:"4px",padding:"4px 12px",cursor:"pointer",fontSize:"14px",marginBottom:"8px"},onClick:()=>$o(B=>!B),children:[Pa?"Hide":"Show"," Advanced Ctrl + Mouse Bindings"]}),Pa&&Re.jsx("div",{style:{marginTop:8},children:q2.slice(3).map(B=>Re.jsxs("div",{style:{marginBottom:10},children:[Re.jsxs("label",{style:{marginRight:8},children:[B.label," + Ctrl:"]}),Re.jsxs("select",{value:No[B.value]||"",onChange:ue=>fa(Te=>({...Te,[B.value]:ue.target.value})),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:[Re.jsx("option",{value:"",children:"(None)"}),md.map(ue=>Re.jsx("option",{value:ue.value,title:ue.label,children:`${ue.icon?`${ue.icon} `:""}${ue.label}`},ue.value))]})]},B.value+"_ctrl"))})]})]}),Re.jsxs("div",{style:{marginTop:8,paddingTop:16,borderTop:"1px solid #333"},children:[Re.jsx("div",{style:{marginBottom:10,fontWeight:"bold"},children:"Stack Grouping"}),Re.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,cursor:"pointer",marginBottom:10},children:[Re.jsx("input",{type:"checkbox",checked:m,onChange:B=>w(B.target.checked)}),"Enable advanced DWI/time/echo grouping"]}),Re.jsx("div",{style:{display:"flex",flexDirection:"column",gap:6,opacity:m?1:.6},children:mp.map(B=>Re.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,cursor:m?"pointer":"default"},title:B.description,children:[Re.jsx("input",{type:"checkbox",disabled:!m,checked:!!x[B.id],onChange:ue=>{const Te=ue.target.checked;C(Ce=>({...Ce,[B.id]:Te}))}}),B.label]},B.id))})]}),Re.jsxs("div",{style:{marginTop:8,paddingTop:16,borderTop:"1px solid #333"},children:[Re.jsx("div",{style:{marginBottom:10,fontWeight:"bold"},children:"Logging"}),Re.jsxs("div",{style:{display:"flex",alignItems:"center",gap:16,marginBottom:10,flexWrap:"wrap"},children:[Re.jsxs("div",{children:[Re.jsx("label",{style:{marginRight:8},children:"Level:"}),Re.jsx("select",{value:g,onChange:B=>p(S5(B.target.value)),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:kSe.map(B=>Re.jsx("option",{value:B.value,children:B.label},B.value))})]}),Re.jsxs("div",{children:[Re.jsx("label",{style:{marginRight:8},children:"Format:"}),Re.jsx("select",{value:v,onChange:B=>y(jp(B.target.value)),style:{background:"#333",color:"#fff",border:"1px solid #444",borderRadius:"4px",padding:"4px 8px",fontSize:"14px"},children:NSe.map(B=>Re.jsx("option",{value:B.value,children:B.label},B.value))})]})]})]}),Re.jsx("button",{style:{position:"absolute",top:12,right:12,background:"transparent",color:"#fff",border:"none",fontSize:"20px",cursor:"pointer"},onClick:()=>_(!1),"aria-label":"Close",children:"×"})]})}),is&&Re.jsx("div",{style:{position:"fixed",top:0,left:0,width:"100vw",height:"100vh",background:"rgba(0,0,0,0.5)",zIndex:2e3,display:"flex",alignItems:"center",justifyContent:"center"},onClick:()=>os(!1),children:Re.jsxs("div",{style:{background:"#222",color:"#fff",borderRadius:"8px",minWidth:"320px",maxWidth:"80vw",maxHeight:"80vh",padding:"24px",boxShadow:"0 4px 24px rgba(0,0,0,0.4)",position:"relative",overflow:"auto"},onClick:B=>B.stopPropagation(),children:[Re.jsx("div",{style:{fontSize:"20px",marginBottom:"16px"},children:"DICOM Metadata"}),rc,Re.jsx("button",{style:{position:"absolute",top:12,right:12,background:"transparent",color:"#fff",border:"none",fontSize:"20px",cursor:"pointer"},onClick:()=>os(!1),"aria-label":"Close",children:"×"})]})})]})}function USe(t){kt.debug("Setting up tools...",t),Yi(Ec),Yi(gu),Yi(bf),Yi(gl),Yi(Bh),Yi(Gf),Yi(Iu),Yi(Wf),Yi(Du),Yi(e0),Yi(Bf),Yi(Ll),Yi(Gh),Yi(gs),Yi(fl),Yi(Vd),Yi($h);let e=xi(t);return e||(e=$k(t),e.addTool(gu.toolName),e.addTool(Ec.toolName),e.addTool(gl.toolName),e.addTool(bf.toolName,{loop:!1}),e.addTool(Bh.toolName),e.addTool(Gf.toolName),e.addTool($h.toolName,{getTextCallback:()=>""}),e.addTool(Wf.toolName),e.addTool(Iu.toolName,{statsCalculator:()=>null}),e.addTool(Du.toolName,{calculateStats:!1,getTextCallback:()=>""}),e.addTool(e0.toolName,{getTextCallback:()=>""}),e.addTool(Bf.toolName,{calculateStats:!1}),e.addTool(Ll.toolName,{}),e.addTool(Gh.toolName,{}),e.addTool(Vd.toolName),e.addTool(gs.toolName)),e}function g7(t,e,r,n){if(!r.length||!e.length)return null;const i=r.map(o=>e.findIndex(a=>a===o.metadata.referencedImageId)).filter(o=>o!==-1).sort((o,a)=>o-a);if(!i.length)return null;if(n===1){for(let o of i)if(o>t)return o;return i[0]}else{for(let o=i.length-1;o>=0;o--)if(i[o]`wadouri:/test_images/stack2/IMG${r+1}.dcm`),Array.from({length:25},(e,r)=>`wadouri:/test_images/stack5/IMG${r+1}.dcm`),Array.from({length:26},(e,r)=>`wadouri:/test_images/stack3/IMG${r+1}.dcm`)]}const NC=new WeakMap,Hp=jW.child("main"),GSe=t=>{const e=t.trim();return!e||e.startsWith("external:")||e.startsWith("wadors:")?e:e.startsWith("wadouri:")?`wadouri:${e.slice(8).replace(/^:+/,"")}`:`wadouri:${e.replace(/^:+/,"")}`},Ym=t=>t.map(GSe),p7=t=>t?{imageIds:Ym(t)}:{imageIds:[]},WSe=t=>{if(!t)return[];if(Array.isArray(t)&&t.length>0&&typeof t[0]=="string")return[p7(t)];if(!Array.isArray(t))return[];const e=[];return t.forEach((r,n)=>{if(r&&typeof r=="object"&&Array.isArray(r.stacks)){const i=r.caseId||r.caseUID||r.case||void 0,o=r.studyId||r.studyUID||r.studyInstanceUID||void 0;r.stacks.forEach((a,s)=>{let c=[];if(Array.isArray(a)?c=a:Array.isArray(a.imageIds)?c=a.imageIds:Array.isArray(a.i)&&(c=a.i),!Array.isArray(c)||c.length===0||!c.every(l=>typeof l=="string")){Hp.warn(`data-named-stacks: skipping invalid nested stack at parsed[${n}].stacks[${s}]`,a);return}e.push({imageIds:Ym(c),name:a.name||a.label||void 0,caseId:i,studyId:a.studyId||o,series:Array.isArray(a.series)?a.series:void 0})});return}if(r&&typeof r=="object"&&(Array.isArray(r.imageIds)||Array.isArray(r.i))){const i=Array.isArray(r.imageIds)?r.imageIds:r.i;if(!Array.isArray(i)||i.length===0||!i.every(o=>typeof o=="string")){Hp.warn(`data-named-stacks: skipping invalid stack object at parsed[${n}]`,r);return}e.push({imageIds:Ym(i),name:r.name||r.label||void 0,caseId:r.caseId||r.caseUID||void 0,studyId:r.studyId||r.studyUID||r.studyInstanceUID||void 0,series:Array.isArray(r.series)?r.series:void 0});return}if(Array.isArray(r)&&r.length>0&&typeof r[0]=="string"){e.push(p7(r));return}Hp.warn(`data-named-stacks: unknown or invalid entry at parsed[${n}] - skipping`,r)}),e},zSe=t=>JSON.stringify({id:t.id||"",empty:t.getAttribute("data-empty")||"",namedStacks:t.getAttribute("data-named-stacks")||"",images:t.getAttribute("data-images")||"",autoCache:t.getAttribute("data-auto-cache-stack")||"",annotation:t.getAttribute("data-annotationjson")||"",viewerState:t.getAttribute("data-viewerstate")||""}),m7=(t,e)=>!(e!=null&&e.containerIds)||e.containerIds.length===0?!0:e.containerIds.includes(t.id||""),$Se=(t,e)=>{var s,c,l;const r=t.getAttribute("data-log-level"),n=t.getAttribute("data-log-debug"),i=t.getAttribute("data-log-format");let o;r!==null?o=S5(r):(s=e==null?void 0:e.logging)!=null&&s.minLevel?o=e.logging.minLevel:n!==null?o=f_(n):((c=e==null?void 0:e.logging)==null?void 0:c.debug)!==void 0?o=f_(e.logging.debug):o="warn";const a=jp(i??((l=e==null?void 0:e.logging)==null?void 0:l.format));return{minLevel:o,format:a}},v7=(t,e,r)=>{const n=zSe(t),i=NC.get(t),o=$Se(t,r);if(i&&!(r!=null&&r.force)&&i.signature===n)return;i&&(i.root.unmount(),NC.delete(t)),T8(o);const a=MM(t);a.render(Re.jsx(FSe,{container_id:t.id||"",imageStacks:e,autoCacheStack:t.getAttribute("data-auto-cache-stack")==="true"||t.getAttribute("data-auto-cache-stack")==="1",annotationJson:t.getAttribute("data-annotationjson")||void 0,viewerState:t.getAttribute("data-viewerstate")||void 0,initialLoggerConfig:o})),NC.set(t,{root:a,signature:n})};function E8(t){document.querySelectorAll(".dicom-viewer-test-root").forEach(n=>{if(!m7(n,t))return;v7(n,()=>BSe(),t)}),document.querySelectorAll(".dicom-viewer-root").forEach(n=>{if(!m7(n,t))return;let i;const o=n.getAttribute("data-empty")==="true",a=n.getAttribute("data-named-stacks"),s=n.getAttribute("data-images");if(o)i=()=>Promise.resolve([]);else if(a){let c;try{c=JSON.parse(a)}catch(f){Hp.error("Invalid data-named-stacks JSON:",f),c=[]}const l=WSe(c);i=()=>Promise.resolve(l)}else if(s){let c;try{c=JSON.parse(s)}catch(l){Hp.error("Invalid data-images JSON:",l),c=[]}Array.isArray(c)&&c.length>0&&typeof c[0]=="string"?i=()=>Promise.resolve([Ym(c)]):Array.isArray(c)?i=()=>Promise.resolve(c.map(l=>Array.isArray(l)?Ym(l):[])):i=()=>Promise.resolve([[]])}else i=()=>Promise.resolve([]);v7(n,i,t)})}E8();window.mountDicomViewers=E8;window.remountDicomViewer=t=>{E8({force:!0,containerIds:[t]})};window.setDicomViewerLogging=t=>{const e=t.minLevel?S5(t.minLevel):t.debug!==void 0?f_(t.debug):void 0;T8({minLevel:e,format:t.format?jp(t.format):void 0})};window.getDicomViewerLogging=()=>C5();