Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fafbeb7c3 | ||
|
|
6f2ac1684a | ||
|
|
1227c87d05 | ||
|
|
89b04ff0c5 | ||
|
|
47079cf27f | ||
|
|
fbf223f8bf | ||
|
|
b74fbb828f | ||
|
|
2e34f7435a | ||
|
|
3805d75dba | ||
|
|
b178d68338 | ||
|
|
37c900ea4a | ||
|
|
0cb0c10dbb | ||
|
|
dfb0b532b9 | ||
|
|
e0bd1d4e86 | ||
|
|
683a980858 | ||
|
|
2befe94f5d | ||
|
|
2f65614fcb | ||
|
|
2722dfa793 | ||
|
|
41d6afc336 | ||
|
|
2901dbb5c7 | ||
|
|
37122cd76c | ||
|
|
7173564ea9 | ||
|
|
be402b1b5c |
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
description: Report a reproducible bug in the current release of NetBox
|
||||
labels: ["type: bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
**NOTE:** This form is only for reporting _reproducible bugs_. If you're having
|
||||
trouble with installation or just looking for assistance with using NetBox
|
||||
Topology Views, please visit our
|
||||
[discussion forum](https://github.com/mattieserver/netbox-topology-views/discussions) instead.
|
||||
- type: input
|
||||
attributes:
|
||||
label: NetBox version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v3.3.9
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Topology Views version
|
||||
description: What version of NetBox Topology Views are you currently running?
|
||||
placeholder: v3.1.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: >
|
||||
Describe in detail the exact steps that someone else can take to
|
||||
reproduce this bug using the current stable release of NetBox Topology Views.
|
||||
placeholder: |
|
||||
1. Click on "create widget"
|
||||
2. Set foo to 12 and bar to G
|
||||
3. Click the "create" button
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: What did you expect to happen?
|
||||
placeholder: A new widget should have been created with the specified attributes
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Observed Behavior
|
||||
description: What happened instead?
|
||||
placeholder: A TypeError exception was raised
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ❓ Discussion
|
||||
url: https://github.com/mattieserver/netbox-topology-views/discussions
|
||||
about: "If you're just looking for help, try starting a discussion instead"
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: ✨ Feature Request
|
||||
description: Propose a new NetBox Topology Views feature or enhancement
|
||||
labels: ["type: feature"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
**NOTE:** This form is only for submitting well-formed proposals to extend or modify
|
||||
NetBox Topology Views in some way. If you're trying to solve a problem but can't figure
|
||||
out how, or if you still need time to work on the details of a proposed new feature,
|
||||
please start a [discussion](https://github.com/mattieserver/netbox-topology-views/discussions) instead.
|
||||
- type: input
|
||||
attributes:
|
||||
label: NetBox version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v3.3.9
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Topology Views version
|
||||
description: What version of NetBox Topology Views are you currently running?
|
||||
placeholder: v3.1.0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Feature type
|
||||
options:
|
||||
- New functionality
|
||||
- Change to existing functionality
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposed functionality
|
||||
description: >
|
||||
Describe in detail the new feature or behavior you are proposing. Include any specific changes
|
||||
to work flows and/or the user interface. The more detail you provide here, the
|
||||
greater chance your proposal has of being discussed. Feature requests which don't include an
|
||||
actionable implementation plan will be rejected.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Use case
|
||||
description: >
|
||||
Explain how adding this functionality would benefit NetBox Topology Views users. What need does it address?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: External dependencies
|
||||
description: >
|
||||
List any new dependencies on external libraries or services that this new feature would
|
||||
introduce. For example, does the proposal require the installation of a new Python package?
|
||||
(Not all new features introduce new dependencies.)
|
||||
@@ -0,0 +1,21 @@
|
||||
<!--
|
||||
IMPORTANT:
|
||||
==========
|
||||
Thank you for contributing to NetBox Topology Views! Please
|
||||
note that our contribution guidelines require a feature
|
||||
request or bug report to be labeled "status: accepted". This
|
||||
helps avoid waste time and effort on a proposed change that
|
||||
we might not be able to accept.
|
||||
|
||||
Please prefix the title of your pull request according to
|
||||
it's type. You should use "Closes #FEATURE_ID: ..." for feature
|
||||
requests and "Fixes #ISSUE_ID: ..." for issues. This helps
|
||||
us closing issues automatically after merging.
|
||||
|
||||
To sum it up:
|
||||
1. Create Bug Report or Feature Request
|
||||
2. Wait until the issue has been labeled "status: accepted"
|
||||
3. Start working on the issue in a seperate branch
|
||||
3. Create a pull request and name the title with a prefix
|
||||
according to the issue ID.
|
||||
-->
|
||||
@@ -1,93 +0,0 @@
|
||||
name: Docker
|
||||
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '35 10 * * *'
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
# This is used to complete the identity challenge
|
||||
# with sigstore/fulcio when running outside of PRs.
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Install the cosign tool except on PR
|
||||
# https://github.com/sigstore/cosign-installer
|
||||
- name: Install cosign
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: sigstore/cosign-installer@7e0881f8fe90b25e305bbf0309761e9314607e25
|
||||
with:
|
||||
cosign-release: 'v1.9.0'
|
||||
|
||||
|
||||
# Workaround: https://github.com/docker/build-push-action/issues/461
|
||||
- name: Setup Docker buildx
|
||||
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf
|
||||
|
||||
# Login against a Docker registry except on PR
|
||||
# https://github.com/docker/login-action
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Extract metadata (tags, labels) for Docker
|
||||
# https://github.com/docker/metadata-action
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
# Build and push Docker image with Buildx (don't push on PR)
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
# Sign the resulting Docker image digest except on PRs.
|
||||
# This will only write to the public Rekor transparency log when the Docker
|
||||
# repository is public to avoid leaking data. If you would like to publish
|
||||
# transparency data even for private images, pass --force to cosign below.
|
||||
# https://github.com/sigstore/cosign
|
||||
- name: Sign the published Docker image
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: "true"
|
||||
# This step uses the identity token to provision an ephemeral certificate
|
||||
# against the sigstore community Fulcio instance.
|
||||
run: cosign sign ${{ steps.meta.outputs.tags }}@${{ steps.build-and-push.outputs.digest }}
|
||||
@@ -1,4 +0,0 @@
|
||||
FROM netboxcommunity/netbox:latest
|
||||
|
||||
COPY ./docker/plugin_requirements.txt /
|
||||
RUN /opt/netbox/venv/bin/pip install --no-warn-script-location -r /plugin_requirements.txt
|
||||
@@ -12,6 +12,8 @@ Support to filter on name, site, tag and device role.
|
||||
|
||||
## Install
|
||||
|
||||
**_NOTE:_** For docker please see: [Docker install](https://github.com/netbox-community/netbox-docker/wiki/Using-Netbox-Plugins)
|
||||
|
||||
The plugin is available as a Python package and can be installed with pip.
|
||||
|
||||
Run `pip install netbox-topology-views` in your virtual env.
|
||||
@@ -44,6 +46,7 @@ python3 manage.py collectstatic --no-input
|
||||
|
||||
| netbox version | netbox-topology-views version |
|
||||
| -------------- | ----------------------------- |
|
||||
| >= 3.4.0 | >= v3.X.X |
|
||||
| >= 3.3.0 | >= v3.0.0 |
|
||||
| >= 3.2.0 | >= v1.1.0 |
|
||||
| >= 3.1.8 | >= v1.0.0 |
|
||||
@@ -85,6 +88,9 @@ PLUGINS_CONFIG = {
|
||||
| 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) |
|
||||
| hide_single_cable_logical_conns | False | (bool) Set to True if you want to hide duplicate cables & logical connections |
|
||||
|
||||
|
||||
|
||||
### Custom Images
|
||||
|
||||
@@ -94,6 +100,31 @@ To change image with associated device use the `Images` page - it allows to map
|
||||
|
||||
Go to the plugins tab in the navbar and click topology or go to `$NETBOX_URL/plugins/netbox_topology_views/` to view your topologies
|
||||
|
||||
Select your options for the topology view:
|
||||
|
||||

|
||||
|
||||
<dl>
|
||||
<dt>Hide Unconnected</dt>
|
||||
<dd>Hide devices which have no connections.</dd>
|
||||
<dt>Save Coordinates</dt>
|
||||
<dd>Save the coordinates of devices in the topology view.</dd>
|
||||
<dd>Please read the "Configure" chapter to set the allow_coordinates_saving option to True.</dd>
|
||||
<dt>Show Cables</dt>
|
||||
<dd>Show cable connections between devices, including cables connected to interfaces, front / rear ports, etc., in the topology view</dd>
|
||||
<dt>Show Logical Connections</dt>
|
||||
<dd>Show logical connections between interfaces (referred to as Interface Connections in NetBox) in the topology view. Where the path between
|
||||
interfaces includes multiple cables (e.g., via patch panels), only the end interface connections are shown, not the
|
||||
intermediate front / rear port connections, etc. This is similar to what was referred to as 'end-to-end' connections in previous versions. </dd>
|
||||
<dd><i>Selecting both 'Show Cables' and 'Show Logical Interfaces' will sometimes result in a topology view with 2 cables per connection as these devices are diretly connected. Select only one of the options or set `hide_single_cable_logical_conns` to True.</i></dd>
|
||||
<dt>Show Circuit Terminations</dt>
|
||||
<dd>Show connections which end at a circuit termination in the topology view.</dd>
|
||||
<dt>Show Wireless Links</dt>
|
||||
<dd>Show wireless connections in the topology view.</dd>
|
||||
<dt>Show Power Feeds</dt>
|
||||
<dd>Show power connections from power feeds in the topology view.</dd>
|
||||
</dl>
|
||||
|
||||
### Update
|
||||
|
||||
Run `pip install netbox-topology-views --upgrade` in your venv.
|
||||
|
||||
+138
-18
@@ -1,23 +1,143 @@
|
||||
# Setup Dev
|
||||
+ install docker
|
||||
+ install docker compose
|
||||
+ install npm
|
||||
+ enable yarn
|
||||
+ clone netbox repo
|
||||
+ clone netbox_topology_views repo
|
||||
+ create venv: `/usr/bin/python3 -m venv venv`
|
||||
+ activate venv: `source venv/bin/activate`
|
||||
+ install deps: `pip3 install -r requirements.txt`
|
||||
+ install build tools: `python3 -m pip install --upgrade build setuptools wheel`
|
||||
|
||||
We will assume that you work in the folder `~/code/netbox_plugin/`, change this if you use another folder for your projects/code.
|
||||
|
||||
## Setup native prerequisites
|
||||
**_NOTE:_** these requirements are needed if you want install Postgresql & Redis native. Check the steps for docker & docker-compose if you don't want this.
|
||||
|
||||
Make sure that you have already installed Postgresql and Redis. Also make sure that the database has already been created and privileges has been granted as described in the NetBox installation instructions at https://docs.netbox.dev/en/stable/installation/.
|
||||
|
||||
In short:
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install -y postgresql
|
||||
sudo systemctl start postgresql
|
||||
sudo systemctl enable postgresql
|
||||
|
||||
sudo -u postgres psql
|
||||
CREATE DATABASE netbox;
|
||||
CREATE USER netbox WITH PASSWORD 'J5brHrAXFLQSif0K';
|
||||
GRANT ALL PRIVILEGES ON DATABASE netbox TO netbox;
|
||||
|
||||
sudo apt install -y redis-server
|
||||
```
|
||||
|
||||
## Setup docker prerequisites
|
||||
|
||||
**_NOTE:_** if you used the 'native' prerequisites you can skip these steps below
|
||||
|
||||
### Docker
|
||||
This depends on your OS or how you want to install docker.
|
||||
See https://docs.docker.com/engine/install/ to find the install steps.
|
||||
|
||||
### Docker compose
|
||||
This also depends on your OS, see the link below:
|
||||
https://docs.docker.com/compose/install/linux/
|
||||
|
||||
## Create the base folder
|
||||
```
|
||||
mkdir ~/code/netbox_plugin/
|
||||
cd ~/code/netbox_plugin/
|
||||
```
|
||||
|
||||
## Install requirements
|
||||
### Python + deps
|
||||
You will need the following packages installed:
|
||||
+ python3-venv
|
||||
+ python3
|
||||
|
||||
Install them with your OS package manager (apt, yum, ...)
|
||||
|
||||
|
||||
### NPM (with nvm)
|
||||
Follow the steps on the repo below to install npm:
|
||||
https://github.com/nvm-sh/nvm#installing-and-updating
|
||||
|
||||
|
||||
## Create venv
|
||||
```
|
||||
python3 -m venv ~/code/netbox_plugin/.venvs/netbox
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
```
|
||||
|
||||
## Setup netbox
|
||||
### Clone netbox repo
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
git clone git@github.com:netbox-community/netbox.git netbox
|
||||
```
|
||||
### Install deps
|
||||
```
|
||||
cd netbox
|
||||
python3 -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
|
||||
## Setup plugin
|
||||
### Clone netbox-topology-views repo
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
git clone git@github.com:mattieserver/netbox-topology-views.git plugin
|
||||
```
|
||||
### Install deps
|
||||
```
|
||||
python3 -m pip install --upgrade build setuptools wheel
|
||||
```
|
||||
### Copy netbox config file
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
cp plugin/dev_setup/configuration.py netbox/netbox/netbox/configuration.py
|
||||
```
|
||||
|
||||
## Start netbox
|
||||
### Start docker compose
|
||||
**_NOTE:_** if you used the 'native' prerequisites you can skip to 'Start netbox'
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
cd plugin/dev_setup
|
||||
docker-compose up -d
|
||||
```
|
||||
### Start netbox
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
cd netbox/netbox/
|
||||
python3 manage.py migrate
|
||||
python3 manage.py runserver
|
||||
```
|
||||
You might need to create a superuser if you want to start with an empty database: `python3 manage.py createsuperuser`
|
||||
|
||||
# Build
|
||||
+ build the package: `python3 setup.py develop`
|
||||
+ build the resources `yarn run bundle`
|
||||
|
||||
# Test
|
||||
+ copy configuration.py from dev_setup to the netbox/netbox/ folder
|
||||
+ run in the netbox repo: `python3 netbox/manage.py migrate`
|
||||
+ (first time only) run in the netbox repo: `python3 netbox/manage.py createsuperuser`
|
||||
+ run in the netbox repo: `python3 netbox/manage.py runserver`
|
||||
+ browse to http://127.0.0.1:8000
|
||||
## Build the plugin
|
||||
|
||||
```
|
||||
cd ~/code/netbox_plugin/
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
cd plugin/
|
||||
python3 setup.py develop
|
||||
```
|
||||
|
||||
## Build javascript
|
||||
```
|
||||
cd plugin/netbox_topology_views/static_dev
|
||||
npm install
|
||||
npm run bundle
|
||||
```
|
||||
|
||||
### Test
|
||||
You can now browse to http://localhost:8000.
|
||||
The plugin should be available in the menu.
|
||||
|
||||
# Import demo data
|
||||
If you want to add demo data instead of your own data, there's an official Repository you can use. The following example shows how to add demo data for NetBox v3.4. You have to use the json file according to the version you are working on.
|
||||
|
||||
```
|
||||
~/code/netbox_plugin/
|
||||
git clone git@github.com:netbox-community/netbox-demo-data.git demodata
|
||||
source ~/code/netbox_plugin/.venvs/netbox/bin/activate
|
||||
cd netbox/netbox/
|
||||
python3 manage.py loaddata -v 3 ~/src/netbox-demo-data/netbox-demo-v3.4.json
|
||||
```
|
||||
|
||||
Please note that the demo data adds a superuser with credentials admin/admin.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
@@ -1 +0,0 @@
|
||||
netbox-topology-views
|
||||
@@ -5,7 +5,7 @@ class TopologyViewsConfig(PluginConfig):
|
||||
name = "netbox_topology_views"
|
||||
verbose_name = "Topology views"
|
||||
description = "An plugin to render topology maps"
|
||||
version = "3.1.0"
|
||||
version = "3.2.1"
|
||||
author = "Mattijs Vanhaverbeke"
|
||||
author_email = "author@example.com"
|
||||
base_url = "netbox_topology_views"
|
||||
@@ -29,6 +29,7 @@ class TopologyViewsConfig(PluginConfig):
|
||||
"always_save_coordinates": False,
|
||||
"preselected_tags": [],
|
||||
"draw_default_layout": False,
|
||||
"hide_single_cable_logical_conns": False,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,10 +31,14 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
||||
None,
|
||||
(
|
||||
"q",
|
||||
"filter_id",
|
||||
"hide_unconnected",
|
||||
"save_coords",
|
||||
"show_cables",
|
||||
"show_circuit",
|
||||
"show_logical_connections",
|
||||
"show_power",
|
||||
"show_wireless",
|
||||
),
|
||||
),
|
||||
(
|
||||
@@ -103,6 +107,15 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
||||
hide_unconnected = forms.BooleanField(
|
||||
label=_("Hide Unconnected"), required=False, initial=False
|
||||
)
|
||||
show_logical_connections = forms.BooleanField(
|
||||
label =_("Show Logical Connections"), required=False, initial=False
|
||||
)
|
||||
show_cables = forms.BooleanField(
|
||||
label =_("Show Cables"), required=False, initial=False
|
||||
)
|
||||
show_wireless = forms.BooleanField(
|
||||
label =_("Show Wireless Links"), required=False, initial=False
|
||||
)
|
||||
show_circuit = forms.BooleanField(
|
||||
label=_("Show Circuit Terminations"), required=False, initial=False
|
||||
)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from extras.plugins import PluginMenuItem
|
||||
from extras.plugins import PluginMenu, PluginMenuItem
|
||||
|
||||
menu_items = (
|
||||
PluginMenuItem(link="plugins:netbox_topology_views:home", link_text="Topology"),
|
||||
PluginMenuItem(
|
||||
link="plugins:netbox_topology_views:images", link_text="Topology Images"
|
||||
menu = PluginMenu(
|
||||
label='Topology Views',
|
||||
groups=(
|
||||
('Topology', (PluginMenuItem(link="plugins:netbox_topology_views:home", link_text="Topology"),),),
|
||||
('CUSTOMIZATION', (PluginMenuItem(link="plugins:netbox_topology_views:images", link_text="Topology Images"),),),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1 +1 @@
|
||||
#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}
|
||||
#visgraph{height:64vh}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}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
#visgraph {
|
||||
height: 70vh;
|
||||
height: 64vh;
|
||||
}
|
||||
|
||||
html[data-netbox-color-mode=dark] #visgraph {
|
||||
|
||||
@@ -70,8 +70,9 @@ const coordSaveCheckbox = document.querySelector('#id_save_coords')
|
||||
graph.fit()
|
||||
|
||||
graph.on('dragEnd', (params) => {
|
||||
if (coordSaveCheckbox == null) return
|
||||
if (!coordSaveCheckbox.checked) return
|
||||
|
||||
|
||||
Promise.allSettled(
|
||||
Object.entries(graph.getPositions(params.nodes)).map(
|
||||
async ([nodeId, nodePosition]) => {
|
||||
@@ -99,9 +100,16 @@ const coordSaveCheckbox = document.querySelector('#id_save_coords')
|
||||
})
|
||||
|
||||
graph.on('doubleClick', (params) => {
|
||||
params.nodes.forEach((node) => {
|
||||
window.open(nodes.get(node).href, '_blank')
|
||||
})
|
||||
if (params.nodes.length > 0) {
|
||||
params.nodes.forEach((node) => {
|
||||
window.open(nodes.get(node).href, '_blank')
|
||||
})
|
||||
}
|
||||
else {
|
||||
params.edges.forEach((edge) => {
|
||||
window.open(edges.get(edge).href, '_blank')
|
||||
})
|
||||
}
|
||||
})
|
||||
})()
|
||||
|
||||
|
||||
+486
-149
@@ -1,454 +1,791 @@
|
||||
{
|
||||
"name": "netbox_topology_views",
|
||||
"version": "3.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"version": "3.2.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@egjs/hammerjs": {
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "netbox_topology_views",
|
||||
"version": "3.2.0",
|
||||
"dependencies": {
|
||||
"vis-data": "^7.1.4",
|
||||
"vis-network": "^9.1.2",
|
||||
"vis-util": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@egjs/hammerjs": "^2.0.0",
|
||||
"component-emitter": "^1.3.0",
|
||||
"esbuild": "^0.12.24",
|
||||
"esbuild-sass-plugin": "^1.5.2",
|
||||
"keycharm": "^0.4.0",
|
||||
"timsort": "^0.3.0",
|
||||
"uuid": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@egjs/hammerjs": {
|
||||
"version": "2.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
|
||||
"integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@types/hammerjs": "^2.0.36"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"@esbuild/linux-loong64": {
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz",
|
||||
"integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"@types/hammerjs": {
|
||||
"node_modules/@types/hammerjs": {
|
||||
"version": "2.0.41",
|
||||
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
|
||||
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
|
||||
},
|
||||
"anymatch": {
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"binary-extensions": {
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"braces": {
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.10.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"component-emitter": {
|
||||
"node_modules/component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"esbuild": {
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.12.29",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.29.tgz",
|
||||
"integrity": "sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
}
|
||||
},
|
||||
"esbuild-android-64": {
|
||||
"node_modules/esbuild-android-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz",
|
||||
"integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-android-arm64": {
|
||||
"node_modules/esbuild-android-arm64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz",
|
||||
"integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-darwin-64": {
|
||||
"node_modules/esbuild-darwin-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz",
|
||||
"integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-darwin-arm64": {
|
||||
"node_modules/esbuild-darwin-arm64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz",
|
||||
"integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-freebsd-64": {
|
||||
"node_modules/esbuild-freebsd-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz",
|
||||
"integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-freebsd-arm64": {
|
||||
"node_modules/esbuild-freebsd-arm64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz",
|
||||
"integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-32": {
|
||||
"node_modules/esbuild-linux-32": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz",
|
||||
"integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-64": {
|
||||
"node_modules/esbuild-linux-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz",
|
||||
"integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-arm": {
|
||||
"node_modules/esbuild-linux-arm": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz",
|
||||
"integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-arm64": {
|
||||
"node_modules/esbuild-linux-arm64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz",
|
||||
"integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-mips64le": {
|
||||
"node_modules/esbuild-linux-mips64le": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz",
|
||||
"integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-ppc64le": {
|
||||
"node_modules/esbuild-linux-ppc64le": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz",
|
||||
"integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-riscv64": {
|
||||
"node_modules/esbuild-linux-riscv64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz",
|
||||
"integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-linux-s390x": {
|
||||
"node_modules/esbuild-linux-s390x": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz",
|
||||
"integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-netbsd-64": {
|
||||
"node_modules/esbuild-netbsd-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz",
|
||||
"integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-openbsd-64": {
|
||||
"node_modules/esbuild-openbsd-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz",
|
||||
"integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-sass-plugin": {
|
||||
"node_modules/esbuild-sass-plugin": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sass-plugin/-/esbuild-sass-plugin-1.8.2.tgz",
|
||||
"integrity": "sha512-ZBjONsRSpmzMKvxSNohnNXCNaBBVlYLqYhyZtN8leGGkJktCvVMKC6g9V5TWIemk1SEaW2XK+YFxz3Whw3+YYw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"esbuild": "^0.14.5",
|
||||
"picomatch": "^2.3.0",
|
||||
"resolve": "^1.20.0",
|
||||
"sass": "^1.45.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"esbuild": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz",
|
||||
"integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@esbuild/linux-loong64": "0.14.54",
|
||||
"esbuild-android-64": "0.14.54",
|
||||
"esbuild-android-arm64": "0.14.54",
|
||||
"esbuild-darwin-64": "0.14.54",
|
||||
"esbuild-darwin-arm64": "0.14.54",
|
||||
"esbuild-freebsd-64": "0.14.54",
|
||||
"esbuild-freebsd-arm64": "0.14.54",
|
||||
"esbuild-linux-32": "0.14.54",
|
||||
"esbuild-linux-64": "0.14.54",
|
||||
"esbuild-linux-arm": "0.14.54",
|
||||
"esbuild-linux-arm64": "0.14.54",
|
||||
"esbuild-linux-mips64le": "0.14.54",
|
||||
"esbuild-linux-ppc64le": "0.14.54",
|
||||
"esbuild-linux-riscv64": "0.14.54",
|
||||
"esbuild-linux-s390x": "0.14.54",
|
||||
"esbuild-netbsd-64": "0.14.54",
|
||||
"esbuild-openbsd-64": "0.14.54",
|
||||
"esbuild-sunos-64": "0.14.54",
|
||||
"esbuild-windows-32": "0.14.54",
|
||||
"esbuild-windows-64": "0.14.54",
|
||||
"esbuild-windows-arm64": "0.14.54"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"esbuild-sunos-64": {
|
||||
"node_modules/esbuild-sass-plugin/node_modules/esbuild": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz",
|
||||
"integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/linux-loong64": "0.14.54",
|
||||
"esbuild-android-64": "0.14.54",
|
||||
"esbuild-android-arm64": "0.14.54",
|
||||
"esbuild-darwin-64": "0.14.54",
|
||||
"esbuild-darwin-arm64": "0.14.54",
|
||||
"esbuild-freebsd-64": "0.14.54",
|
||||
"esbuild-freebsd-arm64": "0.14.54",
|
||||
"esbuild-linux-32": "0.14.54",
|
||||
"esbuild-linux-64": "0.14.54",
|
||||
"esbuild-linux-arm": "0.14.54",
|
||||
"esbuild-linux-arm64": "0.14.54",
|
||||
"esbuild-linux-mips64le": "0.14.54",
|
||||
"esbuild-linux-ppc64le": "0.14.54",
|
||||
"esbuild-linux-riscv64": "0.14.54",
|
||||
"esbuild-linux-s390x": "0.14.54",
|
||||
"esbuild-netbsd-64": "0.14.54",
|
||||
"esbuild-openbsd-64": "0.14.54",
|
||||
"esbuild-sunos-64": "0.14.54",
|
||||
"esbuild-windows-32": "0.14.54",
|
||||
"esbuild-windows-64": "0.14.54",
|
||||
"esbuild-windows-arm64": "0.14.54"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-sunos-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz",
|
||||
"integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-windows-32": {
|
||||
"node_modules/esbuild-windows-32": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz",
|
||||
"integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-windows-64": {
|
||||
"node_modules/esbuild-windows-64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz",
|
||||
"integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"esbuild-windows-arm64": {
|
||||
"node_modules/esbuild-windows-arm64": {
|
||||
"version": "0.14.54",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz",
|
||||
"integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"glob-parent": {
|
||||
"node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"has": {
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"immutable": {
|
||||
"node_modules/immutable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
|
||||
"integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-binary-path": {
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"is-core-module": {
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
|
||||
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"is-extglob": {
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"is-glob": {
|
||||
"node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"keycharm": {
|
||||
"node_modules/keycharm": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz",
|
||||
"integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ=="
|
||||
},
|
||||
"normalize-path": {
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"path-parse": {
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"picomatch": {
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"readdirp": {
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
|
||||
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.9.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"sass": {
|
||||
"node_modules/sass": {
|
||||
"version": "1.56.2",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.56.2.tgz",
|
||||
"integrity": "sha512-ciEJhnyCRwzlBCB+h5cCPM6ie/6f8HrhZMQOf5vlU60Y1bI1rx5Zb0vlDZvaycHsg/MqFfF1Eq2eokAa32iw8w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"sass": "sass.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"source-map-js": {
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"supports-preserve-symlinks-flag": {
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"timsort": {
|
||||
"node_modules/timsort": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
||||
"integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A=="
|
||||
},
|
||||
"to-regex-range": {
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"vis-data": {
|
||||
"node_modules/vis-data": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.4.tgz",
|
||||
"integrity": "sha512-usy+ePX1XnArNvJ5BavQod7YRuGQE1pjFl+pu7IS6rCom2EBoG0o1ZzCqf3l5US6MW51kYkLR+efxRbnjxNl7w=="
|
||||
"integrity": "sha512-usy+ePX1XnArNvJ5BavQod7YRuGQE1pjFl+pu7IS6rCom2EBoG0o1ZzCqf3l5US6MW51kYkLR+efxRbnjxNl7w==",
|
||||
"hasInstallScript": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/visjs"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"uuid": "^7.0.0 || ^8.0.0",
|
||||
"vis-util": "^4.0.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"vis-network": {
|
||||
"node_modules/vis-network": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vis-network/-/vis-network-9.1.2.tgz",
|
||||
"integrity": "sha512-BdapguKg7sk3NvdZaDsM7T6rNhOBFz0/F4ZScxctK4klRzQPLQPTEcmbioXaZhMkkgWymzBR3lFCxL1q+eYyAw=="
|
||||
"integrity": "sha512-BdapguKg7sk3NvdZaDsM7T6rNhOBFz0/F4ZScxctK4klRzQPLQPTEcmbioXaZhMkkgWymzBR3lFCxL1q+eYyAw==",
|
||||
"hasInstallScript": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/visjs"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@egjs/hammerjs": "^2.0.0",
|
||||
"component-emitter": "^1.3.0",
|
||||
"keycharm": "^0.2.0 || ^0.3.0 || ^0.4.0",
|
||||
"timsort": "^0.3.0",
|
||||
"uuid": "^3.4.0 || ^7.0.0 || ^8.0.0",
|
||||
"vis-data": "^7.0.0",
|
||||
"vis-util": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"vis-util": {
|
||||
"node_modules/vis-util": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.3.tgz",
|
||||
"integrity": "sha512-Wf9STUcFrDzK4/Zr7B6epW2Kvm3ORNWF+WiwEz2dpf5RdWkLUXFSbLcuB88n1W6tCdFwVN+v3V4/Xmn9PeL39g=="
|
||||
"integrity": "sha512-Wf9STUcFrDzK4/Zr7B6epW2Kvm3ORNWF+WiwEz2dpf5RdWkLUXFSbLcuB88n1W6tCdFwVN+v3V4/Xmn9PeL39g==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/visjs"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@egjs/hammerjs": "^2.0.0",
|
||||
"component-emitter": "^1.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "netbox_topology_views",
|
||||
"version": "3.1.0",
|
||||
"version": "3.2.1",
|
||||
"scripts": {
|
||||
"bundle": "node bundle.js",
|
||||
"bundle:styles": "node bundle.js --styles",
|
||||
|
||||
@@ -4,44 +4,39 @@
|
||||
|
||||
"@egjs/hammerjs@^2.0.0":
|
||||
version "2.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124"
|
||||
resolved "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz"
|
||||
integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==
|
||||
dependencies:
|
||||
"@types/hammerjs" "^2.0.36"
|
||||
|
||||
"@esbuild/linux-loong64@0.14.53":
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz#251b4cd6760fadb4d68a05815e6dc5e432d69cd6"
|
||||
integrity sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==
|
||||
|
||||
"@types/hammerjs@^2.0.36":
|
||||
version "2.0.41"
|
||||
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.41.tgz#f6ecf57d1b12d2befcce00e928a6a097c22980aa"
|
||||
resolved "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz"
|
||||
integrity sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"
|
||||
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
braces@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
"chokidar@>=3.0.0 <4.0.0":
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz"
|
||||
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
@@ -56,92 +51,17 @@ braces@~3.0.2:
|
||||
|
||||
component-emitter@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
|
||||
resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz"
|
||||
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
|
||||
|
||||
esbuild-android-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz#259bc3ef1399a3cad8f4f67c40ee20779c4de675"
|
||||
integrity sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==
|
||||
|
||||
esbuild-android-arm64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz#2158253d4e8f9fdd2a081bbb4f73b8806178841e"
|
||||
integrity sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==
|
||||
|
||||
esbuild-darwin-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz#b4681831fd8f8d06feb5048acbe90d742074cc2a"
|
||||
integrity sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==
|
||||
|
||||
esbuild-darwin-arm64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz#d267d957852d121b261b3f76ead86e5b5463acc9"
|
||||
integrity sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==
|
||||
|
||||
esbuild-freebsd-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz#aca2af6d72b537fe66a38eb8f374fb66d4c98ca0"
|
||||
integrity sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==
|
||||
|
||||
esbuild-freebsd-arm64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz#76282e19312d914c34343c8a7da6cc5f051580b9"
|
||||
integrity sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==
|
||||
|
||||
esbuild-linux-32@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz#1045d34cf7c5faaf2af3b29cc1573b06580c37e5"
|
||||
integrity sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==
|
||||
|
||||
esbuild-linux-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz#ab3f2ee2ebb5a6930c72d9539cb34b428808cbe4"
|
||||
integrity sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==
|
||||
|
||||
esbuild-linux-arm64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz#1f5530412f6690949e78297122350488d3266cfe"
|
||||
integrity sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==
|
||||
|
||||
esbuild-linux-arm@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz#a44ec9b5b42007ab6c0d65a224ccc6bbd97c54cf"
|
||||
integrity sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==
|
||||
|
||||
esbuild-linux-mips64le@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz#a4d0b6b17cfdeea4e41b0b085a5f73d99311be9f"
|
||||
integrity sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==
|
||||
|
||||
esbuild-linux-ppc64le@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz#8c331822c85465434e086e3e6065863770c38139"
|
||||
integrity sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==
|
||||
|
||||
esbuild-linux-riscv64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz#36fd75543401304bea8a2d63bf8ea18aaa508e00"
|
||||
integrity sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==
|
||||
|
||||
esbuild-linux-s390x@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz#1622677ab6824123f48f75d3afc031cd41936129"
|
||||
integrity sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==
|
||||
|
||||
esbuild-netbsd-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz#e86d0efd0116658be335492ed12e66b26b4baf52"
|
||||
integrity sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==
|
||||
|
||||
esbuild-openbsd-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz#9bcbbe6f86304872c6e91f64c8eb73fc29c3588b"
|
||||
integrity sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==
|
||||
esbuild-linux-64@0.14.54:
|
||||
version "0.14.54"
|
||||
resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz"
|
||||
integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==
|
||||
|
||||
esbuild-sass-plugin@^1.5.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-sass-plugin/-/esbuild-sass-plugin-1.8.2.tgz#76babbd6d4c87ffd14259fd364d446f857b3f513"
|
||||
resolved "https://registry.npmjs.org/esbuild-sass-plugin/-/esbuild-sass-plugin-1.8.2.tgz"
|
||||
integrity sha512-ZBjONsRSpmzMKvxSNohnNXCNaBBVlYLqYhyZtN8leGGkJktCvVMKC6g9V5TWIemk1SEaW2XK+YFxz3Whw3+YYw==
|
||||
dependencies:
|
||||
esbuild "^0.14.5"
|
||||
@@ -149,155 +69,130 @@ esbuild-sass-plugin@^1.5.2:
|
||||
resolve "^1.20.0"
|
||||
sass "^1.45.0"
|
||||
|
||||
esbuild-sunos-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz#f7a872f7460bfb7b131f7188a95fbce3d1c577e8"
|
||||
integrity sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==
|
||||
|
||||
esbuild-windows-32@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz#c5e3ca50e2d1439cc2c9fe4defa63bcd474ce709"
|
||||
integrity sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==
|
||||
|
||||
esbuild-windows-64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz#ec2ab4a60c5215f092ffe1eab6d01319e88238af"
|
||||
integrity sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==
|
||||
|
||||
esbuild-windows-arm64@0.14.53:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz#f71d403806bdf9f4a1f9d097db9aec949bd675c8"
|
||||
integrity sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==
|
||||
|
||||
esbuild@^0.12.24:
|
||||
version "0.12.29"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.29.tgz#be602db7c4dc78944a9dbde0d1ea19d36c1f882d"
|
||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.29.tgz"
|
||||
integrity sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==
|
||||
|
||||
esbuild@^0.14.5:
|
||||
version "0.14.53"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.53.tgz#20b1007f686e8584f2a01a1bec5a37aac9498ce4"
|
||||
integrity sha512-ohO33pUBQ64q6mmheX1mZ8mIXj8ivQY/L4oVuAshr+aJI+zLl+amrp3EodrUNDNYVrKJXGPfIHFGhO8slGRjuw==
|
||||
version "0.14.54"
|
||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz"
|
||||
integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==
|
||||
optionalDependencies:
|
||||
"@esbuild/linux-loong64" "0.14.53"
|
||||
esbuild-android-64 "0.14.53"
|
||||
esbuild-android-arm64 "0.14.53"
|
||||
esbuild-darwin-64 "0.14.53"
|
||||
esbuild-darwin-arm64 "0.14.53"
|
||||
esbuild-freebsd-64 "0.14.53"
|
||||
esbuild-freebsd-arm64 "0.14.53"
|
||||
esbuild-linux-32 "0.14.53"
|
||||
esbuild-linux-64 "0.14.53"
|
||||
esbuild-linux-arm "0.14.53"
|
||||
esbuild-linux-arm64 "0.14.53"
|
||||
esbuild-linux-mips64le "0.14.53"
|
||||
esbuild-linux-ppc64le "0.14.53"
|
||||
esbuild-linux-riscv64 "0.14.53"
|
||||
esbuild-linux-s390x "0.14.53"
|
||||
esbuild-netbsd-64 "0.14.53"
|
||||
esbuild-openbsd-64 "0.14.53"
|
||||
esbuild-sunos-64 "0.14.53"
|
||||
esbuild-windows-32 "0.14.53"
|
||||
esbuild-windows-64 "0.14.53"
|
||||
esbuild-windows-arm64 "0.14.53"
|
||||
"@esbuild/linux-loong64" "0.14.54"
|
||||
esbuild-android-64 "0.14.54"
|
||||
esbuild-android-arm64 "0.14.54"
|
||||
esbuild-darwin-64 "0.14.54"
|
||||
esbuild-darwin-arm64 "0.14.54"
|
||||
esbuild-freebsd-64 "0.14.54"
|
||||
esbuild-freebsd-arm64 "0.14.54"
|
||||
esbuild-linux-32 "0.14.54"
|
||||
esbuild-linux-64 "0.14.54"
|
||||
esbuild-linux-arm "0.14.54"
|
||||
esbuild-linux-arm64 "0.14.54"
|
||||
esbuild-linux-mips64le "0.14.54"
|
||||
esbuild-linux-ppc64le "0.14.54"
|
||||
esbuild-linux-riscv64 "0.14.54"
|
||||
esbuild-linux-s390x "0.14.54"
|
||||
esbuild-netbsd-64 "0.14.54"
|
||||
esbuild-openbsd-64 "0.14.54"
|
||||
esbuild-sunos-64 "0.14.54"
|
||||
esbuild-windows-32 "0.14.54"
|
||||
esbuild-windows-64 "0.14.54"
|
||||
esbuild-windows-arm64 "0.14.54"
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
|
||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
immutable@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef"
|
||||
resolved "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz"
|
||||
integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
|
||||
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-core-module@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
||||
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
|
||||
version "2.11.0"
|
||||
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz"
|
||||
integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
keycharm@^0.4.0:
|
||||
"keycharm@^0.2.0 || ^0.3.0 || ^0.4.0", keycharm@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/keycharm/-/keycharm-0.4.0.tgz#8d684ea9cc01379a07fbddee33ff32d97f5ae2a7"
|
||||
resolved "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz"
|
||||
integrity sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
path-parse@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
|
||||
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
resolve@^1.20.0:
|
||||
version "1.22.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
|
||||
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz"
|
||||
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
|
||||
dependencies:
|
||||
is-core-module "^2.9.0"
|
||||
@@ -305,9 +200,9 @@ resolve@^1.20.0:
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
sass@^1.45.0:
|
||||
version "1.54.1"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.1.tgz#4f72ef57ce2a6c3251f4e2c75eee9a0c19e09eb5"
|
||||
integrity sha512-GHJJr31Me32RjjUBagyzx8tzjKBUcDwo5239XANIRBq0adDu5iIG0aFO0i/TBb/4I9oyxkEv44nq/kL1DxdDhA==
|
||||
version "1.56.2"
|
||||
resolved "https://registry.npmjs.org/sass/-/sass-1.56.2.tgz"
|
||||
integrity sha512-ciEJhnyCRwzlBCB+h5cCPM6ie/6f8HrhZMQOf5vlU60Y1bI1rx5Zb0vlDZvaycHsg/MqFfF1Eq2eokAa32iw8w==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
@@ -315,42 +210,42 @@ sass@^1.45.0:
|
||||
|
||||
"source-map-js@>=0.6.2 <2.0.0":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
||||
supports-preserve-symlinks-flag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
timsort@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||
resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz"
|
||||
integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
|
||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
uuid@^8.0.0:
|
||||
"uuid@^3.4.0 || ^7.0.0 || ^8.0.0", "uuid@^7.0.0 || ^8.0.0", uuid@^8.0.0:
|
||||
version "8.3.2"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
vis-data@^7.1.4:
|
||||
vis-data@^7.0.0, vis-data@^7.1.4:
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/vis-data/-/vis-data-7.1.4.tgz#90e5e796a79e1901de14c0808fb32a1a0735c1dc"
|
||||
resolved "https://registry.npmjs.org/vis-data/-/vis-data-7.1.4.tgz"
|
||||
integrity sha512-usy+ePX1XnArNvJ5BavQod7YRuGQE1pjFl+pu7IS6rCom2EBoG0o1ZzCqf3l5US6MW51kYkLR+efxRbnjxNl7w==
|
||||
|
||||
vis-network@^9.1.2:
|
||||
version "9.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vis-network/-/vis-network-9.1.2.tgz#ddaca300a9764bbf1646a0aa03eb28fe55823ca8"
|
||||
resolved "https://registry.npmjs.org/vis-network/-/vis-network-9.1.2.tgz"
|
||||
integrity sha512-BdapguKg7sk3NvdZaDsM7T6rNhOBFz0/F4ZScxctK4klRzQPLQPTEcmbioXaZhMkkgWymzBR3lFCxL1q+eYyAw==
|
||||
|
||||
vis-util@^5.0.3:
|
||||
"vis-util@^4.0.0 || ^5.0.0", vis-util@^5.0.1, vis-util@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vis-util/-/vis-util-5.0.3.tgz#6a9d67c6ed92f2bfa67e50c20166bb5f59ac07bf"
|
||||
resolved "https://registry.npmjs.org/vis-util/-/vis-util-5.0.3.tgz"
|
||||
integrity sha512-Wf9STUcFrDzK4/Zr7B6epW2Kvm3ORNWF+WiwEz2dpf5RdWkLUXFSbLcuB88n1W6tCdFwVN+v3V4/Xmn9PeL39g==
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
from extras.plugins import PluginTemplateExtension
|
||||
from django.conf import settings
|
||||
from packaging import version
|
||||
|
||||
NETBOX_CURRENT_VERSION = version.parse(settings.VERSION)
|
||||
|
||||
|
||||
class SiteButtons(PluginTemplateExtension):
|
||||
model = 'dcim.site'
|
||||
def buttons(self):
|
||||
return self.render('netbox_topology_views/site_button.html')
|
||||
|
||||
|
||||
template_extensions = [SiteButtons]
|
||||
@@ -0,0 +1,39 @@
|
||||
{% load static %}
|
||||
|
||||
<link rel="stylesheet" href="{% static 'netbox_topology_views/css/vendor.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'netbox_topology_views/css/app.css' %}">
|
||||
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Topology Views</h5>
|
||||
<div class="controls">
|
||||
<div class="control-group">
|
||||
{% block extra_controls %}{% endblock %}
|
||||
<a id="btnDownloadImage" class="btn btn-sm btn-info" href="#">
|
||||
<i class="mdi mdi-download"></i>
|
||||
Download
|
||||
</a>
|
||||
<a class="btn btn-sm btn-danger" data-bs-dismiss="modal">
|
||||
<i class="mdi mdi-close-thick"></i>
|
||||
Close
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" >
|
||||
<div style="max-width: 900px; height: 500px;">
|
||||
<div id="visgraph" style="width: 100%; height: 100%;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style type="text/css">
|
||||
.modal-dialog {
|
||||
max-width: 902px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
const brokenImage = '{{ broken_image }}';
|
||||
const topologyData = {{ topology_data | safe }};
|
||||
</script>
|
||||
<script src="{% static 'netbox_topology_views/js/app.js' %}?ver={{ epoch }} " defer></script>
|
||||
@@ -48,6 +48,12 @@
|
||||
{% with config=settings.PLUGINS_CONFIG.netbox_topology_views %}
|
||||
<div class="tab-content">
|
||||
|
||||
{# Applied filters #}
|
||||
{% if filter_form %}
|
||||
{% applied_filters model filter_form request.GET %}
|
||||
<hr style="margin-top: 0px;">
|
||||
{% endif %}
|
||||
|
||||
<div class="tab-pane show active" id="networks" role="tabpanel" aria-labelledby="network-tab">
|
||||
<div class="panel-body">
|
||||
<div id="visgraph"></div>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<a role="button" class="btn btn-sm btn-primary" title="Topology" href="#" hx-get="/plugins/netbox_topology_views/topology/?site_id={{ object.id }}&show_cables=on" hx-target="#htmx-modal-content" data-bs-toggle="modal" data-bs-target="#htmx-modal">
|
||||
<i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i>
|
||||
Topology
|
||||
</a>
|
||||
@@ -3,15 +3,26 @@ from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Type
|
||||
|
||||
import sys
|
||||
|
||||
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("/")
|
||||
if sys.version_info >= (3,9,0):
|
||||
CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / settings.PLUGINS_CONFIG[
|
||||
"netbox_topology_views"
|
||||
]["static_image_directory"].removeprefix("/")
|
||||
else:
|
||||
prefix = "/"
|
||||
plugin_path = settings.PLUGINS_CONFIG["netbox_topology_views"]["static_image_directory"]
|
||||
if plugin_path.startswith(prefix):
|
||||
plugin_path_new = plugin_path[len(prefix):]
|
||||
CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / plugin_path_new
|
||||
else:
|
||||
CONF_IMAGE_DIR: Path = Path(settings.STATIC_ROOT) / plugin_path
|
||||
|
||||
|
||||
def image_static_url(path: Path) -> str:
|
||||
@@ -21,7 +32,15 @@ def image_static_url(path: Path) -> str:
|
||||
|
||||
|
||||
def get_image_from_url(url: str) -> str:
|
||||
return url.removeprefix(settings.BASE_PATH + settings.STATIC_URL)
|
||||
url_path = settings.BASE_PATH + settings.STATIC_URL
|
||||
if sys.version_info >= (3,9,0):
|
||||
return url.removeprefix(url_path)
|
||||
else:
|
||||
if url.startswith(url_path):
|
||||
url_new = url[len(url_path):]
|
||||
return url_new
|
||||
else:
|
||||
return url
|
||||
|
||||
|
||||
IMAGE_FILETYPES = (
|
||||
|
||||
+206
-115
@@ -1,12 +1,15 @@
|
||||
import json
|
||||
from functools import reduce
|
||||
from typing import DefaultDict, Dict, Optional, Union
|
||||
import time
|
||||
|
||||
from utilities.htmx import is_htmx
|
||||
from circuits.models import Circuit, CircuitTermination
|
||||
from dcim.models import (
|
||||
Cable,
|
||||
CableTermination,
|
||||
Device,
|
||||
device_components,
|
||||
DeviceRole,
|
||||
FrontPort,
|
||||
Interface,
|
||||
@@ -175,6 +178,7 @@ def create_edge(
|
||||
cable: Optional[Cable] = None,
|
||||
wireless: Optional[Dict] = None,
|
||||
power: Optional[bool] = None,
|
||||
interface: Optional[bool] = None,
|
||||
):
|
||||
cable_a_name = (
|
||||
"device A name unknown"
|
||||
@@ -215,12 +219,21 @@ def create_edge(
|
||||
edge["dashes"] = [5, 5, 3, 3]
|
||||
title = "Power Connection"
|
||||
|
||||
elif interface is not None:
|
||||
title = "Interface Connection"
|
||||
edge["width"] = 3
|
||||
edge["dashes"] = [1, 10, 1, 10]
|
||||
edge["arrows"] = {"to": {"enabled": True, "scaleFactor": 0.5}, "from": {"enabled": True, "scaleFactor": 0.5}}
|
||||
edge["color"] = '#f1c232'
|
||||
|
||||
edge[
|
||||
"title"
|
||||
] = f"{title} between<br>{cable_a_dev_name} [{cable_a_name}]<br>{cable_b_dev_name} [{cable_b_name}]"
|
||||
|
||||
if cable is not None and cable.color != "":
|
||||
edge["color"] = "#" + cable.color
|
||||
if cable is not None:
|
||||
edge["href"] = cable.get_absolute_url()
|
||||
if hasattr(cable, 'color') and cable.color != "":
|
||||
edge["color"] = "#" + cable.color
|
||||
|
||||
return edge
|
||||
|
||||
@@ -249,8 +262,11 @@ def get_topology_data(
|
||||
queryset: QuerySet,
|
||||
hide_unconnected: bool,
|
||||
save_coords: bool,
|
||||
show_cables: bool,
|
||||
show_circuit: bool,
|
||||
show_logical_connections: bool,
|
||||
show_power: bool,
|
||||
show_wireless: bool,
|
||||
):
|
||||
if not queryset:
|
||||
return None
|
||||
@@ -264,9 +280,15 @@ def get_topology_data(
|
||||
nodes_powerfeed: Dict[int, PowerFeed] = {}
|
||||
nodes_provider_networks = {}
|
||||
cable_ids = DefaultDict(dict)
|
||||
interface_ids = DefaultDict(dict)
|
||||
ignore_cable_type = settings.PLUGINS_CONFIG["netbox_topology_views"][
|
||||
"ignore_cable_type"
|
||||
]
|
||||
hide_single_cable_logical_conns = bool(
|
||||
settings.PLUGINS_CONFIG["netbox_topology_views"][
|
||||
"hide_single_cable_logical_conns"
|
||||
]
|
||||
)
|
||||
|
||||
device_ids = [d.pk for d in queryset]
|
||||
site_ids = [d.site_id for d in queryset]
|
||||
@@ -312,6 +334,7 @@ def get_topology_data(
|
||||
edges.append(
|
||||
create_edge(
|
||||
edge_id=edge_ids,
|
||||
cable=circuit_termination.cable,
|
||||
circuit=circuit_model,
|
||||
termination_a=termination_a,
|
||||
termination_b=termination_b,
|
||||
@@ -343,15 +366,6 @@ def get_topology_data(
|
||||
for d in nodes_circuits.values():
|
||||
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)
|
||||
)
|
||||
|
||||
if show_power:
|
||||
power_panels_ids = PowerPanel.objects.filter(
|
||||
Q(site_id__in=site_ids)
|
||||
@@ -405,112 +419,154 @@ def get_topology_data(
|
||||
for d in nodes_powerpanel.values():
|
||||
nodes.append(create_node(d, save_coords))
|
||||
|
||||
for link in links:
|
||||
if link.termination_type.name in ignore_cable_type:
|
||||
continue
|
||||
|
||||
# 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] = {}
|
||||
else:
|
||||
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] = {}
|
||||
else:
|
||||
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
|
||||
|
||||
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,
|
||||
}
|
||||
else:
|
||||
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,
|
||||
}
|
||||
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,
|
||||
)
|
||||
)
|
||||
|
||||
for wlan_link in wlan_links:
|
||||
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,
|
||||
)
|
||||
if show_logical_connections:
|
||||
interfaces = Interface.objects.filter(
|
||||
Q(_path__is_complete=True) & Q(device_id__in=device_ids)
|
||||
)
|
||||
|
||||
for interface in interfaces:
|
||||
# print('{} {} {} {}'.format(interface.device.name, interface.name, interface._path.destinations[0].device.name, interface._path.destinations[0].name))
|
||||
for destination in interface._path.destinations:
|
||||
if isinstance(destination, device_components.Interface):
|
||||
if destination.device.id not in device_ids:
|
||||
# print('Destination interface not in device queryset, ignoring')
|
||||
continue
|
||||
|
||||
if destination.id in interface_ids:
|
||||
# we've already captured the destination interface, ignore this connection
|
||||
# print('Destination interface already exists, ignoring')
|
||||
continue
|
||||
|
||||
if hide_single_cable_logical_conns and interface.cable_id==destination.cable_id and show_cables:
|
||||
# interface connection is the same as the cable connection, ignore this connection
|
||||
continue
|
||||
|
||||
interface_ids[interface.id]=interface
|
||||
edge_ids += 1
|
||||
termination_a = { "termination_name": interface.name, "termination_device_name": interface.device.name, "device_id": interface.device.id }
|
||||
termination_b = { "termination_name": destination.name, "termination_device_name": destination.device.name, "device_id": destination.device.id }
|
||||
edges.append(create_edge(edge_id=edge_ids, termination_a=termination_a, termination_b=termination_b, interface=True))
|
||||
nodes_devices[interface.device.id] = interface.device
|
||||
nodes_devices[destination.device.id] = destination.device
|
||||
|
||||
if show_cables:
|
||||
links: QuerySet[CableTermination] = CableTermination.objects.filter(
|
||||
Q(_device_id__in=device_ids)
|
||||
).select_related("termination_type")
|
||||
|
||||
for link in links:
|
||||
if link.termination_type.name in ignore_cable_type:
|
||||
continue
|
||||
|
||||
# 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] = {}
|
||||
else:
|
||||
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] = {}
|
||||
else:
|
||||
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
|
||||
|
||||
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,
|
||||
}
|
||||
else:
|
||||
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,
|
||||
}
|
||||
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,
|
||||
)
|
||||
)
|
||||
|
||||
if show_wireless:
|
||||
wlan_links: QuerySet[WirelessLink] = WirelessLink.objects.filter(
|
||||
Q(_interface_a_device_id__in=device_ids)
|
||||
& Q(_interface_b_device_id__in=device_ids)
|
||||
)
|
||||
|
||||
for wlan_link in wlan_links:
|
||||
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,
|
||||
cable=wlan_link,
|
||||
termination_a=termination_a,
|
||||
termination_b=termination_b,
|
||||
wireless=wireless,
|
||||
)
|
||||
)
|
||||
|
||||
for qs_device in queryset:
|
||||
if qs_device.pk not in nodes_devices and not hide_unconnected:
|
||||
nodes_devices[qs_device.pk] = qs_device
|
||||
@@ -538,6 +594,7 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
||||
"device_type", "device_role"
|
||||
)
|
||||
self.queryset = self.filterset(request.GET, self.queryset).qs
|
||||
self.model = self.queryset.model
|
||||
topo_data = None
|
||||
|
||||
if request.GET:
|
||||
@@ -561,22 +618,43 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
||||
if request.GET["show_circuit"] == "on":
|
||||
show_circuit = True
|
||||
|
||||
show_logical_connections = False
|
||||
if "show_logical_connections" in request.GET:
|
||||
if request.GET["show_logical_connections"] == "on" :
|
||||
show_logical_connections = True
|
||||
|
||||
show_cables = False
|
||||
if "show_cables" in request.GET:
|
||||
if request.GET["show_cables"] == "on" :
|
||||
show_cables = True
|
||||
|
||||
show_wireless = False
|
||||
if "show_wireless" in request.GET:
|
||||
if request.GET["show_wireless"] == "on" :
|
||||
show_wireless = 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_cables,
|
||||
show_circuit,
|
||||
show_logical_connections,
|
||||
show_power,
|
||||
show_wireless,
|
||||
)
|
||||
else:
|
||||
topo_data = get_topology_data(
|
||||
self.queryset,
|
||||
hide_unconnected,
|
||||
save_coords,
|
||||
show_cables,
|
||||
show_circuit,
|
||||
show_logical_connections,
|
||||
show_power,
|
||||
show_wireless,
|
||||
)
|
||||
else:
|
||||
preselected_device_roles = settings.PLUGINS_CONFIG["netbox_topology_views"][
|
||||
@@ -609,6 +687,18 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
||||
query_string = q.urlencode()
|
||||
return HttpResponseRedirect(f"{request.path}?{query_string}")
|
||||
|
||||
if is_htmx(request):
|
||||
return render(
|
||||
request,
|
||||
"netbox_topology_views/htmx_topology.html",
|
||||
{
|
||||
"filter_form": DeviceFilterForm(request.GET, label_suffix=""),
|
||||
"topology_data": json.dumps(topo_data),
|
||||
"broken_image": find_image_url("role-unknown"),
|
||||
"epoch": int(time.time()),
|
||||
},
|
||||
)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"netbox_topology_views/index.html",
|
||||
@@ -616,6 +706,7 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
||||
"filter_form": DeviceFilterForm(request.GET, label_suffix=""),
|
||||
"topology_data": json.dumps(topo_data),
|
||||
"broken_image": find_image_url("role-unknown"),
|
||||
"model": self.model,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user