From 52c2611e9d377316f9ed4b2e95f8e4b80e02590c Mon Sep 17 00:00:00 2001 From: Victor Gorchilov Date: Fri, 9 Dec 2022 14:40:39 +0200 Subject: [PATCH] Feature: Add customisable icons in topology (#193) * [up] add config for custom images, better js * [up] use bundler to bundle js * [fix] remove domcontentloaded since defer is used * [fix] formatting with black * [fix] images drf api * [up] add support for custom icons on additional roles: power panel, power feed, circuit * [up] optimize topology generation by using `_id` when trying to access pk of related object * [fix] kebab case instead of slugification * [fix] use empty queryset in api views & change coord save logic --- README.md | 45 +- netbox_topology_views/__init__.py | 41 +- netbox_topology_views/api/__init__.py | 2 +- netbox_topology_views/api/serializers.py | 20 +- netbox_topology_views/api/urls.py | 12 +- netbox_topology_views/api/views.py | 174 +++-- netbox_topology_views/filters.py | 44 +- netbox_topology_views/forms.py | 96 ++- .../migrations/0001_initial.py | 31 + netbox_topology_views/migrations/__init__.py | 0 netbox_topology_views/models.py | 93 +++ netbox_topology_views/navigation.py | 7 +- .../static/netbox_topology_views/css/app.css | 2 +- .../static/netbox_topology_views/js/app.js | 20 +- .../static/netbox_topology_views/js/images.js | 1 + .../netbox_topology_views/js/images.js.map | 6 + netbox_topology_views/static_dev/bundle.js | 141 ++-- netbox_topology_views/static_dev/css/app.scss | 26 +- .../static_dev/js/csrftoken.js | 17 + netbox_topology_views/static_dev/js/home.js | 266 +++---- netbox_topology_views/static_dev/js/images.js | 41 ++ netbox_topology_views/static_dev/js/toast.js | 18 + .../netbox_topology_views/images.html | 46 ++ .../netbox_topology_views/index.html | 12 +- .../netbox_topology_views/toasts.html | 44 ++ netbox_topology_views/urls.py | 6 +- netbox_topology_views/utils.py | 86 +++ netbox_topology_views/views.py | 689 +++++++++++++----- requirements.txt | 3 + setup.py | 34 +- 30 files changed, 1395 insertions(+), 628 deletions(-) create mode 100644 netbox_topology_views/migrations/0001_initial.py create mode 100644 netbox_topology_views/migrations/__init__.py create mode 100644 netbox_topology_views/models.py create mode 100644 netbox_topology_views/static/netbox_topology_views/js/images.js create mode 100644 netbox_topology_views/static/netbox_topology_views/js/images.js.map create mode 100644 netbox_topology_views/static_dev/js/csrftoken.js create mode 100644 netbox_topology_views/static_dev/js/images.js create mode 100644 netbox_topology_views/static_dev/js/toast.js create mode 100644 netbox_topology_views/templates/netbox_topology_views/images.html create mode 100644 netbox_topology_views/templates/netbox_topology_views/toasts.html create mode 100644 netbox_topology_views/utils.py create mode 100644 requirements.txt diff --git a/README.md b/README.md index 5a85bf3..9e84722 100644 --- a/README.md +++ b/README.md @@ -36,19 +36,20 @@ Then run ```bash cd /opt/netbox/netbox pip3 install netbox-topology-views +python3 manage.py migrate netbox_topology_views python3 manage.py collectstatic --no-input ``` ### Versions -| netbox version | netbox-topology-views version | -| ------------- |-------------| -| >= 3.3.0 | >= v3.0.0 | -| >= 3.2.0 | >= v1.1.0 | -| >= 3.1.8 | >= v1.0.0 | -| >= 2.11.1 | >= v0.5.3 | -| >= 2.10.0 | >= v0.5.0 | -| < 2.10.0 | =< v0.4.10 | +| netbox version | netbox-topology-views version | +| -------------- | ----------------------------- | +| >= 3.3.0 | >= v3.0.0 | +| >= 3.2.0 | >= v1.1.0 | +| >= 3.1.8 | >= v1.0.0 | +| >= 2.11.1 | >= v0.5.3 | +| >= 2.10.0 | >= v0.5.0 | +| < 2.10.0 | =< v0.4.10 | ### Custom field: coordinates @@ -69,27 +70,25 @@ Example: ``` PLUGINS_CONFIG = { 'netbox_topology_views': { - 'device_img': ['router','switch', 'firewall'], - 'preselected_device_roles': ['Router', 'Firewall'] + 'preselected_device_roles': ['Router', 'Firewall'], + 'enable_circuit_terminations': True } } ``` -| Setting | Default value | Description | -| ------------- |-------------| -----| -| device_img |['access-switch', 'core-switch', 'firewall', 'router', 'distribution-switch', 'backup', 'storage,wan-network', 'wireless-ap', 'server', 'internal-switch', 'isp-cpe-material', 'non-racked-devices', 'power-units'] | The slug of the device roles that you have a image for. | -| preselected_device_roles | ['Firewall', 'Router', 'Distribution Switch', 'Core Switch', 'Internal Switch', 'Access Switch', 'Server', 'Storage', 'Backup', 'Wireless AP'] | The full name of the device roles you want to pre select in the global view. Note that this is case sensitive| -| allow_coordinates_saving | False | (bool) Set to true if you use the custom coordinates fields and want to save the coordinates | -| always_save_coordinates | False | (bool) Set if you want to enable the option to save coordinates by default | -| ignore_cable_type | [] | The cable types that you want to ignore in the views | -| preselected_tags | '[]' | The name of tags you want to preload | -| draw_default_layout | False | (bool) Set to True if you want to load draw the topology on the initial load (when you go to the topology plugin page) | +| Setting | Default value | Description | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| static_image_directory | netbox_topology_views/img | (str or pathlib.Path) Specifies the location that images will be loaded from by default. Must be within `STATIC_ROOT` | +| preselected_device_roles | ['Firewall', 'Router', 'Distribution Switch', 'Core Switch', 'Internal Switch', 'Access Switch', 'Server', 'Storage', 'Backup', 'Wireless AP'] | The full name of the device roles you want to pre select in the global view. Note that this is case sensitive | +| allow_coordinates_saving | False | (bool) Set to true if you use the custom coordinates fields and want to save the coordinates | +| always_save_coordinates | False | (bool) Set if you want to enable the option to save coordinates by default | +| ignore_cable_type | [] | The cable types that you want to ignore in the views | +| preselected_tags | [] | The name of tags you want to preload | +| draw_default_layout | False | (bool) Set to True if you want to load draw the topology on the initial load (when you go to the topology plugin page) | ### Custom Images -You upload you own custom images to the netbox static dir (`static/netbox_topology_views/img/`). -These images need to be named after de device role slug and have the .png format/extension. -If you add your own image you also need to add the slug to the `device_img` setting. +To change image with associated device use the `Images` page - it allows to map a device role with an image found in the netbox static directory (defined by the plugin config `static_image_directory` which defaults to `netbox_topology_views/img`). You can also upload you own custom images to there - these images will automatically be used for a device (if it does not already have a specified image in the settings) if their name is the device role slug. ## Use @@ -99,6 +98,8 @@ Go to the plugins tab in the navbar and click topology or go to `$NETBOX_URL/plu Run `pip install netbox-topology-views --upgrade` in your venv. +Run `python3 manage.py migrate netbox_topology_views` + Run `python3 manage.py collectstatic --no-input` diff --git a/netbox_topology_views/__init__.py b/netbox_topology_views/__init__.py index eee4829..9386c9b 100644 --- a/netbox_topology_views/__init__.py +++ b/netbox_topology_views/__init__.py @@ -1,22 +1,35 @@ from extras.plugins import PluginConfig + class TopologyViewsConfig(PluginConfig): - name = 'netbox_topology_views' - verbose_name = 'Topology views' - description = 'An plugin to render topology maps' - version = '3.0.1' - author = 'Mattijs Vanhaverbeke' - author_email = 'author@example.com' - base_url = 'netbox_topology_views' + name = "netbox_topology_views" + verbose_name = "Topology views" + description = "An plugin to render topology maps" + version = "3.0.1" + author = "Mattijs Vanhaverbeke" + author_email = "author@example.com" + base_url = "netbox_topology_views" required_settings = [] default_settings = { - 'preselected_device_roles': ['Firewall', 'Router', 'Distribution Switch', 'Core Switch', 'Internal Switch', 'Access Switch', 'Server', 'Storage', 'Backup', 'Wireless AP'], - 'ignore_cable_type': [], - 'device_img': ['access-switch', 'core-switch', 'firewall', 'router', 'distribution-switch', 'backup', 'storage', 'wan-network', 'wireless-ap', 'server', 'internal-switch', 'isp-cpe-material', 'non-racked-devices', 'power-units'], - 'allow_coordinates_saving': False, - 'always_save_coordinates': False, - 'preselected_tags' : [], - 'draw_default_layout': False + "preselected_device_roles": [ + "Firewall", + "Router", + "Distribution Switch", + "Core Switch", + "Internal Switch", + "Access Switch", + "Server", + "Storage", + "Backup", + "Wireless AP", + ], + "ignore_cable_type": [], + "static_image_directory": "netbox_topology_views/img", + "allow_coordinates_saving": False, + "always_save_coordinates": False, + "preselected_tags": [], + "draw_default_layout": False, } + config = TopologyViewsConfig diff --git a/netbox_topology_views/api/__init__.py b/netbox_topology_views/api/__init__.py index 2bf6ee2..cea588a 100644 --- a/netbox_topology_views/api/__init__.py +++ b/netbox_topology_views/api/__init__.py @@ -1 +1 @@ -"""REST API""" \ No newline at end of file +"""REST API""" diff --git a/netbox_topology_views/api/serializers.py b/netbox_topology_views/api/serializers.py index b4a209b..56dd400 100644 --- a/netbox_topology_views/api/serializers.py +++ b/netbox_topology_views/api/serializers.py @@ -1,12 +1,22 @@ +from dcim.models import Device, DeviceRole from rest_framework.serializers import ModelSerializer -from dcim.models import DeviceRole, Device -from extras.models import Tag +from netbox_topology_views.models import RoleImage class TopologyDummySerializer(ModelSerializer): - class Meta: model = Device - fields = ('id', 'name') - \ No newline at end of file + fields = ("id", "name") + + +class RoleImageSerializer(ModelSerializer): + class Meta: + model = RoleImage + fields = ("role", "image") + + +class DeviceRoleSerializer(ModelSerializer): + class Meta: + model = DeviceRole + fields = ("name", "slug", "color", "vm_role", "description") diff --git a/netbox_topology_views/api/urls.py b/netbox_topology_views/api/urls.py index 1fe59ac..b098317 100644 --- a/netbox_topology_views/api/urls.py +++ b/netbox_topology_views/api/urls.py @@ -1,8 +1,10 @@ -from rest_framework import routers -from . import views +from netbox.api.routers import NetBoxRouter -router = routers.DefaultRouter() +from netbox_topology_views.api import views -router.register('save-coords', views.SaveCoordsViewSet, basename='save_coords') +router = NetBoxRouter() -urlpatterns = router.urls \ No newline at end of file +router.register("save-coords", views.SaveCoordsViewSet) +router.register("images", views.SaveRoleImageViewSet) + +urlpatterns = router.urls diff --git a/netbox_topology_views/api/views.py b/netbox_topology_views/api/views.py index 14217ed..91016ad 100644 --- a/netbox_topology_views/api/views.py +++ b/netbox_topology_views/api/views.py @@ -1,70 +1,128 @@ -from rest_framework.viewsets import ModelViewSet, ViewSet, ReadOnlyModelViewSet, GenericViewSet +from typing import Dict + +from circuits.models import Circuit +from dcim.models import Device, DeviceRole, PowerFeed, PowerPanel +from django.conf import settings +from django.contrib.auth.mixins import PermissionRequiredMixin +from django.contrib.contenttypes.models import ContentType +from django.http import JsonResponse from rest_framework.decorators import action from rest_framework.response import Response -from django.contrib.contenttypes.models import ContentType -from rest_framework.routers import APIRootView +from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet -from .serializers import TopologyDummySerializer -from django.conf import settings - -from dcim.models import DeviceRole, Device, Cable , PowerPanel, PowerFeed -from circuits.models import Circuit -from extras.models import Tag - - -class TopologyViewsRootView(APIRootView): - def get_view_name(self): - return 'TopologyViews' +from netbox_topology_views.api.serializers import ( + RoleImageSerializer, + TopologyDummySerializer, +) +from netbox_topology_views.models import RoleImage +from netbox_topology_views.utils import get_image_from_url class SaveCoordsViewSet(ReadOnlyModelViewSet): - queryset = Device.objects.all() + queryset = Device.objects.none() serializer_class = TopologyDummySerializer - @action(detail=False, methods=['patch']) + @action(detail=False, methods=["patch"]) def save_coords(self, request): - results = {} - if settings.PLUGINS_CONFIG["netbox_topology_views"]["allow_coordinates_saving"]: - device_id = None - x_coord = None - y_coord = None - if "node_id" in request.data: - if request.data["node_id"]: - device_id = request.data["node_id"] - if "x" in request.data: - if request.data["x"]: - x_coord = request.data["x"] - if "y" in request.data: - if request.data["y"]: - y_coord = request.data["y"] - - if device_id.startswith("c"): - device_id = device_id.lstrip('c') - actual_device= Circuit.objects.get(id=device_id) - elif device_id.startswith("p"): - device_id = device_id.lstrip('p') - actual_device= PowerPanel.objects.get(id=device_id) - elif device_id.startswith("f"): - device_id = device_id.lstrip('f') - actual_device= PowerFeed.objects.get(id=device_id) - else: - actual_device= Device.objects.get(id=device_id) + if not settings.PLUGINS_CONFIG["netbox_topology_views"][ + "allow_coordinates_saving" + ]: + return Response({"status": "not allowed to save coords"}, status=500) - if "coordinates" in actual_device.custom_field_data: - actual_device.custom_field_data["coordinates"] = "%s;%s" % (x_coord,y_coord) - actual_device.save() - results["status"] = "saved coords" - else: - try: - actual_device.custom_field_data["coordinates"] = "%s;%s" % (x_coord,y_coord) - actual_device.save() - results["status"] = "saved coords" - except : - results["status"] = "coords custom field not created" - return Response(status=500) + device_id: str = request.data.get("node_id", None) + x_coord = request.data.get("x", None) + y_coord = request.data.get("y", None) - return Response(results) - else: - results["status"] = "not allowed to save coords" - return Response(results, status=500) + actual_device = None + if device_id.startswith("c"): + device_id = device_id.lstrip("c") + actual_device = Circuit.objects.get(id=device_id) + elif device_id.startswith("p"): + device_id = device_id.lstrip("p") + actual_device = PowerPanel.objects.get(id=device_id) + elif device_id.startswith("f"): + device_id = device_id.lstrip("f") + actual_device = PowerFeed.objects.get(id=device_id) + elif device_id.isnumeric(): + actual_device = Device.objects.get(id=device_id) + if not actual_device: + return Response({"status": "invalid node_id in body"}, status=400) + + try: + actual_device.custom_field_data["coordinates"] = "%s;%s" % ( + x_coord, + y_coord, + ) + actual_device.save() + except: + return Response( + {"status": "coords custom field could not be saved"}, status=500 + ) + + return Response({"status": "saved coords"}) + + +class SaveRoleImageViewSet(PermissionRequiredMixin, ViewSet): + queryset = DeviceRole.objects.none() + serializer_class = RoleImageSerializer + permission_required = ( + "dcim.add_device_role", + "dcim.change_device_role", + ) + + def create(self, request): + if not isinstance(request.data, dict): + return JsonResponse( + {"status": "Missing or malformed request body"}, status=400 + ) + + device_roles = {k: v for k, v in request.data.items() if k.isnumeric()} + content_type_ids = { + k[2:]: v + for k, v in request.data.items() + if k.startswith("ct") and k[2:].isnumeric() + } + + roles: Dict[int, DeviceRole] = DeviceRole.objects.in_bulk(device_roles.keys()) + content_types: Dict[int, ContentType] = ContentType.objects.in_bulk( + content_type_ids.keys() + ) + + if len(roles) != len(device_roles): + difference = set(device_roles) - set(roles.keys()) + return JsonResponse( + {"status": f"Got unknown device role ids: {difference}"}, + status=400, + ) + + if len(content_types) != len(content_type_ids): + difference = set(content_type_ids) - set(content_types.keys()) + return JsonResponse( + {"status": f"Got unknown content type ids: {difference}"}, + status=400, + ) + + if device_roles: + device_role_ct = ContentType.objects.get_for_model(DeviceRole) + + for id, url in device_roles.items(): + RoleImage.objects.update_or_create( + { + "content_type_id": device_role_ct.pk, + "object_id": id, + "image": str(get_image_from_url(url)), + }, + object_id=id, + ) + + for content_type_id, url in content_type_ids.items(): + RoleImage.objects.update_or_create( + { + "content_type_id": content_type_id, + "image": str(get_image_from_url(url)), + }, + content_type_id=content_type_id, + ) + + return JsonResponse({"status": "Ok"}) diff --git a/netbox_topology_views/filters.py b/netbox_topology_views/filters.py index 232aabb..9a8e70d 100644 --- a/netbox_topology_views/filters.py +++ b/netbox_topology_views/filters.py @@ -1,63 +1,55 @@ -from cProfile import label import django_filters -from django.db.models import Q - -from dcim.models import Device, DeviceRole, Region, Site, Location, Rack from dcim.choices import DeviceStatusChoices - +from dcim.models import Device, DeviceRole, Location, Rack, Region, Site +from django.db.models import Q from netbox.filtersets import NetBoxModelFilterSet - -from tenancy.models import TenantGroup, Tenant from tenancy.filtersets import TenancyFilterSet - from utilities.filters import TreeNodeMultipleChoiceFilter class DeviceFilterSet(TenancyFilterSet, NetBoxModelFilterSet): q = django_filters.CharFilter( - method='search', - label='Search', + method="search", + label="Search", ) device_role_id = django_filters.ModelMultipleChoiceFilter( - field_name='device_role_id', + field_name="device_role_id", queryset=DeviceRole.objects.all(), - label='Role (ID)', + label="Role (ID)", ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), - field_name='site__region', - lookup_expr='in', - label='Region (ID)', + field_name="site__region", + lookup_expr="in", + label="Region (ID)", ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), - label='Site (ID)', + label="Site (ID)", ) location_id = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), - field_name='location', - lookup_expr='in', - label='Location (ID)', + field_name="location", + lookup_expr="in", + label="Location (ID)", ) rack_id = django_filters.ModelMultipleChoiceFilter( queryset=Rack.objects.all(), - field_name='rack_id', - label='Rack (ID)', + field_name="rack_id", + label="Rack (ID)", ) status = django_filters.MultipleChoiceFilter( choices=DeviceStatusChoices, null_value=None, ) - + class Meta: model = Device - fields = ['id', 'name'] + fields = ["id", "name"] def search(self, queryset, name, value): """Perform the filtered search.""" if not value.strip(): return queryset - qs_filter = ( - Q(name__icontains=value) - ) + qs_filter = Q(name__icontains=value) return queryset.filter(qs_filter) diff --git a/netbox_topology_views/forms.py b/netbox_topology_views/forms.py index 4121f6f..dfa7b2d 100644 --- a/netbox_topology_views/forms.py +++ b/netbox_topology_views/forms.py @@ -13,92 +13,108 @@ from tenancy.models import TenantGroup, Tenant from tenancy.forms import TenancyFilterForm from django.conf import settings from netbox.forms import NetBoxModelFilterSetForm -from utilities.forms import (TagFilterField, DynamicModelMultipleChoiceField, MultipleChoiceField) +from utilities.forms import ( + TagFilterField, + DynamicModelMultipleChoiceField, + MultipleChoiceField, +) -allow_coordinates_saving = bool(settings.PLUGINS_CONFIG["netbox_topology_views"]["allow_coordinates_saving"]) +allow_coordinates_saving = bool( + settings.PLUGINS_CONFIG["netbox_topology_views"]["allow_coordinates_saving"] +) class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): model = Device fieldsets = ( - (None, ('q', 'hide_unconnected', 'save_coords', 'show_circuit', 'show_power' ,)), - (None, ('tenant_group_id', 'tenant_id',)), - (None, ('region_id', 'site_id', 'location_id', 'rack_id')), - (None, ('device_role_id','id','status', )), - (None, ('tag', )), + ( + None, + ( + "q", + "hide_unconnected", + "save_coords", + "show_circuit", + "show_power", + ), + ), + ( + None, + ( + "tenant_group_id", + "tenant_id", + ), + ), + (None, ("region_id", "site_id", "location_id", "rack_id")), + ( + None, + ( + "device_role_id", + "id", + "status", + ), + ), + (None, ("tag",)), ) region_id = DynamicModelMultipleChoiceField( - queryset=Region.objects.all(), - required=False, - label=_('Region') + queryset=Region.objects.all(), required=False, label=_("Region") ) device_role_id = DynamicModelMultipleChoiceField( - queryset=DeviceRole.objects.all(), - required=False, - label=_('Device Role') + queryset=DeviceRole.objects.all(), required=False, label=_("Device Role") ) id = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, - label=_('Device'), + label=_("Device"), query_params={ - 'location_id' : '$location_id', - 'region_id': '$region_id', - 'site_id': '$site_id', - 'role_id': '$device_role_id', + "location_id": "$location_id", + "region_id": "$region_id", + "site_id": "$site_id", + "role_id": "$device_role_id", }, ) site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, query_params={ - 'region_id': '$region_id', + "region_id": "$region_id", }, - label=_('Site') + label=_("Site"), ) location_id = DynamicModelMultipleChoiceField( queryset=Location.objects.all(), required=False, query_params={ - 'region_id': '$region_id', - 'site_id': '$site_id', + "region_id": "$region_id", + "site_id": "$site_id", }, - label=_('Location') + label=_("Location"), ) rack_id = DynamicModelMultipleChoiceField( queryset=Rack.objects.all(), required=False, query_params={ - 'region_id': '$region_id', - 'site_id': '$site_id', - 'location_id': '$location_id', + "region_id": "$region_id", + "site_id": "$site_id", + "location_id": "$location_id", }, - label=_('Rack') + label=_("Rack"), ) hide_unconnected = forms.BooleanField( - label=_("Hide Unconnected"), - required=False, - initial=False + label=_("Hide Unconnected"), required=False, initial=False ) show_circuit = forms.BooleanField( - label=_("Show Circuit Terminations"), - required=False, - initial=False + label=_("Show Circuit Terminations"), required=False, initial=False ) show_power = forms.BooleanField( - label=_("Show Power Feeds"), - required=False, - initial=False + label=_("Show Power Feeds"), required=False, initial=False ) save_coords = forms.BooleanField( label=_("Save Coordinates"), required=False, - disabled=(not allow_coordinates_saving) + disabled=(not allow_coordinates_saving), ) status = MultipleChoiceField( - choices=DeviceStatusChoices, - required=False, - label=_("Device Status") + choices=DeviceStatusChoices, required=False, label=_("Device Status") ) tag = TagFilterField(model) diff --git a/netbox_topology_views/migrations/0001_initial.py b/netbox_topology_views/migrations/0001_initial.py new file mode 100644 index 0000000..c8411dc --- /dev/null +++ b/netbox_topology_views/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 4.0.8 on 2022-12-06 13:07 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ] + + operations = [ + migrations.CreateModel( + name='RoleImage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True, null=True)), + ('last_updated', models.DateTimeField(auto_now=True, null=True)), + ('image', models.CharField(max_length=255)), + ('object_id', models.PositiveIntegerField(blank=True, null=True)), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ], + ), + migrations.AddIndex( + model_name='roleimage', + index=models.Index(fields=['content_type', 'object_id'], name='netbox_topo_content_9d87d4_idx'), + ), + ] diff --git a/netbox_topology_views/migrations/__init__.py b/netbox_topology_views/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/netbox_topology_views/models.py b/netbox_topology_views/models.py new file mode 100644 index 0000000..c4002cc --- /dev/null +++ b/netbox_topology_views/models.py @@ -0,0 +1,93 @@ +from pathlib import Path +from typing import Optional + +from dcim.models import DeviceRole +from django.conf import settings +from django.contrib.contenttypes.models import ContentType +from django.db import models +from django.templatetags.static import static +from netbox.models.features import ( + ChangeLoggingMixin, + ExportTemplatesMixin, + WebhooksMixin, +) + +from netbox_topology_views.utils import ( + CONF_IMAGE_DIR, + IMAGE_DIR, + Role, + find_image_url, + get_model_role, + image_static_url, +) + + +class RoleImage(ChangeLoggingMixin, ExportTemplatesMixin, WebhooksMixin): + class Meta: + indexes = [ + models.Index(fields=["content_type", "object_id"]), + ] + + objects: "models.Manager[RoleImage]" + + image = models.CharField("Path within the netbox static directory", max_length=255) + + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField(null=True, blank=True) + + __role: Optional[Role] = None + + @property + def role(self) -> Role: + if self.__role: + return self.__role + + model_class = self.content_type.model_class() + + if not model_class: + raise ValueError(f"Invalid content type: {self.content_type}") + + if model_class == DeviceRole: + device_role: DeviceRole = DeviceRole.objects.get(pk=self.object_id) + self.__role = Role(slug=device_role.slug, name=device_role.name) + return self.__role + + self.__role = get_model_role(model_class) + return self.__role + + def __str__(self): + return f"{self.role} - {self.image}" + + def get_image(self) -> Path: + """Get Icon + + returns the model's image's absolute path in the filesystem + raises ValueError if the file cannot be found + """ + path = Path(settings.STATIC_ROOT) / self.image + + if not path.exists(): + raise ValueError(f"{self.role} path '{path}' does not exists") + + return path + + def get_default_image(self, dir: Path = CONF_IMAGE_DIR): + """Get default image + + will attempt to find image in given directory with any file extension, + otherwise will try to find a `role-unknown` image + + fallback is `STATIC_ROOT/netbox_topology_views/img/role-unknown.png` + """ + if url := find_image_url(self.role.slug, dir): + return url + + # fallback to default role unknown image + return image_static_url(IMAGE_DIR / "role-unknown.png") + + def get_image_url(self, dir: Path = CONF_IMAGE_DIR) -> str: + try: + self.get_image() + except ValueError: + return self.get_default_image(dir) + return static(f"/{self.image}") diff --git a/netbox_topology_views/navigation.py b/netbox_topology_views/navigation.py index a62c6d1..f1a71b8 100644 --- a/netbox_topology_views/navigation.py +++ b/netbox_topology_views/navigation.py @@ -1,9 +1,8 @@ -from extras.plugins import PluginMenuButton, PluginMenuItem -from utilities.choices import ButtonColorChoices +from extras.plugins import PluginMenuItem menu_items = ( + PluginMenuItem(link="plugins:netbox_topology_views:home", link_text="Topology"), PluginMenuItem( - link='plugins:netbox_topology_views:home', - link_text='Topology' + link="plugins:netbox_topology_views:images", link_text="Topology Images" ), ) diff --git a/netbox_topology_views/static/netbox_topology_views/css/app.css b/netbox_topology_views/static/netbox_topology_views/css/app.css index fd9837e..8cf0d69 100644 --- a/netbox_topology_views/static/netbox_topology_views/css/app.css +++ b/netbox_topology_views/static/netbox_topology_views/css/app.css @@ -1 +1 @@ -#visgraph{height:70vh}html[data-netbox-color-mode=dark] #visgraph{background-color:#212529} +#visgraph{height:70vh}html[data-netbox-color-mode=dark] #visgraph{background-color:#212529}.image-dropdown img{width:64px;height:64px}.image-dropdown-content{display:flex;flex-wrap:wrap;gap:.5rem;padding-inline:.5rem;width:50vw;max-width:32rem}.image-dropdown-content>img{cursor:pointer} diff --git a/netbox_topology_views/static/netbox_topology_views/js/app.js b/netbox_topology_views/static/netbox_topology_views/js/app.js index ad67bbc..1e242a6 100644 --- a/netbox_topology_views/static/netbox_topology_views/js/app.js +++ b/netbox_topology_views/static/netbox_topology_views/js/app.js @@ -1,8 +1,8 @@ -(()=>{var jn=Object.create;var kt=Object.defineProperty,Wn=Object.defineProperties,Vn=Object.getOwnPropertyDescriptor,qn=Object.getOwnPropertyDescriptors,Un=Object.getOwnPropertyNames,Xi=Object.getOwnPropertySymbols,Yn=Object.getPrototypeOf,Gi=Object.prototype.hasOwnProperty,Xn=Object.prototype.propertyIsEnumerable;var ei=(n,e,t)=>e in n?kt(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,ye=(n,e)=>{for(var t in e||(e={}))Gi.call(e,t)&&ei(n,t,e[t]);if(Xi)for(var t of Xi(e))Xn.call(e,t)&&ei(n,t,e[t]);return n},St=(n,e)=>Wn(n,qn(e)),Gn=n=>kt(n,"__esModule",{value:!0});var ti=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var Kn=(n,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Un(e))!Gi.call(n,i)&&i!=="default"&&kt(n,i,{get:()=>e[i],enumerable:!(t=Vn(e,i))||t.enumerable});return n},ii=n=>Kn(Gn(kt(n!=null?jn(Yn(n)):{},"default",n&&n.__esModule&&"default"in n?{get:()=>n.default,enumerable:!0}:{value:n,enumerable:!0})),n);var $=(n,e,t)=>(ei(n,typeof e!="symbol"?e+"":e,t),t);var oi=ti((Ka,si)=>{typeof si!="undefined"&&(si.exports=ne);function ne(n){if(n)return Zn(n)}function Zn(n){for(var e in ne.prototype)n[e]=ne.prototype[e];return n}ne.prototype.on=ne.prototype.addEventListener=function(n,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+n]=this._callbacks["$"+n]||[]).push(e),this};ne.prototype.once=function(n,e){function t(){this.off(n,t),e.apply(this,arguments)}return t.fn=e,this.on(n,t),this};ne.prototype.off=ne.prototype.removeListener=ne.prototype.removeAllListeners=ne.prototype.removeEventListener=function(n,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+n];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+n],this;for(var i,s=0;s{(function(n,e){if(typeof define=="function"&&define.amd)define("timsort",["exports"],e);else if(typeof Yt!="undefined")e(Yt);else{var t={exports:{}};e(t.exports),n.timsort=t.exports}})(Yt,function(n){"use strict";n.__esModule=!0,n.sort=C;function e(f,g){if(!(f instanceof g))throw new TypeError("Cannot call a class as a function")}var t=32,i=7,s=256,o=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9];function r(f){return f<1e5?f<100?f<10?0:1:f<1e4?f<1e3?2:3:4:f<1e7?f<1e6?5:6:f<1e9?f<1e8?7:8:9}function a(f,g){if(f===g)return 0;if(~~f===f&&~~g===g){if(f===0||g===0)return f=0)return-1;if(f>=0)return 1;f=-f,g=-g}var m=r(f),v=r(g),_=0;return mv&&(g*=o[m-v-1],f/=10,_=1),f===g?_:f=t;)g|=f&1,f>>=1;return f+g}function h(f,g,m,v){var _=g+1;if(_===m)return 1;if(v(f[_++],f[g])<0){for(;_=0;)_++;return _-g}function l(f,g,m){for(m--;g>>1;_(E,f[w])<0?x=w:T=w+1}var k=v-T;switch(k){case 3:f[T+3]=f[T+2];case 2:f[T+2]=f[T+1];case 1:f[T+1]=f[T];break;default:for(;k>0;)f[T+k]=f[T+k-1],k--}f[T]=E}}function u(f,g,m,v,_,E){var T=0,x=0,w=1;if(E(f,g[m+_])>0){for(x=v-_;w0;)T=w,w=(w<<1)+1,w<=0&&(w=x);w>x&&(w=x),T+=_,w+=_}else{for(x=_+1;wx&&(w=x);var k=T;T=_-w,w=_-k}for(T++;T>>1);E(f,g[m+N])>0?T=N+1:w=N}return w}function p(f,g,m,v,_,E){var T=0,x=0,w=1;if(E(f,g[m+_])<0){for(x=_+1;wx&&(w=x);var k=T;T=_-w,w=_-k}else{for(x=v-_;w=0;)T=w,w=(w<<1)+1,w<=0&&(w=x);w>x&&(w=x),T+=_,w+=_}for(T++;T>>1);E(f,g[m+N])<0?w=N:T=N+1}return w}var b=function(){function f(g,m){e(this,f),this.array=null,this.compare=null,this.minGallop=i,this.length=0,this.tmpStorageLength=s,this.stackLength=0,this.runStart=null,this.runLength=null,this.stackSize=0,this.array=g,this.compare=m,this.length=g.length,this.length<2*s&&(this.tmpStorageLength=this.length>>>1),this.tmp=new Array(this.tmpStorageLength),this.stackLength=this.length<120?5:this.length<1542?10:this.length<119151?19:40,this.runStart=new Array(this.stackLength),this.runLength=new Array(this.stackLength)}return f.prototype.pushRun=function(m,v){this.runStart[this.stackSize]=m,this.runLength[this.stackSize]=v,this.stackSize+=1},f.prototype.mergeRuns=function(){for(;this.stackSize>1;){var m=this.stackSize-2;if(m>=1&&this.runLength[m-1]<=this.runLength[m]+this.runLength[m+1]||m>=2&&this.runLength[m-2]<=this.runLength[m]+this.runLength[m-1])this.runLength[m-1]this.runLength[m+1])break;this.mergeAt(m)}},f.prototype.forceMergeRuns=function(){for(;this.stackSize>1;){var m=this.stackSize-2;m>0&&this.runLength[m-1]=i||F>=i);if(D)break;R<0&&(R=0),R+=2}if(this.minGallop=R,R<1&&(this.minGallop=1),v===1){for(k=0;k=0;k--)x[B+k]=x[R+k];x[L]=w[W];return}for(var F=this.minGallop;;){var D=0,H=0,Y=!1;do if(T(w[W],x[N])<0){if(x[L--]=x[N--],D++,H=0,--v==0){Y=!0;break}}else if(x[L--]=w[W--],H++,D=0,--E==1){Y=!0;break}while((D|H)=0;k--)x[B+k]=x[R+k];if(v===0){Y=!0;break}}if(x[L--]=w[W--],--E==1){Y=!0;break}if(H=E-u(x[N],w,0,E,E-1,T),H!==0){for(L-=H,W-=H,E-=H,B=L+1,R=W+1,k=0;k=i||H>=i);if(Y)break;F<0&&(F=0),F+=2}if(this.minGallop=F,F<1&&(this.minGallop=1),E===1){for(L-=v,N-=v,B=L+1,R=N+1,k=v-1;k>=0;k--)x[B+k]=x[R+k];x[L]=w[W]}else{if(E===0)throw new Error("mergeHigh preconditions were not respected");for(R=L-(E-1),k=0;kx&&(w=x),c(f,m,m+w,m+E,g),E=w}T.pushRun(m,E),T.mergeRuns(),_-=E,m+=E}while(_!==0);T.forceMergeRuns()}}})});var no=ti((_d,oo)=>{oo.exports=so()});var Ms=ii(oi());function ue(){return ue=Object.assign||function(n){for(var e=1;e-1}function rr(n){if(He(n,ze))return ze;var e=He(n,st),t=He(n,ot);return e&&t?ze:e||t?e?st:ot:He(n,ai)?ai:Ji}var ss=function(){function n(t,i){this.manager=t,this.set(i)}var e=n.prototype;return e.set=function(i){i===$i&&(i=this.compute()),Qi&&this.manager.element.style&&Pt[i]&&(this.manager.element.style[Zi]=i),this.actions=i.toLowerCase().trim()},e.update=function(){this.set(this.manager.options.touchAction)},e.compute=function(){var i=[];return ve(this.manager.recognizers,function(s){Ft(s.options.enable,[s])&&(i=i.concat(s.getTouchAction()))}),rr(i.join(" "))},e.preventDefaults=function(i){var s=i.srcEvent,o=i.offsetDirection;if(this.manager.session.prevented){s.preventDefault();return}var r=this.actions,a=He(r,ze)&&!Pt[ze],d=He(r,ot)&&!Pt[ot],h=He(r,st)&&!Pt[st];if(a){var l=i.pointers.length===1,c=i.distance<2,u=i.deltaTime<250;if(l&&c&&u)return}if(!(h&&d)&&(a||d&&o&pe||h&&o&Re))return this.preventSrc(s)},e.preventSrc=function(i){this.manager.session.prevented=!0,i.preventDefault()},n}();function hi(n,e){for(;n;){if(n===e)return!0;n=n.parentNode}return!1}function os(n){var e=n.length;if(e===1)return{x:Ge(n[0].clientX),y:Ge(n[0].clientY)};for(var t=0,i=0,s=0;s=Ae(e)?n<0?rt:at:e<0?dt:Ke}function ar(n,e){var t=e.center,i=n.offsetDelta||{},s=n.prevDelta||{},o=n.prevInput||{};(e.eventType===ee||o.eventType===K)&&(s=n.prevDelta={x:o.deltaX||0,y:o.deltaY||0},i=n.offsetDelta={x:t.x,y:t.y}),e.deltaX=s.x+(t.x-i.x),e.deltaY=s.y+(t.y-i.y)}function as(n,e,t){return{x:e/n||0,y:t/n||0}}function dr(n,e){return Nt(e[0],e[1],Dt)/Nt(n[0],n[1],Dt)}function hr(n,e){return li(e[1],e[0],Dt)+li(n[1],n[0],Dt)}function lr(n,e){var t=n.lastInterval||e,i=e.timeStamp-t.timeStamp,s,o,r,a;if(e.eventType!==se&&(i>nr||t.velocity===void 0)){var d=e.deltaX-t.deltaX,h=e.deltaY-t.deltaY,l=as(i,d,h);o=l.x,r=l.y,s=Ae(l.x)>Ae(l.y)?l.x:l.y,a=rs(d,h),n.lastInterval=e}else s=t.velocity,o=t.velocityX,r=t.velocityY,a=t.direction;e.velocity=s,e.velocityX=o,e.velocityY=r,e.direction=a}function cr(n,e){var t=n.session,i=e.pointers,s=i.length;t.firstInput||(t.firstInput=ns(e)),s>1&&!t.firstMultiple?t.firstMultiple=ns(e):s===1&&(t.firstMultiple=!1);var o=t.firstInput,r=t.firstMultiple,a=r?r.center:o.center,d=e.center=os(i);e.timeStamp=ri(),e.deltaTime=e.timeStamp-o.timeStamp,e.angle=li(a,d),e.distance=Nt(a,d),ar(t,e),e.offsetDirection=rs(e.deltaX,e.deltaY);var h=as(e.deltaTime,e.deltaX,e.deltaY);e.overallVelocityX=h.x,e.overallVelocityY=h.y,e.overallVelocity=Ae(h.x)>Ae(h.y)?h.x:h.y,e.scale=r?dr(r.pointers,i):1,e.rotation=r?hr(r.pointers,i):0,e.maxPointers=t.prevInput?e.pointers.length>t.prevInput.maxPointers?e.pointers.length:t.prevInput.maxPointers:e.pointers.length,lr(t,e);var l=n.element,c=e.srcEvent,u;c.composedPath?u=c.composedPath()[0]:c.path?u=c.path[0]:u=c.target,hi(u,l)&&(l=u),e.target=l}function ur(n,e,t){var i=t.pointers.length,s=t.changedPointers.length,o=e&ee&&i-s==0,r=e&(K|se)&&i-s==0;t.isFirst=!!o,t.isFinal=!!r,o&&(n.session={}),t.eventType=e,cr(n,t),n.emit("hammer.input",t),n.recognize(t),n.session.prevInput=t}function ht(n){return n.trim().split(/\s+/g)}function lt(n,e,t){ve(ht(e),function(i){n.addEventListener(i,t,!1)})}function ct(n,e,t){ve(ht(e),function(i){n.removeEventListener(i,t,!1)})}function ds(n){var e=n.ownerDocument||n;return e.defaultView||e.parentWindow||window}var Ze=function(){function n(t,i){var s=this;this.manager=t,this.callback=i,this.element=t.element,this.target=t.options.inputTarget,this.domHandler=function(o){Ft(t.options.enable,[t])&&s.handler(o)},this.init()}var e=n.prototype;return e.handler=function(){},e.init=function(){this.evEl&<(this.element,this.evEl,this.domHandler),this.evTarget&<(this.target,this.evTarget,this.domHandler),this.evWin&<(ds(this.element),this.evWin,this.domHandler)},e.destroy=function(){this.evEl&&ct(this.element,this.evEl,this.domHandler),this.evTarget&&ct(this.target,this.evTarget,this.domHandler),this.evWin&&ct(ds(this.element),this.evWin,this.domHandler)},n}();function je(n,e,t){if(n.indexOf&&!t)return n.indexOf(e);for(var i=0;id[e]}):i=i.sort()),i}var gr={touchstart:ee,touchmove:Le,touchend:K,touchcancel:se},mr="touchstart touchmove touchend touchcancel",ui=function(n){de(e,n);function e(){var i;return e.prototype.evTarget=mr,i=n.apply(this,arguments)||this,i.targetIds={},i}var t=e.prototype;return t.handler=function(s){var o=gr[s.type],r=yr.call(this,s,o);!r||this.callback(this.manager,o,{pointers:r[0],changedPointers:r[1],pointerType:nt,srcEvent:s})},e}(Ze);function yr(n,e){var t=ut(n.touches),i=this.targetIds;if(e&(ee|Le)&&t.length===1)return i[t[0].identifier]=!0,[t,t];var s,o,r=ut(n.changedTouches),a=[],d=this.target;if(o=t.filter(function(h){return hi(h.target,d)}),e===ee)for(s=0;s-1&&s.splice(a,1)};setTimeout(o,_r)}}function Er(n,e){n&ee?(this.primaryTouch=e.changedPointers[0].identifier,fs.call(this,e)):n&(K|se)&&fs.call(this,e)}function xr(n){for(var e=n.srcEvent.clientX,t=n.srcEvent.clientY,i=0;i-1&&this.requireFail.splice(s,1),this},e.hasRequireFailures=function(){return this.requireFail.length>0},e.canRecognizeWith=function(i){return!!this.simultaneous[i.id]},e.emit=function(i){var s=this,o=this.state;function r(a){s.manager.emit(a,i)}o=Oe&&r(s.options.event+gs(o))},e.tryEmit=function(i){if(this.canEmit())return this.emit(i);this.state=ge},e.canEmit=function(){for(var i=0;io.threshold&&d&o.direction},t.attrTest=function(s){return Je.prototype.attrTest.call(this,s)&&(this.state&he||!(this.state&he)&&this.directionTest(s))},t.emit=function(s){this.pX=s.deltaX,this.pY=s.deltaY;var o=ms(s.direction);o&&(s.additionalEvent=this.options.event+o),n.prototype.emit.call(this,s)},e}(Je),ys=function(n){de(e,n);function e(i){return i===void 0&&(i={}),n.call(this,ue({event:"swipe",threshold:10,velocity:.3,direction:pe|Re,pointers:1},i))||this}var t=e.prototype;return t.getTouchAction=function(){return gi.prototype.getTouchAction.call(this)},t.attrTest=function(s){var o=this.options.direction,r;return o&(pe|Re)?r=s.overallVelocity:o&pe?r=s.overallVelocityX:o&Re&&(r=s.overallVelocityY),n.prototype.attrTest.call(this,s)&&o&s.offsetDirection&&s.distance>this.options.threshold&&s.maxPointers===this.options.pointers&&Ae(r)>this.options.velocity&&s.eventType&K},t.emit=function(s){var o=ms(s.offsetDirection);o&&this.manager.emit(this.options.event+o,s),this.manager.emit(this.options.event,s)},e}(Je),bs=function(n){de(e,n);function e(i){return i===void 0&&(i={}),n.call(this,ue({event:"pinch",threshold:0,pointers:2},i))||this}var t=e.prototype;return t.getTouchAction=function(){return[ze]},t.attrTest=function(s){return n.prototype.attrTest.call(this,s)&&(Math.abs(s.scale-1)>this.options.threshold||this.state&he)},t.emit=function(s){if(s.scale!==1){var o=s.scale<1?"in":"out";s.additionalEvent=this.options.event+o}n.prototype.emit.call(this,s)},e}(Je),vs=function(n){de(e,n);function e(i){return i===void 0&&(i={}),n.call(this,ue({event:"rotate",threshold:0,pointers:2},i))||this}var t=e.prototype;return t.getTouchAction=function(){return[ze]},t.attrTest=function(s){return n.prototype.attrTest.call(this,s)&&(Math.abs(s.rotation)>this.options.threshold||this.state&he)},e}(Je),ws=function(n){de(e,n);function e(i){var s;return i===void 0&&(i={}),s=n.call(this,ue({event:"press",pointers:1,time:251,threshold:9},i))||this,s._timer=null,s._input=null,s}var t=e.prototype;return t.getTouchAction=function(){return[Ji]},t.process=function(s){var o=this,r=this.options,a=s.pointers.length===r.pointers,d=s.distancer.time;if(this._input=s,!d||!a||s.eventType&(K|se)&&!h)this.reset();else if(s.eventType&ee)this.reset(),this._timer=setTimeout(function(){o.state=we,o.tryEmit()},r.time);else if(s.eventType&K)return we;return ge},t.reset=function(){clearTimeout(this._timer)},t.emit=function(s){this.state===we&&(s&&s.eventType&K?this.manager.emit(this.options.event+"up",s):(this._input.timeStamp=ri(),this.manager.emit(this.options.event,this._input)))},e}(pt),_s={domEvents:!1,touchAction:$i,enable:!0,inputTarget:null,inputClass:null,cssProps:{userSelect:"none",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},Es=[[vs,{enable:!1}],[bs,{enable:!1},["rotate"]],[ys,{direction:pe}],[gi,{direction:pe},["swipe"]],[pi],[pi,{event:"doubletap",taps:2},["tap"]],[ws]],Sr=1,xs=2;function Cs(n,e){var t=n.element;if(!!t.style){var i;ve(n.options.cssProps,function(s,o){i=It(t.style,o),e?(n.oldCssProps[i]=t.style[i],t.style[i]=s):t.style[i]=n.oldCssProps[i]||""}),e||(n.oldCssProps={})}}function Or(n,e){var t=document.createEvent("Event");t.initEvent(n,!0,!0),t.gesture=e,e.target.dispatchEvent(t)}var Ts=function(){function n(t,i){var s=this;this.options=Be({},_s,i||{}),this.options.inputTarget=this.options.inputTarget||t,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=t,this.input=Cr(this),this.touchAction=new ss(this,this.options.touchAction),Cs(this,!0),ve(this.options.recognizers,function(o){var r=s.add(new o[0](o[1]));o[2]&&r.recognizeWith(o[2]),o[3]&&r.requireFailure(o[3])},this)}var e=n.prototype;return e.set=function(i){return Be(this.options,i),i.touchAction&&this.touchAction.update(),i.inputTarget&&(this.input.destroy(),this.input.target=i.inputTarget,this.input.init()),this},e.stop=function(i){this.session.stopped=i?xs:Sr},e.recognize=function(i){var s=this.session;if(!s.stopped){this.touchAction.preventDefaults(i);var o,r=this.recognizers,a=s.curRecognizer;(!a||a&&a.state&we)&&(s.curRecognizer=null,a=null);for(var d=0;d{var Nn=Object.create;var kt=Object.defineProperty,Bn=Object.defineProperties,An=Object.getOwnPropertyDescriptor,zn=Object.getOwnPropertyDescriptors,Ln=Object.getOwnPropertyNames,Ui=Object.getOwnPropertySymbols,Rn=Object.getPrototypeOf,Yi=Object.prototype.hasOwnProperty,Hn=Object.prototype.propertyIsEnumerable;var Jt=(n,e,t)=>e in n?kt(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,de=(n,e)=>{for(var t in e||(e={}))Yi.call(e,t)&&Jt(n,t,e[t]);if(Ui)for(var t of Ui(e))Hn.call(e,t)&&Jt(n,t,e[t]);return n},Be=(n,e)=>Bn(n,zn(e)),jn=n=>kt(n,"__esModule",{value:!0});var ei=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var Wn=(n,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ln(e))!Yi.call(n,i)&&i!=="default"&&kt(n,i,{get:()=>e[i],enumerable:!(t=An(e,i))||t.enumerable});return n},ti=n=>Wn(jn(kt(n!=null?Nn(Rn(n)):{},"default",n&&n.__esModule&&"default"in n?{get:()=>n.default,enumerable:!0}:{value:n,enumerable:!0})),n);var $=(n,e,t)=>(Jt(n,typeof e!="symbol"?e+"":e,t),t);var Xi=(n,e,t)=>new Promise((i,s)=>{var o=d=>{try{a(t.next(d))}catch(h){s(h)}},r=d=>{try{a(t.throw(d))}catch(h){s(h)}},a=d=>d.done?i(d.value):Promise.resolve(d.value).then(o,r);a((t=t.apply(n,e)).next())});var si=ei((ja,ii)=>{typeof ii!="undefined"&&(ii.exports=ne);function ne(n){if(n)return Vn(n)}function Vn(n){for(var e in ne.prototype)n[e]=ne.prototype[e];return n}ne.prototype.on=ne.prototype.addEventListener=function(n,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+n]=this._callbacks["$"+n]||[]).push(e),this};ne.prototype.once=function(n,e){function t(){this.off(n,t),e.apply(this,arguments)}return t.fn=e,this.on(n,t),this};ne.prototype.off=ne.prototype.removeListener=ne.prototype.removeAllListeners=ne.prototype.removeEventListener=function(n,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+n];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+n],this;for(var i,s=0;s{(function(n,e){if(typeof define=="function"&&define.amd)define("timsort",["exports"],e);else if(typeof Ut!="undefined")e(Ut);else{var t={exports:{}};e(t.exports),n.timsort=t.exports}})(Ut,function(n){"use strict";n.__esModule=!0,n.sort=C;function e(f,g){if(!(f instanceof g))throw new TypeError("Cannot call a class as a function")}var t=32,i=7,s=256,o=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9];function r(f){return f<1e5?f<100?f<10?0:1:f<1e4?f<1e3?2:3:4:f<1e7?f<1e6?5:6:f<1e9?f<1e8?7:8:9}function a(f,g){if(f===g)return 0;if(~~f===f&&~~g===g){if(f===0||g===0)return f=0)return-1;if(f>=0)return 1;f=-f,g=-g}var m=r(f),v=r(g),_=0;return mv&&(g*=o[m-v-1],f/=10,_=1),f===g?_:f=t;)g|=f&1,f>>=1;return f+g}function h(f,g,m,v){var _=g+1;if(_===m)return 1;if(v(f[_++],f[g])<0){for(;_=0;)_++;return _-g}function l(f,g,m){for(m--;g>>1;_(E,f[w])<0?x=w:T=w+1}var k=v-T;switch(k){case 3:f[T+3]=f[T+2];case 2:f[T+2]=f[T+1];case 1:f[T+1]=f[T];break;default:for(;k>0;)f[T+k]=f[T+k-1],k--}f[T]=E}}function u(f,g,m,v,_,E){var T=0,x=0,w=1;if(E(f,g[m+_])>0){for(x=v-_;w0;)T=w,w=(w<<1)+1,w<=0&&(w=x);w>x&&(w=x),T+=_,w+=_}else{for(x=_+1;wx&&(w=x);var k=T;T=_-w,w=_-k}for(T++;T>>1);E(f,g[m+N])>0?T=N+1:w=N}return w}function p(f,g,m,v,_,E){var T=0,x=0,w=1;if(E(f,g[m+_])<0){for(x=_+1;wx&&(w=x);var k=T;T=_-w,w=_-k}else{for(x=v-_;w=0;)T=w,w=(w<<1)+1,w<=0&&(w=x);w>x&&(w=x),T+=_,w+=_}for(T++;T>>1);E(f,g[m+N])<0?w=N:T=N+1}return w}var b=function(){function f(g,m){e(this,f),this.array=null,this.compare=null,this.minGallop=i,this.length=0,this.tmpStorageLength=s,this.stackLength=0,this.runStart=null,this.runLength=null,this.stackSize=0,this.array=g,this.compare=m,this.length=g.length,this.length<2*s&&(this.tmpStorageLength=this.length>>>1),this.tmp=new Array(this.tmpStorageLength),this.stackLength=this.length<120?5:this.length<1542?10:this.length<119151?19:40,this.runStart=new Array(this.stackLength),this.runLength=new Array(this.stackLength)}return f.prototype.pushRun=function(m,v){this.runStart[this.stackSize]=m,this.runLength[this.stackSize]=v,this.stackSize+=1},f.prototype.mergeRuns=function(){for(;this.stackSize>1;){var m=this.stackSize-2;if(m>=1&&this.runLength[m-1]<=this.runLength[m]+this.runLength[m+1]||m>=2&&this.runLength[m-2]<=this.runLength[m]+this.runLength[m-1])this.runLength[m-1]this.runLength[m+1])break;this.mergeAt(m)}},f.prototype.forceMergeRuns=function(){for(;this.stackSize>1;){var m=this.stackSize-2;m>0&&this.runLength[m-1]=i||F>=i);if(D)break;R<0&&(R=0),R+=2}if(this.minGallop=R,R<1&&(this.minGallop=1),v===1){for(k=0;k=0;k--)x[B+k]=x[R+k];x[L]=w[W];return}for(var F=this.minGallop;;){var D=0,H=0,Y=!1;do if(T(w[W],x[N])<0){if(x[L--]=x[N--],D++,H=0,--v==0){Y=!0;break}}else if(x[L--]=w[W--],H++,D=0,--E==1){Y=!0;break}while((D|H)=0;k--)x[B+k]=x[R+k];if(v===0){Y=!0;break}}if(x[L--]=w[W--],--E==1){Y=!0;break}if(H=E-u(x[N],w,0,E,E-1,T),H!==0){for(L-=H,W-=H,E-=H,B=L+1,R=W+1,k=0;k=i||H>=i);if(Y)break;F<0&&(F=0),F+=2}if(this.minGallop=F,F<1&&(this.minGallop=1),E===1){for(L-=v,N-=v,B=L+1,R=N+1,k=v-1;k>=0;k--)x[B+k]=x[R+k];x[L]=w[W]}else{if(E===0)throw new Error("mergeHigh preconditions were not respected");for(R=L-(E-1),k=0;kx&&(w=x),c(f,m,m+w,m+E,g),E=w}T.pushRun(m,E),T.mergeRuns(),_-=E,m+=E}while(_!==0);T.forceMergeRuns()}}})});var oo=ei((fd,so)=>{so.exports=io()});var Ps=ti(si());function fe(){return fe=Object.assign||function(n){for(var e=1;e-1}function Jn(n){if(je(n,Le))return Le;var e=je(n,nt),t=je(n,rt);return e&&t?Le:e||t?e?nt:rt:je(n,ri)?ri:$i}var is=function(){function n(t,i){this.manager=t,this.set(i)}var e=n.prototype;return e.set=function(i){i===Qi&&(i=this.compute()),Zi&&this.manager.element.style&&It[i]&&(this.manager.element.style[Ki]=i),this.actions=i.toLowerCase().trim()},e.update=function(){this.set(this.manager.options.touchAction)},e.compute=function(){var i=[];return be(this.manager.recognizers,function(s){Dt(s.options.enable,[s])&&(i=i.concat(s.getTouchAction()))}),Jn(i.join(" "))},e.preventDefaults=function(i){var s=i.srcEvent,o=i.offsetDirection;if(this.manager.session.prevented){s.preventDefault();return}var r=this.actions,a=je(r,Le)&&!It[Le],d=je(r,rt)&&!It[rt],h=je(r,nt)&&!It[nt];if(a){var l=i.pointers.length===1,c=i.distance<2,u=i.deltaTime<250;if(l&&c&&u)return}if(!(h&&d)&&(a||d&&o&pe||h&&o&He))return this.preventSrc(s)},e.preventSrc=function(i){this.manager.session.prevented=!0,i.preventDefault()},n}();function di(n,e){for(;n;){if(n===e)return!0;n=n.parentNode}return!1}function ss(n){var e=n.length;if(e===1)return{x:Ze(n[0].clientX),y:Ze(n[0].clientY)};for(var t=0,i=0,s=0;s=ze(e)?n<0?dt:ht:e<0?lt:Qe}function er(n,e){var t=e.center,i=n.offsetDelta||{},s=n.prevDelta||{},o=n.prevInput||{};(e.eventType===ee||o.eventType===K)&&(s=n.prevDelta={x:o.deltaX||0,y:o.deltaY||0},i=n.offsetDelta={x:t.x,y:t.y}),e.deltaX=s.x+(t.x-i.x),e.deltaY=s.y+(t.y-i.y)}function rs(n,e,t){return{x:e/n||0,y:t/n||0}}function tr(n,e){return Ft(e[0],e[1],Mt)/Ft(n[0],n[1],Mt)}function ir(n,e){return hi(e[1],e[0],Mt)+hi(n[1],n[0],Mt)}function sr(n,e){var t=n.lastInterval||e,i=e.timeStamp-t.timeStamp,s,o,r,a;if(e.eventType!==se&&(i>$n||t.velocity===void 0)){var d=e.deltaX-t.deltaX,h=e.deltaY-t.deltaY,l=rs(i,d,h);o=l.x,r=l.y,s=ze(l.x)>ze(l.y)?l.x:l.y,a=ns(d,h),n.lastInterval=e}else s=t.velocity,o=t.velocityX,r=t.velocityY,a=t.direction;e.velocity=s,e.velocityX=o,e.velocityY=r,e.direction=a}function or(n,e){var t=n.session,i=e.pointers,s=i.length;t.firstInput||(t.firstInput=os(e)),s>1&&!t.firstMultiple?t.firstMultiple=os(e):s===1&&(t.firstMultiple=!1);var o=t.firstInput,r=t.firstMultiple,a=r?r.center:o.center,d=e.center=ss(i);e.timeStamp=ni(),e.deltaTime=e.timeStamp-o.timeStamp,e.angle=hi(a,d),e.distance=Ft(a,d),er(t,e),e.offsetDirection=ns(e.deltaX,e.deltaY);var h=rs(e.deltaTime,e.deltaX,e.deltaY);e.overallVelocityX=h.x,e.overallVelocityY=h.y,e.overallVelocity=ze(h.x)>ze(h.y)?h.x:h.y,e.scale=r?tr(r.pointers,i):1,e.rotation=r?ir(r.pointers,i):0,e.maxPointers=t.prevInput?e.pointers.length>t.prevInput.maxPointers?e.pointers.length:t.prevInput.maxPointers:e.pointers.length,sr(t,e);var l=n.element,c=e.srcEvent,u;c.composedPath?u=c.composedPath()[0]:c.path?u=c.path[0]:u=c.target,di(u,l)&&(l=u),e.target=l}function nr(n,e,t){var i=t.pointers.length,s=t.changedPointers.length,o=e&ee&&i-s==0,r=e&(K|se)&&i-s==0;t.isFirst=!!o,t.isFinal=!!r,o&&(n.session={}),t.eventType=e,or(n,t),n.emit("hammer.input",t),n.recognize(t),n.session.prevInput=t}function ct(n){return n.trim().split(/\s+/g)}function ut(n,e,t){be(ct(e),function(i){n.addEventListener(i,t,!1)})}function ft(n,e,t){be(ct(e),function(i){n.removeEventListener(i,t,!1)})}function as(n){var e=n.ownerDocument||n;return e.defaultView||e.parentWindow||window}var $e=function(){function n(t,i){var s=this;this.manager=t,this.callback=i,this.element=t.element,this.target=t.options.inputTarget,this.domHandler=function(o){Dt(t.options.enable,[t])&&s.handler(o)},this.init()}var e=n.prototype;return e.handler=function(){},e.init=function(){this.evEl&&ut(this.element,this.evEl,this.domHandler),this.evTarget&&ut(this.target,this.evTarget,this.domHandler),this.evWin&&ut(as(this.element),this.evWin,this.domHandler)},e.destroy=function(){this.evEl&&ft(this.element,this.evEl,this.domHandler),this.evTarget&&ft(this.target,this.evTarget,this.domHandler),this.evWin&&ft(as(this.element),this.evWin,this.domHandler)},n}();function We(n,e,t){if(n.indexOf&&!t)return n.indexOf(e);for(var i=0;id[e]}):i=i.sort()),i}var dr={touchstart:ee,touchmove:Re,touchend:K,touchcancel:se},hr="touchstart touchmove touchend touchcancel",ci=function(n){he(e,n);function e(){var i;return e.prototype.evTarget=hr,i=n.apply(this,arguments)||this,i.targetIds={},i}var t=e.prototype;return t.handler=function(s){var o=dr[s.type],r=lr.call(this,s,o);!r||this.callback(this.manager,o,{pointers:r[0],changedPointers:r[1],pointerType:at,srcEvent:s})},e}($e);function lr(n,e){var t=pt(n.touches),i=this.targetIds;if(e&(ee|Re)&&t.length===1)return i[t[0].identifier]=!0,[t,t];var s,o,r=pt(n.changedTouches),a=[],d=this.target;if(o=t.filter(function(h){return di(h.target,d)}),e===ee)for(s=0;s-1&&s.splice(a,1)};setTimeout(o,pr)}}function gr(n,e){n&ee?(this.primaryTouch=e.changedPointers[0].identifier,us.call(this,e)):n&(K|se)&&us.call(this,e)}function mr(n){for(var e=n.srcEvent.clientX,t=n.srcEvent.clientY,i=0;i-1&&this.requireFail.splice(s,1),this},e.hasRequireFailures=function(){return this.requireFail.length>0},e.canRecognizeWith=function(i){return!!this.simultaneous[i.id]},e.emit=function(i){var s=this,o=this.state;function r(a){s.manager.emit(a,i)}o=Oe&&r(s.options.event+ps(o))},e.tryEmit=function(i){if(this.canEmit())return this.emit(i);this.state=ge},e.canEmit=function(){for(var i=0;io.threshold&&d&o.direction},t.attrTest=function(s){return tt.prototype.attrTest.call(this,s)&&(this.state&le||!(this.state&le)&&this.directionTest(s))},t.emit=function(s){this.pX=s.deltaX,this.pY=s.deltaY;var o=gs(s.direction);o&&(s.additionalEvent=this.options.event+o),n.prototype.emit.call(this,s)},e}(tt),ms=function(n){he(e,n);function e(i){return i===void 0&&(i={}),n.call(this,fe({event:"swipe",threshold:10,velocity:.3,direction:pe|He,pointers:1},i))||this}var t=e.prototype;return t.getTouchAction=function(){return pi.prototype.getTouchAction.call(this)},t.attrTest=function(s){var o=this.options.direction,r;return o&(pe|He)?r=s.overallVelocity:o&pe?r=s.overallVelocityX:o&He&&(r=s.overallVelocityY),n.prototype.attrTest.call(this,s)&&o&s.offsetDirection&&s.distance>this.options.threshold&&s.maxPointers===this.options.pointers&&ze(r)>this.options.velocity&&s.eventType&K},t.emit=function(s){var o=gs(s.offsetDirection);o&&this.manager.emit(this.options.event+o,s),this.manager.emit(this.options.event,s)},e}(tt),ys=function(n){he(e,n);function e(i){return i===void 0&&(i={}),n.call(this,fe({event:"pinch",threshold:0,pointers:2},i))||this}var t=e.prototype;return t.getTouchAction=function(){return[Le]},t.attrTest=function(s){return n.prototype.attrTest.call(this,s)&&(Math.abs(s.scale-1)>this.options.threshold||this.state&le)},t.emit=function(s){if(s.scale!==1){var o=s.scale<1?"in":"out";s.additionalEvent=this.options.event+o}n.prototype.emit.call(this,s)},e}(tt),bs=function(n){he(e,n);function e(i){return i===void 0&&(i={}),n.call(this,fe({event:"rotate",threshold:0,pointers:2},i))||this}var t=e.prototype;return t.getTouchAction=function(){return[Le]},t.attrTest=function(s){return n.prototype.attrTest.call(this,s)&&(Math.abs(s.rotation)>this.options.threshold||this.state&le)},e}(tt),vs=function(n){he(e,n);function e(i){var s;return i===void 0&&(i={}),s=n.call(this,fe({event:"press",pointers:1,time:251,threshold:9},i))||this,s._timer=null,s._input=null,s}var t=e.prototype;return t.getTouchAction=function(){return[$i]},t.process=function(s){var o=this,r=this.options,a=s.pointers.length===r.pointers,d=s.distancer.time;if(this._input=s,!d||!a||s.eventType&(K|se)&&!h)this.reset();else if(s.eventType&ee)this.reset(),this._timer=setTimeout(function(){o.state=ve,o.tryEmit()},r.time);else if(s.eventType&K)return ve;return ge},t.reset=function(){clearTimeout(this._timer)},t.emit=function(s){this.state===ve&&(s&&s.eventType&K?this.manager.emit(this.options.event+"up",s):(this._input.timeStamp=ni(),this.manager.emit(this.options.event,this._input)))},e}(mt),ws={domEvents:!1,touchAction:Qi,enable:!0,inputTarget:null,inputClass:null,cssProps:{userSelect:"none",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},_s=[[bs,{enable:!1}],[ys,{enable:!1},["rotate"]],[ms,{direction:pe}],[pi,{direction:pe},["swipe"]],[fi],[fi,{event:"doubletap",taps:2},["tap"]],[vs]],wr=1,Es=2;function xs(n,e){var t=n.element;if(!!t.style){var i;be(n.options.cssProps,function(s,o){i=Ot(t.style,o),e?(n.oldCssProps[i]=t.style[i],t.style[i]=s):t.style[i]=n.oldCssProps[i]||""}),e||(n.oldCssProps={})}}function _r(n,e){var t=document.createEvent("Event");t.initEvent(n,!0,!0),t.gesture=e,e.target.dispatchEvent(t)}var Cs=function(){function n(t,i){var s=this;this.options=Ae({},ws,i||{}),this.options.inputTarget=this.options.inputTarget||t,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=t,this.input=yr(this),this.touchAction=new is(this,this.options.touchAction),xs(this,!0),be(this.options.recognizers,function(o){var r=s.add(new o[0](o[1]));o[2]&&r.recognizeWith(o[2]),o[3]&&r.requireFailure(o[3])},this)}var e=n.prototype;return e.set=function(i){return Ae(this.options,i),i.touchAction&&this.touchAction.update(),i.inputTarget&&(this.input.destroy(),this.input.target=i.inputTarget,this.input.init()),this},e.stop=function(i){this.session.stopped=i?Es:wr},e.recognize=function(i){var s=this.session;if(!s.stopped){this.touchAction.preventDefaults(i);var o,r=this.recognizers,a=s.curRecognizer;(!a||a&&a.state&ve)&&(s.curRecognizer=null,a=null);for(var d=0;d\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",r=window.console&&(window.console.warn||window.console.log);return r&&r.call(window.console,i,o),n.apply(this,arguments)}}var Ss=ks(function(n,e,t){for(var i=Object.keys(e),s=0;s2)return zt(Fs(n[0],n[1]),...n.slice(2));let e=n[0],t=n[1];for(let i of Reflect.ownKeys(t))Object.prototype.propertyIsEnumerable.call(t,i)&&(t[i]===mi?delete e[i]:e[i]!==null&&t[i]!==null&&typeof e[i]=="object"&&typeof t[i]=="object"&&!Array.isArray(e[i])&&!Array.isArray(t[i])?e[i]=zt(e[i],t[i]):e[i]=Ns(t[i]));return e}function Ns(n){return Array.isArray(n)?n.map(e=>Ns(e)):typeof n=="object"&&n!==null?zt({},n):n}function Bs(n){for(let e of Object.keys(n))n[e]===mi?delete n[e]:typeof n[e]=="object"&&n[e]!==null&&Bs(n[e])}function gt(...n){return Ar(n.length?n:[Date.now()])}function Ar(n){let[e,t,i]=zr(n),s=1,o=()=>{let r=2091639*e+s*23283064365386963e-26;return e=t,t=i,i=r-(s=r|0)};return o.uint32=()=>o()*4294967296,o.fract53=()=>o()+(o()*2097152|0)*11102230246251565e-32,o.algorithm="Alea",o.seed=n,o.version="0.9",o}function zr(...n){let e=Lr(),t=e(" "),i=e(" "),s=e(" ");for(let o=0;o>>0,s-=n,s*=n,n=s>>>0,s-=n,n+=s*4294967296}return(n>>>0)*23283064365386963e-26}}function Rr(){let n=()=>{};return{on:n,off:n,destroy:n,emit:n,get(){return{set:n}}}}var yi=typeof window!="undefined"?window.Hammer||Ps:function(){return Rr()};function me(n){this._cleanupQueue=[],this.active=!1,this._dom={container:n,overlay:document.createElement("div")},this._dom.overlay.classList.add("vis-overlay"),this._dom.container.appendChild(this._dom.overlay),this._cleanupQueue.push(()=>{this._dom.overlay.parentNode.removeChild(this._dom.overlay)});let e=yi(this._dom.overlay);e.on("tap",this._onTapOverlay.bind(this)),this._cleanupQueue.push(()=>{e.destroy()}),["tap","doubletap","press","pinch","pan","panstart","panmove","panend"].forEach(i=>{e.on(i,s=>{s.srcEvent.stopPropagation()})}),document&&document.body&&(this._onClick=i=>{Hr(i.target,n)||this.deactivate()},document.body.addEventListener("click",this._onClick),this._cleanupQueue.push(()=>{document.body.removeEventListener("click",this._onClick)})),this._escListener=i=>{("key"in i?i.key==="Escape":i.keyCode===27)&&this.deactivate()}}(0,Ms.default)(me.prototype);me.current=null;me.prototype.destroy=function(){this.deactivate();for(let n of this._cleanupQueue.splice(0).reverse())n()};me.prototype.activate=function(){me.current&&me.current.deactivate(),me.current=this,this.active=!0,this._dom.overlay.style.display="none",this._dom.container.classList.add("vis-active"),this.emit("change"),this.emit("activate"),document.body.addEventListener("keydown",this._escListener)};me.prototype.deactivate=function(){this.active=!1,this._dom.overlay.style.display="block",this._dom.container.classList.remove("vis-active"),document.body.removeEventListener("keydown",this._escListener),this.emit("change"),this.emit("deactivate")};me.prototype._onTapOverlay=function(n){this.activate(),n.srcEvent.stopPropagation()};function Hr(n,e){for(;n;){if(n===e)return!0;n=n.parentNode}return!1}var jr=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,Wr=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,Vr=/^rgb\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *\)$/i,qr=/^rgba\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *([01]|0?\.\d+) *\)$/i;function _e(n){if(n)for(;n.hasChildNodes()===!0;){let e=n.firstChild;e&&(_e(e),n.removeChild(e))}}function Ee(n){return n instanceof String||typeof n=="string"}function As(n){return typeof n=="object"&&n!==null}function We(n,e,t,i){let s=!1;i===!0&&(s=e[t]===null&&n[t]!==void 0),s?delete n[t]:n[t]=e[t]}function bi(n,e,t=!1){for(let i in n)if(e[i]!==void 0)if(e[i]===null||typeof e[i]!="object")We(n,e,i,t);else{let s=n[i],o=e[i];As(s)&&As(o)&&bi(s,o,t)}}function Ve(n,e,t,i=!1){if(Array.isArray(t))throw new TypeError("Arrays are not supported by deepExtend");for(let s=0;s{},this.closeCallback=()=>{},this._create()}insertTo(e){this.hammer!==void 0&&(this.hammer.destroy(),this.hammer=void 0),this.container=e,this.container.appendChild(this.frame),this._bindHammer(),this._setSize()}setUpdateCallback(e){if(typeof e=="function")this.updateCallback=e;else throw new Error("Function attempted to set as colorPicker update callback is not a function.")}setCloseCallback(e){if(typeof e=="function")this.closeCallback=e;else throw new Error("Function attempted to set as colorPicker closing callback is not a function.")}_isColorString(e){if(typeof e=="string")return Gr[e]}setColor(e,t=!0){if(e==="none")return;let i,s=this._isColorString(e);if(s!==void 0&&(e=s),Ee(e)===!0){if(Vs(e)===!0){let o=e.substr(4).substr(0,e.length-5).split(",");i={r:o[0],g:o[1],b:o[2],a:1}}else if(Xr(e)===!0){let o=e.substr(5).substr(0,e.length-6).split(",");i={r:o[0],g:o[1],b:o[2],a:o[3]}}else if(Ws(e)===!0){let o=vi(e);i={r:o.r,g:o.g,b:o.b,a:1}}}else if(e instanceof Object&&e.r!==void 0&&e.g!==void 0&&e.b!==void 0){let o=e.a!==void 0?e.a:"1.0";i={r:e.r,g:e.g,b:e.b,a:o}}if(i===void 0)throw new Error("Unknown color passed to the colorPicker. Supported are strings: rgb, hex, rgba. Object: rgb ({r:r,g:g,b:b,[a:a]}). Supplied: "+JSON.stringify(e));this._setColor(i,t)}show(){this.closeCallback!==void 0&&(this.closeCallback(),this.closeCallback=void 0),this.applied=!1,this.frame.style.display="block",this._generateHueCircle()}_hide(e=!0){e===!0&&(this.previousColor=Object.assign({},this.color)),this.applied===!0&&this.updateCallback(this.initialColor),this.frame.style.display="none",setTimeout(()=>{this.closeCallback!==void 0&&(this.closeCallback(),this.closeCallback=void 0)},0)}_save(){this.updateCallback(this.color),this.applied=!1,this._hide()}_apply(){this.applied=!0,this.updateCallback(this.color),this._updatePicker(this.color)}_loadLast(){this.previousColor!==void 0?this.setColor(this.previousColor,!1):alert("There is no last color to load...")}_setColor(e,t=!0){t===!0&&(this.initialColor=Object.assign({},e)),this.color=e;let i=yt(e.r,e.g,e.b),s=2*Math.PI,o=this.r*i.s,r=this.centerCoordinates.x+o*Math.sin(s*i.h),a=this.centerCoordinates.y+o*Math.cos(s*i.h);this.colorPickerSelector.style.left=r-.5*this.colorPickerSelector.clientWidth+"px",this.colorPickerSelector.style.top=a-.5*this.colorPickerSelector.clientHeight+"px",this._updatePicker(e)}_setOpacity(e){this.color.a=e/100,this._updatePicker(this.color)}_setBrightness(e){let t=yt(this.color.r,this.color.g,this.color.b);t.v=e/100;let i=Ht(t.h,t.s,t.v);i.a=this.color.a,this.color=i,this._updatePicker()}_updatePicker(e=this.color){let t=yt(e.r,e.g,e.b),i=this.colorPickerCanvas.getContext("2d");this.pixelRation===void 0&&(this.pixelRatio=(window.devicePixelRatio||1)/(i.webkitBackingStorePixelRatio||i.mozBackingStorePixelRatio||i.msBackingStorePixelRatio||i.oBackingStorePixelRatio||i.backingStorePixelRatio||1)),i.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0);let s=this.colorPickerCanvas.clientWidth,o=this.colorPickerCanvas.clientHeight;i.clearRect(0,0,s,o),i.putImageData(this.hueCircle,0,0),i.fillStyle="rgba(0,0,0,"+(1-t.v)+")",i.circle(this.centerCoordinates.x,this.centerCoordinates.y,this.r),i.fill(),this.brightnessRange.value=100*t.v,this.opacityRange.value=100*e.a,this.initialColorDiv.style.backgroundColor="rgba("+this.initialColor.r+","+this.initialColor.g+","+this.initialColor.b+","+this.initialColor.a+")",this.newColorDiv.style.backgroundColor="rgba("+this.color.r+","+this.color.g+","+this.color.b+","+this.color.a+")"}_setSize(){this.colorPickerCanvas.style.width="100%",this.colorPickerCanvas.style.height="100%",this.colorPickerCanvas.width=289*this.pixelRatio,this.colorPickerCanvas.height=289*this.pixelRatio}_create(){if(this.frame=document.createElement("div"),this.frame.className="vis-color-picker",this.colorPickerDiv=document.createElement("div"),this.colorPickerSelector=document.createElement("div"),this.colorPickerSelector.className="vis-selector",this.colorPickerDiv.appendChild(this.colorPickerSelector),this.colorPickerCanvas=document.createElement("canvas"),this.colorPickerDiv.appendChild(this.colorPickerCanvas),this.colorPickerCanvas.getContext){let t=this.colorPickerCanvas.getContext("2d");this.pixelRatio=(window.devicePixelRatio||1)/(t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1),this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0)}else{let t=document.createElement("DIV");t.style.color="red",t.style.fontWeight="bold",t.style.padding="10px",t.innerText="Error: your browser does not support HTML canvas",this.colorPickerCanvas.appendChild(t)}this.colorPickerDiv.className="vis-color",this.opacityDiv=document.createElement("div"),this.opacityDiv.className="vis-opacity",this.brightnessDiv=document.createElement("div"),this.brightnessDiv.className="vis-brightness",this.arrowDiv=document.createElement("div"),this.arrowDiv.className="vis-arrow",this.opacityRange=document.createElement("input");try{this.opacityRange.type="range",this.opacityRange.min="0",this.opacityRange.max="100"}catch(t){}this.opacityRange.value="100",this.opacityRange.className="vis-range",this.brightnessRange=document.createElement("input");try{this.brightnessRange.type="range",this.brightnessRange.min="0",this.brightnessRange.max="100"}catch(t){}this.brightnessRange.value="100",this.brightnessRange.className="vis-range",this.opacityDiv.appendChild(this.opacityRange),this.brightnessDiv.appendChild(this.brightnessRange);let e=this;this.opacityRange.onchange=function(){e._setOpacity(this.value)},this.opacityRange.oninput=function(){e._setOpacity(this.value)},this.brightnessRange.onchange=function(){e._setBrightness(this.value)},this.brightnessRange.oninput=function(){e._setBrightness(this.value)},this.brightnessLabel=document.createElement("div"),this.brightnessLabel.className="vis-label vis-brightness",this.brightnessLabel.innerText="brightness:",this.opacityLabel=document.createElement("div"),this.opacityLabel.className="vis-label vis-opacity",this.opacityLabel.innerText="opacity:",this.newColorDiv=document.createElement("div"),this.newColorDiv.className="vis-new-color",this.newColorDiv.innerText="new",this.initialColorDiv=document.createElement("div"),this.initialColorDiv.className="vis-initial-color",this.initialColorDiv.innerText="initial",this.cancelButton=document.createElement("div"),this.cancelButton.className="vis-button vis-cancel",this.cancelButton.innerText="cancel",this.cancelButton.onclick=this._hide.bind(this,!1),this.applyButton=document.createElement("div"),this.applyButton.className="vis-button vis-apply",this.applyButton.innerText="apply",this.applyButton.onclick=this._apply.bind(this),this.saveButton=document.createElement("div"),this.saveButton.className="vis-button vis-save",this.saveButton.innerText="save",this.saveButton.onclick=this._save.bind(this),this.loadButton=document.createElement("div"),this.loadButton.className="vis-button vis-load",this.loadButton.innerText="load last",this.loadButton.onclick=this._loadLast.bind(this),this.frame.appendChild(this.colorPickerDiv),this.frame.appendChild(this.arrowDiv),this.frame.appendChild(this.brightnessLabel),this.frame.appendChild(this.brightnessDiv),this.frame.appendChild(this.opacityLabel),this.frame.appendChild(this.opacityDiv),this.frame.appendChild(this.newColorDiv),this.frame.appendChild(this.initialColorDiv),this.frame.appendChild(this.cancelButton),this.frame.appendChild(this.applyButton),this.frame.appendChild(this.saveButton),this.frame.appendChild(this.loadButton)}_bindHammer(){this.drag={},this.pinch={},this.hammer=new yi(this.colorPickerCanvas),this.hammer.get("pinch").set({enable:!0}),this.hammer.on("hammer.input",e=>{e.isFirst&&this._moveSelector(e)}),this.hammer.on("tap",e=>{this._moveSelector(e)}),this.hammer.on("panstart",e=>{this._moveSelector(e)}),this.hammer.on("panmove",e=>{this._moveSelector(e)}),this.hammer.on("panend",e=>{this._moveSelector(e)})}_generateHueCircle(){if(this.generated===!1){let e=this.colorPickerCanvas.getContext("2d");this.pixelRation===void 0&&(this.pixelRatio=(window.devicePixelRatio||1)/(e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1)),e.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0);let t=this.colorPickerCanvas.clientWidth,i=this.colorPickerCanvas.clientHeight;e.clearRect(0,0,t,i);let s,o,r,a;this.centerCoordinates={x:t*.5,y:i*.5},this.r=.49*t;let d=2*Math.PI/360,h=1/360,l=1/this.r,c;for(r=0;r<360;r++)for(a=0;a!1){this.parent=e,this.changedOptions=[],this.container=t,this.allowCreation=!1,this.hideOption=o,this.options={},this.initialized=!1,this.popupCounter=0,this.defaultOptions={enabled:!1,filter:!0,container:void 0,showButton:!0},Object.assign(this.options,this.defaultOptions),this.configureOptions=i,this.moduleOptions={},this.domElements=[],this.popupDiv={},this.popupLimit=5,this.popupHistory={},this.colorPicker=new Us(s),this.wrapper=void 0}setOptions(e){if(e!==void 0){this.popupHistory={},this._removePopup();let t=!0;if(typeof e=="string")this.options.filter=e;else if(Array.isArray(e))this.options.filter=e.join();else if(typeof e=="object"){if(e==null)throw new TypeError("options cannot be null");e.container!==void 0&&(this.options.container=e.container),e.filter!==void 0&&(this.options.filter=e.filter),e.showButton!==void 0&&(this.options.showButton=e.showButton),e.enabled!==void 0&&(t=e.enabled)}else typeof e=="boolean"?(this.options.filter=!0,t=e):typeof e=="function"&&(this.options.filter=e,t=!0);this.options.filter===!1&&(t=!1),this.options.enabled=t}this._clean()}setModuleOptions(e){this.moduleOptions=e,this.options.enabled===!0&&(this._clean(),this.options.container!==void 0&&(this.container=this.options.container),this._create())}_create(){this._clean(),this.changedOptions=[];let e=this.options.filter,t=0,i=!1;for(let s in this.configureOptions)Object.prototype.hasOwnProperty.call(this.configureOptions,s)&&(this.allowCreation=!1,i=!1,typeof e=="function"?(i=e(s,[]),i=i||this._handleObject(this.configureOptions[s],[s],!0)):(e===!0||e.indexOf(s)!==-1)&&(i=!0),i!==!1&&(this.allowCreation=!0,t>0&&this._makeItem([]),this._makeHeader(s),this._handleObject(this.configureOptions[s],[s])),t++);this._makeButton(),this._push()}_push(){this.wrapper=document.createElement("div"),this.wrapper.className="vis-configuration-wrapper",this.container.appendChild(this.wrapper);for(let e=0;e{i.appendChild(s)}),this.domElements.push(i),this.domElements.length}return 0}_makeHeader(e){let t=document.createElement("div");t.className="vis-configuration vis-config-header",t.innerText=e,this._makeItem([],t)}_makeLabel(e,t,i=!1){let s=document.createElement("div");if(s.className="vis-configuration vis-config-label vis-config-s"+t.length,i===!0){for(;s.firstChild;)s.removeChild(s.firstChild);s.appendChild(wi("i","b",e))}else s.innerText=e+":";return s}_makeDropdown(e,t,i){let s=document.createElement("select");s.className="vis-configuration vis-config-select";let o=0;t!==void 0&&e.indexOf(t)!==-1&&(o=e.indexOf(t));for(let d=0;dr&&r!==1&&(d.max=Math.ceil(t*C),l=d.max,h="range increased"),d.value=t}else d.value=s;let c=document.createElement("input");c.className="vis-configuration vis-config-rangeinput",c.value=d.value;let u=this;d.onchange=function(){c.value=this.value,u._update(Number(this.value),i)},d.oninput=function(){c.value=this.value};let p=this._makeLabel(i[i.length-1],i),b=this._makeItem(i,p,d,c);h!==""&&this.popupHistory[b]!==l&&(this.popupHistory[b]=l,this._setupPopup(h,b))}_makeButton(){if(this.options.showButton===!0){let e=document.createElement("div");e.className="vis-configuration vis-config-button",e.innerText="generate options",e.onclick=()=>{this._printOptions()},e.onmouseover=()=>{e.className="vis-configuration vis-config-button hover"},e.onmouseout=()=>{e.className="vis-configuration vis-config-button"},this.optionsContainer=document.createElement("div"),this.optionsContainer.className="vis-configuration vis-config-option-container",this.domElements.push(this.optionsContainer),this.domElements.push(e)}}_setupPopup(e,t){if(this.initialized===!0&&this.allowCreation===!0&&this.popupCounter{this._removePopup()},this.popupCounter+=1,this.popupDiv={html:i,index:t}}}_removePopup(){this.popupDiv.html!==void 0&&(this.popupDiv.html.parentNode.removeChild(this.popupDiv.html),clearTimeout(this.popupDiv.hideTimeout),clearTimeout(this.popupDiv.deleteTimeout),this.popupDiv={})}_showPopupIfNeeded(){if(this.popupDiv.html!==void 0){let t=this.domElements[this.popupDiv.index].getBoundingClientRect();this.popupDiv.html.style.left=t.left+"px",this.popupDiv.html.style.top=t.top-30+"px",document.body.appendChild(this.popupDiv.html),this.popupDiv.hideTimeout=setTimeout(()=>{this.popupDiv.html.style.opacity=0},1500),this.popupDiv.deleteTimeout=setTimeout(()=>{this._removePopup()},1800)}}_makeCheckbox(e,t,i){let s=document.createElement("input");s.type="checkbox",s.className="vis-configuration vis-config-checkbox",s.checked=e,t!==void 0&&(s.checked=t,t!==e&&(typeof e=="object"?t!==e.enabled&&this.changedOptions.push({path:i,value:t}):this.changedOptions.push({path:i,value:t})));let o=this;s.onchange=function(){o._update(this.checked,i)};let r=this._makeLabel(i[i.length-1],i);this._makeItem(i,r,s)}_makeTextInput(e,t,i){let s=document.createElement("input");s.type="text",s.className="vis-configuration vis-config-text",s.value=t,t!==e&&this.changedOptions.push({path:i,value:t});let o=this;s.onchange=function(){o._update(this.value,i)};let r=this._makeLabel(i[i.length-1],i);this._makeItem(i,r,s)}_makeColorField(e,t,i){let s=e[1],o=document.createElement("div");t=t===void 0?s:t,t!=="none"?(o.className="vis-configuration vis-config-colorBlock",o.style.backgroundColor=t):o.className="vis-configuration vis-config-colorBlock none",t=t===void 0?s:t,o.onclick=()=>{this._showColorPicker(t,o,i)};let r=this._makeLabel(i[i.length-1],i);this._makeItem(i,r,o)}_showColorPicker(e,t,i){t.onclick=function(){},this.colorPicker.insertTo(t),this.colorPicker.show(),this.colorPicker.setColor(e),this.colorPicker.setUpdateCallback(s=>{let o="rgba("+s.r+","+s.g+","+s.b+","+s.a+")";t.style.backgroundColor=o,this._update(o,i)}),this.colorPicker.setCloseCallback(()=>{t.onclick=()=>{this._showColorPicker(e,t,i)}})}_handleObject(e,t=[],i=!1){let s=!1,o=this.options.filter,r=!1;for(let a in e)if(Object.prototype.hasOwnProperty.call(e,a)){s=!0;let d=e[a],h=Lt(t,a);if(typeof o=="function"&&(s=o(a,t),s===!1&&!Array.isArray(d)&&typeof d!="string"&&typeof d!="boolean"&&d instanceof Object&&(this.allowCreation=!1,s=this._handleObject(d,h,!0),this.allowCreation=i===!1)),s!==!1){r=!0;let l=this._getValue(h);if(Array.isArray(d))this._handleArray(d,l,h);else if(typeof d=="string")this._makeTextInput(d,l,h);else if(typeof d=="boolean")this._makeCheckbox(d,l,h);else if(d instanceof Object){if(!this.hideOption(t,a,this.moduleOptions))if(d.enabled!==void 0){let c=Lt(h,"enabled"),u=this._getValue(c);if(u===!0){let p=this._makeLabel(a,h,!0);this._makeItem(h,p),r=this._handleObject(d,h)||r}else this._makeCheckbox(d,u,h)}else{let c=this._makeLabel(a,h,!0);this._makeItem(h,c),r=this._handleObject(d,h)||r}}else console.error("dont know how to handle",d,a,h)}}return r}_handleArray(e,t,i){typeof e[0]=="string"&&e[0]==="color"?(this._makeColorField(e,t,i),e[1]!==t&&this.changedOptions.push({path:i,value:t})):typeof e[0]=="string"?(this._makeDropdown(e,t,i),e[0]!==t&&this.changedOptions.push({path:i,value:t})):typeof e[0]=="number"&&(this._makeRange(e,t,i),e[0]!==t&&this.changedOptions.push({path:i,value:Number(t)}))}_update(e,t){let i=this._constructOptions(e,t);this.parent.body&&this.parent.body.emitter&&this.parent.body.emitter.emit&&this.parent.body.emitter.emit("configChange",i),this.initialized=!0,this.parent.setOptions(i)}_constructOptions(e,t,i={}){let s=i;e=e==="true"?!0:e,e=e==="false"?!1:e;for(let o=0;oo-this.padding&&(d=!0),d?r=this.x-i:r=this.x,h?a=this.y-t:a=this.y}else a=this.y-t,a+t+this.padding>s&&(a=s-t-this.padding),ao&&(r=o-i-this.padding),r\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",r=window.console&&(window.console.warn||window.console.log);return r&&r.call(window.console,i,o),n.apply(this,arguments)}}var ks=Ts(function(n,e,t){for(var i=Object.keys(e),s=0;s2)return At(Ds(n[0],n[1]),...n.slice(2));let e=n[0],t=n[1];for(let i of Reflect.ownKeys(t))Object.prototype.propertyIsEnumerable.call(t,i)&&(t[i]===gi?delete e[i]:e[i]!==null&&t[i]!==null&&typeof e[i]=="object"&&typeof t[i]=="object"&&!Array.isArray(e[i])&&!Array.isArray(t[i])?e[i]=At(e[i],t[i]):e[i]=Fs(t[i]));return e}function Fs(n){return Array.isArray(n)?n.map(e=>Fs(e)):typeof n=="object"&&n!==null?At({},n):n}function Ns(n){for(let e of Object.keys(n))n[e]===gi?delete n[e]:typeof n[e]=="object"&&n[e]!==null&&Ns(n[e])}function yt(...n){return Ir(n.length?n:[Date.now()])}function Ir(n){let[e,t,i]=Pr(n),s=1,o=()=>{let r=2091639*e+s*23283064365386963e-26;return e=t,t=i,i=r-(s=r|0)};return o.uint32=()=>o()*4294967296,o.fract53=()=>o()+(o()*2097152|0)*11102230246251565e-32,o.algorithm="Alea",o.seed=n,o.version="0.9",o}function Pr(...n){let e=Mr(),t=e(" "),i=e(" "),s=e(" ");for(let o=0;o>>0,s-=n,s*=n,n=s>>>0,s-=n,n+=s*4294967296}return(n>>>0)*23283064365386963e-26}}function Dr(){let n=()=>{};return{on:n,off:n,destroy:n,emit:n,get(){return{set:n}}}}var mi=typeof window!="undefined"?window.Hammer||Is:function(){return Dr()};function me(n){this._cleanupQueue=[],this.active=!1,this._dom={container:n,overlay:document.createElement("div")},this._dom.overlay.classList.add("vis-overlay"),this._dom.container.appendChild(this._dom.overlay),this._cleanupQueue.push(()=>{this._dom.overlay.parentNode.removeChild(this._dom.overlay)});let e=mi(this._dom.overlay);e.on("tap",this._onTapOverlay.bind(this)),this._cleanupQueue.push(()=>{e.destroy()}),["tap","doubletap","press","pinch","pan","panstart","panmove","panend"].forEach(i=>{e.on(i,s=>{s.srcEvent.stopPropagation()})}),document&&document.body&&(this._onClick=i=>{Fr(i.target,n)||this.deactivate()},document.body.addEventListener("click",this._onClick),this._cleanupQueue.push(()=>{document.body.removeEventListener("click",this._onClick)})),this._escListener=i=>{("key"in i?i.key==="Escape":i.keyCode===27)&&this.deactivate()}}(0,Ps.default)(me.prototype);me.current=null;me.prototype.destroy=function(){this.deactivate();for(let n of this._cleanupQueue.splice(0).reverse())n()};me.prototype.activate=function(){me.current&&me.current.deactivate(),me.current=this,this.active=!0,this._dom.overlay.style.display="none",this._dom.container.classList.add("vis-active"),this.emit("change"),this.emit("activate"),document.body.addEventListener("keydown",this._escListener)};me.prototype.deactivate=function(){this.active=!1,this._dom.overlay.style.display="block",this._dom.container.classList.remove("vis-active"),document.body.removeEventListener("keydown",this._escListener),this.emit("change"),this.emit("deactivate")};me.prototype._onTapOverlay=function(n){this.activate(),n.srcEvent.stopPropagation()};function Fr(n,e){for(;n;){if(n===e)return!0;n=n.parentNode}return!1}var Nr=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,Br=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,Ar=/^rgb\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *\)$/i,zr=/^rgba\( *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *(1?\d{1,2}|2[0-4]\d|25[0-5]) *, *([01]|0?\.\d+) *\)$/i;function we(n){if(n)for(;n.hasChildNodes()===!0;){let e=n.firstChild;e&&(we(e),n.removeChild(e))}}function _e(n){return n instanceof String||typeof n=="string"}function Bs(n){return typeof n=="object"&&n!==null}function Ve(n,e,t,i){let s=!1;i===!0&&(s=e[t]===null&&n[t]!==void 0),s?delete n[t]:n[t]=e[t]}function yi(n,e,t=!1){for(let i in n)if(e[i]!==void 0)if(e[i]===null||typeof e[i]!="object")Ve(n,e,i,t);else{let s=n[i],o=e[i];Bs(s)&&Bs(o)&&yi(s,o,t)}}function qe(n,e,t,i=!1){if(Array.isArray(t))throw new TypeError("Arrays are not supported by deepExtend");for(let s=0;s{},this.closeCallback=()=>{},this._create()}insertTo(e){this.hammer!==void 0&&(this.hammer.destroy(),this.hammer=void 0),this.container=e,this.container.appendChild(this.frame),this._bindHammer(),this._setSize()}setUpdateCallback(e){if(typeof e=="function")this.updateCallback=e;else throw new Error("Function attempted to set as colorPicker update callback is not a function.")}setCloseCallback(e){if(typeof e=="function")this.closeCallback=e;else throw new Error("Function attempted to set as colorPicker closing callback is not a function.")}_isColorString(e){if(typeof e=="string")return jr[e]}setColor(e,t=!0){if(e==="none")return;let i,s=this._isColorString(e);if(s!==void 0&&(e=s),_e(e)===!0){if(Ws(e)===!0){let o=e.substr(4).substr(0,e.length-5).split(",");i={r:o[0],g:o[1],b:o[2],a:1}}else if(Hr(e)===!0){let o=e.substr(5).substr(0,e.length-6).split(",");i={r:o[0],g:o[1],b:o[2],a:o[3]}}else if(js(e)===!0){let o=bi(e);i={r:o.r,g:o.g,b:o.b,a:1}}}else if(e instanceof Object&&e.r!==void 0&&e.g!==void 0&&e.b!==void 0){let o=e.a!==void 0?e.a:"1.0";i={r:e.r,g:e.g,b:e.b,a:o}}if(i===void 0)throw new Error("Unknown color passed to the colorPicker. Supported are strings: rgb, hex, rgba. Object: rgb ({r:r,g:g,b:b,[a:a]}). Supplied: "+JSON.stringify(e));this._setColor(i,t)}show(){this.closeCallback!==void 0&&(this.closeCallback(),this.closeCallback=void 0),this.applied=!1,this.frame.style.display="block",this._generateHueCircle()}_hide(e=!0){e===!0&&(this.previousColor=Object.assign({},this.color)),this.applied===!0&&this.updateCallback(this.initialColor),this.frame.style.display="none",setTimeout(()=>{this.closeCallback!==void 0&&(this.closeCallback(),this.closeCallback=void 0)},0)}_save(){this.updateCallback(this.color),this.applied=!1,this._hide()}_apply(){this.applied=!0,this.updateCallback(this.color),this._updatePicker(this.color)}_loadLast(){this.previousColor!==void 0?this.setColor(this.previousColor,!1):alert("There is no last color to load...")}_setColor(e,t=!0){t===!0&&(this.initialColor=Object.assign({},e)),this.color=e;let i=vt(e.r,e.g,e.b),s=2*Math.PI,o=this.r*i.s,r=this.centerCoordinates.x+o*Math.sin(s*i.h),a=this.centerCoordinates.y+o*Math.cos(s*i.h);this.colorPickerSelector.style.left=r-.5*this.colorPickerSelector.clientWidth+"px",this.colorPickerSelector.style.top=a-.5*this.colorPickerSelector.clientHeight+"px",this._updatePicker(e)}_setOpacity(e){this.color.a=e/100,this._updatePicker(this.color)}_setBrightness(e){let t=vt(this.color.r,this.color.g,this.color.b);t.v=e/100;let i=Rt(t.h,t.s,t.v);i.a=this.color.a,this.color=i,this._updatePicker()}_updatePicker(e=this.color){let t=vt(e.r,e.g,e.b),i=this.colorPickerCanvas.getContext("2d");this.pixelRation===void 0&&(this.pixelRatio=(window.devicePixelRatio||1)/(i.webkitBackingStorePixelRatio||i.mozBackingStorePixelRatio||i.msBackingStorePixelRatio||i.oBackingStorePixelRatio||i.backingStorePixelRatio||1)),i.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0);let s=this.colorPickerCanvas.clientWidth,o=this.colorPickerCanvas.clientHeight;i.clearRect(0,0,s,o),i.putImageData(this.hueCircle,0,0),i.fillStyle="rgba(0,0,0,"+(1-t.v)+")",i.circle(this.centerCoordinates.x,this.centerCoordinates.y,this.r),i.fill(),this.brightnessRange.value=100*t.v,this.opacityRange.value=100*e.a,this.initialColorDiv.style.backgroundColor="rgba("+this.initialColor.r+","+this.initialColor.g+","+this.initialColor.b+","+this.initialColor.a+")",this.newColorDiv.style.backgroundColor="rgba("+this.color.r+","+this.color.g+","+this.color.b+","+this.color.a+")"}_setSize(){this.colorPickerCanvas.style.width="100%",this.colorPickerCanvas.style.height="100%",this.colorPickerCanvas.width=289*this.pixelRatio,this.colorPickerCanvas.height=289*this.pixelRatio}_create(){if(this.frame=document.createElement("div"),this.frame.className="vis-color-picker",this.colorPickerDiv=document.createElement("div"),this.colorPickerSelector=document.createElement("div"),this.colorPickerSelector.className="vis-selector",this.colorPickerDiv.appendChild(this.colorPickerSelector),this.colorPickerCanvas=document.createElement("canvas"),this.colorPickerDiv.appendChild(this.colorPickerCanvas),this.colorPickerCanvas.getContext){let t=this.colorPickerCanvas.getContext("2d");this.pixelRatio=(window.devicePixelRatio||1)/(t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1),this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0)}else{let t=document.createElement("DIV");t.style.color="red",t.style.fontWeight="bold",t.style.padding="10px",t.innerText="Error: your browser does not support HTML canvas",this.colorPickerCanvas.appendChild(t)}this.colorPickerDiv.className="vis-color",this.opacityDiv=document.createElement("div"),this.opacityDiv.className="vis-opacity",this.brightnessDiv=document.createElement("div"),this.brightnessDiv.className="vis-brightness",this.arrowDiv=document.createElement("div"),this.arrowDiv.className="vis-arrow",this.opacityRange=document.createElement("input");try{this.opacityRange.type="range",this.opacityRange.min="0",this.opacityRange.max="100"}catch(t){}this.opacityRange.value="100",this.opacityRange.className="vis-range",this.brightnessRange=document.createElement("input");try{this.brightnessRange.type="range",this.brightnessRange.min="0",this.brightnessRange.max="100"}catch(t){}this.brightnessRange.value="100",this.brightnessRange.className="vis-range",this.opacityDiv.appendChild(this.opacityRange),this.brightnessDiv.appendChild(this.brightnessRange);let e=this;this.opacityRange.onchange=function(){e._setOpacity(this.value)},this.opacityRange.oninput=function(){e._setOpacity(this.value)},this.brightnessRange.onchange=function(){e._setBrightness(this.value)},this.brightnessRange.oninput=function(){e._setBrightness(this.value)},this.brightnessLabel=document.createElement("div"),this.brightnessLabel.className="vis-label vis-brightness",this.brightnessLabel.innerText="brightness:",this.opacityLabel=document.createElement("div"),this.opacityLabel.className="vis-label vis-opacity",this.opacityLabel.innerText="opacity:",this.newColorDiv=document.createElement("div"),this.newColorDiv.className="vis-new-color",this.newColorDiv.innerText="new",this.initialColorDiv=document.createElement("div"),this.initialColorDiv.className="vis-initial-color",this.initialColorDiv.innerText="initial",this.cancelButton=document.createElement("div"),this.cancelButton.className="vis-button vis-cancel",this.cancelButton.innerText="cancel",this.cancelButton.onclick=this._hide.bind(this,!1),this.applyButton=document.createElement("div"),this.applyButton.className="vis-button vis-apply",this.applyButton.innerText="apply",this.applyButton.onclick=this._apply.bind(this),this.saveButton=document.createElement("div"),this.saveButton.className="vis-button vis-save",this.saveButton.innerText="save",this.saveButton.onclick=this._save.bind(this),this.loadButton=document.createElement("div"),this.loadButton.className="vis-button vis-load",this.loadButton.innerText="load last",this.loadButton.onclick=this._loadLast.bind(this),this.frame.appendChild(this.colorPickerDiv),this.frame.appendChild(this.arrowDiv),this.frame.appendChild(this.brightnessLabel),this.frame.appendChild(this.brightnessDiv),this.frame.appendChild(this.opacityLabel),this.frame.appendChild(this.opacityDiv),this.frame.appendChild(this.newColorDiv),this.frame.appendChild(this.initialColorDiv),this.frame.appendChild(this.cancelButton),this.frame.appendChild(this.applyButton),this.frame.appendChild(this.saveButton),this.frame.appendChild(this.loadButton)}_bindHammer(){this.drag={},this.pinch={},this.hammer=new mi(this.colorPickerCanvas),this.hammer.get("pinch").set({enable:!0}),this.hammer.on("hammer.input",e=>{e.isFirst&&this._moveSelector(e)}),this.hammer.on("tap",e=>{this._moveSelector(e)}),this.hammer.on("panstart",e=>{this._moveSelector(e)}),this.hammer.on("panmove",e=>{this._moveSelector(e)}),this.hammer.on("panend",e=>{this._moveSelector(e)})}_generateHueCircle(){if(this.generated===!1){let e=this.colorPickerCanvas.getContext("2d");this.pixelRation===void 0&&(this.pixelRatio=(window.devicePixelRatio||1)/(e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1)),e.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0);let t=this.colorPickerCanvas.clientWidth,i=this.colorPickerCanvas.clientHeight;e.clearRect(0,0,t,i);let s,o,r,a;this.centerCoordinates={x:t*.5,y:i*.5},this.r=.49*t;let d=2*Math.PI/360,h=1/360,l=1/this.r,c;for(r=0;r<360;r++)for(a=0;a!1){this.parent=e,this.changedOptions=[],this.container=t,this.allowCreation=!1,this.hideOption=o,this.options={},this.initialized=!1,this.popupCounter=0,this.defaultOptions={enabled:!1,filter:!0,container:void 0,showButton:!0},Object.assign(this.options,this.defaultOptions),this.configureOptions=i,this.moduleOptions={},this.domElements=[],this.popupDiv={},this.popupLimit=5,this.popupHistory={},this.colorPicker=new qs(s),this.wrapper=void 0}setOptions(e){if(e!==void 0){this.popupHistory={},this._removePopup();let t=!0;if(typeof e=="string")this.options.filter=e;else if(Array.isArray(e))this.options.filter=e.join();else if(typeof e=="object"){if(e==null)throw new TypeError("options cannot be null");e.container!==void 0&&(this.options.container=e.container),e.filter!==void 0&&(this.options.filter=e.filter),e.showButton!==void 0&&(this.options.showButton=e.showButton),e.enabled!==void 0&&(t=e.enabled)}else typeof e=="boolean"?(this.options.filter=!0,t=e):typeof e=="function"&&(this.options.filter=e,t=!0);this.options.filter===!1&&(t=!1),this.options.enabled=t}this._clean()}setModuleOptions(e){this.moduleOptions=e,this.options.enabled===!0&&(this._clean(),this.options.container!==void 0&&(this.container=this.options.container),this._create())}_create(){this._clean(),this.changedOptions=[];let e=this.options.filter,t=0,i=!1;for(let s in this.configureOptions)Object.prototype.hasOwnProperty.call(this.configureOptions,s)&&(this.allowCreation=!1,i=!1,typeof e=="function"?(i=e(s,[]),i=i||this._handleObject(this.configureOptions[s],[s],!0)):(e===!0||e.indexOf(s)!==-1)&&(i=!0),i!==!1&&(this.allowCreation=!0,t>0&&this._makeItem([]),this._makeHeader(s),this._handleObject(this.configureOptions[s],[s])),t++);this._makeButton(),this._push()}_push(){this.wrapper=document.createElement("div"),this.wrapper.className="vis-configuration-wrapper",this.container.appendChild(this.wrapper);for(let e=0;e{i.appendChild(s)}),this.domElements.push(i),this.domElements.length}return 0}_makeHeader(e){let t=document.createElement("div");t.className="vis-configuration vis-config-header",t.innerText=e,this._makeItem([],t)}_makeLabel(e,t,i=!1){let s=document.createElement("div");if(s.className="vis-configuration vis-config-label vis-config-s"+t.length,i===!0){for(;s.firstChild;)s.removeChild(s.firstChild);s.appendChild(vi("i","b",e))}else s.innerText=e+":";return s}_makeDropdown(e,t,i){let s=document.createElement("select");s.className="vis-configuration vis-config-select";let o=0;t!==void 0&&e.indexOf(t)!==-1&&(o=e.indexOf(t));for(let d=0;dr&&r!==1&&(d.max=Math.ceil(t*C),l=d.max,h="range increased"),d.value=t}else d.value=s;let c=document.createElement("input");c.className="vis-configuration vis-config-rangeinput",c.value=d.value;let u=this;d.onchange=function(){c.value=this.value,u._update(Number(this.value),i)},d.oninput=function(){c.value=this.value};let p=this._makeLabel(i[i.length-1],i),b=this._makeItem(i,p,d,c);h!==""&&this.popupHistory[b]!==l&&(this.popupHistory[b]=l,this._setupPopup(h,b))}_makeButton(){if(this.options.showButton===!0){let e=document.createElement("div");e.className="vis-configuration vis-config-button",e.innerText="generate options",e.onclick=()=>{this._printOptions()},e.onmouseover=()=>{e.className="vis-configuration vis-config-button hover"},e.onmouseout=()=>{e.className="vis-configuration vis-config-button"},this.optionsContainer=document.createElement("div"),this.optionsContainer.className="vis-configuration vis-config-option-container",this.domElements.push(this.optionsContainer),this.domElements.push(e)}}_setupPopup(e,t){if(this.initialized===!0&&this.allowCreation===!0&&this.popupCounter{this._removePopup()},this.popupCounter+=1,this.popupDiv={html:i,index:t}}}_removePopup(){this.popupDiv.html!==void 0&&(this.popupDiv.html.parentNode.removeChild(this.popupDiv.html),clearTimeout(this.popupDiv.hideTimeout),clearTimeout(this.popupDiv.deleteTimeout),this.popupDiv={})}_showPopupIfNeeded(){if(this.popupDiv.html!==void 0){let t=this.domElements[this.popupDiv.index].getBoundingClientRect();this.popupDiv.html.style.left=t.left+"px",this.popupDiv.html.style.top=t.top-30+"px",document.body.appendChild(this.popupDiv.html),this.popupDiv.hideTimeout=setTimeout(()=>{this.popupDiv.html.style.opacity=0},1500),this.popupDiv.deleteTimeout=setTimeout(()=>{this._removePopup()},1800)}}_makeCheckbox(e,t,i){let s=document.createElement("input");s.type="checkbox",s.className="vis-configuration vis-config-checkbox",s.checked=e,t!==void 0&&(s.checked=t,t!==e&&(typeof e=="object"?t!==e.enabled&&this.changedOptions.push({path:i,value:t}):this.changedOptions.push({path:i,value:t})));let o=this;s.onchange=function(){o._update(this.checked,i)};let r=this._makeLabel(i[i.length-1],i);this._makeItem(i,r,s)}_makeTextInput(e,t,i){let s=document.createElement("input");s.type="text",s.className="vis-configuration vis-config-text",s.value=t,t!==e&&this.changedOptions.push({path:i,value:t});let o=this;s.onchange=function(){o._update(this.value,i)};let r=this._makeLabel(i[i.length-1],i);this._makeItem(i,r,s)}_makeColorField(e,t,i){let s=e[1],o=document.createElement("div");t=t===void 0?s:t,t!=="none"?(o.className="vis-configuration vis-config-colorBlock",o.style.backgroundColor=t):o.className="vis-configuration vis-config-colorBlock none",t=t===void 0?s:t,o.onclick=()=>{this._showColorPicker(t,o,i)};let r=this._makeLabel(i[i.length-1],i);this._makeItem(i,r,o)}_showColorPicker(e,t,i){t.onclick=function(){},this.colorPicker.insertTo(t),this.colorPicker.show(),this.colorPicker.setColor(e),this.colorPicker.setUpdateCallback(s=>{let o="rgba("+s.r+","+s.g+","+s.b+","+s.a+")";t.style.backgroundColor=o,this._update(o,i)}),this.colorPicker.setCloseCallback(()=>{t.onclick=()=>{this._showColorPicker(e,t,i)}})}_handleObject(e,t=[],i=!1){let s=!1,o=this.options.filter,r=!1;for(let a in e)if(Object.prototype.hasOwnProperty.call(e,a)){s=!0;let d=e[a],h=zt(t,a);if(typeof o=="function"&&(s=o(a,t),s===!1&&!Array.isArray(d)&&typeof d!="string"&&typeof d!="boolean"&&d instanceof Object&&(this.allowCreation=!1,s=this._handleObject(d,h,!0),this.allowCreation=i===!1)),s!==!1){r=!0;let l=this._getValue(h);if(Array.isArray(d))this._handleArray(d,l,h);else if(typeof d=="string")this._makeTextInput(d,l,h);else if(typeof d=="boolean")this._makeCheckbox(d,l,h);else if(d instanceof Object){if(!this.hideOption(t,a,this.moduleOptions))if(d.enabled!==void 0){let c=zt(h,"enabled"),u=this._getValue(c);if(u===!0){let p=this._makeLabel(a,h,!0);this._makeItem(h,p),r=this._handleObject(d,h)||r}else this._makeCheckbox(d,u,h)}else{let c=this._makeLabel(a,h,!0);this._makeItem(h,c),r=this._handleObject(d,h)||r}}else console.error("dont know how to handle",d,a,h)}}return r}_handleArray(e,t,i){typeof e[0]=="string"&&e[0]==="color"?(this._makeColorField(e,t,i),e[1]!==t&&this.changedOptions.push({path:i,value:t})):typeof e[0]=="string"?(this._makeDropdown(e,t,i),e[0]!==t&&this.changedOptions.push({path:i,value:t})):typeof e[0]=="number"&&(this._makeRange(e,t,i),e[0]!==t&&this.changedOptions.push({path:i,value:Number(t)}))}_update(e,t){let i=this._constructOptions(e,t);this.parent.body&&this.parent.body.emitter&&this.parent.body.emitter.emit&&this.parent.body.emitter.emit("configChange",i),this.initialized=!0,this.parent.setOptions(i)}_constructOptions(e,t,i={}){let s=i;e=e==="true"?!0:e,e=e==="false"?!1:e;for(let o=0;oo-this.padding&&(d=!0),d?r=this.x-i:r=this.x,h?a=this.y-t:a=this.y}else a=this.y-t,a+t+this.padding>s&&(a=s-t-this.padding),ao&&(r=o-i-this.padding),ro.distance?d=" in "+X.printLocation(s.path,e,"")+"Perhaps it was misplaced? Matching option found at: "+X.printLocation(o.path,o.closestMatch,""):s.distance<=r?d='. Did you mean "'+s.closestMatch+'"?'+X.printLocation(s.path,e):d=". Did you mean one of these: "+X.print(Object.keys(t))+X.printLocation(i,e),console.error('%cUnknown option detected: "'+e+'"'+d,_i),bt=!0}static findInOptions(e,t,i,s=!1){let o=1e9,r="",a=[],d=e.toLowerCase(),h;for(let l in t){let c;if(t[l].__type__!==void 0&&s===!0){let u=X.findInOptions(e,t[l],Lt(i,l));o>u.distance&&(r=u.closestMatch,a=u.path,o=u.distance,h=u.indexMatch)}else l.toLowerCase().indexOf(d)!==-1&&(h=l),c=X.levenshteinDistance(e,l),o>c&&(r=l,a=Ur(i),o=c)}return{closestMatch:r,path:a,distance:o,indexMatch:h}}static printLocation(e,t,i=`Problem value found at: +`:o.distance<=a&&s.distance>o.distance?d=" in "+X.printLocation(s.path,e,"")+"Perhaps it was misplaced? Matching option found at: "+X.printLocation(o.path,o.closestMatch,""):s.distance<=r?d='. Did you mean "'+s.closestMatch+'"?'+X.printLocation(s.path,e):d=". Did you mean one of these: "+X.print(Object.keys(t))+X.printLocation(i,e),console.error('%cUnknown option detected: "'+e+'"'+d,wi),wt=!0}static findInOptions(e,t,i,s=!1){let o=1e9,r="",a=[],d=e.toLowerCase(),h;for(let l in t){let c;if(t[l].__type__!==void 0&&s===!0){let u=X.findInOptions(e,t[l],zt(i,l));o>u.distance&&(r=u.closestMatch,a=u.path,o=u.distance,h=u.indexMatch)}else l.toLowerCase().indexOf(d)!==-1&&(h=l),c=X.levenshteinDistance(e,l),o>c&&(r=l,a=Lr(i),o=c)}return{closestMatch:r,path:a,distance:o,indexMatch:h}}static printLocation(e,t,i=`Problem value found at: `){let s=` `+i+`options = { @@ -11,16 +11,16 @@ `;for(let o=0;o1&&arguments[1]!==void 0?arguments[1]:0,t=(Q[n[e+0]]+Q[n[e+1]]+Q[n[e+2]]+Q[n[e+3]]+"-"+Q[n[e+4]]+Q[n[e+5]]+"-"+Q[n[e+6]]+Q[n[e+7]]+"-"+Q[n[e+8]]+Q[n[e+9]]+"-"+Q[n[e+10]]+Q[n[e+11]]+Q[n[e+12]]+Q[n[e+13]]+Q[n[e+14]]+Q[n[e+15]]).toLowerCase();if(!eo(t))throw TypeError("Stringified UUID is invalid");return t}var to=Qr;function $r(n,e,t){n=n||{};var i=n.random||(n.rng||xi)();if(i[6]=i[6]&15|64,i[8]=i[8]&63|128,e){t=t||0;for(var s=0;s<16;++s)e[t+s]=i[s];return e}return to(i)}var Te=$r;function io(n){return typeof n=="string"||typeof n=="number"}var qt=class{constructor(e){$(this,"delay");$(this,"max");$(this,"_queue",[]);$(this,"_timeout",null);$(this,"_extended",null);this.delay=null,this.max=1/0,this.setOptions(e)}setOptions(e){e&&typeof e.delay!="undefined"&&(this.delay=e.delay),e&&typeof e.max!="undefined"&&(this.max=e.max),this._flushIfNeeded()}static extend(e,t){let i=new qt(t);if(e.flush!==void 0)throw new Error("Target object already has a property flush");e.flush=()=>{i.flush()};let s=[{name:"flush",original:void 0}];if(t&&t.replace)for(let o=0;othis.max&&this.flush(),this._timeout!=null&&(clearTimeout(this._timeout),this._timeout=null),this.queue.length>0&&typeof this.delay=="number"&&(this._timeout=setTimeout(()=>{this.flush()},this.delay))}flush(){this._queue.splice(0).forEach(e=>{e.fn.apply(e.context||e.fn,e.args||[])})}},vt=class{constructor(){$(this,"_subscribers",{"*":[],add:[],remove:[],update:[]});$(this,"subscribe",vt.prototype.on);$(this,"unsubscribe",vt.prototype.off)}_trigger(e,t,i){if(e==="*")throw new Error("Cannot trigger event *");[...this._subscribers[e],...this._subscribers["*"]].forEach(s=>{s(e,t,i!=null?i:null)})}on(e,t){typeof t=="function"&&this._subscribers[e].push(t)}off(e,t){this._subscribers[e]=this._subscribers[e].filter(i=>i!==t)}},Ie=class{constructor(e){$(this,"_pairs");this._pairs=e}*[Symbol.iterator](){for(let[e,t]of this._pairs)yield[e,t]}*entries(){for(let[e,t]of this._pairs)yield[e,t]}*keys(){for(let[e]of this._pairs)yield e}*values(){for(let[,e]of this._pairs)yield e}toIdArray(){return[...this._pairs].map(e=>e[0])}toItemArray(){return[...this._pairs].map(e=>e[1])}toEntryArray(){return[...this._pairs]}toObjectMap(){let e=Object.create(null);for(let[t,i]of this._pairs)e[t]=i;return e}toMap(){return new Map(this._pairs)}toIdSet(){return new Set(this.toIdArray())}toItemSet(){return new Set(this.toItemArray())}cache(){return new Ie([...this._pairs])}distinct(e){let t=new Set;for(let[i,s]of this._pairs)t.add(e(s,i));return t}filter(e){let t=this._pairs;return new Ie({*[Symbol.iterator](){for(let[i,s]of t)e(s,i)&&(yield[i,s])}})}forEach(e){for(let[t,i]of this._pairs)e(i,t)}map(e){let t=this._pairs;return new Ie({*[Symbol.iterator](){for(let[i,s]of t)yield[i,e(s,i)]}})}max(e){let t=this._pairs[Symbol.iterator](),i=t.next();if(i.done)return null;let s=i.value[1],o=e(i.value[1],i.value[0]);for(;!(i=t.next()).done;){let[r,a]=i.value,d=e(a,r);d>o&&(o=d,s=a)}return s}min(e){let t=this._pairs[Symbol.iterator](),i=t.next();if(i.done)return null;let s=i.value[1],o=e(i.value[1],i.value[0]);for(;!(i=t.next()).done;){let[r,a]=i.value,d=e(a,r);d[...this._pairs].sort(([t,i],[s,o])=>e(i,o,t,s))[Symbol.iterator]()})}};function Jr(n,e){return n[e]==null&&(n[e]=Te()),n}var fe=class extends vt{constructor(e,t){super();$(this,"flush");$(this,"length");$(this,"_options");$(this,"_data");$(this,"_idProp");$(this,"_queue",null);e&&!Array.isArray(e)&&(t=e,e=[]),this._options=t||{},this._data=new Map,this.length=0,this._idProp=this._options.fieldId||"id",e&&e.length&&this.add(e),this.setOptions(t)}get idProp(){return this._idProp}setOptions(e){e&&e.queue!==void 0&&(e.queue===!1?this._queue&&(this._queue.destroy(),this._queue=null):(this._queue||(this._queue=qt.extend(this,{replace:["add","update","remove"]})),e.queue&&typeof e.queue=="object"&&this._queue.setOptions(e.queue)))}add(e,t){let i=[],s;if(Array.isArray(e)){if(e.map(r=>r[this._idProp]).some(r=>this._data.has(r)))throw new Error("A duplicate id was found in the parameter array.");for(let r=0,a=e.length;r{let l=h[a];if(l!=null&&this._data.has(l)){let c=h,u=Object.assign({},this._data.get(l)),p=this._updateItem(c);s.push(p),r.push(c),o.push(u)}else{let c=this._addItem(h);i.push(c)}};if(Array.isArray(e))for(let h=0,l=e.length;h{let o=this._data.get(s[this._idProp]);if(o==null)throw new Error("Updating non-existent items is not allowed.");return{oldData:o,update:s}}).map(({oldData:s,update:o})=>{let r=s[this._idProp],a=Ds(s,o);return this._data.set(r,a),{id:r,oldData:s,updatedData:a}});if(i.length){let s={items:i.map(o=>o.id),oldData:i.map(o=>o.oldData),data:i.map(o=>o.updatedData)};return this._trigger("update",s,t),s.items}else return[]}get(e,t){let i,s,o;io(e)?(i=e,o=t):Array.isArray(e)?(s=e,o=t):o=e;let r=o&&o.returnType==="Object"?"Object":"Array",a=o&&o.filter,d=[],h,l,c;if(i!=null)h=this._data.get(i),h&&a&&!a(h)&&(h=void 0);else if(s!=null)for(let u=0,p=s.length;u(i[s]=e[s],i),{})}_sort(e,t){if(typeof t=="string"){let i=t;e.sort((s,o)=>{let r=s[i],a=o[i];return r>a?1:ri)&&(t=s,i=o)}return t||null}min(e){let t=null,i=null;for(let s of this._data.values()){let o=s[e];typeof o=="number"&&(i==null||o=.1;)b=+o[c++%r],b>l&&(b=l),p=Math.sqrt(b*b/(1+h*h)),p=a<0?-p:p,e+=p,t+=h*p,u===!0?n.lineTo(e,t):n.moveTo(e,t),l-=b,u=!u}function ra(n,e,t,i){n.beginPath();let s=6,o=Math.PI*2/s;n.moveTo(e+i,t);for(let r=1;r":!0,"--":!0},Pe="",et=0,z="",M="",oe=te.NULL;function ha(){et=0,z=Pe.charAt(0)}function Z(){et++,z=Pe.charAt(et)}function tt(){return Pe.charAt(et+1)}function po(n){var e=n.charCodeAt(0);return e<47?e===35||e===46:e<59?e>47:e<91?e>64:e<96?e===95:e<123?e>96:!1}function Me(n,e){if(n||(n={}),e)for(var t in e)e.hasOwnProperty(t)&&(n[t]=e[t]);return n}function la(n,e,t){for(var i=e.split("."),s=n;i.length;){var o=i.shift();i.length?(s[o]||(s[o]={}),s=s[o]):s[o]=t}}function go(n,e){for(var t,i,s=null,o=[n],r=n;r.parent;)o.push(r.parent),r=r.parent;if(r.nodes){for(t=0,i=r.nodes.length;t=0;t--){var a=o[t];a.nodes||(a.nodes=[]),a.nodes.indexOf(s)===-1&&a.nodes.push(s)}e.attr&&(s.attr=Me(s.attr,e.attr))}function ca(n,e){if(n.edges||(n.edges=[]),n.edges.push(e),n.edge){var t=Me({},n.edge);e.attr=Me(t,e.attr)}}function mo(n,e,t,i,s){var o={from:e,to:t,type:i};return n.edge&&(o.attr=Me({},n.edge)),o.attr=Me(o.attr||{},s),s!=null&&s.hasOwnProperty("arrows")&&s.arrows!=null&&(o.arrows={to:{enabled:!0,type:s.arrows.type}},s.arrows=null),o}function V(){for(oe=te.NULL,M="";z===" "||z===" "||z===` -`||z==="\r";)Z();do{var n=!1;if(z==="#"){for(var e=et-1;Pe.charAt(e)===" "||Pe.charAt(e)===" ";)e--;if(Pe.charAt(e)===` +`}static print(e){return JSON.stringify(e).replace(/(")|(\[)|(\])|(,"__type__")/g,"").replace(/(,)/g,", ")}static levenshteinDistance(e,t){if(e.length===0)return t.length;if(t.length===0)return e.length;let i=[],s;for(s=0;s<=t.length;s++)i[s]=[s];let o;for(o=0;o<=e.length;o++)i[0][o]=o;for(s=1;s<=t.length;s++)for(o=1;o<=e.length;o++)t.charAt(s-1)==e.charAt(o-1)?i[s][o]=i[s-1][o-1]:i[s][o]=Math.min(i[s-1][o-1]+1,Math.min(i[s][o-1]+1,i[s-1][o]+1));return i[t.length][e.length]}},Gs=me;var Ks=Us,Ue=mi,Zs=Ys,_i=wi,Qs=X;var jt,Wr=new Uint8Array(16);function Ei(){if(!jt&&(jt=typeof crypto!="undefined"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||typeof msCrypto!="undefined"&&typeof msCrypto.getRandomValues=="function"&&msCrypto.getRandomValues.bind(msCrypto),!jt))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return jt(Wr)}var $s=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function Vr(n){return typeof n=="string"&&$s.test(n)}var Js=Vr;var Q=[];for(Wt=0;Wt<256;++Wt)Q.push((Wt+256).toString(16).substr(1));var Wt;function qr(n){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,t=(Q[n[e+0]]+Q[n[e+1]]+Q[n[e+2]]+Q[n[e+3]]+"-"+Q[n[e+4]]+Q[n[e+5]]+"-"+Q[n[e+6]]+Q[n[e+7]]+"-"+Q[n[e+8]]+Q[n[e+9]]+"-"+Q[n[e+10]]+Q[n[e+11]]+Q[n[e+12]]+Q[n[e+13]]+Q[n[e+14]]+Q[n[e+15]]).toLowerCase();if(!Js(t))throw TypeError("Stringified UUID is invalid");return t}var eo=qr;function Ur(n,e,t){n=n||{};var i=n.random||(n.rng||Ei)();if(i[6]=i[6]&15|64,i[8]=i[8]&63|128,e){t=t||0;for(var s=0;s<16;++s)e[t+s]=i[s];return e}return eo(i)}var Ce=Ur;function to(n){return typeof n=="string"||typeof n=="number"}var Vt=class{constructor(e){$(this,"delay");$(this,"max");$(this,"_queue",[]);$(this,"_timeout",null);$(this,"_extended",null);this.delay=null,this.max=1/0,this.setOptions(e)}setOptions(e){e&&typeof e.delay!="undefined"&&(this.delay=e.delay),e&&typeof e.max!="undefined"&&(this.max=e.max),this._flushIfNeeded()}static extend(e,t){let i=new Vt(t);if(e.flush!==void 0)throw new Error("Target object already has a property flush");e.flush=()=>{i.flush()};let s=[{name:"flush",original:void 0}];if(t&&t.replace)for(let o=0;othis.max&&this.flush(),this._timeout!=null&&(clearTimeout(this._timeout),this._timeout=null),this.queue.length>0&&typeof this.delay=="number"&&(this._timeout=setTimeout(()=>{this.flush()},this.delay))}flush(){this._queue.splice(0).forEach(e=>{e.fn.apply(e.context||e.fn,e.args||[])})}},_t=class{constructor(){$(this,"_subscribers",{"*":[],add:[],remove:[],update:[]});$(this,"subscribe",_t.prototype.on);$(this,"unsubscribe",_t.prototype.off)}_trigger(e,t,i){if(e==="*")throw new Error("Cannot trigger event *");[...this._subscribers[e],...this._subscribers["*"]].forEach(s=>{s(e,t,i!=null?i:null)})}on(e,t){typeof t=="function"&&this._subscribers[e].push(t)}off(e,t){this._subscribers[e]=this._subscribers[e].filter(i=>i!==t)}},Ie=class{constructor(e){$(this,"_pairs");this._pairs=e}*[Symbol.iterator](){for(let[e,t]of this._pairs)yield[e,t]}*entries(){for(let[e,t]of this._pairs)yield[e,t]}*keys(){for(let[e]of this._pairs)yield e}*values(){for(let[,e]of this._pairs)yield e}toIdArray(){return[...this._pairs].map(e=>e[0])}toItemArray(){return[...this._pairs].map(e=>e[1])}toEntryArray(){return[...this._pairs]}toObjectMap(){let e=Object.create(null);for(let[t,i]of this._pairs)e[t]=i;return e}toMap(){return new Map(this._pairs)}toIdSet(){return new Set(this.toIdArray())}toItemSet(){return new Set(this.toItemArray())}cache(){return new Ie([...this._pairs])}distinct(e){let t=new Set;for(let[i,s]of this._pairs)t.add(e(s,i));return t}filter(e){let t=this._pairs;return new Ie({*[Symbol.iterator](){for(let[i,s]of t)e(s,i)&&(yield[i,s])}})}forEach(e){for(let[t,i]of this._pairs)e(i,t)}map(e){let t=this._pairs;return new Ie({*[Symbol.iterator](){for(let[i,s]of t)yield[i,e(s,i)]}})}max(e){let t=this._pairs[Symbol.iterator](),i=t.next();if(i.done)return null;let s=i.value[1],o=e(i.value[1],i.value[0]);for(;!(i=t.next()).done;){let[r,a]=i.value,d=e(a,r);d>o&&(o=d,s=a)}return s}min(e){let t=this._pairs[Symbol.iterator](),i=t.next();if(i.done)return null;let s=i.value[1],o=e(i.value[1],i.value[0]);for(;!(i=t.next()).done;){let[r,a]=i.value,d=e(a,r);d[...this._pairs].sort(([t,i],[s,o])=>e(i,o,t,s))[Symbol.iterator]()})}};function Yr(n,e){return n[e]==null&&(n[e]=Ce()),n}var Te=class extends _t{constructor(e,t){super();$(this,"flush");$(this,"length");$(this,"_options");$(this,"_data");$(this,"_idProp");$(this,"_queue",null);e&&!Array.isArray(e)&&(t=e,e=[]),this._options=t||{},this._data=new Map,this.length=0,this._idProp=this._options.fieldId||"id",e&&e.length&&this.add(e),this.setOptions(t)}get idProp(){return this._idProp}setOptions(e){e&&e.queue!==void 0&&(e.queue===!1?this._queue&&(this._queue.destroy(),this._queue=null):(this._queue||(this._queue=Vt.extend(this,{replace:["add","update","remove"]})),e.queue&&typeof e.queue=="object"&&this._queue.setOptions(e.queue)))}add(e,t){let i=[],s;if(Array.isArray(e)){if(e.map(r=>r[this._idProp]).some(r=>this._data.has(r)))throw new Error("A duplicate id was found in the parameter array.");for(let r=0,a=e.length;r{let l=h[a];if(l!=null&&this._data.has(l)){let c=h,u=Object.assign({},this._data.get(l)),p=this._updateItem(c);s.push(p),r.push(c),o.push(u)}else{let c=this._addItem(h);i.push(c)}};if(Array.isArray(e))for(let h=0,l=e.length;h{let o=this._data.get(s[this._idProp]);if(o==null)throw new Error("Updating non-existent items is not allowed.");return{oldData:o,update:s}}).map(({oldData:s,update:o})=>{let r=s[this._idProp],a=Ms(s,o);return this._data.set(r,a),{id:r,oldData:s,updatedData:a}});if(i.length){let s={items:i.map(o=>o.id),oldData:i.map(o=>o.oldData),data:i.map(o=>o.updatedData)};return this._trigger("update",s,t),s.items}else return[]}get(e,t){let i,s,o;to(e)?(i=e,o=t):Array.isArray(e)?(s=e,o=t):o=e;let r=o&&o.returnType==="Object"?"Object":"Array",a=o&&o.filter,d=[],h,l,c;if(i!=null)h=this._data.get(i),h&&a&&!a(h)&&(h=void 0);else if(s!=null)for(let u=0,p=s.length;u(i[s]=e[s],i),{})}_sort(e,t){if(typeof t=="string"){let i=t;e.sort((s,o)=>{let r=s[i],a=o[i];return r>a?1:ri)&&(t=s,i=o)}return t||null}min(e){let t=null,i=null;for(let s of this._data.values()){let o=s[e];typeof o=="number"&&(i==null||o=.1;)b=+o[c++%r],b>l&&(b=l),p=Math.sqrt(b*b/(1+h*h)),p=a<0?-p:p,e+=p,t+=h*p,u===!0?n.lineTo(e,t):n.moveTo(e,t),l-=b,u=!u}function Jr(n,e,t,i){n.beginPath();let s=6,o=Math.PI*2/s;n.moveTo(e+i,t);for(let r=1;r":!0,"--":!0},Pe="",it=0,z="",M="",oe=te.NULL;function ia(){it=0,z=Pe.charAt(0)}function Z(){it++,z=Pe.charAt(it)}function st(){return Pe.charAt(it+1)}function fo(n){var e=n.charCodeAt(0);return e<47?e===35||e===46:e<59?e>47:e<91?e>64:e<96?e===95:e<123?e>96:!1}function Me(n,e){if(n||(n={}),e)for(var t in e)e.hasOwnProperty(t)&&(n[t]=e[t]);return n}function sa(n,e,t){for(var i=e.split("."),s=n;i.length;){var o=i.shift();i.length?(s[o]||(s[o]={}),s=s[o]):s[o]=t}}function po(n,e){for(var t,i,s=null,o=[n],r=n;r.parent;)o.push(r.parent),r=r.parent;if(r.nodes){for(t=0,i=r.nodes.length;t=0;t--){var a=o[t];a.nodes||(a.nodes=[]),a.nodes.indexOf(s)===-1&&a.nodes.push(s)}e.attr&&(s.attr=Me(s.attr,e.attr))}function oa(n,e){if(n.edges||(n.edges=[]),n.edges.push(e),n.edge){var t=Me({},n.edge);e.attr=Me(t,e.attr)}}function go(n,e,t,i,s){var o={from:e,to:t,type:i};return n.edge&&(o.attr=Me({},n.edge)),o.attr=Me(o.attr||{},s),s!=null&&s.hasOwnProperty("arrows")&&s.arrows!=null&&(o.arrows={to:{enabled:!0,type:s.arrows.type}},s.arrows=null),o}function V(){for(oe=te.NULL,M="";z===" "||z===" "||z===` +`||z==="\r";)Z();do{var n=!1;if(z==="#"){for(var e=it-1;Pe.charAt(e)===" "||Pe.charAt(e)===" ";)e--;if(Pe.charAt(e)===` `||Pe.charAt(e)===""){for(;z!=""&&z!=` -`;)Z();n=!0}}if(z==="/"&&tt()==="/"){for(;z!=""&&z!=` -`;)Z();n=!0}if(z==="/"&&tt()==="*"){for(;z!="";)if(z==="*"&&tt()==="/"){Z(),Z();break}else Z();n=!0}for(;z===" "||z===" "||z===` -`||z==="\r";)Z()}while(n);if(z===""){oe=te.DELIMITER;return}var t=z+tt();if(fo[t]){oe=te.DELIMITER,M=t,Z(),Z();return}if(fo[z]){oe=te.DELIMITER,M=z,Z();return}if(po(z)||z==="-"){for(M+=z,Z();po(z);)M+=z,Z();M==="false"?M=!1:M==="true"?M=!0:isNaN(Number(M))||(M=Number(M)),oe=te.IDENTIFIER;return}if(z==='"'){for(Z();z!=""&&(z!='"'||z==='"'&&tt()==='"');)z==='"'?(M+=z,Z()):z==="\\"&&tt()==="n"?(M+=` -`,Z()):M+=z,Z();if(z!='"')throw ie('End of string " expected');Z(),oe=te.IDENTIFIER;return}for(oe=te.UNKNOWN;z!="";)M+=z,Z();throw new SyntaxError('Syntax error in part "'+wo(M,30)+'"')}function ua(){var n={};if(ha(),V(),M==="strict"&&(n.strict=!0,V()),(M==="graph"||M==="digraph")&&(n.type=M,V()),oe===te.IDENTIFIER&&(n.id=M,V()),M!="{")throw ie("Angle bracket { expected");if(V(),yo(n),M!="}")throw ie("Angle bracket } expected");if(V(),M!=="")throw ie("End of file expected");return V(),delete n.node,delete n.edge,delete n.graph,n}function yo(n){for(;M!==""&&M!="}";)fa(n),M===";"&&V()}function fa(n){var e=bo(n);if(e){vo(n,e);return}var t=pa(n);if(!t){if(oe!=te.IDENTIFIER)throw ie("Identifier expected");var i=M;if(V(),M==="="){if(V(),oe!=te.IDENTIFIER)throw ie("Identifier expected");n[i]=M,V()}else ga(n,i)}}function bo(n){var e=null;if(M==="subgraph"&&(e={},e.type="subgraph",V(),oe===te.IDENTIFIER&&(e.id=M,V())),M==="{"){if(V(),e||(e={}),e.parent=n,e.node=n.node,e.edge=n.edge,e.graph=n.graph,yo(e),M!="}")throw ie("Angle bracket } expected");V(),delete e.node,delete e.edge,delete e.graph,delete e.parent,n.subgraphs||(n.subgraphs=[]),n.subgraphs.push(e)}return e}function pa(n){return M==="node"?(V(),n.node=_t(),"node"):M==="edge"?(V(),n.edge=_t(),"edge"):M==="graph"?(V(),n.graph=_t(),"graph"):null}function ga(n,e){var t={id:e},i=_t();i&&(t.attr=i),go(n,t),vo(n,e)}function vo(n,e){for(;M==="->"||M==="--";){var t,i=M;V();var s=bo(n);if(s)t=s;else{if(oe!=te.IDENTIFIER)throw ie("Identifier or subgraph expected");t=M,go(n,{id:t}),V()}var o=_t(),r=mo(n,e,t,i,o);ca(n,r),e=t}}function _t(){for(var n,e=null,t={dashed:!0,solid:!1,dotted:[1,5]},i={dot:"circle",box:"box",crow:"crow",curve:"curve",icurve:"inv_curve",normal:"triangle",inv:"inv_triangle",diamond:"diamond",tee:"bar",vee:"vee"},s=new Array,o=new Array;M==="[";){for(V(),e={};M!==""&&M!="]";){if(oe!=te.IDENTIFIER)throw ie("Attribute name expected");var r=M;if(V(),M!="=")throw ie("Equal sign = expected");if(V(),oe!=te.IDENTIFIER)throw ie("Attribute value expected");var a=M;r==="style"&&(a=t[a]);var d;r==="arrowhead"&&(d=i[a],r="arrows",a={to:{enabled:!0,type:d}}),r==="arrowtail"&&(d=i[a],r="arrows",a={from:{enabled:!0,type:d}}),s.push({attr:e,name:r,value:a}),o.push(r),V(),M==","&&V()}if(M!="]")throw ie("Bracket ] expected");V()}if(o.includes("dir")){var h={};for(h.arrows={},n=0;n"&&(o.arrows="to"),o};e.edges.forEach(function(s){var o,r;s.from instanceof Object?o=s.from.nodes:o={id:s.from},s.to instanceof Object?r=s.to.nodes:r={id:s.to},s.from instanceof Object&&s.from.edges&&s.from.edges.forEach(function(a){var d=i(a);t.edges.push(d)}),ma(o,r,function(a,d){var h=mo(t,a.id,d.id,s.type,s.attr),l=i(h);t.edges.push(l)}),s.to instanceof Object&&s.to.edges&&s.to.edges.forEach(function(a){var d=i(a);t.edges.push(d)})})}return e.attr&&(t.options=e.attr),t}function ba(n,e){let t={edges:{inheritColor:!1},nodes:{fixed:!1,parseColor:!1}};e!=null&&(e.fixed!=null&&(t.nodes.fixed=e.fixed),e.parseColor!=null&&(t.nodes.parseColor=e.parseColor),e.inheritColor!=null&&(t.edges.inheritColor=e.inheritColor));let s=n.edges.map(r=>{let a={from:r.source,id:r.id,to:r.target};return r.attributes!=null&&(a.attributes=r.attributes),r.label!=null&&(a.label=r.label),r.attributes!=null&&r.attributes.title!=null&&(a.title=r.attributes.title),r.type==="Directed"&&(a.arrows="to"),r.color&&t.edges.inheritColor===!1&&(a.color=r.color),a});return{nodes:n.nodes.map(r=>{let a={id:r.id,fixed:t.nodes.fixed&&r.x!=null&&r.y!=null};return r.attributes!=null&&(a.attributes=r.attributes),r.label!=null&&(a.label=r.label),r.size!=null&&(a.size=r.size),r.attributes!=null&&r.attributes.title!=null&&(a.title=r.attributes.title),r.title!=null&&(a.title=r.title),r.x!=null&&(a.x=r.x),r.y!=null&&(a.y=r.y),r.color!=null&&(t.nodes.parseColor===!0?a.color=r.color:a.color={background:r.color,border:r.color,highlight:{background:r.color,border:r.color},hover:{background:r.color,border:r.color}}),a}),edges:s}}var va={addDescription:"Click in an empty space to place a new node.",addEdge:"Add Edge",addNode:"Add Node",back:"Back",close:"Close",createEdgeError:"Cannot link edges to a cluster.",del:"Delete selected",deleteClusterError:"Clusters cannot be deleted.",edgeDescription:"Click on a node and drag the edge to another node to connect them.",edit:"Edit",editClusterError:"Clusters cannot be edited.",editEdge:"Edit Edge",editEdgeDescription:"Click on the control points and drag them to a node to connect to it.",editNode:"Edit Node"},wa={addDescription:"Klicke auf eine freie Stelle, um einen neuen Knoten zu plazieren.",addEdge:"Kante hinzuf\xFCgen",addNode:"Knoten hinzuf\xFCgen",back:"Zur\xFCck",close:"Schlie\xDFen",createEdgeError:"Es ist nicht m\xF6glich, Kanten mit Clustern zu verbinden.",del:"L\xF6sche Auswahl",deleteClusterError:"Cluster k\xF6nnen nicht gel\xF6scht werden.",edgeDescription:"Klicke auf einen Knoten und ziehe die Kante zu einem anderen Knoten, um diese zu verbinden.",edit:"Editieren",editClusterError:"Cluster k\xF6nnen nicht editiert werden.",editEdge:"Kante editieren",editEdgeDescription:"Klicke auf die Verbindungspunkte und ziehe diese auf einen Knoten, um sie zu verbinden.",editNode:"Knoten editieren"},_a={addDescription:"Haga clic en un lugar vac\xEDo para colocar un nuevo nodo.",addEdge:"A\xF1adir arista",addNode:"A\xF1adir nodo",back:"Atr\xE1s",close:"Cerrar",createEdgeError:"No se puede conectar una arista a un grupo.",del:"Eliminar selecci\xF3n",deleteClusterError:"No es posible eliminar grupos.",edgeDescription:"Haga clic en un nodo y arrastre la arista hacia otro nodo para conectarlos.",edit:"Editar",editClusterError:"No es posible editar grupos.",editEdge:"Editar arista",editEdgeDescription:"Haga clic en un punto de control y arrastrelo a un nodo para conectarlo.",editNode:"Editar nodo"},Ea={addDescription:"Clicca per aggiungere un nuovo nodo",addEdge:"Aggiungi un vertice",addNode:"Aggiungi un nodo",back:"Indietro",close:"Chiudere",createEdgeError:"Non si possono collegare vertici ad un cluster",del:"Cancella la selezione",deleteClusterError:"I cluster non possono essere cancellati",edgeDescription:"Clicca su un nodo e trascinalo ad un altro nodo per connetterli.",edit:"Modifica",editClusterError:"I clusters non possono essere modificati.",editEdge:"Modifica il vertice",editEdgeDescription:"Clicca sui Punti di controllo e trascinali ad un nodo per connetterli.",editNode:"Modifica il nodo"},xa={addDescription:"Klik op een leeg gebied om een nieuwe node te maken.",addEdge:"Link toevoegen",addNode:"Node toevoegen",back:"Terug",close:"Sluiten",createEdgeError:"Kan geen link maken naar een cluster.",del:"Selectie verwijderen",deleteClusterError:"Clusters kunnen niet worden verwijderd.",edgeDescription:"Klik op een node en sleep de link naar een andere node om ze te verbinden.",edit:"Wijzigen",editClusterError:"Clusters kunnen niet worden aangepast.",editEdge:"Link wijzigen",editEdgeDescription:"Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.",editNode:"Node wijzigen"},Ca={addDescription:"Clique em um espa\xE7o em branco para adicionar um novo n\xF3",addEdge:"Adicionar aresta",addNode:"Adicionar n\xF3",back:"Voltar",close:"Fechar",createEdgeError:"N\xE3o foi poss\xEDvel linkar arestas a um cluster.",del:"Remover selecionado",deleteClusterError:"Clusters n\xE3o puderam ser removidos.",edgeDescription:"Clique em um n\xF3 e arraste a aresta at\xE9 outro n\xF3 para conect\xE1-los",edit:"Editar",editClusterError:"Clusters n\xE3o puderam ser editados.",editEdge:"Editar aresta",editEdgeDescription:"Clique nos pontos de controle e os arraste para um n\xF3 para conect\xE1-los",editNode:"Editar n\xF3"},Ta={addDescription:"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u0432 \u0441\u0432\u043E\u0431\u043E\u0434\u043D\u043E\u0435 \u043C\u0435\u0441\u0442\u043E, \u0447\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043D\u043E\u0432\u044B\u0439 \u0443\u0437\u0435\u043B.",addEdge:"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0440\u0435\u0431\u0440\u043E",addNode:"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0443\u0437\u0435\u043B",back:"\u041D\u0430\u0437\u0430\u0434",close:"\u0417\u0430\u043A\u0440\u044B\u0432\u0430\u0442\u044C",createEdgeError:"\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u044C \u0440\u0435\u0431\u0440\u0430 \u0432 \u043A\u043B\u0430\u0441\u0442\u0435\u0440.",del:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0435",deleteClusterError:"\u041A\u043B\u0430\u0441\u0442\u0435\u0440\u044B \u043D\u0435 \u043C\u043E\u0433\u0443\u0442 \u0431\u044B\u0442\u044C \u0443\u0434\u0430\u043B\u0435\u043D\u044B",edgeDescription:"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043D\u0430 \u0443\u0437\u0435\u043B \u0438 \u043F\u0440\u043E\u0442\u044F\u043D\u0438\u0442\u0435 \u0440\u0435\u0431\u0440\u043E \u043A \u0434\u0440\u0443\u0433\u043E\u043C\u0443 \u0443\u0437\u043B\u0443, \u0447\u0442\u043E\u0431\u044B \u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u044C \u0438\u0445.",edit:"\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C",editClusterError:"\u041A\u043B\u0430\u0441\u0442\u0435\u0440\u044B \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B \u0434\u043B\u044F \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F.",editEdge:"\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0435\u0431\u0440\u043E",editEdgeDescription:"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043D\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u044B\u0435 \u0442\u043E\u0447\u043A\u0438 \u0438 \u043F\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0438\u0445 \u0432 \u0443\u0437\u0435\u043B, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043A \u043D\u0435\u043C\u0443.",editNode:"\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0443\u0437\u0435\u043B"},ka={addDescription:"\u5355\u51FB\u7A7A\u767D\u5904\u653E\u7F6E\u65B0\u8282\u70B9\u3002",addEdge:"\u6DFB\u52A0\u8FDE\u63A5\u7EBF",addNode:"\u6DFB\u52A0\u8282\u70B9",back:"\u8FD4\u56DE",close:"\u95DC\u9589",createEdgeError:"\u65E0\u6CD5\u5C06\u8FDE\u63A5\u7EBF\u8FDE\u63A5\u5230\u7FA4\u96C6\u3002",del:"\u5220\u9664\u9009\u5B9A",deleteClusterError:"\u65E0\u6CD5\u5220\u9664\u7FA4\u96C6\u3002",edgeDescription:"\u5355\u51FB\u67D0\u4E2A\u8282\u70B9\u5E76\u5C06\u8BE5\u8FDE\u63A5\u7EBF\u62D6\u52A8\u5230\u53E6\u4E00\u4E2A\u8282\u70B9\u4EE5\u8FDE\u63A5\u5B83\u4EEC\u3002",edit:"\u7F16\u8F91",editClusterError:"\u65E0\u6CD5\u7F16\u8F91\u7FA4\u96C6\u3002",editEdge:"\u7F16\u8F91\u8FDE\u63A5\u7EBF",editEdgeDescription:"\u5355\u51FB\u63A7\u5236\u8282\u70B9\u5E76\u5C06\u5B83\u4EEC\u62D6\u5230\u8282\u70B9\u4E0A\u8FDE\u63A5\u3002",editNode:"\u7F16\u8F91\u8282\u70B9"},Sa={addDescription:"K\u043B\u0456\u043A\u043D\u0456\u0442\u044C \u043D\u0430 \u0432\u0456\u043B\u044C\u043D\u0435 \u043C\u0456\u0441\u0446\u0435, \u0449\u043E\u0431 \u0434\u043E\u0434\u0430\u0442\u0438 \u043D\u043E\u0432\u0438\u0439 \u0432\u0443\u0437\u043E\u043B.",addEdge:"\u0414\u043E\u0434\u0430\u0442\u0438 \u043A\u0440\u0430\u0439",addNode:"\u0414\u043E\u0434\u0430\u0442\u0438 \u0432\u0443\u0437\u043E\u043B",back:"\u041D\u0430\u0437\u0430\u0434",close:"\u0417\u0430\u043A\u0440\u0438\u0442\u0438",createEdgeError:"\u041D\u0435 \u043C\u043E\u0436\u043B\u0438\u0432\u043E \u043E\u0431'\u0454\u0434\u043D\u0430\u0442\u0438 \u043A\u0440\u0430\u0457 \u0432 \u0433\u0440\u0443\u043F\u0443.",del:"\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438 \u043E\u0431\u0440\u0430\u043D\u0435",deleteClusterError:"\u0413\u0440\u0443\u043F\u0438 \u043D\u0435 \u043C\u043E\u0436\u0443\u0442\u044C \u0431\u0443\u0442\u0438 \u0432\u0438\u0434\u0430\u043B\u0435\u043D\u0456.",edgeDescription:"\u041A\u043B\u0456\u043A\u043D\u0456\u0442\u044C \u043D\u0430 \u0432\u0443\u0437\u043E\u043B \u0456 \u043F\u0435\u0440\u0435\u0442\u044F\u0433\u043D\u0456\u0442\u044C \u043A\u0440\u0430\u0439 \u0434\u043E \u0456\u043D\u0448\u043E\u0433\u043E \u0432\u0443\u0437\u043B\u0430, \u0449\u043E\u0431 \u0457\u0445 \u0437'\u0454\u0434\u043D\u0430\u0442\u0438.",edit:"\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438",editClusterError:"\u0413\u0440\u0443\u043F\u0438 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0456 \u0434\u043B\u044F \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F.",editEdge:"\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u043A\u0440\u0430\u0439",editEdgeDescription:"\u041A\u043B\u0456\u043A\u043D\u0456\u0442\u044C \u043D\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0456 \u0442\u043E\u0447\u043A\u0438 \u0456 \u043F\u0435\u0440\u0435\u0442\u044F\u0433\u043D\u0456\u0442\u044C \u0457\u0445 \u0443 \u0432\u0443\u0437\u043E\u043B, \u0449\u043E\u0431 \u043F\u0456\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u0438\u0441\u044F \u0434\u043E \u043D\u044C\u043E\u0433\u043E.",editNode:"\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u0432\u0443\u0437\u043E\u043B"},Oa={addDescription:"Cliquez dans un endroit vide pour placer un n\u0153ud.",addEdge:"Ajouter un lien",addNode:"Ajouter un n\u0153ud",back:"Retour",close:"Fermer",createEdgeError:"Impossible de cr\xE9er un lien vers un cluster.",del:"Effacer la s\xE9lection",deleteClusterError:"Les clusters ne peuvent pas \xEAtre effac\xE9s.",edgeDescription:"Cliquez sur un n\u0153ud et glissez le lien vers un autre n\u0153ud pour les connecter.",edit:"\xC9diter",editClusterError:"Les clusters ne peuvent pas \xEAtre \xE9dit\xE9s.",editEdge:"\xC9diter le lien",editEdgeDescription:"Cliquez sur les points de contr\xF4le et glissez-les pour connecter un n\u0153ud.",editNode:"\xC9diter le n\u0153ud"},Ia={addDescription:"Kluknut\xEDm do pr\xE1zdn\xE9ho prostoru m\u016F\u017Eete p\u0159idat nov\xFD vrchol.",addEdge:"P\u0159idat hranu",addNode:"P\u0159idat vrchol",back:"Zp\u011Bt",close:"Zav\u0159\xEDt",createEdgeError:"Nelze p\u0159ipojit hranu ke shluku.",del:"Smazat v\xFDb\u011Br",deleteClusterError:"Nelze mazat shluky.",edgeDescription:"P\u0159eta\u017Een\xEDm z jednoho vrcholu do druh\xE9ho m\u016F\u017Eete spojit tyto vrcholy novou hranou.",edit:"Upravit",editClusterError:"Nelze upravovat shluky.",editEdge:"Upravit hranu",editEdgeDescription:"P\u0159eta\u017Een\xEDm kontroln\xEDho vrcholu hrany ji m\u016F\u017Eete p\u0159ipojit k jin\xE9mu vrcholu.",editNode:"Upravit vrchol"},Pa=Object.freeze({__proto__:null,en:va,de:wa,es:_a,it:Ea,nl:xa,pt:Ca,ru:Ta,cn:ka,uk:Sa,fr:Oa,cs:Ia});function Ma(n,e){try{let[t,i]=e.split(/[-_ /]/,2),s=t!=null?t.toLowerCase():null,o=i!=null?i.toUpperCase():null;if(s&&o){let r=s+"-"+o;if(Object.prototype.hasOwnProperty.call(n,r))return r;console.warn(`Unknown variant ${o} of language ${s}.`)}if(s){let r=s;if(Object.prototype.hasOwnProperty.call(n,r))return r;console.warn(`Unknown language ${s}`)}return console.warn(`Unknown locale ${e}, falling back to English.`),"en"}catch(t){return console.error(t),console.warn(`Unexpected error while normalizing locale ${e}, falling back to English.`),"en"}}var Eo=class{constructor(){this.NUM_ITERATIONS=4,this.image=new Image,this.canvas=document.createElement("canvas")}init(){if(this.initialized())return;this.src=this.image.src;let e=this.image.width,t=this.image.height;this.width=e,this.height=t;let i=Math.floor(t/2),s=Math.floor(t/4),o=Math.floor(t/8),r=Math.floor(t/16),a=Math.floor(e/2),d=Math.floor(e/4),h=Math.floor(e/8),l=Math.floor(e/16);this.canvas.width=3*d,this.canvas.height=i,this.coordinates=[[0,0,a,i],[a,0,d,s],[a,s,h,o],[5*h,s,l,r]],this._fillMipMap()}initialized(){return this.coordinates!==void 0}_fillMipMap(){let e=this.canvas.getContext("2d"),t=this.coordinates[0];e.drawImage(this.image,t[0],t[1],t[2],t[3]);for(let i=1;i2){t*=.5;let a=0;for(;t>2&&a=this.NUM_ITERATIONS&&(a=this.NUM_ITERATIONS-1);let d=this.coordinates[a];e.drawImage(this.canvas,d[0],d[1],d[2],d[3],i,s,o,r)}else e.drawImage(this.image,i,s,o,r)}},xo=class{constructor(e){this.images={},this.imageBroken={},this.callback=e}_tryloadBrokenUrl(e,t,i){if(!(e===void 0||i===void 0)){if(t===void 0){console.warn("No broken url image defined");return}i.image.onerror=()=>{console.error("Could not load brokenImage:",t)},i.image.src=t}}_redrawWithImage(e){this.callback&&this.callback(e)}load(e,t){let i=this.images[e];if(i)return i;let s=new Eo;return this.images[e]=s,s.image.onload=()=>{this._fixImageCoordinates(s.image),s.init(),this._redrawWithImage(s)},s.image.onerror=()=>{console.error("Could not load image:",e),this._tryloadBrokenUrl(e,t,s)},s.image.src=e,s}_fixImageCoordinates(e){e.width===0&&(document.body.appendChild(e),e.width=e.offsetWidth,e.height=e.offsetHeight,document.body.removeChild(e))}},Co=class{constructor(){this.clear(),this._defaultIndex=0,this._groupIndex=0,this._defaultGroups=[{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},{border:"#FFA500",background:"#FFFF00",highlight:{border:"#FFA500",background:"#FFFFA3"},hover:{border:"#FFA500",background:"#FFFFA3"}},{border:"#FA0A10",background:"#FB7E81",highlight:{border:"#FA0A10",background:"#FFAFB1"},hover:{border:"#FA0A10",background:"#FFAFB1"}},{border:"#41A906",background:"#7BE141",highlight:{border:"#41A906",background:"#A1EC76"},hover:{border:"#41A906",background:"#A1EC76"}},{border:"#E129F0",background:"#EB7DF4",highlight:{border:"#E129F0",background:"#F0B3F5"},hover:{border:"#E129F0",background:"#F0B3F5"}},{border:"#7C29F0",background:"#AD85E4",highlight:{border:"#7C29F0",background:"#D3BDF0"},hover:{border:"#7C29F0",background:"#D3BDF0"}},{border:"#C37F00",background:"#FFA807",highlight:{border:"#C37F00",background:"#FFCA66"},hover:{border:"#C37F00",background:"#FFCA66"}},{border:"#4220FB",background:"#6E6EFD",highlight:{border:"#4220FB",background:"#9B9BFD"},hover:{border:"#4220FB",background:"#9B9BFD"}},{border:"#FD5A77",background:"#FFC0CB",highlight:{border:"#FD5A77",background:"#FFD1D9"},hover:{border:"#FD5A77",background:"#FFD1D9"}},{border:"#4AD63A",background:"#C2FABC",highlight:{border:"#4AD63A",background:"#E6FFE3"},hover:{border:"#4AD63A",background:"#E6FFE3"}},{border:"#990000",background:"#EE0000",highlight:{border:"#BB0000",background:"#FF3333"},hover:{border:"#BB0000",background:"#FF3333"}},{border:"#FF6000",background:"#FF6000",highlight:{border:"#FF6000",background:"#FF6000"},hover:{border:"#FF6000",background:"#FF6000"}},{border:"#97C2FC",background:"#2B7CE9",highlight:{border:"#D2E5FF",background:"#2B7CE9"},hover:{border:"#D2E5FF",background:"#2B7CE9"}},{border:"#399605",background:"#255C03",highlight:{border:"#399605",background:"#255C03"},hover:{border:"#399605",background:"#255C03"}},{border:"#B70054",background:"#FF007E",highlight:{border:"#B70054",background:"#FF007E"},hover:{border:"#B70054",background:"#FF007E"}},{border:"#AD85E4",background:"#7C29F0",highlight:{border:"#D3BDF0",background:"#7C29F0"},hover:{border:"#D3BDF0",background:"#7C29F0"}},{border:"#4557FA",background:"#000EA1",highlight:{border:"#6E6EFD",background:"#000EA1"},hover:{border:"#6E6EFD",background:"#000EA1"}},{border:"#FFC0CB",background:"#FD5A77",highlight:{border:"#FFD1D9",background:"#FD5A77"},hover:{border:"#FFD1D9",background:"#FD5A77"}},{border:"#C2FABC",background:"#74D66A",highlight:{border:"#E6FFE3",background:"#74D66A"},hover:{border:"#E6FFE3",background:"#74D66A"}},{border:"#EE0000",background:"#990000",highlight:{border:"#FF3333",background:"#BB0000"},hover:{border:"#FF3333",background:"#BB0000"}}],this.options={},this.defaultOptions={useDefaultGroups:!0},Object.assign(this.options,this.defaultOptions)}setOptions(e){let t=["useDefaultGroups"];if(e!==void 0){for(let i in e)if(Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)===-1){let s=e[i];this.add(i,s)}}}clear(){this._groups=new Map,this._groupNames=[]}get(e,t=!0){let i=this._groups.get(e);if(i===void 0&&t)if(this.options.useDefaultGroups===!1&&this._groupNames.length>0){let s=this._groupIndex%this._groupNames.length;++this._groupIndex,i={},i.color=this._groups.get(this._groupNames[s]),this._groups.set(e,i)}else{let s=this._defaultIndex%this._defaultGroups.length;this._defaultIndex++,i={},i.color=this._defaultGroups[s],this._groups.set(e,i)}return i}add(e,t){return this._groups.has(e)||this._groupNames.push(e),this._groups.set(e,t),t}};function Ii(n,e){let t=["node","edge","label"],i=!0,s=Ce(e,"chosen");if(typeof s=="boolean")i=s;else if(typeof s=="object"){if(t.indexOf(n)===-1)throw new Error("choosify: subOption '"+n+"' should be one of '"+t.join("', '")+"'");let o=Ce(e,["chosen",n]);(typeof o=="boolean"||typeof o=="function")&&(i=o)}return i}function Pi(n,e,t){if(n.width<=0||n.height<=0)return!1;if(t!==void 0){let o={x:e.x-t.x,y:e.y-t.y};if(t.angle!==0){let r=-t.angle;e={x:Math.cos(r)*o.x-Math.sin(r)*o.y,y:Math.sin(r)*o.x+Math.cos(r)*o.y}}else e=o}let i=n.x+n.width,s=n.y+n.width;return n.lefte.x&&n.tope.y}function Xt(n){return typeof n=="string"&&n!==""}function To(n,e,t,i){let s=i.x,o=i.y;if(typeof i.distanceToBorder=="function"){let r=i.distanceToBorder(n,e),a=Math.sin(e)*r,d=Math.cos(e)*r;d===r?(s+=r,o=i.y):a===r?(s=i.x,o-=r):(s+=d,o-=a)}else i.shape.width>i.shape.height?(s=i.x+i.shape.width*.5,o=i.y-t):(s=i.x+t,o=i.y-i.shape.height*.5);return{x:s,y:o}}var ko=class{constructor(e){this.measureText=e,this.current=0,this.width=0,this.height=0,this.lines=[]}_add(e,t,i="normal"){this.lines[e]===void 0&&(this.lines[e]={width:0,height:0,blocks:[]});let s=t;(t===void 0||t==="")&&(s=" ");let o=this.measureText(s,i),r=Object.assign({},o.values);r.text=t,r.width=o.width,r.mod=i,(t===void 0||t==="")&&(r.width=0),this.lines[e].blocks.push(r),this.lines[e].width+=r.width}curWidth(){let e=this.lines[this.current];return e===void 0?0:e.width}append(e,t="normal"){this._add(this.current,e,t)}newLine(e,t="normal"){this._add(this.current,e,t),this.current++}determineLineHeights(){for(let e=0;ee&&(e=s.width),t+=s.height}this.width=e,this.height=t}removeEmptyBlocks(){let e=[];for(let t=0;t"://,""://,""://,"":/<\/b>/,"":/<\/i>/,"":/<\/code>/,"*":/\*/,_:/_/,"`":/`/,afterBold:/[^*]/,afterItal:/[^_]/,afterMono:/[^`]/},Mi=class{constructor(e){this.text=e,this.bold=!1,this.ital=!1,this.mono=!1,this.spacing=!1,this.position=0,this.buffer="",this.modStack=[],this.blocks=[]}mod(){return this.modStack.length===0?"normal":this.modStack[0]}modName(){if(this.modStack.length===0)return"normal";if(this.modStack[0]==="mono")return"mono";if(this.bold&&this.ital)return"boldital";if(this.bold)return"bold";if(this.ital)return"ital"}emitBlock(){this.spacing&&(this.add(" "),this.spacing=!1),this.buffer.length>0&&(this.blocks.push({text:this.buffer,mod:this.modName()}),this.buffer="")}add(e){e===" "&&(this.spacing=!0),this.spacing&&(this.buffer+=" ",this.spacing=!1),e!=" "&&(this.buffer+=e)}parseWS(e){return/[ \t]/.test(e)?(this.mono?this.add(e):this.spacing=!0,!0):!1}setTag(e){this.emitBlock(),this[e]=!0,this.modStack.unshift(e)}unsetTag(e){this.emitBlock(),this[e]=!1,this.modStack.shift()}parseStartTag(e,t){return!this.mono&&!this[e]&&this.match(t)?(this.setTag(e),!0):!1}match(e,t=!0){let[i,s]=this.prepareRegExp(e),o=i.test(this.text.substr(this.position,s));return o&&t&&(this.position+=s-1),o}parseEndTag(e,t,i){let s=this.mod()===e;return e==="mono"?s=s&&this.mono:s=s&&!this.mono,s&&this.match(t)?(i!==void 0?(this.position===this.text.length-1||this.match(i,!1))&&this.unsetTag(e):this.unsetTag(e),!0):!1}replace(e,t){return this.match(e)?(this.add(t),this.position+=length-1,!0):!1}prepareRegExp(e){let t,i;if(e instanceof RegExp)i=e,t=1;else{let s=Da[e];s!==void 0?i=s:i=new RegExp(e),t=e.length}return[i,t]}},So=class{constructor(e,t,i,s){this.ctx=e,this.parent=t,this.selected=i,this.hover=s;let o=(r,a)=>{if(r===void 0)return 0;let d=this.parent.getFormattingValues(e,i,s,a),h=0;return r!==""&&(h=this.ctx.measureText(r).width),{width:h,values:d}};this.lines=new ko(o)}process(e){if(!Xt(e))return this.lines.finalize();let t=this.parent.fontOptions;e=e.replace(/\r\n/g,` +`;)Z();n=!0}}if(z==="/"&&st()==="/"){for(;z!=""&&z!=` +`;)Z();n=!0}if(z==="/"&&st()==="*"){for(;z!="";)if(z==="*"&&st()==="/"){Z(),Z();break}else Z();n=!0}for(;z===" "||z===" "||z===` +`||z==="\r";)Z()}while(n);if(z===""){oe=te.DELIMITER;return}var t=z+st();if(uo[t]){oe=te.DELIMITER,M=t,Z(),Z();return}if(uo[z]){oe=te.DELIMITER,M=z,Z();return}if(fo(z)||z==="-"){for(M+=z,Z();fo(z);)M+=z,Z();M==="false"?M=!1:M==="true"?M=!0:isNaN(Number(M))||(M=Number(M)),oe=te.IDENTIFIER;return}if(z==='"'){for(Z();z!=""&&(z!='"'||z==='"'&&st()==='"');)z==='"'?(M+=z,Z()):z==="\\"&&st()==="n"?(M+=` +`,Z()):M+=z,Z();if(z!='"')throw ie('End of string " expected');Z(),oe=te.IDENTIFIER;return}for(oe=te.UNKNOWN;z!="";)M+=z,Z();throw new SyntaxError('Syntax error in part "'+vo(M,30)+'"')}function na(){var n={};if(ia(),V(),M==="strict"&&(n.strict=!0,V()),(M==="graph"||M==="digraph")&&(n.type=M,V()),oe===te.IDENTIFIER&&(n.id=M,V()),M!="{")throw ie("Angle bracket { expected");if(V(),mo(n),M!="}")throw ie("Angle bracket } expected");if(V(),M!=="")throw ie("End of file expected");return V(),delete n.node,delete n.edge,delete n.graph,n}function mo(n){for(;M!==""&&M!="}";)ra(n),M===";"&&V()}function ra(n){var e=yo(n);if(e){bo(n,e);return}var t=aa(n);if(!t){if(oe!=te.IDENTIFIER)throw ie("Identifier expected");var i=M;if(V(),M==="="){if(V(),oe!=te.IDENTIFIER)throw ie("Identifier expected");n[i]=M,V()}else da(n,i)}}function yo(n){var e=null;if(M==="subgraph"&&(e={},e.type="subgraph",V(),oe===te.IDENTIFIER&&(e.id=M,V())),M==="{"){if(V(),e||(e={}),e.parent=n,e.node=n.node,e.edge=n.edge,e.graph=n.graph,mo(e),M!="}")throw ie("Angle bracket } expected");V(),delete e.node,delete e.edge,delete e.graph,delete e.parent,n.subgraphs||(n.subgraphs=[]),n.subgraphs.push(e)}return e}function aa(n){return M==="node"?(V(),n.node=xt(),"node"):M==="edge"?(V(),n.edge=xt(),"edge"):M==="graph"?(V(),n.graph=xt(),"graph"):null}function da(n,e){var t={id:e},i=xt();i&&(t.attr=i),po(n,t),bo(n,e)}function bo(n,e){for(;M==="->"||M==="--";){var t,i=M;V();var s=yo(n);if(s)t=s;else{if(oe!=te.IDENTIFIER)throw ie("Identifier or subgraph expected");t=M,po(n,{id:t}),V()}var o=xt(),r=go(n,e,t,i,o);oa(n,r),e=t}}function xt(){for(var n,e=null,t={dashed:!0,solid:!1,dotted:[1,5]},i={dot:"circle",box:"box",crow:"crow",curve:"curve",icurve:"inv_curve",normal:"triangle",inv:"inv_triangle",diamond:"diamond",tee:"bar",vee:"vee"},s=new Array,o=new Array;M==="[";){for(V(),e={};M!==""&&M!="]";){if(oe!=te.IDENTIFIER)throw ie("Attribute name expected");var r=M;if(V(),M!="=")throw ie("Equal sign = expected");if(V(),oe!=te.IDENTIFIER)throw ie("Attribute value expected");var a=M;r==="style"&&(a=t[a]);var d;r==="arrowhead"&&(d=i[a],r="arrows",a={to:{enabled:!0,type:d}}),r==="arrowtail"&&(d=i[a],r="arrows",a={from:{enabled:!0,type:d}}),s.push({attr:e,name:r,value:a}),o.push(r),V(),M==","&&V()}if(M!="]")throw ie("Bracket ] expected");V()}if(o.includes("dir")){var h={};for(h.arrows={},n=0;n"&&(o.arrows="to"),o};e.edges.forEach(function(s){var o,r;s.from instanceof Object?o=s.from.nodes:o={id:s.from},s.to instanceof Object?r=s.to.nodes:r={id:s.to},s.from instanceof Object&&s.from.edges&&s.from.edges.forEach(function(a){var d=i(a);t.edges.push(d)}),ha(o,r,function(a,d){var h=go(t,a.id,d.id,s.type,s.attr),l=i(h);t.edges.push(l)}),s.to instanceof Object&&s.to.edges&&s.to.edges.forEach(function(a){var d=i(a);t.edges.push(d)})})}return e.attr&&(t.options=e.attr),t}function ca(n,e){let t={edges:{inheritColor:!1},nodes:{fixed:!1,parseColor:!1}};e!=null&&(e.fixed!=null&&(t.nodes.fixed=e.fixed),e.parseColor!=null&&(t.nodes.parseColor=e.parseColor),e.inheritColor!=null&&(t.edges.inheritColor=e.inheritColor));let s=n.edges.map(r=>{let a={from:r.source,id:r.id,to:r.target};return r.attributes!=null&&(a.attributes=r.attributes),r.label!=null&&(a.label=r.label),r.attributes!=null&&r.attributes.title!=null&&(a.title=r.attributes.title),r.type==="Directed"&&(a.arrows="to"),r.color&&t.edges.inheritColor===!1&&(a.color=r.color),a});return{nodes:n.nodes.map(r=>{let a={id:r.id,fixed:t.nodes.fixed&&r.x!=null&&r.y!=null};return r.attributes!=null&&(a.attributes=r.attributes),r.label!=null&&(a.label=r.label),r.size!=null&&(a.size=r.size),r.attributes!=null&&r.attributes.title!=null&&(a.title=r.attributes.title),r.title!=null&&(a.title=r.title),r.x!=null&&(a.x=r.x),r.y!=null&&(a.y=r.y),r.color!=null&&(t.nodes.parseColor===!0?a.color=r.color:a.color={background:r.color,border:r.color,highlight:{background:r.color,border:r.color},hover:{background:r.color,border:r.color}}),a}),edges:s}}var ua={addDescription:"Click in an empty space to place a new node.",addEdge:"Add Edge",addNode:"Add Node",back:"Back",close:"Close",createEdgeError:"Cannot link edges to a cluster.",del:"Delete selected",deleteClusterError:"Clusters cannot be deleted.",edgeDescription:"Click on a node and drag the edge to another node to connect them.",edit:"Edit",editClusterError:"Clusters cannot be edited.",editEdge:"Edit Edge",editEdgeDescription:"Click on the control points and drag them to a node to connect to it.",editNode:"Edit Node"},fa={addDescription:"Klicke auf eine freie Stelle, um einen neuen Knoten zu plazieren.",addEdge:"Kante hinzuf\xFCgen",addNode:"Knoten hinzuf\xFCgen",back:"Zur\xFCck",close:"Schlie\xDFen",createEdgeError:"Es ist nicht m\xF6glich, Kanten mit Clustern zu verbinden.",del:"L\xF6sche Auswahl",deleteClusterError:"Cluster k\xF6nnen nicht gel\xF6scht werden.",edgeDescription:"Klicke auf einen Knoten und ziehe die Kante zu einem anderen Knoten, um diese zu verbinden.",edit:"Editieren",editClusterError:"Cluster k\xF6nnen nicht editiert werden.",editEdge:"Kante editieren",editEdgeDescription:"Klicke auf die Verbindungspunkte und ziehe diese auf einen Knoten, um sie zu verbinden.",editNode:"Knoten editieren"},pa={addDescription:"Haga clic en un lugar vac\xEDo para colocar un nuevo nodo.",addEdge:"A\xF1adir arista",addNode:"A\xF1adir nodo",back:"Atr\xE1s",close:"Cerrar",createEdgeError:"No se puede conectar una arista a un grupo.",del:"Eliminar selecci\xF3n",deleteClusterError:"No es posible eliminar grupos.",edgeDescription:"Haga clic en un nodo y arrastre la arista hacia otro nodo para conectarlos.",edit:"Editar",editClusterError:"No es posible editar grupos.",editEdge:"Editar arista",editEdgeDescription:"Haga clic en un punto de control y arrastrelo a un nodo para conectarlo.",editNode:"Editar nodo"},ga={addDescription:"Clicca per aggiungere un nuovo nodo",addEdge:"Aggiungi un vertice",addNode:"Aggiungi un nodo",back:"Indietro",close:"Chiudere",createEdgeError:"Non si possono collegare vertici ad un cluster",del:"Cancella la selezione",deleteClusterError:"I cluster non possono essere cancellati",edgeDescription:"Clicca su un nodo e trascinalo ad un altro nodo per connetterli.",edit:"Modifica",editClusterError:"I clusters non possono essere modificati.",editEdge:"Modifica il vertice",editEdgeDescription:"Clicca sui Punti di controllo e trascinali ad un nodo per connetterli.",editNode:"Modifica il nodo"},ma={addDescription:"Klik op een leeg gebied om een nieuwe node te maken.",addEdge:"Link toevoegen",addNode:"Node toevoegen",back:"Terug",close:"Sluiten",createEdgeError:"Kan geen link maken naar een cluster.",del:"Selectie verwijderen",deleteClusterError:"Clusters kunnen niet worden verwijderd.",edgeDescription:"Klik op een node en sleep de link naar een andere node om ze te verbinden.",edit:"Wijzigen",editClusterError:"Clusters kunnen niet worden aangepast.",editEdge:"Link wijzigen",editEdgeDescription:"Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.",editNode:"Node wijzigen"},ya={addDescription:"Clique em um espa\xE7o em branco para adicionar um novo n\xF3",addEdge:"Adicionar aresta",addNode:"Adicionar n\xF3",back:"Voltar",close:"Fechar",createEdgeError:"N\xE3o foi poss\xEDvel linkar arestas a um cluster.",del:"Remover selecionado",deleteClusterError:"Clusters n\xE3o puderam ser removidos.",edgeDescription:"Clique em um n\xF3 e arraste a aresta at\xE9 outro n\xF3 para conect\xE1-los",edit:"Editar",editClusterError:"Clusters n\xE3o puderam ser editados.",editEdge:"Editar aresta",editEdgeDescription:"Clique nos pontos de controle e os arraste para um n\xF3 para conect\xE1-los",editNode:"Editar n\xF3"},ba={addDescription:"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u0432 \u0441\u0432\u043E\u0431\u043E\u0434\u043D\u043E\u0435 \u043C\u0435\u0441\u0442\u043E, \u0447\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043D\u043E\u0432\u044B\u0439 \u0443\u0437\u0435\u043B.",addEdge:"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0440\u0435\u0431\u0440\u043E",addNode:"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0443\u0437\u0435\u043B",back:"\u041D\u0430\u0437\u0430\u0434",close:"\u0417\u0430\u043A\u0440\u044B\u0432\u0430\u0442\u044C",createEdgeError:"\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u044C \u0440\u0435\u0431\u0440\u0430 \u0432 \u043A\u043B\u0430\u0441\u0442\u0435\u0440.",del:"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0435",deleteClusterError:"\u041A\u043B\u0430\u0441\u0442\u0435\u0440\u044B \u043D\u0435 \u043C\u043E\u0433\u0443\u0442 \u0431\u044B\u0442\u044C \u0443\u0434\u0430\u043B\u0435\u043D\u044B",edgeDescription:"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043D\u0430 \u0443\u0437\u0435\u043B \u0438 \u043F\u0440\u043E\u0442\u044F\u043D\u0438\u0442\u0435 \u0440\u0435\u0431\u0440\u043E \u043A \u0434\u0440\u0443\u0433\u043E\u043C\u0443 \u0443\u0437\u043B\u0443, \u0447\u0442\u043E\u0431\u044B \u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u044C \u0438\u0445.",edit:"\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C",editClusterError:"\u041A\u043B\u0430\u0441\u0442\u0435\u0440\u044B \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B \u0434\u043B\u044F \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F.",editEdge:"\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0435\u0431\u0440\u043E",editEdgeDescription:"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043D\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u044B\u0435 \u0442\u043E\u0447\u043A\u0438 \u0438 \u043F\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0438\u0445 \u0432 \u0443\u0437\u0435\u043B, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043A \u043D\u0435\u043C\u0443.",editNode:"\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0443\u0437\u0435\u043B"},va={addDescription:"\u5355\u51FB\u7A7A\u767D\u5904\u653E\u7F6E\u65B0\u8282\u70B9\u3002",addEdge:"\u6DFB\u52A0\u8FDE\u63A5\u7EBF",addNode:"\u6DFB\u52A0\u8282\u70B9",back:"\u8FD4\u56DE",close:"\u95DC\u9589",createEdgeError:"\u65E0\u6CD5\u5C06\u8FDE\u63A5\u7EBF\u8FDE\u63A5\u5230\u7FA4\u96C6\u3002",del:"\u5220\u9664\u9009\u5B9A",deleteClusterError:"\u65E0\u6CD5\u5220\u9664\u7FA4\u96C6\u3002",edgeDescription:"\u5355\u51FB\u67D0\u4E2A\u8282\u70B9\u5E76\u5C06\u8BE5\u8FDE\u63A5\u7EBF\u62D6\u52A8\u5230\u53E6\u4E00\u4E2A\u8282\u70B9\u4EE5\u8FDE\u63A5\u5B83\u4EEC\u3002",edit:"\u7F16\u8F91",editClusterError:"\u65E0\u6CD5\u7F16\u8F91\u7FA4\u96C6\u3002",editEdge:"\u7F16\u8F91\u8FDE\u63A5\u7EBF",editEdgeDescription:"\u5355\u51FB\u63A7\u5236\u8282\u70B9\u5E76\u5C06\u5B83\u4EEC\u62D6\u5230\u8282\u70B9\u4E0A\u8FDE\u63A5\u3002",editNode:"\u7F16\u8F91\u8282\u70B9"},wa={addDescription:"K\u043B\u0456\u043A\u043D\u0456\u0442\u044C \u043D\u0430 \u0432\u0456\u043B\u044C\u043D\u0435 \u043C\u0456\u0441\u0446\u0435, \u0449\u043E\u0431 \u0434\u043E\u0434\u0430\u0442\u0438 \u043D\u043E\u0432\u0438\u0439 \u0432\u0443\u0437\u043E\u043B.",addEdge:"\u0414\u043E\u0434\u0430\u0442\u0438 \u043A\u0440\u0430\u0439",addNode:"\u0414\u043E\u0434\u0430\u0442\u0438 \u0432\u0443\u0437\u043E\u043B",back:"\u041D\u0430\u0437\u0430\u0434",close:"\u0417\u0430\u043A\u0440\u0438\u0442\u0438",createEdgeError:"\u041D\u0435 \u043C\u043E\u0436\u043B\u0438\u0432\u043E \u043E\u0431'\u0454\u0434\u043D\u0430\u0442\u0438 \u043A\u0440\u0430\u0457 \u0432 \u0433\u0440\u0443\u043F\u0443.",del:"\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438 \u043E\u0431\u0440\u0430\u043D\u0435",deleteClusterError:"\u0413\u0440\u0443\u043F\u0438 \u043D\u0435 \u043C\u043E\u0436\u0443\u0442\u044C \u0431\u0443\u0442\u0438 \u0432\u0438\u0434\u0430\u043B\u0435\u043D\u0456.",edgeDescription:"\u041A\u043B\u0456\u043A\u043D\u0456\u0442\u044C \u043D\u0430 \u0432\u0443\u0437\u043E\u043B \u0456 \u043F\u0435\u0440\u0435\u0442\u044F\u0433\u043D\u0456\u0442\u044C \u043A\u0440\u0430\u0439 \u0434\u043E \u0456\u043D\u0448\u043E\u0433\u043E \u0432\u0443\u0437\u043B\u0430, \u0449\u043E\u0431 \u0457\u0445 \u0437'\u0454\u0434\u043D\u0430\u0442\u0438.",edit:"\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438",editClusterError:"\u0413\u0440\u0443\u043F\u0438 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0456 \u0434\u043B\u044F \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u043D\u043D\u044F.",editEdge:"\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u043A\u0440\u0430\u0439",editEdgeDescription:"\u041A\u043B\u0456\u043A\u043D\u0456\u0442\u044C \u043D\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0456 \u0442\u043E\u0447\u043A\u0438 \u0456 \u043F\u0435\u0440\u0435\u0442\u044F\u0433\u043D\u0456\u0442\u044C \u0457\u0445 \u0443 \u0432\u0443\u0437\u043E\u043B, \u0449\u043E\u0431 \u043F\u0456\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u0438\u0441\u044F \u0434\u043E \u043D\u044C\u043E\u0433\u043E.",editNode:"\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u0432\u0443\u0437\u043E\u043B"},_a={addDescription:"Cliquez dans un endroit vide pour placer un n\u0153ud.",addEdge:"Ajouter un lien",addNode:"Ajouter un n\u0153ud",back:"Retour",close:"Fermer",createEdgeError:"Impossible de cr\xE9er un lien vers un cluster.",del:"Effacer la s\xE9lection",deleteClusterError:"Les clusters ne peuvent pas \xEAtre effac\xE9s.",edgeDescription:"Cliquez sur un n\u0153ud et glissez le lien vers un autre n\u0153ud pour les connecter.",edit:"\xC9diter",editClusterError:"Les clusters ne peuvent pas \xEAtre \xE9dit\xE9s.",editEdge:"\xC9diter le lien",editEdgeDescription:"Cliquez sur les points de contr\xF4le et glissez-les pour connecter un n\u0153ud.",editNode:"\xC9diter le n\u0153ud"},Ea={addDescription:"Kluknut\xEDm do pr\xE1zdn\xE9ho prostoru m\u016F\u017Eete p\u0159idat nov\xFD vrchol.",addEdge:"P\u0159idat hranu",addNode:"P\u0159idat vrchol",back:"Zp\u011Bt",close:"Zav\u0159\xEDt",createEdgeError:"Nelze p\u0159ipojit hranu ke shluku.",del:"Smazat v\xFDb\u011Br",deleteClusterError:"Nelze mazat shluky.",edgeDescription:"P\u0159eta\u017Een\xEDm z jednoho vrcholu do druh\xE9ho m\u016F\u017Eete spojit tyto vrcholy novou hranou.",edit:"Upravit",editClusterError:"Nelze upravovat shluky.",editEdge:"Upravit hranu",editEdgeDescription:"P\u0159eta\u017Een\xEDm kontroln\xEDho vrcholu hrany ji m\u016F\u017Eete p\u0159ipojit k jin\xE9mu vrcholu.",editNode:"Upravit vrchol"},xa=Object.freeze({__proto__:null,en:ua,de:fa,es:pa,it:ga,nl:ma,pt:ya,ru:ba,cn:va,uk:wa,fr:_a,cs:Ea});function Ca(n,e){try{let[t,i]=e.split(/[-_ /]/,2),s=t!=null?t.toLowerCase():null,o=i!=null?i.toUpperCase():null;if(s&&o){let r=s+"-"+o;if(Object.prototype.hasOwnProperty.call(n,r))return r;console.warn(`Unknown variant ${o} of language ${s}.`)}if(s){let r=s;if(Object.prototype.hasOwnProperty.call(n,r))return r;console.warn(`Unknown language ${s}`)}return console.warn(`Unknown locale ${e}, falling back to English.`),"en"}catch(t){return console.error(t),console.warn(`Unexpected error while normalizing locale ${e}, falling back to English.`),"en"}}var _o=class{constructor(){this.NUM_ITERATIONS=4,this.image=new Image,this.canvas=document.createElement("canvas")}init(){if(this.initialized())return;this.src=this.image.src;let e=this.image.width,t=this.image.height;this.width=e,this.height=t;let i=Math.floor(t/2),s=Math.floor(t/4),o=Math.floor(t/8),r=Math.floor(t/16),a=Math.floor(e/2),d=Math.floor(e/4),h=Math.floor(e/8),l=Math.floor(e/16);this.canvas.width=3*d,this.canvas.height=i,this.coordinates=[[0,0,a,i],[a,0,d,s],[a,s,h,o],[5*h,s,l,r]],this._fillMipMap()}initialized(){return this.coordinates!==void 0}_fillMipMap(){let e=this.canvas.getContext("2d"),t=this.coordinates[0];e.drawImage(this.image,t[0],t[1],t[2],t[3]);for(let i=1;i2){t*=.5;let a=0;for(;t>2&&a=this.NUM_ITERATIONS&&(a=this.NUM_ITERATIONS-1);let d=this.coordinates[a];e.drawImage(this.canvas,d[0],d[1],d[2],d[3],i,s,o,r)}else e.drawImage(this.image,i,s,o,r)}},Eo=class{constructor(e){this.images={},this.imageBroken={},this.callback=e}_tryloadBrokenUrl(e,t,i){if(!(e===void 0||i===void 0)){if(t===void 0){console.warn("No broken url image defined");return}i.image.onerror=()=>{console.error("Could not load brokenImage:",t)},i.image.src=t}}_redrawWithImage(e){this.callback&&this.callback(e)}load(e,t){let i=this.images[e];if(i)return i;let s=new _o;return this.images[e]=s,s.image.onload=()=>{this._fixImageCoordinates(s.image),s.init(),this._redrawWithImage(s)},s.image.onerror=()=>{console.error("Could not load image:",e),this._tryloadBrokenUrl(e,t,s)},s.image.src=e,s}_fixImageCoordinates(e){e.width===0&&(document.body.appendChild(e),e.width=e.offsetWidth,e.height=e.offsetHeight,document.body.removeChild(e))}},xo=class{constructor(){this.clear(),this._defaultIndex=0,this._groupIndex=0,this._defaultGroups=[{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},{border:"#FFA500",background:"#FFFF00",highlight:{border:"#FFA500",background:"#FFFFA3"},hover:{border:"#FFA500",background:"#FFFFA3"}},{border:"#FA0A10",background:"#FB7E81",highlight:{border:"#FA0A10",background:"#FFAFB1"},hover:{border:"#FA0A10",background:"#FFAFB1"}},{border:"#41A906",background:"#7BE141",highlight:{border:"#41A906",background:"#A1EC76"},hover:{border:"#41A906",background:"#A1EC76"}},{border:"#E129F0",background:"#EB7DF4",highlight:{border:"#E129F0",background:"#F0B3F5"},hover:{border:"#E129F0",background:"#F0B3F5"}},{border:"#7C29F0",background:"#AD85E4",highlight:{border:"#7C29F0",background:"#D3BDF0"},hover:{border:"#7C29F0",background:"#D3BDF0"}},{border:"#C37F00",background:"#FFA807",highlight:{border:"#C37F00",background:"#FFCA66"},hover:{border:"#C37F00",background:"#FFCA66"}},{border:"#4220FB",background:"#6E6EFD",highlight:{border:"#4220FB",background:"#9B9BFD"},hover:{border:"#4220FB",background:"#9B9BFD"}},{border:"#FD5A77",background:"#FFC0CB",highlight:{border:"#FD5A77",background:"#FFD1D9"},hover:{border:"#FD5A77",background:"#FFD1D9"}},{border:"#4AD63A",background:"#C2FABC",highlight:{border:"#4AD63A",background:"#E6FFE3"},hover:{border:"#4AD63A",background:"#E6FFE3"}},{border:"#990000",background:"#EE0000",highlight:{border:"#BB0000",background:"#FF3333"},hover:{border:"#BB0000",background:"#FF3333"}},{border:"#FF6000",background:"#FF6000",highlight:{border:"#FF6000",background:"#FF6000"},hover:{border:"#FF6000",background:"#FF6000"}},{border:"#97C2FC",background:"#2B7CE9",highlight:{border:"#D2E5FF",background:"#2B7CE9"},hover:{border:"#D2E5FF",background:"#2B7CE9"}},{border:"#399605",background:"#255C03",highlight:{border:"#399605",background:"#255C03"},hover:{border:"#399605",background:"#255C03"}},{border:"#B70054",background:"#FF007E",highlight:{border:"#B70054",background:"#FF007E"},hover:{border:"#B70054",background:"#FF007E"}},{border:"#AD85E4",background:"#7C29F0",highlight:{border:"#D3BDF0",background:"#7C29F0"},hover:{border:"#D3BDF0",background:"#7C29F0"}},{border:"#4557FA",background:"#000EA1",highlight:{border:"#6E6EFD",background:"#000EA1"},hover:{border:"#6E6EFD",background:"#000EA1"}},{border:"#FFC0CB",background:"#FD5A77",highlight:{border:"#FFD1D9",background:"#FD5A77"},hover:{border:"#FFD1D9",background:"#FD5A77"}},{border:"#C2FABC",background:"#74D66A",highlight:{border:"#E6FFE3",background:"#74D66A"},hover:{border:"#E6FFE3",background:"#74D66A"}},{border:"#EE0000",background:"#990000",highlight:{border:"#FF3333",background:"#BB0000"},hover:{border:"#FF3333",background:"#BB0000"}}],this.options={},this.defaultOptions={useDefaultGroups:!0},Object.assign(this.options,this.defaultOptions)}setOptions(e){let t=["useDefaultGroups"];if(e!==void 0){for(let i in e)if(Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)===-1){let s=e[i];this.add(i,s)}}}clear(){this._groups=new Map,this._groupNames=[]}get(e,t=!0){let i=this._groups.get(e);if(i===void 0&&t)if(this.options.useDefaultGroups===!1&&this._groupNames.length>0){let s=this._groupIndex%this._groupNames.length;++this._groupIndex,i={},i.color=this._groups.get(this._groupNames[s]),this._groups.set(e,i)}else{let s=this._defaultIndex%this._defaultGroups.length;this._defaultIndex++,i={},i.color=this._defaultGroups[s],this._groups.set(e,i)}return i}add(e,t){return this._groups.has(e)||this._groupNames.push(e),this._groups.set(e,t),t}};function Oi(n,e){let t=["node","edge","label"],i=!0,s=xe(e,"chosen");if(typeof s=="boolean")i=s;else if(typeof s=="object"){if(t.indexOf(n)===-1)throw new Error("choosify: subOption '"+n+"' should be one of '"+t.join("', '")+"'");let o=xe(e,["chosen",n]);(typeof o=="boolean"||typeof o=="function")&&(i=o)}return i}function Ii(n,e,t){if(n.width<=0||n.height<=0)return!1;if(t!==void 0){let o={x:e.x-t.x,y:e.y-t.y};if(t.angle!==0){let r=-t.angle;e={x:Math.cos(r)*o.x-Math.sin(r)*o.y,y:Math.sin(r)*o.x+Math.cos(r)*o.y}}else e=o}let i=n.x+n.width,s=n.y+n.width;return n.lefte.x&&n.tope.y}function Yt(n){return typeof n=="string"&&n!==""}function Co(n,e,t,i){let s=i.x,o=i.y;if(typeof i.distanceToBorder=="function"){let r=i.distanceToBorder(n,e),a=Math.sin(e)*r,d=Math.cos(e)*r;d===r?(s+=r,o=i.y):a===r?(s=i.x,o-=r):(s+=d,o-=a)}else i.shape.width>i.shape.height?(s=i.x+i.shape.width*.5,o=i.y-t):(s=i.x+t,o=i.y-i.shape.height*.5);return{x:s,y:o}}var To=class{constructor(e){this.measureText=e,this.current=0,this.width=0,this.height=0,this.lines=[]}_add(e,t,i="normal"){this.lines[e]===void 0&&(this.lines[e]={width:0,height:0,blocks:[]});let s=t;(t===void 0||t==="")&&(s=" ");let o=this.measureText(s,i),r=Object.assign({},o.values);r.text=t,r.width=o.width,r.mod=i,(t===void 0||t==="")&&(r.width=0),this.lines[e].blocks.push(r),this.lines[e].width+=r.width}curWidth(){let e=this.lines[this.current];return e===void 0?0:e.width}append(e,t="normal"){this._add(this.current,e,t)}newLine(e,t="normal"){this._add(this.current,e,t),this.current++}determineLineHeights(){for(let e=0;ee&&(e=s.width),t+=s.height}this.width=e,this.height=t}removeEmptyBlocks(){let e=[];for(let t=0;t"://,""://,""://,"":/<\/b>/,"":/<\/i>/,"":/<\/code>/,"*":/\*/,_:/_/,"`":/`/,afterBold:/[^*]/,afterItal:/[^_]/,afterMono:/[^`]/},Pi=class{constructor(e){this.text=e,this.bold=!1,this.ital=!1,this.mono=!1,this.spacing=!1,this.position=0,this.buffer="",this.modStack=[],this.blocks=[]}mod(){return this.modStack.length===0?"normal":this.modStack[0]}modName(){if(this.modStack.length===0)return"normal";if(this.modStack[0]==="mono")return"mono";if(this.bold&&this.ital)return"boldital";if(this.bold)return"bold";if(this.ital)return"ital"}emitBlock(){this.spacing&&(this.add(" "),this.spacing=!1),this.buffer.length>0&&(this.blocks.push({text:this.buffer,mod:this.modName()}),this.buffer="")}add(e){e===" "&&(this.spacing=!0),this.spacing&&(this.buffer+=" ",this.spacing=!1),e!=" "&&(this.buffer+=e)}parseWS(e){return/[ \t]/.test(e)?(this.mono?this.add(e):this.spacing=!0,!0):!1}setTag(e){this.emitBlock(),this[e]=!0,this.modStack.unshift(e)}unsetTag(e){this.emitBlock(),this[e]=!1,this.modStack.shift()}parseStartTag(e,t){return!this.mono&&!this[e]&&this.match(t)?(this.setTag(e),!0):!1}match(e,t=!0){let[i,s]=this.prepareRegExp(e),o=i.test(this.text.substr(this.position,s));return o&&t&&(this.position+=s-1),o}parseEndTag(e,t,i){let s=this.mod()===e;return e==="mono"?s=s&&this.mono:s=s&&!this.mono,s&&this.match(t)?(i!==void 0?(this.position===this.text.length-1||this.match(i,!1))&&this.unsetTag(e):this.unsetTag(e),!0):!1}replace(e,t){return this.match(e)?(this.add(t),this.position+=length-1,!0):!1}prepareRegExp(e){let t,i;if(e instanceof RegExp)i=e,t=1;else{let s=Ta[e];s!==void 0?i=s:i=new RegExp(e),t=e.length}return[i,t]}},ko=class{constructor(e,t,i,s){this.ctx=e,this.parent=t,this.selected=i,this.hover=s;let o=(r,a)=>{if(r===void 0)return 0;let d=this.parent.getFormattingValues(e,i,s,a),h=0;return r!==""&&(h=this.ctx.measureText(r).width),{width:h,values:d}};this.lines=new To(o)}process(e){if(!Yt(e))return this.lines.finalize();let t=this.parent.fontOptions;e=e.replace(/\r\n/g,` `),e=e.replace(/\r/g,` `);let i=String(e).split(` -`),s=i.length;if(t.multi)for(let o=0;o0)for(let a=0;a0)for(let o=0;o/&/.test(s)?(t.replace(t.text,"<","<")||t.replace(t.text,"&","&")||t.add("&"),!0):!1;for(;t.position")||t.parseStartTag("ital","")||t.parseStartTag("mono","")||t.parseEndTag("bold","")||t.parseEndTag("ital","")||t.parseEndTag("mono",""))||i(s)||t.add(s),t.position++}return t.emitBlock(),t.blocks}splitMarkdownBlocks(e){let t=new Mi(e),i=!0,s=o=>/\\/.test(o)?(t.positionthis.parent.fontOptions.maxWdt}getLongestFit(e){let t="",i=0;for(;i0;){let o=this.getLongestFit(s);if(o===0){let r=s[0],a=this.getLongestFitWord(r);this.lines.newLine(r.slice(0,a),t),s[0]=r.slice(a)}else{let r=o;s[o-1]===" "?o--:s[r]===" "&&r++;let a=s.slice(0,o).join("");o==s.length&&i?this.lines.append(a,t):this.lines.newLine(a,t),s=s.slice(r)}}}},Gt=["bold","ital","boldital","mono"],Ue=class{constructor(e,t,i=!1){this.body=e,this.pointToSelf=!1,this.baseSize=void 0,this.fontOptions={},this.setOptions(t),this.size={top:0,left:0,width:0,height:0,yLine:0},this.isEdgeLabel=i}setOptions(e){if(this.elementOptions=e,this.initFontOptions(e.font),Xt(e.label)?this.labelDirty=!0:e.label=void 0,e.font!==void 0&&e.font!==null){if(typeof e.font=="string")this.baseSize=this.fontOptions.size;else if(typeof e.font=="object"){let t=e.font.size;t!==void 0&&(this.baseSize=t)}}}initFontOptions(e){if(A(Gt,t=>{this.fontOptions[t]={}}),Ue.parseFontString(this.fontOptions,e)){this.fontOptions.vadjust=0;return}A(e,(t,i)=>{t!=null&&typeof t!="object"&&(this.fontOptions[i]=t)})}static parseFontString(e,t){if(!t||typeof t!="string")return!1;let i=t.split(" ");return e.size=+i[0].replace("px",""),e.face=i[1],e.color=i[2],!0}constrain(e){let t={constrainWidth:!1,maxWdt:-1,minWdt:-1,constrainHeight:!1,minHgt:-1,valign:"middle"},i=Ce(e,"widthConstraint");if(typeof i=="number")t.maxWdt=Number(i),t.minWdt=Number(i);else if(typeof i=="object"){let o=Ce(e,["widthConstraint","maximum"]);typeof o=="number"&&(t.maxWdt=Number(o));let r=Ce(e,["widthConstraint","minimum"]);typeof r=="number"&&(t.minWdt=Number(r))}let s=Ce(e,"heightConstraint");if(typeof s=="number")t.minHgt=Number(s);else if(typeof s=="object"){let o=Ce(e,["heightConstraint","minimum"]);typeof o=="number"&&(t.minHgt=Number(o));let r=Ce(e,["heightConstraint","valign"]);typeof r=="string"&&(r==="top"||r==="bottom")&&(t.valign=r)}return t}update(e,t){this.setOptions(e,!0),this.propagateFonts(t),j(this.fontOptions,this.constrain(t)),this.fontOptions.chooser=Ii("label",t)}adjustSizes(e){let t=e?e.right+e.left:0;this.fontOptions.constrainWidth&&(this.fontOptions.maxWdt-=t,this.fontOptions.minWdt-=t);let i=e?e.top+e.bottom:0;this.fontOptions.constrainHeight&&(this.fontOptions.minHgt-=i)}addFontOptionsToPile(e,t){for(let i=0;i{r!==void 0&&(Object.prototype.hasOwnProperty.call(t,a)||(Gt.indexOf(a)!==-1?t[a]={}:t[a]=r))})}return t}getFontOption(e,t,i){let s;for(let o=0;o{o[d]=a}),o.size=Number(o.size),o.vadjust=Number(o.vadjust)}}draw(e,t,i,s,o,r="middle"){if(this.elementOptions.label===void 0)return;let a=this.fontOptions.size*this.body.view.scale;this.elementOptions.label&&a=this.elementOptions.scaling.label.maxVisible&&(a=Number(this.elementOptions.scaling.label.maxVisible)/this.body.view.scale),this.calculateLabelSize(e,s,o,t,i,r),this._drawBackground(e),this._drawText(e,t,this.size.yLine,r,a))}_drawBackground(e){if(this.fontOptions.background!==void 0&&this.fontOptions.background!=="none"){e.fillStyle=this.fontOptions.background;let t=this.getSize();e.fillRect(t.left,t.top,t.width,t.height)}}_drawText(e,t,i,s="middle",o){[t,i]=this._setAlignment(e,t,i,s),e.textAlign="left",t=t-this.size.width/2,this.fontOptions.valign&&this.size.height>this.size.labelHeight&&(this.fontOptions.valign==="top"&&(i-=(this.size.height-this.size.labelHeight)/2),this.fontOptions.valign==="bottom"&&(i+=(this.size.height-this.size.labelHeight)/2));for(let r=0;r0&&(e.lineWidth=l.strokeWidth,e.strokeStyle=u,e.lineJoin="round"),e.fillStyle=c,l.strokeWidth>0&&e.strokeText(l.text,t+d,i+l.vadjust),e.fillText(l.text,t+d,i+l.vadjust),d+=l.width}i+=a.height}}}_setAlignment(e,t,i,s){if(this.isEdgeLabel&&this.fontOptions.align!=="horizontal"&&this.pointToSelf===!1){t=0,i=0;let o=2;this.fontOptions.align==="top"?(e.textBaseline="alphabetic",i-=2*o):this.fontOptions.align==="bottom"?(e.textBaseline="hanging",i+=2*o):e.textBaseline="middle"}else e.textBaseline=s;return[t,i]}_getColor(e,t,i){let s=e||"#000000",o=i||"#ffffff";if(t<=this.elementOptions.scaling.label.drawThreshold){let r=Math.max(0,Math.min(1,1-(this.elementOptions.scaling.label.drawThreshold-t)));s=re(s,r),o=re(o,r)}return[s,o]}getTextSize(e,t=!1,i=!1){return this._processLabel(e,t,i),{width:this.size.width,height:this.size.height,lineCount:this.lineCount}}getSize(){let e=2,t=this.size.left,i=this.size.top-.5*e;if(this.isEdgeLabel){let o=-this.size.width*.5;switch(this.fontOptions.align){case"middle":t=o,i=-this.size.height*.5;break;case"top":t=o,i=-(this.size.height+e);break;case"bottom":t=o,i=e;break}}return{left:t,top:i,width:this.size.width,height:this.size.height}}calculateLabelSize(e,t,i,s=0,o=0,r="middle"){this._processLabel(e,t,i),this.size.left=s-this.size.width*.5,this.size.top=o-this.size.height*.5,this.size.yLine=o+(1-this.lineCount)*.5*this.fontOptions.size,r==="hanging"&&(this.size.top+=.5*this.fontOptions.size,this.size.top+=4,this.size.yLine+=4)}getFormattingValues(e,t,i,s){let o=function(d,h,l){return h==="normal"?l==="mod"?"":d[l]:d[h][l]!==void 0?d[h][l]:d[l]},r={color:o(this.fontOptions,s,"color"),size:o(this.fontOptions,s,"size"),face:o(this.fontOptions,s,"face"),mod:o(this.fontOptions,s,"mod"),vadjust:o(this.fontOptions,s,"vadjust"),strokeWidth:this.fontOptions.strokeWidth,strokeColor:this.fontOptions.strokeColor};(t||i)&&(s==="normal"&&this.fontOptions.chooser===!0&&this.elementOptions.labelHighlightBold?r.mod="bold":typeof this.fontOptions.chooser=="function"&&this.fontOptions.chooser(r,this.elementOptions.id,t,i));let a="";return r.mod!==void 0&&r.mod!==""&&(a+=r.mod+" "),a+=r.size+"px "+r.face,e.font=a.replace(/"/g,""),r.font=e.font,r.height=r.size,r}differentState(e,t){return e!==this.selectedState||t!==this.hoverState}_processLabelText(e,t,i,s){return new So(e,this,t,i).process(s)}_processLabel(e,t,i){if(this.labelDirty===!1&&!this.differentState(t,i))return;let s=this._processLabelText(e,t,i,this.elementOptions.label);this.fontOptions.minWdt>0&&s.width0&&s.height0&&(this.enableBorderDashes(e,t),e.stroke(),this.disableBorderDashes(e,t)),e.restore()}performFill(e,t){e.save(),e.fillStyle=t.color,this.enableShadow(e,t),e.fill(),this.disableShadow(e,t),e.restore(),this.performStroke(e,t)}_addBoundingBoxMargin(e){this.boundingBox.left-=e,this.boundingBox.top-=e,this.boundingBox.bottom+=e,this.boundingBox.right+=e}_updateBoundingBox(e,t,i,s,o){i!==void 0&&this.resize(i,s,o),this.left=e-this.width/2,this.top=t-this.height/2,this.boundingBox.left=this.left,this.boundingBox.top=this.top,this.boundingBox.bottom=this.top+this.height,this.boundingBox.right=this.left+this.width}updateBoundingBox(e,t,i,s,o){this._updateBoundingBox(e,t,i,s,o)}getDimensionsFromLabel(e,t,i){this.textSize=this.labelModule.getTextSize(e,t,i);let s=this.textSize.width,o=this.textSize.height,r=14;return s===0&&(s=r,o=r),{width:s,height:o}}},Oo=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t=this.selected,i=this.hover){if(this.needsRefresh(t,i)){let s=this.getDimensionsFromLabel(e,t,i);this.width=s.width+this.margin.right+this.margin.left,this.height=s.height+this.margin.top+this.margin.bottom,this.radius=this.width/2}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this.initContextForDraw(e,r),ao(e,this.left,this.top,this.width,this.height,r.borderRadius),this.performFill(e,r),this.updateBoundingBox(t,i,e,s,o),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,s,o)}updateBoundingBox(e,t,i,s,o){this._updateBoundingBox(e,t,i,s,o);let r=this.options.shapeProperties.borderRadius;this._addBoundingBoxMargin(r)}distanceToBorder(e,t){e&&this.resize(e);let i=this.options.borderWidth;return Math.min(Math.abs(this.width/2/Math.cos(t)),Math.abs(this.height/2/Math.sin(t)))+i}},Kt=class extends De{constructor(e,t,i){super(e,t,i);this.labelOffset=0,this.selected=!1}setOptions(e,t,i){this.options=e,t===void 0&&i===void 0||this.setImages(t,i)}setImages(e,t){t&&this.selected?(this.imageObj=t,this.imageObjAlt=e):(this.imageObj=e,this.imageObjAlt=t)}switchImages(e){let t=e&&!this.selected||!e&&this.selected;if(this.selected=e,this.imageObjAlt!==void 0&&t){let i=this.imageObj;this.imageObj=this.imageObjAlt,this.imageObjAlt=i}}_getImagePadding(){let e={top:0,right:0,bottom:0,left:0};if(this.options.imagePadding){let t=this.options.imagePadding;typeof t=="object"?(e.top=t.top,e.right=t.right,e.bottom=t.bottom,e.left=t.left):(e.top=t,e.right=t,e.bottom=t,e.left=t)}return e}_resizeImage(){let e,t;if(this.options.shapeProperties.useImageSize===!1){let i=1,s=1;this.imageObj.width&&this.imageObj.height&&(this.imageObj.width>this.imageObj.height?i=this.imageObj.width/this.imageObj.height:s=this.imageObj.height/this.imageObj.width),e=this.options.size*2*i,t=this.options.size*2*s}else{let i=this._getImagePadding();e=this.imageObj.width+i.left+i.right,t=this.imageObj.height+i.top+i.bottom}this.width=e,this.height=t,this.radius=.5*this.width}_drawRawCircle(e,t,i,s){this.initContextForDraw(e,s),Ti(e,t,i,s.size),this.performFill(e,s)}_drawImageAtPosition(e,t){if(this.imageObj.width!=0){e.globalAlpha=t.opacity!==void 0?t.opacity:1,this.enableShadow(e,t);let i=1;this.options.shapeProperties.interpolation===!0&&(i=this.imageObj.width/this.width/this.body.view.scale);let s=this._getImagePadding(),o=this.left+s.left,r=this.top+s.top,a=this.width-s.left-s.right,d=this.height-s.top-s.bottom;this.imageObj.drawImageAtPosition(e,i,o,r,a,d),this.disableShadow(e,t)}}_drawImageLabel(e,t,i,s,o){let r=0;if(this.height!==void 0){r=this.height*.5;let d=this.labelModule.getTextSize(e,s,o);d.lineCount>=1&&(r+=d.height/2)}let a=i+r;this.options.label&&(this.labelOffset=r),this.labelModule.draw(e,t,a,s,o,"hanging")}},Io=class extends Kt{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t=this.selected,i=this.hover){if(this.needsRefresh(t,i)){let s=this.getDimensionsFromLabel(e,t,i),o=Math.max(s.width+this.margin.right+this.margin.left,s.height+this.margin.top+this.margin.bottom);this.options.size=o/2,this.width=o,this.height=o,this.radius=this.width/2}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this._drawRawCircle(e,t,i,r),this.updateBoundingBox(t,i),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,i,s,o)}updateBoundingBox(e,t){this.boundingBox.top=t-this.options.size,this.boundingBox.left=e-this.options.size,this.boundingBox.right=e+this.options.size,this.boundingBox.bottom=t+this.options.size}distanceToBorder(e){return e&&this.resize(e),this.width*.5}},Po=class extends Kt{constructor(e,t,i,s,o){super(e,t,i);this.setImages(s,o)}resize(e,t=this.selected,i=this.hover){if(this.imageObj.src===void 0||this.imageObj.width===void 0||this.imageObj.height===void 0){let o=this.options.size*2;this.width=o,this.height=o,this.radius=.5*this.width;return}this.needsRefresh(t,i)&&this._resizeImage()}draw(e,t,i,s,o,r){this.switchImages(s),this.resize();let a=t,d=i;this.options.shapeProperties.coordinateOrigin==="top-left"?(this.left=t,this.top=i,a+=this.width/2,d+=this.height/2):(this.left=t-this.width/2,this.top=i-this.height/2),this._drawRawCircle(e,a,d,r),e.save(),e.clip(),this._drawImageAtPosition(e,r),e.restore(),this._drawImageLabel(e,a,d,s,o),this.updateBoundingBox(t,i)}updateBoundingBox(e,t){this.options.shapeProperties.coordinateOrigin==="top-left"?(this.boundingBox.top=t,this.boundingBox.left=e,this.boundingBox.right=e+this.options.size*2,this.boundingBox.bottom=t+this.options.size*2):(this.boundingBox.top=t-this.options.size,this.boundingBox.left=e-this.options.size,this.boundingBox.right=e+this.options.size,this.boundingBox.bottom=t+this.options.size),this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelOffset)}distanceToBorder(e){return e&&this.resize(e),this.width*.5}},ke=class extends De{constructor(e,t,i){super(e,t,i)}resize(e,t=this.selected,i=this.hover,s={size:this.options.size}){var o,r;if(this.needsRefresh(t,i)){this.labelModule.getTextSize(e,t,i);let a=2*s.size;this.width=(o=this.customSizeWidth)!=null?o:a,this.height=(r=this.customSizeHeight)!=null?r:a,this.radius=.5*this.width}}_drawShape(e,t,i,s,o,r,a,d){return this.resize(e,r,a,d),this.left=s-this.width/2,this.top=o-this.height/2,this.initContextForDraw(e,d),aa(t)(e,s,o,d.size),this.performFill(e,d),this.options.icon!==void 0&&this.options.icon.code!==void 0&&(e.font=(r?"bold ":"")+this.height/2+"px "+(this.options.icon.face||"FontAwesome"),e.fillStyle=this.options.icon.color||"black",e.textAlign="center",e.textBaseline="middle",e.fillText(this.options.icon.code,s,o)),{drawExternalLabel:()=>{if(this.options.label!==void 0){this.labelModule.calculateLabelSize(e,r,a,s,o,"hanging");let h=o+.5*this.height+.5*this.labelModule.size.height;this.labelModule.draw(e,s,h,r,a,"hanging")}this.updateBoundingBox(s,o)}}}updateBoundingBox(e,t){this.boundingBox.top=t-this.options.size,this.boundingBox.left=e-this.options.size,this.boundingBox.right=e+this.options.size,this.boundingBox.bottom=t+this.options.size,this.options.label!==void 0&&this.labelModule.size.width>0&&(this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelModule.size.height))}},Mo=class extends ke{constructor(e,t,i,s){super(e,t,i,s);this.ctxRenderer=s}draw(e,t,i,s,o,r){this.resize(e,s,o,r),this.left=t-this.width/2,this.top=i-this.height/2,e.save();let a=this.ctxRenderer({ctx:e,id:this.options.id,x:t,y:i,state:{selected:s,hover:o},style:ye({},r),label:this.options.label});if(a.drawNode!=null&&a.drawNode(),e.restore(),a.drawExternalLabel){let d=a.drawExternalLabel;a.drawExternalLabel=()=>{e.save(),d(),e.restore()}}return a.nodeDimensions&&(this.customSizeWidth=a.nodeDimensions.width,this.customSizeHeight=a.nodeDimensions.height),a}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Do=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t,i){if(this.needsRefresh(t,i)){let o=this.getDimensionsFromLabel(e,t,i).width+this.margin.right+this.margin.left;this.width=o,this.height=o,this.radius=this.width/2}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this.initContextForDraw(e,r),ho(e,t-this.width/2,i-this.height/2,this.width,this.height),this.performFill(e,r),this.updateBoundingBox(t,i,e,s,o),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,s,o)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Fo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"diamond",4,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},No=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"circle",2,t,i,s,o,r)}distanceToBorder(e){return e&&this.resize(e),this.options.size}},Di=class extends De{constructor(e,t,i){super(e,t,i)}resize(e,t=this.selected,i=this.hover){if(this.needsRefresh(t,i)){let s=this.getDimensionsFromLabel(e,t,i);this.height=s.height*2,this.width=s.width+s.height,this.radius=.5*this.width}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width*.5,this.top=i-this.height*.5,this.initContextForDraw(e,r),ki(e,this.left,this.top,this.width,this.height),this.performFill(e,r),this.updateBoundingBox(t,i,e,s,o),this.labelModule.draw(e,t,i,s,o)}distanceToBorder(e,t){e&&this.resize(e);let i=this.width*.5,s=this.height*.5,o=Math.sin(t)*i,r=Math.cos(t)*s;return i*s/Math.sqrt(o*o+r*r)}},Bo=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t,i){this.needsRefresh(t,i)&&(this.iconSize={width:Number(this.options.icon.size),height:Number(this.options.icon.size)},this.width=this.iconSize.width+this.margin.right+this.margin.left,this.height=this.iconSize.height+this.margin.top+this.margin.bottom,this.radius=.5*this.width)}draw(e,t,i,s,o,r){return this.resize(e,s,o),this.options.icon.size=this.options.icon.size||50,this.left=t-this.width/2,this.top=i-this.height/2,this._icon(e,t,i,s,o,r),{drawExternalLabel:()=>{if(this.options.label!==void 0){let a=5;this.labelModule.draw(e,this.left+this.iconSize.width/2+this.margin.left,i+this.height/2+a,s)}this.updateBoundingBox(t,i)}}}updateBoundingBox(e,t){if(this.boundingBox.top=t-this.options.icon.size*.5,this.boundingBox.left=e-this.options.icon.size*.5,this.boundingBox.right=e+this.options.icon.size*.5,this.boundingBox.bottom=t+this.options.icon.size*.5,this.options.label!==void 0&&this.labelModule.size.width>0){let i=5;this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelModule.size.height+i)}}_icon(e,t,i,s,o,r){let a=Number(this.options.icon.size);this.options.icon.code!==void 0?(e.font=[this.options.icon.weight!=null?this.options.icon.weight:s?"bold":"",(this.options.icon.weight!=null&&s?5:0)+a+"px",this.options.icon.face].join(" "),e.fillStyle=this.options.icon.color||"black",e.textAlign="center",e.textBaseline="middle",this.enableShadow(e,r),e.fillText(this.options.icon.code,t,i),this.disableShadow(e,r)):console.error("When using the icon shape, you need to define the code in the icon options object. This can be done per node or globally.")}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Ao=class extends Kt{constructor(e,t,i,s,o){super(e,t,i);this.setImages(s,o)}resize(e,t=this.selected,i=this.hover){if(this.imageObj.src===void 0||this.imageObj.width===void 0||this.imageObj.height===void 0){let o=this.options.size*2;this.width=o,this.height=o;return}this.needsRefresh(t,i)&&this._resizeImage()}draw(e,t,i,s,o,r){e.save(),this.switchImages(s),this.resize();let a=t,d=i;if(this.options.shapeProperties.coordinateOrigin==="top-left"?(this.left=t,this.top=i,a+=this.width/2,d+=this.height/2):(this.left=t-this.width/2,this.top=i-this.height/2),this.options.shapeProperties.useBorderWithImage===!0){let h=this.options.borderWidth,l=this.options.borderWidthSelected||2*this.options.borderWidth,c=(s?l:h)/this.body.view.scale;e.lineWidth=Math.min(this.width,c),e.beginPath();let u=s?this.options.color.highlight.border:o?this.options.color.hover.border:this.options.color.border,p=s?this.options.color.highlight.background:o?this.options.color.hover.background:this.options.color.background;r.opacity!==void 0&&(u=re(u,r.opacity),p=re(p,r.opacity)),e.strokeStyle=u,e.fillStyle=p,e.rect(this.left-.5*e.lineWidth,this.top-.5*e.lineWidth,this.width+e.lineWidth,this.height+e.lineWidth),e.fill(),this.performStroke(e,r),e.closePath()}this._drawImageAtPosition(e,r),this._drawImageLabel(e,a,d,s,o),this.updateBoundingBox(t,i),e.restore()}updateBoundingBox(e,t){this.resize(),this.options.shapeProperties.coordinateOrigin==="top-left"?(this.left=e,this.top=t):(this.left=e-this.width/2,this.top=t-this.height/2),this.boundingBox.left=this.left,this.boundingBox.top=this.top,this.boundingBox.bottom=this.top+this.height,this.boundingBox.right=this.left+this.width,this.options.label!==void 0&&this.labelModule.size.width>0&&(this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelOffset))}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},zo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"square",2,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Lo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"hexagon",4,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Ro=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"star",4,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Ho=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t,i){this.needsRefresh(t,i)&&(this.textSize=this.labelModule.getTextSize(e,t,i),this.width=this.textSize.width+this.margin.right+this.margin.left,this.height=this.textSize.height+this.margin.top+this.margin.bottom,this.radius=.5*this.width)}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this.enableShadow(e,r),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,s,o),this.disableShadow(e,r),this.updateBoundingBox(t,i,e,s,o)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},jo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"triangle",3,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Wo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"triangleDown",3,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},U=class{constructor(e,t,i,s,o,r){this.options=xe(o),this.globalOptions=o,this.defaultOptions=r,this.body=t,this.edges=[],this.id=void 0,this.imagelist=i,this.grouplist=s,this.x=void 0,this.y=void 0,this.baseSize=this.options.size,this.baseFontSize=this.options.font.size,this.predefinedPosition=!1,this.selected=!1,this.hover=!1,this.labelModule=new Ue(this.body,this.options,!1),this.setOptions(e)}attachEdge(e){this.edges.indexOf(e)===-1&&this.edges.push(e)}detachEdge(e){let t=this.edges.indexOf(e);t!=-1&&this.edges.splice(t,1)}setOptions(e){let t=this.options.shape;if(!e)return;if(typeof e.color!="undefined"&&(this._localColor=e.color),e.id!==void 0&&(this.id=e.id),this.id===void 0)throw new Error("Node must have an id");U.checkMass(e,this.id),e.x!==void 0&&(e.x===null?(this.x=void 0,this.predefinedPosition=!1):(this.x=parseInt(e.x),this.predefinedPosition=!0)),e.y!==void 0&&(e.y===null?(this.y=void 0,this.predefinedPosition=!1):(this.y=parseInt(e.y),this.predefinedPosition=!0)),e.size!==void 0&&(this.baseSize=e.size),e.value!==void 0&&(e.value=parseFloat(e.value)),U.parseOptions(this.options,e,!0,this.globalOptions,this.grouplist);let i=[e,this.options,this.defaultOptions];return this.chooser=Ii("node",i),this._load_images(),this.updateLabelModule(e),e.opacity!==void 0&&U.checkOpacity(e.opacity)&&(this.options.opacity=e.opacity),this.updateShape(t),e.hidden!==void 0||e.physics!==void 0}_load_images(){if((this.options.shape==="circularImage"||this.options.shape==="image")&&this.options.image===void 0)throw new Error("Option image must be defined for node type '"+this.options.shape+"'");if(this.options.image!==void 0){if(this.imagelist===void 0)throw new Error("Internal Error: No images provided");if(typeof this.options.image=="string")this.imageObj=this.imagelist.load(this.options.image,this.options.brokenImage,this.id);else{if(this.options.image.unselected===void 0)throw new Error("No unselected image provided");this.imageObj=this.imagelist.load(this.options.image.unselected,this.options.brokenImage,this.id),this.options.image.selected!==void 0?this.imageObjAlt=this.imagelist.load(this.options.image.selected,this.options.brokenImage,this.id):this.imageObjAlt=void 0}}}static checkOpacity(e){return 0<=e&&e<=1}static checkCoordinateOrigin(e){return e===void 0||e==="center"||e==="top-left"}static updateGroupOptions(e,t,i){if(i===void 0)return;let s=e.group;if(t!==void 0&&t.group!==void 0&&s!==t.group)throw new Error("updateGroupOptions: group values in options don't match.");if(!(typeof s=="number"||typeof s=="string"&&s!=""))return;let r=i.get(s);r.opacity!==void 0&&t.opacity===void 0&&(U.checkOpacity(r.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+r.opacity),r.opacity=void 0));let a=Object.getOwnPropertyNames(t).filter(d=>t[d]!=null);a.push("font"),mt(a,e,r),e.color=Rt(e.color)}static parseOptions(e,t,i=!1,s={},o){if(mt(["color","fixed","shadow"],e,t,i),U.checkMass(t),e.opacity!==void 0&&(U.checkOpacity(e.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+e.opacity),e.opacity=void 0)),t.opacity!==void 0&&(U.checkOpacity(t.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+t.opacity),t.opacity=void 0)),t.shapeProperties&&!U.checkCoordinateOrigin(t.shapeProperties.coordinateOrigin)&&console.error("Invalid option for node coordinateOrigin, found: "+t.shapeProperties.coordinateOrigin),ae(e,t,"shadow",s),t.color!==void 0&&t.color!==null){let a=Rt(t.color);bi(e.color,a)}else i===!0&&t.color===null&&(e.color=xe(s.color));t.fixed!==void 0&&t.fixed!==null&&(typeof t.fixed=="boolean"?(e.fixed.x=t.fixed,e.fixed.y=t.fixed):(t.fixed.x!==void 0&&typeof t.fixed.x=="boolean"&&(e.fixed.x=t.fixed.x),t.fixed.y!==void 0&&typeof t.fixed.y=="boolean"&&(e.fixed.y=t.fixed.y))),i===!0&&t.font===null&&(e.font=xe(s.font)),U.updateGroupOptions(e,t,o),t.scaling!==void 0&&ae(e.scaling,t.scaling,"label",s.scaling)}getFormattingValues(){let e={color:this.options.color.background,opacity:this.options.opacity,borderWidth:this.options.borderWidth,borderColor:this.options.color.border,size:this.options.size,borderDashes:this.options.shapeProperties.borderDashes,borderRadius:this.options.shapeProperties.borderRadius,shadow:this.options.shadow.enabled,shadowColor:this.options.shadow.color,shadowSize:this.options.shadow.size,shadowX:this.options.shadow.x,shadowY:this.options.shadow.y};if(this.selected||this.hover?this.chooser===!0?this.selected?(this.options.borderWidthSelected!=null?e.borderWidth=this.options.borderWidthSelected:e.borderWidth*=2,e.color=this.options.color.highlight.background,e.borderColor=this.options.color.highlight.border,e.shadow=this.options.shadow.enabled):this.hover&&(e.color=this.options.color.hover.background,e.borderColor=this.options.color.hover.border,e.shadow=this.options.shadow.enabled):typeof this.chooser=="function"&&(this.chooser(e,this.options.id,this.selected,this.hover),e.shadow===!1&&(e.shadowColor!==this.options.shadow.color||e.shadowSize!==this.options.shadow.size||e.shadowX!==this.options.shadow.x||e.shadowY!==this.options.shadow.y)&&(e.shadow=!0)):e.shadow=this.options.shadow.enabled,this.options.opacity!==void 0){let t=this.options.opacity;e.borderColor=re(e.borderColor,t),e.color=re(e.color,t),e.shadowColor=re(e.shadowColor,t)}return e}updateLabelModule(e){(this.options.label===void 0||this.options.label===null)&&(this.options.label=""),U.updateGroupOptions(this.options,St(ye({},e),{color:e&&e.color||this._localColor||void 0}),this.grouplist);let t=this.grouplist.get(this.options.group,!1),i=[e,this.options,t,this.globalOptions,this.defaultOptions];this.labelModule.update(this.options,i),this.labelModule.baseSize!==void 0&&(this.baseFontSize=this.labelModule.baseSize)}updateShape(e){if(e===this.options.shape&&this.shape)this.shape.setOptions(this.options,this.imageObj,this.imageObjAlt);else switch(this.options.shape){case"box":this.shape=new Oo(this.options,this.body,this.labelModule);break;case"circle":this.shape=new Io(this.options,this.body,this.labelModule);break;case"circularImage":this.shape=new Po(this.options,this.body,this.labelModule,this.imageObj,this.imageObjAlt);break;case"custom":this.shape=new Mo(this.options,this.body,this.labelModule,this.options.ctxRenderer);break;case"database":this.shape=new Do(this.options,this.body,this.labelModule);break;case"diamond":this.shape=new Fo(this.options,this.body,this.labelModule);break;case"dot":this.shape=new No(this.options,this.body,this.labelModule);break;case"ellipse":this.shape=new Di(this.options,this.body,this.labelModule);break;case"icon":this.shape=new Bo(this.options,this.body,this.labelModule);break;case"image":this.shape=new Ao(this.options,this.body,this.labelModule,this.imageObj,this.imageObjAlt);break;case"square":this.shape=new zo(this.options,this.body,this.labelModule);break;case"hexagon":this.shape=new Lo(this.options,this.body,this.labelModule);break;case"star":this.shape=new Ro(this.options,this.body,this.labelModule);break;case"text":this.shape=new Ho(this.options,this.body,this.labelModule);break;case"triangle":this.shape=new jo(this.options,this.body,this.labelModule);break;case"triangleDown":this.shape=new Wo(this.options,this.body,this.labelModule);break;default:this.shape=new Di(this.options,this.body,this.labelModule);break}this.needsRefresh()}select(){this.selected=!0,this.needsRefresh()}unselect(){this.selected=!1,this.needsRefresh()}needsRefresh(){this.shape.refreshNeeded=!0}getTitle(){return this.options.title}distanceToBorder(e,t){return this.shape.distanceToBorder(e,t)}isFixed(){return this.options.fixed.x&&this.options.fixed.y}isSelected(){return this.selected}getValue(){return this.options.value}getLabelSize(){return this.labelModule.size()}setValueRange(e,t,i){if(this.options.value!==void 0){let s=this.options.scaling.customScalingFunction(e,t,i,this.options.value),o=this.options.scaling.max-this.options.scaling.min;if(this.options.scaling.label.enabled===!0){let r=this.options.scaling.label.max-this.options.scaling.label.min;this.options.font.size=this.options.scaling.label.min+s*r}this.options.size=this.options.scaling.min+s*o}else this.options.size=this.baseSize,this.options.font.size=this.baseFontSize;this.updateLabelModule()}draw(e){let t=this.getFormattingValues();return this.shape.draw(e,this.x,this.y,this.selected,this.hover,t)||{}}updateBoundingBox(e){this.shape.updateBoundingBox(this.x,this.y,e)}resize(e){let t=this.getFormattingValues();this.shape.resize(e,this.selected,this.hover,t)}getItemsOnPoint(e){let t=[];return this.labelModule.visible()&&Pi(this.labelModule.getSize(),e)&&t.push({nodeId:this.id,labelId:0}),Pi(this.shape.boundingBox,e)&&t.push({nodeId:this.id}),t}isOverlappingWith(e){return this.shape.lefte.left&&this.shape.tope.top}isBoundingBoxOverlappingWith(e){return this.shape.boundingBox.lefte.left&&this.shape.boundingBox.tope.top}static checkMass(e,t){if(e.mass!==void 0&&e.mass<=0){let i="";t!==void 0&&(i=" in node id: "+t),console.error("%cNegative or zero mass disallowed"+i+", setting mass to 1.",Ei),e.mass=1}}},Vo=class{constructor(e,t,i,s){if(this.body=e,this.images=t,this.groups=i,this.layoutEngine=s,this.body.functions.createNode=this.create.bind(this),this.nodesListeners={add:(o,r)=>{this.add(r.items)},update:(o,r)=>{this.update(r.items,r.data,r.oldData)},remove:(o,r)=>{this.remove(r.items)}},this.defaultOptions={borderWidth:1,borderWidthSelected:void 0,brokenImage:void 0,color:{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},opacity:void 0,fixed:{x:!1,y:!1},font:{color:"#343434",size:14,face:"arial",background:"none",strokeWidth:0,strokeColor:"#ffffff",align:"center",vadjust:0,multi:!1,bold:{mod:"bold"},boldital:{mod:"bold italic"},ital:{mod:"italic"},mono:{mod:"",size:15,face:"monospace",vadjust:2}},group:void 0,hidden:!1,icon:{face:"FontAwesome",code:void 0,size:50,color:"#2B7CE9"},image:void 0,imagePadding:{top:0,right:0,bottom:0,left:0},label:void 0,labelHighlightBold:!0,level:void 0,margin:{top:5,right:5,bottom:5,left:5},mass:1,physics:!0,scaling:{min:10,max:30,label:{enabled:!1,min:14,max:30,maxVisible:30,drawThreshold:5},customScalingFunction:function(o,r,a,d){if(r===o)return .5;{let h=1/(r-o);return Math.max(0,(d-o)*h)}}},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:10,x:5,y:5},shape:"ellipse",shapeProperties:{borderDashes:!1,borderRadius:6,interpolation:!0,useImageSize:!1,useBorderWithImage:!1,coordinateOrigin:"center"},size:25,title:void 0,value:void 0,x:void 0,y:void 0},this.defaultOptions.mass<=0)throw"Internal error: mass in defaultOptions of NodesHandler may not be zero or negative";this.options=xe(this.defaultOptions),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("refreshNodes",this.refresh.bind(this)),this.body.emitter.on("refresh",this.refresh.bind(this)),this.body.emitter.on("destroy",()=>{A(this.nodesListeners,(e,t)=>{this.body.data.nodes&&this.body.data.nodes.off(t,e)}),delete this.body.functions.createNode,delete this.nodesListeners.add,delete this.nodesListeners.update,delete this.nodesListeners.remove,delete this.nodesListeners})}setOptions(e){if(e!==void 0){if(U.parseOptions(this.options,e),e.opacity!==void 0&&(Number.isNaN(e.opacity)||!Number.isFinite(e.opacity)||e.opacity<0||e.opacity>1?console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+e.opacity):this.options.opacity=e.opacity),e.shape!==void 0)for(let t in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&this.body.nodes[t].updateShape();if(typeof e.font!="undefined"||typeof e.widthConstraint!="undefined"||typeof e.heightConstraint!="undefined")for(let t of Object.keys(this.body.nodes))this.body.nodes[t].updateLabelModule(),this.body.nodes[t].needsRefresh();if(e.size!==void 0)for(let t in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&this.body.nodes[t].needsRefresh();(e.hidden!==void 0||e.physics!==void 0)&&this.body.emitter.emit("_dataChanged")}}setData(e,t=!1){let i=this.body.data.nodes;if(Ci("id",e))this.body.data.nodes=e;else if(Array.isArray(e))this.body.data.nodes=new fe,this.body.data.nodes.add(e);else if(!e)this.body.data.nodes=new fe;else throw new TypeError("Array or DataSet expected");if(i&&A(this.nodesListeners,function(s,o){i.off(o,s)}),this.body.nodes={},this.body.data.nodes){let s=this;A(this.nodesListeners,function(r,a){s.body.data.nodes.on(a,r)});let o=this.body.data.nodes.getIds();this.add(o,!0)}t===!1&&this.body.emitter.emit("_dataChanged")}add(e,t=!1){let i,s=[];for(let o=0;o{let s=this.body.data.nodes.get(i);s!==void 0&&(e===!0&&t.setOptions({x:null,y:null}),t.setOptions({fixed:!1}),t.setOptions(s))})}getPositions(e){let t={};if(e!==void 0){if(Array.isArray(e)===!0){for(let i=0;i{this.body.emitter.emit("startSimulation")},0)):console.error("Node id supplied to moveNode does not exist. Provided: ",e)}},G=class{static transform(e,t){Array.isArray(e)||(e=[e]);let i=t.point.x,s=t.point.y,o=t.angle,r=t.length;for(let a=0;a0?d>0?r=p:a=p:d>0?a=p:r=p,++C}while(r<=a&&C1?l=1:l<0&&(l=0);let c=e+l*a,u=t+l*d,p=c-o,b=u-r;return Math.sqrt(p*p+b*b)}getArrowData(e,t,i,s,o,r){let a,d,h,l,c,u,p,b=r.width;t==="from"?(h=this.from,l=this.to,c=r.fromArrowScale<0,u=Math.abs(r.fromArrowScale),p=r.fromArrowType):t==="to"?(h=this.to,l=this.from,c=r.toArrowScale<0,u=Math.abs(r.toArrowScale),p=r.toArrowType):(h=this.to,l=this.from,c=r.middleArrowScale<0,u=Math.abs(r.middleArrowScale),p=r.middleArrowType);let C=15*u+3*b;if(h!=l){let v=Math.hypot(h.x-l.x,h.y-l.y),_=C/v;if(t!=="middle")if(this.options.smooth.enabled===!0){let E=this._findBorderPosition(h,e,{via:i}),T=this.getPoint(E.t+_*(t==="from"?1:-1),i);a=Math.atan2(E.y-T.y,E.x-T.x),d=E}else a=Math.atan2(h.y-l.y,h.x-l.x),d=this._findBorderPosition(h,e);else{let E=(c?-_:_)/2,T=this.getPoint(.5+E,i),x=this.getPoint(.5-E,i);a=Math.atan2(T.y-x.y,T.x-x.x),d=this.getPoint(.5,i)}}else{let[v,_,E]=this._getCircleData(e);if(t==="from"){let T=this.options.selfReference.angle,x=this.options.selfReference.angle+Math.PI,w=this._findBorderPositionCircle(this.from,e,{x:v,y:_,low:T,high:x,direction:-1});a=w.t*-2*Math.PI+1.5*Math.PI+.1*Math.PI,d=w}else if(t==="to"){let T=this.options.selfReference.angle,x=this.options.selfReference.angle+Math.PI,w=this._findBorderPositionCircle(this.from,e,{x:v,y:_,low:T,high:x,direction:1});a=w.t*-2*Math.PI+1.5*Math.PI-1.1*Math.PI,d=w}else{let T=this.options.selfReference.angle/(2*Math.PI);d=this._pointOnCircle(v,_,E,T),a=T*-2*Math.PI+1.5*Math.PI+.1*Math.PI}}let f=d.x-C*.9*Math.cos(a),g=d.y-C*.9*Math.sin(a);return{point:d,core:{x:f,y:g},angle:a,length:C,type:p}}drawArrowHead(e,t,i,s,o){e.strokeStyle=this.getColor(e,t),e.fillStyle=e.strokeStyle,e.lineWidth=t.width,Fi.draw(e,o)&&(this.enableShadow(e,t),e.fill(),this.disableShadow(e,t))}enableShadow(e,t){t.shadow===!0&&(e.shadowColor=t.shadowColor,e.shadowBlur=t.shadowSize,e.shadowOffsetX=t.shadowX,e.shadowOffsetY=t.shadowY)}disableShadow(e,t){t.shadow===!0&&(e.shadowColor="rgba(0,0,0,0)",e.shadowBlur=0,e.shadowOffsetX=0,e.shadowOffsetY=0)}drawBackground(e,t){if(t.background!==!1){let i={strokeStyle:e.strokeStyle,lineWidth:e.lineWidth,dashes:e.dashes};e.strokeStyle=t.backgroundColor,e.lineWidth=t.backgroundSize,this.setStrokeDashed(e,t.backgroundDashes),e.stroke(),e.strokeStyle=i.strokeStyle,e.lineWidth=i.lineWidth,e.dashes=i.dashes,this.setStrokeDashed(e,t.dashes)}}setStrokeDashed(e,t){if(t!==!1)if(e.setLineDash!==void 0){let i=Array.isArray(t)?t:[5,5];e.setLineDash(i)}else console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.");else e.setLineDash!==void 0?e.setLineDash([]):console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.")}},Zt=class extends Ni{constructor(e,t,i){super(e,t,i)}_findBorderPositionBezier(e,t,i=this._getViaCoordinates()){let s=10,o=.2,r=!1,a=1,d=0,h=this.to,l,c,u=this.options.endPointOffset?this.options.endPointOffset.to:0;e.id===this.from.id&&(h=this.from,r=!0,u=this.options.endPointOffset?this.options.endPointOffset.from:0),this.options.arrowStrikethrough===!1&&(u=0);let p=0;do{c=(d+a)*.5,l=this.getPoint(c,i);let b=Math.atan2(h.y-l.y,h.x-l.x),C=h.distanceToBorder(t,b)+u,f=Math.sqrt(Math.pow(l.x-h.x,2)+Math.pow(l.y-h.y,2)),g=C-f;if(Math.abs(g)0&&(h=this._getDistanceToLine(b,C,u,p,o,r),d=h{this.positionBezierNode()},this._body.emitter.on("_repositionBezierNodes",this._boundFunction)}setOptions(e){super.setOptions(e);let t=!1;this.options.physics!==e.physics&&(t=!0),this.options=e,this.id=this.options.id,this.from=this._body.nodes[this.options.from],this.to=this._body.nodes[this.options.to],this.setupSupportNode(),this.connect(),t===!0&&(this.via.setOptions({physics:this.options.physics}),this.positionBezierNode())}connect(){this.from=this._body.nodes[this.options.from],this.to=this._body.nodes[this.options.to],this.from===void 0||this.to===void 0||this.options.physics===!1?this.via.setOptions({physics:!1}):this.from.id===this.to.id?this.via.setOptions({physics:!1}):this.via.setOptions({physics:!0})}cleanup(){return this._body.emitter.off("_repositionBezierNodes",this._boundFunction),this.via!==void 0?(delete this._body.nodes[this.via.id],this.via=void 0,!0):!1}setupSupportNode(){if(this.via===void 0){let e="edgeId:"+this.id,t=this._body.functions.createNode({id:e,shape:"circle",physics:!0,hidden:!0});this._body.nodes[e]=t,this.via=t,this.via.parentEdgeId=this.id,this.positionBezierNode()}}positionBezierNode(){this.via!==void 0&&this.from!==void 0&&this.to!==void 0?(this.via.x=.5*(this.from.x+this.to.x),this.via.y=.5*(this.from.y+this.to.y)):this.via!==void 0&&(this.via.x=0,this.via.y=0)}_line(e,t,i){this._bezierCurve(e,t,i)}_getViaCoordinates(){return this.via}getViaNode(){return this.via}getPoint(e,t=this.via){if(this.from===this.to){let[i,s,o]=this._getCircleData(),r=2*Math.PI*(1-e);return{x:i+o*Math.sin(r),y:s+o-o*(1-Math.cos(r))}}else return{x:Math.pow(1-e,2)*this.fromPoint.x+2*e*(1-e)*t.x+Math.pow(e,2)*this.toPoint.x,y:Math.pow(1-e,2)*this.fromPoint.y+2*e*(1-e)*t.y+Math.pow(e,2)*this.toPoint.y}}_findBorderPosition(e,t){return this._findBorderPositionBezier(e,t,this.via)}_getDistanceToEdge(e,t,i,s,o,r){return this._getDistanceToBezierEdge(e,t,i,s,o,r,this.via)}},Ai=class extends Zt{constructor(e,t,i){super(e,t,i)}_line(e,t,i){this._bezierCurve(e,t,i)}getViaNode(){return this._getViaCoordinates()}_getViaCoordinates(){let e=this.options.smooth.roundness,t=this.options.smooth.type,i=Math.abs(this.from.x-this.to.x),s=Math.abs(this.from.y-this.to.y);if(t==="discrete"||t==="diagonalCross"){let o,r;i<=s?o=r=e*s:o=r=e*i,this.from.x>this.to.x&&(o=-o),this.from.y>=this.to.y&&(r=-r);let a=this.from.x+o,d=this.from.y+r;return t==="discrete"&&(i<=s?a=ithis.to.x&&(o=-o),this.from.y>=this.to.y&&(r=-r);let a=this.from.x+o,d=this.from.y+r;return i<=s?this.from.x<=this.to.x?a=this.to.xa?this.to.x:a:this.from.y>=this.to.y?d=this.to.y>d?this.to.y:d:d=this.to.y0){let g=this._getDistanceToLine(l,c,C,f,o,r);h=gMath.abs(t)||this.options.smooth.forceDirection===!0||this.options.smooth.forceDirection==="horizontal")&&this.options.smooth.forceDirection!=="vertical"?(s=this.from.y,r=this.to.y,i=this.from.x-a*e,o=this.to.x+a*e):(s=this.from.y-a*t,r=this.to.y+a*t,i=this.from.x,o=this.to.x),[{x:i,y:s},{x:o,y:r}]}getViaNode(){return this._getViaCoordinates()}_findBorderPosition(e,t){return this._findBorderPositionBezier(e,t)}_getDistanceToEdge(e,t,i,s,o,r,[a,d]=this._getViaCoordinates()){return this._getDistanceToBezierEdge2(e,t,i,s,o,r,a,d)}getPoint(e,[t,i]=this._getViaCoordinates()){let s=e,o=[Math.pow(1-s,3),3*s*Math.pow(1-s,2),3*Math.pow(s,2)*(1-s),Math.pow(s,3)],r=o[0]*this.fromPoint.x+o[1]*t.x+o[2]*i.x+o[3]*this.toPoint.x,a=o[0]*this.fromPoint.y+o[1]*t.y+o[2]*i.y+o[3]*this.toPoint.y;return{x:r,y:a}}},Li=class extends Ni{constructor(e,t,i){super(e,t,i)}_line(e,t){e.beginPath(),e.moveTo(this.fromPoint.x,this.fromPoint.y),e.lineTo(this.toPoint.x,this.toPoint.y),this.enableShadow(e,t),e.stroke(),this.disableShadow(e,t)}getViaNode(){}getPoint(e){return{x:(1-e)*this.fromPoint.x+e*this.toPoint.x,y:(1-e)*this.fromPoint.y+e*this.toPoint.y}}_findBorderPosition(e,t){let i=this.to,s=this.from;e.id===this.from.id&&(i=this.from,s=this.to);let o=Math.atan2(i.y-s.y,i.x-s.x),r=i.x-s.x,a=i.y-s.y,d=Math.sqrt(r*r+a*a),h=e.distanceToBorder(t,o),l=(d-h)/d;return{x:(1-l)*s.x+l*i.x,y:(1-l)*s.y+l*i.y,t:0}}_getDistanceToEdge(e,t,i,s,o,r){return this._getDistanceToLine(e,t,i,s,o,r)}},Se=class{constructor(e,t,i,s,o){if(t===void 0)throw new Error("No body provided");this.options=xe(s),this.globalOptions=s,this.defaultOptions=o,this.body=t,this.imagelist=i,this.id=void 0,this.fromId=void 0,this.toId=void 0,this.selected=!1,this.hover=!1,this.labelDirty=!0,this.baseWidth=this.options.width,this.baseFontSize=this.options.font.size,this.from=void 0,this.to=void 0,this.edgeType=void 0,this.connected=!1,this.labelModule=new Ue(this.body,this.options,!0),this.setOptions(e)}setOptions(e){if(!e)return;let t=typeof e.physics!="undefined"&&this.options.physics!==e.physics||typeof e.hidden!="undefined"&&(this.options.hidden||!1)!==(e.hidden||!1)||typeof e.from!="undefined"&&this.options.from!==e.from||typeof e.to!="undefined"&&this.options.to!==e.to;Se.parseOptions(this.options,e,!0,this.globalOptions),e.id!==void 0&&(this.id=e.id),e.from!==void 0&&(this.fromId=e.from),e.to!==void 0&&(this.toId=e.to),e.title!==void 0&&(this.title=e.title),e.value!==void 0&&(e.value=parseFloat(e.value));let i=[e,this.options,this.defaultOptions];return this.chooser=Ii("edge",i),this.updateLabelModule(e),t=this.updateEdgeType()||t,this._setInteractionWidths(),this.connect(),t}static parseOptions(e,t,i=!1,s={},o=!1){if(Ve(["endPointOffset","arrowStrikethrough","id","from","hidden","hoverWidth","labelHighlightBold","length","line","opacity","physics","scaling","selectionWidth","selfReferenceSize","selfReference","to","title","value","width","font","chosen","widthConstraint"],e,t,i),t.endPointOffset!==void 0&&t.endPointOffset.from!==void 0&&(Number.isFinite(t.endPointOffset.from)?e.endPointOffset.from=t.endPointOffset.from:(e.endPointOffset.from=s.endPointOffset.from!==void 0?s.endPointOffset.from:0,console.error("endPointOffset.from is not a valid number"))),t.endPointOffset!==void 0&&t.endPointOffset.to!==void 0&&(Number.isFinite(t.endPointOffset.to)?e.endPointOffset.to=t.endPointOffset.to:(e.endPointOffset.to=s.endPointOffset.to!==void 0?s.endPointOffset.to:0,console.error("endPointOffset.to is not a valid number"))),Xt(t.label)?e.label=t.label:Xt(e.label)||(e.label=void 0),ae(e,t,"smooth",s),ae(e,t,"shadow",s),ae(e,t,"background",s),t.dashes!==void 0&&t.dashes!==null?e.dashes=t.dashes:i===!0&&t.dashes===null&&(e.dashes=Object.create(s.dashes)),t.scaling!==void 0&&t.scaling!==null?(t.scaling.min!==void 0&&(e.scaling.min=t.scaling.min),t.scaling.max!==void 0&&(e.scaling.max=t.scaling.max),ae(e.scaling,t.scaling,"label",s.scaling)):i===!0&&t.scaling===null&&(e.scaling=Object.create(s.scaling)),t.arrows!==void 0&&t.arrows!==null)if(typeof t.arrows=="string"){let a=t.arrows.toLowerCase();e.arrows.to.enabled=a.indexOf("to")!=-1,e.arrows.middle.enabled=a.indexOf("middle")!=-1,e.arrows.from.enabled=a.indexOf("from")!=-1}else if(typeof t.arrows=="object")ae(e.arrows,t.arrows,"to",s.arrows),ae(e.arrows,t.arrows,"middle",s.arrows),ae(e.arrows,t.arrows,"from",s.arrows);else throw new Error("The arrow newOptions can only be an object or a string. Refer to the documentation. You used:"+JSON.stringify(t.arrows));else i===!0&&t.arrows===null&&(e.arrows=Object.create(s.arrows));if(t.color!==void 0&&t.color!==null){let a=Ee(t.color)?{color:t.color,highlight:t.color,hover:t.color,inherit:!1,opacity:1}:t.color,d=e.color;if(o)j(d,s.color,!1,i);else for(let h in d)Object.prototype.hasOwnProperty.call(d,h)&&delete d[h];if(Ee(d))d.color=d,d.highlight=d,d.hover=d,d.inherit=!1,a.opacity===void 0&&(d.opacity=1);else{let h=!1;a.color!==void 0&&(d.color=a.color,h=!0),a.highlight!==void 0&&(d.highlight=a.highlight,h=!0),a.hover!==void 0&&(d.hover=a.hover,h=!0),a.inherit!==void 0&&(d.inherit=a.inherit),a.opacity!==void 0&&(d.opacity=Math.min(1,Math.max(0,a.opacity))),h===!0?d.inherit=!1:d.inherit===void 0&&(d.inherit="from")}}else i===!0&&t.color===null&&(e.color=xe(s.color));i===!0&&t.font===null&&(e.font=xe(s.font)),Object.prototype.hasOwnProperty.call(t,"selfReferenceSize")&&(console.warn("The selfReferenceSize property has been deprecated. Please use selfReference property instead. The selfReference can be set like thise selfReference:{size:30, angle:Math.PI / 4}"),e.selfReference.size=t.selfReferenceSize)}getFormattingValues(){let e=this.options.arrows.to===!0||this.options.arrows.to.enabled===!0,t=this.options.arrows.from===!0||this.options.arrows.from.enabled===!0,i=this.options.arrows.middle===!0||this.options.arrows.middle.enabled===!0,s=this.options.color.inherit,o={toArrow:e,toArrowScale:this.options.arrows.to.scaleFactor,toArrowType:this.options.arrows.to.type,toArrowSrc:this.options.arrows.to.src,toArrowImageWidth:this.options.arrows.to.imageWidth,toArrowImageHeight:this.options.arrows.to.imageHeight,middleArrow:i,middleArrowScale:this.options.arrows.middle.scaleFactor,middleArrowType:this.options.arrows.middle.type,middleArrowSrc:this.options.arrows.middle.src,middleArrowImageWidth:this.options.arrows.middle.imageWidth,middleArrowImageHeight:this.options.arrows.middle.imageHeight,fromArrow:t,fromArrowScale:this.options.arrows.from.scaleFactor,fromArrowType:this.options.arrows.from.type,fromArrowSrc:this.options.arrows.from.src,fromArrowImageWidth:this.options.arrows.from.imageWidth,fromArrowImageHeight:this.options.arrows.from.imageHeight,arrowStrikethrough:this.options.arrowStrikethrough,color:s?void 0:this.options.color.color,inheritsColor:s,opacity:this.options.color.opacity,hidden:this.options.hidden,length:this.options.length,shadow:this.options.shadow.enabled,shadowColor:this.options.shadow.color,shadowSize:this.options.shadow.size,shadowX:this.options.shadow.x,shadowY:this.options.shadow.y,dashes:this.options.dashes,width:this.options.width,background:this.options.background.enabled,backgroundColor:this.options.background.color,backgroundSize:this.options.background.size,backgroundDashes:this.options.background.dashes};if(this.selected||this.hover)if(this.chooser===!0){if(this.selected){let r=this.options.selectionWidth;typeof r=="function"?o.width=r(o.width):typeof r=="number"&&(o.width+=r),o.width=Math.max(o.width,.3/this.body.view.scale),o.color=this.options.color.highlight,o.shadow=this.options.shadow.enabled}else if(this.hover){let r=this.options.hoverWidth;typeof r=="function"?o.width=r(o.width):typeof r=="number"&&(o.width+=r),o.width=Math.max(o.width,.3/this.body.view.scale),o.color=this.options.color.hover,o.shadow=this.options.shadow.enabled}}else typeof this.chooser=="function"&&(this.chooser(o,this.options.id,this.selected,this.hover),o.color!==void 0&&(o.inheritsColor=!1),o.shadow===!1&&(o.shadowColor!==this.options.shadow.color||o.shadowSize!==this.options.shadow.size||o.shadowX!==this.options.shadow.x||o.shadowY!==this.options.shadow.y)&&(o.shadow=!0));else o.shadow=this.options.shadow.enabled,o.width=Math.max(o.width,.3/this.body.view.scale);return o}updateLabelModule(e){let t=[e,this.options,this.globalOptions,this.defaultOptions];this.labelModule.update(this.options,t),this.labelModule.baseSize!==void 0&&(this.baseFontSize=this.labelModule.baseSize)}updateEdgeType(){let e=this.options.smooth,t=!1,i=!0;return this.edgeType!==void 0&&((this.edgeType instanceof Bi&&e.enabled===!0&&e.type==="dynamic"||this.edgeType instanceof zi&&e.enabled===!0&&e.type==="cubicBezier"||this.edgeType instanceof Ai&&e.enabled===!0&&e.type!=="dynamic"&&e.type!=="cubicBezier"||this.edgeType instanceof Li&&e.type.enabled===!1)&&(i=!1),i===!0&&(t=this.cleanup())),i===!0?e.enabled===!0?e.type==="dynamic"?(t=!0,this.edgeType=new Bi(this.options,this.body,this.labelModule)):e.type==="cubicBezier"?this.edgeType=new zi(this.options,this.body,this.labelModule):this.edgeType=new Ai(this.options,this.body,this.labelModule):this.edgeType=new Li(this.options,this.body,this.labelModule):this.edgeType.setOptions(this.options),t}connect(){this.disconnect(),this.from=this.body.nodes[this.fromId]||void 0,this.to=this.body.nodes[this.toId]||void 0,this.connected=this.from!==void 0&&this.to!==void 0,this.connected===!0?(this.from.attachEdge(this),this.to.attachEdge(this)):(this.from&&this.from.detachEdge(this),this.to&&this.to.detachEdge(this)),this.edgeType.connect()}disconnect(){this.from&&(this.from.detachEdge(this),this.from=void 0),this.to&&(this.to.detachEdge(this),this.to=void 0),this.connected=!1}getTitle(){return this.title}isSelected(){return this.selected}getValue(){return this.options.value}setValueRange(e,t,i){if(this.options.value!==void 0){let s=this.options.scaling.customScalingFunction(e,t,i,this.options.value),o=this.options.scaling.max-this.options.scaling.min;if(this.options.scaling.label.enabled===!0){let r=this.options.scaling.label.max-this.options.scaling.label.min;this.options.font.size=this.options.scaling.label.min+s*r}this.options.width=this.options.scaling.min+s*o}else this.options.width=this.baseWidth,this.options.font.size=this.baseFontSize;this._setInteractionWidths(),this.updateLabelModule()}_setInteractionWidths(){typeof this.options.hoverWidth=="function"?this.edgeType.hoverWidth=this.options.hoverWidth(this.options.width):this.edgeType.hoverWidth=this.options.hoverWidth+this.options.width,typeof this.options.selectionWidth=="function"?this.edgeType.selectionWidth=this.options.selectionWidth(this.options.width):this.edgeType.selectionWidth=this.options.selectionWidth+this.options.width}draw(e){let t=this.getFormattingValues();if(t.hidden)return;let i=this.edgeType.getViaNode();this.edgeType.drawLine(e,t,this.selected,this.hover,i),this.drawLabel(e,i)}drawArrows(e){let t=this.getFormattingValues();if(t.hidden)return;let i=this.edgeType.getViaNode(),s={};this.edgeType.fromPoint=this.edgeType.from,this.edgeType.toPoint=this.edgeType.to,t.fromArrow&&(s.from=this.edgeType.getArrowData(e,"from",i,this.selected,this.hover,t),t.arrowStrikethrough===!1&&(this.edgeType.fromPoint=s.from.core),t.fromArrowSrc&&(s.from.image=this.imagelist.load(t.fromArrowSrc)),t.fromArrowImageWidth&&(s.from.imageWidth=t.fromArrowImageWidth),t.fromArrowImageHeight&&(s.from.imageHeight=t.fromArrowImageHeight)),t.toArrow&&(s.to=this.edgeType.getArrowData(e,"to",i,this.selected,this.hover,t),t.arrowStrikethrough===!1&&(this.edgeType.toPoint=s.to.core),t.toArrowSrc&&(s.to.image=this.imagelist.load(t.toArrowSrc)),t.toArrowImageWidth&&(s.to.imageWidth=t.toArrowImageWidth),t.toArrowImageHeight&&(s.to.imageHeight=t.toArrowImageHeight)),t.middleArrow&&(s.middle=this.edgeType.getArrowData(e,"middle",i,this.selected,this.hover,t),t.middleArrowSrc&&(s.middle.image=this.imagelist.load(t.middleArrowSrc)),t.middleArrowImageWidth&&(s.middle.imageWidth=t.middleArrowImageWidth),t.middleArrowImageHeight&&(s.middle.imageHeight=t.middleArrowImageHeight)),t.fromArrow&&this.edgeType.drawArrowHead(e,t,this.selected,this.hover,s.from),t.middleArrow&&this.edgeType.drawArrowHead(e,t,this.selected,this.hover,s.middle),t.toArrow&&this.edgeType.drawArrowHead(e,t,this.selected,this.hover,s.to)}drawLabel(e,t){if(this.options.label!==void 0){let i=this.from,s=this.to;this.labelModule.differentState(this.selected,this.hover)&&this.labelModule.getTextSize(e,this.selected,this.hover);let o;if(i.id!=s.id){this.labelModule.pointToSelf=!1,o=this.edgeType.getPoint(.5,t),e.save();let r=this._getRotation(e);r.angle!=0&&(e.translate(r.x,r.y),e.rotate(r.angle)),this.labelModule.draw(e,o.x,o.y,this.selected,this.hover),e.restore()}else{this.labelModule.pointToSelf=!0;let r=To(e,this.options.selfReference.angle,this.options.selfReference.size,i);o=this._pointOnCircle(r.x,r.y,this.options.selfReference.size,this.options.selfReference.angle),this.labelModule.draw(e,o.x,o.y,this.selected,this.hover)}}}getItemsOnPoint(e){let t=[];if(this.labelModule.visible()){let s=this._getRotation();Pi(this.labelModule.getSize(),e,s)&&t.push({edgeId:this.id,labelId:0})}let i={left:e.x,top:e.y};return this.isOverlappingWith(i)&&t.push({edgeId:this.id}),t}isOverlappingWith(e){if(this.connected){let t=10,i=this.from.x,s=this.from.y,o=this.to.x,r=this.to.y,a=e.left,d=e.top;return this.edgeType.getDistanceToEdge(i,s,o,r,a,d)0&&r<0)&&(a+=Math.PI),s.angle=a,s}_pointOnCircle(e,t,i,s){return{x:e+i*Math.cos(s),y:t-i*Math.sin(s)}}select(){this.selected=!0}unselect(){this.selected=!1}cleanup(){return this.edgeType.cleanup()}remove(){this.cleanup(),this.disconnect(),delete this.body.edges[this.id]}endPointsValid(){return this.body.nodes[this.fromId]!==void 0&&this.body.nodes[this.toId]!==void 0}},on=class{constructor(e,t,i){this.body=e,this.images=t,this.groups=i,this.body.functions.createEdge=this.create.bind(this),this.edgesListeners={add:(s,o)=>{this.add(o.items)},update:(s,o)=>{this.update(o.items)},remove:(s,o)=>{this.remove(o.items)}},this.options={},this.defaultOptions={arrows:{to:{enabled:!1,scaleFactor:1,type:"arrow"},middle:{enabled:!1,scaleFactor:1,type:"arrow"},from:{enabled:!1,scaleFactor:1,type:"arrow"}},endPointOffset:{from:0,to:0},arrowStrikethrough:!0,color:{color:"#848484",highlight:"#848484",hover:"#848484",inherit:"from",opacity:1},dashes:!1,font:{color:"#343434",size:14,face:"arial",background:"none",strokeWidth:2,strokeColor:"#ffffff",align:"horizontal",multi:!1,vadjust:0,bold:{mod:"bold"},boldital:{mod:"bold italic"},ital:{mod:"italic"},mono:{mod:"",size:15,face:"courier new",vadjust:2}},hidden:!1,hoverWidth:1.5,label:void 0,labelHighlightBold:!0,length:void 0,physics:!0,scaling:{min:1,max:15,label:{enabled:!0,min:14,max:30,maxVisible:30,drawThreshold:5},customScalingFunction:function(s,o,r,a){if(o===s)return .5;{let d=1/(o-s);return Math.max(0,(a-s)*d)}}},selectionWidth:1.5,selfReference:{size:20,angle:Math.PI/4,renderBehindTheNode:!0},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:10,x:5,y:5},background:{enabled:!1,color:"rgba(111,111,111,1)",size:10,dashes:!1},smooth:{enabled:!0,type:"dynamic",forceDirection:"none",roundness:.5},title:void 0,width:1,value:void 0},j(this.options,this.defaultOptions),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("_forceDisableDynamicCurves",(e,t=!0)=>{e==="dynamic"&&(e="continuous");let i=!1;for(let s in this.body.edges)if(Object.prototype.hasOwnProperty.call(this.body.edges,s)){let o=this.body.edges[s],r=this.body.data.edges.get(s);if(r!=null){let a=r.smooth;a!==void 0&&a.enabled===!0&&a.type==="dynamic"&&(e===void 0?o.setOptions({smooth:!1}):o.setOptions({smooth:{type:e}}),i=!0)}}t===!0&&i===!0&&this.body.emitter.emit("_dataChanged")}),this.body.emitter.on("_dataUpdated",()=>{this.reconnectEdges()}),this.body.emitter.on("refreshEdges",this.refresh.bind(this)),this.body.emitter.on("refresh",this.refresh.bind(this)),this.body.emitter.on("destroy",()=>{A(this.edgesListeners,(e,t)=>{this.body.data.edges&&this.body.data.edges.off(t,e)}),delete this.body.functions.createEdge,delete this.edgesListeners.add,delete this.edgesListeners.update,delete this.edgesListeners.remove,delete this.edgesListeners})}setOptions(e){if(e!==void 0){Se.parseOptions(this.options,e,!0,this.defaultOptions,!0);let t=!1;if(e.smooth!==void 0)for(let i in this.body.edges)Object.prototype.hasOwnProperty.call(this.body.edges,i)&&(t=this.body.edges[i].updateEdgeType()||t);if(e.font!==void 0)for(let i in this.body.edges)Object.prototype.hasOwnProperty.call(this.body.edges,i)&&this.body.edges[i].updateLabelModule();(e.hidden!==void 0||e.physics!==void 0||t===!0)&&this.body.emitter.emit("_dataChanged")}}setData(e,t=!1){let i=this.body.data.edges;if(Ci("id",e))this.body.data.edges=e;else if(Array.isArray(e))this.body.data.edges=new fe,this.body.data.edges.add(e);else if(!e)this.body.data.edges=new fe;else throw new TypeError("Array or DataSet expected");if(i&&A(this.edgesListeners,(s,o)=>{i.off(o,s)}),this.body.edges={},this.body.data.edges){A(this.edgesListeners,(o,r)=>{this.body.data.edges.on(r,o)});let s=this.body.data.edges.getIds();this.add(s,!0)}this.body.emitter.emit("_adjustEdgesForHierarchicalLayout"),t===!1&&this.body.emitter.emit("_dataChanged")}add(e,t=!1){let i=this.body.edges,s=this.body.data.edges;for(let o=0;o{let o=i[s];o!==void 0&&o.remove()}),t&&this.body.emitter.emit("_dataChanged")}refresh(){A(this.body.edges,(e,t)=>{let i=this.body.data.edges.get(t);i!==void 0&&e.setOptions(i)})}create(e){return new Se(e,this.body,this.images,this.options,this.defaultOptions)}reconnectEdges(){let e,t=this.body.nodes,i=this.body.edges;for(e in t)Object.prototype.hasOwnProperty.call(t,e)&&(t[e].edges=[]);for(e in i)if(Object.prototype.hasOwnProperty.call(i,e)){let s=i[e];s.from=null,s.to=null,s.connect()}}getConnectedNodes(e){let t=[];if(this.body.edges[e]!==void 0){let i=this.body.edges[e];i.fromId!==void 0&&t.push(i.fromId),i.toId!==void 0&&t.push(i.toId)}return t}_updateState(){this._addMissingEdges(),this._removeInvalidEdges()}_removeInvalidEdges(){let e=[];A(this.body.edges,(t,i)=>{let s=this.body.nodes[t.toId],o=this.body.nodes[t.fromId];s!==void 0&&s.isCluster===!0||o!==void 0&&o.isCluster===!0||(s===void 0||o===void 0)&&e.push(i)}),this.remove(e,!1)}_addMissingEdges(){let e=this.body.data.edges;if(e==null)return;let t=this.body.edges,i=[];e.forEach((s,o)=>{t[o]===void 0&&i.push(o)}),this.add(i,!0)}},Ri=class{constructor(e,t,i){this.body=e,this.physicsBody=t,this.barnesHutTree,this.setOptions(i),this._rng=gt("BARNES HUT SOLVER")}setOptions(e){this.options=e,this.thetaInversed=1/this.options.theta,this.overlapAvoidanceFactor=1-Math.max(0,Math.min(1,this.options.avoidOverlap))}solve(){if(this.options.gravitationalConstant!==0&&this.physicsBody.physicsNodeIndices.length>0){let e,t=this.body.nodes,i=this.physicsBody.physicsNodeIndices,s=i.length,o=this._formBarnesHutTree(t,i);this.barnesHutTree=o;for(let r=0;r0&&this._getForceContributions(o.root,e)}}_getForceContributions(e,t){this._getForceContribution(e.children.NW,t),this._getForceContribution(e.children.NE,t),this._getForceContribution(e.children.SW,t),this._getForceContribution(e.children.SE,t)}_getForceContribution(e,t){if(e.childrenCount>0){let i=e.centerOfMass.x-t.x,s=e.centerOfMass.y-t.y,o=Math.sqrt(i*i+s*s);o*e.calcSize>this.thetaInversed?this._calculateForces(o,i,s,t,e):e.childrenCount===4?this._getForceContributions(e,t):e.children.data.id!=t.id&&this._calculateForces(o,i,s,t,e)}}_calculateForces(e,t,i,s,o){e===0&&(e=.1,t=e),this.overlapAvoidanceFactor<1&&s.shape.radius&&(e=Math.max(.1+this.overlapAvoidanceFactor*s.shape.radius,e-s.shape.radius));let r=this.options.gravitationalConstant*o.mass*s.options.mass/Math.pow(e,3),a=t*r,d=i*r;this.physicsBody.forces[s.id].x+=a,this.physicsBody.forces[s.id].y+=d}_formBarnesHutTree(e,t){let i,s=t.length,o=e[t[0]].x,r=e[t[0]].y,a=e[t[0]].x,d=e[t[0]].y;for(let f=1;f0&&(ma&&(a=m),vd&&(d=v))}let h=Math.abs(a-o)-Math.abs(d-r);h>0?(r-=.5*h,d+=.5*h):(o+=.5*h,a-=.5*h);let c=Math.max(1e-5,Math.abs(a-o)),u=.5*c,p=.5*(o+a),b=.5*(r+d),C={root:{centerOfMass:{x:0,y:0},mass:0,range:{minX:p-u,maxX:p+u,minY:b-u,maxY:b+u},size:c,calcSize:1/c,children:{data:null},maxWidth:0,level:0,childrenCount:4}};this._splitBranch(C.root);for(let f=0;f0&&this._placeInTree(C.root,i);return C}_updateBranchMass(e,t){let i=e.centerOfMass,s=e.mass+t.options.mass,o=1/s;i.x=i.x*e.mass+t.x*t.options.mass,i.x*=o,i.y=i.y*e.mass+t.y*t.options.mass,i.y*=o,e.mass=s;let r=Math.max(Math.max(t.height,t.radius),t.width);e.maxWidth=e.maxWidtht.x?s.maxY>t.y?o="NW":o="SW":s.maxY>t.y?o="NE":o="SE",this._placeInRegion(e,t,o)}_placeInRegion(e,t,i){let s=e.children[i];switch(s.childrenCount){case 0:s.children.data=t,s.childrenCount=1,this._updateBranchMass(s,t);break;case 1:s.children.data.x===t.x&&s.children.data.y===t.y?(t.x+=this._rng(),t.y+=this._rng()):(this._splitBranch(s),this._placeInTree(s,t));break;case 4:this._placeInTree(s,t);break}}_splitBranch(e){let t=null;e.childrenCount===1&&(t=e.children.data,e.mass=0,e.centerOfMass.x=0,e.centerOfMass.y=0),e.childrenCount=4,e.children.data=null,this._insertRegion(e,"NW"),this._insertRegion(e,"NE"),this._insertRegion(e,"SW"),this._insertRegion(e,"SE"),t!=null&&this._placeInTree(e,t)}_insertRegion(e,t){let i,s,o,r,a=.5*e.size;switch(t){case"NW":i=e.range.minX,s=e.range.minX+a,o=e.range.minY,r=e.range.minY+a;break;case"NE":i=e.range.minX+a,s=e.range.maxX,o=e.range.minY,r=e.range.minY+a;break;case"SW":i=e.range.minX,s=e.range.minX+a,o=e.range.minY+a,r=e.range.maxY;break;case"SE":i=e.range.minX+a,s=e.range.maxX,o=e.range.minY+a,r=e.range.maxY;break}e.children[t]={centerOfMass:{x:0,y:0},mass:0,range:{minX:i,maxX:s,minY:o,maxY:r},size:.5*e.size,calcSize:2*e.calcSize,children:{data:null},maxWidth:0,level:e.level+1,childrenCount:0}}_debug(e,t){this.barnesHutTree!==void 0&&(e.lineWidth=1,this._drawBranch(this.barnesHutTree.root,e,t))}_drawBranch(e,t,i){i===void 0&&(i="#FF0000"),e.childrenCount===4&&(this._drawBranch(e.children.NW,t),this._drawBranch(e.children.NE,t),this._drawBranch(e.children.SE,t),this._drawBranch(e.children.SW,t)),t.strokeStyle=i,t.beginPath(),t.moveTo(e.range.minX,e.range.minY),t.lineTo(e.range.maxX,e.range.minY),t.stroke(),t.beginPath(),t.moveTo(e.range.maxX,e.range.minY),t.lineTo(e.range.maxX,e.range.maxY),t.stroke(),t.beginPath(),t.moveTo(e.range.maxX,e.range.maxY),t.lineTo(e.range.minX,e.range.maxY),t.stroke(),t.beginPath(),t.moveTo(e.range.minX,e.range.maxY),t.lineTo(e.range.minX,e.range.minY),t.stroke()}},nn=class{constructor(e,t,i){this._rng=gt("REPULSION SOLVER"),this.body=e,this.physicsBody=t,this.setOptions(i)}setOptions(e){this.options=e}solve(){let e,t,i,s,o,r,a,d,h=this.body.nodes,l=this.physicsBody.physicsNodeIndices,c=this.physicsBody.forces,u=this.options.nodeDistance,p=-2/3/u,b=4/3;for(let C=0;C0){let r=o.edges.length+1,a=this.options.centralGravity*r*o.options.mass;s[o.id].x=t*a,s[o.id].y=i*a}}},ln=class{constructor(e){this.body=e,this.physicsBody={physicsNodeIndices:[],physicsEdgeIndices:[],forces:{},velocities:{}},this.physicsEnabled=!0,this.simulationInterval=1e3/60,this.requiresTimeout=!0,this.previousStates={},this.referenceState={},this.freezeCache={},this.renderTimer=void 0,this.adaptiveTimestep=!1,this.adaptiveTimestepEnabled=!1,this.adaptiveCounter=0,this.adaptiveInterval=3,this.stabilized=!1,this.startedStabilization=!1,this.stabilizationIterations=0,this.ready=!1,this.options={},this.defaultOptions={enabled:!0,barnesHut:{theta:.5,gravitationalConstant:-2e3,centralGravity:.3,springLength:95,springConstant:.04,damping:.09,avoidOverlap:0},forceAtlas2Based:{theta:.5,gravitationalConstant:-50,centralGravity:.01,springConstant:.08,springLength:100,damping:.4,avoidOverlap:0},repulsion:{centralGravity:.2,springLength:200,springConstant:.05,nodeDistance:100,damping:.09,avoidOverlap:0},hierarchicalRepulsion:{centralGravity:0,springLength:100,springConstant:.01,nodeDistance:120,damping:.09},maxVelocity:50,minVelocity:.75,solver:"barnesHut",stabilization:{enabled:!0,iterations:1e3,updateInterval:50,onlyDynamicEdges:!1,fit:!0},timestep:.5,adaptiveTimestep:!0,wind:{x:0,y:0}},Object.assign(this.options,this.defaultOptions),this.timestep=.5,this.layoutFailed=!1,this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("initPhysics",()=>{this.initPhysics()}),this.body.emitter.on("_layoutFailed",()=>{this.layoutFailed=!0}),this.body.emitter.on("resetPhysics",()=>{this.stopSimulation(),this.ready=!1}),this.body.emitter.on("disablePhysics",()=>{this.physicsEnabled=!1,this.stopSimulation()}),this.body.emitter.on("restorePhysics",()=>{this.setOptions(this.options),this.ready===!0&&this.startSimulation()}),this.body.emitter.on("startSimulation",()=>{this.ready===!0&&this.startSimulation()}),this.body.emitter.on("stopSimulation",()=>{this.stopSimulation()}),this.body.emitter.on("destroy",()=>{this.stopSimulation(!1),this.body.emitter.off()}),this.body.emitter.on("_dataChanged",()=>{this.updatePhysicsData()})}setOptions(e){if(e!==void 0)if(e===!1)this.options.enabled=!1,this.physicsEnabled=!1,this.stopSimulation();else if(e===!0)this.options.enabled=!0,this.physicsEnabled=!0,this.startSimulation();else{this.physicsEnabled=!0,mt(["stabilization"],this.options,e),ae(this.options,e,"stabilization"),e.enabled===void 0&&(this.options.enabled=!0),this.options.enabled===!1&&(this.physicsEnabled=!1,this.stopSimulation());let t=this.options.wind;t&&((typeof t.x!="number"||Number.isNaN(t.x))&&(t.x=0),(typeof t.y!="number"||Number.isNaN(t.y))&&(t.y=0)),this.timestep=this.options.timestep}this.init()}init(){let e;this.options.solver==="forceAtlas2Based"?(e=this.options.forceAtlas2Based,this.nodesSolver=new dn(this.body,this.physicsBody,e),this.edgesSolver=new Qt(this.body,this.physicsBody,e),this.gravitySolver=new hn(this.body,this.physicsBody,e)):this.options.solver==="repulsion"?(e=this.options.repulsion,this.nodesSolver=new nn(this.body,this.physicsBody,e),this.edgesSolver=new Qt(this.body,this.physicsBody,e),this.gravitySolver=new Et(this.body,this.physicsBody,e)):this.options.solver==="hierarchicalRepulsion"?(e=this.options.hierarchicalRepulsion,this.nodesSolver=new rn(this.body,this.physicsBody,e),this.edgesSolver=new an(this.body,this.physicsBody,e),this.gravitySolver=new Et(this.body,this.physicsBody,e)):(e=this.options.barnesHut,this.nodesSolver=new Ri(this.body,this.physicsBody,e),this.edgesSolver=new Qt(this.body,this.physicsBody,e),this.gravitySolver=new Et(this.body,this.physicsBody,e)),this.modelOptions=e}initPhysics(){this.physicsEnabled===!0&&this.options.enabled===!0?this.options.stabilization.enabled===!0?this.stabilize():(this.stabilized=!1,this.ready=!0,this.body.emitter.emit("fit",{},this.layoutFailed),this.startSimulation()):(this.ready=!0,this.body.emitter.emit("fit"))}startSimulation(){this.physicsEnabled===!0&&this.options.enabled===!0?(this.stabilized=!1,this.adaptiveTimestep=!1,this.body.emitter.emit("_resizeNodes"),this.viewFunction===void 0&&(this.viewFunction=this.simulationStep.bind(this),this.body.emitter.on("initRedraw",this.viewFunction),this.body.emitter.emit("_startRendering"))):this.body.emitter.emit("_redraw")}stopSimulation(e=!0){this.stabilized=!0,e===!0&&this._emitStabilized(),this.viewFunction!==void 0&&(this.body.emitter.off("initRedraw",this.viewFunction),this.viewFunction=void 0,e===!0&&this.body.emitter.emit("_stopRendering"))}simulationStep(){let e=Date.now();this.physicsTick(),(Date.now()-e<.4*this.simulationInterval||this.runDoubleSpeed===!0)&&this.stabilized===!1&&(this.physicsTick(),this.runDoubleSpeed=!0),this.stabilized===!0&&this.stopSimulation()}_emitStabilized(e=this.stabilizationIterations){(this.stabilizationIterations>1||this.startedStabilization===!0)&&setTimeout(()=>{this.body.emitter.emit("stabilized",{iterations:e}),this.startedStabilization=!1,this.stabilizationIterations=0},0)}physicsStep(){this.gravitySolver.solve(),this.nodesSolver.solve(),this.edgesSolver.solve(),this.moveNodes()}adjustTimeStep(){let e=1.2;this._evaluateStepQuality()===!0?this.timestep=e*this.timestep:this.timestep/er))return!1;return!0}moveNodes(){let e=this.physicsBody.physicsNodeIndices,t=0,i=0,s=5;for(let o=0;or&&(e=e>0?r:-r),e}_performStep(e){let t=this.body.nodes[e],i=this.physicsBody.forces[e];this.options.wind&&(i.x+=this.options.wind.x,i.y+=this.options.wind.y);let s=this.physicsBody.velocities[e];return this.previousStates[e]={x:t.x,y:t.y,vx:s.x,vy:s.y},t.options.fixed.x===!1?(s.x=this.calculateComponentVelocity(s.x,i.x,t.options.mass),t.x+=s.x*this.timestep):(i.x=0,s.x=0),t.options.fixed.y===!1?(s.y=this.calculateComponentVelocity(s.y,i.y,t.options.mass),t.y+=s.y*this.timestep):(i.y=0,s.y=0),Math.sqrt(Math.pow(s.x,2)+Math.pow(s.y,2))}_freezeNodes(){let e=this.body.nodes;for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t)&&e[t].x&&e[t].y){let i=e[t].options.fixed;this.freezeCache[t]={x:i.x,y:i.y},i.x=!0,i.y=!0}}_restoreFrozenNodes(){let e=this.body.nodes;for(let t in e)Object.prototype.hasOwnProperty.call(e,t)&&this.freezeCache[t]!==void 0&&(e[t].options.fixed.x=this.freezeCache[t].x,e[t].options.fixed.y=this.freezeCache[t].y);this.freezeCache={}}stabilize(e=this.options.stabilization.iterations){if(typeof e!="number"&&(e=this.options.stabilization.iterations,console.error("The stabilize method needs a numeric amount of iterations. Switching to default: ",e)),this.physicsBody.physicsNodeIndices.length===0){this.ready=!0;return}this.adaptiveTimestep=this.options.adaptiveTimestep,this.body.emitter.emit("_resizeNodes"),this.stopSimulation(),this.stabilized=!1,this.body.emitter.emit("_blockRedraw"),this.targetIterations=e,this.options.stabilization.onlyDynamicEdges===!0&&this._freezeNodes(),this.stabilizationIterations=0,setTimeout(()=>this._stabilizationBatch(),0)}_startStabilizing(){return this.startedStabilization===!0?!1:(this.body.emitter.emit("startStabilizing"),this.startedStabilization=!0,!0)}_stabilizationBatch(){let e=()=>this.stabilized===!1&&this.stabilizationIterations{this.body.emitter.emit("stabilizationProgress",{iterations:this.stabilizationIterations,total:this.targetIterations})};this._startStabilizing()&&t();let i=0;for(;e()&&i0)for(let d=0;da.shape.boundingBox.left&&(o=a.shape.boundingBox.left),ra.shape.boundingBox.top&&(i=a.shape.boundingBox.top),s0)for(let d=0;da.x&&(o=a.x),ra.y&&(i=a.y),s{delete this.containedEdges[i.id]}),A(t.containedNodes,(i,s)=>{this.containedNodes[s]=i}),t.containedNodes={},A(t.containedEdges,(i,s)=>{this.containedEdges[s]=i}),t.containedEdges={},A(t.edges,i=>{A(this.edges,s=>{let o=s.clusteringEdgeReplacingIds.indexOf(i.id);o!==-1&&(A(i.clusteringEdgeReplacingIds,r=>{s.clusteringEdgeReplacingIds.push(r),this.body.edges[r].edgeReplacedById=s.id}),s.clusteringEdgeReplacingIds.splice(o,1))})}),t.edges=[]}},un=class{constructor(e){this.body=e,this.clusteredNodes={},this.clusteredEdges={},this.options={},this.defaultOptions={},Object.assign(this.options,this.defaultOptions),this.body.emitter.on("_resetData",()=>{this.clusteredNodes={},this.clusteredEdges={}})}clusterByHubsize(e,t){e===void 0?e=this._getHubSize():typeof e=="object"&&(t=this._checkOptions(e),e=this._getHubSize());let i=[];for(let s=0;s=e&&i.push(o.id)}for(let s=0;s{o.options&&e.joinCondition(o.options)===!0&&(i[r]=o,A(o.edges,a=>{this.clusteredEdges[a.id]===void 0&&(s[a.id]=a)}))}),this._cluster(i,s,e,t)}clusterByEdgeCount(e,t,i=!0){t=this._checkOptions(t);let s=[],o={},r,a,d;for(let h=0;h0&&Object.keys(c).length>0&&C===!0){let g=function(){for(let m=0;m-1&&(r[p.id]=p)}}this._cluster(o,r,t,i)}_createClusterEdges(e,t,i,s){let o,r,a,d,h,l,c=Object.keys(e),u=[];for(let C=0;Cs?a.x:s,o=a.yr?a.y:r;return{x:.5*(i+s),y:.5*(o+r)}}openCluster(e,t,i=!0){if(e===void 0)throw new Error("No clusterNodeId supplied to openCluster.");let s=this.body.nodes[e];if(s===void 0)throw new Error("The clusterNodeId supplied to openCluster does not exist.");if(s.isCluster!==!0||s.containedNodes===void 0||s.containedEdges===void 0)throw new Error("The node:"+e+" is not a valid cluster.");let o=this.findNode(e),r=o.indexOf(e)-1;if(r>=0){let l=o[r];this.body.nodes[l]._openChildCluster(e),delete this.body.nodes[e],i===!0&&this.body.emitter.emit("_dataChanged");return}let a=s.containedNodes,d=s.containedEdges;if(t!==void 0&&t.releaseFunction!==void 0&&typeof t.releaseFunction=="function"){let l={},c={x:s.x,y:s.y};for(let p in a)if(Object.prototype.hasOwnProperty.call(a,p)){let b=this.body.nodes[p];l[p]={x:b.x,y:b.y}}let u=t.releaseFunction(c,l);for(let p in a)if(Object.prototype.hasOwnProperty.call(a,p)){let b=this.body.nodes[p];u[p]!==void 0&&(b.x=u[p].x===void 0?s.x:u[p].x,b.y=u[p].y===void 0?s.y:u[p].y)}}else A(a,function(l){l.options.fixed.x===!1&&(l.x=s.x),l.options.fixed.y===!1&&(l.y=s.y)});for(let l in a)if(Object.prototype.hasOwnProperty.call(a,l)){let c=this.body.nodes[l];c.vx=s.vx,c.vy=s.vy,c.setOptions({physics:!0}),delete this.clusteredNodes[l]}let h=[];for(let l=0;l0&&rs&&(s=h.edges.length),e+=h.edges.length,t+=Math.pow(h.edges.length,2),i+=1}e=e/i,t=t/i;let o=t-Math.pow(e,2),r=Math.sqrt(o),a=Math.floor(e+2*r);return a>s&&(a=s),a}_createClusteredEdge(e,t,i,s,o){let r=J.cloneOptions(i,"edge");j(r,s),r.from=e,r.to=t,r.id="clusterEdge:"+Te(),o!==void 0&&j(r,o);let a=this.body.functions.createEdge(r);return a.clusteringEdgeReplacingIds=[i.id],a.connect(),this.body.edges[a.id]=a,a}_clusterEdges(e,t,i,s){if(t instanceof Se){let o=t,r={};r[o.id]=o,t=r}if(e instanceof U){let o=e,r={};r[o.id]=o,e=r}if(i==null)throw new Error("_clusterEdges: parameter clusterNode required");s===void 0&&(s=i.clusterEdgeProperties),this._createClusterEdges(e,t,i,s);for(let o in t)if(Object.prototype.hasOwnProperty.call(t,o)&&this.body.edges[o]!==void 0){let r=this.body.edges[o];this._backupEdgeOptions(r),r.setOptions({physics:!1})}for(let o in e)Object.prototype.hasOwnProperty.call(e,o)&&(this.clusteredNodes[o]={clusterId:i.id,node:this.body.nodes[o]},this.body.nodes[o].setOptions({physics:!1}))}_getClusterNodeForNode(e){if(e===void 0)return;let t=this.clusteredNodes[e];if(t===void 0)return;let i=t.clusterId;if(i!==void 0)return this.body.nodes[i]}_filter(e,t){let i=[];return A(e,s=>{t(s)&&i.push(s)}),i}_updateState(){let e,t=[],i={},s=d=>{A(this.body.nodes,h=>{h.isCluster===!0&&d(h)})};for(e in this.clusteredNodes){if(!Object.prototype.hasOwnProperty.call(this.clusteredNodes,e))continue;this.body.nodes[e]===void 0&&t.push(e)}s(function(d){for(let h=0;h{let h=this.body.edges[d];(h===void 0||!h.endPointsValid())&&(i[d]=d)}),s(function(d){A(d.containedEdges,(h,l)=>{!h.endPointsValid()&&!i[l]&&(i[l]=l)})}),A(this.body.edges,(d,h)=>{let l=!0,c=d.clusteringEdgeReplacingIds;if(c!==void 0){let u=0;A(c,p=>{let b=this.body.edges[p];b!==void 0&&b.endPointsValid()&&(u+=1)}),l=u>0}(!d.endPointsValid()||!l)&&(i[h]=h)}),s(d=>{A(i,h=>{delete d.containedEdges[h],A(d.edges,(l,c)=>{if(l.id===h){d.edges[c]=null;return}l.clusteringEdgeReplacingIds=this._filter(l.clusteringEdgeReplacingIds,function(u){return!i[u]})}),d.edges=this._filter(d.edges,function(l){return l!==null})})}),A(i,d=>{delete this.clusteredEdges[d]}),A(i,d=>{delete this.body.edges[d]});let o=Object.keys(this.body.edges);A(o,d=>{let h=this.body.edges[d],l=this._isClusteredNode(h.fromId)||this._isClusteredNode(h.toId);if(l!==this._isClusteredEdge(h.id))if(l){let c=this._getClusterNodeForNode(h.fromId);c!==void 0&&this._clusterEdges(this.body.nodes[h.fromId],h,c);let u=this._getClusterNodeForNode(h.toId);u!==void 0&&this._clusterEdges(this.body.nodes[h.toId],h,u)}else delete this._clusterEdges[d],this._restoreEdge(h)});let r=!1,a=!0;for(;a;){let d=[];s(function(h){let l=Object.keys(h.containedNodes).length,c=h.options.allowSingleNodeCluster===!0;(c&&l<1||!c&&l<2)&&d.push(h.id)});for(let h=0;h0,r=r||a}r&&this._updateState()}_isClusteredNode(e){return this.clusteredNodes[e]!==void 0}_isClusteredEdge(e){return this.clusteredEdges[e]!==void 0}};function Fa(){let n;window!==void 0&&(n=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame),n===void 0?window.requestAnimationFrame=function(e){e()}:window.requestAnimationFrame=n}var fn=class{constructor(e,t){Fa(),this.body=e,this.canvas=t,this.redrawRequested=!1,this.renderTimer=void 0,this.requiresTimeout=!0,this.renderingActive=!1,this.renderRequests=0,this.allowRedraw=!0,this.dragging=!1,this.zooming=!1,this.options={},this.defaultOptions={hideEdgesOnDrag:!1,hideEdgesOnZoom:!1,hideNodesOnDrag:!1},Object.assign(this.options,this.defaultOptions),this._determineBrowserMethod(),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("dragStart",()=>{this.dragging=!0}),this.body.emitter.on("dragEnd",()=>{this.dragging=!1}),this.body.emitter.on("zoom",()=>{this.zooming=!0,window.clearTimeout(this.zoomTimeoutId),this.zoomTimeoutId=window.setTimeout(()=>{this.zooming=!1,this._requestRedraw.bind(this)()},250)}),this.body.emitter.on("_resizeNodes",()=>{this._resizeNodes()}),this.body.emitter.on("_redraw",()=>{this.renderingActive===!1&&this._redraw()}),this.body.emitter.on("_blockRedraw",()=>{this.allowRedraw=!1}),this.body.emitter.on("_allowRedraw",()=>{this.allowRedraw=!0,this.redrawRequested=!1}),this.body.emitter.on("_requestRedraw",this._requestRedraw.bind(this)),this.body.emitter.on("_startRendering",()=>{this.renderRequests+=1,this.renderingActive=!0,this._startRendering()}),this.body.emitter.on("_stopRendering",()=>{this.renderRequests-=1,this.renderingActive=this.renderRequests>0,this.renderTimer=void 0}),this.body.emitter.on("destroy",()=>{this.renderRequests=0,this.allowRedraw=!1,this.renderingActive=!1,this.requiresTimeout===!0?clearTimeout(this.renderTimer):window.cancelAnimationFrame(this.renderTimer),this.body.emitter.off()})}setOptions(e){e!==void 0&&Ve(["hideEdgesOnDrag","hideEdgesOnZoom","hideNodesOnDrag"],this.options,e)}_requestNextFrame(e,t){if(typeof window=="undefined")return;let i,s=window;return this.requiresTimeout===!0?i=s.setTimeout(e,t):s.requestAnimationFrame&&(i=s.requestAnimationFrame(e)),i}_startRendering(){this.renderingActive===!0&&this.renderTimer===void 0&&(this.renderTimer=this._requestNextFrame(this._renderStep.bind(this),this.simulationInterval))}_renderStep(){this.renderingActive===!0&&(this.renderTimer=void 0,this.requiresTimeout===!0&&this._startRendering(),this._redraw(),this.requiresTimeout===!1&&this._startRendering())}redraw(){this.body.emitter.emit("setSize"),this._redraw()}_requestRedraw(){this.redrawRequested!==!0&&this.renderingActive===!1&&this.allowRedraw===!0&&(this.redrawRequested=!0,this._requestNextFrame(()=>{this._redraw(!1)},0))}_redraw(e=!1){if(this.allowRedraw===!0){this.body.emitter.emit("initRedraw"),this.redrawRequested=!1;let t={drawExternalLabels:null};(this.canvas.frame.canvas.width===0||this.canvas.frame.canvas.height===0)&&this.canvas.setSize(),this.canvas.setTransform();let i=this.canvas.getContext(),s=this.canvas.frame.canvas.clientWidth,o=this.canvas.frame.canvas.clientHeight;if(i.clearRect(0,0,s,o),this.canvas.frame.clientWidth===0)return;if(i.save(),i.translate(this.body.view.translation.x,this.body.view.translation.y),i.scale(this.body.view.scale,this.body.view.scale),i.beginPath(),this.body.emitter.emit("beforeDrawing",i),i.closePath(),e===!1&&(this.dragging===!1||this.dragging===!0&&this.options.hideEdgesOnDrag===!1)&&(this.zooming===!1||this.zooming===!0&&this.options.hideEdgesOnZoom===!1)&&this._drawEdges(i),this.dragging===!1||this.dragging===!0&&this.options.hideNodesOnDrag===!1){let{drawExternalLabels:r}=this._drawNodes(i,e);t.drawExternalLabels=r}e===!1&&(this.dragging===!1||this.dragging===!0&&this.options.hideEdgesOnDrag===!1)&&(this.zooming===!1||this.zooming===!0&&this.options.hideEdgesOnZoom===!1)&&this._drawArrows(i),t.drawExternalLabels!=null&&t.drawExternalLabels(),e===!1&&this._drawSelectionBox(i),i.beginPath(),this.body.emitter.emit("afterDrawing",i),i.closePath(),i.restore(),e===!0&&i.clearRect(0,0,s,o)}}_resizeNodes(){this.canvas.setTransform();let e=this.canvas.getContext();e.save(),e.translate(this.body.view.translation.x,this.body.view.translation.y),e.scale(this.body.view.scale,this.body.view.scale);let t=this.body.nodes,i;for(let s in t)Object.prototype.hasOwnProperty.call(t,s)&&(i=t[s],i.resize(e),i.updateBoundingBox(e,i.selected));e.restore()}_drawNodes(e,t=!1){let i=this.body.nodes,s=this.body.nodeIndices,o,r=[],a=[],d=20,h=this.canvas.DOMtoCanvas({x:-d,y:-d}),l=this.canvas.DOMtoCanvas({x:this.canvas.frame.canvas.clientWidth+d,y:this.canvas.frame.canvas.clientHeight+d}),c={top:h.y,left:h.x,bottom:l.y,right:l.x},u=[];for(let f=0;f{for(let f of u)f()}}}_drawEdges(e){let t=this.body.edges,i=this.body.edgeIndices;for(let s=0;s{e.width!==0&&(this.body.view.translation.x=e.width*.5),e.height!==0&&(this.body.view.translation.y=e.height*.5)}),this.body.emitter.on("setSize",this.setSize.bind(this)),this.body.emitter.on("destroy",()=>{this.hammerFrame.destroy(),this.hammer.destroy(),this._cleanUp()})}setOptions(e){if(e!==void 0&&Ve(["width","height","autoResize"],this.options,e),this._cleanUp(),this.options.autoResize===!0){if(window.ResizeObserver){let i=new ResizeObserver(()=>{this.setSize()===!0&&this.body.emitter.emit("_requestRedraw")}),{frame:s}=this;i.observe(s),this._cleanupCallbacks.push(()=>{i.unobserve(s)})}else{let i=setInterval(()=>{this.setSize()===!0&&this.body.emitter.emit("_requestRedraw")},1e3);this._cleanupCallbacks.push(()=>{clearInterval(i)})}let t=this._onResize.bind(this);Rs(window,"resize",t),this._cleanupCallbacks.push(()=>{Hs(window,"resize",t)})}}_cleanUp(){this._cleanupCallbacks.splice(0).reverse().forEach(e=>{try{e()}catch(t){console.error(t)}})}_onResize(){this.setSize(),this.body.emitter.emit("_redraw")}_getCameraState(e=this.pixelRatio){this.initialized===!0&&(this.cameraState.previousWidth=this.frame.canvas.width/e,this.cameraState.previousHeight=this.frame.canvas.height/e,this.cameraState.scale=this.body.view.scale,this.cameraState.position=this.DOMtoCanvas({x:.5*this.frame.canvas.width/e,y:.5*this.frame.canvas.height/e}))}_setCameraState(){if(this.cameraState.scale!==void 0&&this.frame.canvas.clientWidth!==0&&this.frame.canvas.clientHeight!==0&&this.pixelRatio!==0&&this.cameraState.previousWidth>0&&this.cameraState.previousHeight>0){let e=this.frame.canvas.width/this.pixelRatio/this.cameraState.previousWidth,t=this.frame.canvas.height/this.pixelRatio/this.cameraState.previousHeight,i=this.cameraState.scale;e!=1&&t!=1?i=this.cameraState.scale*.5*(e+t):e!=1?i=this.cameraState.scale*e:t!=1&&(i=this.cameraState.scale*t),this.body.view.scale=i;let s=this.DOMtoCanvas({x:.5*this.frame.canvas.clientWidth,y:.5*this.frame.canvas.clientHeight}),o={x:s.x-this.cameraState.position.x,y:s.y-this.cameraState.position.y};this.body.view.translation.x+=o.x*this.body.view.scale,this.body.view.translation.y+=o.y*this.body.view.scale}}_prepareValue(e){if(typeof e=="number")return e+"px";if(typeof e=="string"){if(e.indexOf("%")!==-1||e.indexOf("px")!==-1)return e;if(e.indexOf("%")===-1)return e+"px"}throw new Error("Could not use the value supplied for width or height:"+e)}_create(){for(;this.body.container.hasChildNodes();)this.body.container.removeChild(this.body.container.firstChild);if(this.frame=document.createElement("div"),this.frame.className="vis-network",this.frame.style.position="relative",this.frame.style.overflow="hidden",this.frame.tabIndex=0,this.frame.canvas=document.createElement("canvas"),this.frame.canvas.style.position="relative",this.frame.appendChild(this.frame.canvas),this.frame.canvas.getContext)this._setPixelRatio(),this.setTransform();else{let e=document.createElement("DIV");e.style.color="red",e.style.fontWeight="bold",e.style.padding="10px",e.innerText="Error: your browser does not support HTML canvas",this.frame.canvas.appendChild(e)}this.body.container.appendChild(this.frame),this.body.view.scale=1,this.body.view.translation={x:.5*this.frame.canvas.clientWidth,y:.5*this.frame.canvas.clientHeight},this._bindHammer()}_bindHammer(){this.hammer!==void 0&&this.hammer.destroy(),this.drag={},this.pinch={},this.hammer=new qe(this.frame.canvas),this.hammer.get("pinch").set({enable:!0}),this.hammer.get("pan").set({threshold:5,direction:qe.DIRECTION_ALL}),$t(this.hammer,e=>{this.body.eventListeners.onTouch(e)}),this.hammer.on("tap",e=>{this.body.eventListeners.onTap(e)}),this.hammer.on("doubletap",e=>{this.body.eventListeners.onDoubleTap(e)}),this.hammer.on("press",e=>{this.body.eventListeners.onHold(e)}),this.hammer.on("panstart",e=>{this.body.eventListeners.onDragStart(e)}),this.hammer.on("panmove",e=>{this.body.eventListeners.onDrag(e)}),this.hammer.on("panend",e=>{this.body.eventListeners.onDragEnd(e)}),this.hammer.on("pinch",e=>{this.body.eventListeners.onPinch(e)}),this.frame.canvas.addEventListener("wheel",e=>{this.body.eventListeners.onMouseWheel(e)}),this.frame.canvas.addEventListener("mousemove",e=>{this.body.eventListeners.onMouseMove(e)}),this.frame.canvas.addEventListener("contextmenu",e=>{this.body.eventListeners.onContext(e)}),this.hammerFrame=new qe(this.frame),pn(this.hammerFrame,e=>{this.body.eventListeners.onRelease(e)})}setSize(e=this.options.width,t=this.options.height){e=this._prepareValue(e),t=this._prepareValue(t);let i=!1,s=this.frame.canvas.width,o=this.frame.canvas.height,r=this.pixelRatio;if(this._setPixelRatio(),e!=this.options.width||t!=this.options.height||this.frame.style.width!=e||this.frame.style.height!=t)this._getCameraState(r),this.frame.style.width=e,this.frame.style.height=t,this.frame.canvas.style.width="100%",this.frame.canvas.style.height="100%",this.frame.canvas.width=Math.round(this.frame.canvas.clientWidth*this.pixelRatio),this.frame.canvas.height=Math.round(this.frame.canvas.clientHeight*this.pixelRatio),this.options.width=e,this.options.height=t,this.canvasViewCenter={x:.5*this.frame.clientWidth,y:.5*this.frame.clientHeight},i=!0;else{let a=Math.round(this.frame.canvas.clientWidth*this.pixelRatio),d=Math.round(this.frame.canvas.clientHeight*this.pixelRatio);(this.frame.canvas.width!==a||this.frame.canvas.height!==d)&&this._getCameraState(r),this.frame.canvas.width!==a&&(this.frame.canvas.width=a,i=!0),this.frame.canvas.height!==d&&(this.frame.canvas.height=d,i=!0)}return i===!0&&(this.body.emitter.emit("resize",{width:Math.round(this.frame.canvas.width/this.pixelRatio),height:Math.round(this.frame.canvas.height/this.pixelRatio),oldWidth:Math.round(s/this.pixelRatio),oldHeight:Math.round(o/this.pixelRatio)}),this._setCameraState()),this.initialized=!0,i}getContext(){return this.frame.canvas.getContext("2d")}_determinePixelRatio(){let e=this.getContext();if(e===void 0)throw new Error("Could not get canvax context");let t=1;typeof window!="undefined"&&(t=window.devicePixelRatio||1);let i=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return t/i}_setPixelRatio(){this.pixelRatio=this._determinePixelRatio()}setTransform(){let e=this.getContext();if(e===void 0)throw new Error("Could not get canvax context");e.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0)}_XconvertDOMtoCanvas(e){return(e-this.body.view.translation.x)/this.body.view.scale}_XconvertCanvasToDOM(e){return e*this.body.view.scale+this.body.view.translation.x}_YconvertDOMtoCanvas(e){return(e-this.body.view.translation.y)/this.body.view.scale}_YconvertCanvasToDOM(e){return e*this.body.view.scale+this.body.view.translation.y}canvasToDOM(e){return{x:this._XconvertCanvasToDOM(e.x),y:this._YconvertCanvasToDOM(e.y)}}DOMtoCanvas(e){return{x:this._XconvertDOMtoCanvas(e.x),y:this._YconvertDOMtoCanvas(e.y)}}};function Na(n,e){let t=Object.assign({nodes:e,minZoomLevel:Number.MIN_VALUE,maxZoomLevel:1},n!=null?n:{});if(!Array.isArray(t.nodes))throw new TypeError("Nodes has to be an array of ids.");if(t.nodes.length===0&&(t.nodes=e),!(typeof t.minZoomLevel=="number"&&t.minZoomLevel>0))throw new TypeError("Min zoom level has to be a number higher than zero.");if(!(typeof t.maxZoomLevel=="number"&&t.minZoomLevel<=t.maxZoomLevel))throw new TypeError("Max zoom level has to be a number higher than min zoom level.");return t}var mn=class{constructor(e,t){this.body=e,this.canvas=t,this.animationSpeed=1/this.renderRefreshRate,this.animationEasingFunction="easeInOutQuint",this.easingTime=0,this.sourceScale=0,this.targetScale=0,this.sourceTranslation=0,this.targetTranslation=0,this.lockedOnNodeId=void 0,this.lockedOnNodeOffset=void 0,this.touchTime=0,this.viewFunction=void 0,this.body.emitter.on("fit",this.fit.bind(this)),this.body.emitter.on("animationFinished",()=>{this.body.emitter.emit("_stopRendering")}),this.body.emitter.on("unlockNode",this.releaseNode.bind(this))}setOptions(e={}){this.options=e}fit(e,t=!1){e=Na(e,this.body.nodeIndices);let i=this.canvas.frame.canvas.clientWidth,s=this.canvas.frame.canvas.clientHeight,o,r;if(i===0||s===0)r=1,o=J.getRange(this.body.nodes,e.nodes);else if(t===!0){let h=0;for(let u in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,u)&&this.body.nodes[u].predefinedPosition===!0&&(h+=1);if(h>.5*this.body.nodeIndices.length){this.fit(e,!1);return}o=J.getRange(this.body.nodes,e.nodes);let l=this.body.nodeIndices.length;r=12.662/(l+7.4147)+.0964822,r*=Math.min(i/600,s/600)}else{this.body.emitter.emit("_resizeNodes"),o=J.getRange(this.body.nodes,e.nodes);let h=Math.abs(o.maxX-o.minX)*1.1,l=Math.abs(o.maxY-o.minY)*1.1,c=i/h,u=s/l;r=c<=u?c:u}r>e.maxZoomLevel?r=e.maxZoomLevel:r0))throw new TypeError('The option "scale" has to be a number greater than zero.')}else e.scale=this.body.view.scale;e.animation===void 0&&(e.animation={duration:0}),e.animation===!1&&(e.animation={duration:0}),e.animation===!0&&(e.animation={}),e.animation.duration===void 0&&(e.animation.duration=1e3),e.animation.easingFunction===void 0&&(e.animation.easingFunction="easeInOutQuad"),this.animateView(e)}animateView(e){if(e===void 0)return;this.animationEasingFunction=e.animation.easingFunction,this.releaseNode(),e.locked===!0&&(this.lockedOnNodeId=e.lockedOnNode,this.lockedOnNodeOffset=e.offset),this.easingTime!=0&&this._transitionRedraw(!0),this.sourceScale=this.body.view.scale,this.sourceTranslation=this.body.view.translation,this.targetScale=e.scale,this.body.view.scale=this.targetScale;let t=this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight}),i={x:t.x-e.position.x,y:t.y-e.position.y};this.targetTranslation={x:this.sourceTranslation.x+i.x*this.targetScale+e.offset.x,y:this.sourceTranslation.y+i.y*this.targetScale+e.offset.y},e.animation.duration===0?this.lockedOnNodeId!=null?(this.viewFunction=this._lockedRedraw.bind(this),this.body.emitter.on("initRedraw",this.viewFunction)):(this.body.view.scale=this.targetScale,this.body.view.translation=this.targetTranslation,this.body.emitter.emit("_requestRedraw")):(this.animationSpeed=1/(60*e.animation.duration*.001)||1/60,this.animationEasingFunction=e.animation.easingFunction,this.viewFunction=this._transitionRedraw.bind(this),this.body.emitter.on("initRedraw",this.viewFunction),this.body.emitter.emit("_startRendering"))}_lockedRedraw(){let e={x:this.body.nodes[this.lockedOnNodeId].x,y:this.body.nodes[this.lockedOnNodeId].y},t=this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight}),i={x:t.x-e.x,y:t.y-e.y},s=this.body.view.translation,o={x:s.x+i.x*this.body.view.scale+this.lockedOnNodeOffset.x,y:s.y+i.y*this.body.view.scale+this.lockedOnNodeOffset.y};this.body.view.translation=o}releaseNode(){this.lockedOnNodeId!==void 0&&this.viewFunction!==void 0&&(this.body.emitter.off("initRedraw",this.viewFunction),this.lockedOnNodeId=void 0,this.lockedOnNodeOffset=void 0)}_transitionRedraw(e=!1){this.easingTime+=this.animationSpeed,this.easingTime=e===!0?1:this.easingTime;let t=qs[this.animationEasingFunction](this.easingTime);this.body.view.scale=this.sourceScale+(this.targetScale-this.sourceScale)*t,this.body.view.translation={x:this.sourceTranslation.x+(this.targetTranslation.x-this.sourceTranslation.x)*t,y:this.sourceTranslation.y+(this.targetTranslation.y-this.sourceTranslation.y)*t},this.easingTime>=1&&(this.body.emitter.off("initRedraw",this.viewFunction),this.easingTime=0,this.lockedOnNodeId!=null&&(this.viewFunction=this._lockedRedraw.bind(this),this.body.emitter.on("initRedraw",this.viewFunction)),this.body.emitter.emit("animationFinished"))}getScale(){return this.body.view.scale}getViewPosition(){return this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight})}},yn=class{constructor(e,t){this.body=e,this.canvas=t,this.iconsCreated=!1,this.navigationHammers=[],this.boundFunctions={},this.touchTime=0,this.activated=!1,this.body.emitter.on("activate",()=>{this.activated=!0,this.configureKeyboardBindings()}),this.body.emitter.on("deactivate",()=>{this.activated=!1,this.configureKeyboardBindings()}),this.body.emitter.on("destroy",()=>{this.keycharm!==void 0&&this.keycharm.destroy()}),this.options={}}setOptions(e){e!==void 0&&(this.options=e,this.create())}create(){this.options.navigationButtons===!0?this.iconsCreated===!1&&this.loadNavigationElements():this.iconsCreated===!0&&this.cleanNavigation(),this.configureKeyboardBindings()}cleanNavigation(){if(this.navigationHammers.length!=0){for(let e=0;e{this._stopMovement()}),this.navigationHammers.push(i),this.iconsCreated=!0}bindToRedraw(e){this.boundFunctions[e]===void 0&&(this.boundFunctions[e]=this[e].bind(this),this.body.emitter.on("initRedraw",this.boundFunctions[e]),this.body.emitter.emit("_startRendering"))}unbindFromRedraw(e){this.boundFunctions[e]!==void 0&&(this.body.emitter.off("initRedraw",this.boundFunctions[e]),this.body.emitter.emit("_stopRendering"),delete this.boundFunctions[e])}_fit(){new Date().valueOf()-this.touchTime>700&&(this.body.emitter.emit("fit",{duration:700}),this.touchTime=new Date().valueOf())}_stopMovement(){for(let e in this.boundFunctions)Object.prototype.hasOwnProperty.call(this.boundFunctions,e)&&(this.body.emitter.off("initRedraw",this.boundFunctions[e]),this.body.emitter.emit("_stopRendering"));this.boundFunctions={}}_moveUp(){this.body.view.translation.y+=this.options.keyboard.speed.y}_moveDown(){this.body.view.translation.y-=this.options.keyboard.speed.y}_moveLeft(){this.body.view.translation.x+=this.options.keyboard.speed.x}_moveRight(){this.body.view.translation.x-=this.options.keyboard.speed.x}_zoomIn(){let e=this.body.view.scale,t=this.body.view.scale*(1+this.options.keyboard.speed.zoom),i=this.body.view.translation,s=t/e,o=(1-s)*this.canvas.canvasViewCenter.x+i.x*s,r=(1-s)*this.canvas.canvasViewCenter.y+i.y*s;this.body.view.scale=t,this.body.view.translation={x:o,y:r},this.body.emitter.emit("zoom",{direction:"+",scale:this.body.view.scale,pointer:null})}_zoomOut(){let e=this.body.view.scale,t=this.body.view.scale/(1+this.options.keyboard.speed.zoom),i=this.body.view.translation,s=t/e,o=(1-s)*this.canvas.canvasViewCenter.x+i.x*s,r=(1-s)*this.canvas.canvasViewCenter.y+i.y*s;this.body.view.scale=t,this.body.view.translation={x:o,y:r},this.body.emitter.emit("zoom",{direction:"-",scale:this.body.view.scale,pointer:null})}configureKeyboardBindings(){this.keycharm!==void 0&&this.keycharm.destroy(),this.options.keyboard.enabled===!0&&(this.options.keyboard.bindToWindow===!0?this.keycharm=Ut({container:window,preventDefault:!0}):this.keycharm=Ut({container:this.canvas.frame,preventDefault:!0}),this.keycharm.reset(),this.activated===!0&&(this.keycharm.bind("up",()=>{this.bindToRedraw("_moveUp")},"keydown"),this.keycharm.bind("down",()=>{this.bindToRedraw("_moveDown")},"keydown"),this.keycharm.bind("left",()=>{this.bindToRedraw("_moveLeft")},"keydown"),this.keycharm.bind("right",()=>{this.bindToRedraw("_moveRight")},"keydown"),this.keycharm.bind("=",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("num+",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("num-",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("-",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("[",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("]",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("pageup",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("pagedown",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("up",()=>{this.unbindFromRedraw("_moveUp")},"keyup"),this.keycharm.bind("down",()=>{this.unbindFromRedraw("_moveDown")},"keyup"),this.keycharm.bind("left",()=>{this.unbindFromRedraw("_moveLeft")},"keyup"),this.keycharm.bind("right",()=>{this.unbindFromRedraw("_moveRight")},"keyup"),this.keycharm.bind("=",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("num+",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("num-",()=>{this.unbindFromRedraw("_zoomOut")},"keyup"),this.keycharm.bind("-",()=>{this.unbindFromRedraw("_zoomOut")},"keyup"),this.keycharm.bind("[",()=>{this.unbindFromRedraw("_zoomOut")},"keyup"),this.keycharm.bind("]",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("pageup",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("pagedown",()=>{this.unbindFromRedraw("_zoomOut")},"keyup")))}},bn=class{constructor(e,t,i){this.body=e,this.canvas=t,this.selectionHandler=i,this.navigationHandler=new yn(e,t),this.body.eventListeners.onTap=this.onTap.bind(this),this.body.eventListeners.onTouch=this.onTouch.bind(this),this.body.eventListeners.onDoubleTap=this.onDoubleTap.bind(this),this.body.eventListeners.onHold=this.onHold.bind(this),this.body.eventListeners.onDragStart=this.onDragStart.bind(this),this.body.eventListeners.onDrag=this.onDrag.bind(this),this.body.eventListeners.onDragEnd=this.onDragEnd.bind(this),this.body.eventListeners.onMouseWheel=this.onMouseWheel.bind(this),this.body.eventListeners.onPinch=this.onPinch.bind(this),this.body.eventListeners.onMouseMove=this.onMouseMove.bind(this),this.body.eventListeners.onRelease=this.onRelease.bind(this),this.body.eventListeners.onContext=this.onContext.bind(this),this.touchTime=0,this.drag={},this.pinch={},this.popup=void 0,this.popupObj=void 0,this.popupTimer=void 0,this.body.functions.getPointer=this.getPointer.bind(this),this.options={},this.defaultOptions={dragNodes:!0,dragView:!0,hover:!1,keyboard:{enabled:!1,speed:{x:10,y:10,zoom:.02},bindToWindow:!0,autoFocus:!0},navigationButtons:!1,tooltipDelay:300,zoomView:!0,zoomSpeed:1},Object.assign(this.options,this.defaultOptions),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("destroy",()=>{clearTimeout(this.popupTimer),delete this.body.functions.getPointer})}setOptions(e){e!==void 0&&(mt(["hideEdgesOnDrag","hideEdgesOnZoom","hideNodesOnDrag","keyboard","multiselect","selectable","selectConnectedEdges"],this.options,e),ae(this.options,e,"keyboard"),e.tooltip&&(Object.assign(this.options.tooltip,e.tooltip),e.tooltip.color&&(this.options.tooltip.color=Rt(e.tooltip.color)))),this.navigationHandler.setOptions(this.options)}getPointer(e){return{x:e.x-zs(this.canvas.frame.canvas),y:e.y-Ls(this.canvas.frame.canvas)}}onTouch(e){new Date().valueOf()-this.touchTime>50&&(this.drag.pointer=this.getPointer(e.center),this.drag.pinched=!1,this.pinch.scale=this.body.view.scale,this.touchTime=new Date().valueOf())}onTap(e){let t=this.getPointer(e.center),i=this.selectionHandler.options.multiselect&&(e.changedPointers[0].ctrlKey||e.changedPointers[0].metaKey);this.checkSelectionChanges(t,i),this.selectionHandler.commitAndEmit(t,e),this.selectionHandler.generateClickEvent("click",e,t)}onDoubleTap(e){let t=this.getPointer(e.center);this.selectionHandler.generateClickEvent("doubleClick",e,t)}onHold(e){let t=this.getPointer(e.center),i=this.selectionHandler.options.multiselect;this.checkSelectionChanges(t,i),this.selectionHandler.commitAndEmit(t,e),this.selectionHandler.generateClickEvent("click",e,t),this.selectionHandler.generateClickEvent("hold",e,t)}onRelease(e){if(new Date().valueOf()-this.touchTime>10){let t=this.getPointer(e.center);this.selectionHandler.generateClickEvent("release",e,t),this.touchTime=new Date().valueOf()}}onContext(e){let t=this.getPointer({x:e.clientX,y:e.clientY});this.selectionHandler.generateClickEvent("oncontext",e,t)}checkSelectionChanges(e,t=!1){t===!0?this.selectionHandler.selectAdditionalOnPoint(e):this.selectionHandler.selectOnPoint(e)}_determineDifference(e,t){let i=function(s,o){let r=[];for(let a=0;a{let a=r.node;r.xFixed===!1&&(a.x=this.canvas._XconvertDOMtoCanvas(this.canvas._XconvertCanvasToDOM(r.x)+s)),r.yFixed===!1&&(a.y=this.canvas._YconvertDOMtoCanvas(this.canvas._YconvertCanvasToDOM(r.y)+o))}),this.body.emitter.emit("startSimulation")}else{if(e.srcEvent.shiftKey){if(this.selectionHandler.generateClickEvent("dragging",e,t,void 0,!0),this.drag.pointer===void 0){this.onDragStart(e);return}this.body.selectionBox.position.end={x:this.canvas._XconvertDOMtoCanvas(t.x),y:this.canvas._YconvertDOMtoCanvas(t.y)},this.body.emitter.emit("_requestRedraw")}if(this.options.dragView===!0&&!e.srcEvent.shiftKey){if(this.selectionHandler.generateClickEvent("dragging",e,t,void 0,!0),this.drag.pointer===void 0){this.onDragStart(e);return}let s=t.x-this.drag.pointer.x,o=t.y-this.drag.pointer.y;this.body.view.translation={x:this.drag.translation.x+s,y:this.drag.translation.y+o},this.body.emitter.emit("_requestRedraw")}}}onDragEnd(e){if(this.drag.dragging=!1,this.body.selectionBox.show){this.body.selectionBox.show=!1;let t=this.body.selectionBox.position,i={minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)};this.body.nodeIndices.filter(r=>{let a=this.body.nodes[r];return a.x>=i.minX&&a.x<=i.maxX&&a.y>=i.minY&&a.y<=i.maxY}).forEach(r=>this.selectionHandler.selectObject(this.body.nodes[r]));let o=this.getPointer(e.center);this.selectionHandler.commitAndEmit(o,e),this.selectionHandler.generateClickEvent("dragEnd",e,this.getPointer(e.center),void 0,!0),this.body.emitter.emit("_requestRedraw")}else{let t=this.drag.selection;t&&t.length?(t.forEach(function(i){i.node.options.fixed.x=i.xFixed,i.node.options.fixed.y=i.yFixed}),this.selectionHandler.generateClickEvent("dragEnd",e,this.getPointer(e.center)),this.body.emitter.emit("startSimulation")):(this.selectionHandler.generateClickEvent("dragEnd",e,this.getPointer(e.center),void 0,!0),this.body.emitter.emit("_requestRedraw"))}}onPinch(e){let t=this.getPointer(e.center);this.drag.pinched=!0,this.pinch.scale===void 0&&(this.pinch.scale=1);let i=this.pinch.scale*e.scale;this.zoom(i,t)}zoom(e,t){if(this.options.zoomView===!0){let i=this.body.view.scale;e<1e-5&&(e=1e-5),e>10&&(e=10);let s;this.drag!==void 0&&this.drag.dragging===!0&&(s=this.canvas.DOMtoCanvas(this.drag.pointer));let o=this.body.view.translation,r=e/i,a=(1-r)*t.x+o.x*r,d=(1-r)*t.y+o.y*r;if(this.body.view.scale=e,this.body.view.translation={x:a,y:d},s!=null){let h=this.canvas.canvasToDOM(s);this.drag.pointer.x=h.x,this.drag.pointer.y=h.y}this.body.emitter.emit("_requestRedraw"),ithis._checkShowPopup(t),this.options.tooltipDelay))),this.options.hover===!0&&this.selectionHandler.hoverObject(e,t)}_checkShowPopup(e){let t=this.canvas._XconvertDOMtoCanvas(e.x),i=this.canvas._YconvertDOMtoCanvas(e.y),s={left:t,top:i,right:t,bottom:i},o=this.popupObj===void 0?void 0:this.popupObj.id,r=!1,a="node";if(this.popupObj===void 0){let d=this.body.nodeIndices,h=this.body.nodes,l,c=[];for(let u=0;u0&&(this.popupObj=h[c[c.length-1]],r=!0)}if(this.popupObj===void 0&&r===!1){let d=this.body.edgeIndices,h=this.body.edges,l,c=[];for(let u=0;u0&&(this.popupObj=h[c[c.length-1]],a="edge")}this.popupObj!==void 0?this.popupObj.id!==o&&(this.popup===void 0&&(this.popup=new Qs(this.canvas.frame)),this.popup.popupTargetType=a,this.popup.popupTargetId=this.popupObj.id,this.popup.setPosition(e.x+3,e.y-5),this.popup.setText(this.popupObj.getTitle()),this.popup.show(),this.body.emitter.emit("showPopup",this.popupObj.id)):this.popup!==void 0&&(this.popup.hide(),this.body.emitter.emit("hidePopup"))}_checkHidePopup(e){let t=this.selectionHandler._pointerToPositionObject(e),i=!1;if(this.popup.popupTargetType==="node"){if(this.body.nodes[this.popup.popupTargetId]!==void 0&&(i=this.body.nodes[this.popup.popupTargetId].isOverlappingWith(t),i===!0)){let s=this.selectionHandler.getNodeAt(e);i=s===void 0?!1:s.id===this.popup.popupTargetId}}else this.selectionHandler.getNodeAt(e)===void 0&&this.body.edges[this.popup.popupTargetId]!==void 0&&(i=this.body.edges[this.popup.popupTargetId].isOverlappingWith(t));i===!1&&(this.popupObj=void 0,this.popup.hide(),this.body.emitter.emit("hidePopup"))}};function q(n,e,t,i){if(t==="a"&&!i)throw new TypeError("Private accessor was defined without a getter");if(typeof e=="function"?n!==e||!i:!e.has(n))throw new TypeError("Cannot read private member from an object whose class did not declare it");return t==="m"?i:t==="a"?i.call(n):i?i.value:e.get(n)}function Hi(n,e,t,i,s){if(i==="m")throw new TypeError("Private method is not writable");if(i==="a"&&!s)throw new TypeError("Private accessor was defined without a setter");if(typeof e=="function"?n!==e||!s:!e.has(n))throw new TypeError("Cannot write private member to an object whose class did not declare it");return i==="a"?s.call(n,t):s?s.value=t:e.set(n,t),t}var Ye,le,Fe,Ne,Jt;function vn(n,e){let t=new Set;for(let i of e)n.has(i)||t.add(i);return t}var ji=class{constructor(){Ye.set(this,new Set),le.set(this,new Set)}get size(){return q(this,le,"f").size}add(...e){for(let t of e)q(this,le,"f").add(t)}delete(...e){for(let t of e)q(this,le,"f").delete(t)}clear(){q(this,le,"f").clear()}getSelection(){return[...q(this,le,"f")]}getChanges(){return{added:[...vn(q(this,Ye,"f"),q(this,le,"f"))],deleted:[...vn(q(this,le,"f"),q(this,Ye,"f"))],previous:[...new Set(q(this,Ye,"f"))],current:[...new Set(q(this,le,"f"))]}}commit(){let e=this.getChanges();Hi(this,Ye,q(this,le,"f"),"f"),Hi(this,le,new Set(q(this,Ye,"f")),"f");for(let t of e.added)t.select();for(let t of e.deleted)t.unselect();return e}};Ye=new WeakMap,le=new WeakMap;var wn=class{constructor(e=()=>{}){Fe.set(this,new ji),Ne.set(this,new ji),Jt.set(this,void 0),Hi(this,Jt,e,"f")}get sizeNodes(){return q(this,Fe,"f").size}get sizeEdges(){return q(this,Ne,"f").size}getNodes(){return q(this,Fe,"f").getSelection()}getEdges(){return q(this,Ne,"f").getSelection()}addNodes(...e){q(this,Fe,"f").add(...e)}addEdges(...e){q(this,Ne,"f").add(...e)}deleteNodes(e){q(this,Fe,"f").delete(e)}deleteEdges(e){q(this,Ne,"f").delete(e)}clear(){q(this,Fe,"f").clear(),q(this,Ne,"f").clear()}commit(...e){let t={nodes:q(this,Fe,"f").commit(),edges:q(this,Ne,"f").commit()};return q(this,Jt,"f").call(this,t,...e),t}};Fe=new WeakMap,Ne=new WeakMap,Jt=new WeakMap;var _n=class{constructor(e,t){this.body=e,this.canvas=t,this._selectionAccumulator=new wn,this.hoverObj={nodes:{},edges:{}},this.options={},this.defaultOptions={multiselect:!1,selectable:!0,selectConnectedEdges:!0,hoverConnectedEdges:!0},Object.assign(this.options,this.defaultOptions),this.body.emitter.on("_dataChanged",()=>{this.updateSelection()})}setOptions(e){e!==void 0&&Ve(["multiselect","hoverConnectedEdges","selectable","selectConnectedEdges"],this.options,e)}selectOnPoint(e){let t=!1;if(this.options.selectable===!0){let i=this.getNodeAt(e)||this.getEdgeAt(e);this.unselectAll(),i!==void 0&&(t=this.selectObject(i)),this.body.emitter.emit("_requestRedraw")}return t}selectAdditionalOnPoint(e){let t=!1;if(this.options.selectable===!0){let i=this.getNodeAt(e)||this.getEdgeAt(e);i!==void 0&&(t=!0,i.isSelected()===!0?this.deselectObject(i):this.selectObject(i),this.body.emitter.emit("_requestRedraw"))}return t}_initBaseEvent(e,t){let i={};return i.pointer={DOM:{x:t.x,y:t.y},canvas:this.canvas.DOMtoCanvas(t)},i.event=e,i}generateClickEvent(e,t,i,s,o=!1){let r=this._initBaseEvent(t,i);if(o===!0)r.nodes=[],r.edges=[];else{let a=this.getSelection();r.nodes=a.nodes,r.edges=a.edges}s!==void 0&&(r.previousSelection=s),e=="click"&&(r.items=this.getClickedItems(i)),t.controlEdge!==void 0&&(r.controlEdge=t.controlEdge),this.body.emitter.emit(e,r)}selectObject(e,t=this.options.selectConnectedEdges){return e!==void 0?(e instanceof U?(t===!0&&this._selectionAccumulator.addEdges(...e.edges),this._selectionAccumulator.addNodes(e)):this._selectionAccumulator.addEdges(e),!0):!1}deselectObject(e){e.isSelected()===!0&&(e.selected=!1,this._removeFromSelection(e))}_getAllNodesOverlappingWith(e){let t=[],i=this.body.nodes;for(let s=0;s0)return t===!0?this.body.nodes[s[s.length-1]]:s[s.length-1]}_getEdgesOverlappingWith(e,t){let i=this.body.edges;for(let s=0;s0&&(this.generateClickEvent("deselectEdge",t,e,o),i=!0),s.nodes.deleted.length>0&&(this.generateClickEvent("deselectNode",t,e,o),i=!0),s.nodes.added.length>0&&(this.generateClickEvent("selectNode",t,e),i=!0),s.edges.added.length>0&&(this.generateClickEvent("selectEdge",t,e),i=!0),i===!0&&this.generateClickEvent("select",t,e)}getSelection(){return{nodes:this.getSelectedNodeIds(),edges:this.getSelectedEdgeIds()}}getSelectedNodes(){return this._selectionAccumulator.getNodes()}getSelectedEdges(){return this._selectionAccumulator.getEdges()}getSelectedNodeIds(){return this._selectionAccumulator.getNodes().map(e=>e.id)}getSelectedEdgeIds(){return this._selectionAccumulator.getEdges().map(e=>e.id)}setSelection(e,t={}){if(!e||!e.nodes&&!e.edges)throw new TypeError("Selection must be an object with nodes and/or edges properties");if((t.unselectAll||t.unselectAll===void 0)&&this.unselectAll(),e.nodes)for(let i of e.nodes){let s=this.body.nodes[i];if(!s)throw new RangeError('Node with id "'+i+'" not found');this.selectObject(s,t.highlightEdges)}if(e.edges)for(let i of e.edges){let s=this.body.edges[i];if(!s)throw new RangeError('Edge with id "'+i+'" not found');this.selectObject(s)}this.body.emitter.emit("_requestRedraw"),this._selectionAccumulator.commit()}selectNodes(e,t=!0){if(!e||e.length===void 0)throw"Selection must be an array with ids";this.setSelection({nodes:e},{highlightEdges:t})}selectEdges(e){if(!e||e.length===void 0)throw"Selection must be an array with ids";this.setSelection({edges:e})}updateSelection(){for(let e in this._selectionAccumulator.getNodes())Object.prototype.hasOwnProperty.call(this.body.nodes,e.id)||this._selectionAccumulator.deleteNodes(e);for(let e in this._selectionAccumulator.getEdges())Object.prototype.hasOwnProperty.call(this.body.edges,e.id)||this._selectionAccumulator.deleteEdges(e)}getClickedItems(e){let t=this.canvas.DOMtoCanvas(e),i=[],s=this.body.nodeIndices,o=this.body.nodes;for(let d=s.length-1;d>=0;d--){let l=o[s[d]].getItemsOnPoint(t);i.push.apply(i,l)}let r=this.body.edgeIndices,a=this.body.edges;for(let d=r.length-1;d>=0;d--){let l=a[r[d]].getItemsOnPoint(t);i.push.apply(i,l)}return i}},Wi=class{abstract(){throw new Error("Can't instantiate abstract class!")}fake_use(){}curveType(){return this.abstract()}getPosition(e){return this.fake_use(e),this.abstract()}setPosition(e,t,i=void 0){this.fake_use(e,t,i),this.abstract()}getTreeSize(e){return this.fake_use(e),this.abstract()}sort(e){this.fake_use(e),this.abstract()}fix(e,t){this.fake_use(e,t),this.abstract()}shift(e,t){this.fake_use(e,t),this.abstract()}},En=class extends Wi{constructor(e){super();this.layout=e}curveType(){return"horizontal"}getPosition(e){return e.x}setPosition(e,t,i=void 0){i!==void 0&&this.layout.hierarchical.addToOrdering(e,i),e.x=t}getTreeSize(e){let t=this.layout.hierarchical.getTreeSize(this.layout.body.nodes,e);return{min:t.min_x,max:t.max_x}}sort(e){(0,wt.sort)(e,function(t,i){return t.x-i.x})}fix(e,t){e.y=this.layout.options.hierarchical.levelSeparation*t,e.options.fixed.y=!0}shift(e,t){this.layout.body.nodes[e].x+=t}},xn=class extends Wi{constructor(e){super();this.layout=e}curveType(){return"vertical"}getPosition(e){return e.y}setPosition(e,t,i=void 0){i!==void 0&&this.layout.hierarchical.addToOrdering(e,i),e.y=t}getTreeSize(e){let t=this.layout.hierarchical.getTreeSize(this.layout.body.nodes,e);return{min:t.min_y,max:t.max_y}}sort(e){(0,wt.sort)(e,function(t,i){return t.y-i.y})}fix(e,t){e.x=this.layout.options.hierarchical.levelSeparation*t,e.options.fixed.x=!0}shift(e,t){this.layout.body.nodes[e].y+=t}};function Ba(n,e){let t=new Set;return n.forEach(i=>{i.edges.forEach(s=>{s.connected&&t.add(s)})}),t.forEach(i=>{let s=i.from.id,o=i.to.id;e[s]==null&&(e[s]=0),(e[o]==null||e[s]>=e[o])&&(e[o]=e[s]+1)}),e}function Aa(n){return Cn(e=>e.edges.filter(t=>n.has(t.toId)).every(t=>t.to===e),(e,t)=>t>e,"from",n)}function za(n){return Cn(e=>e.edges.filter(t=>n.has(t.toId)).every(t=>t.from===e),(e,t)=>td+1+h.edges.length,0),r=t+"Id",a=t==="to"?1:-1;for(let[d,h]of i){if(!i.has(d)||!n(h))continue;s[d]=0;let l=[h],c=0,u;for(;u=l.pop();){if(!i.has(d))continue;let p=s[u.id]+a;if(u.edges.filter(b=>b.connected&&b.to!==b.from&&b[t]!==u&&i.has(b.toId)&&i.has(b.fromId)).forEach(b=>{let C=b[r],f=s[C];(f==null||e(p,f))&&(s[C]=p,l.push(b[t]))}),c>o)return Ba(i,s);++c}}return s}var Tn=class{constructor(){this.childrenReference={},this.parentReference={},this.trees={},this.distributionOrdering={},this.levels={},this.distributionIndex={},this.isTree=!1,this.treeIndex=-1}addRelation(e,t){this.childrenReference[e]===void 0&&(this.childrenReference[e]=[]),this.childrenReference[e].push(t),this.parentReference[t]===void 0&&(this.parentReference[t]=[]),this.parentReference[t].push(e)}checkIfTree(){for(let e in this.parentReference)if(this.parentReference[e].length>1){this.isTree=!1;return}this.isTree=!0}numTrees(){return this.treeIndex+1}setTreeIndex(e,t){t!==void 0&&this.trees[e.id]===void 0&&(this.trees[e.id]=t,this.treeIndex=Math.max(t,this.treeIndex))}ensureLevel(e){this.levels[e]===void 0&&(this.levels[e]=0)}getMaxLevel(e){let t={},i=s=>{if(t[s]!==void 0)return t[s];let o=this.levels[s];if(this.childrenReference[s]){let r=this.childrenReference[s];if(r.length>0)for(let a=0;a{this.setupHierarchicalLayout()}),this.body.emitter.on("_dataLoaded",()=>{this.layoutNetwork()}),this.body.emitter.on("_resetHierarchicalLayout",()=>{this.setupHierarchicalLayout()}),this.body.emitter.on("_adjustEdgesForHierarchicalLayout",()=>{if(this.options.hierarchical.enabled!==!0)return;let e=this.direction.curveType();this.body.emitter.emit("_forceDisableDynamicCurves",e,!1)})}setOptions(e,t){if(e!==void 0){let i=this.options.hierarchical,s=i.enabled;if(Ve(["randomSeed","improvedLayout","clusterThreshold"],this.options,e),ae(this.options,e,"hierarchical"),e.randomSeed!==void 0&&this._resetRNG(e.randomSeed),i.enabled===!0)return s===!0&&this.body.emitter.emit("refresh",!0),i.direction==="RL"||i.direction==="DU"?i.levelSeparation>0&&(i.levelSeparation*=-1):i.levelSeparation<0&&(i.levelSeparation*=-1),this.setDirectionStrategy(),this.body.emitter.emit("_resetHierarchicalLayout"),this.adaptAllOptionsForHierarchicalLayout(t);if(s===!0)return this.body.emitter.emit("refresh"),j(t,this.optionsBackup)}return t}_resetRNG(e){this.initialRandomSeed=e,this._rng=gt(this.initialRandomSeed)}adaptAllOptionsForHierarchicalLayout(e){if(this.options.hierarchical.enabled===!0){let t=this.optionsBackup.physics;e.physics===void 0||e.physics===!0?(e.physics={enabled:t.enabled===void 0?!0:t.enabled,solver:"hierarchicalRepulsion"},t.enabled=t.enabled===void 0?!0:t.enabled,t.solver=t.solver||"barnesHut"):typeof e.physics=="object"?(t.enabled=e.physics.enabled===void 0?!0:e.physics.enabled,t.solver=e.physics.solver||"barnesHut",e.physics.solver="hierarchicalRepulsion"):e.physics!==!1&&(t.solver="barnesHut",e.physics={solver:"hierarchicalRepulsion"});let i=this.direction.curveType();if(e.edges===void 0)this.optionsBackup.edges={smooth:{enabled:!0,type:"dynamic"}},e.edges={smooth:!1};else if(e.edges.smooth===void 0)this.optionsBackup.edges={smooth:{enabled:!0,type:"dynamic"}},e.edges.smooth=!1;else if(typeof e.edges.smooth=="boolean")this.optionsBackup.edges={smooth:e.edges.smooth},e.edges.smooth={enabled:e.edges.smooth,type:i};else{let s=e.edges.smooth;s.type!==void 0&&s.type!=="dynamic"&&(i=s.type),this.optionsBackup.edges={smooth:{enabled:s.enabled===void 0?!0:s.enabled,type:s.type===void 0?"dynamic":s.type,roundness:s.roundness===void 0?.5:s.roundness,forceDirection:s.forceDirection===void 0?!1:s.forceDirection}},e.edges.smooth={enabled:s.enabled===void 0?!0:s.enabled,type:i,roundness:s.roundness===void 0?.5:s.roundness,forceDirection:s.forceDirection===void 0?!1:s.forceDirection}}this.body.emitter.emit("_forceDisableDynamicCurves",i)}return e}positionInitially(e){if(this.options.hierarchical.enabled!==!0){this._resetRNG(this.initialRandomSeed);let t=e.length+50;for(let i=0;io){let d=e.length;for(;e.length>o&&s<=i;){s+=1;let h=e.length;s%3==0?this.body.modules.clustering.clusterBridges(r):this.body.modules.clustering.clusterOutliers(r);let l=e.length;if(h==l&&s%3!=0){this._declusterAll(),this.body.emitter.emit("_layoutFailed"),console.info("This network could not be positioned by this version of the improved layout algorithm. Please disable improvedLayout for better performance.");return}}this.body.modules.kamadaKawai.setOptions({springLength:Math.max(150,2*d)})}s>i&&console.info("The clustering didn't succeed within the amount of interations allowed, progressing with partial result."),this.body.modules.kamadaKawai.solve(e,this.body.edgeIndices,!0),this._shiftToCenter();let a=70;for(let d=0;d0){let e,t,i=!1,s=!1;this.lastNodeOnLevel={},this.hierarchical=new Tn;for(t in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&(e=this.body.nodes[t],e.options.level!==void 0?(i=!0,this.hierarchical.levels[t]=e.options.level):s=!0);if(s===!0&&i===!0)throw new Error("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");{if(s===!0){let r=this.options.hierarchical.sortMethod;r==="hubsize"?this._determineLevelsByHubsize():r==="directed"?this._determineLevelsDirected():r==="custom"&&this._determineLevelsCustomCallback()}for(let r in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,r)&&this.hierarchical.ensureLevel(r);let o=this._getDistribution();this._generateMap(),this._placeNodesByHierarchy(o),this._condenseHierarchy(),this._shiftToCenter()}}}_condenseHierarchy(){let e=!1,t={},i=()=>{let f=o(),g=0;for(let m=0;m{let m=this.hierarchical.trees;for(let v in m)Object.prototype.hasOwnProperty.call(m,v)&&m[v]===f&&this.direction.shift(v,g)},o=()=>{let f=[];for(let g=0;g{if(!g[f.id]&&(g[f.id]=!0,this.hierarchical.childrenReference[f.id])){let m=this.hierarchical.childrenReference[f.id];if(m.length>0)for(let v=0;v{let m=1e9,v=1e9,_=1e9,E=-1e9;for(let T in f)if(Object.prototype.hasOwnProperty.call(f,T)){let x=this.body.nodes[T],w=this.hierarchical.levels[x.id],k=this.direction.getPosition(x),[N,W]=this._getSpaceAroundNode(x,f);m=Math.min(N,m),v=Math.min(W,v),w<=g&&(_=Math.min(k,_),E=Math.max(k,E))}return[_,E,m,v]},d=(f,g)=>{let m=this.hierarchical.getMaxLevel(f.id),v=this.hierarchical.getMaxLevel(g.id);return Math.min(m,v)},h=(f,g,m)=>{let v=this.hierarchical;for(let _=0;_1)for(let x=0;x{let v=this.direction.getPosition(f),_=this.direction.getPosition(g),E=Math.abs(_-v),T=this.options.hierarchical.nodeSpacing;if(E>T){let x={},w={};r(f,x),r(g,w);let k=d(f,g),N=a(x,k),W=a(w,k),L=N[1],R=W[0],B=W[2];if(Math.abs(L-R)>T){let D=L-R+T;D<-B+T&&(D=-B+T),D<0&&(this._shiftBlock(g.id,D),e=!0,m===!0&&this._centerParent(g))}}},c=(f,g)=>{let m=g.id,v=g.edges,_=this.hierarchical.levels[g.id],E=this.options.hierarchical.levelSeparation*this.options.hierarchical.levelSeparation,T={},x=[];for(let B=0;B{let D=0;for(let H=0;H{let D=0;for(let H=0;H{let D=this.direction.getPosition(g),H={};for(let Y=0;Y{let F=this.direction.getPosition(g);if(t[g.id]===void 0){let it={};r(g,it),t[g.id]=it}let D=a(t[g.id]),H=D[2],Y=D[3],ce=B-F,Xe=0;ce>0?Xe=Math.min(ce,Y-this.options.hierarchical.nodeSpacing):ce<0&&(Xe=-Math.min(-ce,H-this.options.hierarchical.nodeSpacing)),Xe!=0&&(this._shiftBlock(g.id,Xe),e=!0)},L=B=>{let F=this.direction.getPosition(g),[D,H]=this._getSpaceAroundNode(g),Y=B-F,ce=F;Y>0?ce=Math.min(F+(H-this.options.hierarchical.nodeSpacing),B):Y<0&&(ce=Math.max(F-(D-this.options.hierarchical.nodeSpacing),B)),ce!==F&&(this.direction.setPosition(g,ce),e=!0)},R=N(f,x);W(R),R=N(f,v),L(R)},u=f=>{let g=this.hierarchical.getLevels();g=g.reverse();for(let m=0;m{let g=this.hierarchical.getLevels();g=g.reverse();for(let m=0;m{for(let f in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,f)&&this._centerParent(this.body.nodes[f])},C=()=>{let f=this.hierarchical.getLevels();f=f.reverse();for(let g=0;g0&&Math.abs(c)0&&(d=this.direction.getPosition(i[o-1])+a),this.direction.setPosition(r,d,t),this._validatePositionAndContinue(r,t,d),s++}}}}_placeBranchNodes(e,t){let i=this.hierarchical.childrenReference[e];if(i===void 0)return;let s=[];for(let r=0;rt&&this.positionedNodes[a.id]===void 0){let h=this.options.hierarchical.nodeSpacing,l;r===0?l=this.direction.getPosition(this.body.nodes[e]):l=this.direction.getPosition(s[r-1])+h,this.direction.setPosition(a,l,d),this._validatePositionAndContinue(a,d,l)}else return}let o=this._getCenterPosition(s);this.direction.setPosition(this.body.nodes[e],o,t)}_validatePositionAndContinue(e,t,i){if(!!this.hierarchical.isTree){if(this.lastNodeOnLevel[t]!==void 0){let s=this.direction.getPosition(this.body.nodes[this.lastNodeOnLevel[t]]);if(i-s{this.body.edgeIndices.indexOf(i.id)!==-1&&t.push(i)}),t}_getHubSizes(){let e={},t=this.body.nodeIndices;A(t,s=>{let o=this.body.nodes[s],r=this._getActiveEdges(o).length;e[r]=!0});let i=[];return A(e,s=>{i.push(Number(s))}),wt.default.sort(i,function(s,o){return o-s}),i}_determineLevelsByHubsize(){let e=(i,s)=>{this.hierarchical.levelDownstream(i,s)},t=this._getHubSizes();for(let i=0;i{let r=this.body.nodes[o];s===this._getActiveEdges(r).length&&this._crawlNetwork(e,o)})}}_determineLevelsCustomCallback(){let e=1e5,t=function(s,o,r){},i=(s,o,r)=>{let a=this.hierarchical.levels[s.id];a===void 0&&(a=this.hierarchical.levels[s.id]=e);let d=t(J.cloneOptions(s,"node"),J.cloneOptions(o,"node"),J.cloneOptions(r,"edge"));this.hierarchical.levels[o.id]=a+d};this._crawlNetwork(i),this.hierarchical.setMinLevelToZero(this.body.nodes)}_determineLevelsDirected(){let e=this.body.nodeIndices.reduce((t,i)=>(t.set(i,this.body.nodes[i]),t),new Map);this.options.hierarchical.shakeTowards==="roots"?this.hierarchical.levels=za(e):this.hierarchical.levels=Aa(e),this.hierarchical.setMinLevelToZero(this.body.nodes)}_generateMap(){let e=(t,i)=>{this.hierarchical.levels[i.id]>this.hierarchical.levels[t.id]&&this.hierarchical.addRelation(t.id,i.id)};this._crawlNetwork(e),this.hierarchical.checkIfTree()}_crawlNetwork(e=function(){},t){let i={},s=(o,r)=>{if(i[o.id]===void 0){this.hierarchical.setTreeIndex(o,r),i[o.id]=!0;let a,d=this._getActiveEdges(o);for(let h=0;h{if(i[o])return;i[o]=!0,this.direction.shift(o,t);let r=this.hierarchical.childrenReference[o];if(r!==void 0)for(let a=0;a{let d=this.hierarchical.parentReference[a];if(d!==void 0)for(let h=0;h{let d=this.hierarchical.parentReference[a];if(d!==void 0)for(let h=0;h{this._clean()}),this.body.emitter.on("_dataChanged",this._restore.bind(this)),this.body.emitter.on("_resetData",this._restore.bind(this))}_restore(){this.inMode!==!1&&(this.options.initiallyActive===!0?this.enableEditMode():this.disableEditMode())}setOptions(e,t,i){t!==void 0&&(t.locale!==void 0?this.options.locale=t.locale:this.options.locale=i.locale,t.locales!==void 0?this.options.locales=t.locales:this.options.locales=i.locales),e!==void 0&&(typeof e=="boolean"?this.options.enabled=e:(this.options.enabled=!0,j(this.options,e)),this.options.initiallyActive===!0&&(this.editMode=!0),this._setup())}toggleEditMode(){this.editMode===!0?this.disableEditMode():this.enableEditMode()}enableEditMode(){this.editMode=!0,this._clean(),this.guiEnabled===!0&&(this.manipulationDiv.style.display="block",this.closeDiv.style.display="block",this.editModeDiv.style.display="none",this.showManipulatorToolbar())}disableEditMode(){this.editMode=!1,this._clean(),this.guiEnabled===!0&&(this.manipulationDiv.style.display="none",this.closeDiv.style.display="none",this.editModeDiv.style.display="block",this._createEditButton())}showManipulatorToolbar(){if(this._clean(),this.manipulationDOM={},this.guiEnabled===!0){this.editMode=!0,this.manipulationDiv.style.display="block",this.closeDiv.style.display="block";let e=this.selectionHandler.getSelectedNodeCount(),t=this.selectionHandler.getSelectedEdgeCount(),i=e+t,s=this.options.locales[this.options.locale],o=!1;this.options.addNode!==!1&&(this._createAddNodeButton(s),o=!0),this.options.addEdge!==!1&&(o===!0?this._createSeperator(1):o=!0,this._createAddEdgeButton(s)),e===1&&typeof this.options.editNode=="function"?(o===!0?this._createSeperator(2):o=!0,this._createEditNodeButton(s)):t===1&&e===0&&this.options.editEdge!==!1&&(o===!0?this._createSeperator(3):o=!0,this._createEditEdgeButton(s)),i!==0&&(e>0&&this.options.deleteNode!==!1?(o===!0&&this._createSeperator(4),this._createDeleteButton(s)):e===0&&this.options.deleteEdge!==!1&&(o===!0&&this._createSeperator(4),this._createDeleteButton(s))),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this)),this._temporaryBindEvent("select",this.showManipulatorToolbar.bind(this))}this.body.emitter.emit("_redraw")}addNodeMode(){if(this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="addNode",this.guiEnabled===!0){let e=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(e),this._createSeperator(),this._createDescription(e.addDescription||this.options.locales.en.addDescription),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this))}this._temporaryBindEvent("click",this._performAddNode.bind(this))}editNode(){this.editMode!==!0&&this.enableEditMode(),this._clean();let e=this.selectionHandler.getSelectedNodes()[0];if(e!==void 0)if(this.inMode="editNode",typeof this.options.editNode=="function")if(e.isCluster!==!0){let t=j({},e.options,!1);if(t.x=e.x,t.y=e.y,this.options.editNode.length===2)this.options.editNode(t,i=>{i!=null&&this.inMode==="editNode"&&this.body.data.nodes.getDataSet().update(i),this.showManipulatorToolbar()});else throw new Error("The function for edit does not support two arguments (data, callback)")}else alert(this.options.locales[this.options.locale].editClusterError||this.options.locales.en.editClusterError);else throw new Error("No function has been configured to handle the editing of nodes.");else this.showManipulatorToolbar()}addEdgeMode(){if(this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="addEdge",this.guiEnabled===!0){let e=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(e),this._createSeperator(),this._createDescription(e.edgeDescription||this.options.locales.en.edgeDescription),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this))}this._temporaryBindUI("onTouch",this._handleConnect.bind(this)),this._temporaryBindUI("onDragEnd",this._finishConnect.bind(this)),this._temporaryBindUI("onDrag",this._dragControlNode.bind(this)),this._temporaryBindUI("onRelease",this._finishConnect.bind(this)),this._temporaryBindUI("onDragStart",this._dragStartEdge.bind(this)),this._temporaryBindUI("onHold",()=>{})}editEdgeMode(){if(this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="editEdge",typeof this.options.editEdge=="object"&&typeof this.options.editEdge.editWithoutDrag=="function"&&(this.edgeBeingEditedId=this.selectionHandler.getSelectedEdgeIds()[0],this.edgeBeingEditedId!==void 0)){let e=this.body.edges[this.edgeBeingEditedId];this._performEditEdge(e.from.id,e.to.id);return}if(this.guiEnabled===!0){let e=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(e),this._createSeperator(),this._createDescription(e.editEdgeDescription||this.options.locales.en.editEdgeDescription),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this))}if(this.edgeBeingEditedId=this.selectionHandler.getSelectedEdgeIds()[0],this.edgeBeingEditedId!==void 0){let e=this.body.edges[this.edgeBeingEditedId],t=this._getNewTargetNode(e.from.x,e.from.y),i=this._getNewTargetNode(e.to.x,e.to.y);this.temporaryIds.nodes.push(t.id),this.temporaryIds.nodes.push(i.id),this.body.nodes[t.id]=t,this.body.nodeIndices.push(t.id),this.body.nodes[i.id]=i,this.body.nodeIndices.push(i.id),this._temporaryBindUI("onTouch",this._controlNodeTouch.bind(this)),this._temporaryBindUI("onTap",()=>{}),this._temporaryBindUI("onHold",()=>{}),this._temporaryBindUI("onDragStart",this._controlNodeDragStart.bind(this)),this._temporaryBindUI("onDrag",this._controlNodeDrag.bind(this)),this._temporaryBindUI("onDragEnd",this._controlNodeDragEnd.bind(this)),this._temporaryBindUI("onMouseMove",()=>{}),this._temporaryBindEvent("beforeDrawing",s=>{let o=e.edgeType.findBorderPositions(s);t.selected===!1&&(t.x=o.from.x,t.y=o.from.y),i.selected===!1&&(i.x=o.to.x,i.y=o.to.y)}),this.body.emitter.emit("_redraw")}else this.showManipulatorToolbar()}deleteSelected(){this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="delete";let e=this.selectionHandler.getSelectedNodeIds(),t=this.selectionHandler.getSelectedEdgeIds(),i;if(e.length>0){for(let s=0;s0&&typeof this.options.deleteEdge=="function"&&(i=this.options.deleteEdge);if(typeof i=="function"){let s={nodes:e,edges:t};if(i.length===2)i(s,o=>{o!=null&&this.inMode==="delete"?(this.body.data.edges.getDataSet().remove(o.edges),this.body.data.nodes.getDataSet().remove(o.nodes),this.body.emitter.emit("startSimulation"),this.showManipulatorToolbar()):(this.body.emitter.emit("startSimulation"),this.showManipulatorToolbar())});else throw new Error("The function for delete does not support two arguments (data, callback)")}else this.body.data.edges.getDataSet().remove(t),this.body.data.nodes.getDataSet().remove(e),this.body.emitter.emit("startSimulation"),this.showManipulatorToolbar()}_setup(){this.options.enabled===!0?(this.guiEnabled=!0,this._createWrappers(),this.editMode===!1?this._createEditButton():this.showManipulatorToolbar()):(this._removeManipulationDOM(),this.guiEnabled=!1)}_createWrappers(){var e,t;this.manipulationDiv===void 0&&(this.manipulationDiv=document.createElement("div"),this.manipulationDiv.className="vis-manipulation",this.editMode===!0?this.manipulationDiv.style.display="block":this.manipulationDiv.style.display="none",this.canvas.frame.appendChild(this.manipulationDiv)),this.editModeDiv===void 0&&(this.editModeDiv=document.createElement("div"),this.editModeDiv.className="vis-edit-mode",this.editMode===!0?this.editModeDiv.style.display="none":this.editModeDiv.style.display="block",this.canvas.frame.appendChild(this.editModeDiv)),this.closeDiv===void 0&&(this.closeDiv=document.createElement("button"),this.closeDiv.className="vis-close",this.closeDiv.setAttribute("aria-label",(t=(e=this.options.locales[this.options.locale])==null?void 0:e.close)!=null?t:this.options.locales.en.close),this.closeDiv.style.display=this.manipulationDiv.style.display,this.canvas.frame.appendChild(this.closeDiv))}_getNewTargetNode(e,t){let i=j({},this.options.controlNodeStyle);i.id="targetNode"+Te(),i.hidden=!1,i.physics=!1,i.x=e,i.y=t;let s=this.body.functions.createNode(i);return s.shape.boundingBox={left:e,right:e,top:t,bottom:t},s}_createEditButton(){this._clean(),this.manipulationDOM={},_e(this.editModeDiv);let e=this.options.locales[this.options.locale],t=this._createButton("editMode","vis-edit vis-edit-mode",e.edit||this.options.locales.en.edit);this.editModeDiv.appendChild(t),this._bindElementEvents(t,this.toggleEditMode.bind(this))}_clean(){this.inMode=!1,this.guiEnabled===!0&&(_e(this.editModeDiv),_e(this.manipulationDiv),this._cleanupDOMEventListeners()),this._cleanupTemporaryNodesAndEdges(),this._unbindTemporaryUIs(),this._unbindTemporaryEvents(),this.body.emitter.emit("restorePhysics")}_cleanupDOMEventListeners(){for(let e of this._domEventListenerCleanupQueue.splice(0))e()}_removeManipulationDOM(){this._clean(),_e(this.manipulationDiv),_e(this.editModeDiv),_e(this.closeDiv),this.manipulationDiv&&this.canvas.frame.removeChild(this.manipulationDiv),this.editModeDiv&&this.canvas.frame.removeChild(this.editModeDiv),this.closeDiv&&this.canvas.frame.removeChild(this.closeDiv),this.manipulationDiv=void 0,this.editModeDiv=void 0,this.closeDiv=void 0}_createSeperator(e=1){this.manipulationDOM["seperatorLineDiv"+e]=document.createElement("div"),this.manipulationDOM["seperatorLineDiv"+e].className="vis-separator-line",this.manipulationDiv.appendChild(this.manipulationDOM["seperatorLineDiv"+e])}_createAddNodeButton(e){let t=this._createButton("addNode","vis-add",e.addNode||this.options.locales.en.addNode);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.addNodeMode.bind(this))}_createAddEdgeButton(e){let t=this._createButton("addEdge","vis-connect",e.addEdge||this.options.locales.en.addEdge);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.addEdgeMode.bind(this))}_createEditNodeButton(e){let t=this._createButton("editNode","vis-edit",e.editNode||this.options.locales.en.editNode);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.editNode.bind(this))}_createEditEdgeButton(e){let t=this._createButton("editEdge","vis-edit",e.editEdge||this.options.locales.en.editEdge);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.editEdgeMode.bind(this))}_createDeleteButton(e){let t;this.options.rtl?t="vis-delete-rtl":t="vis-delete";let i=this._createButton("delete",t,e.del||this.options.locales.en.del);this.manipulationDiv.appendChild(i),this._bindElementEvents(i,this.deleteSelected.bind(this))}_createBackButton(e){let t=this._createButton("back","vis-back",e.back||this.options.locales.en.back);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.showManipulatorToolbar.bind(this))}_createButton(e,t,i,s="vis-label"){return this.manipulationDOM[e+"Div"]=document.createElement("button"),this.manipulationDOM[e+"Div"].className="vis-button "+t,this.manipulationDOM[e+"Label"]=document.createElement("div"),this.manipulationDOM[e+"Label"].className=s,this.manipulationDOM[e+"Label"].innerText=i,this.manipulationDOM[e+"Div"].appendChild(this.manipulationDOM[e+"Label"]),this.manipulationDOM[e+"Div"]}_createDescription(e){this.manipulationDOM.descriptionLabel=document.createElement("div"),this.manipulationDOM.descriptionLabel.className="vis-none",this.manipulationDOM.descriptionLabel.innerText=e,this.manipulationDiv.appendChild(this.manipulationDOM.descriptionLabel)}_temporaryBindEvent(e,t){this.temporaryEventFunctions.push({event:e,boundFunction:t}),this.body.emitter.on(e,t)}_temporaryBindUI(e,t){if(this.body.eventListeners[e]!==void 0)this.temporaryUIFunctions[e]=this.body.eventListeners[e],this.body.eventListeners[e]=t;else throw new Error("This UI function does not exist. Typo? You tried: "+e+" possible are: "+JSON.stringify(Object.keys(this.body.eventListeners)))}_unbindTemporaryUIs(){for(let e in this.temporaryUIFunctions)Object.prototype.hasOwnProperty.call(this.temporaryUIFunctions,e)&&(this.body.eventListeners[e]=this.temporaryUIFunctions[e],delete this.temporaryUIFunctions[e]);this.temporaryUIFunctions={}}_unbindTemporaryEvents(){for(let e=0;e{i.destroy()});let s=({keyCode:o,key:r})=>{(r==="Enter"||r===" "||o===13||o===32)&&t()};e.addEventListener("keyup",s,!1),this._domEventListenerCleanupQueue.push(()=>{e.removeEventListener("keyup",s,!1)})}_cleanupTemporaryNodesAndEdges(){for(let e=0;e=0;a--)if(o[a]!==this.selectedControlNode.id){r=this.body.nodes[o[a]];break}if(r!==void 0&&this.selectedControlNode!==void 0)if(r.isCluster===!0)alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError);else{let a=this.body.nodes[this.temporaryIds.nodes[0]];this.selectedControlNode.id===a.id?this._performEditEdge(r.id,s.to.id):this._performEditEdge(s.from.id,r.id)}else s.updateEdgeType(),this.body.emitter.emit("restorePhysics");this.body.emitter.emit("_redraw")}_handleConnect(e){if(new Date().valueOf()-this.touchTime>100){this.lastTouch=this.body.functions.getPointer(e.center),this.lastTouch.translation=Object.assign({},this.body.view.translation),this.interactionHandler.drag.pointer=this.lastTouch,this.interactionHandler.drag.translation=this.lastTouch.translation;let t=this.lastTouch,i=this.selectionHandler.getNodeAt(t);if(i!==void 0)if(i.isCluster===!0)alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError);else{let s=this._getNewTargetNode(i.x,i.y);this.body.nodes[s.id]=s,this.body.nodeIndices.push(s.id);let o=this.body.functions.createEdge({id:"connectionEdge"+Te(),from:i.id,to:s.id,physics:!1,smooth:{enabled:!0,type:"continuous",roundness:.5}});this.body.edges[o.id]=o,this.body.edgeIndices.push(o.id),this.temporaryIds.nodes.push(s.id),this.temporaryIds.edges.push(o.id)}this.touchTime=new Date().valueOf()}}_dragControlNode(e){let t=this.body.functions.getPointer(e.center),i=this.selectionHandler._pointerToPositionObject(t),s;this.temporaryIds.edges[0]!==void 0&&(s=this.body.edges[this.temporaryIds.edges[0]].fromId);let o=this.selectionHandler._getAllNodesOverlappingWith(i),r;for(let a=o.length-1;a>=0;a--)if(this.temporaryIds.nodes.indexOf(o[a])===-1){r=this.body.nodes[o[a]];break}if(e.controlEdge={from:s,to:r?r.id:void 0},this.selectionHandler.generateClickEvent("controlNodeDragging",e,t),this.temporaryIds.nodes[0]!==void 0){let a=this.body.nodes[this.temporaryIds.nodes[0]];a.x=this.canvas._XconvertDOMtoCanvas(t.x),a.y=this.canvas._YconvertDOMtoCanvas(t.y),this.body.emitter.emit("_redraw")}else this.interactionHandler.onDrag(e)}_finishConnect(e){let t=this.body.functions.getPointer(e.center),i=this.selectionHandler._pointerToPositionObject(t),s;this.temporaryIds.edges[0]!==void 0&&(s=this.body.edges[this.temporaryIds.edges[0]].fromId);let o=this.selectionHandler._getAllNodesOverlappingWith(i),r;for(let a=o.length-1;a>=0;a--)if(this.temporaryIds.nodes.indexOf(o[a])===-1){r=this.body.nodes[o[a]];break}this._cleanupTemporaryNodesAndEdges(),r!==void 0&&(r.isCluster===!0?alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError):this.body.nodes[s]!==void 0&&this.body.nodes[r.id]!==void 0&&this._performAddEdge(s,r.id)),e.controlEdge={from:s,to:r?r.id:void 0},this.selectionHandler.generateClickEvent("controlNodeDragEnd",e,t),this.body.emitter.emit("_redraw")}_dragStartEdge(e){let t=this.lastTouch;this.selectionHandler.generateClickEvent("dragStart",e,t,void 0,!0)}_performAddNode(e){let t={id:Te(),x:e.pointer.canvas.x,y:e.pointer.canvas.y,label:"new"};if(typeof this.options.addNode=="function")if(this.options.addNode.length===2)this.options.addNode(t,i=>{i!=null&&this.inMode==="addNode"&&this.body.data.nodes.getDataSet().add(i),this.showManipulatorToolbar()});else throw this.showManipulatorToolbar(),new Error("The function for add does not support two arguments (data,callback)");else this.body.data.nodes.getDataSet().add(t),this.showManipulatorToolbar()}_performAddEdge(e,t){let i={from:e,to:t};if(typeof this.options.addEdge=="function")if(this.options.addEdge.length===2)this.options.addEdge(i,s=>{s!=null&&this.inMode==="addEdge"&&(this.body.data.edges.getDataSet().add(s),this.selectionHandler.unselectAll(),this.showManipulatorToolbar())});else throw new Error("The function for connect does not support two arguments (data,callback)");else this.body.data.edges.getDataSet().add(i),this.selectionHandler.unselectAll(),this.showManipulatorToolbar()}_performEditEdge(e,t){let i={id:this.edgeBeingEditedId,from:e,to:t,label:this.body.data.edges.get(this.edgeBeingEditedId).label},s=this.options.editEdge;if(typeof s=="object"&&(s=s.editWithoutDrag),typeof s=="function")if(s.length===2)s(i,o=>{o==null||this.inMode!=="editEdge"?(this.body.edges[i.id].updateEdgeType(),this.body.emitter.emit("_redraw"),this.showManipulatorToolbar()):(this.body.data.edges.getDataSet().update(o),this.selectionHandler.unselectAll(),this.showManipulatorToolbar())});else throw new Error("The function for edit does not support two arguments (data, callback)");else this.body.data.edges.getDataSet().update(i),this.selectionHandler.unselectAll(),this.showManipulatorToolbar()}},O="string",S="boolean",y="number",xt="array",P="object",On="dom",La="any",Vi=["arrow","bar","box","circle","crow","curve","diamond","image","inv_curve","inv_triangle","triangle","vee"],qi={borderWidth:{number:y},borderWidthSelected:{number:y,undefined:"undefined"},brokenImage:{string:O,undefined:"undefined"},chosen:{label:{boolean:S,function:"function"},node:{boolean:S,function:"function"},__type__:{object:P,boolean:S}},color:{border:{string:O},background:{string:O},highlight:{border:{string:O},background:{string:O},__type__:{object:P,string:O}},hover:{border:{string:O},background:{string:O},__type__:{object:P,string:O}},__type__:{object:P,string:O}},opacity:{number:y,undefined:"undefined"},fixed:{x:{boolean:S},y:{boolean:S},__type__:{object:P,boolean:S}},font:{align:{string:O},color:{string:O},size:{number:y},face:{string:O},background:{string:O},strokeWidth:{number:y},strokeColor:{string:O},vadjust:{number:y},multi:{boolean:S,string:O},bold:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},boldital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},ital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},mono:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},__type__:{object:P,string:O}},group:{string:O,number:y,undefined:"undefined"},heightConstraint:{minimum:{number:y},valign:{string:O},__type__:{object:P,boolean:S,number:y}},hidden:{boolean:S},icon:{face:{string:O},code:{string:O},size:{number:y},color:{string:O},weight:{string:O,number:y},__type__:{object:P}},id:{string:O,number:y},image:{selected:{string:O,undefined:"undefined"},unselected:{string:O,undefined:"undefined"},__type__:{object:P,string:O}},imagePadding:{top:{number:y},right:{number:y},bottom:{number:y},left:{number:y},__type__:{object:P,number:y}},label:{string:O,undefined:"undefined"},labelHighlightBold:{boolean:S},level:{number:y,undefined:"undefined"},margin:{top:{number:y},right:{number:y},bottom:{number:y},left:{number:y},__type__:{object:P,number:y}},mass:{number:y},physics:{boolean:S},scaling:{min:{number:y},max:{number:y},label:{enabled:{boolean:S},min:{number:y},max:{number:y},maxVisible:{number:y},drawThreshold:{number:y},__type__:{object:P,boolean:S}},customScalingFunction:{function:"function"},__type__:{object:P}},shadow:{enabled:{boolean:S},color:{string:O},size:{number:y},x:{number:y},y:{number:y},__type__:{object:P,boolean:S}},shape:{string:["custom","ellipse","circle","database","box","text","image","circularImage","diamond","dot","star","triangle","triangleDown","square","icon","hexagon"]},ctxRenderer:{function:"function"},shapeProperties:{borderDashes:{boolean:S,array:xt},borderRadius:{number:y},interpolation:{boolean:S},useImageSize:{boolean:S},useBorderWithImage:{boolean:S},coordinateOrigin:{string:["center","top-left"]},__type__:{object:P}},size:{number:y},title:{string:O,dom:On,undefined:"undefined"},value:{number:y,undefined:"undefined"},widthConstraint:{minimum:{number:y},maximum:{number:y},__type__:{object:P,boolean:S,number:y}},x:{number:y},y:{number:y},__type__:{object:P}},Ra={configure:{enabled:{boolean:S},filter:{boolean:S,string:O,array:xt,function:"function"},container:{dom:On},showButton:{boolean:S},__type__:{object:P,boolean:S,string:O,array:xt,function:"function"}},edges:{arrows:{to:{enabled:{boolean:S},scaleFactor:{number:y},type:{string:Vi},imageHeight:{number:y},imageWidth:{number:y},src:{string:O},__type__:{object:P,boolean:S}},middle:{enabled:{boolean:S},scaleFactor:{number:y},type:{string:Vi},imageWidth:{number:y},imageHeight:{number:y},src:{string:O},__type__:{object:P,boolean:S}},from:{enabled:{boolean:S},scaleFactor:{number:y},type:{string:Vi},imageWidth:{number:y},imageHeight:{number:y},src:{string:O},__type__:{object:P,boolean:S}},__type__:{string:["from","to","middle"],object:P}},endPointOffset:{from:{number:y},to:{number:y},__type__:{object:P,number:y}},arrowStrikethrough:{boolean:S},background:{enabled:{boolean:S},color:{string:O},size:{number:y},dashes:{boolean:S,array:xt},__type__:{object:P,boolean:S}},chosen:{label:{boolean:S,function:"function"},edge:{boolean:S,function:"function"},__type__:{object:P,boolean:S}},color:{color:{string:O},highlight:{string:O},hover:{string:O},inherit:{string:["from","to","both"],boolean:S},opacity:{number:y},__type__:{object:P,string:O}},dashes:{boolean:S,array:xt},font:{color:{string:O},size:{number:y},face:{string:O},background:{string:O},strokeWidth:{number:y},strokeColor:{string:O},align:{string:["horizontal","top","middle","bottom"]},vadjust:{number:y},multi:{boolean:S,string:O},bold:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},boldital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},ital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},mono:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},__type__:{object:P,string:O}},hidden:{boolean:S},hoverWidth:{function:"function",number:y},label:{string:O,undefined:"undefined"},labelHighlightBold:{boolean:S},length:{number:y,undefined:"undefined"},physics:{boolean:S},scaling:{min:{number:y},max:{number:y},label:{enabled:{boolean:S},min:{number:y},max:{number:y},maxVisible:{number:y},drawThreshold:{number:y},__type__:{object:P,boolean:S}},customScalingFunction:{function:"function"},__type__:{object:P}},selectionWidth:{function:"function",number:y},selfReferenceSize:{number:y},selfReference:{size:{number:y},angle:{number:y},renderBehindTheNode:{boolean:S},__type__:{object:P}},shadow:{enabled:{boolean:S},color:{string:O},size:{number:y},x:{number:y},y:{number:y},__type__:{object:P,boolean:S}},smooth:{enabled:{boolean:S},type:{string:["dynamic","continuous","discrete","diagonalCross","straightCross","horizontal","vertical","curvedCW","curvedCCW","cubicBezier"]},roundness:{number:y},forceDirection:{string:["horizontal","vertical","none"],boolean:S},__type__:{object:P,boolean:S}},title:{string:O,undefined:"undefined"},width:{number:y},widthConstraint:{maximum:{number:y},__type__:{object:P,boolean:S,number:y}},value:{number:y,undefined:"undefined"},__type__:{object:P}},groups:{useDefaultGroups:{boolean:S},__any__:qi,__type__:{object:P}},interaction:{dragNodes:{boolean:S},dragView:{boolean:S},hideEdgesOnDrag:{boolean:S},hideEdgesOnZoom:{boolean:S},hideNodesOnDrag:{boolean:S},hover:{boolean:S},keyboard:{enabled:{boolean:S},speed:{x:{number:y},y:{number:y},zoom:{number:y},__type__:{object:P}},bindToWindow:{boolean:S},autoFocus:{boolean:S},__type__:{object:P,boolean:S}},multiselect:{boolean:S},navigationButtons:{boolean:S},selectable:{boolean:S},selectConnectedEdges:{boolean:S},hoverConnectedEdges:{boolean:S},tooltipDelay:{number:y},zoomView:{boolean:S},zoomSpeed:{number:y},__type__:{object:P}},layout:{randomSeed:{undefined:"undefined",number:y,string:O},improvedLayout:{boolean:S},clusterThreshold:{number:y},hierarchical:{enabled:{boolean:S},levelSeparation:{number:y},nodeSpacing:{number:y},treeSpacing:{number:y},blockShifting:{boolean:S},edgeMinimization:{boolean:S},parentCentralization:{boolean:S},direction:{string:["UD","DU","LR","RL"]},sortMethod:{string:["hubsize","directed"]},shakeTowards:{string:["leaves","roots"]},__type__:{object:P,boolean:S}},__type__:{object:P}},manipulation:{enabled:{boolean:S},initiallyActive:{boolean:S},addNode:{boolean:S,function:"function"},addEdge:{boolean:S,function:"function"},editNode:{function:"function"},editEdge:{editWithoutDrag:{function:"function"},__type__:{object:P,boolean:S,function:"function"}},deleteNode:{boolean:S,function:"function"},deleteEdge:{boolean:S,function:"function"},controlNodeStyle:qi,__type__:{object:P,boolean:S}},nodes:qi,physics:{enabled:{boolean:S},barnesHut:{theta:{number:y},gravitationalConstant:{number:y},centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},damping:{number:y},avoidOverlap:{number:y},__type__:{object:P}},forceAtlas2Based:{theta:{number:y},gravitationalConstant:{number:y},centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},damping:{number:y},avoidOverlap:{number:y},__type__:{object:P}},repulsion:{centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},nodeDistance:{number:y},damping:{number:y},__type__:{object:P}},hierarchicalRepulsion:{centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},nodeDistance:{number:y},damping:{number:y},avoidOverlap:{number:y},__type__:{object:P}},maxVelocity:{number:y},minVelocity:{number:y},solver:{string:["barnesHut","repulsion","hierarchicalRepulsion","forceAtlas2Based"]},stabilization:{enabled:{boolean:S},iterations:{number:y},updateInterval:{number:y},onlyDynamicEdges:{boolean:S},fit:{boolean:S},__type__:{object:P,boolean:S}},timestep:{number:y},adaptiveTimestep:{boolean:S},wind:{x:{number:y},y:{number:y},__type__:{object:P}},__type__:{object:P,boolean:S}},autoResize:{boolean:S},clickToUse:{boolean:S},locale:{string:O},locales:{__any__:{any:La},__type__:{object:P}},height:{string:O},width:{string:O},__type__:{object:P}},In={nodes:{borderWidth:[1,0,10,1],borderWidthSelected:[2,0,10,1],color:{border:["color","#2B7CE9"],background:["color","#97C2FC"],highlight:{border:["color","#2B7CE9"],background:["color","#D2E5FF"]},hover:{border:["color","#2B7CE9"],background:["color","#D2E5FF"]}},opacity:[0,0,1,.1],fixed:{x:!1,y:!1},font:{color:["color","#343434"],size:[14,0,100,1],face:["arial","verdana","tahoma"],background:["color","none"],strokeWidth:[0,0,50,1],strokeColor:["color","#ffffff"]},hidden:!1,labelHighlightBold:!0,physics:!0,scaling:{min:[10,0,200,1],max:[30,0,200,1],label:{enabled:!1,min:[14,0,200,1],max:[30,0,200,1],maxVisible:[30,0,200,1],drawThreshold:[5,0,20,1]}},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:[10,0,20,1],x:[5,-30,30,1],y:[5,-30,30,1]},shape:["ellipse","box","circle","database","diamond","dot","square","star","text","triangle","triangleDown","hexagon"],shapeProperties:{borderDashes:!1,borderRadius:[6,0,20,1],interpolation:!0,useImageSize:!1},size:[25,0,200,1]},edges:{arrows:{to:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"},middle:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"},from:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"}},endPointOffset:{from:[0,-10,10,1],to:[0,-10,10,1]},arrowStrikethrough:!0,color:{color:["color","#848484"],highlight:["color","#848484"],hover:["color","#848484"],inherit:["from","to","both",!0,!1],opacity:[1,0,1,.05]},dashes:!1,font:{color:["color","#343434"],size:[14,0,100,1],face:["arial","verdana","tahoma"],background:["color","none"],strokeWidth:[2,0,50,1],strokeColor:["color","#ffffff"],align:["horizontal","top","middle","bottom"]},hidden:!1,hoverWidth:[1.5,0,5,.1],labelHighlightBold:!0,physics:!0,scaling:{min:[1,0,100,1],max:[15,0,100,1],label:{enabled:!0,min:[14,0,200,1],max:[30,0,200,1],maxVisible:[30,0,200,1],drawThreshold:[5,0,20,1]}},selectionWidth:[1.5,0,5,.1],selfReferenceSize:[20,0,200,1],selfReference:{size:[20,0,200,1],angle:[Math.PI/2,-6*Math.PI,6*Math.PI,Math.PI/8],renderBehindTheNode:!0},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:[10,0,20,1],x:[5,-30,30,1],y:[5,-30,30,1]},smooth:{enabled:!0,type:["dynamic","continuous","discrete","diagonalCross","straightCross","horizontal","vertical","curvedCW","curvedCCW","cubicBezier"],forceDirection:["horizontal","vertical","none"],roundness:[.5,0,1,.05]},width:[1,0,30,1]},layout:{hierarchical:{enabled:!1,levelSeparation:[150,20,500,5],nodeSpacing:[100,20,500,5],treeSpacing:[200,20,500,5],blockShifting:!0,edgeMinimization:!0,parentCentralization:!0,direction:["UD","DU","LR","RL"],sortMethod:["hubsize","directed"],shakeTowards:["leaves","roots"]}},interaction:{dragNodes:!0,dragView:!0,hideEdgesOnDrag:!1,hideEdgesOnZoom:!1,hideNodesOnDrag:!1,hover:!1,keyboard:{enabled:!1,speed:{x:[10,0,40,1],y:[10,0,40,1],zoom:[.02,0,.1,.005]},bindToWindow:!0,autoFocus:!0},multiselect:!1,navigationButtons:!1,selectable:!0,selectConnectedEdges:!0,hoverConnectedEdges:!0,tooltipDelay:[300,0,1e3,25],zoomView:!0,zoomSpeed:[1,.1,2,.1]},manipulation:{enabled:!1,initiallyActive:!1},physics:{enabled:!0,barnesHut:{theta:[.5,.1,1,.05],gravitationalConstant:[-2e3,-3e4,0,50],centralGravity:[.3,0,10,.05],springLength:[95,0,500,5],springConstant:[.04,0,1.2,.005],damping:[.09,0,1,.01],avoidOverlap:[0,0,1,.01]},forceAtlas2Based:{theta:[.5,.1,1,.05],gravitationalConstant:[-50,-500,0,1],centralGravity:[.01,0,1,.005],springLength:[95,0,500,5],springConstant:[.08,0,1.2,.005],damping:[.4,0,1,.01],avoidOverlap:[0,0,1,.01]},repulsion:{centralGravity:[.2,0,10,.05],springLength:[200,0,500,5],springConstant:[.05,0,1.2,.005],nodeDistance:[100,0,500,5],damping:[.09,0,1,.01]},hierarchicalRepulsion:{centralGravity:[.2,0,10,.05],springLength:[100,0,500,5],springConstant:[.01,0,1.2,.005],nodeDistance:[120,0,500,5],damping:[.09,0,1,.01],avoidOverlap:[0,0,1,.01]},maxVelocity:[50,0,150,1],minVelocity:[.1,.01,.5,.01],solver:["barnesHut","forceAtlas2Based","repulsion","hierarchicalRepulsion"],timestep:[.5,.01,1,.01],wind:{x:[0,-10,10,.1],y:[0,-10,10,.1]}}},Ha=(n,e,t)=>!!(n.includes("physics")&&In.physics.solver.includes(e)&&t.physics.solver!==e&&e!=="wind");var Pn=class{constructor(){}getDistances(e,t,i){let s={},o=e.edges;for(let a=0;ao&&ar&&Cthis.body.emitter.emit("_requestRedraw")),this.groups=new Co,this.canvas=new gn(this.body),this.selectionHandler=new _n(this.body,this.canvas),this.interactionHandler=new bn(this.body,this.canvas,this.selectionHandler),this.view=new mn(this.body,this.canvas),this.renderer=new fn(this.body,this.canvas),this.physics=new ln(this.body),this.layoutEngine=new kn(this.body),this.clustering=new un(this.body),this.manipulation=new Sn(this.body,this.canvas,this.selectionHandler,this.interactionHandler),this.nodesHandler=new Vo(this.body,this.images,this.groups,this.layoutEngine),this.edgesHandler=new on(this.body,this.images,this.groups),this.body.modules.kamadaKawai=new Mn(this.body,150,.05),this.body.modules.clustering=this.clustering,this.canvas._create(),this.setOptions(t),this.setData(e)}(0,ro.default)(I.prototype);I.prototype.setOptions=function(n){if(n===null&&(n=void 0),n!==void 0){if($s.validate(n,Ra)===!0&&console.error("%cErrors have been found in the supplied options object.",Ei),Ve(["locale","locales","clickToUse"],this.options,n),n.locale!==void 0&&(n.locale=Ma(n.locales||this.options.locales,n.locale)),n=this.layoutEngine.setOptions(n.layout,n),this.canvas.setOptions(n),this.groups.setOptions(n.groups),this.nodesHandler.setOptions(n.nodes),this.edgesHandler.setOptions(n.edges),this.physics.setOptions(n.physics),this.manipulation.setOptions(n.manipulation,n,this.options),this.interactionHandler.setOptions(n.interaction),this.renderer.setOptions(n.interaction),this.selectionHandler.setOptions(n.interaction),n.groups!==void 0&&this.body.emitter.emit("refreshNodes"),"configure"in n&&(this.configurator||(this.configurator=new Zs(this,this.body.container,In,this.canvas.pixelRatio,Ha)),this.configurator.setOptions(n.configure)),this.configurator&&this.configurator.options.enabled===!0){let i={nodes:{},edges:{},layout:{},interaction:{},manipulation:{},physics:{},global:{}};j(i.nodes,this.nodesHandler.options),j(i.edges,this.edgesHandler.options),j(i.layout,this.layoutEngine.options),j(i.interaction,this.selectionHandler.options),j(i.interaction,this.renderer.options),j(i.interaction,this.interactionHandler.options),j(i.manipulation,this.manipulation.options),j(i.physics,this.physics.options),j(i.global,this.canvas.options),j(i.global,this.options),this.configurator.setModuleOptions(i)}n.clickToUse!==void 0?n.clickToUse===!0?this.activator===void 0&&(this.activator=new Ks(this.canvas.frame),this.activator.on("change",()=>{this.body.emitter.emit("activate")})):(this.activator!==void 0&&(this.activator.destroy(),delete this.activator),this.body.emitter.emit("activate")):this.body.emitter.emit("activate"),this.canvas.setSize(),this.body.emitter.emit("startSimulation")}};I.prototype._updateVisibleIndices=function(){let n=this.body.nodes,e=this.body.edges;this.body.nodeIndices=[],this.body.edgeIndices=[];for(let t in n)Object.prototype.hasOwnProperty.call(n,t)&&!this.clustering._isClusteredNode(t)&&n[t].options.hidden===!1&&this.body.nodeIndices.push(n[t].id);for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t)){let i=e[t],s=n[i.fromId],o=n[i.toId],r=s!==void 0&&o!==void 0;!this.clustering._isClusteredEdge(t)&&i.options.hidden===!1&&r&&s.options.hidden===!1&&o.options.hidden===!1&&this.body.edgeIndices.push(i.id)}};I.prototype.bindEventListeners=function(){this.body.emitter.on("_dataChanged",()=>{this.edgesHandler._updateState(),this.body.emitter.emit("_dataUpdated")}),this.body.emitter.on("_dataUpdated",()=>{this.clustering._updateState(),this._updateVisibleIndices(),this._updateValueRange(this.body.nodes),this._updateValueRange(this.body.edges),this.body.emitter.emit("startSimulation"),this.body.emitter.emit("_requestRedraw")})};I.prototype.setData=function(n){if(this.body.emitter.emit("resetPhysics"),this.body.emitter.emit("_resetData"),this.selectionHandler.unselectAll(),n&&n.dot&&(n.nodes||n.edges))throw new SyntaxError('Data must contain either parameter "dot" or parameter pair "nodes" and "edges", but not both.');if(this.setOptions(n&&n.options),n&&n.dot){console.warn("The dot property has been deprecated. Please use the static convertDot method to convert DOT into vis.network format and use the normal data format with nodes and edges. This converter is used like this: var data = vis.network.convertDot(dotString);");let e=ya(n.dot);this.setData(e);return}else if(n&&n.gephi){console.warn("The gephi property has been deprecated. Please use the static convertGephi method to convert gephi into vis.network format and use the normal data format with nodes and edges. This converter is used like this: var data = vis.network.convertGephi(gephiJson);");let e=ba(n.gephi);this.setData(e);return}else this.nodesHandler.setData(n&&n.nodes,!0),this.edgesHandler.setData(n&&n.edges,!0);this.body.emitter.emit("_dataChanged"),this.body.emitter.emit("_dataLoaded"),this.body.emitter.emit("initPhysics")};I.prototype.destroy=function(){this.body.emitter.emit("destroy"),this.body.emitter.off(),this.off(),delete this.groups,delete this.canvas,delete this.selectionHandler,delete this.interactionHandler,delete this.view,delete this.renderer,delete this.physics,delete this.layoutEngine,delete this.clustering,delete this.manipulation,delete this.nodesHandler,delete this.edgesHandler,delete this.configurator,delete this.images;for(let n in this.body.nodes)!Object.prototype.hasOwnProperty.call(this.body.nodes,n)||delete this.body.nodes[n];for(let n in this.body.edges)!Object.prototype.hasOwnProperty.call(this.body.edges,n)||delete this.body.edges[n];_e(this.body.container)};I.prototype._updateValueRange=function(n){let e,t,i,s=0;for(e in n)if(Object.prototype.hasOwnProperty.call(n,e)){let o=n[e].getValue();o!==void 0&&(t=t===void 0?o:Math.min(o,t),i=i===void 0?o:Math.max(o,i),s+=o)}if(t!==void 0&&i!==void 0)for(e in n)Object.prototype.hasOwnProperty.call(n,e)&&n[e].setValueRange(t,i,s)};I.prototype.isActive=function(){return!this.activator||this.activator.active};I.prototype.setSize=function(){return this.canvas.setSize.apply(this.canvas,arguments)};I.prototype.canvasToDOM=function(){return this.canvas.canvasToDOM.apply(this.canvas,arguments)};I.prototype.DOMtoCanvas=function(){return this.canvas.DOMtoCanvas.apply(this.canvas,arguments)};I.prototype.findNode=function(){return this.clustering.findNode.apply(this.clustering,arguments)};I.prototype.isCluster=function(){return this.clustering.isCluster.apply(this.clustering,arguments)};I.prototype.openCluster=function(){return this.clustering.openCluster.apply(this.clustering,arguments)};I.prototype.cluster=function(){return this.clustering.cluster.apply(this.clustering,arguments)};I.prototype.getNodesInCluster=function(){return this.clustering.getNodesInCluster.apply(this.clustering,arguments)};I.prototype.clusterByConnection=function(){return this.clustering.clusterByConnection.apply(this.clustering,arguments)};I.prototype.clusterByHubsize=function(){return this.clustering.clusterByHubsize.apply(this.clustering,arguments)};I.prototype.updateClusteredNode=function(){return this.clustering.updateClusteredNode.apply(this.clustering,arguments)};I.prototype.getClusteredEdges=function(){return this.clustering.getClusteredEdges.apply(this.clustering,arguments)};I.prototype.getBaseEdge=function(){return this.clustering.getBaseEdge.apply(this.clustering,arguments)};I.prototype.getBaseEdges=function(){return this.clustering.getBaseEdges.apply(this.clustering,arguments)};I.prototype.updateEdge=function(){return this.clustering.updateEdge.apply(this.clustering,arguments)};I.prototype.clusterOutliers=function(){return this.clustering.clusterOutliers.apply(this.clustering,arguments)};I.prototype.getSeed=function(){return this.layoutEngine.getSeed.apply(this.layoutEngine,arguments)};I.prototype.enableEditMode=function(){return this.manipulation.enableEditMode.apply(this.manipulation,arguments)};I.prototype.disableEditMode=function(){return this.manipulation.disableEditMode.apply(this.manipulation,arguments)};I.prototype.addNodeMode=function(){return this.manipulation.addNodeMode.apply(this.manipulation,arguments)};I.prototype.editNode=function(){return this.manipulation.editNode.apply(this.manipulation,arguments)};I.prototype.editNodeMode=function(){return console.warn("Deprecated: Please use editNode instead of editNodeMode."),this.manipulation.editNode.apply(this.manipulation,arguments)};I.prototype.addEdgeMode=function(){return this.manipulation.addEdgeMode.apply(this.manipulation,arguments)};I.prototype.editEdgeMode=function(){return this.manipulation.editEdgeMode.apply(this.manipulation,arguments)};I.prototype.deleteSelected=function(){return this.manipulation.deleteSelected.apply(this.manipulation,arguments)};I.prototype.getPositions=function(){return this.nodesHandler.getPositions.apply(this.nodesHandler,arguments)};I.prototype.getPosition=function(){return this.nodesHandler.getPosition.apply(this.nodesHandler,arguments)};I.prototype.storePositions=function(){return this.nodesHandler.storePositions.apply(this.nodesHandler,arguments)};I.prototype.moveNode=function(){return this.nodesHandler.moveNode.apply(this.nodesHandler,arguments)};I.prototype.getBoundingBox=function(){return this.nodesHandler.getBoundingBox.apply(this.nodesHandler,arguments)};I.prototype.getConnectedNodes=function(n){return this.body.nodes[n]!==void 0?this.nodesHandler.getConnectedNodes.apply(this.nodesHandler,arguments):this.edgesHandler.getConnectedNodes.apply(this.edgesHandler,arguments)};I.prototype.getConnectedEdges=function(){return this.nodesHandler.getConnectedEdges.apply(this.nodesHandler,arguments)};I.prototype.startSimulation=function(){return this.physics.startSimulation.apply(this.physics,arguments)};I.prototype.stopSimulation=function(){return this.physics.stopSimulation.apply(this.physics,arguments)};I.prototype.stabilize=function(){return this.physics.stabilize.apply(this.physics,arguments)};I.prototype.getSelection=function(){return this.selectionHandler.getSelection.apply(this.selectionHandler,arguments)};I.prototype.setSelection=function(){return this.selectionHandler.setSelection.apply(this.selectionHandler,arguments)};I.prototype.getSelectedNodes=function(){return this.selectionHandler.getSelectedNodeIds.apply(this.selectionHandler,arguments)};I.prototype.getSelectedEdges=function(){return this.selectionHandler.getSelectedEdgeIds.apply(this.selectionHandler,arguments)};I.prototype.getNodeAt=function(){let n=this.selectionHandler.getNodeAt.apply(this.selectionHandler,arguments);return n!==void 0&&n.id!==void 0?n.id:n};I.prototype.getEdgeAt=function(){let n=this.selectionHandler.getEdgeAt.apply(this.selectionHandler,arguments);return n!==void 0&&n.id!==void 0?n.id:n};I.prototype.selectNodes=function(){return this.selectionHandler.selectNodes.apply(this.selectionHandler,arguments)};I.prototype.selectEdges=function(){return this.selectionHandler.selectEdges.apply(this.selectionHandler,arguments)};I.prototype.unselectAll=function(){this.selectionHandler.unselectAll.apply(this.selectionHandler,arguments),this.selectionHandler.commitWithoutEmitting.apply(this.selectionHandler),this.redraw()};I.prototype.redraw=function(){return this.renderer.redraw.apply(this.renderer,arguments)};I.prototype.getScale=function(){return this.view.getScale.apply(this.view,arguments)};I.prototype.getViewPosition=function(){return this.view.getViewPosition.apply(this.view,arguments)};I.prototype.fit=function(){return this.view.fit.apply(this.view,arguments)};I.prototype.moveTo=function(){return this.view.moveTo.apply(this.view,arguments)};I.prototype.focus=function(){return this.view.focus.apply(this.view,arguments)};I.prototype.releaseNode=function(){return this.view.releaseNode.apply(this.view,arguments)};I.prototype.getOptionsFromConfigurator=function(){let n={};return this.configurator&&(n=this.configurator.getOptions.apply(this.configurator)),n};var Ct=null,Tt=null,Dn=null,ja="image/png",Fn=null,Nn=null,Ui=new fe,Yi=new fe,Bn={interaction:{hover:!0,hoverConnectedEdges:!0,multiselect:!0},nodes:{shape:"image",brokenImage:"../../static/netbox_topology_views/img/role-unknown.png",size:35,font:{multi:"md",face:"helvetica"}},edges:{length:100,width:2,font:{face:"helvetica"},shadow:{enabled:!0}},physics:{solver:"forceAtlas2Based"}},An=null,zn=null;function Wa(n){var e=null;if(document.cookie&&document.cookie!=="")for(var t=document.cookie.split(";"),i=0;i0)for(let a=0;a0)for(let o=0;o/&/.test(s)?(t.replace(t.text,"<","<")||t.replace(t.text,"&","&")||t.add("&"),!0):!1;for(;t.position")||t.parseStartTag("ital","")||t.parseStartTag("mono","")||t.parseEndTag("bold","")||t.parseEndTag("ital","")||t.parseEndTag("mono",""))||i(s)||t.add(s),t.position++}return t.emitBlock(),t.blocks}splitMarkdownBlocks(e){let t=new Pi(e),i=!0,s=o=>/\\/.test(o)?(t.positionthis.parent.fontOptions.maxWdt}getLongestFit(e){let t="",i=0;for(;i0;){let o=this.getLongestFit(s);if(o===0){let r=s[0],a=this.getLongestFitWord(r);this.lines.newLine(r.slice(0,a),t),s[0]=r.slice(a)}else{let r=o;s[o-1]===" "?o--:s[r]===" "&&r++;let a=s.slice(0,o).join("");o==s.length&&i?this.lines.append(a,t):this.lines.newLine(a,t),s=s.slice(r)}}}},Xt=["bold","ital","boldital","mono"],Ye=class{constructor(e,t,i=!1){this.body=e,this.pointToSelf=!1,this.baseSize=void 0,this.fontOptions={},this.setOptions(t),this.size={top:0,left:0,width:0,height:0,yLine:0},this.isEdgeLabel=i}setOptions(e){if(this.elementOptions=e,this.initFontOptions(e.font),Yt(e.label)?this.labelDirty=!0:e.label=void 0,e.font!==void 0&&e.font!==null){if(typeof e.font=="string")this.baseSize=this.fontOptions.size;else if(typeof e.font=="object"){let t=e.font.size;t!==void 0&&(this.baseSize=t)}}}initFontOptions(e){if(A(Xt,t=>{this.fontOptions[t]={}}),Ye.parseFontString(this.fontOptions,e)){this.fontOptions.vadjust=0;return}A(e,(t,i)=>{t!=null&&typeof t!="object"&&(this.fontOptions[i]=t)})}static parseFontString(e,t){if(!t||typeof t!="string")return!1;let i=t.split(" ");return e.size=+i[0].replace("px",""),e.face=i[1],e.color=i[2],!0}constrain(e){let t={constrainWidth:!1,maxWdt:-1,minWdt:-1,constrainHeight:!1,minHgt:-1,valign:"middle"},i=xe(e,"widthConstraint");if(typeof i=="number")t.maxWdt=Number(i),t.minWdt=Number(i);else if(typeof i=="object"){let o=xe(e,["widthConstraint","maximum"]);typeof o=="number"&&(t.maxWdt=Number(o));let r=xe(e,["widthConstraint","minimum"]);typeof r=="number"&&(t.minWdt=Number(r))}let s=xe(e,"heightConstraint");if(typeof s=="number")t.minHgt=Number(s);else if(typeof s=="object"){let o=xe(e,["heightConstraint","minimum"]);typeof o=="number"&&(t.minHgt=Number(o));let r=xe(e,["heightConstraint","valign"]);typeof r=="string"&&(r==="top"||r==="bottom")&&(t.valign=r)}return t}update(e,t){this.setOptions(e,!0),this.propagateFonts(t),j(this.fontOptions,this.constrain(t)),this.fontOptions.chooser=Oi("label",t)}adjustSizes(e){let t=e?e.right+e.left:0;this.fontOptions.constrainWidth&&(this.fontOptions.maxWdt-=t,this.fontOptions.minWdt-=t);let i=e?e.top+e.bottom:0;this.fontOptions.constrainHeight&&(this.fontOptions.minHgt-=i)}addFontOptionsToPile(e,t){for(let i=0;i{r!==void 0&&(Object.prototype.hasOwnProperty.call(t,a)||(Xt.indexOf(a)!==-1?t[a]={}:t[a]=r))})}return t}getFontOption(e,t,i){let s;for(let o=0;o{o[d]=a}),o.size=Number(o.size),o.vadjust=Number(o.vadjust)}}draw(e,t,i,s,o,r="middle"){if(this.elementOptions.label===void 0)return;let a=this.fontOptions.size*this.body.view.scale;this.elementOptions.label&&a=this.elementOptions.scaling.label.maxVisible&&(a=Number(this.elementOptions.scaling.label.maxVisible)/this.body.view.scale),this.calculateLabelSize(e,s,o,t,i,r),this._drawBackground(e),this._drawText(e,t,this.size.yLine,r,a))}_drawBackground(e){if(this.fontOptions.background!==void 0&&this.fontOptions.background!=="none"){e.fillStyle=this.fontOptions.background;let t=this.getSize();e.fillRect(t.left,t.top,t.width,t.height)}}_drawText(e,t,i,s="middle",o){[t,i]=this._setAlignment(e,t,i,s),e.textAlign="left",t=t-this.size.width/2,this.fontOptions.valign&&this.size.height>this.size.labelHeight&&(this.fontOptions.valign==="top"&&(i-=(this.size.height-this.size.labelHeight)/2),this.fontOptions.valign==="bottom"&&(i+=(this.size.height-this.size.labelHeight)/2));for(let r=0;r0&&(e.lineWidth=l.strokeWidth,e.strokeStyle=u,e.lineJoin="round"),e.fillStyle=c,l.strokeWidth>0&&e.strokeText(l.text,t+d,i+l.vadjust),e.fillText(l.text,t+d,i+l.vadjust),d+=l.width}i+=a.height}}}_setAlignment(e,t,i,s){if(this.isEdgeLabel&&this.fontOptions.align!=="horizontal"&&this.pointToSelf===!1){t=0,i=0;let o=2;this.fontOptions.align==="top"?(e.textBaseline="alphabetic",i-=2*o):this.fontOptions.align==="bottom"?(e.textBaseline="hanging",i+=2*o):e.textBaseline="middle"}else e.textBaseline=s;return[t,i]}_getColor(e,t,i){let s=e||"#000000",o=i||"#ffffff";if(t<=this.elementOptions.scaling.label.drawThreshold){let r=Math.max(0,Math.min(1,1-(this.elementOptions.scaling.label.drawThreshold-t)));s=re(s,r),o=re(o,r)}return[s,o]}getTextSize(e,t=!1,i=!1){return this._processLabel(e,t,i),{width:this.size.width,height:this.size.height,lineCount:this.lineCount}}getSize(){let e=2,t=this.size.left,i=this.size.top-.5*e;if(this.isEdgeLabel){let o=-this.size.width*.5;switch(this.fontOptions.align){case"middle":t=o,i=-this.size.height*.5;break;case"top":t=o,i=-(this.size.height+e);break;case"bottom":t=o,i=e;break}}return{left:t,top:i,width:this.size.width,height:this.size.height}}calculateLabelSize(e,t,i,s=0,o=0,r="middle"){this._processLabel(e,t,i),this.size.left=s-this.size.width*.5,this.size.top=o-this.size.height*.5,this.size.yLine=o+(1-this.lineCount)*.5*this.fontOptions.size,r==="hanging"&&(this.size.top+=.5*this.fontOptions.size,this.size.top+=4,this.size.yLine+=4)}getFormattingValues(e,t,i,s){let o=function(d,h,l){return h==="normal"?l==="mod"?"":d[l]:d[h][l]!==void 0?d[h][l]:d[l]},r={color:o(this.fontOptions,s,"color"),size:o(this.fontOptions,s,"size"),face:o(this.fontOptions,s,"face"),mod:o(this.fontOptions,s,"mod"),vadjust:o(this.fontOptions,s,"vadjust"),strokeWidth:this.fontOptions.strokeWidth,strokeColor:this.fontOptions.strokeColor};(t||i)&&(s==="normal"&&this.fontOptions.chooser===!0&&this.elementOptions.labelHighlightBold?r.mod="bold":typeof this.fontOptions.chooser=="function"&&this.fontOptions.chooser(r,this.elementOptions.id,t,i));let a="";return r.mod!==void 0&&r.mod!==""&&(a+=r.mod+" "),a+=r.size+"px "+r.face,e.font=a.replace(/"/g,""),r.font=e.font,r.height=r.size,r}differentState(e,t){return e!==this.selectedState||t!==this.hoverState}_processLabelText(e,t,i,s){return new ko(e,this,t,i).process(s)}_processLabel(e,t,i){if(this.labelDirty===!1&&!this.differentState(t,i))return;let s=this._processLabelText(e,t,i,this.elementOptions.label);this.fontOptions.minWdt>0&&s.width0&&s.height0&&(this.enableBorderDashes(e,t),e.stroke(),this.disableBorderDashes(e,t)),e.restore()}performFill(e,t){e.save(),e.fillStyle=t.color,this.enableShadow(e,t),e.fill(),this.disableShadow(e,t),e.restore(),this.performStroke(e,t)}_addBoundingBoxMargin(e){this.boundingBox.left-=e,this.boundingBox.top-=e,this.boundingBox.bottom+=e,this.boundingBox.right+=e}_updateBoundingBox(e,t,i,s,o){i!==void 0&&this.resize(i,s,o),this.left=e-this.width/2,this.top=t-this.height/2,this.boundingBox.left=this.left,this.boundingBox.top=this.top,this.boundingBox.bottom=this.top+this.height,this.boundingBox.right=this.left+this.width}updateBoundingBox(e,t,i,s,o){this._updateBoundingBox(e,t,i,s,o)}getDimensionsFromLabel(e,t,i){this.textSize=this.labelModule.getTextSize(e,t,i);let s=this.textSize.width,o=this.textSize.height,r=14;return s===0&&(s=r,o=r),{width:s,height:o}}},So=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t=this.selected,i=this.hover){if(this.needsRefresh(t,i)){let s=this.getDimensionsFromLabel(e,t,i);this.width=s.width+this.margin.right+this.margin.left,this.height=s.height+this.margin.top+this.margin.bottom,this.radius=this.width/2}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this.initContextForDraw(e,r),ro(e,this.left,this.top,this.width,this.height,r.borderRadius),this.performFill(e,r),this.updateBoundingBox(t,i,e,s,o),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,s,o)}updateBoundingBox(e,t,i,s,o){this._updateBoundingBox(e,t,i,s,o);let r=this.options.shapeProperties.borderRadius;this._addBoundingBoxMargin(r)}distanceToBorder(e,t){e&&this.resize(e);let i=this.options.borderWidth;return Math.min(Math.abs(this.width/2/Math.cos(t)),Math.abs(this.height/2/Math.sin(t)))+i}},Gt=class extends De{constructor(e,t,i){super(e,t,i);this.labelOffset=0,this.selected=!1}setOptions(e,t,i){this.options=e,t===void 0&&i===void 0||this.setImages(t,i)}setImages(e,t){t&&this.selected?(this.imageObj=t,this.imageObjAlt=e):(this.imageObj=e,this.imageObjAlt=t)}switchImages(e){let t=e&&!this.selected||!e&&this.selected;if(this.selected=e,this.imageObjAlt!==void 0&&t){let i=this.imageObj;this.imageObj=this.imageObjAlt,this.imageObjAlt=i}}_getImagePadding(){let e={top:0,right:0,bottom:0,left:0};if(this.options.imagePadding){let t=this.options.imagePadding;typeof t=="object"?(e.top=t.top,e.right=t.right,e.bottom=t.bottom,e.left=t.left):(e.top=t,e.right=t,e.bottom=t,e.left=t)}return e}_resizeImage(){let e,t;if(this.options.shapeProperties.useImageSize===!1){let i=1,s=1;this.imageObj.width&&this.imageObj.height&&(this.imageObj.width>this.imageObj.height?i=this.imageObj.width/this.imageObj.height:s=this.imageObj.height/this.imageObj.width),e=this.options.size*2*i,t=this.options.size*2*s}else{let i=this._getImagePadding();e=this.imageObj.width+i.left+i.right,t=this.imageObj.height+i.top+i.bottom}this.width=e,this.height=t,this.radius=.5*this.width}_drawRawCircle(e,t,i,s){this.initContextForDraw(e,s),Ci(e,t,i,s.size),this.performFill(e,s)}_drawImageAtPosition(e,t){if(this.imageObj.width!=0){e.globalAlpha=t.opacity!==void 0?t.opacity:1,this.enableShadow(e,t);let i=1;this.options.shapeProperties.interpolation===!0&&(i=this.imageObj.width/this.width/this.body.view.scale);let s=this._getImagePadding(),o=this.left+s.left,r=this.top+s.top,a=this.width-s.left-s.right,d=this.height-s.top-s.bottom;this.imageObj.drawImageAtPosition(e,i,o,r,a,d),this.disableShadow(e,t)}}_drawImageLabel(e,t,i,s,o){let r=0;if(this.height!==void 0){r=this.height*.5;let d=this.labelModule.getTextSize(e,s,o);d.lineCount>=1&&(r+=d.height/2)}let a=i+r;this.options.label&&(this.labelOffset=r),this.labelModule.draw(e,t,a,s,o,"hanging")}},Oo=class extends Gt{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t=this.selected,i=this.hover){if(this.needsRefresh(t,i)){let s=this.getDimensionsFromLabel(e,t,i),o=Math.max(s.width+this.margin.right+this.margin.left,s.height+this.margin.top+this.margin.bottom);this.options.size=o/2,this.width=o,this.height=o,this.radius=this.width/2}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this._drawRawCircle(e,t,i,r),this.updateBoundingBox(t,i),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,i,s,o)}updateBoundingBox(e,t){this.boundingBox.top=t-this.options.size,this.boundingBox.left=e-this.options.size,this.boundingBox.right=e+this.options.size,this.boundingBox.bottom=t+this.options.size}distanceToBorder(e){return e&&this.resize(e),this.width*.5}},Io=class extends Gt{constructor(e,t,i,s,o){super(e,t,i);this.setImages(s,o)}resize(e,t=this.selected,i=this.hover){if(this.imageObj.src===void 0||this.imageObj.width===void 0||this.imageObj.height===void 0){let o=this.options.size*2;this.width=o,this.height=o,this.radius=.5*this.width;return}this.needsRefresh(t,i)&&this._resizeImage()}draw(e,t,i,s,o,r){this.switchImages(s),this.resize();let a=t,d=i;this.options.shapeProperties.coordinateOrigin==="top-left"?(this.left=t,this.top=i,a+=this.width/2,d+=this.height/2):(this.left=t-this.width/2,this.top=i-this.height/2),this._drawRawCircle(e,a,d,r),e.save(),e.clip(),this._drawImageAtPosition(e,r),e.restore(),this._drawImageLabel(e,a,d,s,o),this.updateBoundingBox(t,i)}updateBoundingBox(e,t){this.options.shapeProperties.coordinateOrigin==="top-left"?(this.boundingBox.top=t,this.boundingBox.left=e,this.boundingBox.right=e+this.options.size*2,this.boundingBox.bottom=t+this.options.size*2):(this.boundingBox.top=t-this.options.size,this.boundingBox.left=e-this.options.size,this.boundingBox.right=e+this.options.size,this.boundingBox.bottom=t+this.options.size),this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelOffset)}distanceToBorder(e){return e&&this.resize(e),this.width*.5}},ke=class extends De{constructor(e,t,i){super(e,t,i)}resize(e,t=this.selected,i=this.hover,s={size:this.options.size}){var o,r;if(this.needsRefresh(t,i)){this.labelModule.getTextSize(e,t,i);let a=2*s.size;this.width=(o=this.customSizeWidth)!=null?o:a,this.height=(r=this.customSizeHeight)!=null?r:a,this.radius=.5*this.width}}_drawShape(e,t,i,s,o,r,a,d){return this.resize(e,r,a,d),this.left=s-this.width/2,this.top=o-this.height/2,this.initContextForDraw(e,d),ea(t)(e,s,o,d.size),this.performFill(e,d),this.options.icon!==void 0&&this.options.icon.code!==void 0&&(e.font=(r?"bold ":"")+this.height/2+"px "+(this.options.icon.face||"FontAwesome"),e.fillStyle=this.options.icon.color||"black",e.textAlign="center",e.textBaseline="middle",e.fillText(this.options.icon.code,s,o)),{drawExternalLabel:()=>{if(this.options.label!==void 0){this.labelModule.calculateLabelSize(e,r,a,s,o,"hanging");let h=o+.5*this.height+.5*this.labelModule.size.height;this.labelModule.draw(e,s,h,r,a,"hanging")}this.updateBoundingBox(s,o)}}}updateBoundingBox(e,t){this.boundingBox.top=t-this.options.size,this.boundingBox.left=e-this.options.size,this.boundingBox.right=e+this.options.size,this.boundingBox.bottom=t+this.options.size,this.options.label!==void 0&&this.labelModule.size.width>0&&(this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelModule.size.height))}},Po=class extends ke{constructor(e,t,i,s){super(e,t,i,s);this.ctxRenderer=s}draw(e,t,i,s,o,r){this.resize(e,s,o,r),this.left=t-this.width/2,this.top=i-this.height/2,e.save();let a=this.ctxRenderer({ctx:e,id:this.options.id,x:t,y:i,state:{selected:s,hover:o},style:de({},r),label:this.options.label});if(a.drawNode!=null&&a.drawNode(),e.restore(),a.drawExternalLabel){let d=a.drawExternalLabel;a.drawExternalLabel=()=>{e.save(),d(),e.restore()}}return a.nodeDimensions&&(this.customSizeWidth=a.nodeDimensions.width,this.customSizeHeight=a.nodeDimensions.height),a}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Mo=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t,i){if(this.needsRefresh(t,i)){let o=this.getDimensionsFromLabel(e,t,i).width+this.margin.right+this.margin.left;this.width=o,this.height=o,this.radius=this.width/2}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this.initContextForDraw(e,r),ao(e,t-this.width/2,i-this.height/2,this.width,this.height),this.performFill(e,r),this.updateBoundingBox(t,i,e,s,o),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,s,o)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Do=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"diamond",4,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Fo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"circle",2,t,i,s,o,r)}distanceToBorder(e){return e&&this.resize(e),this.options.size}},Mi=class extends De{constructor(e,t,i){super(e,t,i)}resize(e,t=this.selected,i=this.hover){if(this.needsRefresh(t,i)){let s=this.getDimensionsFromLabel(e,t,i);this.height=s.height*2,this.width=s.width+s.height,this.radius=.5*this.width}}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width*.5,this.top=i-this.height*.5,this.initContextForDraw(e,r),Ti(e,this.left,this.top,this.width,this.height),this.performFill(e,r),this.updateBoundingBox(t,i,e,s,o),this.labelModule.draw(e,t,i,s,o)}distanceToBorder(e,t){e&&this.resize(e);let i=this.width*.5,s=this.height*.5,o=Math.sin(t)*i,r=Math.cos(t)*s;return i*s/Math.sqrt(o*o+r*r)}},No=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t,i){this.needsRefresh(t,i)&&(this.iconSize={width:Number(this.options.icon.size),height:Number(this.options.icon.size)},this.width=this.iconSize.width+this.margin.right+this.margin.left,this.height=this.iconSize.height+this.margin.top+this.margin.bottom,this.radius=.5*this.width)}draw(e,t,i,s,o,r){return this.resize(e,s,o),this.options.icon.size=this.options.icon.size||50,this.left=t-this.width/2,this.top=i-this.height/2,this._icon(e,t,i,s,o,r),{drawExternalLabel:()=>{if(this.options.label!==void 0){let a=5;this.labelModule.draw(e,this.left+this.iconSize.width/2+this.margin.left,i+this.height/2+a,s)}this.updateBoundingBox(t,i)}}}updateBoundingBox(e,t){if(this.boundingBox.top=t-this.options.icon.size*.5,this.boundingBox.left=e-this.options.icon.size*.5,this.boundingBox.right=e+this.options.icon.size*.5,this.boundingBox.bottom=t+this.options.icon.size*.5,this.options.label!==void 0&&this.labelModule.size.width>0){let i=5;this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelModule.size.height+i)}}_icon(e,t,i,s,o,r){let a=Number(this.options.icon.size);this.options.icon.code!==void 0?(e.font=[this.options.icon.weight!=null?this.options.icon.weight:s?"bold":"",(this.options.icon.weight!=null&&s?5:0)+a+"px",this.options.icon.face].join(" "),e.fillStyle=this.options.icon.color||"black",e.textAlign="center",e.textBaseline="middle",this.enableShadow(e,r),e.fillText(this.options.icon.code,t,i),this.disableShadow(e,r)):console.error("When using the icon shape, you need to define the code in the icon options object. This can be done per node or globally.")}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Bo=class extends Gt{constructor(e,t,i,s,o){super(e,t,i);this.setImages(s,o)}resize(e,t=this.selected,i=this.hover){if(this.imageObj.src===void 0||this.imageObj.width===void 0||this.imageObj.height===void 0){let o=this.options.size*2;this.width=o,this.height=o;return}this.needsRefresh(t,i)&&this._resizeImage()}draw(e,t,i,s,o,r){e.save(),this.switchImages(s),this.resize();let a=t,d=i;if(this.options.shapeProperties.coordinateOrigin==="top-left"?(this.left=t,this.top=i,a+=this.width/2,d+=this.height/2):(this.left=t-this.width/2,this.top=i-this.height/2),this.options.shapeProperties.useBorderWithImage===!0){let h=this.options.borderWidth,l=this.options.borderWidthSelected||2*this.options.borderWidth,c=(s?l:h)/this.body.view.scale;e.lineWidth=Math.min(this.width,c),e.beginPath();let u=s?this.options.color.highlight.border:o?this.options.color.hover.border:this.options.color.border,p=s?this.options.color.highlight.background:o?this.options.color.hover.background:this.options.color.background;r.opacity!==void 0&&(u=re(u,r.opacity),p=re(p,r.opacity)),e.strokeStyle=u,e.fillStyle=p,e.rect(this.left-.5*e.lineWidth,this.top-.5*e.lineWidth,this.width+e.lineWidth,this.height+e.lineWidth),e.fill(),this.performStroke(e,r),e.closePath()}this._drawImageAtPosition(e,r),this._drawImageLabel(e,a,d,s,o),this.updateBoundingBox(t,i),e.restore()}updateBoundingBox(e,t){this.resize(),this.options.shapeProperties.coordinateOrigin==="top-left"?(this.left=e,this.top=t):(this.left=e-this.width/2,this.top=t-this.height/2),this.boundingBox.left=this.left,this.boundingBox.top=this.top,this.boundingBox.bottom=this.top+this.height,this.boundingBox.right=this.left+this.width,this.options.label!==void 0&&this.labelModule.size.width>0&&(this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelOffset))}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Ao=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"square",2,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},zo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"hexagon",4,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Lo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"star",4,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Ro=class extends De{constructor(e,t,i){super(e,t,i);this._setMargins(i)}resize(e,t,i){this.needsRefresh(t,i)&&(this.textSize=this.labelModule.getTextSize(e,t,i),this.width=this.textSize.width+this.margin.right+this.margin.left,this.height=this.textSize.height+this.margin.top+this.margin.bottom,this.radius=.5*this.width)}draw(e,t,i,s,o,r){this.resize(e,s,o),this.left=t-this.width/2,this.top=i-this.height/2,this.enableShadow(e,r),this.labelModule.draw(e,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,s,o),this.disableShadow(e,r),this.updateBoundingBox(t,i,e,s,o)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},Ho=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"triangle",3,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},jo=class extends ke{constructor(e,t,i){super(e,t,i)}draw(e,t,i,s,o,r){return this._drawShape(e,"triangleDown",3,t,i,s,o,r)}distanceToBorder(e,t){return this._distanceToBorder(e,t)}},U=class{constructor(e,t,i,s,o,r){this.options=Ee(o),this.globalOptions=o,this.defaultOptions=r,this.body=t,this.edges=[],this.id=void 0,this.imagelist=i,this.grouplist=s,this.x=void 0,this.y=void 0,this.baseSize=this.options.size,this.baseFontSize=this.options.font.size,this.predefinedPosition=!1,this.selected=!1,this.hover=!1,this.labelModule=new Ye(this.body,this.options,!1),this.setOptions(e)}attachEdge(e){this.edges.indexOf(e)===-1&&this.edges.push(e)}detachEdge(e){let t=this.edges.indexOf(e);t!=-1&&this.edges.splice(t,1)}setOptions(e){let t=this.options.shape;if(!e)return;if(typeof e.color!="undefined"&&(this._localColor=e.color),e.id!==void 0&&(this.id=e.id),this.id===void 0)throw new Error("Node must have an id");U.checkMass(e,this.id),e.x!==void 0&&(e.x===null?(this.x=void 0,this.predefinedPosition=!1):(this.x=parseInt(e.x),this.predefinedPosition=!0)),e.y!==void 0&&(e.y===null?(this.y=void 0,this.predefinedPosition=!1):(this.y=parseInt(e.y),this.predefinedPosition=!0)),e.size!==void 0&&(this.baseSize=e.size),e.value!==void 0&&(e.value=parseFloat(e.value)),U.parseOptions(this.options,e,!0,this.globalOptions,this.grouplist);let i=[e,this.options,this.defaultOptions];return this.chooser=Oi("node",i),this._load_images(),this.updateLabelModule(e),e.opacity!==void 0&&U.checkOpacity(e.opacity)&&(this.options.opacity=e.opacity),this.updateShape(t),e.hidden!==void 0||e.physics!==void 0}_load_images(){if((this.options.shape==="circularImage"||this.options.shape==="image")&&this.options.image===void 0)throw new Error("Option image must be defined for node type '"+this.options.shape+"'");if(this.options.image!==void 0){if(this.imagelist===void 0)throw new Error("Internal Error: No images provided");if(typeof this.options.image=="string")this.imageObj=this.imagelist.load(this.options.image,this.options.brokenImage,this.id);else{if(this.options.image.unselected===void 0)throw new Error("No unselected image provided");this.imageObj=this.imagelist.load(this.options.image.unselected,this.options.brokenImage,this.id),this.options.image.selected!==void 0?this.imageObjAlt=this.imagelist.load(this.options.image.selected,this.options.brokenImage,this.id):this.imageObjAlt=void 0}}}static checkOpacity(e){return 0<=e&&e<=1}static checkCoordinateOrigin(e){return e===void 0||e==="center"||e==="top-left"}static updateGroupOptions(e,t,i){if(i===void 0)return;let s=e.group;if(t!==void 0&&t.group!==void 0&&s!==t.group)throw new Error("updateGroupOptions: group values in options don't match.");if(!(typeof s=="number"||typeof s=="string"&&s!=""))return;let r=i.get(s);r.opacity!==void 0&&t.opacity===void 0&&(U.checkOpacity(r.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+r.opacity),r.opacity=void 0));let a=Object.getOwnPropertyNames(t).filter(d=>t[d]!=null);a.push("font"),bt(a,e,r),e.color=Lt(e.color)}static parseOptions(e,t,i=!1,s={},o){if(bt(["color","fixed","shadow"],e,t,i),U.checkMass(t),e.opacity!==void 0&&(U.checkOpacity(e.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+e.opacity),e.opacity=void 0)),t.opacity!==void 0&&(U.checkOpacity(t.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+t.opacity),t.opacity=void 0)),t.shapeProperties&&!U.checkCoordinateOrigin(t.shapeProperties.coordinateOrigin)&&console.error("Invalid option for node coordinateOrigin, found: "+t.shapeProperties.coordinateOrigin),ae(e,t,"shadow",s),t.color!==void 0&&t.color!==null){let a=Lt(t.color);yi(e.color,a)}else i===!0&&t.color===null&&(e.color=Ee(s.color));t.fixed!==void 0&&t.fixed!==null&&(typeof t.fixed=="boolean"?(e.fixed.x=t.fixed,e.fixed.y=t.fixed):(t.fixed.x!==void 0&&typeof t.fixed.x=="boolean"&&(e.fixed.x=t.fixed.x),t.fixed.y!==void 0&&typeof t.fixed.y=="boolean"&&(e.fixed.y=t.fixed.y))),i===!0&&t.font===null&&(e.font=Ee(s.font)),U.updateGroupOptions(e,t,o),t.scaling!==void 0&&ae(e.scaling,t.scaling,"label",s.scaling)}getFormattingValues(){let e={color:this.options.color.background,opacity:this.options.opacity,borderWidth:this.options.borderWidth,borderColor:this.options.color.border,size:this.options.size,borderDashes:this.options.shapeProperties.borderDashes,borderRadius:this.options.shapeProperties.borderRadius,shadow:this.options.shadow.enabled,shadowColor:this.options.shadow.color,shadowSize:this.options.shadow.size,shadowX:this.options.shadow.x,shadowY:this.options.shadow.y};if(this.selected||this.hover?this.chooser===!0?this.selected?(this.options.borderWidthSelected!=null?e.borderWidth=this.options.borderWidthSelected:e.borderWidth*=2,e.color=this.options.color.highlight.background,e.borderColor=this.options.color.highlight.border,e.shadow=this.options.shadow.enabled):this.hover&&(e.color=this.options.color.hover.background,e.borderColor=this.options.color.hover.border,e.shadow=this.options.shadow.enabled):typeof this.chooser=="function"&&(this.chooser(e,this.options.id,this.selected,this.hover),e.shadow===!1&&(e.shadowColor!==this.options.shadow.color||e.shadowSize!==this.options.shadow.size||e.shadowX!==this.options.shadow.x||e.shadowY!==this.options.shadow.y)&&(e.shadow=!0)):e.shadow=this.options.shadow.enabled,this.options.opacity!==void 0){let t=this.options.opacity;e.borderColor=re(e.borderColor,t),e.color=re(e.color,t),e.shadowColor=re(e.shadowColor,t)}return e}updateLabelModule(e){(this.options.label===void 0||this.options.label===null)&&(this.options.label=""),U.updateGroupOptions(this.options,Be(de({},e),{color:e&&e.color||this._localColor||void 0}),this.grouplist);let t=this.grouplist.get(this.options.group,!1),i=[e,this.options,t,this.globalOptions,this.defaultOptions];this.labelModule.update(this.options,i),this.labelModule.baseSize!==void 0&&(this.baseFontSize=this.labelModule.baseSize)}updateShape(e){if(e===this.options.shape&&this.shape)this.shape.setOptions(this.options,this.imageObj,this.imageObjAlt);else switch(this.options.shape){case"box":this.shape=new So(this.options,this.body,this.labelModule);break;case"circle":this.shape=new Oo(this.options,this.body,this.labelModule);break;case"circularImage":this.shape=new Io(this.options,this.body,this.labelModule,this.imageObj,this.imageObjAlt);break;case"custom":this.shape=new Po(this.options,this.body,this.labelModule,this.options.ctxRenderer);break;case"database":this.shape=new Mo(this.options,this.body,this.labelModule);break;case"diamond":this.shape=new Do(this.options,this.body,this.labelModule);break;case"dot":this.shape=new Fo(this.options,this.body,this.labelModule);break;case"ellipse":this.shape=new Mi(this.options,this.body,this.labelModule);break;case"icon":this.shape=new No(this.options,this.body,this.labelModule);break;case"image":this.shape=new Bo(this.options,this.body,this.labelModule,this.imageObj,this.imageObjAlt);break;case"square":this.shape=new Ao(this.options,this.body,this.labelModule);break;case"hexagon":this.shape=new zo(this.options,this.body,this.labelModule);break;case"star":this.shape=new Lo(this.options,this.body,this.labelModule);break;case"text":this.shape=new Ro(this.options,this.body,this.labelModule);break;case"triangle":this.shape=new Ho(this.options,this.body,this.labelModule);break;case"triangleDown":this.shape=new jo(this.options,this.body,this.labelModule);break;default:this.shape=new Mi(this.options,this.body,this.labelModule);break}this.needsRefresh()}select(){this.selected=!0,this.needsRefresh()}unselect(){this.selected=!1,this.needsRefresh()}needsRefresh(){this.shape.refreshNeeded=!0}getTitle(){return this.options.title}distanceToBorder(e,t){return this.shape.distanceToBorder(e,t)}isFixed(){return this.options.fixed.x&&this.options.fixed.y}isSelected(){return this.selected}getValue(){return this.options.value}getLabelSize(){return this.labelModule.size()}setValueRange(e,t,i){if(this.options.value!==void 0){let s=this.options.scaling.customScalingFunction(e,t,i,this.options.value),o=this.options.scaling.max-this.options.scaling.min;if(this.options.scaling.label.enabled===!0){let r=this.options.scaling.label.max-this.options.scaling.label.min;this.options.font.size=this.options.scaling.label.min+s*r}this.options.size=this.options.scaling.min+s*o}else this.options.size=this.baseSize,this.options.font.size=this.baseFontSize;this.updateLabelModule()}draw(e){let t=this.getFormattingValues();return this.shape.draw(e,this.x,this.y,this.selected,this.hover,t)||{}}updateBoundingBox(e){this.shape.updateBoundingBox(this.x,this.y,e)}resize(e){let t=this.getFormattingValues();this.shape.resize(e,this.selected,this.hover,t)}getItemsOnPoint(e){let t=[];return this.labelModule.visible()&&Ii(this.labelModule.getSize(),e)&&t.push({nodeId:this.id,labelId:0}),Ii(this.shape.boundingBox,e)&&t.push({nodeId:this.id}),t}isOverlappingWith(e){return this.shape.lefte.left&&this.shape.tope.top}isBoundingBoxOverlappingWith(e){return this.shape.boundingBox.lefte.left&&this.shape.boundingBox.tope.top}static checkMass(e,t){if(e.mass!==void 0&&e.mass<=0){let i="";t!==void 0&&(i=" in node id: "+t),console.error("%cNegative or zero mass disallowed"+i+", setting mass to 1.",_i),e.mass=1}}},Wo=class{constructor(e,t,i,s){if(this.body=e,this.images=t,this.groups=i,this.layoutEngine=s,this.body.functions.createNode=this.create.bind(this),this.nodesListeners={add:(o,r)=>{this.add(r.items)},update:(o,r)=>{this.update(r.items,r.data,r.oldData)},remove:(o,r)=>{this.remove(r.items)}},this.defaultOptions={borderWidth:1,borderWidthSelected:void 0,brokenImage:void 0,color:{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},opacity:void 0,fixed:{x:!1,y:!1},font:{color:"#343434",size:14,face:"arial",background:"none",strokeWidth:0,strokeColor:"#ffffff",align:"center",vadjust:0,multi:!1,bold:{mod:"bold"},boldital:{mod:"bold italic"},ital:{mod:"italic"},mono:{mod:"",size:15,face:"monospace",vadjust:2}},group:void 0,hidden:!1,icon:{face:"FontAwesome",code:void 0,size:50,color:"#2B7CE9"},image:void 0,imagePadding:{top:0,right:0,bottom:0,left:0},label:void 0,labelHighlightBold:!0,level:void 0,margin:{top:5,right:5,bottom:5,left:5},mass:1,physics:!0,scaling:{min:10,max:30,label:{enabled:!1,min:14,max:30,maxVisible:30,drawThreshold:5},customScalingFunction:function(o,r,a,d){if(r===o)return .5;{let h=1/(r-o);return Math.max(0,(d-o)*h)}}},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:10,x:5,y:5},shape:"ellipse",shapeProperties:{borderDashes:!1,borderRadius:6,interpolation:!0,useImageSize:!1,useBorderWithImage:!1,coordinateOrigin:"center"},size:25,title:void 0,value:void 0,x:void 0,y:void 0},this.defaultOptions.mass<=0)throw"Internal error: mass in defaultOptions of NodesHandler may not be zero or negative";this.options=Ee(this.defaultOptions),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("refreshNodes",this.refresh.bind(this)),this.body.emitter.on("refresh",this.refresh.bind(this)),this.body.emitter.on("destroy",()=>{A(this.nodesListeners,(e,t)=>{this.body.data.nodes&&this.body.data.nodes.off(t,e)}),delete this.body.functions.createNode,delete this.nodesListeners.add,delete this.nodesListeners.update,delete this.nodesListeners.remove,delete this.nodesListeners})}setOptions(e){if(e!==void 0){if(U.parseOptions(this.options,e),e.opacity!==void 0&&(Number.isNaN(e.opacity)||!Number.isFinite(e.opacity)||e.opacity<0||e.opacity>1?console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+e.opacity):this.options.opacity=e.opacity),e.shape!==void 0)for(let t in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&this.body.nodes[t].updateShape();if(typeof e.font!="undefined"||typeof e.widthConstraint!="undefined"||typeof e.heightConstraint!="undefined")for(let t of Object.keys(this.body.nodes))this.body.nodes[t].updateLabelModule(),this.body.nodes[t].needsRefresh();if(e.size!==void 0)for(let t in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&this.body.nodes[t].needsRefresh();(e.hidden!==void 0||e.physics!==void 0)&&this.body.emitter.emit("_dataChanged")}}setData(e,t=!1){let i=this.body.data.nodes;if(xi("id",e))this.body.data.nodes=e;else if(Array.isArray(e))this.body.data.nodes=new Te,this.body.data.nodes.add(e);else if(!e)this.body.data.nodes=new Te;else throw new TypeError("Array or DataSet expected");if(i&&A(this.nodesListeners,function(s,o){i.off(o,s)}),this.body.nodes={},this.body.data.nodes){let s=this;A(this.nodesListeners,function(r,a){s.body.data.nodes.on(a,r)});let o=this.body.data.nodes.getIds();this.add(o,!0)}t===!1&&this.body.emitter.emit("_dataChanged")}add(e,t=!1){let i,s=[];for(let o=0;o{let s=this.body.data.nodes.get(i);s!==void 0&&(e===!0&&t.setOptions({x:null,y:null}),t.setOptions({fixed:!1}),t.setOptions(s))})}getPositions(e){let t={};if(e!==void 0){if(Array.isArray(e)===!0){for(let i=0;i{this.body.emitter.emit("startSimulation")},0)):console.error("Node id supplied to moveNode does not exist. Provided: ",e)}},G=class{static transform(e,t){Array.isArray(e)||(e=[e]);let i=t.point.x,s=t.point.y,o=t.angle,r=t.length;for(let a=0;a0?d>0?r=p:a=p:d>0?a=p:r=p,++C}while(r<=a&&C1?l=1:l<0&&(l=0);let c=e+l*a,u=t+l*d,p=c-o,b=u-r;return Math.sqrt(p*p+b*b)}getArrowData(e,t,i,s,o,r){let a,d,h,l,c,u,p,b=r.width;t==="from"?(h=this.from,l=this.to,c=r.fromArrowScale<0,u=Math.abs(r.fromArrowScale),p=r.fromArrowType):t==="to"?(h=this.to,l=this.from,c=r.toArrowScale<0,u=Math.abs(r.toArrowScale),p=r.toArrowType):(h=this.to,l=this.from,c=r.middleArrowScale<0,u=Math.abs(r.middleArrowScale),p=r.middleArrowType);let C=15*u+3*b;if(h!=l){let v=Math.hypot(h.x-l.x,h.y-l.y),_=C/v;if(t!=="middle")if(this.options.smooth.enabled===!0){let E=this._findBorderPosition(h,e,{via:i}),T=this.getPoint(E.t+_*(t==="from"?1:-1),i);a=Math.atan2(E.y-T.y,E.x-T.x),d=E}else a=Math.atan2(h.y-l.y,h.x-l.x),d=this._findBorderPosition(h,e);else{let E=(c?-_:_)/2,T=this.getPoint(.5+E,i),x=this.getPoint(.5-E,i);a=Math.atan2(T.y-x.y,T.x-x.x),d=this.getPoint(.5,i)}}else{let[v,_,E]=this._getCircleData(e);if(t==="from"){let T=this.options.selfReference.angle,x=this.options.selfReference.angle+Math.PI,w=this._findBorderPositionCircle(this.from,e,{x:v,y:_,low:T,high:x,direction:-1});a=w.t*-2*Math.PI+1.5*Math.PI+.1*Math.PI,d=w}else if(t==="to"){let T=this.options.selfReference.angle,x=this.options.selfReference.angle+Math.PI,w=this._findBorderPositionCircle(this.from,e,{x:v,y:_,low:T,high:x,direction:1});a=w.t*-2*Math.PI+1.5*Math.PI-1.1*Math.PI,d=w}else{let T=this.options.selfReference.angle/(2*Math.PI);d=this._pointOnCircle(v,_,E,T),a=T*-2*Math.PI+1.5*Math.PI+.1*Math.PI}}let f=d.x-C*.9*Math.cos(a),g=d.y-C*.9*Math.sin(a);return{point:d,core:{x:f,y:g},angle:a,length:C,type:p}}drawArrowHead(e,t,i,s,o){e.strokeStyle=this.getColor(e,t),e.fillStyle=e.strokeStyle,e.lineWidth=t.width,Di.draw(e,o)&&(this.enableShadow(e,t),e.fill(),this.disableShadow(e,t))}enableShadow(e,t){t.shadow===!0&&(e.shadowColor=t.shadowColor,e.shadowBlur=t.shadowSize,e.shadowOffsetX=t.shadowX,e.shadowOffsetY=t.shadowY)}disableShadow(e,t){t.shadow===!0&&(e.shadowColor="rgba(0,0,0,0)",e.shadowBlur=0,e.shadowOffsetX=0,e.shadowOffsetY=0)}drawBackground(e,t){if(t.background!==!1){let i={strokeStyle:e.strokeStyle,lineWidth:e.lineWidth,dashes:e.dashes};e.strokeStyle=t.backgroundColor,e.lineWidth=t.backgroundSize,this.setStrokeDashed(e,t.backgroundDashes),e.stroke(),e.strokeStyle=i.strokeStyle,e.lineWidth=i.lineWidth,e.dashes=i.dashes,this.setStrokeDashed(e,t.dashes)}}setStrokeDashed(e,t){if(t!==!1)if(e.setLineDash!==void 0){let i=Array.isArray(t)?t:[5,5];e.setLineDash(i)}else console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.");else e.setLineDash!==void 0?e.setLineDash([]):console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.")}},Kt=class extends Fi{constructor(e,t,i){super(e,t,i)}_findBorderPositionBezier(e,t,i=this._getViaCoordinates()){let s=10,o=.2,r=!1,a=1,d=0,h=this.to,l,c,u=this.options.endPointOffset?this.options.endPointOffset.to:0;e.id===this.from.id&&(h=this.from,r=!0,u=this.options.endPointOffset?this.options.endPointOffset.from:0),this.options.arrowStrikethrough===!1&&(u=0);let p=0;do{c=(d+a)*.5,l=this.getPoint(c,i);let b=Math.atan2(h.y-l.y,h.x-l.x),C=h.distanceToBorder(t,b)+u,f=Math.sqrt(Math.pow(l.x-h.x,2)+Math.pow(l.y-h.y,2)),g=C-f;if(Math.abs(g)0&&(h=this._getDistanceToLine(b,C,u,p,o,r),d=h{this.positionBezierNode()},this._body.emitter.on("_repositionBezierNodes",this._boundFunction)}setOptions(e){super.setOptions(e);let t=!1;this.options.physics!==e.physics&&(t=!0),this.options=e,this.id=this.options.id,this.from=this._body.nodes[this.options.from],this.to=this._body.nodes[this.options.to],this.setupSupportNode(),this.connect(),t===!0&&(this.via.setOptions({physics:this.options.physics}),this.positionBezierNode())}connect(){this.from=this._body.nodes[this.options.from],this.to=this._body.nodes[this.options.to],this.from===void 0||this.to===void 0||this.options.physics===!1?this.via.setOptions({physics:!1}):this.from.id===this.to.id?this.via.setOptions({physics:!1}):this.via.setOptions({physics:!0})}cleanup(){return this._body.emitter.off("_repositionBezierNodes",this._boundFunction),this.via!==void 0?(delete this._body.nodes[this.via.id],this.via=void 0,!0):!1}setupSupportNode(){if(this.via===void 0){let e="edgeId:"+this.id,t=this._body.functions.createNode({id:e,shape:"circle",physics:!0,hidden:!0});this._body.nodes[e]=t,this.via=t,this.via.parentEdgeId=this.id,this.positionBezierNode()}}positionBezierNode(){this.via!==void 0&&this.from!==void 0&&this.to!==void 0?(this.via.x=.5*(this.from.x+this.to.x),this.via.y=.5*(this.from.y+this.to.y)):this.via!==void 0&&(this.via.x=0,this.via.y=0)}_line(e,t,i){this._bezierCurve(e,t,i)}_getViaCoordinates(){return this.via}getViaNode(){return this.via}getPoint(e,t=this.via){if(this.from===this.to){let[i,s,o]=this._getCircleData(),r=2*Math.PI*(1-e);return{x:i+o*Math.sin(r),y:s+o-o*(1-Math.cos(r))}}else return{x:Math.pow(1-e,2)*this.fromPoint.x+2*e*(1-e)*t.x+Math.pow(e,2)*this.toPoint.x,y:Math.pow(1-e,2)*this.fromPoint.y+2*e*(1-e)*t.y+Math.pow(e,2)*this.toPoint.y}}_findBorderPosition(e,t){return this._findBorderPositionBezier(e,t,this.via)}_getDistanceToEdge(e,t,i,s,o,r){return this._getDistanceToBezierEdge(e,t,i,s,o,r,this.via)}},Bi=class extends Kt{constructor(e,t,i){super(e,t,i)}_line(e,t,i){this._bezierCurve(e,t,i)}getViaNode(){return this._getViaCoordinates()}_getViaCoordinates(){let e=this.options.smooth.roundness,t=this.options.smooth.type,i=Math.abs(this.from.x-this.to.x),s=Math.abs(this.from.y-this.to.y);if(t==="discrete"||t==="diagonalCross"){let o,r;i<=s?o=r=e*s:o=r=e*i,this.from.x>this.to.x&&(o=-o),this.from.y>=this.to.y&&(r=-r);let a=this.from.x+o,d=this.from.y+r;return t==="discrete"&&(i<=s?a=ithis.to.x&&(o=-o),this.from.y>=this.to.y&&(r=-r);let a=this.from.x+o,d=this.from.y+r;return i<=s?this.from.x<=this.to.x?a=this.to.xa?this.to.x:a:this.from.y>=this.to.y?d=this.to.y>d?this.to.y:d:d=this.to.y0){let g=this._getDistanceToLine(l,c,C,f,o,r);h=gMath.abs(t)||this.options.smooth.forceDirection===!0||this.options.smooth.forceDirection==="horizontal")&&this.options.smooth.forceDirection!=="vertical"?(s=this.from.y,r=this.to.y,i=this.from.x-a*e,o=this.to.x+a*e):(s=this.from.y-a*t,r=this.to.y+a*t,i=this.from.x,o=this.to.x),[{x:i,y:s},{x:o,y:r}]}getViaNode(){return this._getViaCoordinates()}_findBorderPosition(e,t){return this._findBorderPositionBezier(e,t)}_getDistanceToEdge(e,t,i,s,o,r,[a,d]=this._getViaCoordinates()){return this._getDistanceToBezierEdge2(e,t,i,s,o,r,a,d)}getPoint(e,[t,i]=this._getViaCoordinates()){let s=e,o=[Math.pow(1-s,3),3*s*Math.pow(1-s,2),3*Math.pow(s,2)*(1-s),Math.pow(s,3)],r=o[0]*this.fromPoint.x+o[1]*t.x+o[2]*i.x+o[3]*this.toPoint.x,a=o[0]*this.fromPoint.y+o[1]*t.y+o[2]*i.y+o[3]*this.toPoint.y;return{x:r,y:a}}},zi=class extends Fi{constructor(e,t,i){super(e,t,i)}_line(e,t){e.beginPath(),e.moveTo(this.fromPoint.x,this.fromPoint.y),e.lineTo(this.toPoint.x,this.toPoint.y),this.enableShadow(e,t),e.stroke(),this.disableShadow(e,t)}getViaNode(){}getPoint(e){return{x:(1-e)*this.fromPoint.x+e*this.toPoint.x,y:(1-e)*this.fromPoint.y+e*this.toPoint.y}}_findBorderPosition(e,t){let i=this.to,s=this.from;e.id===this.from.id&&(i=this.from,s=this.to);let o=Math.atan2(i.y-s.y,i.x-s.x),r=i.x-s.x,a=i.y-s.y,d=Math.sqrt(r*r+a*a),h=e.distanceToBorder(t,o),l=(d-h)/d;return{x:(1-l)*s.x+l*i.x,y:(1-l)*s.y+l*i.y,t:0}}_getDistanceToEdge(e,t,i,s,o,r){return this._getDistanceToLine(e,t,i,s,o,r)}},Se=class{constructor(e,t,i,s,o){if(t===void 0)throw new Error("No body provided");this.options=Ee(s),this.globalOptions=s,this.defaultOptions=o,this.body=t,this.imagelist=i,this.id=void 0,this.fromId=void 0,this.toId=void 0,this.selected=!1,this.hover=!1,this.labelDirty=!0,this.baseWidth=this.options.width,this.baseFontSize=this.options.font.size,this.from=void 0,this.to=void 0,this.edgeType=void 0,this.connected=!1,this.labelModule=new Ye(this.body,this.options,!0),this.setOptions(e)}setOptions(e){if(!e)return;let t=typeof e.physics!="undefined"&&this.options.physics!==e.physics||typeof e.hidden!="undefined"&&(this.options.hidden||!1)!==(e.hidden||!1)||typeof e.from!="undefined"&&this.options.from!==e.from||typeof e.to!="undefined"&&this.options.to!==e.to;Se.parseOptions(this.options,e,!0,this.globalOptions),e.id!==void 0&&(this.id=e.id),e.from!==void 0&&(this.fromId=e.from),e.to!==void 0&&(this.toId=e.to),e.title!==void 0&&(this.title=e.title),e.value!==void 0&&(e.value=parseFloat(e.value));let i=[e,this.options,this.defaultOptions];return this.chooser=Oi("edge",i),this.updateLabelModule(e),t=this.updateEdgeType()||t,this._setInteractionWidths(),this.connect(),t}static parseOptions(e,t,i=!1,s={},o=!1){if(qe(["endPointOffset","arrowStrikethrough","id","from","hidden","hoverWidth","labelHighlightBold","length","line","opacity","physics","scaling","selectionWidth","selfReferenceSize","selfReference","to","title","value","width","font","chosen","widthConstraint"],e,t,i),t.endPointOffset!==void 0&&t.endPointOffset.from!==void 0&&(Number.isFinite(t.endPointOffset.from)?e.endPointOffset.from=t.endPointOffset.from:(e.endPointOffset.from=s.endPointOffset.from!==void 0?s.endPointOffset.from:0,console.error("endPointOffset.from is not a valid number"))),t.endPointOffset!==void 0&&t.endPointOffset.to!==void 0&&(Number.isFinite(t.endPointOffset.to)?e.endPointOffset.to=t.endPointOffset.to:(e.endPointOffset.to=s.endPointOffset.to!==void 0?s.endPointOffset.to:0,console.error("endPointOffset.to is not a valid number"))),Yt(t.label)?e.label=t.label:Yt(e.label)||(e.label=void 0),ae(e,t,"smooth",s),ae(e,t,"shadow",s),ae(e,t,"background",s),t.dashes!==void 0&&t.dashes!==null?e.dashes=t.dashes:i===!0&&t.dashes===null&&(e.dashes=Object.create(s.dashes)),t.scaling!==void 0&&t.scaling!==null?(t.scaling.min!==void 0&&(e.scaling.min=t.scaling.min),t.scaling.max!==void 0&&(e.scaling.max=t.scaling.max),ae(e.scaling,t.scaling,"label",s.scaling)):i===!0&&t.scaling===null&&(e.scaling=Object.create(s.scaling)),t.arrows!==void 0&&t.arrows!==null)if(typeof t.arrows=="string"){let a=t.arrows.toLowerCase();e.arrows.to.enabled=a.indexOf("to")!=-1,e.arrows.middle.enabled=a.indexOf("middle")!=-1,e.arrows.from.enabled=a.indexOf("from")!=-1}else if(typeof t.arrows=="object")ae(e.arrows,t.arrows,"to",s.arrows),ae(e.arrows,t.arrows,"middle",s.arrows),ae(e.arrows,t.arrows,"from",s.arrows);else throw new Error("The arrow newOptions can only be an object or a string. Refer to the documentation. You used:"+JSON.stringify(t.arrows));else i===!0&&t.arrows===null&&(e.arrows=Object.create(s.arrows));if(t.color!==void 0&&t.color!==null){let a=_e(t.color)?{color:t.color,highlight:t.color,hover:t.color,inherit:!1,opacity:1}:t.color,d=e.color;if(o)j(d,s.color,!1,i);else for(let h in d)Object.prototype.hasOwnProperty.call(d,h)&&delete d[h];if(_e(d))d.color=d,d.highlight=d,d.hover=d,d.inherit=!1,a.opacity===void 0&&(d.opacity=1);else{let h=!1;a.color!==void 0&&(d.color=a.color,h=!0),a.highlight!==void 0&&(d.highlight=a.highlight,h=!0),a.hover!==void 0&&(d.hover=a.hover,h=!0),a.inherit!==void 0&&(d.inherit=a.inherit),a.opacity!==void 0&&(d.opacity=Math.min(1,Math.max(0,a.opacity))),h===!0?d.inherit=!1:d.inherit===void 0&&(d.inherit="from")}}else i===!0&&t.color===null&&(e.color=Ee(s.color));i===!0&&t.font===null&&(e.font=Ee(s.font)),Object.prototype.hasOwnProperty.call(t,"selfReferenceSize")&&(console.warn("The selfReferenceSize property has been deprecated. Please use selfReference property instead. The selfReference can be set like thise selfReference:{size:30, angle:Math.PI / 4}"),e.selfReference.size=t.selfReferenceSize)}getFormattingValues(){let e=this.options.arrows.to===!0||this.options.arrows.to.enabled===!0,t=this.options.arrows.from===!0||this.options.arrows.from.enabled===!0,i=this.options.arrows.middle===!0||this.options.arrows.middle.enabled===!0,s=this.options.color.inherit,o={toArrow:e,toArrowScale:this.options.arrows.to.scaleFactor,toArrowType:this.options.arrows.to.type,toArrowSrc:this.options.arrows.to.src,toArrowImageWidth:this.options.arrows.to.imageWidth,toArrowImageHeight:this.options.arrows.to.imageHeight,middleArrow:i,middleArrowScale:this.options.arrows.middle.scaleFactor,middleArrowType:this.options.arrows.middle.type,middleArrowSrc:this.options.arrows.middle.src,middleArrowImageWidth:this.options.arrows.middle.imageWidth,middleArrowImageHeight:this.options.arrows.middle.imageHeight,fromArrow:t,fromArrowScale:this.options.arrows.from.scaleFactor,fromArrowType:this.options.arrows.from.type,fromArrowSrc:this.options.arrows.from.src,fromArrowImageWidth:this.options.arrows.from.imageWidth,fromArrowImageHeight:this.options.arrows.from.imageHeight,arrowStrikethrough:this.options.arrowStrikethrough,color:s?void 0:this.options.color.color,inheritsColor:s,opacity:this.options.color.opacity,hidden:this.options.hidden,length:this.options.length,shadow:this.options.shadow.enabled,shadowColor:this.options.shadow.color,shadowSize:this.options.shadow.size,shadowX:this.options.shadow.x,shadowY:this.options.shadow.y,dashes:this.options.dashes,width:this.options.width,background:this.options.background.enabled,backgroundColor:this.options.background.color,backgroundSize:this.options.background.size,backgroundDashes:this.options.background.dashes};if(this.selected||this.hover)if(this.chooser===!0){if(this.selected){let r=this.options.selectionWidth;typeof r=="function"?o.width=r(o.width):typeof r=="number"&&(o.width+=r),o.width=Math.max(o.width,.3/this.body.view.scale),o.color=this.options.color.highlight,o.shadow=this.options.shadow.enabled}else if(this.hover){let r=this.options.hoverWidth;typeof r=="function"?o.width=r(o.width):typeof r=="number"&&(o.width+=r),o.width=Math.max(o.width,.3/this.body.view.scale),o.color=this.options.color.hover,o.shadow=this.options.shadow.enabled}}else typeof this.chooser=="function"&&(this.chooser(o,this.options.id,this.selected,this.hover),o.color!==void 0&&(o.inheritsColor=!1),o.shadow===!1&&(o.shadowColor!==this.options.shadow.color||o.shadowSize!==this.options.shadow.size||o.shadowX!==this.options.shadow.x||o.shadowY!==this.options.shadow.y)&&(o.shadow=!0));else o.shadow=this.options.shadow.enabled,o.width=Math.max(o.width,.3/this.body.view.scale);return o}updateLabelModule(e){let t=[e,this.options,this.globalOptions,this.defaultOptions];this.labelModule.update(this.options,t),this.labelModule.baseSize!==void 0&&(this.baseFontSize=this.labelModule.baseSize)}updateEdgeType(){let e=this.options.smooth,t=!1,i=!0;return this.edgeType!==void 0&&((this.edgeType instanceof Ni&&e.enabled===!0&&e.type==="dynamic"||this.edgeType instanceof Ai&&e.enabled===!0&&e.type==="cubicBezier"||this.edgeType instanceof Bi&&e.enabled===!0&&e.type!=="dynamic"&&e.type!=="cubicBezier"||this.edgeType instanceof zi&&e.type.enabled===!1)&&(i=!1),i===!0&&(t=this.cleanup())),i===!0?e.enabled===!0?e.type==="dynamic"?(t=!0,this.edgeType=new Ni(this.options,this.body,this.labelModule)):e.type==="cubicBezier"?this.edgeType=new Ai(this.options,this.body,this.labelModule):this.edgeType=new Bi(this.options,this.body,this.labelModule):this.edgeType=new zi(this.options,this.body,this.labelModule):this.edgeType.setOptions(this.options),t}connect(){this.disconnect(),this.from=this.body.nodes[this.fromId]||void 0,this.to=this.body.nodes[this.toId]||void 0,this.connected=this.from!==void 0&&this.to!==void 0,this.connected===!0?(this.from.attachEdge(this),this.to.attachEdge(this)):(this.from&&this.from.detachEdge(this),this.to&&this.to.detachEdge(this)),this.edgeType.connect()}disconnect(){this.from&&(this.from.detachEdge(this),this.from=void 0),this.to&&(this.to.detachEdge(this),this.to=void 0),this.connected=!1}getTitle(){return this.title}isSelected(){return this.selected}getValue(){return this.options.value}setValueRange(e,t,i){if(this.options.value!==void 0){let s=this.options.scaling.customScalingFunction(e,t,i,this.options.value),o=this.options.scaling.max-this.options.scaling.min;if(this.options.scaling.label.enabled===!0){let r=this.options.scaling.label.max-this.options.scaling.label.min;this.options.font.size=this.options.scaling.label.min+s*r}this.options.width=this.options.scaling.min+s*o}else this.options.width=this.baseWidth,this.options.font.size=this.baseFontSize;this._setInteractionWidths(),this.updateLabelModule()}_setInteractionWidths(){typeof this.options.hoverWidth=="function"?this.edgeType.hoverWidth=this.options.hoverWidth(this.options.width):this.edgeType.hoverWidth=this.options.hoverWidth+this.options.width,typeof this.options.selectionWidth=="function"?this.edgeType.selectionWidth=this.options.selectionWidth(this.options.width):this.edgeType.selectionWidth=this.options.selectionWidth+this.options.width}draw(e){let t=this.getFormattingValues();if(t.hidden)return;let i=this.edgeType.getViaNode();this.edgeType.drawLine(e,t,this.selected,this.hover,i),this.drawLabel(e,i)}drawArrows(e){let t=this.getFormattingValues();if(t.hidden)return;let i=this.edgeType.getViaNode(),s={};this.edgeType.fromPoint=this.edgeType.from,this.edgeType.toPoint=this.edgeType.to,t.fromArrow&&(s.from=this.edgeType.getArrowData(e,"from",i,this.selected,this.hover,t),t.arrowStrikethrough===!1&&(this.edgeType.fromPoint=s.from.core),t.fromArrowSrc&&(s.from.image=this.imagelist.load(t.fromArrowSrc)),t.fromArrowImageWidth&&(s.from.imageWidth=t.fromArrowImageWidth),t.fromArrowImageHeight&&(s.from.imageHeight=t.fromArrowImageHeight)),t.toArrow&&(s.to=this.edgeType.getArrowData(e,"to",i,this.selected,this.hover,t),t.arrowStrikethrough===!1&&(this.edgeType.toPoint=s.to.core),t.toArrowSrc&&(s.to.image=this.imagelist.load(t.toArrowSrc)),t.toArrowImageWidth&&(s.to.imageWidth=t.toArrowImageWidth),t.toArrowImageHeight&&(s.to.imageHeight=t.toArrowImageHeight)),t.middleArrow&&(s.middle=this.edgeType.getArrowData(e,"middle",i,this.selected,this.hover,t),t.middleArrowSrc&&(s.middle.image=this.imagelist.load(t.middleArrowSrc)),t.middleArrowImageWidth&&(s.middle.imageWidth=t.middleArrowImageWidth),t.middleArrowImageHeight&&(s.middle.imageHeight=t.middleArrowImageHeight)),t.fromArrow&&this.edgeType.drawArrowHead(e,t,this.selected,this.hover,s.from),t.middleArrow&&this.edgeType.drawArrowHead(e,t,this.selected,this.hover,s.middle),t.toArrow&&this.edgeType.drawArrowHead(e,t,this.selected,this.hover,s.to)}drawLabel(e,t){if(this.options.label!==void 0){let i=this.from,s=this.to;this.labelModule.differentState(this.selected,this.hover)&&this.labelModule.getTextSize(e,this.selected,this.hover);let o;if(i.id!=s.id){this.labelModule.pointToSelf=!1,o=this.edgeType.getPoint(.5,t),e.save();let r=this._getRotation(e);r.angle!=0&&(e.translate(r.x,r.y),e.rotate(r.angle)),this.labelModule.draw(e,o.x,o.y,this.selected,this.hover),e.restore()}else{this.labelModule.pointToSelf=!0;let r=Co(e,this.options.selfReference.angle,this.options.selfReference.size,i);o=this._pointOnCircle(r.x,r.y,this.options.selfReference.size,this.options.selfReference.angle),this.labelModule.draw(e,o.x,o.y,this.selected,this.hover)}}}getItemsOnPoint(e){let t=[];if(this.labelModule.visible()){let s=this._getRotation();Ii(this.labelModule.getSize(),e,s)&&t.push({edgeId:this.id,labelId:0})}let i={left:e.x,top:e.y};return this.isOverlappingWith(i)&&t.push({edgeId:this.id}),t}isOverlappingWith(e){if(this.connected){let t=10,i=this.from.x,s=this.from.y,o=this.to.x,r=this.to.y,a=e.left,d=e.top;return this.edgeType.getDistanceToEdge(i,s,o,r,a,d)0&&r<0)&&(a+=Math.PI),s.angle=a,s}_pointOnCircle(e,t,i,s){return{x:e+i*Math.cos(s),y:t-i*Math.sin(s)}}select(){this.selected=!0}unselect(){this.selected=!1}cleanup(){return this.edgeType.cleanup()}remove(){this.cleanup(),this.disconnect(),delete this.body.edges[this.id]}endPointsValid(){return this.body.nodes[this.fromId]!==void 0&&this.body.nodes[this.toId]!==void 0}},sn=class{constructor(e,t,i){this.body=e,this.images=t,this.groups=i,this.body.functions.createEdge=this.create.bind(this),this.edgesListeners={add:(s,o)=>{this.add(o.items)},update:(s,o)=>{this.update(o.items)},remove:(s,o)=>{this.remove(o.items)}},this.options={},this.defaultOptions={arrows:{to:{enabled:!1,scaleFactor:1,type:"arrow"},middle:{enabled:!1,scaleFactor:1,type:"arrow"},from:{enabled:!1,scaleFactor:1,type:"arrow"}},endPointOffset:{from:0,to:0},arrowStrikethrough:!0,color:{color:"#848484",highlight:"#848484",hover:"#848484",inherit:"from",opacity:1},dashes:!1,font:{color:"#343434",size:14,face:"arial",background:"none",strokeWidth:2,strokeColor:"#ffffff",align:"horizontal",multi:!1,vadjust:0,bold:{mod:"bold"},boldital:{mod:"bold italic"},ital:{mod:"italic"},mono:{mod:"",size:15,face:"courier new",vadjust:2}},hidden:!1,hoverWidth:1.5,label:void 0,labelHighlightBold:!0,length:void 0,physics:!0,scaling:{min:1,max:15,label:{enabled:!0,min:14,max:30,maxVisible:30,drawThreshold:5},customScalingFunction:function(s,o,r,a){if(o===s)return .5;{let d=1/(o-s);return Math.max(0,(a-s)*d)}}},selectionWidth:1.5,selfReference:{size:20,angle:Math.PI/4,renderBehindTheNode:!0},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:10,x:5,y:5},background:{enabled:!1,color:"rgba(111,111,111,1)",size:10,dashes:!1},smooth:{enabled:!0,type:"dynamic",forceDirection:"none",roundness:.5},title:void 0,width:1,value:void 0},j(this.options,this.defaultOptions),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("_forceDisableDynamicCurves",(e,t=!0)=>{e==="dynamic"&&(e="continuous");let i=!1;for(let s in this.body.edges)if(Object.prototype.hasOwnProperty.call(this.body.edges,s)){let o=this.body.edges[s],r=this.body.data.edges.get(s);if(r!=null){let a=r.smooth;a!==void 0&&a.enabled===!0&&a.type==="dynamic"&&(e===void 0?o.setOptions({smooth:!1}):o.setOptions({smooth:{type:e}}),i=!0)}}t===!0&&i===!0&&this.body.emitter.emit("_dataChanged")}),this.body.emitter.on("_dataUpdated",()=>{this.reconnectEdges()}),this.body.emitter.on("refreshEdges",this.refresh.bind(this)),this.body.emitter.on("refresh",this.refresh.bind(this)),this.body.emitter.on("destroy",()=>{A(this.edgesListeners,(e,t)=>{this.body.data.edges&&this.body.data.edges.off(t,e)}),delete this.body.functions.createEdge,delete this.edgesListeners.add,delete this.edgesListeners.update,delete this.edgesListeners.remove,delete this.edgesListeners})}setOptions(e){if(e!==void 0){Se.parseOptions(this.options,e,!0,this.defaultOptions,!0);let t=!1;if(e.smooth!==void 0)for(let i in this.body.edges)Object.prototype.hasOwnProperty.call(this.body.edges,i)&&(t=this.body.edges[i].updateEdgeType()||t);if(e.font!==void 0)for(let i in this.body.edges)Object.prototype.hasOwnProperty.call(this.body.edges,i)&&this.body.edges[i].updateLabelModule();(e.hidden!==void 0||e.physics!==void 0||t===!0)&&this.body.emitter.emit("_dataChanged")}}setData(e,t=!1){let i=this.body.data.edges;if(xi("id",e))this.body.data.edges=e;else if(Array.isArray(e))this.body.data.edges=new Te,this.body.data.edges.add(e);else if(!e)this.body.data.edges=new Te;else throw new TypeError("Array or DataSet expected");if(i&&A(this.edgesListeners,(s,o)=>{i.off(o,s)}),this.body.edges={},this.body.data.edges){A(this.edgesListeners,(o,r)=>{this.body.data.edges.on(r,o)});let s=this.body.data.edges.getIds();this.add(s,!0)}this.body.emitter.emit("_adjustEdgesForHierarchicalLayout"),t===!1&&this.body.emitter.emit("_dataChanged")}add(e,t=!1){let i=this.body.edges,s=this.body.data.edges;for(let o=0;o{let o=i[s];o!==void 0&&o.remove()}),t&&this.body.emitter.emit("_dataChanged")}refresh(){A(this.body.edges,(e,t)=>{let i=this.body.data.edges.get(t);i!==void 0&&e.setOptions(i)})}create(e){return new Se(e,this.body,this.images,this.options,this.defaultOptions)}reconnectEdges(){let e,t=this.body.nodes,i=this.body.edges;for(e in t)Object.prototype.hasOwnProperty.call(t,e)&&(t[e].edges=[]);for(e in i)if(Object.prototype.hasOwnProperty.call(i,e)){let s=i[e];s.from=null,s.to=null,s.connect()}}getConnectedNodes(e){let t=[];if(this.body.edges[e]!==void 0){let i=this.body.edges[e];i.fromId!==void 0&&t.push(i.fromId),i.toId!==void 0&&t.push(i.toId)}return t}_updateState(){this._addMissingEdges(),this._removeInvalidEdges()}_removeInvalidEdges(){let e=[];A(this.body.edges,(t,i)=>{let s=this.body.nodes[t.toId],o=this.body.nodes[t.fromId];s!==void 0&&s.isCluster===!0||o!==void 0&&o.isCluster===!0||(s===void 0||o===void 0)&&e.push(i)}),this.remove(e,!1)}_addMissingEdges(){let e=this.body.data.edges;if(e==null)return;let t=this.body.edges,i=[];e.forEach((s,o)=>{t[o]===void 0&&i.push(o)}),this.add(i,!0)}},Li=class{constructor(e,t,i){this.body=e,this.physicsBody=t,this.barnesHutTree,this.setOptions(i),this._rng=yt("BARNES HUT SOLVER")}setOptions(e){this.options=e,this.thetaInversed=1/this.options.theta,this.overlapAvoidanceFactor=1-Math.max(0,Math.min(1,this.options.avoidOverlap))}solve(){if(this.options.gravitationalConstant!==0&&this.physicsBody.physicsNodeIndices.length>0){let e,t=this.body.nodes,i=this.physicsBody.physicsNodeIndices,s=i.length,o=this._formBarnesHutTree(t,i);this.barnesHutTree=o;for(let r=0;r0&&this._getForceContributions(o.root,e)}}_getForceContributions(e,t){this._getForceContribution(e.children.NW,t),this._getForceContribution(e.children.NE,t),this._getForceContribution(e.children.SW,t),this._getForceContribution(e.children.SE,t)}_getForceContribution(e,t){if(e.childrenCount>0){let i=e.centerOfMass.x-t.x,s=e.centerOfMass.y-t.y,o=Math.sqrt(i*i+s*s);o*e.calcSize>this.thetaInversed?this._calculateForces(o,i,s,t,e):e.childrenCount===4?this._getForceContributions(e,t):e.children.data.id!=t.id&&this._calculateForces(o,i,s,t,e)}}_calculateForces(e,t,i,s,o){e===0&&(e=.1,t=e),this.overlapAvoidanceFactor<1&&s.shape.radius&&(e=Math.max(.1+this.overlapAvoidanceFactor*s.shape.radius,e-s.shape.radius));let r=this.options.gravitationalConstant*o.mass*s.options.mass/Math.pow(e,3),a=t*r,d=i*r;this.physicsBody.forces[s.id].x+=a,this.physicsBody.forces[s.id].y+=d}_formBarnesHutTree(e,t){let i,s=t.length,o=e[t[0]].x,r=e[t[0]].y,a=e[t[0]].x,d=e[t[0]].y;for(let f=1;f0&&(ma&&(a=m),vd&&(d=v))}let h=Math.abs(a-o)-Math.abs(d-r);h>0?(r-=.5*h,d+=.5*h):(o+=.5*h,a-=.5*h);let c=Math.max(1e-5,Math.abs(a-o)),u=.5*c,p=.5*(o+a),b=.5*(r+d),C={root:{centerOfMass:{x:0,y:0},mass:0,range:{minX:p-u,maxX:p+u,minY:b-u,maxY:b+u},size:c,calcSize:1/c,children:{data:null},maxWidth:0,level:0,childrenCount:4}};this._splitBranch(C.root);for(let f=0;f0&&this._placeInTree(C.root,i);return C}_updateBranchMass(e,t){let i=e.centerOfMass,s=e.mass+t.options.mass,o=1/s;i.x=i.x*e.mass+t.x*t.options.mass,i.x*=o,i.y=i.y*e.mass+t.y*t.options.mass,i.y*=o,e.mass=s;let r=Math.max(Math.max(t.height,t.radius),t.width);e.maxWidth=e.maxWidtht.x?s.maxY>t.y?o="NW":o="SW":s.maxY>t.y?o="NE":o="SE",this._placeInRegion(e,t,o)}_placeInRegion(e,t,i){let s=e.children[i];switch(s.childrenCount){case 0:s.children.data=t,s.childrenCount=1,this._updateBranchMass(s,t);break;case 1:s.children.data.x===t.x&&s.children.data.y===t.y?(t.x+=this._rng(),t.y+=this._rng()):(this._splitBranch(s),this._placeInTree(s,t));break;case 4:this._placeInTree(s,t);break}}_splitBranch(e){let t=null;e.childrenCount===1&&(t=e.children.data,e.mass=0,e.centerOfMass.x=0,e.centerOfMass.y=0),e.childrenCount=4,e.children.data=null,this._insertRegion(e,"NW"),this._insertRegion(e,"NE"),this._insertRegion(e,"SW"),this._insertRegion(e,"SE"),t!=null&&this._placeInTree(e,t)}_insertRegion(e,t){let i,s,o,r,a=.5*e.size;switch(t){case"NW":i=e.range.minX,s=e.range.minX+a,o=e.range.minY,r=e.range.minY+a;break;case"NE":i=e.range.minX+a,s=e.range.maxX,o=e.range.minY,r=e.range.minY+a;break;case"SW":i=e.range.minX,s=e.range.minX+a,o=e.range.minY+a,r=e.range.maxY;break;case"SE":i=e.range.minX+a,s=e.range.maxX,o=e.range.minY+a,r=e.range.maxY;break}e.children[t]={centerOfMass:{x:0,y:0},mass:0,range:{minX:i,maxX:s,minY:o,maxY:r},size:.5*e.size,calcSize:2*e.calcSize,children:{data:null},maxWidth:0,level:e.level+1,childrenCount:0}}_debug(e,t){this.barnesHutTree!==void 0&&(e.lineWidth=1,this._drawBranch(this.barnesHutTree.root,e,t))}_drawBranch(e,t,i){i===void 0&&(i="#FF0000"),e.childrenCount===4&&(this._drawBranch(e.children.NW,t),this._drawBranch(e.children.NE,t),this._drawBranch(e.children.SE,t),this._drawBranch(e.children.SW,t)),t.strokeStyle=i,t.beginPath(),t.moveTo(e.range.minX,e.range.minY),t.lineTo(e.range.maxX,e.range.minY),t.stroke(),t.beginPath(),t.moveTo(e.range.maxX,e.range.minY),t.lineTo(e.range.maxX,e.range.maxY),t.stroke(),t.beginPath(),t.moveTo(e.range.maxX,e.range.maxY),t.lineTo(e.range.minX,e.range.maxY),t.stroke(),t.beginPath(),t.moveTo(e.range.minX,e.range.maxY),t.lineTo(e.range.minX,e.range.minY),t.stroke()}},on=class{constructor(e,t,i){this._rng=yt("REPULSION SOLVER"),this.body=e,this.physicsBody=t,this.setOptions(i)}setOptions(e){this.options=e}solve(){let e,t,i,s,o,r,a,d,h=this.body.nodes,l=this.physicsBody.physicsNodeIndices,c=this.physicsBody.forces,u=this.options.nodeDistance,p=-2/3/u,b=4/3;for(let C=0;C0){let r=o.edges.length+1,a=this.options.centralGravity*r*o.options.mass;s[o.id].x=t*a,s[o.id].y=i*a}}},hn=class{constructor(e){this.body=e,this.physicsBody={physicsNodeIndices:[],physicsEdgeIndices:[],forces:{},velocities:{}},this.physicsEnabled=!0,this.simulationInterval=1e3/60,this.requiresTimeout=!0,this.previousStates={},this.referenceState={},this.freezeCache={},this.renderTimer=void 0,this.adaptiveTimestep=!1,this.adaptiveTimestepEnabled=!1,this.adaptiveCounter=0,this.adaptiveInterval=3,this.stabilized=!1,this.startedStabilization=!1,this.stabilizationIterations=0,this.ready=!1,this.options={},this.defaultOptions={enabled:!0,barnesHut:{theta:.5,gravitationalConstant:-2e3,centralGravity:.3,springLength:95,springConstant:.04,damping:.09,avoidOverlap:0},forceAtlas2Based:{theta:.5,gravitationalConstant:-50,centralGravity:.01,springConstant:.08,springLength:100,damping:.4,avoidOverlap:0},repulsion:{centralGravity:.2,springLength:200,springConstant:.05,nodeDistance:100,damping:.09,avoidOverlap:0},hierarchicalRepulsion:{centralGravity:0,springLength:100,springConstant:.01,nodeDistance:120,damping:.09},maxVelocity:50,minVelocity:.75,solver:"barnesHut",stabilization:{enabled:!0,iterations:1e3,updateInterval:50,onlyDynamicEdges:!1,fit:!0},timestep:.5,adaptiveTimestep:!0,wind:{x:0,y:0}},Object.assign(this.options,this.defaultOptions),this.timestep=.5,this.layoutFailed=!1,this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("initPhysics",()=>{this.initPhysics()}),this.body.emitter.on("_layoutFailed",()=>{this.layoutFailed=!0}),this.body.emitter.on("resetPhysics",()=>{this.stopSimulation(),this.ready=!1}),this.body.emitter.on("disablePhysics",()=>{this.physicsEnabled=!1,this.stopSimulation()}),this.body.emitter.on("restorePhysics",()=>{this.setOptions(this.options),this.ready===!0&&this.startSimulation()}),this.body.emitter.on("startSimulation",()=>{this.ready===!0&&this.startSimulation()}),this.body.emitter.on("stopSimulation",()=>{this.stopSimulation()}),this.body.emitter.on("destroy",()=>{this.stopSimulation(!1),this.body.emitter.off()}),this.body.emitter.on("_dataChanged",()=>{this.updatePhysicsData()})}setOptions(e){if(e!==void 0)if(e===!1)this.options.enabled=!1,this.physicsEnabled=!1,this.stopSimulation();else if(e===!0)this.options.enabled=!0,this.physicsEnabled=!0,this.startSimulation();else{this.physicsEnabled=!0,bt(["stabilization"],this.options,e),ae(this.options,e,"stabilization"),e.enabled===void 0&&(this.options.enabled=!0),this.options.enabled===!1&&(this.physicsEnabled=!1,this.stopSimulation());let t=this.options.wind;t&&((typeof t.x!="number"||Number.isNaN(t.x))&&(t.x=0),(typeof t.y!="number"||Number.isNaN(t.y))&&(t.y=0)),this.timestep=this.options.timestep}this.init()}init(){let e;this.options.solver==="forceAtlas2Based"?(e=this.options.forceAtlas2Based,this.nodesSolver=new an(this.body,this.physicsBody,e),this.edgesSolver=new Zt(this.body,this.physicsBody,e),this.gravitySolver=new dn(this.body,this.physicsBody,e)):this.options.solver==="repulsion"?(e=this.options.repulsion,this.nodesSolver=new on(this.body,this.physicsBody,e),this.edgesSolver=new Zt(this.body,this.physicsBody,e),this.gravitySolver=new Ct(this.body,this.physicsBody,e)):this.options.solver==="hierarchicalRepulsion"?(e=this.options.hierarchicalRepulsion,this.nodesSolver=new nn(this.body,this.physicsBody,e),this.edgesSolver=new rn(this.body,this.physicsBody,e),this.gravitySolver=new Ct(this.body,this.physicsBody,e)):(e=this.options.barnesHut,this.nodesSolver=new Li(this.body,this.physicsBody,e),this.edgesSolver=new Zt(this.body,this.physicsBody,e),this.gravitySolver=new Ct(this.body,this.physicsBody,e)),this.modelOptions=e}initPhysics(){this.physicsEnabled===!0&&this.options.enabled===!0?this.options.stabilization.enabled===!0?this.stabilize():(this.stabilized=!1,this.ready=!0,this.body.emitter.emit("fit",{},this.layoutFailed),this.startSimulation()):(this.ready=!0,this.body.emitter.emit("fit"))}startSimulation(){this.physicsEnabled===!0&&this.options.enabled===!0?(this.stabilized=!1,this.adaptiveTimestep=!1,this.body.emitter.emit("_resizeNodes"),this.viewFunction===void 0&&(this.viewFunction=this.simulationStep.bind(this),this.body.emitter.on("initRedraw",this.viewFunction),this.body.emitter.emit("_startRendering"))):this.body.emitter.emit("_redraw")}stopSimulation(e=!0){this.stabilized=!0,e===!0&&this._emitStabilized(),this.viewFunction!==void 0&&(this.body.emitter.off("initRedraw",this.viewFunction),this.viewFunction=void 0,e===!0&&this.body.emitter.emit("_stopRendering"))}simulationStep(){let e=Date.now();this.physicsTick(),(Date.now()-e<.4*this.simulationInterval||this.runDoubleSpeed===!0)&&this.stabilized===!1&&(this.physicsTick(),this.runDoubleSpeed=!0),this.stabilized===!0&&this.stopSimulation()}_emitStabilized(e=this.stabilizationIterations){(this.stabilizationIterations>1||this.startedStabilization===!0)&&setTimeout(()=>{this.body.emitter.emit("stabilized",{iterations:e}),this.startedStabilization=!1,this.stabilizationIterations=0},0)}physicsStep(){this.gravitySolver.solve(),this.nodesSolver.solve(),this.edgesSolver.solve(),this.moveNodes()}adjustTimeStep(){let e=1.2;this._evaluateStepQuality()===!0?this.timestep=e*this.timestep:this.timestep/er))return!1;return!0}moveNodes(){let e=this.physicsBody.physicsNodeIndices,t=0,i=0,s=5;for(let o=0;or&&(e=e>0?r:-r),e}_performStep(e){let t=this.body.nodes[e],i=this.physicsBody.forces[e];this.options.wind&&(i.x+=this.options.wind.x,i.y+=this.options.wind.y);let s=this.physicsBody.velocities[e];return this.previousStates[e]={x:t.x,y:t.y,vx:s.x,vy:s.y},t.options.fixed.x===!1?(s.x=this.calculateComponentVelocity(s.x,i.x,t.options.mass),t.x+=s.x*this.timestep):(i.x=0,s.x=0),t.options.fixed.y===!1?(s.y=this.calculateComponentVelocity(s.y,i.y,t.options.mass),t.y+=s.y*this.timestep):(i.y=0,s.y=0),Math.sqrt(Math.pow(s.x,2)+Math.pow(s.y,2))}_freezeNodes(){let e=this.body.nodes;for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t)&&e[t].x&&e[t].y){let i=e[t].options.fixed;this.freezeCache[t]={x:i.x,y:i.y},i.x=!0,i.y=!0}}_restoreFrozenNodes(){let e=this.body.nodes;for(let t in e)Object.prototype.hasOwnProperty.call(e,t)&&this.freezeCache[t]!==void 0&&(e[t].options.fixed.x=this.freezeCache[t].x,e[t].options.fixed.y=this.freezeCache[t].y);this.freezeCache={}}stabilize(e=this.options.stabilization.iterations){if(typeof e!="number"&&(e=this.options.stabilization.iterations,console.error("The stabilize method needs a numeric amount of iterations. Switching to default: ",e)),this.physicsBody.physicsNodeIndices.length===0){this.ready=!0;return}this.adaptiveTimestep=this.options.adaptiveTimestep,this.body.emitter.emit("_resizeNodes"),this.stopSimulation(),this.stabilized=!1,this.body.emitter.emit("_blockRedraw"),this.targetIterations=e,this.options.stabilization.onlyDynamicEdges===!0&&this._freezeNodes(),this.stabilizationIterations=0,setTimeout(()=>this._stabilizationBatch(),0)}_startStabilizing(){return this.startedStabilization===!0?!1:(this.body.emitter.emit("startStabilizing"),this.startedStabilization=!0,!0)}_stabilizationBatch(){let e=()=>this.stabilized===!1&&this.stabilizationIterations{this.body.emitter.emit("stabilizationProgress",{iterations:this.stabilizationIterations,total:this.targetIterations})};this._startStabilizing()&&t();let i=0;for(;e()&&i0)for(let d=0;da.shape.boundingBox.left&&(o=a.shape.boundingBox.left),ra.shape.boundingBox.top&&(i=a.shape.boundingBox.top),s0)for(let d=0;da.x&&(o=a.x),ra.y&&(i=a.y),s{delete this.containedEdges[i.id]}),A(t.containedNodes,(i,s)=>{this.containedNodes[s]=i}),t.containedNodes={},A(t.containedEdges,(i,s)=>{this.containedEdges[s]=i}),t.containedEdges={},A(t.edges,i=>{A(this.edges,s=>{let o=s.clusteringEdgeReplacingIds.indexOf(i.id);o!==-1&&(A(i.clusteringEdgeReplacingIds,r=>{s.clusteringEdgeReplacingIds.push(r),this.body.edges[r].edgeReplacedById=s.id}),s.clusteringEdgeReplacingIds.splice(o,1))})}),t.edges=[]}},cn=class{constructor(e){this.body=e,this.clusteredNodes={},this.clusteredEdges={},this.options={},this.defaultOptions={},Object.assign(this.options,this.defaultOptions),this.body.emitter.on("_resetData",()=>{this.clusteredNodes={},this.clusteredEdges={}})}clusterByHubsize(e,t){e===void 0?e=this._getHubSize():typeof e=="object"&&(t=this._checkOptions(e),e=this._getHubSize());let i=[];for(let s=0;s=e&&i.push(o.id)}for(let s=0;s{o.options&&e.joinCondition(o.options)===!0&&(i[r]=o,A(o.edges,a=>{this.clusteredEdges[a.id]===void 0&&(s[a.id]=a)}))}),this._cluster(i,s,e,t)}clusterByEdgeCount(e,t,i=!0){t=this._checkOptions(t);let s=[],o={},r,a,d;for(let h=0;h0&&Object.keys(c).length>0&&C===!0){let g=function(){for(let m=0;m-1&&(r[p.id]=p)}}this._cluster(o,r,t,i)}_createClusterEdges(e,t,i,s){let o,r,a,d,h,l,c=Object.keys(e),u=[];for(let C=0;Cs?a.x:s,o=a.yr?a.y:r;return{x:.5*(i+s),y:.5*(o+r)}}openCluster(e,t,i=!0){if(e===void 0)throw new Error("No clusterNodeId supplied to openCluster.");let s=this.body.nodes[e];if(s===void 0)throw new Error("The clusterNodeId supplied to openCluster does not exist.");if(s.isCluster!==!0||s.containedNodes===void 0||s.containedEdges===void 0)throw new Error("The node:"+e+" is not a valid cluster.");let o=this.findNode(e),r=o.indexOf(e)-1;if(r>=0){let l=o[r];this.body.nodes[l]._openChildCluster(e),delete this.body.nodes[e],i===!0&&this.body.emitter.emit("_dataChanged");return}let a=s.containedNodes,d=s.containedEdges;if(t!==void 0&&t.releaseFunction!==void 0&&typeof t.releaseFunction=="function"){let l={},c={x:s.x,y:s.y};for(let p in a)if(Object.prototype.hasOwnProperty.call(a,p)){let b=this.body.nodes[p];l[p]={x:b.x,y:b.y}}let u=t.releaseFunction(c,l);for(let p in a)if(Object.prototype.hasOwnProperty.call(a,p)){let b=this.body.nodes[p];u[p]!==void 0&&(b.x=u[p].x===void 0?s.x:u[p].x,b.y=u[p].y===void 0?s.y:u[p].y)}}else A(a,function(l){l.options.fixed.x===!1&&(l.x=s.x),l.options.fixed.y===!1&&(l.y=s.y)});for(let l in a)if(Object.prototype.hasOwnProperty.call(a,l)){let c=this.body.nodes[l];c.vx=s.vx,c.vy=s.vy,c.setOptions({physics:!0}),delete this.clusteredNodes[l]}let h=[];for(let l=0;l0&&rs&&(s=h.edges.length),e+=h.edges.length,t+=Math.pow(h.edges.length,2),i+=1}e=e/i,t=t/i;let o=t-Math.pow(e,2),r=Math.sqrt(o),a=Math.floor(e+2*r);return a>s&&(a=s),a}_createClusteredEdge(e,t,i,s,o){let r=J.cloneOptions(i,"edge");j(r,s),r.from=e,r.to=t,r.id="clusterEdge:"+Ce(),o!==void 0&&j(r,o);let a=this.body.functions.createEdge(r);return a.clusteringEdgeReplacingIds=[i.id],a.connect(),this.body.edges[a.id]=a,a}_clusterEdges(e,t,i,s){if(t instanceof Se){let o=t,r={};r[o.id]=o,t=r}if(e instanceof U){let o=e,r={};r[o.id]=o,e=r}if(i==null)throw new Error("_clusterEdges: parameter clusterNode required");s===void 0&&(s=i.clusterEdgeProperties),this._createClusterEdges(e,t,i,s);for(let o in t)if(Object.prototype.hasOwnProperty.call(t,o)&&this.body.edges[o]!==void 0){let r=this.body.edges[o];this._backupEdgeOptions(r),r.setOptions({physics:!1})}for(let o in e)Object.prototype.hasOwnProperty.call(e,o)&&(this.clusteredNodes[o]={clusterId:i.id,node:this.body.nodes[o]},this.body.nodes[o].setOptions({physics:!1}))}_getClusterNodeForNode(e){if(e===void 0)return;let t=this.clusteredNodes[e];if(t===void 0)return;let i=t.clusterId;if(i!==void 0)return this.body.nodes[i]}_filter(e,t){let i=[];return A(e,s=>{t(s)&&i.push(s)}),i}_updateState(){let e,t=[],i={},s=d=>{A(this.body.nodes,h=>{h.isCluster===!0&&d(h)})};for(e in this.clusteredNodes){if(!Object.prototype.hasOwnProperty.call(this.clusteredNodes,e))continue;this.body.nodes[e]===void 0&&t.push(e)}s(function(d){for(let h=0;h{let h=this.body.edges[d];(h===void 0||!h.endPointsValid())&&(i[d]=d)}),s(function(d){A(d.containedEdges,(h,l)=>{!h.endPointsValid()&&!i[l]&&(i[l]=l)})}),A(this.body.edges,(d,h)=>{let l=!0,c=d.clusteringEdgeReplacingIds;if(c!==void 0){let u=0;A(c,p=>{let b=this.body.edges[p];b!==void 0&&b.endPointsValid()&&(u+=1)}),l=u>0}(!d.endPointsValid()||!l)&&(i[h]=h)}),s(d=>{A(i,h=>{delete d.containedEdges[h],A(d.edges,(l,c)=>{if(l.id===h){d.edges[c]=null;return}l.clusteringEdgeReplacingIds=this._filter(l.clusteringEdgeReplacingIds,function(u){return!i[u]})}),d.edges=this._filter(d.edges,function(l){return l!==null})})}),A(i,d=>{delete this.clusteredEdges[d]}),A(i,d=>{delete this.body.edges[d]});let o=Object.keys(this.body.edges);A(o,d=>{let h=this.body.edges[d],l=this._isClusteredNode(h.fromId)||this._isClusteredNode(h.toId);if(l!==this._isClusteredEdge(h.id))if(l){let c=this._getClusterNodeForNode(h.fromId);c!==void 0&&this._clusterEdges(this.body.nodes[h.fromId],h,c);let u=this._getClusterNodeForNode(h.toId);u!==void 0&&this._clusterEdges(this.body.nodes[h.toId],h,u)}else delete this._clusterEdges[d],this._restoreEdge(h)});let r=!1,a=!0;for(;a;){let d=[];s(function(h){let l=Object.keys(h.containedNodes).length,c=h.options.allowSingleNodeCluster===!0;(c&&l<1||!c&&l<2)&&d.push(h.id)});for(let h=0;h0,r=r||a}r&&this._updateState()}_isClusteredNode(e){return this.clusteredNodes[e]!==void 0}_isClusteredEdge(e){return this.clusteredEdges[e]!==void 0}};function ka(){let n;window!==void 0&&(n=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame),n===void 0?window.requestAnimationFrame=function(e){e()}:window.requestAnimationFrame=n}var un=class{constructor(e,t){ka(),this.body=e,this.canvas=t,this.redrawRequested=!1,this.renderTimer=void 0,this.requiresTimeout=!0,this.renderingActive=!1,this.renderRequests=0,this.allowRedraw=!0,this.dragging=!1,this.zooming=!1,this.options={},this.defaultOptions={hideEdgesOnDrag:!1,hideEdgesOnZoom:!1,hideNodesOnDrag:!1},Object.assign(this.options,this.defaultOptions),this._determineBrowserMethod(),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("dragStart",()=>{this.dragging=!0}),this.body.emitter.on("dragEnd",()=>{this.dragging=!1}),this.body.emitter.on("zoom",()=>{this.zooming=!0,window.clearTimeout(this.zoomTimeoutId),this.zoomTimeoutId=window.setTimeout(()=>{this.zooming=!1,this._requestRedraw.bind(this)()},250)}),this.body.emitter.on("_resizeNodes",()=>{this._resizeNodes()}),this.body.emitter.on("_redraw",()=>{this.renderingActive===!1&&this._redraw()}),this.body.emitter.on("_blockRedraw",()=>{this.allowRedraw=!1}),this.body.emitter.on("_allowRedraw",()=>{this.allowRedraw=!0,this.redrawRequested=!1}),this.body.emitter.on("_requestRedraw",this._requestRedraw.bind(this)),this.body.emitter.on("_startRendering",()=>{this.renderRequests+=1,this.renderingActive=!0,this._startRendering()}),this.body.emitter.on("_stopRendering",()=>{this.renderRequests-=1,this.renderingActive=this.renderRequests>0,this.renderTimer=void 0}),this.body.emitter.on("destroy",()=>{this.renderRequests=0,this.allowRedraw=!1,this.renderingActive=!1,this.requiresTimeout===!0?clearTimeout(this.renderTimer):window.cancelAnimationFrame(this.renderTimer),this.body.emitter.off()})}setOptions(e){e!==void 0&&qe(["hideEdgesOnDrag","hideEdgesOnZoom","hideNodesOnDrag"],this.options,e)}_requestNextFrame(e,t){if(typeof window=="undefined")return;let i,s=window;return this.requiresTimeout===!0?i=s.setTimeout(e,t):s.requestAnimationFrame&&(i=s.requestAnimationFrame(e)),i}_startRendering(){this.renderingActive===!0&&this.renderTimer===void 0&&(this.renderTimer=this._requestNextFrame(this._renderStep.bind(this),this.simulationInterval))}_renderStep(){this.renderingActive===!0&&(this.renderTimer=void 0,this.requiresTimeout===!0&&this._startRendering(),this._redraw(),this.requiresTimeout===!1&&this._startRendering())}redraw(){this.body.emitter.emit("setSize"),this._redraw()}_requestRedraw(){this.redrawRequested!==!0&&this.renderingActive===!1&&this.allowRedraw===!0&&(this.redrawRequested=!0,this._requestNextFrame(()=>{this._redraw(!1)},0))}_redraw(e=!1){if(this.allowRedraw===!0){this.body.emitter.emit("initRedraw"),this.redrawRequested=!1;let t={drawExternalLabels:null};(this.canvas.frame.canvas.width===0||this.canvas.frame.canvas.height===0)&&this.canvas.setSize(),this.canvas.setTransform();let i=this.canvas.getContext(),s=this.canvas.frame.canvas.clientWidth,o=this.canvas.frame.canvas.clientHeight;if(i.clearRect(0,0,s,o),this.canvas.frame.clientWidth===0)return;if(i.save(),i.translate(this.body.view.translation.x,this.body.view.translation.y),i.scale(this.body.view.scale,this.body.view.scale),i.beginPath(),this.body.emitter.emit("beforeDrawing",i),i.closePath(),e===!1&&(this.dragging===!1||this.dragging===!0&&this.options.hideEdgesOnDrag===!1)&&(this.zooming===!1||this.zooming===!0&&this.options.hideEdgesOnZoom===!1)&&this._drawEdges(i),this.dragging===!1||this.dragging===!0&&this.options.hideNodesOnDrag===!1){let{drawExternalLabels:r}=this._drawNodes(i,e);t.drawExternalLabels=r}e===!1&&(this.dragging===!1||this.dragging===!0&&this.options.hideEdgesOnDrag===!1)&&(this.zooming===!1||this.zooming===!0&&this.options.hideEdgesOnZoom===!1)&&this._drawArrows(i),t.drawExternalLabels!=null&&t.drawExternalLabels(),e===!1&&this._drawSelectionBox(i),i.beginPath(),this.body.emitter.emit("afterDrawing",i),i.closePath(),i.restore(),e===!0&&i.clearRect(0,0,s,o)}}_resizeNodes(){this.canvas.setTransform();let e=this.canvas.getContext();e.save(),e.translate(this.body.view.translation.x,this.body.view.translation.y),e.scale(this.body.view.scale,this.body.view.scale);let t=this.body.nodes,i;for(let s in t)Object.prototype.hasOwnProperty.call(t,s)&&(i=t[s],i.resize(e),i.updateBoundingBox(e,i.selected));e.restore()}_drawNodes(e,t=!1){let i=this.body.nodes,s=this.body.nodeIndices,o,r=[],a=[],d=20,h=this.canvas.DOMtoCanvas({x:-d,y:-d}),l=this.canvas.DOMtoCanvas({x:this.canvas.frame.canvas.clientWidth+d,y:this.canvas.frame.canvas.clientHeight+d}),c={top:h.y,left:h.x,bottom:l.y,right:l.x},u=[];for(let f=0;f{for(let f of u)f()}}}_drawEdges(e){let t=this.body.edges,i=this.body.edgeIndices;for(let s=0;s{e.width!==0&&(this.body.view.translation.x=e.width*.5),e.height!==0&&(this.body.view.translation.y=e.height*.5)}),this.body.emitter.on("setSize",this.setSize.bind(this)),this.body.emitter.on("destroy",()=>{this.hammerFrame.destroy(),this.hammer.destroy(),this._cleanUp()})}setOptions(e){if(e!==void 0&&qe(["width","height","autoResize"],this.options,e),this._cleanUp(),this.options.autoResize===!0){if(window.ResizeObserver){let i=new ResizeObserver(()=>{this.setSize()===!0&&this.body.emitter.emit("_requestRedraw")}),{frame:s}=this;i.observe(s),this._cleanupCallbacks.push(()=>{i.unobserve(s)})}else{let i=setInterval(()=>{this.setSize()===!0&&this.body.emitter.emit("_requestRedraw")},1e3);this._cleanupCallbacks.push(()=>{clearInterval(i)})}let t=this._onResize.bind(this);Ls(window,"resize",t),this._cleanupCallbacks.push(()=>{Rs(window,"resize",t)})}}_cleanUp(){this._cleanupCallbacks.splice(0).reverse().forEach(e=>{try{e()}catch(t){console.error(t)}})}_onResize(){this.setSize(),this.body.emitter.emit("_redraw")}_getCameraState(e=this.pixelRatio){this.initialized===!0&&(this.cameraState.previousWidth=this.frame.canvas.width/e,this.cameraState.previousHeight=this.frame.canvas.height/e,this.cameraState.scale=this.body.view.scale,this.cameraState.position=this.DOMtoCanvas({x:.5*this.frame.canvas.width/e,y:.5*this.frame.canvas.height/e}))}_setCameraState(){if(this.cameraState.scale!==void 0&&this.frame.canvas.clientWidth!==0&&this.frame.canvas.clientHeight!==0&&this.pixelRatio!==0&&this.cameraState.previousWidth>0&&this.cameraState.previousHeight>0){let e=this.frame.canvas.width/this.pixelRatio/this.cameraState.previousWidth,t=this.frame.canvas.height/this.pixelRatio/this.cameraState.previousHeight,i=this.cameraState.scale;e!=1&&t!=1?i=this.cameraState.scale*.5*(e+t):e!=1?i=this.cameraState.scale*e:t!=1&&(i=this.cameraState.scale*t),this.body.view.scale=i;let s=this.DOMtoCanvas({x:.5*this.frame.canvas.clientWidth,y:.5*this.frame.canvas.clientHeight}),o={x:s.x-this.cameraState.position.x,y:s.y-this.cameraState.position.y};this.body.view.translation.x+=o.x*this.body.view.scale,this.body.view.translation.y+=o.y*this.body.view.scale}}_prepareValue(e){if(typeof e=="number")return e+"px";if(typeof e=="string"){if(e.indexOf("%")!==-1||e.indexOf("px")!==-1)return e;if(e.indexOf("%")===-1)return e+"px"}throw new Error("Could not use the value supplied for width or height:"+e)}_create(){for(;this.body.container.hasChildNodes();)this.body.container.removeChild(this.body.container.firstChild);if(this.frame=document.createElement("div"),this.frame.className="vis-network",this.frame.style.position="relative",this.frame.style.overflow="hidden",this.frame.tabIndex=0,this.frame.canvas=document.createElement("canvas"),this.frame.canvas.style.position="relative",this.frame.appendChild(this.frame.canvas),this.frame.canvas.getContext)this._setPixelRatio(),this.setTransform();else{let e=document.createElement("DIV");e.style.color="red",e.style.fontWeight="bold",e.style.padding="10px",e.innerText="Error: your browser does not support HTML canvas",this.frame.canvas.appendChild(e)}this.body.container.appendChild(this.frame),this.body.view.scale=1,this.body.view.translation={x:.5*this.frame.canvas.clientWidth,y:.5*this.frame.canvas.clientHeight},this._bindHammer()}_bindHammer(){this.hammer!==void 0&&this.hammer.destroy(),this.drag={},this.pinch={},this.hammer=new Ue(this.frame.canvas),this.hammer.get("pinch").set({enable:!0}),this.hammer.get("pan").set({threshold:5,direction:Ue.DIRECTION_ALL}),Qt(this.hammer,e=>{this.body.eventListeners.onTouch(e)}),this.hammer.on("tap",e=>{this.body.eventListeners.onTap(e)}),this.hammer.on("doubletap",e=>{this.body.eventListeners.onDoubleTap(e)}),this.hammer.on("press",e=>{this.body.eventListeners.onHold(e)}),this.hammer.on("panstart",e=>{this.body.eventListeners.onDragStart(e)}),this.hammer.on("panmove",e=>{this.body.eventListeners.onDrag(e)}),this.hammer.on("panend",e=>{this.body.eventListeners.onDragEnd(e)}),this.hammer.on("pinch",e=>{this.body.eventListeners.onPinch(e)}),this.frame.canvas.addEventListener("wheel",e=>{this.body.eventListeners.onMouseWheel(e)}),this.frame.canvas.addEventListener("mousemove",e=>{this.body.eventListeners.onMouseMove(e)}),this.frame.canvas.addEventListener("contextmenu",e=>{this.body.eventListeners.onContext(e)}),this.hammerFrame=new Ue(this.frame),fn(this.hammerFrame,e=>{this.body.eventListeners.onRelease(e)})}setSize(e=this.options.width,t=this.options.height){e=this._prepareValue(e),t=this._prepareValue(t);let i=!1,s=this.frame.canvas.width,o=this.frame.canvas.height,r=this.pixelRatio;if(this._setPixelRatio(),e!=this.options.width||t!=this.options.height||this.frame.style.width!=e||this.frame.style.height!=t)this._getCameraState(r),this.frame.style.width=e,this.frame.style.height=t,this.frame.canvas.style.width="100%",this.frame.canvas.style.height="100%",this.frame.canvas.width=Math.round(this.frame.canvas.clientWidth*this.pixelRatio),this.frame.canvas.height=Math.round(this.frame.canvas.clientHeight*this.pixelRatio),this.options.width=e,this.options.height=t,this.canvasViewCenter={x:.5*this.frame.clientWidth,y:.5*this.frame.clientHeight},i=!0;else{let a=Math.round(this.frame.canvas.clientWidth*this.pixelRatio),d=Math.round(this.frame.canvas.clientHeight*this.pixelRatio);(this.frame.canvas.width!==a||this.frame.canvas.height!==d)&&this._getCameraState(r),this.frame.canvas.width!==a&&(this.frame.canvas.width=a,i=!0),this.frame.canvas.height!==d&&(this.frame.canvas.height=d,i=!0)}return i===!0&&(this.body.emitter.emit("resize",{width:Math.round(this.frame.canvas.width/this.pixelRatio),height:Math.round(this.frame.canvas.height/this.pixelRatio),oldWidth:Math.round(s/this.pixelRatio),oldHeight:Math.round(o/this.pixelRatio)}),this._setCameraState()),this.initialized=!0,i}getContext(){return this.frame.canvas.getContext("2d")}_determinePixelRatio(){let e=this.getContext();if(e===void 0)throw new Error("Could not get canvax context");let t=1;typeof window!="undefined"&&(t=window.devicePixelRatio||1);let i=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return t/i}_setPixelRatio(){this.pixelRatio=this._determinePixelRatio()}setTransform(){let e=this.getContext();if(e===void 0)throw new Error("Could not get canvax context");e.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0)}_XconvertDOMtoCanvas(e){return(e-this.body.view.translation.x)/this.body.view.scale}_XconvertCanvasToDOM(e){return e*this.body.view.scale+this.body.view.translation.x}_YconvertDOMtoCanvas(e){return(e-this.body.view.translation.y)/this.body.view.scale}_YconvertCanvasToDOM(e){return e*this.body.view.scale+this.body.view.translation.y}canvasToDOM(e){return{x:this._XconvertCanvasToDOM(e.x),y:this._YconvertCanvasToDOM(e.y)}}DOMtoCanvas(e){return{x:this._XconvertDOMtoCanvas(e.x),y:this._YconvertDOMtoCanvas(e.y)}}};function Sa(n,e){let t=Object.assign({nodes:e,minZoomLevel:Number.MIN_VALUE,maxZoomLevel:1},n!=null?n:{});if(!Array.isArray(t.nodes))throw new TypeError("Nodes has to be an array of ids.");if(t.nodes.length===0&&(t.nodes=e),!(typeof t.minZoomLevel=="number"&&t.minZoomLevel>0))throw new TypeError("Min zoom level has to be a number higher than zero.");if(!(typeof t.maxZoomLevel=="number"&&t.minZoomLevel<=t.maxZoomLevel))throw new TypeError("Max zoom level has to be a number higher than min zoom level.");return t}var gn=class{constructor(e,t){this.body=e,this.canvas=t,this.animationSpeed=1/this.renderRefreshRate,this.animationEasingFunction="easeInOutQuint",this.easingTime=0,this.sourceScale=0,this.targetScale=0,this.sourceTranslation=0,this.targetTranslation=0,this.lockedOnNodeId=void 0,this.lockedOnNodeOffset=void 0,this.touchTime=0,this.viewFunction=void 0,this.body.emitter.on("fit",this.fit.bind(this)),this.body.emitter.on("animationFinished",()=>{this.body.emitter.emit("_stopRendering")}),this.body.emitter.on("unlockNode",this.releaseNode.bind(this))}setOptions(e={}){this.options=e}fit(e,t=!1){e=Sa(e,this.body.nodeIndices);let i=this.canvas.frame.canvas.clientWidth,s=this.canvas.frame.canvas.clientHeight,o,r;if(i===0||s===0)r=1,o=J.getRange(this.body.nodes,e.nodes);else if(t===!0){let h=0;for(let u in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,u)&&this.body.nodes[u].predefinedPosition===!0&&(h+=1);if(h>.5*this.body.nodeIndices.length){this.fit(e,!1);return}o=J.getRange(this.body.nodes,e.nodes);let l=this.body.nodeIndices.length;r=12.662/(l+7.4147)+.0964822,r*=Math.min(i/600,s/600)}else{this.body.emitter.emit("_resizeNodes"),o=J.getRange(this.body.nodes,e.nodes);let h=Math.abs(o.maxX-o.minX)*1.1,l=Math.abs(o.maxY-o.minY)*1.1,c=i/h,u=s/l;r=c<=u?c:u}r>e.maxZoomLevel?r=e.maxZoomLevel:r0))throw new TypeError('The option "scale" has to be a number greater than zero.')}else e.scale=this.body.view.scale;e.animation===void 0&&(e.animation={duration:0}),e.animation===!1&&(e.animation={duration:0}),e.animation===!0&&(e.animation={}),e.animation.duration===void 0&&(e.animation.duration=1e3),e.animation.easingFunction===void 0&&(e.animation.easingFunction="easeInOutQuad"),this.animateView(e)}animateView(e){if(e===void 0)return;this.animationEasingFunction=e.animation.easingFunction,this.releaseNode(),e.locked===!0&&(this.lockedOnNodeId=e.lockedOnNode,this.lockedOnNodeOffset=e.offset),this.easingTime!=0&&this._transitionRedraw(!0),this.sourceScale=this.body.view.scale,this.sourceTranslation=this.body.view.translation,this.targetScale=e.scale,this.body.view.scale=this.targetScale;let t=this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight}),i={x:t.x-e.position.x,y:t.y-e.position.y};this.targetTranslation={x:this.sourceTranslation.x+i.x*this.targetScale+e.offset.x,y:this.sourceTranslation.y+i.y*this.targetScale+e.offset.y},e.animation.duration===0?this.lockedOnNodeId!=null?(this.viewFunction=this._lockedRedraw.bind(this),this.body.emitter.on("initRedraw",this.viewFunction)):(this.body.view.scale=this.targetScale,this.body.view.translation=this.targetTranslation,this.body.emitter.emit("_requestRedraw")):(this.animationSpeed=1/(60*e.animation.duration*.001)||1/60,this.animationEasingFunction=e.animation.easingFunction,this.viewFunction=this._transitionRedraw.bind(this),this.body.emitter.on("initRedraw",this.viewFunction),this.body.emitter.emit("_startRendering"))}_lockedRedraw(){let e={x:this.body.nodes[this.lockedOnNodeId].x,y:this.body.nodes[this.lockedOnNodeId].y},t=this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight}),i={x:t.x-e.x,y:t.y-e.y},s=this.body.view.translation,o={x:s.x+i.x*this.body.view.scale+this.lockedOnNodeOffset.x,y:s.y+i.y*this.body.view.scale+this.lockedOnNodeOffset.y};this.body.view.translation=o}releaseNode(){this.lockedOnNodeId!==void 0&&this.viewFunction!==void 0&&(this.body.emitter.off("initRedraw",this.viewFunction),this.lockedOnNodeId=void 0,this.lockedOnNodeOffset=void 0)}_transitionRedraw(e=!1){this.easingTime+=this.animationSpeed,this.easingTime=e===!0?1:this.easingTime;let t=Vs[this.animationEasingFunction](this.easingTime);this.body.view.scale=this.sourceScale+(this.targetScale-this.sourceScale)*t,this.body.view.translation={x:this.sourceTranslation.x+(this.targetTranslation.x-this.sourceTranslation.x)*t,y:this.sourceTranslation.y+(this.targetTranslation.y-this.sourceTranslation.y)*t},this.easingTime>=1&&(this.body.emitter.off("initRedraw",this.viewFunction),this.easingTime=0,this.lockedOnNodeId!=null&&(this.viewFunction=this._lockedRedraw.bind(this),this.body.emitter.on("initRedraw",this.viewFunction)),this.body.emitter.emit("animationFinished"))}getScale(){return this.body.view.scale}getViewPosition(){return this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight})}},mn=class{constructor(e,t){this.body=e,this.canvas=t,this.iconsCreated=!1,this.navigationHammers=[],this.boundFunctions={},this.touchTime=0,this.activated=!1,this.body.emitter.on("activate",()=>{this.activated=!0,this.configureKeyboardBindings()}),this.body.emitter.on("deactivate",()=>{this.activated=!1,this.configureKeyboardBindings()}),this.body.emitter.on("destroy",()=>{this.keycharm!==void 0&&this.keycharm.destroy()}),this.options={}}setOptions(e){e!==void 0&&(this.options=e,this.create())}create(){this.options.navigationButtons===!0?this.iconsCreated===!1&&this.loadNavigationElements():this.iconsCreated===!0&&this.cleanNavigation(),this.configureKeyboardBindings()}cleanNavigation(){if(this.navigationHammers.length!=0){for(let e=0;e{this._stopMovement()}),this.navigationHammers.push(i),this.iconsCreated=!0}bindToRedraw(e){this.boundFunctions[e]===void 0&&(this.boundFunctions[e]=this[e].bind(this),this.body.emitter.on("initRedraw",this.boundFunctions[e]),this.body.emitter.emit("_startRendering"))}unbindFromRedraw(e){this.boundFunctions[e]!==void 0&&(this.body.emitter.off("initRedraw",this.boundFunctions[e]),this.body.emitter.emit("_stopRendering"),delete this.boundFunctions[e])}_fit(){new Date().valueOf()-this.touchTime>700&&(this.body.emitter.emit("fit",{duration:700}),this.touchTime=new Date().valueOf())}_stopMovement(){for(let e in this.boundFunctions)Object.prototype.hasOwnProperty.call(this.boundFunctions,e)&&(this.body.emitter.off("initRedraw",this.boundFunctions[e]),this.body.emitter.emit("_stopRendering"));this.boundFunctions={}}_moveUp(){this.body.view.translation.y+=this.options.keyboard.speed.y}_moveDown(){this.body.view.translation.y-=this.options.keyboard.speed.y}_moveLeft(){this.body.view.translation.x+=this.options.keyboard.speed.x}_moveRight(){this.body.view.translation.x-=this.options.keyboard.speed.x}_zoomIn(){let e=this.body.view.scale,t=this.body.view.scale*(1+this.options.keyboard.speed.zoom),i=this.body.view.translation,s=t/e,o=(1-s)*this.canvas.canvasViewCenter.x+i.x*s,r=(1-s)*this.canvas.canvasViewCenter.y+i.y*s;this.body.view.scale=t,this.body.view.translation={x:o,y:r},this.body.emitter.emit("zoom",{direction:"+",scale:this.body.view.scale,pointer:null})}_zoomOut(){let e=this.body.view.scale,t=this.body.view.scale/(1+this.options.keyboard.speed.zoom),i=this.body.view.translation,s=t/e,o=(1-s)*this.canvas.canvasViewCenter.x+i.x*s,r=(1-s)*this.canvas.canvasViewCenter.y+i.y*s;this.body.view.scale=t,this.body.view.translation={x:o,y:r},this.body.emitter.emit("zoom",{direction:"-",scale:this.body.view.scale,pointer:null})}configureKeyboardBindings(){this.keycharm!==void 0&&this.keycharm.destroy(),this.options.keyboard.enabled===!0&&(this.options.keyboard.bindToWindow===!0?this.keycharm=qt({container:window,preventDefault:!0}):this.keycharm=qt({container:this.canvas.frame,preventDefault:!0}),this.keycharm.reset(),this.activated===!0&&(this.keycharm.bind("up",()=>{this.bindToRedraw("_moveUp")},"keydown"),this.keycharm.bind("down",()=>{this.bindToRedraw("_moveDown")},"keydown"),this.keycharm.bind("left",()=>{this.bindToRedraw("_moveLeft")},"keydown"),this.keycharm.bind("right",()=>{this.bindToRedraw("_moveRight")},"keydown"),this.keycharm.bind("=",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("num+",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("num-",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("-",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("[",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("]",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("pageup",()=>{this.bindToRedraw("_zoomIn")},"keydown"),this.keycharm.bind("pagedown",()=>{this.bindToRedraw("_zoomOut")},"keydown"),this.keycharm.bind("up",()=>{this.unbindFromRedraw("_moveUp")},"keyup"),this.keycharm.bind("down",()=>{this.unbindFromRedraw("_moveDown")},"keyup"),this.keycharm.bind("left",()=>{this.unbindFromRedraw("_moveLeft")},"keyup"),this.keycharm.bind("right",()=>{this.unbindFromRedraw("_moveRight")},"keyup"),this.keycharm.bind("=",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("num+",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("num-",()=>{this.unbindFromRedraw("_zoomOut")},"keyup"),this.keycharm.bind("-",()=>{this.unbindFromRedraw("_zoomOut")},"keyup"),this.keycharm.bind("[",()=>{this.unbindFromRedraw("_zoomOut")},"keyup"),this.keycharm.bind("]",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("pageup",()=>{this.unbindFromRedraw("_zoomIn")},"keyup"),this.keycharm.bind("pagedown",()=>{this.unbindFromRedraw("_zoomOut")},"keyup")))}},yn=class{constructor(e,t,i){this.body=e,this.canvas=t,this.selectionHandler=i,this.navigationHandler=new mn(e,t),this.body.eventListeners.onTap=this.onTap.bind(this),this.body.eventListeners.onTouch=this.onTouch.bind(this),this.body.eventListeners.onDoubleTap=this.onDoubleTap.bind(this),this.body.eventListeners.onHold=this.onHold.bind(this),this.body.eventListeners.onDragStart=this.onDragStart.bind(this),this.body.eventListeners.onDrag=this.onDrag.bind(this),this.body.eventListeners.onDragEnd=this.onDragEnd.bind(this),this.body.eventListeners.onMouseWheel=this.onMouseWheel.bind(this),this.body.eventListeners.onPinch=this.onPinch.bind(this),this.body.eventListeners.onMouseMove=this.onMouseMove.bind(this),this.body.eventListeners.onRelease=this.onRelease.bind(this),this.body.eventListeners.onContext=this.onContext.bind(this),this.touchTime=0,this.drag={},this.pinch={},this.popup=void 0,this.popupObj=void 0,this.popupTimer=void 0,this.body.functions.getPointer=this.getPointer.bind(this),this.options={},this.defaultOptions={dragNodes:!0,dragView:!0,hover:!1,keyboard:{enabled:!1,speed:{x:10,y:10,zoom:.02},bindToWindow:!0,autoFocus:!0},navigationButtons:!1,tooltipDelay:300,zoomView:!0,zoomSpeed:1},Object.assign(this.options,this.defaultOptions),this.bindEventListeners()}bindEventListeners(){this.body.emitter.on("destroy",()=>{clearTimeout(this.popupTimer),delete this.body.functions.getPointer})}setOptions(e){e!==void 0&&(bt(["hideEdgesOnDrag","hideEdgesOnZoom","hideNodesOnDrag","keyboard","multiselect","selectable","selectConnectedEdges"],this.options,e),ae(this.options,e,"keyboard"),e.tooltip&&(Object.assign(this.options.tooltip,e.tooltip),e.tooltip.color&&(this.options.tooltip.color=Lt(e.tooltip.color)))),this.navigationHandler.setOptions(this.options)}getPointer(e){return{x:e.x-As(this.canvas.frame.canvas),y:e.y-zs(this.canvas.frame.canvas)}}onTouch(e){new Date().valueOf()-this.touchTime>50&&(this.drag.pointer=this.getPointer(e.center),this.drag.pinched=!1,this.pinch.scale=this.body.view.scale,this.touchTime=new Date().valueOf())}onTap(e){let t=this.getPointer(e.center),i=this.selectionHandler.options.multiselect&&(e.changedPointers[0].ctrlKey||e.changedPointers[0].metaKey);this.checkSelectionChanges(t,i),this.selectionHandler.commitAndEmit(t,e),this.selectionHandler.generateClickEvent("click",e,t)}onDoubleTap(e){let t=this.getPointer(e.center);this.selectionHandler.generateClickEvent("doubleClick",e,t)}onHold(e){let t=this.getPointer(e.center),i=this.selectionHandler.options.multiselect;this.checkSelectionChanges(t,i),this.selectionHandler.commitAndEmit(t,e),this.selectionHandler.generateClickEvent("click",e,t),this.selectionHandler.generateClickEvent("hold",e,t)}onRelease(e){if(new Date().valueOf()-this.touchTime>10){let t=this.getPointer(e.center);this.selectionHandler.generateClickEvent("release",e,t),this.touchTime=new Date().valueOf()}}onContext(e){let t=this.getPointer({x:e.clientX,y:e.clientY});this.selectionHandler.generateClickEvent("oncontext",e,t)}checkSelectionChanges(e,t=!1){t===!0?this.selectionHandler.selectAdditionalOnPoint(e):this.selectionHandler.selectOnPoint(e)}_determineDifference(e,t){let i=function(s,o){let r=[];for(let a=0;a{let a=r.node;r.xFixed===!1&&(a.x=this.canvas._XconvertDOMtoCanvas(this.canvas._XconvertCanvasToDOM(r.x)+s)),r.yFixed===!1&&(a.y=this.canvas._YconvertDOMtoCanvas(this.canvas._YconvertCanvasToDOM(r.y)+o))}),this.body.emitter.emit("startSimulation")}else{if(e.srcEvent.shiftKey){if(this.selectionHandler.generateClickEvent("dragging",e,t,void 0,!0),this.drag.pointer===void 0){this.onDragStart(e);return}this.body.selectionBox.position.end={x:this.canvas._XconvertDOMtoCanvas(t.x),y:this.canvas._YconvertDOMtoCanvas(t.y)},this.body.emitter.emit("_requestRedraw")}if(this.options.dragView===!0&&!e.srcEvent.shiftKey){if(this.selectionHandler.generateClickEvent("dragging",e,t,void 0,!0),this.drag.pointer===void 0){this.onDragStart(e);return}let s=t.x-this.drag.pointer.x,o=t.y-this.drag.pointer.y;this.body.view.translation={x:this.drag.translation.x+s,y:this.drag.translation.y+o},this.body.emitter.emit("_requestRedraw")}}}onDragEnd(e){if(this.drag.dragging=!1,this.body.selectionBox.show){this.body.selectionBox.show=!1;let t=this.body.selectionBox.position,i={minX:Math.min(t.start.x,t.end.x),minY:Math.min(t.start.y,t.end.y),maxX:Math.max(t.start.x,t.end.x),maxY:Math.max(t.start.y,t.end.y)};this.body.nodeIndices.filter(r=>{let a=this.body.nodes[r];return a.x>=i.minX&&a.x<=i.maxX&&a.y>=i.minY&&a.y<=i.maxY}).forEach(r=>this.selectionHandler.selectObject(this.body.nodes[r]));let o=this.getPointer(e.center);this.selectionHandler.commitAndEmit(o,e),this.selectionHandler.generateClickEvent("dragEnd",e,this.getPointer(e.center),void 0,!0),this.body.emitter.emit("_requestRedraw")}else{let t=this.drag.selection;t&&t.length?(t.forEach(function(i){i.node.options.fixed.x=i.xFixed,i.node.options.fixed.y=i.yFixed}),this.selectionHandler.generateClickEvent("dragEnd",e,this.getPointer(e.center)),this.body.emitter.emit("startSimulation")):(this.selectionHandler.generateClickEvent("dragEnd",e,this.getPointer(e.center),void 0,!0),this.body.emitter.emit("_requestRedraw"))}}onPinch(e){let t=this.getPointer(e.center);this.drag.pinched=!0,this.pinch.scale===void 0&&(this.pinch.scale=1);let i=this.pinch.scale*e.scale;this.zoom(i,t)}zoom(e,t){if(this.options.zoomView===!0){let i=this.body.view.scale;e<1e-5&&(e=1e-5),e>10&&(e=10);let s;this.drag!==void 0&&this.drag.dragging===!0&&(s=this.canvas.DOMtoCanvas(this.drag.pointer));let o=this.body.view.translation,r=e/i,a=(1-r)*t.x+o.x*r,d=(1-r)*t.y+o.y*r;if(this.body.view.scale=e,this.body.view.translation={x:a,y:d},s!=null){let h=this.canvas.canvasToDOM(s);this.drag.pointer.x=h.x,this.drag.pointer.y=h.y}this.body.emitter.emit("_requestRedraw"),ithis._checkShowPopup(t),this.options.tooltipDelay))),this.options.hover===!0&&this.selectionHandler.hoverObject(e,t)}_checkShowPopup(e){let t=this.canvas._XconvertDOMtoCanvas(e.x),i=this.canvas._YconvertDOMtoCanvas(e.y),s={left:t,top:i,right:t,bottom:i},o=this.popupObj===void 0?void 0:this.popupObj.id,r=!1,a="node";if(this.popupObj===void 0){let d=this.body.nodeIndices,h=this.body.nodes,l,c=[];for(let u=0;u0&&(this.popupObj=h[c[c.length-1]],r=!0)}if(this.popupObj===void 0&&r===!1){let d=this.body.edgeIndices,h=this.body.edges,l,c=[];for(let u=0;u0&&(this.popupObj=h[c[c.length-1]],a="edge")}this.popupObj!==void 0?this.popupObj.id!==o&&(this.popup===void 0&&(this.popup=new Zs(this.canvas.frame)),this.popup.popupTargetType=a,this.popup.popupTargetId=this.popupObj.id,this.popup.setPosition(e.x+3,e.y-5),this.popup.setText(this.popupObj.getTitle()),this.popup.show(),this.body.emitter.emit("showPopup",this.popupObj.id)):this.popup!==void 0&&(this.popup.hide(),this.body.emitter.emit("hidePopup"))}_checkHidePopup(e){let t=this.selectionHandler._pointerToPositionObject(e),i=!1;if(this.popup.popupTargetType==="node"){if(this.body.nodes[this.popup.popupTargetId]!==void 0&&(i=this.body.nodes[this.popup.popupTargetId].isOverlappingWith(t),i===!0)){let s=this.selectionHandler.getNodeAt(e);i=s===void 0?!1:s.id===this.popup.popupTargetId}}else this.selectionHandler.getNodeAt(e)===void 0&&this.body.edges[this.popup.popupTargetId]!==void 0&&(i=this.body.edges[this.popup.popupTargetId].isOverlappingWith(t));i===!1&&(this.popupObj=void 0,this.popup.hide(),this.body.emitter.emit("hidePopup"))}};function q(n,e,t,i){if(t==="a"&&!i)throw new TypeError("Private accessor was defined without a getter");if(typeof e=="function"?n!==e||!i:!e.has(n))throw new TypeError("Cannot read private member from an object whose class did not declare it");return t==="m"?i:t==="a"?i.call(n):i?i.value:e.get(n)}function Ri(n,e,t,i,s){if(i==="m")throw new TypeError("Private method is not writable");if(i==="a"&&!s)throw new TypeError("Private accessor was defined without a setter");if(typeof e=="function"?n!==e||!s:!e.has(n))throw new TypeError("Cannot write private member to an object whose class did not declare it");return i==="a"?s.call(n,t):s?s.value=t:e.set(n,t),t}var Xe,ce,Fe,Ne,$t;function bn(n,e){let t=new Set;for(let i of e)n.has(i)||t.add(i);return t}var Hi=class{constructor(){Xe.set(this,new Set),ce.set(this,new Set)}get size(){return q(this,ce,"f").size}add(...e){for(let t of e)q(this,ce,"f").add(t)}delete(...e){for(let t of e)q(this,ce,"f").delete(t)}clear(){q(this,ce,"f").clear()}getSelection(){return[...q(this,ce,"f")]}getChanges(){return{added:[...bn(q(this,Xe,"f"),q(this,ce,"f"))],deleted:[...bn(q(this,ce,"f"),q(this,Xe,"f"))],previous:[...new Set(q(this,Xe,"f"))],current:[...new Set(q(this,ce,"f"))]}}commit(){let e=this.getChanges();Ri(this,Xe,q(this,ce,"f"),"f"),Ri(this,ce,new Set(q(this,Xe,"f")),"f");for(let t of e.added)t.select();for(let t of e.deleted)t.unselect();return e}};Xe=new WeakMap,ce=new WeakMap;var vn=class{constructor(e=()=>{}){Fe.set(this,new Hi),Ne.set(this,new Hi),$t.set(this,void 0),Ri(this,$t,e,"f")}get sizeNodes(){return q(this,Fe,"f").size}get sizeEdges(){return q(this,Ne,"f").size}getNodes(){return q(this,Fe,"f").getSelection()}getEdges(){return q(this,Ne,"f").getSelection()}addNodes(...e){q(this,Fe,"f").add(...e)}addEdges(...e){q(this,Ne,"f").add(...e)}deleteNodes(e){q(this,Fe,"f").delete(e)}deleteEdges(e){q(this,Ne,"f").delete(e)}clear(){q(this,Fe,"f").clear(),q(this,Ne,"f").clear()}commit(...e){let t={nodes:q(this,Fe,"f").commit(),edges:q(this,Ne,"f").commit()};return q(this,$t,"f").call(this,t,...e),t}};Fe=new WeakMap,Ne=new WeakMap,$t=new WeakMap;var wn=class{constructor(e,t){this.body=e,this.canvas=t,this._selectionAccumulator=new vn,this.hoverObj={nodes:{},edges:{}},this.options={},this.defaultOptions={multiselect:!1,selectable:!0,selectConnectedEdges:!0,hoverConnectedEdges:!0},Object.assign(this.options,this.defaultOptions),this.body.emitter.on("_dataChanged",()=>{this.updateSelection()})}setOptions(e){e!==void 0&&qe(["multiselect","hoverConnectedEdges","selectable","selectConnectedEdges"],this.options,e)}selectOnPoint(e){let t=!1;if(this.options.selectable===!0){let i=this.getNodeAt(e)||this.getEdgeAt(e);this.unselectAll(),i!==void 0&&(t=this.selectObject(i)),this.body.emitter.emit("_requestRedraw")}return t}selectAdditionalOnPoint(e){let t=!1;if(this.options.selectable===!0){let i=this.getNodeAt(e)||this.getEdgeAt(e);i!==void 0&&(t=!0,i.isSelected()===!0?this.deselectObject(i):this.selectObject(i),this.body.emitter.emit("_requestRedraw"))}return t}_initBaseEvent(e,t){let i={};return i.pointer={DOM:{x:t.x,y:t.y},canvas:this.canvas.DOMtoCanvas(t)},i.event=e,i}generateClickEvent(e,t,i,s,o=!1){let r=this._initBaseEvent(t,i);if(o===!0)r.nodes=[],r.edges=[];else{let a=this.getSelection();r.nodes=a.nodes,r.edges=a.edges}s!==void 0&&(r.previousSelection=s),e=="click"&&(r.items=this.getClickedItems(i)),t.controlEdge!==void 0&&(r.controlEdge=t.controlEdge),this.body.emitter.emit(e,r)}selectObject(e,t=this.options.selectConnectedEdges){return e!==void 0?(e instanceof U?(t===!0&&this._selectionAccumulator.addEdges(...e.edges),this._selectionAccumulator.addNodes(e)):this._selectionAccumulator.addEdges(e),!0):!1}deselectObject(e){e.isSelected()===!0&&(e.selected=!1,this._removeFromSelection(e))}_getAllNodesOverlappingWith(e){let t=[],i=this.body.nodes;for(let s=0;s0)return t===!0?this.body.nodes[s[s.length-1]]:s[s.length-1]}_getEdgesOverlappingWith(e,t){let i=this.body.edges;for(let s=0;s0&&(this.generateClickEvent("deselectEdge",t,e,o),i=!0),s.nodes.deleted.length>0&&(this.generateClickEvent("deselectNode",t,e,o),i=!0),s.nodes.added.length>0&&(this.generateClickEvent("selectNode",t,e),i=!0),s.edges.added.length>0&&(this.generateClickEvent("selectEdge",t,e),i=!0),i===!0&&this.generateClickEvent("select",t,e)}getSelection(){return{nodes:this.getSelectedNodeIds(),edges:this.getSelectedEdgeIds()}}getSelectedNodes(){return this._selectionAccumulator.getNodes()}getSelectedEdges(){return this._selectionAccumulator.getEdges()}getSelectedNodeIds(){return this._selectionAccumulator.getNodes().map(e=>e.id)}getSelectedEdgeIds(){return this._selectionAccumulator.getEdges().map(e=>e.id)}setSelection(e,t={}){if(!e||!e.nodes&&!e.edges)throw new TypeError("Selection must be an object with nodes and/or edges properties");if((t.unselectAll||t.unselectAll===void 0)&&this.unselectAll(),e.nodes)for(let i of e.nodes){let s=this.body.nodes[i];if(!s)throw new RangeError('Node with id "'+i+'" not found');this.selectObject(s,t.highlightEdges)}if(e.edges)for(let i of e.edges){let s=this.body.edges[i];if(!s)throw new RangeError('Edge with id "'+i+'" not found');this.selectObject(s)}this.body.emitter.emit("_requestRedraw"),this._selectionAccumulator.commit()}selectNodes(e,t=!0){if(!e||e.length===void 0)throw"Selection must be an array with ids";this.setSelection({nodes:e},{highlightEdges:t})}selectEdges(e){if(!e||e.length===void 0)throw"Selection must be an array with ids";this.setSelection({edges:e})}updateSelection(){for(let e in this._selectionAccumulator.getNodes())Object.prototype.hasOwnProperty.call(this.body.nodes,e.id)||this._selectionAccumulator.deleteNodes(e);for(let e in this._selectionAccumulator.getEdges())Object.prototype.hasOwnProperty.call(this.body.edges,e.id)||this._selectionAccumulator.deleteEdges(e)}getClickedItems(e){let t=this.canvas.DOMtoCanvas(e),i=[],s=this.body.nodeIndices,o=this.body.nodes;for(let d=s.length-1;d>=0;d--){let l=o[s[d]].getItemsOnPoint(t);i.push.apply(i,l)}let r=this.body.edgeIndices,a=this.body.edges;for(let d=r.length-1;d>=0;d--){let l=a[r[d]].getItemsOnPoint(t);i.push.apply(i,l)}return i}},ji=class{abstract(){throw new Error("Can't instantiate abstract class!")}fake_use(){}curveType(){return this.abstract()}getPosition(e){return this.fake_use(e),this.abstract()}setPosition(e,t,i=void 0){this.fake_use(e,t,i),this.abstract()}getTreeSize(e){return this.fake_use(e),this.abstract()}sort(e){this.fake_use(e),this.abstract()}fix(e,t){this.fake_use(e,t),this.abstract()}shift(e,t){this.fake_use(e,t),this.abstract()}},_n=class extends ji{constructor(e){super();this.layout=e}curveType(){return"horizontal"}getPosition(e){return e.x}setPosition(e,t,i=void 0){i!==void 0&&this.layout.hierarchical.addToOrdering(e,i),e.x=t}getTreeSize(e){let t=this.layout.hierarchical.getTreeSize(this.layout.body.nodes,e);return{min:t.min_x,max:t.max_x}}sort(e){(0,Et.sort)(e,function(t,i){return t.x-i.x})}fix(e,t){e.y=this.layout.options.hierarchical.levelSeparation*t,e.options.fixed.y=!0}shift(e,t){this.layout.body.nodes[e].x+=t}},En=class extends ji{constructor(e){super();this.layout=e}curveType(){return"vertical"}getPosition(e){return e.y}setPosition(e,t,i=void 0){i!==void 0&&this.layout.hierarchical.addToOrdering(e,i),e.y=t}getTreeSize(e){let t=this.layout.hierarchical.getTreeSize(this.layout.body.nodes,e);return{min:t.min_y,max:t.max_y}}sort(e){(0,Et.sort)(e,function(t,i){return t.y-i.y})}fix(e,t){e.x=this.layout.options.hierarchical.levelSeparation*t,e.options.fixed.x=!0}shift(e,t){this.layout.body.nodes[e].y+=t}};function Oa(n,e){let t=new Set;return n.forEach(i=>{i.edges.forEach(s=>{s.connected&&t.add(s)})}),t.forEach(i=>{let s=i.from.id,o=i.to.id;e[s]==null&&(e[s]=0),(e[o]==null||e[s]>=e[o])&&(e[o]=e[s]+1)}),e}function Ia(n){return xn(e=>e.edges.filter(t=>n.has(t.toId)).every(t=>t.to===e),(e,t)=>t>e,"from",n)}function Pa(n){return xn(e=>e.edges.filter(t=>n.has(t.toId)).every(t=>t.from===e),(e,t)=>td+1+h.edges.length,0),r=t+"Id",a=t==="to"?1:-1;for(let[d,h]of i){if(!i.has(d)||!n(h))continue;s[d]=0;let l=[h],c=0,u;for(;u=l.pop();){if(!i.has(d))continue;let p=s[u.id]+a;if(u.edges.filter(b=>b.connected&&b.to!==b.from&&b[t]!==u&&i.has(b.toId)&&i.has(b.fromId)).forEach(b=>{let C=b[r],f=s[C];(f==null||e(p,f))&&(s[C]=p,l.push(b[t]))}),c>o)return Oa(i,s);++c}}return s}var Cn=class{constructor(){this.childrenReference={},this.parentReference={},this.trees={},this.distributionOrdering={},this.levels={},this.distributionIndex={},this.isTree=!1,this.treeIndex=-1}addRelation(e,t){this.childrenReference[e]===void 0&&(this.childrenReference[e]=[]),this.childrenReference[e].push(t),this.parentReference[t]===void 0&&(this.parentReference[t]=[]),this.parentReference[t].push(e)}checkIfTree(){for(let e in this.parentReference)if(this.parentReference[e].length>1){this.isTree=!1;return}this.isTree=!0}numTrees(){return this.treeIndex+1}setTreeIndex(e,t){t!==void 0&&this.trees[e.id]===void 0&&(this.trees[e.id]=t,this.treeIndex=Math.max(t,this.treeIndex))}ensureLevel(e){this.levels[e]===void 0&&(this.levels[e]=0)}getMaxLevel(e){let t={},i=s=>{if(t[s]!==void 0)return t[s];let o=this.levels[s];if(this.childrenReference[s]){let r=this.childrenReference[s];if(r.length>0)for(let a=0;a{this.setupHierarchicalLayout()}),this.body.emitter.on("_dataLoaded",()=>{this.layoutNetwork()}),this.body.emitter.on("_resetHierarchicalLayout",()=>{this.setupHierarchicalLayout()}),this.body.emitter.on("_adjustEdgesForHierarchicalLayout",()=>{if(this.options.hierarchical.enabled!==!0)return;let e=this.direction.curveType();this.body.emitter.emit("_forceDisableDynamicCurves",e,!1)})}setOptions(e,t){if(e!==void 0){let i=this.options.hierarchical,s=i.enabled;if(qe(["randomSeed","improvedLayout","clusterThreshold"],this.options,e),ae(this.options,e,"hierarchical"),e.randomSeed!==void 0&&this._resetRNG(e.randomSeed),i.enabled===!0)return s===!0&&this.body.emitter.emit("refresh",!0),i.direction==="RL"||i.direction==="DU"?i.levelSeparation>0&&(i.levelSeparation*=-1):i.levelSeparation<0&&(i.levelSeparation*=-1),this.setDirectionStrategy(),this.body.emitter.emit("_resetHierarchicalLayout"),this.adaptAllOptionsForHierarchicalLayout(t);if(s===!0)return this.body.emitter.emit("refresh"),j(t,this.optionsBackup)}return t}_resetRNG(e){this.initialRandomSeed=e,this._rng=yt(this.initialRandomSeed)}adaptAllOptionsForHierarchicalLayout(e){if(this.options.hierarchical.enabled===!0){let t=this.optionsBackup.physics;e.physics===void 0||e.physics===!0?(e.physics={enabled:t.enabled===void 0?!0:t.enabled,solver:"hierarchicalRepulsion"},t.enabled=t.enabled===void 0?!0:t.enabled,t.solver=t.solver||"barnesHut"):typeof e.physics=="object"?(t.enabled=e.physics.enabled===void 0?!0:e.physics.enabled,t.solver=e.physics.solver||"barnesHut",e.physics.solver="hierarchicalRepulsion"):e.physics!==!1&&(t.solver="barnesHut",e.physics={solver:"hierarchicalRepulsion"});let i=this.direction.curveType();if(e.edges===void 0)this.optionsBackup.edges={smooth:{enabled:!0,type:"dynamic"}},e.edges={smooth:!1};else if(e.edges.smooth===void 0)this.optionsBackup.edges={smooth:{enabled:!0,type:"dynamic"}},e.edges.smooth=!1;else if(typeof e.edges.smooth=="boolean")this.optionsBackup.edges={smooth:e.edges.smooth},e.edges.smooth={enabled:e.edges.smooth,type:i};else{let s=e.edges.smooth;s.type!==void 0&&s.type!=="dynamic"&&(i=s.type),this.optionsBackup.edges={smooth:{enabled:s.enabled===void 0?!0:s.enabled,type:s.type===void 0?"dynamic":s.type,roundness:s.roundness===void 0?.5:s.roundness,forceDirection:s.forceDirection===void 0?!1:s.forceDirection}},e.edges.smooth={enabled:s.enabled===void 0?!0:s.enabled,type:i,roundness:s.roundness===void 0?.5:s.roundness,forceDirection:s.forceDirection===void 0?!1:s.forceDirection}}this.body.emitter.emit("_forceDisableDynamicCurves",i)}return e}positionInitially(e){if(this.options.hierarchical.enabled!==!0){this._resetRNG(this.initialRandomSeed);let t=e.length+50;for(let i=0;io){let d=e.length;for(;e.length>o&&s<=i;){s+=1;let h=e.length;s%3==0?this.body.modules.clustering.clusterBridges(r):this.body.modules.clustering.clusterOutliers(r);let l=e.length;if(h==l&&s%3!=0){this._declusterAll(),this.body.emitter.emit("_layoutFailed"),console.info("This network could not be positioned by this version of the improved layout algorithm. Please disable improvedLayout for better performance.");return}}this.body.modules.kamadaKawai.setOptions({springLength:Math.max(150,2*d)})}s>i&&console.info("The clustering didn't succeed within the amount of interations allowed, progressing with partial result."),this.body.modules.kamadaKawai.solve(e,this.body.edgeIndices,!0),this._shiftToCenter();let a=70;for(let d=0;d0){let e,t,i=!1,s=!1;this.lastNodeOnLevel={},this.hierarchical=new Cn;for(t in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&(e=this.body.nodes[t],e.options.level!==void 0?(i=!0,this.hierarchical.levels[t]=e.options.level):s=!0);if(s===!0&&i===!0)throw new Error("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");{if(s===!0){let r=this.options.hierarchical.sortMethod;r==="hubsize"?this._determineLevelsByHubsize():r==="directed"?this._determineLevelsDirected():r==="custom"&&this._determineLevelsCustomCallback()}for(let r in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,r)&&this.hierarchical.ensureLevel(r);let o=this._getDistribution();this._generateMap(),this._placeNodesByHierarchy(o),this._condenseHierarchy(),this._shiftToCenter()}}}_condenseHierarchy(){let e=!1,t={},i=()=>{let f=o(),g=0;for(let m=0;m{let m=this.hierarchical.trees;for(let v in m)Object.prototype.hasOwnProperty.call(m,v)&&m[v]===f&&this.direction.shift(v,g)},o=()=>{let f=[];for(let g=0;g{if(!g[f.id]&&(g[f.id]=!0,this.hierarchical.childrenReference[f.id])){let m=this.hierarchical.childrenReference[f.id];if(m.length>0)for(let v=0;v{let m=1e9,v=1e9,_=1e9,E=-1e9;for(let T in f)if(Object.prototype.hasOwnProperty.call(f,T)){let x=this.body.nodes[T],w=this.hierarchical.levels[x.id],k=this.direction.getPosition(x),[N,W]=this._getSpaceAroundNode(x,f);m=Math.min(N,m),v=Math.min(W,v),w<=g&&(_=Math.min(k,_),E=Math.max(k,E))}return[_,E,m,v]},d=(f,g)=>{let m=this.hierarchical.getMaxLevel(f.id),v=this.hierarchical.getMaxLevel(g.id);return Math.min(m,v)},h=(f,g,m)=>{let v=this.hierarchical;for(let _=0;_1)for(let x=0;x{let v=this.direction.getPosition(f),_=this.direction.getPosition(g),E=Math.abs(_-v),T=this.options.hierarchical.nodeSpacing;if(E>T){let x={},w={};r(f,x),r(g,w);let k=d(f,g),N=a(x,k),W=a(w,k),L=N[1],R=W[0],B=W[2];if(Math.abs(L-R)>T){let D=L-R+T;D<-B+T&&(D=-B+T),D<0&&(this._shiftBlock(g.id,D),e=!0,m===!0&&this._centerParent(g))}}},c=(f,g)=>{let m=g.id,v=g.edges,_=this.hierarchical.levels[g.id],E=this.options.hierarchical.levelSeparation*this.options.hierarchical.levelSeparation,T={},x=[];for(let B=0;B{let D=0;for(let H=0;H{let D=0;for(let H=0;H{let D=this.direction.getPosition(g),H={};for(let Y=0;Y{let F=this.direction.getPosition(g);if(t[g.id]===void 0){let ot={};r(g,ot),t[g.id]=ot}let D=a(t[g.id]),H=D[2],Y=D[3],ue=B-F,Ke=0;ue>0?Ke=Math.min(ue,Y-this.options.hierarchical.nodeSpacing):ue<0&&(Ke=-Math.min(-ue,H-this.options.hierarchical.nodeSpacing)),Ke!=0&&(this._shiftBlock(g.id,Ke),e=!0)},L=B=>{let F=this.direction.getPosition(g),[D,H]=this._getSpaceAroundNode(g),Y=B-F,ue=F;Y>0?ue=Math.min(F+(H-this.options.hierarchical.nodeSpacing),B):Y<0&&(ue=Math.max(F-(D-this.options.hierarchical.nodeSpacing),B)),ue!==F&&(this.direction.setPosition(g,ue),e=!0)},R=N(f,x);W(R),R=N(f,v),L(R)},u=f=>{let g=this.hierarchical.getLevels();g=g.reverse();for(let m=0;m{let g=this.hierarchical.getLevels();g=g.reverse();for(let m=0;m{for(let f in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,f)&&this._centerParent(this.body.nodes[f])},C=()=>{let f=this.hierarchical.getLevels();f=f.reverse();for(let g=0;g0&&Math.abs(c)0&&(d=this.direction.getPosition(i[o-1])+a),this.direction.setPosition(r,d,t),this._validatePositionAndContinue(r,t,d),s++}}}}_placeBranchNodes(e,t){let i=this.hierarchical.childrenReference[e];if(i===void 0)return;let s=[];for(let r=0;rt&&this.positionedNodes[a.id]===void 0){let h=this.options.hierarchical.nodeSpacing,l;r===0?l=this.direction.getPosition(this.body.nodes[e]):l=this.direction.getPosition(s[r-1])+h,this.direction.setPosition(a,l,d),this._validatePositionAndContinue(a,d,l)}else return}let o=this._getCenterPosition(s);this.direction.setPosition(this.body.nodes[e],o,t)}_validatePositionAndContinue(e,t,i){if(!!this.hierarchical.isTree){if(this.lastNodeOnLevel[t]!==void 0){let s=this.direction.getPosition(this.body.nodes[this.lastNodeOnLevel[t]]);if(i-s{this.body.edgeIndices.indexOf(i.id)!==-1&&t.push(i)}),t}_getHubSizes(){let e={},t=this.body.nodeIndices;A(t,s=>{let o=this.body.nodes[s],r=this._getActiveEdges(o).length;e[r]=!0});let i=[];return A(e,s=>{i.push(Number(s))}),Et.default.sort(i,function(s,o){return o-s}),i}_determineLevelsByHubsize(){let e=(i,s)=>{this.hierarchical.levelDownstream(i,s)},t=this._getHubSizes();for(let i=0;i{let r=this.body.nodes[o];s===this._getActiveEdges(r).length&&this._crawlNetwork(e,o)})}}_determineLevelsCustomCallback(){let e=1e5,t=function(s,o,r){},i=(s,o,r)=>{let a=this.hierarchical.levels[s.id];a===void 0&&(a=this.hierarchical.levels[s.id]=e);let d=t(J.cloneOptions(s,"node"),J.cloneOptions(o,"node"),J.cloneOptions(r,"edge"));this.hierarchical.levels[o.id]=a+d};this._crawlNetwork(i),this.hierarchical.setMinLevelToZero(this.body.nodes)}_determineLevelsDirected(){let e=this.body.nodeIndices.reduce((t,i)=>(t.set(i,this.body.nodes[i]),t),new Map);this.options.hierarchical.shakeTowards==="roots"?this.hierarchical.levels=Pa(e):this.hierarchical.levels=Ia(e),this.hierarchical.setMinLevelToZero(this.body.nodes)}_generateMap(){let e=(t,i)=>{this.hierarchical.levels[i.id]>this.hierarchical.levels[t.id]&&this.hierarchical.addRelation(t.id,i.id)};this._crawlNetwork(e),this.hierarchical.checkIfTree()}_crawlNetwork(e=function(){},t){let i={},s=(o,r)=>{if(i[o.id]===void 0){this.hierarchical.setTreeIndex(o,r),i[o.id]=!0;let a,d=this._getActiveEdges(o);for(let h=0;h{if(i[o])return;i[o]=!0,this.direction.shift(o,t);let r=this.hierarchical.childrenReference[o];if(r!==void 0)for(let a=0;a{let d=this.hierarchical.parentReference[a];if(d!==void 0)for(let h=0;h{let d=this.hierarchical.parentReference[a];if(d!==void 0)for(let h=0;h{this._clean()}),this.body.emitter.on("_dataChanged",this._restore.bind(this)),this.body.emitter.on("_resetData",this._restore.bind(this))}_restore(){this.inMode!==!1&&(this.options.initiallyActive===!0?this.enableEditMode():this.disableEditMode())}setOptions(e,t,i){t!==void 0&&(t.locale!==void 0?this.options.locale=t.locale:this.options.locale=i.locale,t.locales!==void 0?this.options.locales=t.locales:this.options.locales=i.locales),e!==void 0&&(typeof e=="boolean"?this.options.enabled=e:(this.options.enabled=!0,j(this.options,e)),this.options.initiallyActive===!0&&(this.editMode=!0),this._setup())}toggleEditMode(){this.editMode===!0?this.disableEditMode():this.enableEditMode()}enableEditMode(){this.editMode=!0,this._clean(),this.guiEnabled===!0&&(this.manipulationDiv.style.display="block",this.closeDiv.style.display="block",this.editModeDiv.style.display="none",this.showManipulatorToolbar())}disableEditMode(){this.editMode=!1,this._clean(),this.guiEnabled===!0&&(this.manipulationDiv.style.display="none",this.closeDiv.style.display="none",this.editModeDiv.style.display="block",this._createEditButton())}showManipulatorToolbar(){if(this._clean(),this.manipulationDOM={},this.guiEnabled===!0){this.editMode=!0,this.manipulationDiv.style.display="block",this.closeDiv.style.display="block";let e=this.selectionHandler.getSelectedNodeCount(),t=this.selectionHandler.getSelectedEdgeCount(),i=e+t,s=this.options.locales[this.options.locale],o=!1;this.options.addNode!==!1&&(this._createAddNodeButton(s),o=!0),this.options.addEdge!==!1&&(o===!0?this._createSeperator(1):o=!0,this._createAddEdgeButton(s)),e===1&&typeof this.options.editNode=="function"?(o===!0?this._createSeperator(2):o=!0,this._createEditNodeButton(s)):t===1&&e===0&&this.options.editEdge!==!1&&(o===!0?this._createSeperator(3):o=!0,this._createEditEdgeButton(s)),i!==0&&(e>0&&this.options.deleteNode!==!1?(o===!0&&this._createSeperator(4),this._createDeleteButton(s)):e===0&&this.options.deleteEdge!==!1&&(o===!0&&this._createSeperator(4),this._createDeleteButton(s))),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this)),this._temporaryBindEvent("select",this.showManipulatorToolbar.bind(this))}this.body.emitter.emit("_redraw")}addNodeMode(){if(this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="addNode",this.guiEnabled===!0){let e=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(e),this._createSeperator(),this._createDescription(e.addDescription||this.options.locales.en.addDescription),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this))}this._temporaryBindEvent("click",this._performAddNode.bind(this))}editNode(){this.editMode!==!0&&this.enableEditMode(),this._clean();let e=this.selectionHandler.getSelectedNodes()[0];if(e!==void 0)if(this.inMode="editNode",typeof this.options.editNode=="function")if(e.isCluster!==!0){let t=j({},e.options,!1);if(t.x=e.x,t.y=e.y,this.options.editNode.length===2)this.options.editNode(t,i=>{i!=null&&this.inMode==="editNode"&&this.body.data.nodes.getDataSet().update(i),this.showManipulatorToolbar()});else throw new Error("The function for edit does not support two arguments (data, callback)")}else alert(this.options.locales[this.options.locale].editClusterError||this.options.locales.en.editClusterError);else throw new Error("No function has been configured to handle the editing of nodes.");else this.showManipulatorToolbar()}addEdgeMode(){if(this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="addEdge",this.guiEnabled===!0){let e=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(e),this._createSeperator(),this._createDescription(e.edgeDescription||this.options.locales.en.edgeDescription),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this))}this._temporaryBindUI("onTouch",this._handleConnect.bind(this)),this._temporaryBindUI("onDragEnd",this._finishConnect.bind(this)),this._temporaryBindUI("onDrag",this._dragControlNode.bind(this)),this._temporaryBindUI("onRelease",this._finishConnect.bind(this)),this._temporaryBindUI("onDragStart",this._dragStartEdge.bind(this)),this._temporaryBindUI("onHold",()=>{})}editEdgeMode(){if(this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="editEdge",typeof this.options.editEdge=="object"&&typeof this.options.editEdge.editWithoutDrag=="function"&&(this.edgeBeingEditedId=this.selectionHandler.getSelectedEdgeIds()[0],this.edgeBeingEditedId!==void 0)){let e=this.body.edges[this.edgeBeingEditedId];this._performEditEdge(e.from.id,e.to.id);return}if(this.guiEnabled===!0){let e=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(e),this._createSeperator(),this._createDescription(e.editEdgeDescription||this.options.locales.en.editEdgeDescription),this._bindElementEvents(this.closeDiv,this.toggleEditMode.bind(this))}if(this.edgeBeingEditedId=this.selectionHandler.getSelectedEdgeIds()[0],this.edgeBeingEditedId!==void 0){let e=this.body.edges[this.edgeBeingEditedId],t=this._getNewTargetNode(e.from.x,e.from.y),i=this._getNewTargetNode(e.to.x,e.to.y);this.temporaryIds.nodes.push(t.id),this.temporaryIds.nodes.push(i.id),this.body.nodes[t.id]=t,this.body.nodeIndices.push(t.id),this.body.nodes[i.id]=i,this.body.nodeIndices.push(i.id),this._temporaryBindUI("onTouch",this._controlNodeTouch.bind(this)),this._temporaryBindUI("onTap",()=>{}),this._temporaryBindUI("onHold",()=>{}),this._temporaryBindUI("onDragStart",this._controlNodeDragStart.bind(this)),this._temporaryBindUI("onDrag",this._controlNodeDrag.bind(this)),this._temporaryBindUI("onDragEnd",this._controlNodeDragEnd.bind(this)),this._temporaryBindUI("onMouseMove",()=>{}),this._temporaryBindEvent("beforeDrawing",s=>{let o=e.edgeType.findBorderPositions(s);t.selected===!1&&(t.x=o.from.x,t.y=o.from.y),i.selected===!1&&(i.x=o.to.x,i.y=o.to.y)}),this.body.emitter.emit("_redraw")}else this.showManipulatorToolbar()}deleteSelected(){this.editMode!==!0&&this.enableEditMode(),this._clean(),this.inMode="delete";let e=this.selectionHandler.getSelectedNodeIds(),t=this.selectionHandler.getSelectedEdgeIds(),i;if(e.length>0){for(let s=0;s0&&typeof this.options.deleteEdge=="function"&&(i=this.options.deleteEdge);if(typeof i=="function"){let s={nodes:e,edges:t};if(i.length===2)i(s,o=>{o!=null&&this.inMode==="delete"?(this.body.data.edges.getDataSet().remove(o.edges),this.body.data.nodes.getDataSet().remove(o.nodes),this.body.emitter.emit("startSimulation"),this.showManipulatorToolbar()):(this.body.emitter.emit("startSimulation"),this.showManipulatorToolbar())});else throw new Error("The function for delete does not support two arguments (data, callback)")}else this.body.data.edges.getDataSet().remove(t),this.body.data.nodes.getDataSet().remove(e),this.body.emitter.emit("startSimulation"),this.showManipulatorToolbar()}_setup(){this.options.enabled===!0?(this.guiEnabled=!0,this._createWrappers(),this.editMode===!1?this._createEditButton():this.showManipulatorToolbar()):(this._removeManipulationDOM(),this.guiEnabled=!1)}_createWrappers(){var e,t;this.manipulationDiv===void 0&&(this.manipulationDiv=document.createElement("div"),this.manipulationDiv.className="vis-manipulation",this.editMode===!0?this.manipulationDiv.style.display="block":this.manipulationDiv.style.display="none",this.canvas.frame.appendChild(this.manipulationDiv)),this.editModeDiv===void 0&&(this.editModeDiv=document.createElement("div"),this.editModeDiv.className="vis-edit-mode",this.editMode===!0?this.editModeDiv.style.display="none":this.editModeDiv.style.display="block",this.canvas.frame.appendChild(this.editModeDiv)),this.closeDiv===void 0&&(this.closeDiv=document.createElement("button"),this.closeDiv.className="vis-close",this.closeDiv.setAttribute("aria-label",(t=(e=this.options.locales[this.options.locale])==null?void 0:e.close)!=null?t:this.options.locales.en.close),this.closeDiv.style.display=this.manipulationDiv.style.display,this.canvas.frame.appendChild(this.closeDiv))}_getNewTargetNode(e,t){let i=j({},this.options.controlNodeStyle);i.id="targetNode"+Ce(),i.hidden=!1,i.physics=!1,i.x=e,i.y=t;let s=this.body.functions.createNode(i);return s.shape.boundingBox={left:e,right:e,top:t,bottom:t},s}_createEditButton(){this._clean(),this.manipulationDOM={},we(this.editModeDiv);let e=this.options.locales[this.options.locale],t=this._createButton("editMode","vis-edit vis-edit-mode",e.edit||this.options.locales.en.edit);this.editModeDiv.appendChild(t),this._bindElementEvents(t,this.toggleEditMode.bind(this))}_clean(){this.inMode=!1,this.guiEnabled===!0&&(we(this.editModeDiv),we(this.manipulationDiv),this._cleanupDOMEventListeners()),this._cleanupTemporaryNodesAndEdges(),this._unbindTemporaryUIs(),this._unbindTemporaryEvents(),this.body.emitter.emit("restorePhysics")}_cleanupDOMEventListeners(){for(let e of this._domEventListenerCleanupQueue.splice(0))e()}_removeManipulationDOM(){this._clean(),we(this.manipulationDiv),we(this.editModeDiv),we(this.closeDiv),this.manipulationDiv&&this.canvas.frame.removeChild(this.manipulationDiv),this.editModeDiv&&this.canvas.frame.removeChild(this.editModeDiv),this.closeDiv&&this.canvas.frame.removeChild(this.closeDiv),this.manipulationDiv=void 0,this.editModeDiv=void 0,this.closeDiv=void 0}_createSeperator(e=1){this.manipulationDOM["seperatorLineDiv"+e]=document.createElement("div"),this.manipulationDOM["seperatorLineDiv"+e].className="vis-separator-line",this.manipulationDiv.appendChild(this.manipulationDOM["seperatorLineDiv"+e])}_createAddNodeButton(e){let t=this._createButton("addNode","vis-add",e.addNode||this.options.locales.en.addNode);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.addNodeMode.bind(this))}_createAddEdgeButton(e){let t=this._createButton("addEdge","vis-connect",e.addEdge||this.options.locales.en.addEdge);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.addEdgeMode.bind(this))}_createEditNodeButton(e){let t=this._createButton("editNode","vis-edit",e.editNode||this.options.locales.en.editNode);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.editNode.bind(this))}_createEditEdgeButton(e){let t=this._createButton("editEdge","vis-edit",e.editEdge||this.options.locales.en.editEdge);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.editEdgeMode.bind(this))}_createDeleteButton(e){let t;this.options.rtl?t="vis-delete-rtl":t="vis-delete";let i=this._createButton("delete",t,e.del||this.options.locales.en.del);this.manipulationDiv.appendChild(i),this._bindElementEvents(i,this.deleteSelected.bind(this))}_createBackButton(e){let t=this._createButton("back","vis-back",e.back||this.options.locales.en.back);this.manipulationDiv.appendChild(t),this._bindElementEvents(t,this.showManipulatorToolbar.bind(this))}_createButton(e,t,i,s="vis-label"){return this.manipulationDOM[e+"Div"]=document.createElement("button"),this.manipulationDOM[e+"Div"].className="vis-button "+t,this.manipulationDOM[e+"Label"]=document.createElement("div"),this.manipulationDOM[e+"Label"].className=s,this.manipulationDOM[e+"Label"].innerText=i,this.manipulationDOM[e+"Div"].appendChild(this.manipulationDOM[e+"Label"]),this.manipulationDOM[e+"Div"]}_createDescription(e){this.manipulationDOM.descriptionLabel=document.createElement("div"),this.manipulationDOM.descriptionLabel.className="vis-none",this.manipulationDOM.descriptionLabel.innerText=e,this.manipulationDiv.appendChild(this.manipulationDOM.descriptionLabel)}_temporaryBindEvent(e,t){this.temporaryEventFunctions.push({event:e,boundFunction:t}),this.body.emitter.on(e,t)}_temporaryBindUI(e,t){if(this.body.eventListeners[e]!==void 0)this.temporaryUIFunctions[e]=this.body.eventListeners[e],this.body.eventListeners[e]=t;else throw new Error("This UI function does not exist. Typo? You tried: "+e+" possible are: "+JSON.stringify(Object.keys(this.body.eventListeners)))}_unbindTemporaryUIs(){for(let e in this.temporaryUIFunctions)Object.prototype.hasOwnProperty.call(this.temporaryUIFunctions,e)&&(this.body.eventListeners[e]=this.temporaryUIFunctions[e],delete this.temporaryUIFunctions[e]);this.temporaryUIFunctions={}}_unbindTemporaryEvents(){for(let e=0;e{i.destroy()});let s=({keyCode:o,key:r})=>{(r==="Enter"||r===" "||o===13||o===32)&&t()};e.addEventListener("keyup",s,!1),this._domEventListenerCleanupQueue.push(()=>{e.removeEventListener("keyup",s,!1)})}_cleanupTemporaryNodesAndEdges(){for(let e=0;e=0;a--)if(o[a]!==this.selectedControlNode.id){r=this.body.nodes[o[a]];break}if(r!==void 0&&this.selectedControlNode!==void 0)if(r.isCluster===!0)alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError);else{let a=this.body.nodes[this.temporaryIds.nodes[0]];this.selectedControlNode.id===a.id?this._performEditEdge(r.id,s.to.id):this._performEditEdge(s.from.id,r.id)}else s.updateEdgeType(),this.body.emitter.emit("restorePhysics");this.body.emitter.emit("_redraw")}_handleConnect(e){if(new Date().valueOf()-this.touchTime>100){this.lastTouch=this.body.functions.getPointer(e.center),this.lastTouch.translation=Object.assign({},this.body.view.translation),this.interactionHandler.drag.pointer=this.lastTouch,this.interactionHandler.drag.translation=this.lastTouch.translation;let t=this.lastTouch,i=this.selectionHandler.getNodeAt(t);if(i!==void 0)if(i.isCluster===!0)alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError);else{let s=this._getNewTargetNode(i.x,i.y);this.body.nodes[s.id]=s,this.body.nodeIndices.push(s.id);let o=this.body.functions.createEdge({id:"connectionEdge"+Ce(),from:i.id,to:s.id,physics:!1,smooth:{enabled:!0,type:"continuous",roundness:.5}});this.body.edges[o.id]=o,this.body.edgeIndices.push(o.id),this.temporaryIds.nodes.push(s.id),this.temporaryIds.edges.push(o.id)}this.touchTime=new Date().valueOf()}}_dragControlNode(e){let t=this.body.functions.getPointer(e.center),i=this.selectionHandler._pointerToPositionObject(t),s;this.temporaryIds.edges[0]!==void 0&&(s=this.body.edges[this.temporaryIds.edges[0]].fromId);let o=this.selectionHandler._getAllNodesOverlappingWith(i),r;for(let a=o.length-1;a>=0;a--)if(this.temporaryIds.nodes.indexOf(o[a])===-1){r=this.body.nodes[o[a]];break}if(e.controlEdge={from:s,to:r?r.id:void 0},this.selectionHandler.generateClickEvent("controlNodeDragging",e,t),this.temporaryIds.nodes[0]!==void 0){let a=this.body.nodes[this.temporaryIds.nodes[0]];a.x=this.canvas._XconvertDOMtoCanvas(t.x),a.y=this.canvas._YconvertDOMtoCanvas(t.y),this.body.emitter.emit("_redraw")}else this.interactionHandler.onDrag(e)}_finishConnect(e){let t=this.body.functions.getPointer(e.center),i=this.selectionHandler._pointerToPositionObject(t),s;this.temporaryIds.edges[0]!==void 0&&(s=this.body.edges[this.temporaryIds.edges[0]].fromId);let o=this.selectionHandler._getAllNodesOverlappingWith(i),r;for(let a=o.length-1;a>=0;a--)if(this.temporaryIds.nodes.indexOf(o[a])===-1){r=this.body.nodes[o[a]];break}this._cleanupTemporaryNodesAndEdges(),r!==void 0&&(r.isCluster===!0?alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError):this.body.nodes[s]!==void 0&&this.body.nodes[r.id]!==void 0&&this._performAddEdge(s,r.id)),e.controlEdge={from:s,to:r?r.id:void 0},this.selectionHandler.generateClickEvent("controlNodeDragEnd",e,t),this.body.emitter.emit("_redraw")}_dragStartEdge(e){let t=this.lastTouch;this.selectionHandler.generateClickEvent("dragStart",e,t,void 0,!0)}_performAddNode(e){let t={id:Ce(),x:e.pointer.canvas.x,y:e.pointer.canvas.y,label:"new"};if(typeof this.options.addNode=="function")if(this.options.addNode.length===2)this.options.addNode(t,i=>{i!=null&&this.inMode==="addNode"&&this.body.data.nodes.getDataSet().add(i),this.showManipulatorToolbar()});else throw this.showManipulatorToolbar(),new Error("The function for add does not support two arguments (data,callback)");else this.body.data.nodes.getDataSet().add(t),this.showManipulatorToolbar()}_performAddEdge(e,t){let i={from:e,to:t};if(typeof this.options.addEdge=="function")if(this.options.addEdge.length===2)this.options.addEdge(i,s=>{s!=null&&this.inMode==="addEdge"&&(this.body.data.edges.getDataSet().add(s),this.selectionHandler.unselectAll(),this.showManipulatorToolbar())});else throw new Error("The function for connect does not support two arguments (data,callback)");else this.body.data.edges.getDataSet().add(i),this.selectionHandler.unselectAll(),this.showManipulatorToolbar()}_performEditEdge(e,t){let i={id:this.edgeBeingEditedId,from:e,to:t,label:this.body.data.edges.get(this.edgeBeingEditedId).label},s=this.options.editEdge;if(typeof s=="object"&&(s=s.editWithoutDrag),typeof s=="function")if(s.length===2)s(i,o=>{o==null||this.inMode!=="editEdge"?(this.body.edges[i.id].updateEdgeType(),this.body.emitter.emit("_redraw"),this.showManipulatorToolbar()):(this.body.data.edges.getDataSet().update(o),this.selectionHandler.unselectAll(),this.showManipulatorToolbar())});else throw new Error("The function for edit does not support two arguments (data, callback)");else this.body.data.edges.getDataSet().update(i),this.selectionHandler.unselectAll(),this.showManipulatorToolbar()}},O="string",S="boolean",y="number",Tt="array",P="object",Sn="dom",Ma="any",Wi=["arrow","bar","box","circle","crow","curve","diamond","image","inv_curve","inv_triangle","triangle","vee"],Vi={borderWidth:{number:y},borderWidthSelected:{number:y,undefined:"undefined"},brokenImage:{string:O,undefined:"undefined"},chosen:{label:{boolean:S,function:"function"},node:{boolean:S,function:"function"},__type__:{object:P,boolean:S}},color:{border:{string:O},background:{string:O},highlight:{border:{string:O},background:{string:O},__type__:{object:P,string:O}},hover:{border:{string:O},background:{string:O},__type__:{object:P,string:O}},__type__:{object:P,string:O}},opacity:{number:y,undefined:"undefined"},fixed:{x:{boolean:S},y:{boolean:S},__type__:{object:P,boolean:S}},font:{align:{string:O},color:{string:O},size:{number:y},face:{string:O},background:{string:O},strokeWidth:{number:y},strokeColor:{string:O},vadjust:{number:y},multi:{boolean:S,string:O},bold:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},boldital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},ital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},mono:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},__type__:{object:P,string:O}},group:{string:O,number:y,undefined:"undefined"},heightConstraint:{minimum:{number:y},valign:{string:O},__type__:{object:P,boolean:S,number:y}},hidden:{boolean:S},icon:{face:{string:O},code:{string:O},size:{number:y},color:{string:O},weight:{string:O,number:y},__type__:{object:P}},id:{string:O,number:y},image:{selected:{string:O,undefined:"undefined"},unselected:{string:O,undefined:"undefined"},__type__:{object:P,string:O}},imagePadding:{top:{number:y},right:{number:y},bottom:{number:y},left:{number:y},__type__:{object:P,number:y}},label:{string:O,undefined:"undefined"},labelHighlightBold:{boolean:S},level:{number:y,undefined:"undefined"},margin:{top:{number:y},right:{number:y},bottom:{number:y},left:{number:y},__type__:{object:P,number:y}},mass:{number:y},physics:{boolean:S},scaling:{min:{number:y},max:{number:y},label:{enabled:{boolean:S},min:{number:y},max:{number:y},maxVisible:{number:y},drawThreshold:{number:y},__type__:{object:P,boolean:S}},customScalingFunction:{function:"function"},__type__:{object:P}},shadow:{enabled:{boolean:S},color:{string:O},size:{number:y},x:{number:y},y:{number:y},__type__:{object:P,boolean:S}},shape:{string:["custom","ellipse","circle","database","box","text","image","circularImage","diamond","dot","star","triangle","triangleDown","square","icon","hexagon"]},ctxRenderer:{function:"function"},shapeProperties:{borderDashes:{boolean:S,array:Tt},borderRadius:{number:y},interpolation:{boolean:S},useImageSize:{boolean:S},useBorderWithImage:{boolean:S},coordinateOrigin:{string:["center","top-left"]},__type__:{object:P}},size:{number:y},title:{string:O,dom:Sn,undefined:"undefined"},value:{number:y,undefined:"undefined"},widthConstraint:{minimum:{number:y},maximum:{number:y},__type__:{object:P,boolean:S,number:y}},x:{number:y},y:{number:y},__type__:{object:P}},Da={configure:{enabled:{boolean:S},filter:{boolean:S,string:O,array:Tt,function:"function"},container:{dom:Sn},showButton:{boolean:S},__type__:{object:P,boolean:S,string:O,array:Tt,function:"function"}},edges:{arrows:{to:{enabled:{boolean:S},scaleFactor:{number:y},type:{string:Wi},imageHeight:{number:y},imageWidth:{number:y},src:{string:O},__type__:{object:P,boolean:S}},middle:{enabled:{boolean:S},scaleFactor:{number:y},type:{string:Wi},imageWidth:{number:y},imageHeight:{number:y},src:{string:O},__type__:{object:P,boolean:S}},from:{enabled:{boolean:S},scaleFactor:{number:y},type:{string:Wi},imageWidth:{number:y},imageHeight:{number:y},src:{string:O},__type__:{object:P,boolean:S}},__type__:{string:["from","to","middle"],object:P}},endPointOffset:{from:{number:y},to:{number:y},__type__:{object:P,number:y}},arrowStrikethrough:{boolean:S},background:{enabled:{boolean:S},color:{string:O},size:{number:y},dashes:{boolean:S,array:Tt},__type__:{object:P,boolean:S}},chosen:{label:{boolean:S,function:"function"},edge:{boolean:S,function:"function"},__type__:{object:P,boolean:S}},color:{color:{string:O},highlight:{string:O},hover:{string:O},inherit:{string:["from","to","both"],boolean:S},opacity:{number:y},__type__:{object:P,string:O}},dashes:{boolean:S,array:Tt},font:{color:{string:O},size:{number:y},face:{string:O},background:{string:O},strokeWidth:{number:y},strokeColor:{string:O},align:{string:["horizontal","top","middle","bottom"]},vadjust:{number:y},multi:{boolean:S,string:O},bold:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},boldital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},ital:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},mono:{color:{string:O},size:{number:y},face:{string:O},mod:{string:O},vadjust:{number:y},__type__:{object:P,string:O}},__type__:{object:P,string:O}},hidden:{boolean:S},hoverWidth:{function:"function",number:y},label:{string:O,undefined:"undefined"},labelHighlightBold:{boolean:S},length:{number:y,undefined:"undefined"},physics:{boolean:S},scaling:{min:{number:y},max:{number:y},label:{enabled:{boolean:S},min:{number:y},max:{number:y},maxVisible:{number:y},drawThreshold:{number:y},__type__:{object:P,boolean:S}},customScalingFunction:{function:"function"},__type__:{object:P}},selectionWidth:{function:"function",number:y},selfReferenceSize:{number:y},selfReference:{size:{number:y},angle:{number:y},renderBehindTheNode:{boolean:S},__type__:{object:P}},shadow:{enabled:{boolean:S},color:{string:O},size:{number:y},x:{number:y},y:{number:y},__type__:{object:P,boolean:S}},smooth:{enabled:{boolean:S},type:{string:["dynamic","continuous","discrete","diagonalCross","straightCross","horizontal","vertical","curvedCW","curvedCCW","cubicBezier"]},roundness:{number:y},forceDirection:{string:["horizontal","vertical","none"],boolean:S},__type__:{object:P,boolean:S}},title:{string:O,undefined:"undefined"},width:{number:y},widthConstraint:{maximum:{number:y},__type__:{object:P,boolean:S,number:y}},value:{number:y,undefined:"undefined"},__type__:{object:P}},groups:{useDefaultGroups:{boolean:S},__any__:Vi,__type__:{object:P}},interaction:{dragNodes:{boolean:S},dragView:{boolean:S},hideEdgesOnDrag:{boolean:S},hideEdgesOnZoom:{boolean:S},hideNodesOnDrag:{boolean:S},hover:{boolean:S},keyboard:{enabled:{boolean:S},speed:{x:{number:y},y:{number:y},zoom:{number:y},__type__:{object:P}},bindToWindow:{boolean:S},autoFocus:{boolean:S},__type__:{object:P,boolean:S}},multiselect:{boolean:S},navigationButtons:{boolean:S},selectable:{boolean:S},selectConnectedEdges:{boolean:S},hoverConnectedEdges:{boolean:S},tooltipDelay:{number:y},zoomView:{boolean:S},zoomSpeed:{number:y},__type__:{object:P}},layout:{randomSeed:{undefined:"undefined",number:y,string:O},improvedLayout:{boolean:S},clusterThreshold:{number:y},hierarchical:{enabled:{boolean:S},levelSeparation:{number:y},nodeSpacing:{number:y},treeSpacing:{number:y},blockShifting:{boolean:S},edgeMinimization:{boolean:S},parentCentralization:{boolean:S},direction:{string:["UD","DU","LR","RL"]},sortMethod:{string:["hubsize","directed"]},shakeTowards:{string:["leaves","roots"]},__type__:{object:P,boolean:S}},__type__:{object:P}},manipulation:{enabled:{boolean:S},initiallyActive:{boolean:S},addNode:{boolean:S,function:"function"},addEdge:{boolean:S,function:"function"},editNode:{function:"function"},editEdge:{editWithoutDrag:{function:"function"},__type__:{object:P,boolean:S,function:"function"}},deleteNode:{boolean:S,function:"function"},deleteEdge:{boolean:S,function:"function"},controlNodeStyle:Vi,__type__:{object:P,boolean:S}},nodes:Vi,physics:{enabled:{boolean:S},barnesHut:{theta:{number:y},gravitationalConstant:{number:y},centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},damping:{number:y},avoidOverlap:{number:y},__type__:{object:P}},forceAtlas2Based:{theta:{number:y},gravitationalConstant:{number:y},centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},damping:{number:y},avoidOverlap:{number:y},__type__:{object:P}},repulsion:{centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},nodeDistance:{number:y},damping:{number:y},__type__:{object:P}},hierarchicalRepulsion:{centralGravity:{number:y},springLength:{number:y},springConstant:{number:y},nodeDistance:{number:y},damping:{number:y},avoidOverlap:{number:y},__type__:{object:P}},maxVelocity:{number:y},minVelocity:{number:y},solver:{string:["barnesHut","repulsion","hierarchicalRepulsion","forceAtlas2Based"]},stabilization:{enabled:{boolean:S},iterations:{number:y},updateInterval:{number:y},onlyDynamicEdges:{boolean:S},fit:{boolean:S},__type__:{object:P,boolean:S}},timestep:{number:y},adaptiveTimestep:{boolean:S},wind:{x:{number:y},y:{number:y},__type__:{object:P}},__type__:{object:P,boolean:S}},autoResize:{boolean:S},clickToUse:{boolean:S},locale:{string:O},locales:{__any__:{any:Ma},__type__:{object:P}},height:{string:O},width:{string:O},__type__:{object:P}},On={nodes:{borderWidth:[1,0,10,1],borderWidthSelected:[2,0,10,1],color:{border:["color","#2B7CE9"],background:["color","#97C2FC"],highlight:{border:["color","#2B7CE9"],background:["color","#D2E5FF"]},hover:{border:["color","#2B7CE9"],background:["color","#D2E5FF"]}},opacity:[0,0,1,.1],fixed:{x:!1,y:!1},font:{color:["color","#343434"],size:[14,0,100,1],face:["arial","verdana","tahoma"],background:["color","none"],strokeWidth:[0,0,50,1],strokeColor:["color","#ffffff"]},hidden:!1,labelHighlightBold:!0,physics:!0,scaling:{min:[10,0,200,1],max:[30,0,200,1],label:{enabled:!1,min:[14,0,200,1],max:[30,0,200,1],maxVisible:[30,0,200,1],drawThreshold:[5,0,20,1]}},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:[10,0,20,1],x:[5,-30,30,1],y:[5,-30,30,1]},shape:["ellipse","box","circle","database","diamond","dot","square","star","text","triangle","triangleDown","hexagon"],shapeProperties:{borderDashes:!1,borderRadius:[6,0,20,1],interpolation:!0,useImageSize:!1},size:[25,0,200,1]},edges:{arrows:{to:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"},middle:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"},from:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"}},endPointOffset:{from:[0,-10,10,1],to:[0,-10,10,1]},arrowStrikethrough:!0,color:{color:["color","#848484"],highlight:["color","#848484"],hover:["color","#848484"],inherit:["from","to","both",!0,!1],opacity:[1,0,1,.05]},dashes:!1,font:{color:["color","#343434"],size:[14,0,100,1],face:["arial","verdana","tahoma"],background:["color","none"],strokeWidth:[2,0,50,1],strokeColor:["color","#ffffff"],align:["horizontal","top","middle","bottom"]},hidden:!1,hoverWidth:[1.5,0,5,.1],labelHighlightBold:!0,physics:!0,scaling:{min:[1,0,100,1],max:[15,0,100,1],label:{enabled:!0,min:[14,0,200,1],max:[30,0,200,1],maxVisible:[30,0,200,1],drawThreshold:[5,0,20,1]}},selectionWidth:[1.5,0,5,.1],selfReferenceSize:[20,0,200,1],selfReference:{size:[20,0,200,1],angle:[Math.PI/2,-6*Math.PI,6*Math.PI,Math.PI/8],renderBehindTheNode:!0},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:[10,0,20,1],x:[5,-30,30,1],y:[5,-30,30,1]},smooth:{enabled:!0,type:["dynamic","continuous","discrete","diagonalCross","straightCross","horizontal","vertical","curvedCW","curvedCCW","cubicBezier"],forceDirection:["horizontal","vertical","none"],roundness:[.5,0,1,.05]},width:[1,0,30,1]},layout:{hierarchical:{enabled:!1,levelSeparation:[150,20,500,5],nodeSpacing:[100,20,500,5],treeSpacing:[200,20,500,5],blockShifting:!0,edgeMinimization:!0,parentCentralization:!0,direction:["UD","DU","LR","RL"],sortMethod:["hubsize","directed"],shakeTowards:["leaves","roots"]}},interaction:{dragNodes:!0,dragView:!0,hideEdgesOnDrag:!1,hideEdgesOnZoom:!1,hideNodesOnDrag:!1,hover:!1,keyboard:{enabled:!1,speed:{x:[10,0,40,1],y:[10,0,40,1],zoom:[.02,0,.1,.005]},bindToWindow:!0,autoFocus:!0},multiselect:!1,navigationButtons:!1,selectable:!0,selectConnectedEdges:!0,hoverConnectedEdges:!0,tooltipDelay:[300,0,1e3,25],zoomView:!0,zoomSpeed:[1,.1,2,.1]},manipulation:{enabled:!1,initiallyActive:!1},physics:{enabled:!0,barnesHut:{theta:[.5,.1,1,.05],gravitationalConstant:[-2e3,-3e4,0,50],centralGravity:[.3,0,10,.05],springLength:[95,0,500,5],springConstant:[.04,0,1.2,.005],damping:[.09,0,1,.01],avoidOverlap:[0,0,1,.01]},forceAtlas2Based:{theta:[.5,.1,1,.05],gravitationalConstant:[-50,-500,0,1],centralGravity:[.01,0,1,.005],springLength:[95,0,500,5],springConstant:[.08,0,1.2,.005],damping:[.4,0,1,.01],avoidOverlap:[0,0,1,.01]},repulsion:{centralGravity:[.2,0,10,.05],springLength:[200,0,500,5],springConstant:[.05,0,1.2,.005],nodeDistance:[100,0,500,5],damping:[.09,0,1,.01]},hierarchicalRepulsion:{centralGravity:[.2,0,10,.05],springLength:[100,0,500,5],springConstant:[.01,0,1.2,.005],nodeDistance:[120,0,500,5],damping:[.09,0,1,.01],avoidOverlap:[0,0,1,.01]},maxVelocity:[50,0,150,1],minVelocity:[.1,.01,.5,.01],solver:["barnesHut","forceAtlas2Based","repulsion","hierarchicalRepulsion"],timestep:[.5,.01,1,.01],wind:{x:[0,-10,10,.1],y:[0,-10,10,.1]}}},Fa=(n,e,t)=>!!(n.includes("physics")&&On.physics.solver.includes(e)&&t.physics.solver!==e&&e!=="wind");var In=class{constructor(){}getDistances(e,t,i){let s={},o=e.edges;for(let a=0;ao&&ar&&Cthis.body.emitter.emit("_requestRedraw")),this.groups=new xo,this.canvas=new pn(this.body),this.selectionHandler=new wn(this.body,this.canvas),this.interactionHandler=new yn(this.body,this.canvas,this.selectionHandler),this.view=new gn(this.body,this.canvas),this.renderer=new un(this.body,this.canvas),this.physics=new hn(this.body),this.layoutEngine=new Tn(this.body),this.clustering=new cn(this.body),this.manipulation=new kn(this.body,this.canvas,this.selectionHandler,this.interactionHandler),this.nodesHandler=new Wo(this.body,this.images,this.groups,this.layoutEngine),this.edgesHandler=new sn(this.body,this.images,this.groups),this.body.modules.kamadaKawai=new Pn(this.body,150,.05),this.body.modules.clustering=this.clustering,this.canvas._create(),this.setOptions(t),this.setData(e)}(0,no.default)(I.prototype);I.prototype.setOptions=function(n){if(n===null&&(n=void 0),n!==void 0){if(Qs.validate(n,Da)===!0&&console.error("%cErrors have been found in the supplied options object.",_i),qe(["locale","locales","clickToUse"],this.options,n),n.locale!==void 0&&(n.locale=Ca(n.locales||this.options.locales,n.locale)),n=this.layoutEngine.setOptions(n.layout,n),this.canvas.setOptions(n),this.groups.setOptions(n.groups),this.nodesHandler.setOptions(n.nodes),this.edgesHandler.setOptions(n.edges),this.physics.setOptions(n.physics),this.manipulation.setOptions(n.manipulation,n,this.options),this.interactionHandler.setOptions(n.interaction),this.renderer.setOptions(n.interaction),this.selectionHandler.setOptions(n.interaction),n.groups!==void 0&&this.body.emitter.emit("refreshNodes"),"configure"in n&&(this.configurator||(this.configurator=new Ks(this,this.body.container,On,this.canvas.pixelRatio,Fa)),this.configurator.setOptions(n.configure)),this.configurator&&this.configurator.options.enabled===!0){let i={nodes:{},edges:{},layout:{},interaction:{},manipulation:{},physics:{},global:{}};j(i.nodes,this.nodesHandler.options),j(i.edges,this.edgesHandler.options),j(i.layout,this.layoutEngine.options),j(i.interaction,this.selectionHandler.options),j(i.interaction,this.renderer.options),j(i.interaction,this.interactionHandler.options),j(i.manipulation,this.manipulation.options),j(i.physics,this.physics.options),j(i.global,this.canvas.options),j(i.global,this.options),this.configurator.setModuleOptions(i)}n.clickToUse!==void 0?n.clickToUse===!0?this.activator===void 0&&(this.activator=new Gs(this.canvas.frame),this.activator.on("change",()=>{this.body.emitter.emit("activate")})):(this.activator!==void 0&&(this.activator.destroy(),delete this.activator),this.body.emitter.emit("activate")):this.body.emitter.emit("activate"),this.canvas.setSize(),this.body.emitter.emit("startSimulation")}};I.prototype._updateVisibleIndices=function(){let n=this.body.nodes,e=this.body.edges;this.body.nodeIndices=[],this.body.edgeIndices=[];for(let t in n)Object.prototype.hasOwnProperty.call(n,t)&&!this.clustering._isClusteredNode(t)&&n[t].options.hidden===!1&&this.body.nodeIndices.push(n[t].id);for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t)){let i=e[t],s=n[i.fromId],o=n[i.toId],r=s!==void 0&&o!==void 0;!this.clustering._isClusteredEdge(t)&&i.options.hidden===!1&&r&&s.options.hidden===!1&&o.options.hidden===!1&&this.body.edgeIndices.push(i.id)}};I.prototype.bindEventListeners=function(){this.body.emitter.on("_dataChanged",()=>{this.edgesHandler._updateState(),this.body.emitter.emit("_dataUpdated")}),this.body.emitter.on("_dataUpdated",()=>{this.clustering._updateState(),this._updateVisibleIndices(),this._updateValueRange(this.body.nodes),this._updateValueRange(this.body.edges),this.body.emitter.emit("startSimulation"),this.body.emitter.emit("_requestRedraw")})};I.prototype.setData=function(n){if(this.body.emitter.emit("resetPhysics"),this.body.emitter.emit("_resetData"),this.selectionHandler.unselectAll(),n&&n.dot&&(n.nodes||n.edges))throw new SyntaxError('Data must contain either parameter "dot" or parameter pair "nodes" and "edges", but not both.');if(this.setOptions(n&&n.options),n&&n.dot){console.warn("The dot property has been deprecated. Please use the static convertDot method to convert DOT into vis.network format and use the normal data format with nodes and edges. This converter is used like this: var data = vis.network.convertDot(dotString);");let e=la(n.dot);this.setData(e);return}else if(n&&n.gephi){console.warn("The gephi property has been deprecated. Please use the static convertGephi method to convert gephi into vis.network format and use the normal data format with nodes and edges. This converter is used like this: var data = vis.network.convertGephi(gephiJson);");let e=ca(n.gephi);this.setData(e);return}else this.nodesHandler.setData(n&&n.nodes,!0),this.edgesHandler.setData(n&&n.edges,!0);this.body.emitter.emit("_dataChanged"),this.body.emitter.emit("_dataLoaded"),this.body.emitter.emit("initPhysics")};I.prototype.destroy=function(){this.body.emitter.emit("destroy"),this.body.emitter.off(),this.off(),delete this.groups,delete this.canvas,delete this.selectionHandler,delete this.interactionHandler,delete this.view,delete this.renderer,delete this.physics,delete this.layoutEngine,delete this.clustering,delete this.manipulation,delete this.nodesHandler,delete this.edgesHandler,delete this.configurator,delete this.images;for(let n in this.body.nodes)!Object.prototype.hasOwnProperty.call(this.body.nodes,n)||delete this.body.nodes[n];for(let n in this.body.edges)!Object.prototype.hasOwnProperty.call(this.body.edges,n)||delete this.body.edges[n];we(this.body.container)};I.prototype._updateValueRange=function(n){let e,t,i,s=0;for(e in n)if(Object.prototype.hasOwnProperty.call(n,e)){let o=n[e].getValue();o!==void 0&&(t=t===void 0?o:Math.min(o,t),i=i===void 0?o:Math.max(o,i),s+=o)}if(t!==void 0&&i!==void 0)for(e in n)Object.prototype.hasOwnProperty.call(n,e)&&n[e].setValueRange(t,i,s)};I.prototype.isActive=function(){return!this.activator||this.activator.active};I.prototype.setSize=function(){return this.canvas.setSize.apply(this.canvas,arguments)};I.prototype.canvasToDOM=function(){return this.canvas.canvasToDOM.apply(this.canvas,arguments)};I.prototype.DOMtoCanvas=function(){return this.canvas.DOMtoCanvas.apply(this.canvas,arguments)};I.prototype.findNode=function(){return this.clustering.findNode.apply(this.clustering,arguments)};I.prototype.isCluster=function(){return this.clustering.isCluster.apply(this.clustering,arguments)};I.prototype.openCluster=function(){return this.clustering.openCluster.apply(this.clustering,arguments)};I.prototype.cluster=function(){return this.clustering.cluster.apply(this.clustering,arguments)};I.prototype.getNodesInCluster=function(){return this.clustering.getNodesInCluster.apply(this.clustering,arguments)};I.prototype.clusterByConnection=function(){return this.clustering.clusterByConnection.apply(this.clustering,arguments)};I.prototype.clusterByHubsize=function(){return this.clustering.clusterByHubsize.apply(this.clustering,arguments)};I.prototype.updateClusteredNode=function(){return this.clustering.updateClusteredNode.apply(this.clustering,arguments)};I.prototype.getClusteredEdges=function(){return this.clustering.getClusteredEdges.apply(this.clustering,arguments)};I.prototype.getBaseEdge=function(){return this.clustering.getBaseEdge.apply(this.clustering,arguments)};I.prototype.getBaseEdges=function(){return this.clustering.getBaseEdges.apply(this.clustering,arguments)};I.prototype.updateEdge=function(){return this.clustering.updateEdge.apply(this.clustering,arguments)};I.prototype.clusterOutliers=function(){return this.clustering.clusterOutliers.apply(this.clustering,arguments)};I.prototype.getSeed=function(){return this.layoutEngine.getSeed.apply(this.layoutEngine,arguments)};I.prototype.enableEditMode=function(){return this.manipulation.enableEditMode.apply(this.manipulation,arguments)};I.prototype.disableEditMode=function(){return this.manipulation.disableEditMode.apply(this.manipulation,arguments)};I.prototype.addNodeMode=function(){return this.manipulation.addNodeMode.apply(this.manipulation,arguments)};I.prototype.editNode=function(){return this.manipulation.editNode.apply(this.manipulation,arguments)};I.prototype.editNodeMode=function(){return console.warn("Deprecated: Please use editNode instead of editNodeMode."),this.manipulation.editNode.apply(this.manipulation,arguments)};I.prototype.addEdgeMode=function(){return this.manipulation.addEdgeMode.apply(this.manipulation,arguments)};I.prototype.editEdgeMode=function(){return this.manipulation.editEdgeMode.apply(this.manipulation,arguments)};I.prototype.deleteSelected=function(){return this.manipulation.deleteSelected.apply(this.manipulation,arguments)};I.prototype.getPositions=function(){return this.nodesHandler.getPositions.apply(this.nodesHandler,arguments)};I.prototype.getPosition=function(){return this.nodesHandler.getPosition.apply(this.nodesHandler,arguments)};I.prototype.storePositions=function(){return this.nodesHandler.storePositions.apply(this.nodesHandler,arguments)};I.prototype.moveNode=function(){return this.nodesHandler.moveNode.apply(this.nodesHandler,arguments)};I.prototype.getBoundingBox=function(){return this.nodesHandler.getBoundingBox.apply(this.nodesHandler,arguments)};I.prototype.getConnectedNodes=function(n){return this.body.nodes[n]!==void 0?this.nodesHandler.getConnectedNodes.apply(this.nodesHandler,arguments):this.edgesHandler.getConnectedNodes.apply(this.edgesHandler,arguments)};I.prototype.getConnectedEdges=function(){return this.nodesHandler.getConnectedEdges.apply(this.nodesHandler,arguments)};I.prototype.startSimulation=function(){return this.physics.startSimulation.apply(this.physics,arguments)};I.prototype.stopSimulation=function(){return this.physics.stopSimulation.apply(this.physics,arguments)};I.prototype.stabilize=function(){return this.physics.stabilize.apply(this.physics,arguments)};I.prototype.getSelection=function(){return this.selectionHandler.getSelection.apply(this.selectionHandler,arguments)};I.prototype.setSelection=function(){return this.selectionHandler.setSelection.apply(this.selectionHandler,arguments)};I.prototype.getSelectedNodes=function(){return this.selectionHandler.getSelectedNodeIds.apply(this.selectionHandler,arguments)};I.prototype.getSelectedEdges=function(){return this.selectionHandler.getSelectedEdgeIds.apply(this.selectionHandler,arguments)};I.prototype.getNodeAt=function(){let n=this.selectionHandler.getNodeAt.apply(this.selectionHandler,arguments);return n!==void 0&&n.id!==void 0?n.id:n};I.prototype.getEdgeAt=function(){let n=this.selectionHandler.getEdgeAt.apply(this.selectionHandler,arguments);return n!==void 0&&n.id!==void 0?n.id:n};I.prototype.selectNodes=function(){return this.selectionHandler.selectNodes.apply(this.selectionHandler,arguments)};I.prototype.selectEdges=function(){return this.selectionHandler.selectEdges.apply(this.selectionHandler,arguments)};I.prototype.unselectAll=function(){this.selectionHandler.unselectAll.apply(this.selectionHandler,arguments),this.selectionHandler.commitWithoutEmitting.apply(this.selectionHandler),this.redraw()};I.prototype.redraw=function(){return this.renderer.redraw.apply(this.renderer,arguments)};I.prototype.getScale=function(){return this.view.getScale.apply(this.view,arguments)};I.prototype.getViewPosition=function(){return this.view.getViewPosition.apply(this.view,arguments)};I.prototype.fit=function(){return this.view.fit.apply(this.view,arguments)};I.prototype.moveTo=function(){return this.view.moveTo.apply(this.view,arguments)};I.prototype.focus=function(){return this.view.focus.apply(this.view,arguments)};I.prototype.releaseNode=function(){return this.view.releaseNode.apply(this.view,arguments)};I.prototype.getOptionsFromConfigurator=function(){let n={};return this.configurator&&(n=this.configurator.getOptions.apply(this.configurator)),n};var Mn=n=>{if(!document.cookie)return;let e=null,t=document.cookie.split(";");for(let i=0;iBe(de({},s),{title:e(s.title)}))),i=new Te(topologyData.edges.map(s=>Be(de({},s),{title:e(s.title)})));Ge=new I(Dn,{nodes:t,edges:i},qi),Ge.fit(),Ge.on("dragEnd",s=>{!Ba.checked||Promise.allSettled(Object.entries(Ge.getPositions(s.nodes)).map(a=>Xi(this,[a],function*([o,r]){let d=yield fetch("/api/plugins/netbox_topology_views/save-coords/",{method:"PATCH",headers:{"X-CSRFToken":Na,Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({node_id:o,x:r.x,y:r.y})});console.log(o,d.status,d.statusText)})))}),Ge.on("doubleClick",s=>{s.nodes.forEach(o=>{window.open(t.get(o).href,"_blank")})})})();var Aa="image/png",za=document.querySelector("#btnDownloadImage");za.addEventListener("click",n=>{La()});function La(){let n=Dn.querySelector("canvas"),e=document.createElement("a"),t=n.toDataURL(Aa);e.href=t,e.download="topology",document.body.appendChild(e),e.click(),document.body.removeChild(e)}var Ra=new MutationObserver(n=>n.forEach(e=>{if(!Ge||e.type!=="attributes"||e.attributeName!=="data-netbox-color-mode"||!(e.target instanceof HTMLElement))return;let{netboxColorMode:t}=e.target.dataset;qi.nodes.font.color=t==="dark"?"#fff":"#000",Ge.setOptions(qi)}));Ra.observe(document.documentElement,{attributes:!0,attributeFilter:["data-netbox-color-mode"]});})(); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. diff --git a/netbox_topology_views/static/netbox_topology_views/js/images.js b/netbox_topology_views/static/netbox_topology_views/js/images.js new file mode 100644 index 0000000..4dabe87 --- /dev/null +++ b/netbox_topology_views/static/netbox_topology_views/js/images.js @@ -0,0 +1 @@ +(()=>{var l=(e,t,o)=>new Promise((n,r)=>{var c=s=>{try{i(o.next(s))}catch(a){r(a)}},m=s=>{try{i(o.throw(s))}catch(a){r(a)}},i=s=>s.done?n(s.value):Promise.resolve(s.value).then(c,m);i((o=o.apply(e,t)).next())});var d=e=>{if(!document.cookie)return;let t=null,o=document.cookie.split(";");for(let n=0;n{let t=document.querySelector("#topology-plugin-success-toast");if(!t)return console.error("Could not find toast component!");let o=t.querySelector("span");o.textContent=e,new window.Toast(t).show()},error:e=>{let t=document.querySelector("#topology-plugin-error-toast");if(!t)return console.error("Could not find toast component!");let o=t.querySelector("span");o.textContent=e,new window.Toast(t).show()}};var g={},p=d("csrftoken");document.querySelector("form#images").addEventListener("submit",e=>l(void 0,null,function*(){e.preventDefault();try{let t=yield fetch("/api/plugins/netbox_topology_views/images/",{method:"POST",body:JSON.stringify(g),headers:{"X-CSRFToken":p,"Content-Type":"application/json"}});if(!t.ok)throw new Error(yield t.text());u.success("Saved settings")}catch(t){console.dir(t),u.error(t.message)}}));document.querySelectorAll("form#images .dropdown-menu img").forEach(e=>{e.addEventListener("click",t=>{var c;if(!(t.currentTarget instanceof HTMLElement))return;let{dataset:{role:o,image:n}}=t.currentTarget;g[o]=n;let r=(c=t.currentTarget.closest(".dropdown"))==null?void 0:c.querySelector(`#dropdownMenuButton${o}`);r&&(r.innerHTML=``)})});})(); diff --git a/netbox_topology_views/static/netbox_topology_views/js/images.js.map b/netbox_topology_views/static/netbox_topology_views/js/images.js.map new file mode 100644 index 0000000..77d4e0c --- /dev/null +++ b/netbox_topology_views/static/netbox_topology_views/js/images.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../../../static_dev/js/csrftoken.js", "../../../static_dev/js/toast.js", "../../../static_dev/js/images.js"], + "mappings": "mNAAO,GAAM,GAAY,AAAC,GAAS,CAC/B,GAAI,CAAC,SAAS,OAAQ,OAEtB,GAAI,GAAc,KACZ,EAAU,SAAS,OAAO,MAAM,KAEtC,OAAS,GAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACrC,GAAM,GAAS,EAAQ,GAAG,OAE1B,GAAI,EAAO,UAAU,EAAG,EAAK,OAAS,KAAO,EAAO,IAAK,CACrD,EAAc,mBAAmB,EAAO,UAAU,EAAK,OAAS,IAChE,OAIR,MAAO,ICfJ,GAAM,GAAQ,CACjB,QAAS,AAAC,GAAY,CAClB,GAAM,GAAK,SAAS,cAAc,kCAClC,GAAI,CAAC,EAAI,MAAO,SAAQ,MAAM,mCAC9B,GAAM,GAAU,EAAG,cAAc,QACjC,EAAQ,YAAc,EAEtB,AADc,GAAI,QAAO,MAAM,GACzB,QAEV,MAAO,AAAC,GAAY,CAChB,GAAM,GAAK,SAAS,cAAc,gCAClC,GAAI,CAAC,EAAI,MAAO,SAAQ,MAAM,mCAC9B,GAAM,GAAU,EAAG,cAAc,QACjC,EAAQ,YAAc,EAEtB,AADc,GAAI,QAAO,MAAM,GACzB,SCZd,GAAM,GAAU,GACV,EAAY,EAAU,aAE5B,SAAS,cAAc,eAAe,iBAAiB,SAAU,AAAO,GAAM,0BAC1E,EAAE,iBACF,GAAI,CACA,GAAM,GAAM,KAAM,OAAM,6CAA8C,CAClE,OAAQ,OACR,KAAM,KAAK,UAAU,GACrB,QAAS,CACL,cAAe,EACf,eAAgB,sBAIxB,GAAI,CAAC,EAAI,GAAI,KAAM,IAAI,OAAM,KAAM,GAAI,QACvC,EAAM,QAAQ,wBACT,EAAP,CACE,QAAQ,IAAI,GACZ,EAAM,MAAM,EAAI,aAIxB,SAAS,iBAAiB,kCAAkC,QAAQ,AAAC,GAAO,CACxE,EAAG,iBAAiB,QAAS,AAAC,GAAM,CA3BxC,MA4BQ,GAAI,CAAE,GAAE,wBAAyB,cAAc,OAC/C,GAAM,CACF,QAAS,CAAE,OAAM,UACjB,EAAE,cAEN,EAAQ,GAAQ,EAEhB,GAAM,GAAS,KAAE,cACZ,QAAQ,eADE,cAET,cAAc,sBAAsB,KAC1C,AAAI,GAAQ,GAAO,UAAY,aAAa", + "names": [] +} diff --git a/netbox_topology_views/static_dev/bundle.js b/netbox_topology_views/static_dev/bundle.js index abfe414..759aa37 100644 --- a/netbox_topology_views/static_dev/bundle.js +++ b/netbox_topology_views/static_dev/bundle.js @@ -1,87 +1,96 @@ -const esbuild = require('esbuild'); -const { sassPlugin } = require('esbuild-sass-plugin'); +const esbuild = require('esbuild') +const { sassPlugin } = require('esbuild-sass-plugin') const options = { bundle: true, minify: true, sourcemap: 'external', sourcesContent: false, - logLevel: 'error', -}; - -const ARGS = process.argv.slice(2); + logLevel: 'error' +} +const ARGS = process.argv.slice(2) +const noCache = ARGS.includes('--no-cache') async function bundleScripts() { - const entryPoints = { - 'app': 'js/home.js' - }; - try { - const result = await esbuild.build({ - ...options, - outdir: '../static/netbox_topology_views/js/', - entryPoints, - target: 'es2016', - }); - if (result.errors.length === 0) { - for (const [targetName, sourceName] of Object.entries(entryPoints)) { - const source = sourceName.split('/')[1]; - console.log(`✅ Bundled source file '${source}' to '${targetName}.js'`); - } + const entryPoints = { + app: 'js/home.js', + images: 'js/images.js' + } + + try { + const result = await esbuild.build({ + ...options, + outdir: '../static/netbox_topology_views/js/', + entryPoints, + target: 'es2016' + }) + if (result.errors.length !== 0) return + + for (const [targetName, sourceName] of Object.entries(entryPoints)) { + const source = sourceName.split('/').pop() // take last element + console.log( + `✅ Bundled source file '${source}' to '${targetName}.js'` + ) + } + } catch (err) { + console.error(err) } - } catch (err) { - console.error(err); - } } async function bundleStyles() { try { - const entryPoints = { - 'vendor': 'css/_external.scss', - 'app': 'css/app.scss', - }; - const pluginOptions = { outputStyle: 'compressed' }; - // Allow cache disabling. - if (ARGS.includes('--no-cache')) { - pluginOptions.cache = false; - } - let result = await esbuild.build({ - ...options, - outdir: '../static/netbox_topology_views/css/', - // Disable sourcemaps for CSS/SCSS files, see #7068 - sourcemap: false, - entryPoints, - plugins: [sassPlugin(pluginOptions)], - loader: { - '.eot': 'file', - '.woff': 'file', - '.woff2': 'file', - '.svg': 'file', - '.ttf': 'file', - }, - }); - if (result.errors.length === 0) { - for (const [targetName, sourceName] of Object.entries(entryPoints)) { - const source = sourceName.split('/')[1]; - console.log(`✅ Bundled source file '${source}' to '${targetName}.css'`); + const entryPoints = { + vendor: 'css/_external.scss', + app: 'css/app.scss' + } + const pluginOptions = { outputStyle: 'compressed' } + // Allow cache disabling. + if (noCache) { + pluginOptions.cache = false } - } - } catch (err) { - console.error(err); - } - } + const result = await esbuild.build({ + ...options, + outdir: '../static/netbox_topology_views/css/', + // Disable sourcemaps for CSS/SCSS files, see #7068 + sourcemap: false, + entryPoints, + plugins: [sassPlugin(pluginOptions)], + loader: { + '.eot': 'file', + '.woff': 'file', + '.woff2': 'file', + '.svg': 'file', + '.ttf': 'file' + } + }) + if (result.errors.length === 0) { + for (const [targetName, sourceName] of Object.entries( + entryPoints + )) { + const source = sourceName.split('/')[1] + console.log( + `✅ Bundled source file '${source}' to '${targetName}.css'` + ) + } + } + } catch (err) { + console.error(err) + } +} async function bundleAll() { if (ARGS.includes('--styles')) { - // Only run style jobs. - return await bundleStyles(); - } else if (ARGS.includes('--scripts')) { - // Only run script jobs. - return await bundleScripts(); + // Only run style jobs. + return await bundleStyles() } - await bundleStyles(); - await bundleScripts(); + if (ARGS.includes('--scripts')) { + // Only run script jobs. + return await bundleScripts() + } + await bundleStyles() + await bundleScripts() } - -bundleAll(); \ No newline at end of file + +bundleAll() diff --git a/netbox_topology_views/static_dev/css/app.scss b/netbox_topology_views/static_dev/css/app.scss index 21f5f88..f76d1be 100644 --- a/netbox_topology_views/static_dev/css/app.scss +++ b/netbox_topology_views/static_dev/css/app.scss @@ -1,7 +1,27 @@ #visgraph { - height: 70vh; - } + height: 70vh; +} html[data-netbox-color-mode=dark] #visgraph { background-color: #212529; -} \ No newline at end of file +} + + +.image-dropdown img { + width: 64px; + height: 64px; +} + +.image-dropdown-content { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + + padding-inline: 0.5rem; + width: 50vw; + max-width: 32rem; + + > img { + cursor: pointer; + } +} diff --git a/netbox_topology_views/static_dev/js/csrftoken.js b/netbox_topology_views/static_dev/js/csrftoken.js new file mode 100644 index 0000000..d99da1a --- /dev/null +++ b/netbox_topology_views/static_dev/js/csrftoken.js @@ -0,0 +1,17 @@ +export const getCookie = (name) => { + if (!document.cookie) return + + let cookieValue = null + const cookies = document.cookie.split(';') + + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i].trim() + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) === name + '=') { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)) + break + } + } + + return cookieValue +} diff --git a/netbox_topology_views/static_dev/js/home.js b/netbox_topology_views/static_dev/js/home.js index 5e7b1e7..df5c016 100644 --- a/netbox_topology_views/static_dev/js/home.js +++ b/netbox_topology_views/static_dev/js/home.js @@ -1,17 +1,8 @@ -import { DataSet } from "vis-data/esnext"; -import { Network } from "vis-network/esnext"; -//import 'vis-util'; +import { DataSet } from 'vis-data/esnext' +import { Network } from 'vis-network/esnext' +import { getCookie } from './csrftoken.js' - -var graph = null; -var container = null; -var downloadButton = null; -const MIME_TYPE = "image/png"; -var canvas = null; -var csrftoken = null; -var nodes = new DataSet(); -var edges = new DataSet(); -var options = { +const options = { interaction: { hover: true, hoverConnectedEdges: true, @@ -19,18 +10,22 @@ var options = { }, nodes: { shape: 'image', - brokenImage: '../../static/netbox_topology_views/img/role-unknown.png', + brokenImage: brokenImage ?? '', size: 35, font: { multi: 'md', face: 'helvetica', - }, + color: + document.documentElement.dataset.netboxColorMode === 'dark' + ? '#fff' + : '#000' + } }, edges: { length: 100, width: 2, font: { - face: 'helvetica', + face: 'helvetica' }, shadow: { enabled: true @@ -39,149 +34,114 @@ var options = { physics: { solver: 'forceAtlas2Based' } -}; -var coord_save_checkbox = null; -var htmlElement = null; - -export function getCookie(name) { - var cookieValue = null; - if (document.cookie && document.cookie !== '') { - var cookies = document.cookie.split(';'); - for (var i = 0; i < cookies.length; i++) { - var cookie = cookies[i].trim(); - // Does this cookie string begin with the name we want? - if (cookie.substring(0, name.length + 1) === (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; -}; - - -export function htmlTitle(html) { - container = document.createElement("div"); - container.innerHTML = html; - return container; -}; - -export function addEdge(item) { - item.title = htmlTitle(item.title); - edges.add(item); -}; - -export function addNode(item) { - item.title = htmlTitle(item.title); - nodes.add(item); } -export function iniPlotboxIndex() { - csrftoken = getCookie('csrftoken'); - container = document.getElementById('visgraph'); - htmlElement = document.getElementsByTagName("html")[0]; - downloadButton = document.getElementById('btnDownloadImage'); - handleLoadData(); - btnFullView = document.getElementById('btnFullView'); - coord_save_checkbox = document.getElementById('id_save_coords'); -}; +// Load CSRF token +const csrftoken = getCookie('csrftoken') -export function performGraphDownload() { - var tempDownloadLink = document.createElement('a'); - var generatedImageUrl = canvas.toDataURL(MIME_TYPE); +// Render vis graph +let graph = null // vis graph instance - tempDownloadLink.href = generatedImageUrl; - tempDownloadLink.download = "topology"; - document.body.appendChild(tempDownloadLink); - tempDownloadLink.click(); - document.body.removeChild(tempDownloadLink); -}; +const container = document.querySelector('#visgraph') +const coordSaveCheckbox = document.querySelector('#id_save_coords') +;(function handleLoadData() { + if (!topologyData) return -export function handleLoadData() { - if (topology_data !== null) { - - if (htmlElement.dataset.netboxColorMode == "dark") { - options.nodes.font.color = "#fff"; - } - - graph = null; - nodes = new DataSet(); - edges = new DataSet(); - graph = new Network(container, { nodes: nodes, edges: edges }, options); - - topology_data.edges.forEach(addEdge); - topology_data.nodes.forEach(addNode); - - graph.fit(); - canvas = document.getElementById('visgraph').getElementsByTagName('canvas')[0]; - - downloadButton.onclick = function(e) { performGraphDownload(); return false; }; - - graph.on("dragEnd", function (params) { - dragged = this.getPositions(params.nodes); - - if (coord_save_checkbox.checked) { - if (Object.keys(dragged).length !== 0) { - for (dragged_device in dragged) { - var node_id = dragged_device; - - var url = "/api/plugins/netbox_topology_views/save-coords/save_coords/"; - var xhr = new XMLHttpRequest(); - xhr.open("PATCH", url); - xhr.setRequestHeader('X-CSRFToken', csrftoken ); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("Content-Type", "application/json"); - - xhr.onreadystatechange = function () { - if (xhr.readyState === 4) { - console.log(xhr.status); - }}; - - var data = JSON.stringify({ - 'node_id': node_id, - 'x': dragged[node_id].x, - 'y': dragged[node_id].y}); - - xhr.send(data); - } - } - } - }); - - graph.on("doubleClick", function (params) { - let selected_devices = params.nodes; - for (let selected_device in selected_devices) { - let url = "" - if(String(selected_devices[selected_device]).startsWith("c")) { - cid = selected_devices[selected_device].substring(1); - url = "/circuits/circuits/" + cid + "/"; - } - else if (String(selected_devices[selected_device]).startsWith("p")) { - cid = selected_devices[selected_device].substring(1); - url = "/dcim/power-panels/" + cid + "/"; - } - else if (String(selected_devices[selected_device]).startsWith("f")) { - cid = selected_devices[selected_device].substring(1); - url = "/dcim/power-feeds/" + cid + "/"; - } - else { - url = "/dcim/devices/" + selected_devices[selected_device] + "/"; - } - - window.open(url, "_blank"); - } - - }); + function htmlTitle(text) { + const container = document.createElement('div') + container.innerHTML = text + return container } -}; -export function load_doc() { - if (document.readyState !== 'loading') { - iniPlotboxIndex(); - } else { - document.addEventListener('DOMContentLoaded', iniPlotboxIndex); - } -}; + const nodes = new DataSet( + topologyData.nodes.map((node) => ({ + ...node, + title: htmlTitle(node.title) + })) + ) + const edges = new DataSet( + topologyData.edges.map((node) => ({ + ...node, + title: htmlTitle(node.title) + })) + ) + graph = new Network(container, { nodes, edges }, options) + graph.fit() -load_doc(); + graph.on('dragEnd', (params) => { + if (!coordSaveCheckbox.checked) return + + Promise.allSettled( + Object.entries(graph.getPositions(params.nodes)).map( + async ([nodeId, nodePosition]) => { + const res = await fetch( + '/api/plugins/netbox_topology_views/save-coords/', + { + method: 'PATCH', + headers: { + 'X-CSRFToken': csrftoken, + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + node_id: nodeId, + x: nodePosition.x, + y: nodePosition.y + }) + } + ) + + console.log(nodeId, res.status, res.statusText) + } + ) + ) + }) + + graph.on('doubleClick', (params) => { + params.nodes.forEach((node) => { + window.open(nodes.get(node).href, '_blank') + }) + }) +})() + +// Download Graph +const MIME_TYPE = 'image/png' + +const downloadButton = document.querySelector('#btnDownloadImage') +downloadButton.addEventListener('click', (e) => { + performGraphDownload() +}) + +function performGraphDownload() { + const canvas = container.querySelector('canvas') + const tempDownloadLink = document.createElement('a') + const generatedImageUrl = canvas.toDataURL(MIME_TYPE) + + tempDownloadLink.href = generatedImageUrl + tempDownloadLink.download = 'topology' + document.body.appendChild(tempDownloadLink) + tempDownloadLink.click() + document.body.removeChild(tempDownloadLink) +} + +// Theme switching +const observer = new MutationObserver((mutations) => + mutations.forEach((mutation) => { + if ( + !graph || + mutation.type !== 'attributes' || + mutation.attributeName !== 'data-netbox-color-mode' || + !(mutation.target instanceof HTMLElement) + ) + return + const { netboxColorMode } = mutation.target.dataset + options.nodes.font.color = netboxColorMode === 'dark' ? '#fff' : '#000' + graph.setOptions(options) + }) +) + +observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['data-netbox-color-mode'] +}) diff --git a/netbox_topology_views/static_dev/js/images.js b/netbox_topology_views/static_dev/js/images.js new file mode 100644 index 0000000..28d7944 --- /dev/null +++ b/netbox_topology_views/static_dev/js/images.js @@ -0,0 +1,41 @@ +import { getCookie } from './csrftoken.js' +import { toast } from './toast.js' + +const mapping = {} +const csrftoken = getCookie('csrftoken') + +document.querySelector('form#images').addEventListener('submit', async (e) => { + e.preventDefault() + try { + const res = await fetch('/api/plugins/netbox_topology_views/images/', { + method: 'POST', + body: JSON.stringify(mapping), + headers: { + 'X-CSRFToken': csrftoken, + 'Content-Type': 'application/json' + } + }) + + if (!res.ok) throw new Error(await res.text()) + toast.success('Saved settings') + } catch (err) { + console.dir(err) + toast.error(err.message) + } +}) + +document.querySelectorAll('form#images .dropdown-menu img').forEach((el) => { + el.addEventListener('click', (e) => { + if (!(e.currentTarget instanceof HTMLElement)) return + const { + dataset: { role, image } + } = e.currentTarget + + mapping[role] = image + + const button = e.currentTarget + .closest('.dropdown') + ?.querySelector(`#dropdownMenuButton${role}`) + if (button) button.innerHTML = `` + }) +}) diff --git a/netbox_topology_views/static_dev/js/toast.js b/netbox_topology_views/static_dev/js/toast.js new file mode 100644 index 0000000..9fa087e --- /dev/null +++ b/netbox_topology_views/static_dev/js/toast.js @@ -0,0 +1,18 @@ +export const toast = { + success: (message) => { + const el = document.querySelector('#topology-plugin-success-toast') + if (!el) return console.error('Could not find toast component!') + const content = el.querySelector('span') + content.textContent = message + const toast = new window.Toast(el) + toast.show() + }, + error: (message) => { + const el = document.querySelector('#topology-plugin-error-toast') + if (!el) return console.error('Could not find toast component!') + const content = el.querySelector('span') + content.textContent = message + const toast = new window.Toast(el) + toast.show() + } +} diff --git a/netbox_topology_views/templates/netbox_topology_views/images.html b/netbox_topology_views/templates/netbox_topology_views/images.html new file mode 100644 index 0000000..1e86889 --- /dev/null +++ b/netbox_topology_views/templates/netbox_topology_views/images.html @@ -0,0 +1,46 @@ +{% extends 'base/layout.html' %} +{% load buttons %} +{% load render_table from django_tables2 %} +{% load helpers %} +{% load static %} + +{% block title %}Topology Views Images{% endblock %} + +{% block head %} + +{% endblock %} + +{% block content-wrapper %} +
+
+ {% for role in roles %} +
+ + {{ role.name }} +
+ {% endfor %} +
+ + +
+ {% include 'netbox_topology_views/toasts.html' %} +{% endblock content-wrapper %} + +{% block javascript %} + +{% endblock javascript %} \ No newline at end of file diff --git a/netbox_topology_views/templates/netbox_topology_views/index.html b/netbox_topology_views/templates/netbox_topology_views/index.html index 1ff9ef0..6a88e2b 100644 --- a/netbox_topology_views/templates/netbox_topology_views/index.html +++ b/netbox_topology_views/templates/netbox_topology_views/index.html @@ -50,12 +50,8 @@
-
+
- -
{% if filter_form %} @@ -69,5 +65,9 @@ {% endblock content-wrapper %} {% block javascript %} - + + {% endblock javascript %} diff --git a/netbox_topology_views/templates/netbox_topology_views/toasts.html b/netbox_topology_views/templates/netbox_topology_views/toasts.html new file mode 100644 index 0000000..d9aaef9 --- /dev/null +++ b/netbox_topology_views/templates/netbox_topology_views/toasts.html @@ -0,0 +1,44 @@ +
+ + +
\ No newline at end of file diff --git a/netbox_topology_views/urls.py b/netbox_topology_views/urls.py index 5a1c715..95d7057 100644 --- a/netbox_topology_views/urls.py +++ b/netbox_topology_views/urls.py @@ -1,10 +1,12 @@ from django.urls import path +from django.views.generic.base import RedirectView from . import views - # Define a list of URL patterns to be imported by NetBox. Each pattern maps a URL to # a specific view so that it can be accessed by users. urlpatterns = ( - path('', views.TopologyHomeView.as_view(), name='home'), + path("", RedirectView.as_view(url="topology/", permanent=True)), + path("topology/", views.TopologyHomeView.as_view(), name="home"), + path("images/", views.TopologyImagesView.as_view(), name="images"), ) diff --git a/netbox_topology_views/utils.py b/netbox_topology_views/utils.py new file mode 100644 index 0000000..5fce018 --- /dev/null +++ b/netbox_topology_views/utils.py @@ -0,0 +1,86 @@ +from dataclasses import dataclass +from functools import lru_cache +from pathlib import Path +from typing import Type + +from django.conf import settings +from django.db.models import Model +from django.templatetags.static import static +from django.utils.text import camel_case_to_spaces, re_camel_case + +IMAGE_DIR = Path(settings.STATIC_ROOT) / "netbox_topology_views/img" +CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / settings.PLUGINS_CONFIG[ + "netbox_topology_views" +]["static_image_directory"].removeprefix("/") + + +def image_static_url(path: Path) -> str: + return settings.BASE_PATH + static( + f"/{path.relative_to(Path(settings.STATIC_ROOT))}" + ) + + +def get_image_from_url(url: str) -> str: + return url.removeprefix(settings.BASE_PATH + settings.STATIC_URL) + + +IMAGE_FILETYPES = ( + "apng", + "avif", + "bmp", + "cur", + "gif", + "ico", + "jfif", + "jpeg", + "jpg", + "pjp", + "pjpeg", + "png", + "svg", + "webp", +) + + +def find_image_in_dir(glob: str, dir: Path): + return next( + (f for f in dir.glob(f"{glob}.*") if f.suffix.lstrip(".") in IMAGE_FILETYPES), + None, + ) + + +@lru_cache(maxsize=50) +def find_image_url(glob: str, dir: Path = CONF_IMAGE_DIR): + """ + will attempt to find a file that matches glob in given directory with any file extension, + otherwise will try to find a `role-unknown` image + + returns static file url + """ + if file := find_image_in_dir(glob, dir): + return image_static_url(file) + + if glob != "role-unknown" and (file := find_image_in_dir("role-unknown", dir)): + return image_static_url(file) + + if dir != IMAGE_DIR and (file := find_image_in_dir("role-unknown", IMAGE_DIR)): + return image_static_url(file) + + return "" + + +@dataclass +class Role: + slug: str + name: str + + +def get_model_slug(model: Type[Model]): + return camel_case_to_spaces(model.__name__).replace(" ", "-") + + +def get_model_role(model: Type[Model]) -> Role: + return Role( + slug=get_model_slug(model), + name=re_camel_case.sub(r" \1", model.__name__), + ) diff --git a/netbox_topology_views/views.py b/netbox_topology_views/views.py index cec81f0..f1f24a3 100644 --- a/netbox_topology_views/views.py +++ b/netbox_topology_views/views.py @@ -1,379 +1,678 @@ -from django.shortcuts import render -from django.db.models import Q -from django.views.generic import View -from django.contrib.auth.mixins import PermissionRequiredMixin -from django.conf import settings -from django.http import QueryDict -from django.http import HttpResponseRedirect - -from .forms import DeviceFilterForm -from .filters import DeviceFilterSet - import json +from functools import reduce +from typing import DefaultDict, Dict, Optional, Union -from dcim.models import Device, CableTermination, DeviceRole, Interface, FrontPort, RearPort, PowerPanel, PowerFeed -from circuits.models import CircuitTermination -from wireless.models import WirelessLink +from circuits.models import Circuit, CircuitTermination +from dcim.models import ( + Cable, + CableTermination, + Device, + DeviceRole, + FrontPort, + Interface, + PowerFeed, + PowerPanel, + RearPort, +) +from django.conf import settings +from django.contrib.auth.mixins import PermissionRequiredMixin +from django.contrib.contenttypes.models import ContentType +from django.db.models import Q, QuerySet +from django.http import HttpRequest, HttpResponseRedirect, QueryDict +from django.shortcuts import render +from django.views.generic import View from extras.models import Tag +from wireless.models import WirelessLink -supported_termination_types = ["interface", "front port", "rear port", "power outlet", "power port", "console port", "console server port"] +from netbox_topology_views.filters import DeviceFilterSet +from netbox_topology_views.forms import DeviceFilterForm +from netbox_topology_views.models import RoleImage +from netbox_topology_views.utils import ( + CONF_IMAGE_DIR, + find_image_url, + get_model_role, + get_model_slug, + image_static_url, +) -def create_node(device, save_coords, circuit = None, powerpanel = None, powerfeed= None): +supported_termination_types = [ + "interface", + "front port", + "rear port", + "power outlet", + "power port", + "console port", + "console server port", +] + +def get_image_for_entity(entity: Union[Device, Circuit, PowerPanel, PowerFeed]): + is_device = isinstance(entity, Device) + query = ( + {"object_id": entity.device_role_id} + if is_device + else {"content_type_id": ContentType.objects.get_for_model(entity).pk} + ) + + try: + return RoleImage.objects.get(**query).get_image_url() + except RoleImage.DoesNotExist: + return find_image_url( + entity.device_role.slug if is_device else get_model_slug(entity.__class__) + ) + + +def create_node( + device: Union[Device, Circuit, PowerPanel, PowerFeed], save_coords: bool +): node = {} node_content = "" - if circuit: - dev_name = "Circuit " + str(device.cid) - node["image"] = "../../static/netbox_topology_views/img/circuit.png" - node["id"] = "c{}".format(device.id) + if isinstance(device, Circuit): + dev_name = f"Circuit {device.cid}" + node["id"] = f"c{device.pk}" if device.provider is not None: - node_content += "Provider: " + device.provider.name + "" + node_content += ( + f"Provider: {device.provider.name}" + ) if device.type is not None: - node_content += "Type: " + device.type.name + "" - elif powerpanel: - dev_name = "Power Panel " + str(device.id) - node["image"] = "../../static/netbox_topology_views/img/power-panel.png" - node["id"] = "p{}".format(device.id) + node_content += f"Type: {device.type.name}" + elif isinstance(device, PowerPanel): + dev_name = f"Power Panel {device.pk}" + node["id"] = f"p{device.pk}" if device.site is not None: - node_content += "Site: " + device.site.name + "" + node_content += f"Site: {device.site.name}" if device.location is not None: - node_content += "Location: " + device.location.name + "" - elif powerfeed: - dev_name = "Power Feed " + str(device.id) - node["image"] = "../../static/netbox_topology_views/img/power-feed.png" - node["id"] = "f{}".format(device.id) + node_content += ( + f"Location: {device.location.name}" + ) + elif isinstance(device, PowerFeed): + dev_name = f"Power Feed {device.pk}" + node["id"] = f"f{device.pk}" if device.power_panel is not None: - node_content += "Power Panel: " + device.power_panel.name + "" + node_content += ( + f"Power Panel: {device.power_panel.name}" + ) if device.type is not None: - node_content += "Type: " + device.type + "" + node_content += f"Type: {device.type}" if device.supply is not None: - node_content += "Supply: " + device.supply + "" + node_content += f"Supply: {device.supply}" if device.phase is not None: - node_content += "Phase: " + device.phase + "" + node_content += f"Phase: {device.phase}" if device.amperage is not None: - node_content += "Amperage: " + str(device.amperage )+ "" + node_content += f"Amperage: {device.amperage}" if device.voltage is not None: - node_content += "Voltage: " + str(device.voltage) + "" + node_content += f"Voltage: {device.voltage}" else: dev_name = device.name if dev_name is None: dev_name = "device name unknown" if device.device_type is not None: - node_content += "Type: " + device.device_type.model + "" + node_content += ( + f"Type: {device.device_type.model}" + ) if device.device_role.name is not None: - node_content += "Role: " + device.device_role.name + "" + node_content += ( + f"Role: {device.device_role.name}" + ) if device.serial != "": - node_content += "Serial: " + device.serial + "" + node_content += f"Serial: {device.serial}" if device.primary_ip is not None: - node_content += "IP Address: " + str(device.primary_ip.address) + "" + node_content += ( + f"IP Address: {device.primary_ip.address}" + ) if device.site is not None: - node_content += "Site: " + device.site.name + "" + node_content += f"Site: {device.site.name}" if device.location is not None: - node_content += "Location: " + device.location.name + "" + node_content += ( + f"Location: {device.location.name}" + ) if device.rack is not None: - node_content += "Rack: " + device.rack.name + "" + node_content += f"Rack: {device.rack.name}" if device.position is not None: if device.face is not None: - node_content += "Position: {} ({}) ".format(device.position, device.face) + node_content += f"Position: {device.position} ({device.face})" else: - node_content += "Position: " + device.position + "" + node_content += ( + f"Position: {device.position}" + ) - node["id"] = device.id - - if device.device_role.slug in settings.PLUGINS_CONFIG["netbox_topology_views"]["device_img"]: - node["image"] = "../../static/netbox_topology_views/img/" + device.device_role.slug + ".png" - else: - node["image"] = "../../static/netbox_topology_views/img/role-unknown.png" + node["id"] = device.pk if device.device_role.color != "": node["color.border"] = "#" + device.device_role.color - + dev_title = " %s
" % (node_content) node["title"] = dev_title node["name"] = dev_name node["label"] = dev_name node["shape"] = "image" + node["href"] = device.get_absolute_url() + node["image"] = get_image_for_entity(device) - node["physics"] = True + node["physics"] = True if "coordinates" in device.custom_field_data: if device.custom_field_data["coordinates"] is not None: if ";" in device.custom_field_data["coordinates"]: - cords = device.custom_field_data["coordinates"].split(";") + cords = device.custom_field_data["coordinates"].split(";") node["x"] = int(cords[0]) node["y"] = int(cords[1]) node["physics"] = False - else: - if save_coords: - node["physics"] = False - else: - node["physics"] = True + elif save_coords: + node["physics"] = False return node -def create_edge(edge_id, termination_a, termination_b, circuit = None, cable = None, wireless = None, power=None): - cable_a_name = "device A name unknown" if termination_a["termination_name"] is None else termination_a["termination_name"] - cable_a_dev_name = "device A name unknown" if termination_a["termination_device_name"] is None else termination_a["termination_device_name"] - cable_b_name= "device A name unknown" if termination_b["termination_name"] is None else termination_b["termination_name"] - cable_b_dev_name = "cable B name unknown" if termination_b["termination_device_name"] is None else termination_b["termination_device_name"] + +def create_edge( + edge_id: int, + termination_a: Dict, + termination_b: Dict, + circuit: Optional[Dict] = None, + cable: Optional[Cable] = None, + wireless: Optional[Dict] = None, + power: Optional[bool] = None, +): + cable_a_name = ( + "device A name unknown" + if termination_a["termination_name"] is None + else termination_a["termination_name"] + ) + cable_a_dev_name = ( + "device A name unknown" + if termination_a["termination_device_name"] is None + else termination_a["termination_device_name"] + ) + cable_b_name = ( + "device A name unknown" + if termination_b["termination_name"] is None + else termination_b["termination_name"] + ) + cable_b_dev_name = ( + "cable B name unknown" + if termination_b["termination_device_name"] is None + else termination_b["termination_device_name"] + ) edge = {} edge["id"] = edge_id edge["from"] = termination_a["device_id"] edge["to"] = termination_b["device_id"] + title = "Cable" if circuit is not None: edge["dashes"] = True - edge["title"] = "Circuit provider: " + circuit["provider_name"] + "
" - edge["title"] += "Termination between
" - edge["title"] += cable_b_dev_name + " [" + cable_b_name + "]
" - edge["title"] += cable_a_dev_name + " [" + cable_a_name + "]" + title = f"Circuit provider: {circuit['provider_name']}
Termination" + elif wireless is not None: edge["dashes"] = [2, 10, 2, 10] - edge["title"] = "Wireless Connection between
" + cable_a_dev_name + " [" + cable_a_name + "]
" + cable_b_dev_name + " [" + cable_b_name + "]" + title = "Wireless Connection" + elif power is not None: - edge["dashes"] = [5, 5, 3, 3] - edge["title"] = "Power Connection between
" + cable_a_dev_name + " [" + cable_a_name + "]
" + cable_b_dev_name + " [" + cable_b_name + "]" - else: - edge["title"] = "Cable between
" + cable_a_dev_name + " [" + cable_a_name + "]
" + cable_b_dev_name + " [" + cable_b_name + "]" - + edge["dashes"] = [5, 5, 3, 3] + title = "Power Connection" + + edge[ + "title" + ] = f"{title} between
{cable_a_dev_name} [{cable_a_name}]
{cable_b_dev_name} [{cable_b_name}]" + if cable is not None and cable.color != "": edge["color"] = "#" + cable.color - + return edge + def create_circuit_termination(termination): if isinstance(termination, CircuitTermination): - return { "termination_name": termination.circuit.provider.name, "termination_device_name": termination.circuit.cid, "device_id": "c{}".format(termination.circuit.id) } - if isinstance(termination, Interface) or isinstance(termination, FrontPort) or isinstance(termination, RearPort): - return { "termination_name": termination.name, "termination_device_name": termination.device.name, "device_id": termination.device.id } + return { + "termination_name": termination.circuit.provider.name, + "termination_device_name": termination.circuit.cid, + "device_id": "c{}".format(termination.circuit.pk), + } + if ( + isinstance(termination, Interface) + or isinstance(termination, FrontPort) + or isinstance(termination, RearPort) + ): + return { + "termination_name": termination.name, + "termination_device_name": termination.device.name, + "device_id": termination.device.pk, + } return None -def get_topology_data(queryset, hide_unconnected, save_coords, show_circuit, show_power): + +def get_topology_data( + queryset: QuerySet, + hide_unconnected: bool, + save_coords: bool, + show_circuit: bool, + show_power: bool, +): + if not queryset: + return None + nodes_devices = {} edges = [] nodes = [] edge_ids = 0 - nodes_circuits = {} - nodes_powerpanel = {} - nodes_powerfeed = {} + nodes_circuits: Dict[int, Circuit] = {} + nodes_powerpanel: Dict[int, PowerPanel] = {} + nodes_powerfeed: Dict[int, PowerFeed] = {} nodes_provider_networks = {} - cable_ids = {} - if not queryset: - return None + cable_ids = DefaultDict(dict) + ignore_cable_type = settings.PLUGINS_CONFIG["netbox_topology_views"][ + "ignore_cable_type" + ] - ignore_cable_type = settings.PLUGINS_CONFIG["netbox_topology_views"]["ignore_cable_type"] - - device_ids = [d.id for d in queryset] - site_ids = [d.site.id for d in queryset] + device_ids = [d.pk for d in queryset] + site_ids = [d.site_id for d in queryset] if show_circuit: - circuits = CircuitTermination.objects.filter( Q(site_id__in=site_ids) | Q( provider_network__isnull=False) ).prefetch_related("provider_network", "circuit") - for circuit in circuits: - if not hide_unconnected and circuit.circuit.id not in nodes_circuits: - nodes_circuits[circuit.circuit.id] = circuit.circuit + circuit_terminations = CircuitTermination.objects.filter( + Q(site_id__in=site_ids) | Q(provider_network__isnull=False) + ).prefetch_related("provider_network", "circuit") + for circuit_termination in circuit_terminations: + circuit_termination: CircuitTermination + if ( + not hide_unconnected + and circuit_termination.circuit_id not in nodes_circuits + ): + nodes_circuits[ + circuit_termination.circuit.pk + ] = circuit_termination.circuit termination_a = {} termination_b = {} circuit_model = {} - if circuit.cable is not None: - termination_a = create_circuit_termination(circuit.cable.a_terminations[0]) - termination_b = create_circuit_termination(circuit.cable.b_terminations[0]) - elif circuit.provider_network is not None: - if circuit.provider_network.id not in nodes_provider_networks: - nodes_provider_networks[circuit.provider_network.id] = circuit.provider_network + if circuit_termination.cable is not None: + termination_a = create_circuit_termination( + circuit_termination.cable.a_terminations[0] + ) + termination_b = create_circuit_termination( + circuit_termination.cable.b_terminations[0] + ) + elif circuit_termination.provider_network is not None: + if ( + circuit_termination.provider_network_id + not in nodes_provider_networks + ): + nodes_provider_networks[ + circuit_termination.provider_network.pk + ] = circuit_termination.provider_network if bool(termination_a) and bool(termination_b): - circuit_model = {"provider_name": circuit.circuit.provider.name} + circuit_model = { + "provider_name": circuit_termination.circuit.provider.name + } edge_ids += 1 - edges.append(create_edge(edge_id=edge_ids,circuit=circuit_model, termination_a=termination_a, termination_b=termination_b)) + edges.append( + create_edge( + edge_id=edge_ids, + circuit=circuit_model, + termination_a=termination_a, + termination_b=termination_b, + ) + ) circuit_has_connections = False - for termination in [circuit.cable.a_terminations[0], circuit.cable.b_terminations[0]]: + for termination in [ + circuit_termination.cable.a_terminations[0], + circuit_termination.cable.b_terminations[0], + ]: if not isinstance(termination, CircuitTermination): - if termination.device.id not in nodes_devices and termination.device.id in device_ids: - nodes_devices[termination.device.id] = termination.device + if ( + termination.device_id not in nodes_devices + and termination.device_id in device_ids + ): + nodes_devices[termination.device_id] = termination.device circuit_has_connections = True else: - if termination.device.id in device_ids: - circuit_has_connections = True - + if termination.device_id in device_ids: + circuit_has_connections = True + if circuit_has_connections and hide_unconnected: - if circuit.circuit.id not in nodes_circuits: - nodes_circuits[circuit.circuit.id] = circuit.circuit + if circuit_termination.circuit_id not in nodes_circuits: + nodes_circuits[ + circuit_termination.circuit.pk + ] = circuit_termination.circuit - for d in nodes_circuits.values(): - nodes.append(create_node(d, save_coords, circuit=True)) + nodes.append(create_node(d, save_coords)) + + links: QuerySet[CableTermination] = CableTermination.objects.filter( + Q(_device_id__in=device_ids) + ).select_related("termination_type") + + wlan_links: QuerySet[WirelessLink] = WirelessLink.objects.filter( + Q(_interface_a_device_id__in=device_ids) + & Q(_interface_b_device_id__in=device_ids) + ) - links = CableTermination.objects.filter( Q(_device_id__in=device_ids) ).select_related("termination_type") - wlan_links = WirelessLink.objects.filter( Q(_interface_a_device_id__in=device_ids) & Q(_interface_b_device_id__in=device_ids)) - if show_power: - power_panels = PowerPanel.objects.filter( Q (site_id__in=site_ids)) - power_panels_ids = [d.id for d in power_panels] - power_feeds = PowerFeed.objects.filter( Q (power_panel_id__in=power_panels_ids)) - + power_panels_ids = PowerPanel.objects.filter( + Q(site_id__in=site_ids) + ).values_list("pk", flat=True) + power_feeds: QuerySet[PowerFeed] = PowerFeed.objects.filter( + Q(power_panel_id__in=power_panels_ids) + ) + for power_feed in power_feeds: - if not hide_unconnected or (hide_unconnected and power_feed.cable_id is not None): - if power_feed.power_panel.id not in nodes_powerpanel: - nodes_powerpanel[power_feed.power_panel.id] = power_feed.power_panel + if not hide_unconnected or ( + hide_unconnected and power_feed.cable_id is not None + ): + if power_feed.power_panel_id not in nodes_powerpanel: + nodes_powerpanel[power_feed.power_panel.pk] = power_feed.power_panel power_link_name = "" - if power_feed.id not in nodes_powerfeed: + if power_feed.pk not in nodes_powerfeed: if hide_unconnected: - if power_feed.link_peers[0].device.id in device_ids: - nodes_powerfeed[power_feed.id] = power_feed - power_link_name =power_feed.link_peers[0].name + if power_feed.link_peers[0].device_id in device_ids: + nodes_powerfeed[power_feed.pk] = power_feed + power_link_name = power_feed.link_peers[0].name else: - nodes_powerfeed[power_feed.id] = power_feed + nodes_powerfeed[power_feed.pk] = power_feed edge_ids += 1 - termination_a = { "termination_name": power_feed.power_panel.name, "termination_device_name": "", "device_id": "p{}".format(power_feed.power_panel.id) } - termination_b = { "termination_name": power_feed.name, "termination_device_name": power_link_name, "device_id": "f{}".format(power_feed.id) } - edges.append(create_edge(edge_id=edge_ids, termination_a=termination_a, termination_b=termination_b, power=True)) + termination_a = { + "termination_name": power_feed.power_panel.name, + "termination_device_name": "", + "device_id": f"p{power_feed.power_panel_id}", + } + termination_b = { + "termination_name": power_feed.name, + "termination_device_name": power_link_name, + "device_id": f"f{power_feed.pk}", + } + edges.append( + create_edge( + edge_id=edge_ids, + termination_a=termination_a, + termination_b=termination_b, + power=True, + ) + ) if power_feed.cable_id is not None: - if power_feed.cable.id not in cable_ids: - cable_ids[power_feed.cable.id] = {} - cable_ids[power_feed.cable.id][power_feed.cable_end] = termination_b - - + cable_ids[power_feed.cable_id][power_feed.cable_end] = termination_b + for d in nodes_powerfeed.values(): - nodes.append(create_node(d, save_coords, powerfeed = True)) - + nodes.append(create_node(d, save_coords)) + for d in nodes_powerpanel.values(): - nodes.append(create_node(d, save_coords, powerpanel = True)) + nodes.append(create_node(d, save_coords)) for link in links: - if link.termination_type.name in ignore_cable_type : + if link.termination_type.name in ignore_cable_type: continue - - #Normal device cables + + # Normal device cables if link.termination_type.name in supported_termination_types: complete_link = False if link.cable_end == "A": - if link.cable.id not in cable_ids: - cable_ids[link.cable.id] = {} + if link.cable_id not in cable_ids: + cable_ids[link.cable_id] = {} else: - if 'B' in cable_ids[link.cable.id]: - if cable_ids[link.cable.id]['B'] is not None: + if "B" in cable_ids[link.cable_id]: + if cable_ids[link.cable_id]["B"] is not None: complete_link = True elif link.cable_end == "B": - if link.cable.id not in cable_ids: - cable_ids[link.cable.id] = {} + if link.cable_id not in cable_ids: + cable_ids[link.cable_id] = {} else: - if 'A' in cable_ids[link.cable.id]: - if cable_ids[link.cable.id]['A'] is not None: + if "A" in cable_ids[link.cable_id]: + if cable_ids[link.cable_id]["A"] is not None: complete_link = True else: print("Unkown cable end") - cable_ids[link.cable.id][link.cable_end] = link + cable_ids[link.cable_id][link.cable_end] = link if complete_link: edge_ids += 1 - if isinstance(cable_ids[link.cable.id]["B"], CableTermination): - if cable_ids[link.cable.id]["B"]._device_id not in nodes_devices: - nodes_devices[cable_ids[link.cable.id]["B"]._device_id] = cable_ids[link.cable.id]["B"].termination.device - termination_b = { "termination_name": cable_ids[link.cable.id]["B"].termination.name, "termination_device_name": cable_ids[link.cable.id]["B"].termination.device.name, "device_id": cable_ids[link.cable.id]["B"].termination.device.id } + if isinstance(cable_ids[link.cable_id]["B"], CableTermination): + if cable_ids[link.cable_id]["B"]._device_id not in nodes_devices: + nodes_devices[ + cable_ids[link.cable_id]["B"]._device_id + ] = cable_ids[link.cable_id]["B"].termination.device + termination_b = { + "termination_name": cable_ids[link.cable_id][ + "B" + ].termination.name, + "termination_device_name": cable_ids[link.cable_id][ + "B" + ].termination.device.name, + "device_id": cable_ids[link.cable_id][ + "B" + ].termination.device_id, + } else: - termination_b = cable_ids[link.cable.id]["B"] + termination_b = cable_ids[link.cable_id]["B"] - if isinstance(cable_ids[link.cable.id]["A"], CableTermination): - if cable_ids[link.cable.id]["A"]._device_id not in nodes_devices: - nodes_devices[cable_ids[link.cable.id]["A"]._device_id] = cable_ids[link.cable.id]["A"].termination.device - termination_a = { "termination_name": cable_ids[link.cable.id]["A"].termination.name, "termination_device_name": cable_ids[link.cable.id]["A"].termination.device.name, "device_id": cable_ids[link.cable.id]["A"].termination.device.id } + if isinstance(cable_ids[link.cable_id]["A"], CableTermination): + if cable_ids[link.cable_id]["A"]._device_id not in nodes_devices: + nodes_devices[ + cable_ids[link.cable_id]["A"]._device_id + ] = cable_ids[link.cable_id]["A"].termination.device + termination_a = { + "termination_name": cable_ids[link.cable_id][ + "A" + ].termination.name, + "termination_device_name": cable_ids[link.cable_id][ + "A" + ].termination.device.name, + "device_id": cable_ids[link.cable_id][ + "A" + ].termination.device_id, + } else: - termination_a = cable_ids[link.cable.id]["A"] - - edges.append(create_edge(edge_id=edge_ids, cable=link.cable, termination_a=termination_a, termination_b=termination_b)) + termination_a = cable_ids[link.cable_id]["A"] + + edges.append( + create_edge( + edge_id=edge_ids, + cable=link.cable, + termination_a=termination_a, + termination_b=termination_b, + ) + ) for wlan_link in wlan_links: - if wlan_link.interface_a.device.id not in nodes_devices: - nodes_devices[wlan_link.interface_a.device.id] = wlan_link.interface_a.device - if wlan_link.interface_b.device.id not in nodes_devices: - nodes_devices[wlan_link.interface_b.device.id] = wlan_link.interface_b.device - - termination_a = {"termination_name": wlan_link.interface_a.name, "termination_device_name": wlan_link.interface_a.device.name, "device_id": wlan_link.interface_a.device.id} - termination_b = {"termination_name": wlan_link.interface_b.name, "termination_device_name": wlan_link.interface_b.device.name, "device_id": wlan_link.interface_b.device.id} - wireless = {"ssid": wlan_link.ssid } + if wlan_link.interface_a.device_id not in nodes_devices: + nodes_devices[ + wlan_link.interface_a.device.pk + ] = wlan_link.interface_a.device + if wlan_link.interface_b.device_id not in nodes_devices: + nodes_devices[ + wlan_link.interface_b.device.pk + ] = wlan_link.interface_b.device + + termination_a = { + "termination_name": wlan_link.interface_a.name, + "termination_device_name": wlan_link.interface_a.device.name, + "device_id": wlan_link.interface_a.device_id, + } + termination_b = { + "termination_name": wlan_link.interface_b.name, + "termination_device_name": wlan_link.interface_b.device.name, + "device_id": wlan_link.interface_b.device_id, + } + wireless = {"ssid": wlan_link.ssid} edge_ids += 1 - edges.append(create_edge(edge_id=edge_ids, termination_a=termination_a, termination_b=termination_b,wireless=wireless)) + edges.append( + create_edge( + edge_id=edge_ids, + termination_a=termination_a, + termination_b=termination_b, + wireless=wireless, + ) + ) for qs_device in queryset: - if qs_device.id not in nodes_devices and not hide_unconnected: - nodes_devices[qs_device.id] = qs_device + if qs_device.pk not in nodes_devices and not hide_unconnected: + nodes_devices[qs_device.pk] = qs_device results = {} - + for d in nodes_devices.values(): nodes.append(create_node(d, save_coords)) - results["nodes"] = nodes + results["nodes"] = nodes results["edges"] = edges return results + class TopologyHomeView(PermissionRequiredMixin, View): permission_required = ("dcim.view_site", "dcim.view_device") """ Show the home page """ + def get(self, request): self.filterset = DeviceFilterSet - self.queryset = Device.objects.all().select_related("device_type", "device_role") + self.queryset = Device.objects.all().select_related( + "device_type", "device_role" + ) self.queryset = self.filterset(request.GET, self.queryset).qs topo_data = None if request.GET: save_coords = False - if 'save_coords' in request.GET: + if "save_coords" in request.GET: if request.GET["save_coords"] == "on": save_coords = True - + hide_unconnected = False if "hide_unconnected" in request.GET: - if request.GET["hide_unconnected"] == "on" : + if request.GET["hide_unconnected"] == "on": hide_unconnected = True show_power = False if "show_power" in request.GET: - if request.GET["show_power"] == "on" : + if request.GET["show_power"] == "on": show_power = True show_circuit = False if "show_circuit" in request.GET: - if request.GET["show_circuit"] == "on" : + if request.GET["show_circuit"] == "on": show_circuit = True if "draw_init" in request.GET: if request.GET["draw_init"].lower() == "true": - topo_data = get_topology_data(self.queryset, hide_unconnected, save_coords, show_circuit, show_power) + topo_data = get_topology_data( + self.queryset, + hide_unconnected, + save_coords, + show_circuit, + show_power, + ) else: - topo_data = get_topology_data(self.queryset, hide_unconnected, save_coords, show_circuit, show_power) + topo_data = get_topology_data( + self.queryset, + hide_unconnected, + save_coords, + show_circuit, + show_power, + ) else: - preselected_device_roles = settings.PLUGINS_CONFIG["netbox_topology_views"]["preselected_device_roles"] - preselected_tags = settings.PLUGINS_CONFIG["netbox_topology_views"]["preselected_tags"] - always_save_coordinates = bool(settings.PLUGINS_CONFIG["netbox_topology_views"]["always_save_coordinates"]) + preselected_device_roles = settings.PLUGINS_CONFIG["netbox_topology_views"][ + "preselected_device_roles" + ] + preselected_tags = settings.PLUGINS_CONFIG["netbox_topology_views"][ + "preselected_tags" + ] + always_save_coordinates = bool( + settings.PLUGINS_CONFIG["netbox_topology_views"][ + "always_save_coordinates" + ] + ) - q_device_role_id = DeviceRole.objects.filter(name__in=preselected_device_roles).values_list("id", flat=True) - q_tags = Tag.objects.filter(name__in=preselected_tags).values_list("name", flat=True) + q_device_role_id = DeviceRole.objects.filter( + name__in=preselected_device_roles + ).values_list("id", flat=True) + q_tags = Tag.objects.filter(name__in=preselected_tags).values_list( + "name", flat=True + ) q = QueryDict(mutable=True) q.setlist("device_role_id", list(q_device_role_id)) q.setlist("tag", list(q_tags)) - q["draw_init"] = settings.PLUGINS_CONFIG["netbox_topology_views"]["draw_default_layout"] + q["draw_init"] = settings.PLUGINS_CONFIG["netbox_topology_views"][ + "draw_default_layout" + ] if always_save_coordinates: q["save_coords"] = "on" query_string = q.urlencode() - return HttpResponseRedirect(request.path + "?" + query_string) + return HttpResponseRedirect(f"{request.path}?{query_string}") - return render(request, "netbox_topology_views/index.html" , { - "filter_form": DeviceFilterForm(request.GET, label_suffix=""), - "topology_data": json.dumps(topo_data) - } + return render( + request, + "netbox_topology_views/index.html", + { + "filter_form": DeviceFilterForm(request.GET, label_suffix=""), + "topology_data": json.dumps(topo_data), + "broken_image": find_image_url("role-unknown"), + }, + ) + + +CONFIG = settings.PLUGINS_CONFIG["netbox_topology_views"] +ADDITIONAL_ROLES = (PowerPanel, PowerFeed, Circuit) + + +class TopologyImagesView(PermissionRequiredMixin, View): + permission_required = ( + "dcim.view_site", + "dcim.view_device_role", + "dcim.add_device_role", + "dcim.change_device_role", + ) + + def get(self, request: HttpRequest): + images = [ + {"url": image_static_url(image), "title": image.stem} + for image in CONF_IMAGE_DIR.iterdir() + ] + + roles = reduce( + lambda acc, cur: { + **acc, + cur.name: { + "id": cur.pk, + "name": cur.name, + "slug": cur.slug, + "image": find_image_url(cur.slug), + }, + }, + DeviceRole.objects.all(), + dict(), + ) + + for additional_role in ADDITIONAL_ROLES: + cur = get_model_role(additional_role) + ct = ContentType.objects.get_for_model(additional_role).pk + + roles[cur.name] = { + "id": f"ct{ct}", + "name": cur.name, + "slug": cur.slug, + "image": find_image_url(cur.slug), + } + + role_images = RoleImage.objects.all() + + for role_image in role_images: + roles[role_image.role.name]["image"] = role_image.get_image_url() + + return render( + request, + "netbox_topology_views/images.html", + { + "roles": sorted(list(roles.values()), key=lambda r: r["name"]), + "images": images, + }, ) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..cde2133 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +djangorestframework +django-filter +black \ No newline at end of file diff --git a/setup.py b/setup.py index 409462e..1277200 100644 --- a/setup.py +++ b/setup.py @@ -1,29 +1,29 @@ -from setuptools import setup, find_packages +from pathlib import Path -from os import path -top_level_directory = path.abspath(path.dirname(__file__)) -with open(path.join(top_level_directory, 'README.md'), encoding='utf-8') as file: - long_description = file.read() +from setuptools import find_packages, setup + +readme = Path(__file__).parent / "README.md" +long_description = readme.read_text() setup( - name='netbox-topology-views', - version='3.0.1', - description='An NetBox plugin to create Topology maps', + name="netbox-topology-views", + version="3.0.1", + description="An NetBox plugin to create Topology maps", long_description=long_description, - long_description_content_type='text/markdown', - url='https://github.com/mattieserver/netbox-topology-views', - author='Mattijs Vanhaverbeke', - license='Apache 2.0', + long_description_content_type="text/markdown", + url="https://github.com/mattieserver/netbox-topology-views", + author="Mattijs Vanhaverbeke", + license="Apache 2.0", install_requires=[], packages=find_packages(), include_package_data=True, - keywords=['netbox-plugin'], + keywords=["netbox-plugin"], classifiers=[ - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", ], project_urls={ - 'Source': 'https://github.com/mattieserver/netbox-topology-views', + "Source": "https://github.com/mattieserver/netbox-topology-views", }, )