From 016bbd4380349ee80878295e6e6cd6ed0194f0f7 Mon Sep 17 00:00:00 2001 From: Arcuri Davide Date: Tue, 26 Mar 2024 11:09:36 +0100 Subject: [PATCH] 2.2.0 (#1069) * local files, nginx * api test code * vt/maxmind error, update notebook * python3.12 - go1.22 - ws updates * #1030 update - #947 method 1 * update libs * upgrade tree view * fix download dump error * keep pip for volatility for shared install path * improve plugin install, regipy plugins * fix admin upload plugins * #1068 * update changelog --------- --- .env.sample | 1 + .envs/.local/.django | 25 +- .gitignore | 7 +- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 17 +- compose/local/dask/Dockerfile | 10 +- compose/local/django/Dockerfile | 15 +- compose/local/django/start | 2 +- compose/local/nginx/Dockerfile | 19 + compose/local/nginx/conf/default.conf | 57 + config/routing.py | 10 +- config/settings/base.py | 15 +- config/settings/local.py | 2 +- docker-compose-swarm.yml | 6 +- docker-compose.yml | 81 +- examples/local_api.ipynb | 256 + orochi/static/README.txt | 7 +- orochi/static/css/jstree/32px.png | Bin 8740 -> 0 bytes orochi/static/css/jstree/40px.png | Bin 6055 -> 0 bytes orochi/static/css/jstree/style.min.css | 1 - orochi/static/css/jstree/throbber.gif | Bin 1849 -> 0 bytes orochi/static/css/style.css | 50 +- orochi/static/css/wunderbaum/wunderbaum.css | 701 ++ .../static/css/wunderbaum/wunderbaum.css.map | 1 + orochi/static/js/jstree/jstree.min.js | 3 - orochi/static/js/jstree/jstreetable.js | 1107 --- orochi/static/js/wunderbaum/wunderbaum.umd.js | 7881 +++++++++++++++++ .../js/wunderbaum/wunderbaum.umd.min.js | 86 + .../js/wunderbaum/wunderbaum.umd.min.js.map | 1 + orochi/templates/base.html | 29 +- orochi/templates/users/user_plugins.html | 17 +- orochi/templates/website/index.html | 26 +- orochi/templates/website/partial_folder.html | 2 +- orochi/templates/website/partial_indices.html | 7 +- orochi/templates/website/partial_info.html | 80 +- orochi/templates/website/partial_json.html | 7 + orochi/templates/website/partial_note.html | 2 + orochi/templates/website/partial_pstree.html | 28 - orochi/templates/website/partial_tree.html | 117 + orochi/users/views.py | 33 +- orochi/utils/plugin_install.py | 76 +- orochi/utils/volatility_dask_elk.py | 205 +- orochi/website/admin.py | 9 +- orochi/website/api/permissions.py | 25 +- orochi/website/api/serializers.py | 14 +- orochi/website/api/views.py | 44 +- orochi/website/consumers.py | 12 +- orochi/website/defaults.py | 165 + orochi/website/forms.py | 59 +- .../management/commands/plugins_sync.py | 24 +- orochi/website/middleware.py | 9 +- .../migrations/0053_create_default_groups.py | 14 + .../migrations/0054_dump_regipy_plugins.py | 25 + orochi/website/models.py | 220 +- orochi/website/routing.py | 4 +- orochi/website/templatetags/custom_tags.py | 6 + orochi/website/urls.py | 1 + orochi/website/views.py | 754 +- requirements/base.txt | 36 +- requirements/local.txt | 10 +- version.py | 2 +- 61 files changed, 10451 insertions(+), 1974 deletions(-) create mode 100644 .env.sample create mode 100644 compose/local/nginx/Dockerfile create mode 100644 compose/local/nginx/conf/default.conf create mode 100644 examples/local_api.ipynb delete mode 100644 orochi/static/css/jstree/32px.png delete mode 100644 orochi/static/css/jstree/40px.png delete mode 100644 orochi/static/css/jstree/style.min.css delete mode 100644 orochi/static/css/jstree/throbber.gif create mode 100644 orochi/static/css/wunderbaum/wunderbaum.css create mode 100644 orochi/static/css/wunderbaum/wunderbaum.css.map delete mode 100644 orochi/static/js/jstree/jstree.min.js delete mode 100644 orochi/static/js/jstree/jstreetable.js create mode 100644 orochi/static/js/wunderbaum/wunderbaum.umd.js create mode 100644 orochi/static/js/wunderbaum/wunderbaum.umd.min.js create mode 100644 orochi/static/js/wunderbaum/wunderbaum.umd.min.js.map delete mode 100644 orochi/templates/website/partial_pstree.html create mode 100644 orochi/templates/website/partial_tree.html create mode 100644 orochi/website/defaults.py create mode 100644 orochi/website/migrations/0053_create_default_groups.py create mode 100644 orochi/website/migrations/0054_dump_regipy_plugins.py diff --git a/.env.sample b/.env.sample new file mode 100644 index 00000000..0fd25230 --- /dev/null +++ b/.env.sample @@ -0,0 +1 @@ +VERSION=latest diff --git a/.envs/.local/.django b/.envs/.local/.django index b42718e1..e5628db0 100755 --- a/.envs/.local/.django +++ b/.envs/.local/.django @@ -7,6 +7,14 @@ IPYTHONDIR=/app/.ipython # ------------------------------------------------------------------------------ ALLOWED_HOSTS=* +# Smtp +# ------------------------------------------------------------------------------ +EMAIL_HOST=mailpit +EMAIL_PORT=1025 +EMAIL_USE_TLS=False +EMAIL_HOST_USER= +EMAIL_HOST_PASSWORD= + # Redis # ------------------------------------------------------------------------------ REDIS_URL=redis://redis:6379/0 @@ -29,6 +37,21 @@ AWESOME_PATH=https://raw.githubusercontent.com/InQuest/awesome-yara/master/READM LOCAL_YARA_PATH=/yara DEFAULT_YARA_RULE_PATH=/yara/default.yara VOLATILITY_SYMBOL_DOWNLOAD_PATH=https://downloads.volatilityfoundation.org/volatility3/symbols +LOCAL_UPLOAD_PATH=/uploads +# $ from regipy.plugins.plugin import PLUGINS +# $ [plugin.NAME for plugin in PLUGINS] +# ['amcache', 'terminal_services_history', 'bootkey', 'last_logon_plugin', 'winscp_saved_sessions', +# 'ras_tracing', 'active_control_set', 'timezone_data', 'safeboot_configuration', 'uac_plugin', +# 'user_assist', 'word_wheel_query', 'print_demon_plugin', 'shimcache', 'usbstor_plugin', 'wdigest', +# 'installed_programs_ntuser', 'software_classes_installer', 'installed_programs_software', 'background_activity_moderator', +# 'ntuser_classes_installer', 'typed_urls', 'usrclass_shellbag_plugin', 'network_data', 'image_file_execution_options', +# 'domain_sid', 'routes', 'boot_entry_list', 'ntuser_shellbag_plugin', 'typed_paths', 'services', 'local_sid', +# 'host_domain_name', 'profilelist_plugin', 'winrar_plugin', 'ntuser_persistence', 'computer_name', 'network_drives_plugin', 'software_plugin'] +REGIPY_PLUGINS=computer_name,host_domain_name,network_drives_plugin + +# Debug +# ------------------------------------------------------------------------------ +DEBUG_LEVEL=WARNING # Ldap # ------------------------------------------------------------------------------ @@ -47,4 +70,4 @@ no_proxy= # CSRF_TRUSTED_ORIGINS # ------------------------------------------------------------------------------ -CSRF_TRUSTED_ORIGINS= +CSRF_TRUSTED_ORIGINS=https://orochi.dev,https://localhost diff --git a/.gitignore b/.gitignore index 21d1c867..14235ea5 100644 --- a/.gitignore +++ b/.gitignore @@ -271,7 +271,12 @@ compose/local/clamav/freshclam.conf # History .history + +# Temporary test files orochi/utils/test.py +docker-compose__tmp.yml + +# Maxmind compose/local/maxmind/GeoLite2-ASN.mmdb compose/local/maxmind/GeoLite2-City.mmdb -compose/local/maxmind/GeoLite2-Country.mmdb \ No newline at end of file +compose/local/maxmind/GeoLite2-Country.mmdb diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd7c07f7..d3dd7a4d 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: check-yaml - repo: https://github.com/psf/black - rev: 24.1.1 + rev: 24.3.0 hooks: - id: black diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e9b1308..71c4986e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,23 @@ ## Changelog -
- OROCHI 2.2.0 + OROCHI 2.2.0 [2024/03/26] + + * Upload ntoskrnl.exe and generate symbol [[#1020](https://github.com/LDO-CERT/orochi/issues/1020)] + * evaluate possibility to switch from daphne to uvicorn for asgi [[#982](https://github.com/LDO-CERT/orochi/issues/982)] + * Improve path flexibility for local import [[#451](https://github.com/LDO-CERT/orochi/issues/451)] + * uv for installing requirements [[#1030](https://github.com/LDO-CERT/orochi/issues/1030)] + * Read only users for educational. [[#947](https://github.com/LDO-CERT/orochi/issues/947)] + * Add use case example with API. [[#248](https://github.com/LDO-CERT/orochi/issues/248)] + * put custom plugins under volatility3 /plugins/ [[#1068](https://github.com/LDO-CERT/orochi/issues/1068)] + * Improve tree rendered plugins +
+ +
+ OROCHI 2.1.1 [2024/02/13] * ADD more info on foreign addr in netstat [[#494](https://github.com/LDO-CERT/orochi/issues/494)] + * Expand/Collapse folders [[#1006](https://github.com/LDO-CERT/orochi/issues/1006)]
diff --git a/compose/local/dask/Dockerfile b/compose/local/dask/Dockerfile index e1e74f4e..252c37f0 100644 --- a/compose/local/dask/Dockerfile +++ b/compose/local/dask/Dockerfile @@ -1,6 +1,8 @@ -FROM daskdev/dask:2024.1.1-py3.11 +FROM daskdev/dask:2024.3.1-py3.12 ENV DEBIAN_FRONTEND noninteractive +ARG local_folder=/uploads + RUN apt-get --allow-releaseinfo-change update \ # dependencies for building Python packages && apt-get install -y --no-install-recommends build-essential \ @@ -45,7 +47,8 @@ RUN python setup.py build \ # Workers should have similar reqs as django WORKDIR / COPY ./requirements /requirements -RUN pip install -r /requirements/base.txt --ignore-installed ruamel.yaml +RUN pip install uv==0.1.21 -e git+https://github.com/volatilityfoundation/volatility3.git@55dd39f2ba60ffdd2126b7ea011940f0df42815a#egg=volatility3 \ + && uv pip install --no-cache --system -r /requirements/base.txt COPY ./compose/local/dask/prepare.sh /usr/bin/prepare.sh RUN chmod +x /usr/bin/prepare.sh @@ -53,6 +56,9 @@ RUN chmod +x /usr/bin/prepare.sh COPY ./compose/local/dask/daskworkerinit.py /opt/daskworkerinit.py COPY ./compose/local/__init__.py /src/volatility3/volatility3/framework/constants/__init__.py +RUN mkdir -p $local_folder /maxmind +COPY ./compose/local/maxmind /maxmind + WORKDIR /app COPY . . ENV PYTHONPATH "${PYTHONPATH}:/app" diff --git a/compose/local/django/Dockerfile b/compose/local/django/Dockerfile index 485c6051..31dc026a 100644 --- a/compose/local/django/Dockerfile +++ b/compose/local/django/Dockerfile @@ -1,9 +1,11 @@ -FROM python:3.11-slim-buster as common-base +FROM python:3.12-slim-bookworm as common-base ENV DJANGO_SETTINGS_MODULE config.settings.local ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 +ARG local_folder=/uploads + RUN apt-get update \ # dependencies for building Python packages && apt-get install -y --no-install-recommends build-essential \ @@ -54,10 +56,8 @@ RUN python setup.py build FROM base-builder as go-builder WORKDIR / -RUN curl https://dl.google.com/go/go1.15.2.linux-amd64.tar.gz --output go1.15.2.linux-amd64.tar.gz \ - && tar -C /usr/local -xzf go1.15.2.linux-amd64.tar.gz -RUN curl https://dl.google.com/go/go1.15.2.linux-amd64.tar.gz --output go1.15.2.linux-amd64.tar.gz \ - && tar -C /usr/local -xzf go1.15.2.linux-amd64.tar.gz +RUN curl https://dl.google.com/go/go1.22.0.linux-amd64.tar.gz --output go1.22.0.linux-amd64.tar.gz \ + && tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz RUN git clone https://github.com/volatilityfoundation/dwarf2json.git WORKDIR /dwarf2json RUN /usr/local/go/bin/go build @@ -65,11 +65,12 @@ RUN /usr/local/go/bin/go build FROM common-base WORKDIR / COPY ./requirements /requirements -RUN pip install -r /requirements/local.txt --ignore-installed ruamel.yaml +RUN pip install uv==0.1.21 -e git+https://github.com/volatilityfoundation/volatility3.git@55dd39f2ba60ffdd2126b7ea011940f0df42815a#egg=volatility3 \ + && uv pip install --no-cache --system -r /requirements/base.txt COPY ./compose/local/__init__.py /src/volatility3/volatility3/framework/constants/__init__.py -RUN mkdir /maxmind +RUN mkdir -p $local_folder /maxmind COPY ./compose/local/maxmind /maxmind WORKDIR /app diff --git a/compose/local/django/start b/compose/local/django/start index 9264c353..1fc4406f 100644 --- a/compose/local/django/start +++ b/compose/local/django/start @@ -7,4 +7,4 @@ set -o nounset python manage.py makemigrations python manage.py migrate python manage.py collectstatic --skip-checks --noinput --clear -daphne -b 0.0.0.0 -p 8000 config.asgi:application +gunicorn config.wsgi:application --workers=2 --timeout 1800 -b :8000 diff --git a/compose/local/nginx/Dockerfile b/compose/local/nginx/Dockerfile new file mode 100644 index 00000000..49c6a1ec --- /dev/null +++ b/compose/local/nginx/Dockerfile @@ -0,0 +1,19 @@ +FROM alpine:latest as alpine +ARG DOMAIN_NAME=orochi.dev +ARG DAYS_VALID=365 + +RUN apk add --no-cache openssl +RUN echo "Creating self-signed certificate valid for ${DAYS_VALID} days for domain ${DOMAIN_NAME}" && \ + openssl \ + req -x509 \ + -nodes \ + -subj "/CN=${DOMAIN_NAME}" \ + -addext "subjectAltName=DNS:${DOMAIN_NAME}" \ + -days ${DAYS_VALID} \ + -newkey rsa:2048 -keyout /tmp/self-signed.key \ + -out /tmp/self-signed.crt + +# Prepare an NGINX-based image with the certificate created above. +FROM nginx:latest as nginx +COPY --from=alpine /tmp/self-signed.key /etc/ssl/private +COPY --from=alpine /tmp/self-signed.crt /etc/ssl/certs diff --git a/compose/local/nginx/conf/default.conf b/compose/local/nginx/conf/default.conf new file mode 100644 index 00000000..ae114825 --- /dev/null +++ b/compose/local/nginx/conf/default.conf @@ -0,0 +1,57 @@ +upstream django_wsgi { + server django_wsgi:8000; +} + +upstream django_asgi { + server django_asgi:9000; +} + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + listen [::]:80; + server_name _; + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + + proxy_connect_timeout 50000; + proxy_read_timeout 50000; + proxy_send_timeout 50000; + + server_name orochi.dev; + + location = /favicon.ico { access_log off; log_not_found off; } + + ssl_certificate /etc/ssl/certs/self-signed.crt; + ssl_certificate_key /etc/ssl/private/self-signed.key; + + location / { + proxy_pass http://django_wsgi; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + + client_max_body_size 1000M; + } + + location /ws/notify/ { + proxy_pass http://django_asgi; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } +} diff --git a/config/routing.py b/config/routing.py index e662ff08..ccb6943d 100644 --- a/config/routing.py +++ b/config/routing.py @@ -1,13 +1,15 @@ -import orochi.website.routing -from django.core.asgi import get_asgi_application from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter +from channels.security.websocket import AllowedHostsOriginValidator +from django.core.asgi import get_asgi_application + +import orochi.website.routing application = ProtocolTypeRouter( { "http": get_asgi_application(), - "websocket": AuthMiddlewareStack( - URLRouter(orochi.website.routing.websocket_urlpatterns) + "websocket": AllowedHostsOriginValidator( + AuthMiddlewareStack(URLRouter(orochi.website.routing.websocket_urlpatterns)) ), } ) diff --git a/config/settings/base.py b/config/settings/base.py index ee858f83..0ae5f334 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -228,6 +228,7 @@ # LOGGING # ------------------------------------------------------------------------------ +DEBUG_LEVEL = env("DEBUG_LEVEL", default="WARNING") LOGGING = { "version": 1, "disable_existing_loggers": False, @@ -239,14 +240,14 @@ }, "handlers": { "console": { - "level": "INFO", + "level": DEBUG_LEVEL, "class": "logging.StreamHandler", "formatter": "verbose", } }, - "root": {"level": "INFO", "handlers": ["console"]}, + "root": {"level": DEBUG_LEVEL, "handlers": ["console"]}, "loggers": { - "distributed": {"level": "INFO", "handlers": ["console"]}, + "distributed": {"level": DEBUG_LEVEL, "handlers": ["console"]}, }, } @@ -275,7 +276,7 @@ ASGI_APPLICATION = "config.routing.application" CHANNEL_LAYERS = { "default": { - "BACKEND": "channels_redis.pubsub.RedisPubSubChannelLayer", + "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [(env("REDIS_SERVER"), env("REDIS_PORT"))], }, @@ -329,8 +330,12 @@ RULES_ANALYSIS_INDEX = "rules_analysis" # local path of volatility folder VOLATILITY_SYMBOL_PATH = "/src/volatility3/volatility3/symbols" -VOLATILITY_PLUGIN_PATH = "/src/volatility3/volatility3/framework/plugins/custom" +VOLATILITY_PLUGIN_PATH = "/src/volatility3/volatility3/plugins/custom" # local path of dwarg2json executable DWARF2JSON = "/dwarf2json/./dwarf2json" # online path of volatility symbols VOLATILITY_SYMBOL_DOWNLOAD_PATH = env("VOLATILITY_SYMBOL_DOWNLOAD_PATH") +# path of a remote folder with already uploaded files +LOCAL_UPLOAD_PATH = env("LOCAL_UPLOAD_PATH") +# Regipy plugins +REGIPY_PLUGINS = env.list("REGIPY_PLUGINS") diff --git a/config/settings/local.py b/config/settings/local.py index ed6bdd56..da468de2 100644 --- a/config/settings/local.py +++ b/config/settings/local.py @@ -27,7 +27,7 @@ # EMAIL # ------------------------------------------------------------------------------ -EMAIL_HOST = env("EMAIL_HOST", default="mailhog") +EMAIL_HOST = env("EMAIL_HOST", default="mailpit") EMAIL_PORT = 1025 EMAIL_USE_TLS = env("EMAIL_USE_TLS", default=True) EMAIL_HOST_USER = env("EMAIL_HOST_USER", default=None) diff --git a/docker-compose-swarm.yml b/docker-compose-swarm.yml index 2e2a36aa..48dd2cb1 100644 --- a/docker-compose-swarm.yml +++ b/docker-compose-swarm.yml @@ -68,7 +68,7 @@ services: volumes: - media_path:/media - symbols_path:/src/volatility3/volatility3/symbols - - plugin_path:/src/volatility3/volatility3/framework/plugins/custom + - plugin_path:/src/volatility3/volatility3/plugins/custom - yara_path:/yara - cache_path:/root/.cache/volatility3 - ./compose/local/__init__.py:/src/volatility3/volatility3/framework/constants/__init__.py @@ -178,7 +178,7 @@ services: volumes: - media_path:/media - symbols_path:/src/volatility3/volatility3/symbols - - plugin_path:/src/volatility3/volatility3/framework/plugins/custom + - plugin_path:/src/volatility3/volatility3/plugins/custom - yara_path:/yara - cache_path:/root/.cache/volatility3 @@ -213,7 +213,7 @@ services: volumes: - media_path:/media - symbols_path:/src/volatility3/volatility3/symbols - - plugin_path:/src/volatility3/volatility3/framework/plugins/custom + - plugin_path:/src/volatility3/volatility3/plugins/custom - yara_path:/yara - cache_path:/root/.cache/volatility3 - ./compose/local/__init__.py:/src/volatility3/volatility3/framework/constants/__init__.py diff --git a/docker-compose.yml b/docker-compose.yml index 2608ec48..d6daad8d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,24 +13,40 @@ volumes: services: - django: &django + nginx: + build: + context: . + dockerfile: ./compose/local/nginx/Dockerfile + image: ghcr.io/ldo-cert/orochi_nginx:${VERSION:-latest} + container_name: orochi_nginx + depends_on: + - django_asgi + - django_wsgi + volumes: + - ./compose/local/nginx/conf:/etc/nginx/conf.d + ports: + - "80:80" + - "443:443" + + django_wsgi: build: context: . dockerfile: ./compose/local/django/Dockerfile args: - http_proxy - https_proxy - image: ghcr.io/ldo-cert/orochi_django:latest - container_name: orochi_django + - local_upload_path + image: ghcr.io/ldo-cert/orochi_django:${VERSION:-latest} + container_name: orochi_django_wsgi hostname: django restart: always depends_on: - postgres - - mailhog + - mailpit volumes: - media_path:/media - symbols_path:/src/volatility3/volatility3/symbols - - plugin_path:/src/volatility3/volatility3/framework/plugins/custom + - plugin_path:/src/volatility3/volatility3/plugins/custom - yara_path:/yara - cache_path:/root/.cache/volatility3 env_file: @@ -39,15 +55,43 @@ services: environment: - http_proxy=${http_proxy} - https_proxy=${https_proxy} - ports: - - "8000:8000" + expose: + - 8000 command: /start - postgres: + django_asgi: build: context: . - dockerfile: ./compose/local/postgres/Dockerfile - image: ghcr.io/ldo-cert/orochi_postgres:latest + dockerfile: ./compose/local/django/Dockerfile + args: + - http_proxy + - https_proxy + - local_upload_path + image: ghcr.io/ldo-cert/orochi_django:${VERSION:-latest} + container_name: orochi_django_asgi + hostname: django + restart: always + depends_on: + - postgres + - mailpit + volumes: + - media_path:/media + - symbols_path:/src/volatility3/volatility3/symbols + - plugin_path:/src/volatility3/volatility3/plugins/custom + - yara_path:/yara + - cache_path:/root/.cache/volatility3 + env_file: + - ./.envs/.local/.django + - ./.envs/.local/.postgres + environment: + - http_proxy=${http_proxy} + - https_proxy=${https_proxy} + expose: + - 9000 + command: daphne -b 0.0.0.0 -p 9000 config.asgi:application + + postgres: + image: postgres:16.2 container_name: orochi_postgres hostname: postgres restart: always @@ -59,12 +103,13 @@ services: ports: - "5432:5432" - mailhog: - image: mailhog/mailhog:v1.0.1 - container_name: orochi_mailhog - hostname: mailhog + mailpit: + image: 'axllent/mailpit:latest' + container_name: orochi_mailpit + hostname: mailpit restart: always ports: + - "1025:1025" - "8025:8025" redis: @@ -112,7 +157,7 @@ services: MONITORING_ENABLED: "false" scheduler: - image: ghcr.io/ldo-cert/orochi_worker:latest + image: ghcr.io/ldo-cert/orochi_worker:${VERSION:-latest} build: context: . dockerfile: ./compose/local/dask/Dockerfile @@ -139,12 +184,12 @@ services: volumes: - media_path:/media - symbols_path:/src/volatility3/volatility3/symbols - - plugin_path:/src/volatility3/volatility3/framework/plugins/custom + - plugin_path:/src/volatility3/volatility3/plugins/custom - yara_path:/yara - cache_path:/root/.cache/volatility3 worker: - image: ghcr.io/ldo-cert/orochi_worker:latest + image: ghcr.io/ldo-cert/orochi_worker:${VERSION:-latest} deploy: replicas: 2 build: @@ -174,7 +219,7 @@ services: volumes: - media_path:/media - symbols_path:/src/volatility3/volatility3/symbols - - plugin_path:/src/volatility3/volatility3/framework/plugins/custom + - plugin_path:/src/volatility3/volatility3/plugins/custom - yara_path:/yara - cache_path:/root/.cache/volatility3 env_file: diff --git a/examples/local_api.ipynb b/examples/local_api.ipynb new file mode 100644 index 00000000..2426adaa --- /dev/null +++ b/examples/local_api.ipynb @@ -0,0 +1,256 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import getpass\n", + "from requests import Session\n", + "from pprint import pprint\n", + "\n", + "url = \"http://127.0.0.1\"\n", + "user = input()\n", + "password = getpass.getpass()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LOGIN" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "session = Session()\n", + "req = session.post(\n", + " f\"{url}/auth-token/\", \n", + " data={\"username\": user, \"password\": password}\n", + ")\n", + "if req.status_code != 200:\n", + " print(req.json())\n", + " exit(1)\n", + "token = req.json()[\"token\"]\n", + "session.headers[\"Authorization\"] = f\"Token {token}\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GET DUMP LIST" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dumps = session.get(f\"{url}/api/dumps/\").json()\n", + "print(f\"{len(dumps)} dumps found\")\n", + "pprint(dumps[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CREATE DUMP" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "files = {'upload': open('/home/DATA/AMF_MemorySamples/linux/sorpresa.zip','rb')}\n", + "values = {'operating_system': 'Linux', 'name': 'sorpresa'}\n", + "res = session.post(f\"{url}/api/dumps/\", files=files, data=values)\n", + "if res.status_code == 200:\n", + " pprint(res.json())\n", + " dump_pk = res.json()[\"pk\"]\n", + "else:\n", + " print(res.status_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CREATE DUMP FROM REMOTE DUMP" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# This code requires a file on the server in the folder specified in the LOCAL_UPLOAD_PATH\n", + "# settings folder\n", + "\n", + "res = session.post(f\"{url}/api/dumps/import_local/\", files=(\n", + " ('operating_system', (None, 'Linux')),\n", + " ('name', (None, 'sasf3sfas33')),\n", + " ('filepath', (None, '/uploads/linux/linux-sample-4.bin')),\n", + " ))\n", + "if res.status_code == 200:\n", + " pprint(res.json())\n", + "else:\n", + " print(res.status_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GET PLUGIN LIST" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "res = session.get(f\"{url}/api/plugin/\")\n", + "if res.status_code == 200:\n", + " plugins = res.json()\n", + " print(f\"{len(plugins)} plugins found\")\n", + " pprint(plugins[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GET PLUGIN STATUS ON SELECTED DUMP" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "res = session.get(f\"{url}/api/dumps/{dump_pk}/results/\")\n", + "if res.status_code == 200:\n", + " pprint(res.json())\n", + " result_pk = [x['pk'] for x in res.json() if x['plugin'] == 'linux.pslist.PsList'][0]\n", + " print(res.status_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# RESUBMIT PLUGIN" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "res = session.post(f\"{url}/api/dumps/{dump_pk}/results/{result_pk}/resubmit/\", data={'parameter': {'dump': True}})\n", + "if res.status_code == 200:\n", + " pprint(res.json())\n", + "else:\n", + " print(res.status_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CHECK PLUGIN STATUS" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "status = 'Running'\n", + "while status != 'Success':\n", + " res = session.get(f\"{url}/api/dumps/{dump_pk}/results/{result_pk}/\")\n", + " if res.status_code == 200:\n", + " status = res.json()['status']\n", + " pprint(status)\n", + " else:\n", + " print(res.status_code)\n", + " break" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SHOW PLUGIN RESULT" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "res = session.get(f\"{url}/api/dumps/{dump_pk}/results/{result_pk}/result\")\n", + "if res.status_code == 200:\n", + " pprint(len(res.json()))\n", + "else:\n", + " print(res.status_code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# WORK WITH RETURNED DATA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import pygwalker as pyg\n", + "df = pd.DataFrame.from_records(res.json())\n", + "walker = pyg.walk(df)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "orochi", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/orochi/static/README.txt b/orochi/static/README.txt index 82b57963..4b083068 100644 --- a/orochi/static/README.txt +++ b/orochi/static/README.txt @@ -22,10 +22,9 @@ --> http://bootboxjs.com/ --> version 6.0.0 -# jstree [TREE VIEW FOR PSTREE] ---> https://www.jstree.com/ ---> version 3.3.16 ---> with plugin jstree-table https://github.com/adamjimenez/jstree-table +# wunderbaum [TREE VIEW FOR PSTREE] +--> https://github.com/mar10/wunderbaum/ +--> version 0.8.2 # Datatables [TABLE RENDERING] --> https://datatables.net/ diff --git a/orochi/static/css/jstree/32px.png b/orochi/static/css/jstree/32px.png deleted file mode 100644 index ac74418d2843d0233fc67c04a59462caa82bd860..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8740 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 diff --git a/orochi/static/css/jstree/40px.png b/orochi/static/css/jstree/40px.png deleted file mode 100644 index 29273260075f1654bb86a9e3f42c3f32ab5a2d23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6055 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 B1Y7_B diff --git a/orochi/static/css/jstree/style.min.css b/orochi/static/css/jstree/style.min.css deleted file mode 100644 index 3223b65b..00000000 --- a/orochi/static/css/jstree/style.min.css +++ /dev/null @@ -1 +0,0 @@ -.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-no-icons{margin-left:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("32px.png")}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background-image:none}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:transparent}.jstree-default .jstree-disabled.jstree-hovered{background:transparent}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background-image:none}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 24px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default.jstree-rtl .jstree-last{background-image:none}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("32px.png")}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background-image:none}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:transparent}.jstree-default-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background-image:none}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 18px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-small.jstree-rtl .jstree-last{background-image:none}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("32px.png")}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background-image:none}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:transparent}.jstree-default-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background-image:none}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 32px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-large.jstree-rtl .jstree-last{background-image:none}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-responsive>.jstree-striped{background:transparent}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background-image:none}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} diff --git a/orochi/static/css/jstree/throbber.gif b/orochi/static/css/jstree/throbber.gif deleted file mode 100644 index 5b33f7e54f4e55b6b8774d86d96895db9af044b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1849 zcma*odr(tX9tZI2z31lM+(&YVk%mZ}5P~KlG2s=WSbGzm0!x7^P##Mnh7t-jP!X0Q zk_SQ}Po-L1tlDK;6l?(>v)e5ZBQx4|Y-Q?nr@Px3?9h(3ZWr3^tj=`TP57gKr87N$ zp2wWee1GRRCwo_xahnw)5cxNPJbCg2L6DV|6`#+yw6v6!mDS$f9-JvFD^n;GQ&UrZ zzh5jCkByB101O60U0q#p_1BM>Cv-vP?&s4@g_((4_1L=L$(a91)0=J91Gas#R{McE znYG^9*0A5YZ>#;~+Wkn(W5B0^yELIYLP!K}mB~<)AM@1&nqekynuaEGqPrzoH|KodRXJy)%+w_fu3nE5>@Bd_b zqC$EQ;{c`T&?EsNO|igL9gC7Ygxv?aQUEXMq?~>wg{EyW;VcJ37CUF#HjrT=KQO_* zS>M9yydXk18D(+QDJ1>r);Lav_uYKp$T?4vr{Q$lTo&pKv^?(>L-)G2*lwH!Ah7k? z7oH<8h-(KTKt5V6$8gF)C7Io&P5=SjTh)=zV=E2EUhQZP##L8S{d%UK>>+y82>+FV+#^BzW7u3F)Bb>=lYQ%%j`F>ASe zo*cw@V#u6T`A2He;70mR(V&iV&-7{qP~=SRf&jm9-T{*ZeZ}$rd0#6c&fLG^xJcf5 z+p<`wJYgW+_s*V{uI$nMB;%8`S_3>PfGOj3Rq}@Cx^+j?rk92fANSFDBYnOqQ>Vdj z)(|$AhP4t&Lb=Gvo2#3Gl%9<=Gv`Mz?Po@P4iLF!x}GUWJICDlFk-hS^Whyh7x~VH z@0vD1>HYD4&e+~yzS*-sFR{9`{QEEZO1zg7>R&7cHts-6j!xHVdA8eI+ZlVzd%`es zJT@$#GX(gvCJ1oJN%yLBK}{V=V;seo;!w|Yte!W1%5qLNFWqvZW>h&IiH+oPT=b@E zPhGzv5=(Un*X>v`>%8h_nj^NdYcE6NHS_ifkCV$*D)Tqrbu`s;<=t<4 zAHNqNV?6(g<1PY-w@#I-WYFViz?9TrkMr)u0g`O`u|>T;k|2sV*YF^punvT;$SuTy{j3Gv)yqD!R_CF>yR)MzmmYS5v+~R zXAdD%ng9?df;wd8GxR#%3O+gz};Vo;)sK%Bj-q>Oq%R7JU-KD?vYu>#2UjaDo z&8$>5xW~?KPD_#XFToU1hIb*VOMidUr6iYiO0N|i-7s`T8!cFT`rN!^1Pt78J93i6 z5HI1wIM$94m{3SLDvISDe6$ZG1;eq_D9RTaaC>=cO{@Bs>$IlPCPJJ$h$)-3vzNUQ6OsN#_zWxey!_9%hxwH2_dEJi=yY|1c7nDm2_Lm!Cof8-R_+9UkS zcBE(o47yE)oMR(Q=dp1a2wTX5KvvGyLqlWTa7V&!A*|w|)ax~1_~aJ0=_Lilg*0iQk7#ZD EAHN$8j{pDw diff --git a/orochi/static/css/style.css b/orochi/static/css/style.css index 5b908ac8..55482b61 100644 --- a/orochi/static/css/style.css +++ b/orochi/static/css/style.css @@ -26,7 +26,10 @@ a.navbar-brand { } .list-group-item { - background-color: rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important; + background-color: rgba( + var(--bs-tertiary-bg-rgb), + var(--bs-bg-opacity) + ) !important; } /******************************************************** @@ -124,13 +127,12 @@ main { transform: rotate(45deg); } - /******************************************************** DUMP MENU ICONS ********************************************************/ -.download-index{ - color:#440b5d; +.download-index { + color: #440b5d; } .error-index:hover, @@ -201,7 +203,6 @@ ul.nested-list li.list-group-item { padding-top: 10px; } - /******************************************************** TABLE ********************************************************/ @@ -210,14 +211,6 @@ ul.nested-list li.list-group-item { overflow-x: hidden; } -/******************************************************** - JSTREE -********************************************************/ - -.jstree-table-wrapper.demo { - line-height: 1.75; -} - /******************************************************** MAKE SVG ON BUTTON FIRE CLICK ********************************************************/ @@ -237,14 +230,14 @@ ul.nested-list li.list-group-item { /******************************************************** SMALLER TEXT IN DIALOG INFO ********************************************************/ -.small-dlg{ +.small-dlg { font-size: small; } /******************************************************** SINGLE CHAR PADDING FOR HEX VIEW ********************************************************/ -.singlechar{ +.singlechar { padding-left: 2px; padding-right: 2px; display: inline-block; @@ -254,17 +247,38 @@ ul.nested-list li.list-group-item { /******************************************************** ADDITIONAL DATATABLES BUTTONS ********************************************************/ -.goto input, .next input{ +.goto input, +.next input { display: inline-block; width: auto; margin-left: 0.5em; } -.goto label, .next label{ +.goto label, +.next label { font-weight: normal; text-align: left; white-space: nowrap; } -.goto, div.next, .dataTables_length{ +.goto, +div.next, +.dataTables_length { float: left; margin-left: 50px; } + +/******************************************************** + FIX ICON +********************************************************/ +.wb-icon { + padding-left: 2px; + padding-right: 2px; +} + +main.view { + height: 800px; + overflow: hidden; +} + +div.wunderbaum { + height: 95%; +} diff --git a/orochi/static/css/wunderbaum/wunderbaum.css b/orochi/static/css/wunderbaum/wunderbaum.css new file mode 100644 index 00000000..0547b56c --- /dev/null +++ b/orochi/static/css/wunderbaum/wunderbaum.css @@ -0,0 +1,701 @@ +@charset "UTF-8"; +/*! + * Wunderbaum style sheet (generated from wunderbaum.scss) + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * @VERSION, @DATE (https://github.com/mar10/wunderbaum) + */ +:root, +:host { + --wb-font-stack: Helvetica, sans-serif; + --wb-error-color: #b5373b; + --wb-node-text-color: #56534c; + --wb-border-color: #56534c; + --wb-bg-highlight-color: #26a0da; + --wb-header-color: #dedede; + --wb-background-color: #ffffff; + --wb-alternate-row-color: #f7f7f7; + --wb-alternate-row-color-hover: #f3f3f3; + --wb-focus-border-color: #275dc5; + --wb-drop-source-color: #d3d2ce; + --wb-drop-target-color: #d4ecf8; + --wb-dim-color: #8c877c; + --wb-error-background-color: #f5ddde; + --wb-hover-color: #f7fcfe; + --wb-hover-border-color: #f7fcfe; + --wb-grid-color: #dedede; + --wb-active-color: #e5f3fb; + --wb-active-cell-color: #7dc6e9; + --wb-active-border-color: #70c0e7; + --wb-active-hover-color: #dceff8; + --wb-active-hover-border-color: #26a0da; + --wb-active-column-color: #f7fcfe; + --wb-active-header-column-color: #c5c5c5; + --wb-active-color-grayscale: #f0f0f0; + --wb-active-border-color-grayscale: #acacac; + --wb-active-hover-color-grayscale: #eaeaea; + --wb-active-cell-color-grayscale: #b3b3b3; + --wb-grid-color-grayscale: #dedede; + --wb-filter-dim-color: #dedede; + --wb-filter-submatch-color: #868581; + --wb-row-outer-height: 22px; + --wb-row-inner-height: 20px; + --wb-row-padding-y: 1px; + --wb-col-padding-x: 2px; + --wb-icon-outer-height: 20px; + --wb-icon-outer-width: 20px; + --wb-icon-height: 16px; + --wb-icon-width: 16px; + --wb-icon-padding-y: 2px; + --wb-icon-padding-x: 2px; + --wb-header-height: 22px; +} + +div.wunderbaum * { + box-sizing: border-box; +} + +div.wunderbaum { + height: 100%; + min-height: 4px; + background-color: var(--wb-background-color); + margin: 0; + padding: 0; + font-family: var(--wb-font-stack); + font-size: 14px; + color: var(--wb-node-text-color); + border: 2px solid var(--wb-border-color); + border-radius: 4px; + background-clip: content-box; + overflow-x: auto; + overflow-y: scroll; + /* --- FIXED-COLUMN --- */ + /* Fixed column must be opaque, i.e. have the bg color set. */ + /* --- GRID --- */ + /* --- FILTER --- */ + /* --- DND --- */ + /* --- SPECIAL EFFECTS --- */ + /* Colorize indentation levels. */ + /* Fade out expanders, when container is not hovered or active */ + /* Skeleton */ + /* Auto-hide checkboxes unless selected or hovered */ +} +div.wunderbaum:focus, +div.wunderbaum:focus-within { + border-color: var(--wb-focus-border-color); +} +div.wunderbaum.wb-disabled { + opacity: 0.7; + pointer-events: none; +} +div.wunderbaum div.wb-list-container { + position: relative; + min-height: 4px; +} +div.wunderbaum div.wb-header { + position: sticky; + top: 0; + z-index: 2; +} +div.wunderbaum div.wb-header, +div.wunderbaum div.wb-list-container { + overflow: unset; +} +div.wunderbaum div.wb-row { + position: absolute; + width: 100%; + height: var(--wb-row-outer-height); + line-height: var(--wb-row-outer-height); + border: 1px solid transparent; +} +div.wunderbaum.wb-fixed-col span.wb-col:first-of-type { + position: sticky; + left: 0; + z-index: 1; + background-color: var(--wb-background-color); +} +div.wunderbaum.wb-fixed-col div.wb-header span.wb-col:first-of-type { + background-color: var(--wb-header-color); +} +div.wunderbaum.wb-fixed-col + div.wb-node-list + div.wb-row.wb-active + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col + div.wb-node-list + div.wb-row.wb-selected + span.wb-col:first-of-type { + background-color: var(--wb-active-color); +} +div.wunderbaum.wb-fixed-col + div.wb-node-list + div.wb-row.wb-active:hover + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col + div.wb-node-list + div.wb-row.wb-selected:hover + span.wb-col:first-of-type { + background-color: var(--wb-active-hover-color); +} +div.wunderbaum.wb-fixed-col + div.wb-node-list + div.wb-row:hover + span.wb-col:first-of-type { + background-color: var(--wb-hover-color); +} +div.wunderbaum.wb-fixed-col:not(:focus-within) + div.wb-node-list + div.wb-row.wb-active + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col:not(:focus-within) + div.wb-node-list + div.wb-row.wb-selected + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col:not(:focus) + div.wb-node-list + div.wb-row.wb-active + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col:not(:focus) + div.wb-node-list + div.wb-row.wb-selected + span.wb-col:first-of-type { + background-color: var(--wb-active-color-grayscale); + border-color: var(--wb-active-border-color-grayscale); +} +div.wunderbaum.wb-fixed-col:not(:focus-within) + div.wb-node-list + div.wb-row.wb-active + span.wb-col:first-of-type:hover + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col:not(:focus-within) + div.wb-node-list + div.wb-row.wb-selected + span.wb-col:first-of-type:hover + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col:not(:focus) + div.wb-node-list + div.wb-row.wb-active + span.wb-col:first-of-type:hover + span.wb-col:first-of-type, +div.wunderbaum.wb-fixed-col:not(:focus) + div.wb-node-list + div.wb-row.wb-selected + span.wb-col:first-of-type:hover + span.wb-col:first-of-type { + background-color: var(--wb-active-hover-color-grayscale); +} +div.wunderbaum:not(:focus-within) div.wb-node-list div.wb-row.wb-active, +div.wunderbaum:not(:focus-within) div.wb-node-list div.wb-row.wb-selected, +div.wunderbaum:not(:focus) div.wb-node-list div.wb-row.wb-active, +div.wunderbaum:not(:focus) div.wb-node-list div.wb-row.wb-selected { + background-color: var(--wb-active-color-grayscale); + border-color: var(--wb-active-border-color-grayscale); +} +div.wunderbaum:not(:focus-within) div.wb-node-list div.wb-row.wb-active:hover, +div.wunderbaum:not(:focus-within) div.wb-node-list div.wb-row.wb-selected:hover, +div.wunderbaum:not(:focus) div.wb-node-list div.wb-row.wb-active:hover, +div.wunderbaum:not(:focus) div.wb-node-list div.wb-row.wb-selected:hover { + background-color: var(--wb-active-hover-color-grayscale); +} +div.wunderbaum.wb-alternate + div.wb-node-list + div.wb-row:nth-of-type(even):not(.wb-active):not(.wb-selected) { + background-color: var(--wb-alternate-row-color); +} +div.wunderbaum.wb-alternate + div.wb-node-list + div.wb-row:nth-of-type(even):not(.wb-active):not(.wb-selected):hover { + background-color: var(--wb-alternate-row-color-hover); +} +div.wunderbaum div.wb-node-list div.wb-row:hover { + background-color: var(--wb-hover-color); +} +div.wunderbaum div.wb-node-list div.wb-row.wb-active, +div.wunderbaum div.wb-node-list div.wb-row.wb-selected { + background-color: var(--wb-active-color); +} +div.wunderbaum div.wb-node-list div.wb-row.wb-active:hover, +div.wunderbaum div.wb-node-list div.wb-row.wb-selected:hover { + background-color: var(--wb-active-hover-color); +} +div.wunderbaum div.wb-node-list div.wb-row.wb-focus:not(.wb-active) { + border-style: dotted; + border-color: var(--wb-active-border-color); +} +div.wunderbaum div.wb-node-list div.wb-row.wb-active { + border-style: solid; + border-color: var(--wb-active-border-color); +} +div.wunderbaum div.wb-node-list div.wb-row.wb-active:hover { + border-color: var(--wb-active-hover-border-color); +} +div.wunderbaum div.wb-node-list div.wb-row.wb-loading { + font-style: italic; +} +div.wunderbaum div.wb-node-list div.wb-row.wb-busy, +div.wunderbaum div.wb-node-list div.wb-row i.wb-busy, +div.wunderbaum div.wb-node-list div.wb-row .wb-col.wb-busy { + font-style: italic; + background: repeating-linear-gradient( + 45deg, + transparent, + transparent 3.88px, + var(--wb-grid-color) 3.88px, + var(--wb-grid-color) 7.78px + ); + animation: wb-busy-animation 2s linear infinite; +} +div.wunderbaum div.wb-node-list div.wb-row.wb-error, +div.wunderbaum div.wb-node-list div.wb-row.wb-status-error { + color: var(--wb-error-color); +} +div.wunderbaum div.wb-header { + position: sticky; + height: var(--wb-header-height); + border-bottom: 1px solid var(--wb-border-color); + padding: 0; + background-color: var(--wb-header-color); +} +div.wunderbaum div.wb-header span.wb-col { + font-weight: bold; + overflow: visible; +} +div.wunderbaum div.wb-header span.wb-col-title { + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +div.wunderbaum div.wb-header span.wb-col-resizer { + position: absolute; + top: 0; + right: -1px; + width: 3px; + border: none; + border-right: 2px solid var(--wb-border-color); + height: 100%; + cursor: col-resize; +} +div.wunderbaum span.wb-col { + position: absolute; + display: inline-block; + overflow: hidden; + height: var(--wb-row-inner-height); + line-height: var(--wb-row-inner-height); + padding: 0 var(--wb-col-padding-x); + border-right: 1px solid var(--wb-grid-color); + white-space: nowrap; +} +div.wunderbaum span.wb-col:last-of-type { + border-right: none; +} +div.wunderbaum span.wb-node { + user-select: none; + /* Fix Bootstrap Icon alignment */ +} +div.wunderbaum span.wb-node i.wb-checkbox, +div.wunderbaum span.wb-node i.wb-expander, +div.wunderbaum span.wb-node i.wb-icon, +div.wunderbaum span.wb-node i.wb-indent { + height: var(--wb-icon-outer-height); + width: var(--wb-icon-outer-width); + padding: var(--wb-icon-padding-y) var(--wb-icon-padding-x); + display: inline-block; +} +div.wunderbaum span.wb-node i.wb-expander, +div.wunderbaum span.wb-node i.wb-icon { + background-repeat: no-repeat; + background-size: contain; +} +div.wunderbaum span.wb-node i.bi::before { + vertical-align: baseline; +} +div.wunderbaum span.wb-node img.wb-icon { + width: var(--wb-icon-width); + height: var(--wb-icon-height); + padding: var(--wb-icon-padding-y) var(--wb-icon-padding-x); +} +div.wunderbaum span.wb-node i.wb-indent::before { + content: " "; +} +div.wunderbaum span.wb-node i.wb-expander.wb-spin, +div.wunderbaum span.wb-node i.wb-icon.wb-spin { + height: unset; + width: unset; + padding: 0 3px; + animation: wb-spin-animation 2s linear infinite; +} +div.wunderbaum span.wb-node span.wb-title { + min-width: 1em; + vertical-align: top; + overflow-x: hidden; + display: inline-block; + white-space: nowrap; + text-overflow: ellipsis; +} +div.wunderbaum.wb-grid div.wb-header div.wb-row span.wb-col:hover { + background-color: var(--wb-active-header-column-color); +} +div.wunderbaum.wb-grid.wb-cell-mode + div.wb-header + div.wb-row + span.wb-col.wb-active { + background-color: var(--wb-active-hover-color); +} +div.wunderbaum.wb-grid div.wb-node-list div.wb-row { + border-bottom-color: var(--wb-grid-color); +} +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row:hover:not(.wb-active):not(.wb-selected) { + background-color: var(--wb-hover-color); +} +div.wunderbaum.wb-grid div.wb-node-list div.wb-row.wb-active { + border-bottom-color: var(--wb-active-border-color); +} +div.wunderbaum.wb-grid div.wb-node-list div.wb-row span.wb-col { + border-right: 1px solid var(--wb-grid-color); +} +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + input.wb-input-edit, +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="color"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="date"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="datetime"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="datetime-local"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="email"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="month"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="number"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="password"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="search"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="tel"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="text"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="time"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="url"], +div.wunderbaum.wb-grid + div.wb-node-list + div.wb-row + span.wb-col + > input[type="week"], +div.wunderbaum.wb-grid div.wb-node-list div.wb-row span.wb-col > select { + width: 100%; + max-height: var(--wb-row-inner-height); + border: none; +} +div.wunderbaum.wb-grid div.wb-node-list div.wb-row span.wb-col > input:focus, +div.wunderbaum.wb-grid div.wb-node-list div.wb-row span.wb-col > select:focus { + border: 1px dashed #70c0e7; +} +div.wunderbaum.wb-grid.wb-cell-mode + div.wb-row:not(.wb-colspan).wb-active + span.wb-col.wb-active { + background-color: var(--wb-active-cell-color-grayscale); +} +div.wunderbaum.wb-grid.wb-cell-mode:focus-within + div.wb-row:not(.wb-colspan):not(.wb-selected) + span.wb-col.wb-active, +div.wunderbaum.wb-grid.wb-cell-mode:focus + div.wb-row:not(.wb-colspan):not(.wb-selected) + span.wb-col.wb-active { + background-color: var(--wb-active-column-color); +} +div.wunderbaum.wb-grid.wb-cell-mode:focus-within + div.wb-row:not(.wb-colspan):not(.wb-selected).wb-active, +div.wunderbaum.wb-grid.wb-cell-mode:focus + div.wb-row:not(.wb-colspan):not(.wb-selected).wb-active { + background-color: var(--wb-active-column-color); +} +div.wunderbaum.wb-grid.wb-cell-mode:focus-within + div.wb-row:not(.wb-colspan):not(.wb-selected).wb-active + span.wb-col.wb-active, +div.wunderbaum.wb-grid.wb-cell-mode:focus + div.wb-row:not(.wb-colspan):not(.wb-selected).wb-active + span.wb-col.wb-active { + background-color: var(--wb-active-cell-color); +} +div.wunderbaum.wb-grid.wb-alternate + div.wb-node-list + div.wb-row:nth-of-type(even):not(.wb-active):not(.wb-selected) { + background-color: var(--wb-alternate-row-color); +} +div.wunderbaum.wb-grid.wb-alternate + div.wb-node-list + div.wb-row:nth-of-type(even):not(.wb-active):not(.wb-selected):hover { + background-color: var(--wb-alternate-row-color-hover); +} +div.wunderbaum.wb-grid:not(:focus-within) div.wb-node-list div.wb-row, +div.wunderbaum.wb-grid:not(:focus) div.wb-node-list div.wb-row { + border-bottom-color: var(--wb-grid-color-grayscale); +} +div.wunderbaum.wb-ext-filter-dim div.wb-node-list div.wb-row, +div.wunderbaum.wb-ext-filter-hide div.wb-node-list div.wb-row { + color: var(--wb-filter-dim-color); +} +div.wunderbaum.wb-ext-filter-dim div.wb-node-list div.wb-row.wb-submatch, +div.wunderbaum.wb-ext-filter-hide div.wb-node-list div.wb-row.wb-submatch { + color: var(--wb-filter-submatch-color); +} +div.wunderbaum.wb-ext-filter-dim div.wb-node-list div.wb-row.wb-match, +div.wunderbaum.wb-ext-filter-hide div.wb-node-list div.wb-row.wb-match { + color: var(--wb-node-text-color); +} +div.wunderbaum div.wb-row.wb-drag-source { + opacity: 0.5; +} +div.wunderbaum div.wb-row.wb-drag-source .wb-node { + background-color: var(--wb-drop-source-color); +} +div.wunderbaum div.wb-row.wb-drop-target { + overflow: visible; +} +div.wunderbaum div.wb-row.wb-drop-target .wb-node { + background-color: var(--wb-drop-target-color); + overflow: visible; +} +div.wunderbaum div.wb-row.wb-drop-target .wb-node .wb-icon { + position: relative; + overflow: visible; +} +div.wunderbaum div.wb-row.wb-drop-target .wb-node .wb-icon::after { + position: absolute; + z-index: 1000; + content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAMAAABA3o1rAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACKUExURe/v9/f39+//7+f35+f/79bW5wgIawwYd97e55Tnpc731rjA2d7350LOY1LWa7Xvvf///wAQcyAze97e773vxnuczgA5pQBCpdb33rXvxu//9whjxgBaxlKU1oOz5ABz3gB73tbn99bW1rXe/wCM9xiU997v/97e3gCc/xil/9bv/wic/+/3/wAAALM9X5QAAAAudFJOU////////////////////////////////////////////////////////////wCCj3NVAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAqUlEQVQoU6WQ2w6CMAxA54agsCHq1HlFBREv/f/fs1tHAoaoiedlbXrWtGXwhV8FNqAXuAi4DwkShmE0cgGIcSwCCgkSkrAxpEonot0DhQxJptFsbnOpdNdgsFh6VtYwyqzTmG+oijDY7hr22E4qY7QybeGQe46nsxP0Wwc3Q1GWl+qKec8MlqKubxX+xzV7tkDuD1+3d+heigT2zGx/hCMUeUj4wL8CwAsW1kqCTugMCwAAAABJRU5ErkJggg==); + left: 0; + top: calc((22px - var(--wb-icon-height)) / 2); +} +div.wunderbaum + div.wb-row.wb-drop-target.wb-drop-before + .wb-node + .wb-icon::after, +div.wunderbaum + div.wb-row.wb-drop-target.wb-drop-after + .wb-node + .wb-icon::after { + content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAQCAMAAACROYkbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACNUExURe/v9/f39+//7+f35+f/79bW5wgIawwYd97e55Tnpc731rjA2d7350LOY1LWa7Xvvf///wAQcyAze97e773vxgAAAHuczgA5pQBCpdb33rXvxu//9whjxgBaxlKU1oOz5ABz3gB73tbn99bW1rXe/wCM9xiU997v/97e3gCc/xil/9bv/wic/+/3/wAAAParqS4AAAAvdFJOU/////////////////////////////////////////////////////////////8AWqU49wAAAAlwSFlzAAAOwwAADsMBx2+oZAAAALlJREFUOE/FktsSgiAQhglMS8WstKLzQTM77Ps/XguL16I208cFyzB8/LPAYCC/ErARzcCFx23pBgnGfjAxBYhpKDwq3SBB5DeGWCYz0SUDClIkmgeLpV7HMiNDbrbbYbBaWzbaoKTaJiHfQe5oYLA/NBwxTiyVyqTSghYwox4MTmfL5XozgqxjAtODoizv1QPXPXqgKer6WeH9+Iw9XgF5ve15/Q+6/SQSsE+q8yMcocoREgzg3wKAL4vrpBIKREShAAAAAElFTkSuQmCC); + left: 0; + top: calc((22px - var(--wb-icon-height)) / 2 - 11px); +} +div.wunderbaum + div.wb-row.wb-drop-target.wb-drop-after + .wb-node + .wb-icon::after { + top: calc((22px - var(--wb-icon-height)) / 2 + 11px); +} +div.wunderbaum.wb-rainbow i.wb-expander:nth-child(4n + 1), +div.wunderbaum.wb-rainbow i.wb-indent:nth-child(4n + 1) { + background: rgb(255, 255, 201); +} +div.wunderbaum.wb-rainbow i.wb-expander:nth-child(4n + 2), +div.wunderbaum.wb-rainbow i.wb-indent:nth-child(4n + 2) { + background: rgb(218, 255, 218); +} +div.wunderbaum.wb-rainbow i.wb-expander:nth-child(4n + 3), +div.wunderbaum.wb-rainbow i.wb-indent:nth-child(4n + 3) { + background: rgb(255, 217, 254); +} +div.wunderbaum.wb-rainbow i.wb-expander:nth-child(4n + 4), +div.wunderbaum.wb-rainbow i.wb-indent:nth-child(4n + 4) { + background: rgb(204, 250, 250); +} +div.wunderbaum.wb-fade-expander i.wb-expander { + transition: color 1.5s; + color: rgba(86, 83, 76, 0); +} +div.wunderbaum.wb-fade-expander div.wb-row.wb-loading i.wb-expander, +div.wunderbaum.wb-fade-expander:hover i.wb-expander, +div.wunderbaum.wb-fade-expander:focus i.wb-expander, +div.wunderbaum.wb-fade-expander:focus-within i.wb-expander, +div.wunderbaum.wb-fade-expander [class*="wb-statusnode-"] i.wb-expander { + transition: color 0.6s; + color: var(--wb-node-text-color); +} +div.wunderbaum div.wb-row.wb-skeleton span.wb-title, +div.wunderbaum div.wb-row.wb-skeleton i.wb-icon { + animation: wb-skeleton-animation 1s linear infinite alternate; + border-radius: 0.25em; + color: transparent; + opacity: 0.7; +} +div.wunderbaum.wb-checkbox-auto-hide i.wb-checkbox { + visibility: hidden; +} +div.wunderbaum.wb-checkbox-auto-hide .wb-row:hover i.wb-checkbox, +div.wunderbaum.wb-checkbox-auto-hide .wb-row.wb-selected i.wb-checkbox { + visibility: unset; +} +div.wunderbaum.wb-checkbox-auto-hide:focus .wb-row.wb-active i.wb-checkbox, +div.wunderbaum.wb-checkbox-auto-hide:focus-within + .wb-row.wb-active + i.wb-checkbox { + visibility: unset; +} + +/* --- TOOL CLASSES --- */ +.wb-helper-center { + text-align: center; +} + +.wb-helper-disabled { + color: var(--wb-dim-color); +} + +.wb-helper-hidden { + display: none; +} + +.wb-helper-invalid { + color: var(--wb-error-color); +} + +.wb-helper-lazy-expander { + color: var(--wb-bg-highlight-color); +} + +.wb-helper-link { + cursor: pointer; +} + +.wb-no-select { + user-select: none; + -webkit-user-select: none; +} +.wb-no-select span.wb-title { + user-select: contain; + -webkit-user-select: contain; +} + +/* RTL support */ +.wb-helper-start, +.wb-helper-start > input { + text-align: left; +} + +.wb-helper-end, +.wb-helper-end > input { + text-align: right; +} + +.wb-rtl .wb-helper-start, +.wb-rtl .wb-helper-start > input { + text-align: right; +} +.wb-rtl .wb-helper-end, +.wb-rtl .wb-helper-end > input { + text-align: left; +} + +i.wb-icon { + position: relative; +} +i.wb-icon > span.wb-badge { + position: absolute; + display: inline-block; + top: 0; + left: -0.6rem; + color: white; + background-color: var(--wb-bg-highlight-color); + padding: 0.2em 0.3rem 0.1em 0.3rem; + font-size: 60%; + font-weight: 200; + line-height: 1; + text-align: center; + white-space: nowrap; + border-radius: 0.5rem; + pointer-events: none; +} + +/* Class 'wb-tristate' is used to mark checkboxes that should toggle like + * indeterminate -> checked -> unchecked -> indeterminate ... + */ +.wb-col input[type="checkbox"]:indeterminate { + color: var(--wb-dim-color); + background-color: red; +} + +.wb-col input:invalid { + background-color: var(--wb-error-background-color); +} + +.wb-col.wb-invalid { + border: 1px dotted var(--wb-error-color); +} + +@keyframes wb-spin-animation { + 0% { + transform: rotate(0deg); + } + to { + transform: rotate(1turn); + } +} +@keyframes wb-skeleton-animation { + 0% { + background-color: hsl(200, 20%, 70%); + } + 100% { + background-color: hsl(200, 20%, 95%); + } +} +@keyframes wb-busy-animation { + 0% { + background-position: 0 0; + } + 100% { + background-position: 0 22px; + } +} + +/*# sourceMappingURL=wunderbaum.css.map */ diff --git a/orochi/static/css/wunderbaum/wunderbaum.css.map b/orochi/static/css/wunderbaum/wunderbaum.css.map new file mode 100644 index 00000000..56e50b85 --- /dev/null +++ b/orochi/static/css/wunderbaum/wunderbaum.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../src/wunderbaum.scss"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AA2EA;AAAA;EAME;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;;;AAMF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EAGA;AAsBA;AAuBA;AAwQA;AAoHA;AAwBA;AAgEA;AAEA;AAUA;AAoBA;AAYA;;AAziBA;EAEE;;AAIF;EACE;EACA;;AAGF;EACE;EAEA;;AAMF;EACE;EACA;EACA;;AAGF;AAAA;EAEE;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAMA;EACE;EACA;EACA;EACA;;AAIA;EACE;;AAKF;EAEE;;AAGF;EAEE;;AAGF;EACE;;AAOA;EAEE;EACA;;AAEA;EACE;;AAaN;EAEE;EACA;;AAEA;EACE;;AAON;EACE;;AAEA;EACE;;AAOF;EACE;;AAGF;EAEE;;AAGA;EACE;;AAKJ;EACE;EACA;;AAGF;EAEE;EACA;;AAEA;EAEE;;AAIJ;EACE;;AAGF;AAAA;AAAA;EAGE;EAcA;EASA;;AAGF;EAEE;;AAON;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EAIA;;AAIF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;AAqBA;;AAhBA;AAAA;AAAA;AAAA;EAIE;EACA;EACA;EACA;;AAGF;AAAA;EAEE;EACA;;AAIF;EACE;;AAGF;EACE;EACA;EACA;;AAMA;EACE;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;;AAGF;EACE;EAEA;EACA;EACA;EACA;EACA;;AAUI;EACE;;AAON;EACE;;AAIJ;EACE;;AAEA;EACE;;AAIF;EACE;;AAGF;EACE;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAgBE;EACA;EACA;;AAGF;AAAA;EAEE;;AAcA;EACE;;AAWJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAON;EACE;;AAEA;EACE;;AAQJ;EACE;;AASJ;EACE;;AAEA;EACE;;AAGF;EACE;;AAcN;EACE;;AAEA;EACE;;AAIJ;EACE;;AAEA;EACE;EACA;;AAGA;EACE;EACA;;AAEA;EAGE;EACA;EAGA;EACA;EACA;;AAgBR;AAAA;EAIE;EACA;EACA;;AAKF;EACE;;AAUE;AAAA;EAEE;;AAFF;AAAA;EAEE;;AAFF;AAAA;EAEE;;AAFF;AAAA;EAEE;;AAOJ;EAIE;EACA;;AAGF;AAAA;EAKE;EACA;;AAMF;AAAA;EAEE;EACA;EACA;EACA;;AAOF;EACE;;AAGF;AAAA;EAEE;;AAKA;EACE;;;AAMR;AAEA;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;;AAQJ;AACA;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAIA;AAAA;EAEE;;AAGF;AAAA;EAEE;;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAIJ;AAAA;AAAA;AAMA;EACE;EACA;;;AAGF;EAGE;;;AAGF;EACE;;;AAKF;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE","file":"wunderbaum.css"} diff --git a/orochi/static/js/jstree/jstree.min.js b/orochi/static/js/jstree/jstree.min.js deleted file mode 100644 index abc88e7f..00000000 --- a/orochi/static/js/jstree/jstree.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! jsTree - v3.3.16 - 2023-09-19 - (MIT) */ - -!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"undefined"!=typeof module&&module.exports?module.exports=e(require("jquery")):e(jQuery)}(function(E,P){"use strict";if(!E.jstree){var s=0,a=!1,n=!1,o=!1,r=[],e=E("script:last").attr("src"),b=window.document,c=window.setImmediate,i=window.Promise;!c&&i&&(c=function(e,t){i.resolve(t).then(e)}),E.jstree={version:"3.3.16",defaults:{plugins:[]},plugins:{},path:e&&-1!==e.indexOf("/")?e.replace(/\/[^\/]+$/,""):"",idregex:/[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,root:"#"},E.jstree.create=function(e,i){var r=new E.jstree.core(++s),t=i;return i=E.extend(!0,{},E.jstree.defaults,i),t&&t.plugins&&(i.plugins=t.plugins),E.each(i.plugins,function(e,t){"core"!==e&&(r=r.plugin(t,i[t]))}),E(e).data("jstree",r),r.init(e,i),r},E.jstree.destroy=function(){E(".jstree:jstree").jstree("destroy"),E(b).off(".jstree")},E.jstree.core=function(e){this._id=e,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1,ellipsis:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},E.jstree.reference=function(t){var i=null,e=null;if(!t||!t.id||t.tagName&&t.nodeType||(t=t.id),!e||!e.length)try{e=E(t)}catch(e){}if(!e||!e.length)try{e=E("#"+t.replace(E.jstree.idregex,"\\$&"))}catch(e){}return e&&e.length&&(e=e.closest(".jstree")).length&&(e=e.data("jstree"))?i=e:E(".jstree").each(function(){var e=E(this).data("jstree");if(e&&e._model.data[t])return i=e,!1}),i},E.fn.jstree=function(i){var r="string"==typeof i,s=Array.prototype.slice.call(arguments,1),a=null;return!(!0===i&&!this.length)&&(this.each(function(){var e=E.jstree.reference(this),t=r&&e?e[i]:null;if(a=r&&t?t.apply(e,s):null,e||r||i!==P&&!E.isPlainObject(i)||E.jstree.create(this,i),null!==(a=e&&!r||!0===i?e||!1:a)&&a!==P)return!1}),null!==a&&a!==P?a:this)},E.expr.pseudos.jstree=E.expr.createPseudo(function(e){return function(e){return E(e).hasClass("jstree")&&E(e).data("jstree")!==P}}),E.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:E.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,ellipsis:!1,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0,loaded_state:!1,restore_focus:!0,compute_elements_positions:!1,keyboard:{"ctrl-space":function(e){e.type="click",E(e.currentTarget).trigger(e)},enter:function(e){e.type="click",E(e.currentTarget).trigger(e)},left:function(e){var e;e.preventDefault(),this.is_open(e.currentTarget)?this.close_node(e.currentTarget):(e=this.get_parent(e.currentTarget))&&e.id!==E.jstree.root&&this.get_node(e,!0).children(".jstree-anchor").trigger("focus")},up:function(e){e.preventDefault();var e=this.get_prev_dom(e.currentTarget);e&&e.length&&e.children(".jstree-anchor").trigger("focus")},right:function(e){var e;e.preventDefault(),this.is_closed(e.currentTarget)?this.open_node(e.currentTarget,function(e){this.get_node(e,!0).children(".jstree-anchor").trigger("focus")}):!this.is_open(e.currentTarget)||(e=this.get_node(e.currentTarget,!0).children(".jstree-children")[0])&&E(this._firstChild(e)).children(".jstree-anchor").trigger("focus")},down:function(e){e.preventDefault();var e=this.get_next_dom(e.currentTarget);e&&e.length&&e.children(".jstree-anchor").trigger("focus")},"*":function(e){this.open_all()},home:function(e){e.preventDefault();var e=this._firstChild(this.get_container_ul()[0]);e&&E(e).children(".jstree-anchor").filter(":visible").trigger("focus")},end:function(e){e.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().trigger("focus")},f2:function(e){e.preventDefault(),this.edit(e.currentTarget)}},allow_reselect:!1},E.jstree.core.prototype={plugin:function(e,t){var i=E.jstree.plugins[e];return i?(this._data[e]={},i.prototype=this,new i(t,this)):this},init:function(e,t){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[E.jstree.root]={id:E.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=E(e).addClass("jstree jstree-"+this._id),this.settings=t,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().outerHeight()||24,this._data.core.node=this._create_prototype_node(),this.trigger("loading"),this.load_node(E.jstree.root)},destroy:function(e){if(this.trigger("destroy"),this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(e){}e||this.element.empty(),this.teardown()},_create_prototype_node:function(){var e=b.createElement("LI"),t,i;return e.setAttribute("role","none"),(t=b.createElement("I")).className="jstree-icon jstree-ocl",t.setAttribute("role","presentation"),e.appendChild(t),(t=b.createElement("A")).className="jstree-anchor",t.setAttribute("href","#"),t.setAttribute("tabindex","-1"),t.setAttribute("role","treeitem"),(i=b.createElement("I")).className="jstree-icon jstree-themeicon",i.setAttribute("role","presentation"),t.appendChild(i),e.appendChild(t),t=i=null,e},_kbevent_to_func:function(e){var t={8:"Backspace",9:"Tab",13:"Enter",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock",16:"Shift",17:"Ctrl",18:"Alt",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*",173:"-"},i=[];if(e.ctrlKey&&i.push("ctrl"),e.altKey&&i.push("alt"),e.shiftKey&&i.push("shift"),i.push(t[e.which]?t[e.which].toLowerCase():e.which),"shift-shift"===(i=i.sort().join("-").toLowerCase())||"ctrl-ctrl"===i||"alt-alt"===i)return null;var r=this.settings.core.keyboard,s,a;for(s in r)if(r.hasOwnProperty(s)&&(a="-"!==(a=s)&&"+"!==a?(a=a.replace("--","-MINUS").replace("+-","-MINUS").replace("++","-PLUS").replace("-+","-PLUS")).split(/-|\+/).sort().join("-").replace("MINUS","-").replace("PLUS","+").toLowerCase():a)===i)return r[s];return null},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var s="",a=null,t=0;this.element.on("dblclick.jstree",function(e){if(e.target.tagName&&"input"===e.target.tagName.toLowerCase())return!0;if(b.selection&&b.selection.empty)b.selection.empty();else if(window.getSelection){var e=window.getSelection();try{e.removeAllRanges(),e.collapse()}catch(e){}}}).on("mousedown.jstree",function(e){e.target===this.element[0]&&(e.preventDefault(),t=+new Date)}.bind(this)).on("mousedown.jstree",".jstree-ocl",function(e){e.preventDefault()}).on("click.jstree",".jstree-ocl",function(e){this.toggle_node(e.target)}.bind(this)).on("dblclick.jstree",".jstree-anchor",function(e){if(e.target.tagName&&"input"===e.target.tagName.toLowerCase())return!0;this.settings.core.dblclick_toggle&&this.toggle_node(e.target)}.bind(this)).on("click.jstree",".jstree-anchor",function(e){e.preventDefault(),e.currentTarget!==b.activeElement&&E(e.currentTarget).trigger("focus"),this.activate_node(e.currentTarget,e)}.bind(this)).on("keydown.jstree",".jstree-anchor",function(e){if(e.target.tagName&&"input"===e.target.tagName.toLowerCase())return!0;this._data.core.rtl&&(37===e.which?e.which=39:39===e.which&&(e.which=37));var t=this._kbevent_to_func(e);if(t){var e=t.call(this,e);if(!1===e||!0===e)return e}}.bind(this)).on("load_node.jstree",function(e,t){t.status&&(t.node.id!==E.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){for(var e=[],t,i,t=0,i=this._data.core.selected.length;t .jstree-anchor").trigger("focus"))}.bind(this)).on("mouseenter.jstree",".jstree-anchor",function(e){this.hover_node(e.currentTarget)}.bind(this)).on("mouseleave.jstree",".jstree-anchor",function(e){this.dehover_node(e.currentTarget)}.bind(this))},unbind:function(){this.element.off(".jstree"),E(b).off(".jstree-"+this._id)},trigger:function(e,t){((t=t||{}).instance=this).element.triggerHandler(e.replace(".jstree","")+".jstree",t)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(e){var t=this.settings.core.strings;return E.vakata.is_function(t)?t.call(this,e):t&&t[e]?t[e]:e},_firstChild:function(e){e=e?e.firstChild:null;while(null!==e&&1!==e.nodeType)e=e.nextSibling;return e},_nextSibling:function(e){e=e?e.nextSibling:null;while(null!==e&&1!==e.nodeType)e=e.nextSibling;return e},_previousSibling:function(e){e=e?e.previousSibling:null;while(null!==e&&1!==e.nodeType)e=e.previousSibling;return e},get_node:function(e,t){var i;(e=e&&(e.id||0===e.id)?e.id:e)instanceof E&&e.length&&e[0].id&&(e=e[0].id);try{if(this._model.data[e])e=this._model.data[e];else if("string"==typeof e&&this._model.data[e.replace(/^#/,"")])e=this._model.data[e.replace(/^#/,"")];else if("string"==typeof e&&(i=E("#"+e.replace(E.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[i.closest(".jstree-node").attr("id")])e=this._model.data[i.closest(".jstree-node").attr("id")];else if((i=this.element.find(e)).length&&this._model.data[i.closest(".jstree-node").attr("id")])e=this._model.data[i.closest(".jstree-node").attr("id")];else{if(!(i=this.element.find(e)).length||!i.hasClass("jstree"))return!1;e=this._model.data[E.jstree.root]}return e=t?e.id===E.jstree.root?this.element:E("#"+e.id.replace(E.jstree.idregex,"\\$&"),this.element):e}catch(e){return!1}},get_path:function(e,t,i){if(!(e=e.parents?e:this.get_node(e))||e.id===E.jstree.root||!e.parents)return!1;var r,s,a=[];for(a.push(i?e.id:e.text),r=0,s=e.parents.length;r").html(t),n.text=this.settings.core.force_text?t.text():t.html(),t=e.data(),n.data=t?E.extend(!0,{},t):null,n.state.opened=e.hasClass("jstree-open"),n.state.selected=e.children("a").hasClass("jstree-clicked"),n.state.disabled=e.children("a").hasClass("jstree-disabled"),n.data&&n.data.jstree)for(o in n.data.jstree)n.data.jstree.hasOwnProperty(o)&&(n.state[o]=n.data.jstree[o]);(t=e.children("a").children(".jstree-themeicon")).length&&(n.icon=!t.hasClass("jstree-themeicon-hidden")&&t.attr("rel")),n.state.icon!==P&&(n.icon=n.state.icon),n.icon!==P&&null!==n.icon&&""!==n.icon||(n.icon=!0),t=e.children("ul").children("li");do{d="j"+this._id+"_"+ ++this._cnt}while(a[d]);return n.id=n.li_attr.id?n.li_attr.id.toString():d,t.length?(t.each(function(e,t){r=this._parse_model_from_html(E(t),n.id,i),s=this._model.data[r],n.children.push(r),s.children_d.length&&(n.children_d=n.children_d.concat(s.children_d))}.bind(this)),n.children_d=n.children_d.concat(n.children)):e.hasClass("jstree-closed")&&(n.state.loaded=!1),n.li_attr.class&&(n.li_attr.class=n.li_attr.class.replace("jstree-closed","").replace("jstree-open","")),n.a_attr.class&&(n.a_attr.class=n.a_attr.class.replace("jstree-clicked","").replace("jstree-disabled","")),(a[n.id]=n).state.selected&&this._data.core.selected.push(n.id),n.id},_parse_model_from_flat_json:function(e,t,i){i=i?i.concat():[],t&&i.unshift(t);var r=e.id.toString(),s=this._model.data,a=this._model.default_state,n,o,d,c,l={id:r,text:e.text||"",icon:e.icon===P||e.icon,parent:t,parents:i,children:e.children||[],children_d:e.children_d||[],data:e.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(n in a)a.hasOwnProperty(n)&&(l.state[n]=a[n]);if(e&&e.data&&e.data.jstree&&e.data.jstree.icon&&(l.icon=e.data.jstree.icon),l.icon!==P&&null!==l.icon&&""!==l.icon||(l.icon=!0),e&&e.data&&(l.data=e.data,e.data.jstree))for(n in e.data.jstree)e.data.jstree.hasOwnProperty(n)&&(l.state[n]=e.data.jstree[n]);if(e&&"object"==typeof e.state)for(n in e.state)e.state.hasOwnProperty(n)&&(l.state[n]=e.state[n]);if(e&&"object"==typeof e.li_attr)for(n in e.li_attr)e.li_attr.hasOwnProperty(n)&&(l.li_attr[n]=e.li_attr[n]);if(l.li_attr.id||(l.li_attr.id=r),e&&"object"==typeof e.a_attr)for(n in e.a_attr)e.a_attr.hasOwnProperty(n)&&(l.a_attr[n]=e.a_attr[n]);for(e&&e.children&&!0===e.children&&(l.state.loaded=!1,l.children=[],l.children_d=[]),n=0,o=(s[l.id]=l).children.length;n
  • "+this.get_string("Loading ...")+"
  • "),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(E.jstree.root,function(e,t){t&&(this.get_container_ul()[0].className=i,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(E.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(t){if(!(t=this.get_node(t))||t.id===E.jstree.root)return!1;var i=[],e=[],r=this._data.core.selected.concat([]);e.push(t.id),!0===t.state.opened&&i.push(t.id),this.get_node(t,!0).find(".jstree-open").each(function(){e.push(this.id),i.push(this.id)}),this._load_nodes(e,function(e){this.open_node(i,!1,0),this.select_node(r),this.trigger("refresh_node",{node:t,nodes:e})}.bind(this),!1,!0)},set_id:function(e,t){if(!(e=this.get_node(e))||e.id===E.jstree.root)return!1;var i,r,s=this._model.data,a=e.id;for(t=t.toString(),s[e.parent].children[E.inArray(e.id,s[e.parent].children)]=t,i=0,r=e.parents.length;ie.children.length&&(i=e.children.length),t.id===P&&(t.id=!0),!this.check("create_node",t,e,i))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(!0===t.id&&delete t.id,!(t=this._parse_model_from_json(t,e.id,e.parents.concat())))return!1;for(a=this.get_node(t),(n=[]).push(t),n=n.concat(a.children_d),this.trigger("model",{nodes:n,parent:e.id}),e.children_d=e.children_d.concat(n),o=0,d=e.parents.length;oh.children.length&&(i=h.children.length),!this.check("move_node",e,h,i,{core:!0,origin:n,is_multi:_&&_._id&&_._id!==this._id,is_foreign:!_||!_._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(e.parent===h.id){for(u=h.children.concat(),-1!==(f=E.inArray(e.id,u))&&(u=E.vakata.array_remove(u,f),ff.children.length&&(i=f.children.length),!this.check("copy_node",e,f,i,{core:!0,origin:n,is_multi:p&&p._id&&p._id!==this._id,is_foreign:!p||!p._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(!(g=p?p.get_json(e,{no_id:!0,no_data:!0,no_state:!0}):e))return!1;if(!0===g.id&&delete g.id,!(g=this._parse_model_from_json(g,f.id,f.parents.concat())))return!1;for(l=this.get_node(g),e&&e.state&&!1===e.state.loaded&&(l.state.loaded=!1),(c=[]).push(g),c=c.concat(l.children_d),this.trigger("model",{nodes:c,parent:f.id}),h=0,_=f.parents.length;h<_;h++)this._model.data[f.parents[h]].children_d=this._model.data[f.parents[h]].children_d.concat(c);for(c=[],h=0,_=f.children.length;h<_;h++)c[i<=h?h+1:h]=f.children[h];return c[i]=l.id,f.children=c,f.children_d.push(l.id),f.children_d=f.children_d.concat(l.children_d),f.id===E.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(f.id),a||this.redraw(f.id===E.jstree.root),r&&r.call(this,l,f,i),this.trigger("copy_node",{node:l,original:e,parent:f.id,position:i,old_parent:u,old_position:p&&p._id&&u&&p._model.data[u]&&p._model.data[u].children?E.inArray(e.id,p._model.data[u].children):-1,is_multi:p&&p._id&&p._id!==this._id,is_foreign:!p||!p._id,old_instance:p,new_instance:this}),l.id},cut:function(e){if(e=e||this._data.core.selected.concat(),!(e=!E.vakata.is_array(e)?[e]:e).length)return!1;for(var t=[],i,r,s,r=0,s=e.length;r"),o=e,d=E("
    ",{css:{position:"absolute",top:"-200px",left:t?"0px":"-1000px",visibility:"hidden"}}).appendTo(b.body),c=E("",{value:o,class:"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:function(e){e.stopImmediatePropagation(),e.preventDefault();var t,i=n.children(".jstree-rename-input").val(),e=this.settings.core.force_text,e;""===i&&(i=o),d.remove(),n.replaceWith(a),n.remove(),o=e?o:E("
    ").append(E.parseHTML(o)).html(),r=this.get_node(r),this.set_text(r,o),(e=!!this.rename_node(r,e?E("
    ").text(i).text():E("
    ").append(E.parseHTML(i)).html()))||this.set_text(r,o),this._data.core.focused=l.id,setTimeout(function(){var e=this.get_node(l.id,!0);e.length&&(this._data.core.focused=l.id,e.children(".jstree-anchor").trigger("focus"))}.bind(this),0),s&&s.call(this,l,e,h,i),c=null}.bind(this),keydown:function(e){var t=e.which;27===t&&(h=!0,this.value=o),27!==t&&13!==t&&37!==t&&38!==t&&39!==t&&40!==t&&32!==t||e.stopImmediatePropagation(),27!==t&&13!==t||(e.preventDefault(),this.blur())},click:function(e){e.stopImmediatePropagation()},mousedown:function(e){e.stopImmediatePropagation()},keyup:function(e){c.width(Math.min(d.text("pW"+this.value).width(),i))},keypress:function(e){if(13===e.which)return!1}}),t={fontFamily:a.css("fontFamily")||"",fontSize:a.css("fontSize")||"",fontWeight:a.css("fontWeight")||"",fontStyle:a.css("fontStyle")||"",fontStretch:a.css("fontStretch")||"",fontVariant:a.css("fontVariant")||"",letterSpacing:a.css("letterSpacing")||"",wordSpacing:a.css("wordSpacing")||""},n.attr("class",a.attr("class")).append(a.contents().clone()).append(c),a.replaceWith(n),d.css(t),c.css(t).width(Math.min(d.text("pW"+c[0].value).width(),i))[0].select(),void E(b).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(e){c&&e.target!==c&&E(c).trigger("blur")})):(this.settings.core.error.call(this,this._data.core.last_error),!1))},set_theme:function(e,t){if(!e)return!1;var i,i;(t=!0===t?(i=(i=this.settings.core.themes.dir)||E.jstree.path+"/themes")+"/"+e+"/style.css":t)&&-1===E.inArray(t,r)&&(E("head").append(''),r.push(t)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=e,this.element.addClass("jstree-"+e),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+e+"-responsive"),this.trigger("set_theme",{theme:e})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(e){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),(this._data.core.themes.variant=e)&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped"),this.trigger("show_stripes")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped"),this.trigger("hide_stripes")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots"),this.trigger("show_dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots"),this.trigger("hide_dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons"),this.trigger("show_icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons"),this.trigger("hide_icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},show_ellipsis:function(){this._data.core.themes.ellipsis=!0,this.get_container_ul().addClass("jstree-ellipsis"),this.trigger("show_ellipsis")},hide_ellipsis:function(){this._data.core.themes.ellipsis=!1,this.get_container_ul().removeClass("jstree-ellipsis"),this.trigger("hide_ellipsis")},toggle_ellipsis:function(){this._data.core.themes.ellipsis?this.hide_ellipsis():this.show_ellipsis()},set_icon:function(e,t){var i,r,s,a;if(E.vakata.is_array(e)){for(i=0,r=(e=e.slice()).length;i "),r=!1,i+="
  • ",i+="",h.vakata.context.settings.icons&&(i+="'+(t.shortcut_label||"")+"":"")+"",t.submenu&&(s=h.vakata.context._parse(t.submenu,!0))&&(i+=s),i+="
  • ",void(t.separator_after&&(i+="
  •  
  • ",r=!0)))}),i=i.replace(/
  • <\/li\>$/,""),t&&(i+=""),t||(g.html=i,h.vakata.context._trigger("parse")),10"),g.element.on("mouseenter","li",function(e){e.stopImmediatePropagation(),h.contains(this,e.relatedTarget)||(i&&clearTimeout(i),g.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),h(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),h.vakata.context._show_submenu(this))}).on("mouseleave","li",function(e){h.contains(this,e.relatedTarget)||h(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(e){var t;h(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),h.vakata.context.settings.hide_onmouseleave&&(i=setTimeout((t=this,function(){h.vakata.context.hide()}),h.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(e){e.preventDefault(),h(this).trigger("blur").parent().hasClass("vakata-context-disabled")||!1===h.vakata.context._execute(h(this).attr("rel"))||h.vakata.context.hide()}).on("keydown","a",function(e){var t=null;switch(e.which){case 13:case 32:e.type="click",e.preventDefault(),h(e.currentTarget).trigger(e);break;case 37:g.is_visible&&(g.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 38:g.is_visible&&((t=!(t=g.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first()).length?g.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last():t).addClass("vakata-context-hover").children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 39:g.is_visible&&(g.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 40:g.is_visible&&((t=!(t=g.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first()).length?g.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first():t).addClass("vakata-context-hover").children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 27:h.vakata.context.hide(),e.preventDefault()}}).on("keydown",function(e){e.preventDefault();var e=g.element.find(".vakata-contextmenu-shortcut-"+e.which).parent();e.parent().not(".vakata-context-disabled")&&e.trigger("click")}),h(b).on("mousedown.vakata.jstree",function(e){g.is_visible&&g.element[0]!==e.target&&!h.contains(g.element[0],e.target)&&h.vakata.context.hide()}).on("context_show.vakata.jstree",function(e,t){g.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),_&&g.element.addClass("vakata-context-rtl").css("direction","rtl"),g.element.find("ul").hide().end()})}),E.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1,blank_space_drop:!1},E.jstree.plugins.dnd=function(e,o){this.init=function(e,t){o.init.call(this,e,t),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in b.createElement("span")},this.bind=function(){o.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",function(e){if(this.settings.dnd.large_drag_target&&E(e.target).closest(".jstree-node")[0]!==e.currentTarget)return!0;if("touchstart"===e.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!E(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var t=this.get_node(e.target),i=this.is_selected(t)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,r=1'+r+'+');E.vakata.dnd._trigger("start",e,{helper:E(),element:u,data:d})}}.bind(this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(e){return e.preventDefault(),E.vakata.dnd._trigger("move",e,{helper:E(),element:u,data:d}),!1}).on("drop.jstree",function(e){return e.preventDefault(),E.vakata.dnd._trigger("stop",e,{helper:E(),element:u,data:d}),!1}.bind(this))},this.redraw_node=function(e,t,i,r){if((e=o.redraw_node.apply(this,arguments))&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)e.setAttribute("draggable",!0);else{for(var s,a,n=null,s=0,a=e.childNodes.length;s ').hide();E(b).on("dragover.vakata.jstree",function(e){u&&E.vakata.dnd._trigger("move",e,{helper:E(),element:u,data:d})}).on("drop.vakata.jstree",function(e){u&&(E.vakata.dnd._trigger("stop",e,{helper:E(),element:u,data:d}),d=u=null)}).on("dnd_start.vakata.jstree",function(e,t){O=N=!1,t&&t.data&&t.data.jstree&&S.appendTo(b.body)}).on("dnd_move.vakata.jstree",function(e,s){var a=s.event.target!==O.target;if(A&&(s.event&&"dragover"===s.event.type&&!a||clearTimeout(A)),s&&s.data&&s.data.jstree&&(!s.event.target.id||"jstree-marker"!==s.event.target.id)){O=s.event;var n=E.jstree.reference(s.event.target),o=!1,d=!1,t=!1,i,c,l,h,_,g,u,f,p,m,v,j,k,b,y,x,w,C;if(n&&n._data&&n._data.dnd)if(S.attr("class","jstree-"+n.get_theme()+(n.settings.core.themes.responsive?" jstree-dnd-responsive":"")),x=s.data.origin&&(s.data.origin.settings.dnd.always_copy||s.data.origin.settings.dnd.copy&&(s.event.metaKey||s.event.ctrlKey)),s.helper.children().attr("class","jstree-"+n.get_theme()+" jstree-"+n.get_theme()+"-"+n.get_theme_variant()+" "+(n.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[x?"show":"hide"](),s.event.target!==n.element[0]&&s.event.target!==n.get_container_ul()[0]||0!==n.get_container_ul().children().length&&!n.settings.dnd.blank_space_drop){if((o=n.settings.dnd.large_drop_target?E(s.event.target).closest(".jstree-node").children(".jstree-anchor"):E(s.event.target).closest(".jstree-anchor"))&&o.length&&o.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(d=o.offset(),t=(s.event.pageY!==P?s.event:s.event.originalEvent).pageY-d.top,h=o.outerHeight(),u=tE.inArray(s.data.nodes[p],k.children)&&--j),!(f=f&&(n&&n.settings&&n.settings.dnd&&!1===n.settings.dnd.check_while_dragging||n.check(v,s.data.origin&&s.data.origin!==n?s.data.origin.get_node(s.data.nodes[p]):s.data.nodes[p],_,j,{dnd:!0,ref:n.get_node(o.parent()),pos:t,origin:s.data.origin,is_multi:s.data.origin&&s.data.origin!==n,is_foreign:!s.data.origin})))){n&&n.last_error&&(T=n.last_error());break}var i,r;if("i"===t&&o.parent().is(".jstree-closed")&&n.settings.dnd.open_timeout&&(s.event&&"dragover"===s.event.type&&!a||(A&&clearTimeout(A),A=setTimeout((r=o,function(){i.open_node(r)}),(i=n).settings.dnd.open_timeout))),f)return(w=n.get_node(_,!0)).hasClass(".jstree-dnd-parent")||(E(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),w.addClass("jstree-dnd-parent")),N={ins:n,par:_,pos:"i"!==t||"last"!==b||0!==g||n.is_loaded(y)?g:"last"},S.css({left:c+"px",top:l+"px"}).show(),S.removeClass("jstree-above jstree-inside jstree-below").addClass(C),s.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),s.event.originalEvent&&s.event.originalEvent.dataTransfer&&(s.event.originalEvent.dataTransfer.dropEffect=x?"copy":"move"),T={},!(u=!0)}),!0===u))return}else{for(f=!0,p=0,m=s.data.nodes.length;p"),escape:function(e){return f.vakata.html.div.text(e).html()},strip:function(e){return f.vakata.html.div.empty().append(f.parseHTML(e)).text()}}),target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},f.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:10},_trigger:function(e,t,i){(i=i===P?f.vakata.dnd._get():i).event=t,f(b).triggerHandler("dnd_"+e+".vakata",i)},_get:function(){return{data:p.data,element:p.element,helper:p.helper}},_clean:function(){p.helper&&p.helper.remove(),p.scroll_i&&(clearInterval(p.scroll_i),p.scroll_i=!1),p={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},u=null,f(b).off("mousemove.vakata.jstree touchmove.vakata.jstree",f.vakata.dnd.drag),f(b).off("mouseup.vakata.jstree touchend.vakata.jstree",f.vakata.dnd.stop)},_scroll:function(e){if(!p.scroll_e||!p.scroll_l&&!p.scroll_t)return p.scroll_i&&(clearInterval(p.scroll_i),p.scroll_i=!1),!1;if(!p.scroll_i)return p.scroll_i=setInterval(f.vakata.dnd._scroll,100),!1;if(!0===e)return!1;var t=p.scroll_e.scrollTop(),e=p.scroll_e.scrollLeft();p.scroll_e.scrollTop(t+p.scroll_t*f.vakata.dnd.settings.scroll_speed),p.scroll_e.scrollLeft(e+p.scroll_l*f.vakata.dnd.settings.scroll_speed),t===p.scroll_e.scrollTop()&&e===p.scroll_e.scrollLeft()||f.vakata.dnd._trigger("scroll",p.scroll_e)},start:function(e,t,i){"touchstart"===e.type&&e.originalEvent&&e.originalEvent.changedTouches&&e.originalEvent.changedTouches[0]&&(e.pageX=e.originalEvent.changedTouches[0].pageX,e.pageY=e.originalEvent.changedTouches[0].pageY,e.target=b.elementFromPoint(e.originalEvent.changedTouches[0].pageX-window.pageXOffset,e.originalEvent.changedTouches[0].pageY-window.pageYOffset)),p.is_drag&&f.vakata.dnd.stop({});try{e.currentTarget.unselectable="on",e.currentTarget.onselectstart=function(){return!1},e.currentTarget.style&&(e.currentTarget.style.touchAction="none",e.currentTarget.style.msTouchAction="none",e.currentTarget.style.MozUserSelect="none")}catch(e){}return p.init_x=e.pageX,p.init_y=e.pageY,p.data=t,p.is_down=!0,p.element=e.currentTarget,p.target=e.target,p.is_touch="touchstart"===e.type,!1!==i&&(p.helper=f("
    ").html(i).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),f(b).on("mousemove.vakata.jstree touchmove.vakata.jstree",f.vakata.dnd.drag),f(b).on("mouseup.vakata.jstree touchend.vakata.jstree",f.vakata.dnd.stop),!1},drag:function(i){if("touchmove"===i.type&&i.originalEvent&&i.originalEvent.changedTouches&&i.originalEvent.changedTouches[0]&&(i.pageX=i.originalEvent.changedTouches[0].pageX,i.pageY=i.originalEvent.changedTouches[0].pageY,i.target=b.elementFromPoint(i.originalEvent.changedTouches[0].pageX-window.pageXOffset,i.originalEvent.changedTouches[0].pageY-window.pageYOffset)),p.is_down){if(!p.is_drag){if(!(Math.abs(i.pageX-p.init_x)>(p.is_touch?f.vakata.dnd.settings.threshold_touch:f.vakata.dnd.settings.threshold)||Math.abs(i.pageY-p.init_y)>(p.is_touch?f.vakata.dnd.settings.threshold_touch:f.vakata.dnd.settings.threshold)))return;p.helper&&(p.helper.appendTo(b.body),p.helper_w=p.helper.outerWidth()),p.is_drag=!0,f(p.target).one("click.vakata",!1),f.vakata.dnd._trigger("start",i)}var e=!1,t=!1,r=!1,s=!1,a=!1,n=!1,o=!1,d=!1,c=!1,l=!1;return p.scroll_t=0,p.scroll_l=0,p.scroll_e=!1,f(f(i.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return this.ownerDocument&&/^auto|scroll$/.test(f(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var e=f(this),t=e.offset();if(this.scrollHeight>this.offsetHeight&&(t.top+e.height()-i.pageYthis.offsetWidth&&(t.left+e.width()-i.pageXa&&(l=a-(p.helper_w+2)),p.helper.css({left:l+"px",top:(c=r&&rs)break;c=_}return{isMatch:0<=a,score:u}},!0===e?{search:t}:t(e)},w.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1},E.jstree.defaults.sort=function(e,t){return this.get_text(e)>this.get_text(t)?1:-1};var m=!(E.jstree.plugins.sort=function(e,t){this.bind=function(){t.bind.call(this),this.element.on("model.jstree",function(e,t){this.sort(t.parent,!0)}.bind(this)).on("rename_node.jstree create_node.jstree",function(e,t){this.sort(t.parent||t.node.parent,!1),this.redraw_node(t.parent||t.node.parent,!0)}.bind(this)).on("move_node.jstree copy_node.jstree",function(e,t){this.sort(t.parent,!1),this.redraw_node(t.parent,!0)}.bind(this))},this.sort=function(e,t){var i,r;if((e=this.get_node(e))&&e.children&&e.children.length&&(e.children.sort(this.settings.sort.bind(this)),t))for(i=0,r=e.children_d.length;ii.ttl)&&(!!(i=(i=i&&i.state?i.state:i)&&E.vakata.is_function(this.settings.state.filter)?this.settings.state.filter.call(this,i):i)&&(this.settings.state.preserve_loaded||delete i.core.loaded,this.element.one("set_state.jstree",function(e,t){t.instance.trigger("restore_state",{state:E.extend(!0,{},i)})}),this.set_state(i),!0))},this.clear_state=function(){return E.vakata.storage.del(this.settings.state.key)}},E.vakata.storage={set:function(e,t){return window.localStorage.setItem(e,t)},get:function(e){return window.localStorage.getItem(e)},del:function(e){return window.localStorage.removeItem(e)}},E.jstree.defaults.types={default:{}},E.jstree.defaults.types[E.jstree.root]={},E.jstree.plugins.types=function(e,l){this.init=function(e,t){var i,r;if(t&&t.types&&t.types.default)for(i in t.types)if("default"!==i&&i!==E.jstree.root&&t.types.hasOwnProperty(i))for(r in t.types.default)t.types.default.hasOwnProperty(r)&&t.types[i][r]===P&&(t.types[i][r]=t.types.default[r]);l.init.call(this,e,t),this._model.data[E.jstree.root].type=E.jstree.root},this.refresh=function(e,t){l.refresh.call(this,e,t),this._model.data[E.jstree.root].type=E.jstree.root},this.bind=function(){this.element.on("model.jstree",function(e,t){for(var i=this._model.data,r=t.nodes,s=this.settings.types,a,n,o="default",d,a=0,n=r.length;a .jstree-ocl",function(e){e.stopImmediatePropagation();var t=E.Event("click",{metaKey:e.metaKey,ctrlKey:e.ctrlKey,altKey:e.altKey,shiftKey:e.shiftKey});E(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(t).trigger("focus")}.bind(this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",function(e){return e.stopImmediatePropagation(),this.is_disabled(e.currentTarget)||this.hover_node(e.currentTarget),!1}.bind(this)).on("mouseleave.jstree",".jstree-node",function(e){this.dehover_node(e.currentTarget)}.bind(this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),a.teardown.call(this)},this.redraw_node=function(e,t,i,r){var s;return(e=a.redraw_node.apply(this,arguments))&&(s=j.cloneNode(!0),-1!==E.inArray(e.id,this._data.core.selected)&&(s.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===e.id&&(s.className+=" jstree-wholerow-hovered"),e.insertBefore(s,e.childNodes[0])),e}},window.customElements&&Object&&Object.create){var e=Object.create(HTMLElement.prototype);e.createdCallback=function(){var e={core:{},plugins:[]},t;for(t in E.jstree.plugins)E.jstree.plugins.hasOwnProperty(t)&&this.attributes[t]&&(e.plugins.push(t),this.getAttribute(t)&&JSON.parse(this.getAttribute(t))&&(e[t]=JSON.parse(this.getAttribute(t))));for(t in E.jstree.defaults.core)E.jstree.defaults.core.hasOwnProperty(t)&&this.attributes[t]&&(e.core[t]=JSON.parse(this.getAttribute(t))||this.getAttribute(t));E(this).jstree(e)};try{window.customElements.define("vakata-jstree",function(){},{prototype:e})}catch(e){}}}}); diff --git a/orochi/static/js/jstree/jstreetable.js b/orochi/static/js/jstree/jstreetable.js deleted file mode 100644 index 8fe1fa6b..00000000 --- a/orochi/static/js/jstree/jstreetable.js +++ /dev/null @@ -1,1107 +0,0 @@ -/* - * http://github.com/adamjimenez/jstree-table - * - * This plugin handles adding columns to a tree to display additional data - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/mit-license.php - * - * Works only with jstree version >= 3.0.0 - * - * $Revision: 3.4.2 $ - */ - -/*jslint nomen:true */ -/*jshint unused:vars */ -/*global navigator, document, jQuery, define, localStorage */ - -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery', 'jstree'], factory); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - var renderATitle, getIndent, copyData, htmlstripre, findLastClosedNode, BLANKRE = /^\s*$/g, - IDREGEX = /[\\:&!^|()\[\]<>@*'+~#";,= \/${}%]/g, escapeId = function (id) { - return (id||"").replace(IDREGEX,'\\$&'); - }, NODE_DATA_ATTR = "data-jstreetable", COL_DATA_ATTR = "data-jstreetable-column", - SPECIAL_TITLE = "_DATA_", LEVELINDENT = 24, styled = false, TABLECELLID_PREFIX = "jstable_",TABLECELLID_POSTFIX = "_col", - MINCOLWIDTH = 10, - findDataCell = function (from,id) { - return from.find("div["+NODE_DATA_ATTR+'="'+ escapeId(id) +'"]'); - }, - isClickedSep = false, toResize = null, oldMouseX = 0, newMouseX = 0; - - /*jslint regexp:true */ - htmlstripre = /<\/?[^>]+>/gi; - /*jslint regexp:false */ - - getIndent = function(node,tree) { - var div, i, li, width; - - // did we already save it for this tree? - tree._tableSettings = tree._tableSettings || {}; - if (tree._tableSettings.indent > 0) { - width = tree._tableSettings.indent; - } else { - // create a new div on the DOM but not visible on the page - div = $("
    "); - i = node.prev("i"); - li = i.parent(); - // add to that div all of the classes on the tree root - div.addClass(tree.get_node("#",true).attr("class")); - - // move the li to the temporary div root - li.appendTo(div); - - // attach to the body quickly - div.appendTo($("body")); - - // get the width - width = i.width() || LEVELINDENT; - - // detach the li from the new div and destroy the new div - li.detach(); - div.remove(); - - // save it for the future - tree._tableSettings.indent = width; - } - - - return(width); - - }; - - copyData = function (fromtree,from,totree,to,recurse) { - var i, j; - to.data = $.extend(true, {}, from.data); - if (from && from.children_d && recurse) { - for(i = 0, j = from.children_d.length; i < j; i++) { - copyData(fromtree,fromtree.get_node(from.children_d[i]),totree,totree.get_node(to.children_d[i]),recurse); - } - } - }; - - findLastClosedNode = function (tree,id) { - // first get our node - var ret, node = tree.get_node(id), children = node.children; - // is it closed? - if (!children || children.length <= 0 || !node.state.opened) { - ret = id; - } else { - ret = findLastClosedNode(tree,children[children.length-1]); - } - return(ret); - }; - - renderAWidth = function(node,tree) { - var depth, width, - fullWidth = parseInt(tree.settings.table.columns[0].width,10) + parseInt(tree._tableSettings.treeWidthDiff,10); - // need to use a selector in jquery 1.4.4+ - depth = tree.get_node(node).parents.length; - width = fullWidth - depth*getIndent(node,tree); - // the following line is no longer needed, since we are doing this inside a - //a.css({"vertical-align": "top", "overflow":"hidden"}); - return(fullWidth); - }; - renderATitle = function(node,t,tree) { - var a = node.get(0).tagName.toLowerCase() === "a" ? node : node.children("a"), title, col = tree.settings.table.columns[0]; - // get the title - title = ""; - if (col.title) { - if (col.title === SPECIAL_TITLE) { - title = tree.get_text(t); - } else if (t.attr(col.title)) { - title = t.attr(col.title); - } - } - // strip out HTML - title = title.replace(htmlstripre, ''); - if (title) { - a.attr("title",title); - } - }; - - $.jstree.defaults.table = { - width: 'auto' - }; - - $.jstree.plugins.table = function(options,parent) { - var _this = this; - - this._initialize = function () { - if (!this._initialized) { - var s = this.settings.table || {}, styles, container = this.element, i, - gs = this._tableSettings = { - columns : s.columns || [], - treeClass : "jstree-table-col-0", - context: s.contextmenu || false, - columnWidth : s.columnWidth, - defaultConf : {"*display":"inline","*+display":"inline"}, - isThemeroller : !!this._data.themeroller, - treeWidthDiff : 0, - resizable : s.resizable, - draggable : s.draggable, - stateful: s.stateful, - indent: 0, - sortFn: [], - sortOrder: 'text', - sortAsc: true, - fixedHeader: s.fixedHeader !== false, - headerContextMenu: s.headerContextMenu !== false, - checkIcon: 'fa fa-check', - arrowDownIcon: 'fa fa-chevron-down', - arrowUpIcon: 'fa fa-chevron-up', - width: s.width, - height: s.height - }, cols = gs.columns, treecol = 0; - // find which column our tree shuld go in - for (i=0;i'+styles.join("\n")+'').appendTo("head"); - } - this.tableWrapper = $("
    ").addClass("jstree-table-wrapper").insertAfter(container); - this.headerWrapper = $("
    ").addClass("jstree-table-headerwrapper").appendTo(this.tableWrapper); - this.midWrapper = $("
    ").addClass("jstree-table-midwrapper").appendTo(this.tableWrapper); - // set the wrapper width - if (s.width) { - this.tableWrapper.width(s.width); - } - if (s.height) { - this.tableWrapper.height(s.height); - } - // create the data columns - for (i=0;i").addClass("jstree-default jstree-table-column jstree-table-column-"+i+" jstree-table-column-root-"+this.rootid).appendTo(this.midWrapper); - } - this.midWrapper.children("div:eq("+treecol+")").append(container); - container.addClass("jstree-table-cell"); - - //move header with scroll - /* - if (gs.fixedHeader) { - this.tableWrapper.scroll(function() { - $(this).find('.jstree-table-header').css('top', $(this).scrollTop()); - }); - } - */ - - // copy original sort function - var defaultSort = $.proxy(this.settings.sort, this); - - // override sort function - this.settings.sort = function (a, b) { - var bigger; - - if (gs.sortOrder==='text') { - bigger = defaultSort(a, b); - } else { - var nodeA = this.get_node(a); - var nodeB = this.get_node(b); - var valueA = nodeA.data[gs.sortOrder]; - var valueB = nodeB.data[gs.sortOrder]; - if(valueA && valueB){ - if(gs.sortFn[gs.sortOrder]){ - bigger = gs.sortFn[gs.sortOrder](valueA, valueB, nodeA, nodeB); - }else{ - // Default sorting - bigger = (valueA > valueB ? 1 : -1); - } - }else{ - // undefined is second - if(valueA){ - bigger = 1; - }else if(valueB){ - bigger = -1; - }else{ - // Compare two nodes without values - bigger = defaultSort(a, b); - } - } - } - - if (gs.sortAsc===false){ - bigger = -bigger; - - } - - return bigger; - }; - - // sortable columns when jQuery UI is available - if (gs.draggable) { - if (!$.ui || !$.ui.sortable) { - console.warn('[jstree-table] draggable option requires jQuery UI'); - } else { - var from, to; - this.headerWrapper.sortable({ - axis: "x", - //handle: ".jstree-table-header-cell", - cancel: ".jstree-table-separator", - start: function (event, ui) { - ui.item.parent().children().css('display', 'inline-block'); - from = ui.item.index(); - }, - stop: function (event, ui) { - ui.item.parent().children().css('display', 'table-cell'); - to = ui.item.index(); - - if (to===from) return; - - gs.columns.splice(to, 0, gs.columns.splice(from, 1)[0]); - - var col = $('.jstree-table-midwrapper>div').eq(from); - if (to>from) { - col.insertAfter(col.parent().children("div").eq(to)); - } else if (to\ - div.jstree-table-cell-root-'+me.rootid+' {line-height: '+anchorHeight+'px; min-height: '+anchorHeight+'px;}\ - div.jstree-table-midwrapper a.jstree-clicked:before, .jstree-table-midwrapper a.jstree-hovered:before {width: ' + tableWidth + 'px;}\ - ').appendTo("head"); - } - - resize(); - - // resize column headers - this.autosize_all_columns(); - - // resize rows on zoom - $(window).on('resize', resize); - - // resize column expand - this.element.on("resize_column.jstree-table", resize); - },this)) - .on("move_node.jstree",$.proxy(function(e,data) { - var node = data.new_instance.element; - //renderAWidth(node,this); - // check all the children, because we could drag a tree over - node.find("li > a").each($.proxy(function(i,elm) { - //renderAWidth($(elm),this); - },this)); - },this)) - .on("select_node.jstree",$.proxy(function(node,selected,event){ - var id = selected.node.id; - findDataCell(this.tableWrapper,id).addClass("jstree-clicked"); - this.get_node(selected.node.id,true).children("div.jstree-table-cell").addClass("jstree-clicked"); - },this)) - .on("deselect_node.jstree",$.proxy(function(node,selected,event){ - var id = selected.node.id; - findDataCell(this.tableWrapper,id).removeClass("jstree-clicked"); - },this)) - .on("deselect_all.jstree",$.proxy(function(node,selected,event){ - // get all of the ids that were unselected - var ids = selected.node || [], i; - for (i=0;i"); - //col.appendTo(colgroup); - cl = cols[i].headerClass || ""; - ccl = cols[i].columnClass || ""; - val = cols[i].header || ""; - name = cols[i].value || "text"; - - if (val) {hasHeaders = true;} - if(gs.stateful && localStorage['jstree-root-'+rootid+'-column-'+i]) - width = localStorage['jstree-root-'+rootid+'-column-'+i]; - else - width = cols[i].width || defaultWidth; - - col = this.headerWrapper; - last = $("
    ").css(conf).addClass("jstree-table-div-"+this.uniq+"-"+i+" "+(tr?"ui-widget-header ":"")+" jstree-table-header jstree-table-header-cell jstree-table-header-"+classAdd+" "+cl+" "+ccl).html(val); - last.addClass((tr?"ui-widget-header ":"")+"jstree-table-header jstree-table-header-"+classAdd); - last.appendTo(col); - - if (name) { - last.attr(COL_DATA_ATTR, name); - } - last.hover(function () { - $(this).addClass("jstree-hovered jstree-table-header-hovered"); - }, function () { - $(this).removeClass("jstree-hovered jstree-table-header-hovered"); - }); - totalWidth += last.outerWidth(); - puller = $("
     
    ").appendTo(last); - } - - last.addClass((tr?"ui-widget-header ":"")+"jstree-table-header jstree-table-header-last jstree-table-header-"+classAdd); - // if there is no width given for the last column, do it via automatic - if (cols[cols.length-1].width === undefined) { - totalWidth -= width; - col.css({width:"auto"}); - last.addClass("jstree-table-width-auto").next(".jstree-table-separator").remove(); - } - if (hasHeaders) { - // save the offset of the div from the body - //gs.divOffset = header.parent().offset().left; - gs.header = header; - } else { - $("div.jstree-table-header").hide(); - } - - if (!this.bound && resizable) { - this.bound = true; - $(document).mouseup(function () { - var ref, cols, width, headers, currentTree, colNum; - if (isClickedSep) { - colNum = toResize.prevAll(".jstree-table-column").length; - currentTree = toResize.closest(".jstree-table-wrapper").find(".jstree"); - ref = $.jstree.reference(currentTree); - cols = ref.settings.table.columns; - headers = toResize.parent().children("div.jstree-table-column"); - if (isNaN(colNum) || colNum < 0) { ref._tableSettings.treeWidthDiff = currentTree.find("ins:eq(0)").width() + currentTree.find("a:eq(0)").width() - ref._tableSettings.columns[0].width; } - width = ref._tableSettings.columns[colNum].width = parseFloat(toResize.css("width")); - isClickedSep = false; - toResize = null; - - currentTree.trigger("resize_column.jstree-table", [colNum,width]); - } - }).mousemove(function (e) { - if (isClickedSep) { - newMouseX = e.pageX; - var diff = newMouseX - oldMouseX, - oldPrevHeaderInner, - oldPrevColWidth, newPrevColWidth; - - if (diff !== 0) { - oldPrevHeaderInner = toResize.width(); - oldPrevColWidth = parseFloat(toResize.css("width")); - - // handle a Chrome issue with columns set to auto - // thanks to Brabus https://github.com/side-by-side - if (!oldPrevColWidth) { - oldPrevColWidth = toResize.innerWidth(); - } - - // make sure that diff cannot be beyond the left/right limits - diff = diff < 0 ? Math.max(diff,-oldPrevHeaderInner) : diff; - newPrevColWidth = oldPrevColWidth+diff; - - // only do this if we are not shrinking past 0 on left - and limit it to that amount - if ((diff > 0 || oldPrevHeaderInner > 0) && newPrevColWidth > MINCOLWIDTH) { - var index = toResize.parent().children().index(toResize); - var col = $('.jstree-table-midwrapper>div').eq(index); - - toResize.width(newPrevColWidth+"px"); - toResize.css("min-width",newPrevColWidth+"px"); - toResize.css("max-width",newPrevColWidth+"px"); - - col.width(newPrevColWidth+"px"); - col.css("min-width",newPrevColWidth+"px"); - col.css("max-width",newPrevColWidth+"px"); - - oldMouseX = newMouseX; - } - } - } - }); - this.tableWrapper.on("selectstart", ".jstree-table-resizable-separator", function () { - return false; - }) - .on("mousedown", ".jstree-table-resizable-separator", function (e) { - isClickedSep = true; - oldMouseX = e.pageX; - toResize = $(this).closest("div.jstree-table-header"); - // the max rightmost position we will allow is the right-most of the wrapper minus a buffer (10) - return false; - }) - .on("dblclick", ".jstree-table-resizable-separator", function (e) { - var headerCol = $(this).closest("div.jstree-table-header"); - var index = headerCol.parent().children().index(headerCol); - var col = $('.jstree-table-midwrapper>div').eq(index); - _this.autosize_column(col); - }) - .on("click", ".jstree-table-separator", function (e) { - // don't sort after resize - e.stopPropagation(); - }); - } - - this.tableWrapper.on("click", ".jstree-table-header-cell", function (e) { - if (!_this.sort) { return; } - - // get column - var name = $(this).attr(COL_DATA_ATTR); - if (!name) { return; } - - // sort order - var arrowClass; - if (gs.sortOrder === name && gs.sortAsc === true) { - gs.sortAsc = false; - arrowClass = gs.arrowDownIcon; - } else { - gs.sortOrder = name; - gs.sortAsc = true; - arrowClass = gs.arrowUpIcon; - } - - // add sort arrow - $(this).closest('.jstree-table-wrapper').find(".jstree-table-sort-icon").remove(); - $("").addClass("jstree-table-sort-icon").appendTo($(this)).addClass(arrowClass); - - // sort by column - var rootNode = _this.get_node('#'); - _this.sort(rootNode, true); - _this.redraw_node(rootNode, true); - }); - - // header context menu - this.headerWrapper.on("contextmenu", ".jstree-table-header-cell", function(e) { - if (!gs.headerContextMenu) { return; } - e.preventDefault(); - - var options = { - "fit":{label:"Size column to fit","action": function (data) { - var headerCol = $(e.target).closest("div.jstree-table-header"); - var index = headerCol.parent().children().index(headerCol); - var col = $('.jstree-table-midwrapper>div').eq(index); - - _this.autosize_column(col); - }}, - "fitAll":{"separator_after": true,label:"Size all columns to fit","action": function (data) { - _this.autosize_all_columns(); - }} - }; - - // create menu item for every header cell - var cell, icon, value, label; - _this.midWrapper.find(".jstree-table-header-cell").each(function() { - cell = $(this); - icon = cell.is(":visible") ? gs.checkIcon : false; - value = cell.attr(COL_DATA_ATTR); - //get label without sorting arrows - label = cell.clone().children('.jstree-table-sort-icon').remove().end().text().trim(); - - options[value] = {icon:icon, column:value, label:label, _disabled: (value === 'text'), "action": function (data) { - var col = _this.midWrapper.find(".jstree-table-header-cell["+COL_DATA_ATTR+"='"+data.item.column+"']").parent(); - col.toggle(); - }}; - }); - - $.vakata.context.show(this,{ 'x' : e.pageX, 'y' : e.pageY },options); - }); - }; - - - /* - * Override redraw_node to correctly insert the table - */ - this.redraw_node = function(obj, deep, is_callback, force_render) { - // first allow the parent to redraw the node - obj = parent.redraw_node.call(this, obj, deep, is_callback, force_render); - // next prepare the table - if(obj) { - this._prepare_table(obj); - } - return obj; - }; - this.refresh = function () { - this._clean_table(); - return parent.refresh.apply(this,arguments); - }; - /* - * Override set_id to update cell attributes - */ - this.set_id = function (obj, id) { - var old; - if(obj) { - old = obj.id; - } - var result = parent.set_id.apply(this,arguments); - if(result) { - if (old !== undefined) { - var table = this.tableWrapper, oldNodes = [old], i; - // get children - if (obj && obj.children_d) { - oldNodes = oldNodes.concat(obj.children_d); - } - // update id in children - for (i=0;i", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"), - h2 = $("<"+"input />", { - "value" : t, - "class" : "jstree-rename-input", - "css" : { - "padding" : "0", - "border" : "1px solid silver", - "box-sizing" : "border-box", - "display" : "inline-block", - "height" : (this._data.core.li_height) + "px", - "lineHeight" : (this._data.core.li_height) + "px", - "width" : "150px" // will be set a bit further down - }, - "blur" : $.proxy(function () { - var v = h2.val(); - // save the value if changed - if(v === "" || v === t) { - v = t; - } else { - obj.data[col.value] = v; - this.element.trigger('update_cell.jstree-table',{node:obj, col:col.value, value:v, old:t}); - this._prepare_table(this.get_node(obj,true)); - } - h2.remove(); - element.show(); - }, this), - "keydown" : function (event) { - var key = event.which; - if(key === 27) { - this.value = t; - } - if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) { - event.stopImmediatePropagation(); - } - if(key === 27 || key === 13) { - event.preventDefault(); - this.blur(); - } - }, - "click" : function (e) { e.stopImmediatePropagation(); }, - "mousedown" : function (e) { e.stopImmediatePropagation(); }, - "keyup" : function (event) { - h2.width(Math.min(h1.text("pW" + this.value).width(),w)); - }, - "keypress" : function(event) { - if(event.which === 13) { return false; } - } - }), - fn = { - fontFamily : element.css('fontFamily') || '', - fontSize : element.css('fontSize') || '', - fontWeight : element.css('fontWeight') || '', - fontStyle : element.css('fontStyle') || '', - fontStretch : element.css('fontStretch') || '', - fontVariant : element.css('fontVariant') || '', - letterSpacing : element.css('letterSpacing') || '', - wordSpacing : element.css('wordSpacing') || '' - }; - element.hide(); - element.parent().append(h2); - h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select(); - }; - - this.autosize_column = function (col) { - // don't resize hidden columns - if (col.is(":hidden")) { return; } - - var oldPrevColWidth = parseFloat(col.css("width")), newWidth = 0, diff, - colNum = col.prevAll(".jstree-table-column").length, - oldPrevHeaderInner = col.width(), newPrevColWidth; - - //find largest width - col.find(".jstree-table-cell").each(function() { - var item = $(this), width; - item.css("position", "absolute"); - item.css("width", "auto"); - width = item.outerWidth(); - item.css("position", "static"); - - if (width>newWidth) { - newWidth = width; - } - }); - - diff = newWidth-oldPrevColWidth; - - // make sure that diff cannot be beyond the left limits - diff = diff < 0 ? Math.max(diff,-oldPrevHeaderInner) : diff; - newPrevColWidth = (oldPrevColWidth+diff)+"px"; - - col.width(newPrevColWidth); - col.css("min-width",newPrevColWidth); - col.css("max-width",newPrevColWidth); - - var index = col.parent().children().index(col); - var headerCol = $('.jstree-table-headerwrapper>div').eq(index); - headerCol.width(newPrevColWidth); - headerCol.css("min-width",newPrevColWidth); - headerCol.css("max-width",newPrevColWidth); - - $(this).closest(".jstree-table-wrapper").find(".jstree").trigger("resize_column.jstree-table",[colNum,newPrevColWidth]); - }; - - this.autosize_all_columns = function () { - this.tableWrapper.find(".jstree-table-column").each(function() { - _this.autosize_column($(this)); - }); - }; - - this._prepare_table = function (obj) { - var gs = this._tableSettings, c = gs.treeClass, _this = this, t, cols = gs.columns || [], width, tr = gs.isThemeroller, - tree = this.element, rootid = this.rootid, - classAdd = (tr?"themeroller":"regular"), img, objData = this.get_node(obj), - defaultWidth = gs.columnWidth, conf = gs.defaultConf, cellClickHandler = function (tree,node,val,col,t) { - return function(e) { - node.children(".jstree-anchor").trigger("click",e); - }; - }, cellDblClickHandler = function (tree,node,val,col,t) { - return function(e) { - node.children(".jstree-anchor").trigger("dblclick",e); - }; - }, cellRightClickHandler = function (tree,node,val,col,t) { - return function (e) { - if (gs.context) { - e.preventDefault(); - $.vakata.context.show(this,{ 'x' : e.pageX, 'y' : e.pageY },{ - "edit":{label:"Edit","action": function (data) { - var obj = t.get_node(node); - _this._edit(obj,col,e.target); - }} - }); - } - }; - }, - hoverInHandler = function (node, jsTreeInstance) { - return function() { jsTreeInstance.hover_node(node); }; - }, - hoverOutHandler = function (node, jsTreeInstance) { - return function() { jsTreeInstance.dehover_node(node); }; - }, - i, val, cl, wcl, ccl, a, last, valClass, wideValClass, span, paddingleft, title, tableCellName, tableCellParentId, tableCellParent, - tableCellPrev, tableCellPrevId, tableCellNext, tableCellNextId, tableCellChild, tableCellChildId, - col, content, tmpWidth, mw = this.midWrapper, dataCell, lid = objData.id, - peers = this.get_node(objData.parent).children, - // find my position in the list of peers. "peers" is the list of everyone at my level under my parent, in order - pos = $.inArray(lid,peers), - hc = this.holdingCells, rendered = false, closed; - // get our column definition - t = $(obj); - - // find the a children - a = t.children("a"); - - if (a.length === 1) { - closed = !objData.state.opened; - tableCellName = TABLECELLID_PREFIX+escapeId(lid)+TABLECELLID_POSTFIX; - tableCellParentId = objData.parent === "#" ? null : objData.parent; - a.addClass(c); - //renderAWidth(a,_this); - renderATitle(a,t,_this); - last = a; - // find which column our tree shuld go in - var s = this.settings.table; - var treecol = 0; - for (i=0;i' : '';} - } else { content = val; } - - // content cannot be blank, or it messes up heights - if (content === undefined || content === null || BLANKRE.test(content)) { - content = " "; - } - - // get the valueClass - valClass = col.valueClass && objData.data !== null && objData.data !== undefined ? objData.data[col.valueClass] || "" : ""; - if (valClass && col.valueClassPrefix && col.valueClassPrefix !== "") { - valClass = col.valueClassPrefix + valClass; - } - // get the wideValueClass - wideValClass = col.wideValueClass && objData.data !== null && objData.data !== undefined ? objData.data[col.wideValueClass] || "" : ""; - if (wideValClass && col.wideValueClassPrefix && col.wideValueClassPrefix !== "") { - wideValClass = col.wideValueClassPrefix + wideValClass; - } - // get the title - title = col.title && objData.data !== null && objData.data !== undefined ? objData.data[col.title] || "" : ""; - // strip out HTML - if (typeof title === 'string') { - title = title.replace(htmlstripre, ''); - } - - // get the width - paddingleft = 7; - width = col.width || defaultWidth; - if (width !== 'auto') { - width = tmpWidth || (width - paddingleft); - } - - last = findDataCell(dataCell, lid); - if (!last || last.length < 1) { - last = $("
    "); - $("").appendTo(last); - last.attr("id",tableCellName+i); - last.addClass(tableCellName); - last.attr(NODE_DATA_ATTR,lid); - - } - // we need to put it in the dataCell - after the parent, but the position matters - // if we have no parent, then we are one of the root nodes, but still need to look at peers - - - // if we are first, i.e. pos === 0, we go right after the parent; - // if we are not first, and our previous peer (one before us) is closed, we go right after the previous peer cell - // if we are not first, and our previous peer is opened, then we have to find its youngest & lowest closed child (incl. leaf) - // - // probably be much easier to go *before* our next one - // but that one might not be drawn yet - // here is the logic for jstree drawing: - // it draws peers from first to last or from last to first - // it draws children before a parent - // - // so I can rely on my *parent* not being drawn, but I cannot rely on my previous peer or my next peer being drawn - - // so we do the following: - // 1- We are the first child: install after the parent - // 2- Our previous peer is already drawn: install after the previous peer - // 3- Our previous peer is not drawn, we have a child that is drawn: install right before our first child - // 4- Our previous peer is not drawn, we have no child that is drawn, our next peer is drawn: install right before our next peer - // 5- Our previous peer is not drawn, we have no child that is drawn, our next peer is not drawn: install right after parent - tableCellPrevId = pos <=0 ? objData.parent : findLastClosedNode(this,peers[pos-1]); - tableCellPrev = findDataCell(dataCell,tableCellPrevId); - tableCellNextId = pos >= peers.length-1 ? "NULL" : peers[pos+1]; - tableCellNext = findDataCell(dataCell,tableCellNextId); - tableCellChildId = objData.children && objData.children.length > 0 ? objData.children[0] : "NULL"; - tableCellChild = findDataCell(dataCell,tableCellChildId); - tableCellParent = findDataCell(dataCell,tableCellParentId); - - // if our parent is already drawn, then we put this in the right order under our parent - if (tableCellParentId) { - if (tableCellParent && tableCellParent.length > 0) { - if (tableCellPrev && tableCellPrev.length > 0) { - last.insertAfter(tableCellPrev); - } else if (tableCellChild && tableCellChild.length > 0) { - last.insertBefore(tableCellChild); - } else if (tableCellNext && tableCellNext.length > 0) { - last.insertBefore(tableCellNext); - } else { - last.insertAfter(tableCellParent); - } - rendered = true; - } else { - rendered = false; - } - // always put it in the holding cells, and then sort when the parent comes in, in case parent is (re)drawn later - hc[tableCellName+i] = last; - } else { - if (tableCellPrev && tableCellPrev.length > 0) { - last.insertAfter(tableCellPrev); - } else if (tableCellChild && tableCellChild.length > 0) { - last.insertBefore(tableCellChild); - } else if (tableCellNext && tableCellNext.length > 0) { - last.insertBefore(tableCellNext); - } else { - last.appendTo(dataCell); - } - rendered = true; - } - // do we have any children waiting for this cell? walk down through the children/grandchildren/etc tree - if (rendered) { - last.after(this.getHoldingCells(objData,i,hc)); - } - // need to make the height of this match the line height of the tree. How? - span = last.children("span"); - - // create a span inside the div, so we can control what happens in the whole div versus inside just the text/background - span.addClass(cl+" "+valClass).html(content); - last = last.css(conf).addClass("jstree-table-cell jstree-table-cell-regular jstree-table-cell-root-"+rootid+" jstree-table-cell-"+classAdd+" "+wcl+ " " + wideValClass + (tr?" ui-state-default":"")).addClass("jstree-table-col-"+i); - // add click handler for clicking inside a table cell - last.click(cellClickHandler(tree,t,val,col,this)); - last.dblclick(cellDblClickHandler(tree,t,val,col,this)); - last.on("contextmenu",cellRightClickHandler(tree,t,val,col,this)); - last.hover(hoverInHandler(t, this), hoverOutHandler(t, this)); - - if (title) { - span.attr("title",title); - } - } - last.addClass("jstree-table-cell-last"+(tr?" ui-state-default":"")); - // if there is no width given for the last column, do it via automatic - if (cols[cols.length-1].width === undefined) { - last.addClass("jstree-table-width-auto").next(".jstree-table-separator").remove(); - } - } - this.element.css({'overflow-y':'auto !important'}); - }; - // clean up holding cells - this.holdingCells = {}; - }; -})); diff --git a/orochi/static/js/wunderbaum/wunderbaum.umd.js b/orochi/static/js/wunderbaum/wunderbaum.umd.js new file mode 100644 index 00000000..7475d319 --- /dev/null +++ b/orochi/static/js/wunderbaum/wunderbaum.umd.js @@ -0,0 +1,7881 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mar10 = {})); +})(this, (function (exports) { 'use strict'; + + /*! + * debounce & throttle, taken from https://github.com/lodash/lodash v4.17.21 + * MIT License: https://raw.githubusercontent.com/lodash/lodash/4.17.21-npm/LICENSE + * Modified for TypeScript type annotations. + */ + /* --- */ + /** Detect free variable `global` from Node.js. */ + const freeGlobal = typeof global === "object" && + global !== null && + global.Object === Object && + global; + /** Detect free variable `globalThis` */ + const freeGlobalThis = typeof globalThis === "object" && + globalThis !== null && + globalThis.Object == Object && + globalThis; + /** Detect free variable `self`. */ + const freeSelf = typeof self === "object" && self !== null && self.Object === Object && self; + /** Used as a reference to the global object. */ + const root = freeGlobalThis || freeGlobal || freeSelf || Function("return this")(); + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * isObject({}) + * // => true + * + * isObject([1, 2, 3]) + * // => true + * + * isObject(Function) + * // => true + * + * isObject(null) + * // => false + */ + function isObject(value) { + const type = typeof value; + return value != null && (type === "object" || type === "function"); + } + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked, or until the next browser frame is drawn. The debounced function + * comes with a `cancel` method to cancel delayed `func` invocations and a + * `flush` method to immediately invoke them. Provide `options` to indicate + * whether `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. The `func` is invoked with the last arguments provided to the + * debounced function. Subsequent calls to the debounced function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until the next tick, similar to `setTimeout` with a timeout of `0`. + * + * If `wait` is omitted in an environment with `requestAnimationFrame`, `func` + * invocation will be deferred until the next frame is drawn (typically about + * 16ms). + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `debounce` and `throttle`. + * + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] + * The number of milliseconds to delay; if omitted, `requestAnimationFrame` is + * used (if available). + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', debounce(calculateLayout, 150)) + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })) + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * const debounced = debounce(batchLog, 250, { 'maxWait': 1000 }) + * const source = new EventSource('/stream') + * jQuery(source).on('message', debounced) + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel) + * + * // Check for pending invocations. + * const status = debounced.pending() ? "Pending..." : "Ready" + */ + function debounce(func, wait = 0, options = {}) { + let lastArgs, lastThis, maxWait, result, timerId, lastCallTime; + let lastInvokeTime = 0; + let leading = false; + let maxing = false; + let trailing = true; + // Bypass `requestAnimationFrame` by explicitly setting `wait=0`. + const useRAF = !wait && wait !== 0 && typeof root.requestAnimationFrame === "function"; + if (typeof func !== "function") { + throw new TypeError("Expected a function"); + } + wait = +wait || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = "maxWait" in options; + maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait; + trailing = "trailing" in options ? !!options.trailing : trailing; + } + function invokeFunc(time) { + const args = lastArgs; + const thisArg = lastThis; + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + function startTimer(pendingFunc, wait) { + if (useRAF) { + root.cancelAnimationFrame(timerId); + return root.requestAnimationFrame(pendingFunc); + } + return setTimeout(pendingFunc, wait); + } + function cancelTimer(id) { + if (useRAF) { + return root.cancelAnimationFrame(id); + } + clearTimeout(id); + } + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = startTimer(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + function remainingWait(time) { + const timeSinceLastCall = time - lastCallTime; + const timeSinceLastInvoke = time - lastInvokeTime; + const timeWaiting = wait - timeSinceLastCall; + return maxing + ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + function shouldInvoke(time) { + const timeSinceLastCall = time - lastCallTime; + const timeSinceLastInvoke = time - lastInvokeTime; + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || + timeSinceLastCall >= wait || + timeSinceLastCall < 0 || + (maxing && timeSinceLastInvoke >= maxWait)); + } + function timerExpired() { + const time = Date.now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = startTimer(timerExpired, remainingWait(time)); + } + function trailingEdge(time) { + timerId = undefined; + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + function cancel() { + if (timerId !== undefined) { + cancelTimer(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + function flush() { + return timerId === undefined ? result : trailingEdge(Date.now()); + } + function pending() { + return timerId !== undefined; + } + function debounced(...args) { + const time = Date.now(); + const isInvoking = shouldInvoke(time); + lastArgs = args; + // eslint-disable-next-line @typescript-eslint/no-this-alias + lastThis = this; + lastCallTime = time; + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = startTimer(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = startTimer(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + debounced.pending = pending; + return debounced; + } + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds (or once per browser frame). The throttled function + * comes with a `cancel` method to cancel delayed `func` invocations and a + * `flush` method to immediately invoke them. Provide `options` to indicate + * whether `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until the next tick, similar to `setTimeout` with a timeout of `0`. + * + * If `wait` is omitted in an environment with `requestAnimationFrame`, `func` + * invocation will be deferred until the next frame is drawn (typically about + * 16ms). + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `throttle` and `debounce`. + * + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] + * The number of milliseconds to throttle invocations to; if omitted, + * `requestAnimationFrame` is used (if available). + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', throttle(updatePosition, 100)) + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * const throttled = throttle(renewToken, 300000, { 'trailing': false }) + * jQuery(element).on('click', throttled) + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel) + */ + function throttle(func, wait = 0, options = {}) { + let leading = true; + let trailing = true; + if (typeof func !== "function") { + throw new TypeError("Expected a function"); + } + if (isObject(options)) { + leading = "leading" in options ? !!options.leading : leading; + trailing = "trailing" in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + leading, + trailing, + maxWait: wait, + }); + } + + /*! + * Wunderbaum - util + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + /** @module util */ + /** Readable names for `MouseEvent.button` */ + const MOUSE_BUTTONS = { + 0: "", + 1: "left", + 2: "middle", + 3: "right", + 4: "back", + 5: "forward", + }; + const MAX_INT = 9007199254740991; + const userInfo = _getUserInfo(); + /**True if the client is using a macOS platform. */ + const isMac = userInfo.isMac; + const REX_HTML = /[&<>"'/]/g; // Escape those characters + const REX_TOOLTIP = /[<>"'/]/g; // Don't escape `&` in tooltips + const ENTITY_MAP = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "/": "/", + }; + /** A generic error that can be thrown to indicate a validation error when + * handling the `apply` event for a node title or the `change` event for a + * grid cell. + */ + class ValidationError extends Error { + constructor(message) { + super(message); + this.name = "ValidationError"; + } + } + /** + * A ES6 Promise, that exposes the resolve()/reject() methods. + * + * TODO: See [Promise.withResolvers()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers#description) + * , a proposed standard, but not yet implemented in any browser. + */ + let Deferred$1 = class Deferred { + constructor() { + this.thens = []; + this.catches = []; + this.status = ""; + } + resolve(value) { + if (this.status) { + throw new Error("already settled"); + } + this.status = "resolved"; + this.resolvedValue = value; + this.thens.forEach((t) => t(value)); + this.thens = []; // Avoid memleaks. + } + reject(error) { + if (this.status) { + throw new Error("already settled"); + } + this.status = "rejected"; + this.rejectedError = error; + this.catches.forEach((c) => c(error)); + this.catches = []; // Avoid memleaks. + } + then(cb) { + if (status === "resolved") { + cb(this.resolvedValue); + } + else { + this.thens.unshift(cb); + } + } + catch(cb) { + if (this.status === "rejected") { + cb(this.rejectedError); + } + else { + this.catches.unshift(cb); + } + } + promise() { + return { + then: this.then, + catch: this.catch, + }; + } + }; + /**Throw an `Error` if `cond` is falsey. */ + function assert(cond, msg) { + if (!cond) { + msg = msg || "Assertion failed."; + throw new Error(msg); + } + } + function _getUserInfo() { + const nav = navigator; + // const ua = nav.userAgentData; + const res = { + isMac: /Mac/.test(nav.platform), + }; + return res; + } + /** Run `callback` when document was loaded. */ + function documentReady(callback) { + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", callback); + } + else { + callback(); + } + } + /** Resolve when document was loaded. */ + function documentReadyPromise() { + return new Promise((resolve) => { + documentReady(resolve); + }); + } + /** + * Iterate over Object properties or array elements. + * + * @param obj `Object`, `Array` or null + * @param callback(index, item) called for every item. + * `this` also contains the item. + * Return `false` to stop the iteration. + */ + function each(obj, callback) { + if (obj == null) { + // accept `null` or `undefined` + return obj; + } + const length = obj.length; + let i = 0; + if (typeof length === "number") { + for (; i < length; i++) { + if (callback.call(obj[i], i, obj[i]) === false) { + break; + } + } + } + else { + for (const k in obj) { + if (callback.call(obj[i], k, obj[k]) === false) { + break; + } + } + } + return obj; + } + /** Shortcut for `throw new Error(msg)`.*/ + function error(msg) { + throw new Error(msg); + } + /** Convert `<`, `>`, `&`, `"`, `'`, and `/` to the equivalent entities. */ + function escapeHtml(s) { + return ("" + s).replace(REX_HTML, function (s) { + return ENTITY_MAP[s]; + }); + } + // export function escapeRegExp(s: string) { + // return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + // } + /**Convert a regular expression string by escaping special characters (e.g. `"$"` -> `"\$"`) */ + function escapeRegex(s) { + return ("" + s).replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); + } + /** Convert `<`, `>`, `"`, `'`, and `/` (but not `&`) to the equivalent entities. */ + function escapeTooltip(s) { + return ("" + s).replace(REX_TOOLTIP, function (s) { + return ENTITY_MAP[s]; + }); + } + /** TODO */ + function extractHtmlText(s) { + if (s.indexOf(">") >= 0) { + error("Not implemented"); + // return $("
    ").html(s).text(); + } + return s; + } + /** + * Read the value from an HTML input element. + * + * If a `` is passed, the first child input is used. + * Depending on the target element type, `value` is interpreted accordingly. + * For example for a checkbox, a value of true, false, or null is returned if + * the element is checked, unchecked, or indeterminate. + * For datetime input control a numerical value is assumed, etc. + * + * Common use case: store the new user input in a `change` event handler: + * + * ```ts + * change: (e) => { + * const tree = e.tree; + * const node = e.node; + * // Read the value from the input control that triggered the change event: + * let value = tree.getValueFromElem(e.element); + * // and store it to the node model (assuming the column id matches the property name) + * node.data[e.info.colId] = value; + * }, + * ``` + * @param elem `` or `` or `` handle it + node.logDebug(`Ignored ${eventName} inside focused input`); + return; + } + // const curInputType = curInput.type || curInput.tagName; + // const breakoutKeys = INPUT_KEYS[curInputType]; + // if (!breakoutKeys.includes(eventName)) { + // node.logDebug(`Ignored ${eventName} inside ${curInputType} input`); + // return; + // } + } + else if (curInput) { + // On a cell that has an embedded, unfocused + if (eventName.length === 1 && inputCanFocus) { + // Typing a single char + curInput.focus(); + curInput.value = ""; + node.logDebug(`Focus input: ${eventName}`); + return false; + } + } + if (eventName === "Tab") { + eventName = "ArrowRight"; + handled = true; + } + else if (eventName === "Shift+Tab") { + eventName = tree.activeColIdx > 0 ? "ArrowLeft" : ""; + handled = true; + } + switch (eventName) { + case "+": + case "Add": + // case "=": // 187: '+' @ Chrome, Safari + node.setExpanded(true); + break; + case "-": + case "Subtract": + node.setExpanded(false); + break; + case " ": // Space + if (tree.activeColIdx === 0 && node.getOption("checkbox")) { + node.toggleSelected(); + handled = true; + } + else if (curInput && curInputType === "checkbox") { + curInput.click(); + // toggleCheckbox(curInput) + // new Event("change") + // curInput.change + handled = true; + } + break; + case "F2": + if (curInput && !inputHasFocus && inputCanFocus) { + curInput.focus(); + handled = true; + } + break; + case "Enter": + tree.setFocus(); // Blur prev. input if any + if ((tree.activeColIdx === 0 || isColspan) && node.isExpandable()) { + node.setExpanded(!node.isExpanded()); + handled = true; + } + else if (curInput && !inputHasFocus && inputCanFocus) { + curInput.focus(); + handled = true; + } + break; + case "Escape": + tree.setFocus(); // Blur prev. input if any + node.log(`keynav: focus tree...`); + if (tree.isCellNav() && navModeOption !== NavModeEnum.cell) { + node.log(`keynav: setCellNav(false)`); + tree.setCellNav(false); // row-nav mode + tree.setFocus(); // + handled = true; + } + break; + case "ArrowLeft": + tree.setFocus(); // Blur prev. input if any + if (isColspan && node.isExpanded()) { + node.setExpanded(false); + } + else if (!isColspan && tree.activeColIdx > 0) { + tree.setColumn(tree.activeColIdx - 1); + } + else if (navModeOption !== NavModeEnum.cell) { + tree.setCellNav(false); // row-nav mode + } + handled = true; + break; + case "ArrowRight": + tree.setFocus(); // Blur prev. input if any + if (isColspan && !node.isExpanded()) { + node.setExpanded(); + } + else if (!isColspan && + tree.activeColIdx < tree.columns.length - 1) { + tree.setColumn(tree.activeColIdx + 1); + } + handled = true; + break; + case "Home": // Generated by [Fn] + ArrowLeft on Mac + // case "Meta+ArrowLeft": + tree.setFocus(); // Blur prev. input if any + if (!isColspan && tree.activeColIdx > 0) { + tree.setColumn(0); + } + handled = true; + break; + case "End": // Generated by [Fn] + ArrowRight on Mac + // case "Meta+ArrowRight": + tree.setFocus(); // Blur prev. input if any + if (!isColspan && tree.activeColIdx < tree.columns.length - 1) { + tree.setColumn(tree.columns.length - 1); + } + handled = true; + break; + case "ArrowDown": + case "ArrowUp": + case "Backspace": + case "Control+End": // Generated by Control + [Fn] + ArrowRight on Mac + case "Control+Home": // Generated by Control + [Fn] + Arrowleft on Mac + case "Meta+ArrowDown": // [⌘] + ArrowDown on Mac + case "Meta+ArrowUp": // [⌘] + ArrowUp on Mac + case "PageDown": // Generated by [Fn] + ArrowDown on Mac + case "PageUp": // Generated by [Fn] + ArrowUp on Mac + node.navigate(eventName, { activate: activate, event: event }); + // if (isCellEditMode) { + // this._getEmbeddedInputElem(null, true); // set focus to input + // } + handled = true; + break; + default: + handled = false; + } + } + if (handled) { + event.preventDefault(); + } + return; + } + } + + /*! + * Wunderbaum - ext-logger + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + class LoggerExtension extends WunderbaumExtension { + constructor(tree) { + super(tree, "logger", {}); + this.ignoreEvents = new Set([ + "iconBadge", + // "enhanceTitle", + "render", + "discard", + ]); + this.prefix = tree + ".ext-logger"; + } + init() { + const tree = this.tree; + // this.ignoreEvents.add(); + if (tree.getOption("debugLevel") >= 4) { + // const self = this; + const ignoreEvents = this.ignoreEvents; + const prefix = this.prefix; + overrideMethod(tree, "callEvent", function (name, extra) { + /* eslint-disable prefer-rest-params */ + if (ignoreEvents.has(name)) { + return tree._superApply(arguments); + } + const start = Date.now(); + const res = tree._superApply(arguments); + tree.logDebug(`${prefix}: callEvent('${name}') took ${Date.now() - start} ms.`, arguments[1]); + return res; + }); + } + } + onKeyEvent(data) { + // this.tree.logInfo("onKeyEvent", eventToString(data.event), data); + this.tree.logDebug(`${this.prefix}: onKeyEvent()`, data); + return; + } + } + + /*! + * Wunderbaum - common + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + const DEFAULT_DEBUGLEVEL = 3; // Replaced by rollup script + /** + * Fixed height of a row in pixel. Must match the SCSS variable `$row-outer-height`. + */ + const ROW_HEIGHT = 22; + /** + * Fixed width of node icons in pixel. Must match the SCSS variable `$icon-outer-width`. + */ + const ICON_WIDTH = 20; + /** + * Adjust the width of the title span, so overflow ellipsis work. + * (2 x `$col-padding-x` + 3px rounding errors). + */ + const TITLE_SPAN_PAD_Y = 7; + /** Render row markup for N nodes above and below the visible viewport. */ + const RENDER_MAX_PREFETCH = 5; + /** Regular expression to detect if a string describes an image URL (in contrast + * to a class name). Strings are considered image urls if they contain '.' or '/'. + */ + const TEST_IMG = new RegExp(/\.|\//); + // export const RECURSIVE_REQUEST_ERROR = "$recursive_request"; + // export const INVALID_REQUEST_TARGET_ERROR = "$request_target_invalid"; + /** + * Default node icons. + * Requires bootstrap icons https://icons.getbootstrap.com + */ + const iconMaps = { + bootstrap: { + error: "bi bi-exclamation-triangle", + // loading: "bi bi-hourglass-split wb-busy", + loading: "bi bi-chevron-right wb-busy", + // loading: "bi bi-arrow-repeat wb-spin", + // loading: '
    Loading...
    ', + // noData: "bi bi-search", + noData: "bi bi-question-circle", + expanderExpanded: "bi bi-chevron-down", + // expanderExpanded: "bi bi-dash-square", + expanderCollapsed: "bi bi-chevron-right", + // expanderCollapsed: "bi bi-plus-square", + expanderLazy: "bi bi-chevron-right wb-helper-lazy-expander", + // expanderLazy: "bi bi-chevron-bar-right", + checkChecked: "bi bi-check-square", + checkUnchecked: "bi bi-square", + checkUnknown: "bi bi-dash-square-dotted", + radioChecked: "bi bi-circle-fill", + radioUnchecked: "bi bi-circle", + radioUnknown: "bi bi-record-circle", + folder: "bi bi-folder2", + folderOpen: "bi bi-folder2-open", + folderLazy: "bi bi-folder-symlink", + doc: "bi bi-file-earmark", + }, + fontawesome6: { + error: "fa-solid fa-triangle-exclamation", + loading: "fa-solid fa-chevron-right fa-beat", + noData: "fa-solid fa-circle-question", + expanderExpanded: "fa-solid fa-chevron-down", + expanderCollapsed: "fa-solid fa-chevron-right", + expanderLazy: "fa-solid fa-chevron-right wb-helper-lazy-expander", + checkChecked: "fa-regular fa-square-check", + checkUnchecked: "fa-regular fa-square", + checkUnknown: "fa-regular fa-square-minus", + radioChecked: "fa-solid fa-circle", + radioUnchecked: "fa-regular fa-circle", + radioUnknown: "fa-regular fa-circle-question", + folder: "fa-solid fa-folder-closed", + folderOpen: "fa-regular fa-folder-open", + folderLazy: "fa-solid fa-folder-plus", + doc: "fa-regular fa-file", + }, + }; + /** Dict keys that are evaluated by source loader (others are added to `tree.data` instead). */ + const RESERVED_TREE_SOURCE_KEYS = new Set([ + "_format", + "_keyMap", + "_positional", + "_typeList", + "_valueMap", + "_version", + "children", + "columns", + "types", + ]); + // /** Key codes that trigger grid navigation, even when inside an input element. */ + // export const INPUT_BREAKOUT_KEYS: Set = new Set([ + // // "ArrowDown", + // // "ArrowUp", + // "Enter", + // "Escape", + // ]); + /** Map `KeyEvent.key` to navigation action. */ + const KEY_TO_ACTION_DICT = { + " ": "toggleSelect", + "+": "expand", + Add: "expand", + ArrowDown: "down", + ArrowLeft: "left", + ArrowRight: "right", + ArrowUp: "up", + Backspace: "parent", + "/": "collapseAll", + Divide: "collapseAll", + End: "lastCol", + Home: "firstCol", + "Control+End": "last", + "Control+Home": "first", + "Meta+ArrowDown": "last", + "Meta+ArrowUp": "first", + "*": "expandAll", + Multiply: "expandAll", + PageDown: "pageDown", + PageUp: "pageUp", + "-": "collapse", + Subtract: "collapse", + }; + /** Return a callback that returns true if the node title matches the string + * or regular expression. + * @see {@link WunderbaumNode.findAll()} + */ + function makeNodeTitleMatcher(match) { + if (match instanceof RegExp) { + return function (node) { + return match.test(node.title); + }; + } + assert(typeof match === "string", `Expected a string or RegExp: ${match}`); + // s = escapeRegex(s.toLowerCase()); + return function (node) { + return node.title === match; + // console.log("match " + node, node.title.toLowerCase().indexOf(match)) + // return node.title.toLowerCase().indexOf(match) >= 0; + }; + } + /** Return a callback that returns true if the node title starts with a string (case-insensitive). */ + function makeNodeTitleStartMatcher(s) { + s = escapeRegex(s); + const reMatch = new RegExp("^" + s, "i"); + return function (node) { + return reMatch.test(node.title); + }; + } + /** Compare two nodes by title (case-insensitive). */ + function nodeTitleSorter(a, b) { + const x = a.title.toLowerCase(); + const y = b.title.toLowerCase(); + return x === y ? 0 : x > y ? 1 : -1; + } + /** + * Convert 'flat' to 'nested' format. + * + * Flat node entry format: + * [PARENT_ID, [POSITIONAL_ARGS]] + * or + * [PARENT_ID, [POSITIONAL_ARGS], {KEY_VALUE_ARGS}] + * + * 1. Parent-referencing list is converted to a list of nested dicts with + * optional `children` properties. + * 2. `[POSITIONAL_ARGS]` are added as dict attributes. + */ + function unflattenSource(source) { + var _a, _b, _c; + const { _format, _keyMap = {}, _positional = [], children } = source; + if (_format !== "flat") { + throw new Error(`Expected source._format: "flat", but got ${_format}`); + } + if (_positional && _positional.includes("children")) { + throw new Error(`source._positional must not include "children": ${_positional}`); + } + let longToShort = _keyMap; + if (_keyMap.t) { + // Inverse keyMap was used (pre 0.7.0) + // TODO: raise Error on final 1.x release + const msg = `source._keyMap maps from long to short since v0.7.0. Flip key/value!`; + console.warn(msg); // eslint-disable-line no-console + longToShort = {}; + for (const [key, value] of Object.entries(_keyMap)) { + longToShort[value] = key; + } + } + const positionalShort = _positional.map((e) => longToShort[e]); + const newChildren = []; + const keyToNodeMap = {}; + const indexToNodeMap = {}; + const keyAttrName = (_a = longToShort["key"]) !== null && _a !== void 0 ? _a : "key"; + const childrenAttrName = (_b = longToShort["children"]) !== null && _b !== void 0 ? _b : "children"; + for (const [index, nodeTuple] of children.entries()) { + // Node entry format: + // [PARENT_ID, [POSITIONAL_ARGS]] + // or + // [PARENT_ID, [POSITIONAL_ARGS], {KEY_VALUE_ARGS}] + const [parentId, args, kwargs = {}] = nodeTuple; + // Free up some memory as we go + nodeTuple[1] = null; + if (nodeTuple[2] != null) { + nodeTuple[2] = null; + } + // console.log("flatten", parentId, args, kwargs) + // We keep `kwargs` as our new node definition. Then we add all positional + // values to this object: + args.forEach((val, positionalIdx) => { + kwargs[positionalShort[positionalIdx]] = val; + }); + // Find the parent node. `null` means 'toplevel'. PARENT_ID may be the numeric + // index of the source.children list. If PARENT_ID is a string, we search + // a parent with node.key of this value. + indexToNodeMap[index] = kwargs; + const key = kwargs[keyAttrName]; + if (key != null) { + keyToNodeMap[key] = kwargs; + } + let parentNode = null; + if (parentId === null) ; + else if (typeof parentId === "number") { + parentNode = indexToNodeMap[parentId]; + if (parentNode === undefined) { + throw new Error(`unflattenSource: Could not find parent node by index: ${parentId}.`); + } + } + else { + parentNode = keyToNodeMap[parentId]; + if (parentNode === undefined) { + throw new Error(`unflattenSource: Could not find parent node by key: ${parentId}`); + } + } + if (parentNode) { + (_c = parentNode[childrenAttrName]) !== null && _c !== void 0 ? _c : (parentNode[childrenAttrName] = []); + parentNode[childrenAttrName].push(kwargs); + } + else { + newChildren.push(kwargs); + } + } + source.children = newChildren; + } + /** + * Decompresses the source data by + * - converting from 'flat' to 'nested' format + * - expanding short alias names to long names (if defined in _keyMap) + * - resolving value indexes to value strings (if defined in _valueMap) + * + * @param source - The source object to be decompressed. + * @returns void + */ + function decompressSourceData(source) { + let { _format, _version = 1, _keyMap, _valueMap } = source; + assert(_version === 1, `Expected file version 1 instead of ${_version}`); + let longToShort = _keyMap; + let shortToLong = {}; + if (longToShort) { + for (const [key, value] of Object.entries(longToShort)) { + shortToLong[value] = key; + } + } + // Fallback for old format (pre 0.7.0, using _keyMap in reverse direction) + // TODO: raise Error on final 1.x release + if (longToShort && longToShort.t) { + const msg = `source._keyMap maps from long to short since v0.7.0. Flip key/value!`; + console.warn(msg); // eslint-disable-line no-console + [longToShort, shortToLong] = [shortToLong, longToShort]; + } + // Fallback for old format (pre 0.7.0, using _typeList instead of _valueMap) + // TODO: raise Error on final 1.x release + if (source._typeList != null) { + const msg = `source._typeList is deprecated since v0.7.0: use source._valueMap: {"type": [...]} instead.`; + if (_valueMap != null) { + throw new Error(msg); + } + else { + console.warn(msg); // eslint-disable-line no-console + _valueMap = { type: source._typeList }; + delete source._typeList; + } + } + if (_format === "flat") { + unflattenSource(source); + } + delete source._format; + delete source._version; + delete source._keyMap; + delete source._valueMap; + delete source._positional; + function _iter(childList) { + for (const node of childList) { + // Iterate over a list of names, because we modify inside the loop + // (for ... of ... does not allow this) + Object.getOwnPropertyNames(node).forEach((propName) => { + const value = node[propName]; + // Replace short names with long names if defined in _keyMap + let longName = propName; + if (_keyMap && shortToLong[propName] != null) { + longName = shortToLong[propName]; + if (longName !== propName) { + node[longName] = value; + delete node[propName]; + } + } + // Replace type index with type name if defined in _valueMap + if (_valueMap && + typeof value === "number" && + _valueMap[longName] != null) { + const newValue = _valueMap[longName][value]; + if (newValue == null) { + throw new Error(`Expected valueMap[${longName}][${value}] entry in [${_valueMap[longName]}]`); + } + node[longName] = newValue; + } + }); + // Recursion + if (node.children) { + _iter(node.children); + } + } + } + if (_keyMap || _valueMap) { + _iter(source.children); + } + } + + /*! + * Wunderbaum - ext-dnd + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + const nodeMimeType = "application/x-wunderbaum-node"; + class DndExtension extends WunderbaumExtension { + constructor(tree) { + super(tree, "dnd", { + autoExpandMS: 1500, + // dropMarkerInsertOffsetX: -16, // Additional offset for drop-marker with hitMode = "before"/"after" + // dropMarkerOffsetX: -24, // Absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop) + // #1021 `document.body` is not available yet + // dropMarkerParent: "body", // Root Container used for drop marker (could be a shadow root) + multiSource: false, + effectAllowed: "all", + dropEffectDefault: "move", + guessDropEffect: true, + preventForeignNodes: false, + preventLazyParents: true, + preventNonNodes: false, + preventRecursion: true, + preventSameParent: false, + preventVoidMoves: true, + serializeClipboardData: true, + scroll: true, + scrollSensitivity: 20, + // scrollnterval: 50, // Generate event every 50 ms + scrollSpeed: 5, + // setTextTypeJson: false, // Allow dragging of nodes to different IE windows + sourceCopyHook: null, + // Events (drag support) + dragStart: null, + drag: null, + dragEnd: null, + // Events (drop support) + dragEnter: null, + dragOver: null, + dragExpand: null, + drop: null, + dragLeave: null, // Callback(targetNode, data) + }); + // public dropMarkerElem?: HTMLElement; + this.srcNode = null; + this.lastTargetNode = null; + this.lastEnterStamp = 0; + this.lastAllowedDropRegions = null; + this.lastDropEffect = null; + this.lastDropRegion = false; + this.currentScrollDir = 0; + this.applyScrollDirThrottled = throttle(this._applyScrollDir, 50); + } + init() { + super.init(); + // Store the current scroll parent, which may be the tree + // container, any enclosing div, or the document. + // #761: scrollParent() always needs a container child + // $temp = $("").appendTo(this.$container); + // this.$scrollParent = $temp.scrollParent(); + // $temp.remove(); + const tree = this.tree; + const dndOpts = tree.options.dnd; + // Enable drag support if dragStart() is specified: + if (dndOpts.dragStart) { + onEvent(tree.element, "dragstart drag dragend", this.onDragEvent.bind(this)); + } + // Enable drop support if dragEnter() is specified: + if (dndOpts.dragEnter) { + onEvent(tree.element, "dragenter dragover dragleave drop", this.onDropEvent.bind(this)); + } + } + /** Cleanup classes after target node is no longer hovered. */ + _leaveNode() { + // We remove the marker on dragenter from the previous target: + const ltn = this.lastTargetNode; + this.lastEnterStamp = 0; + if (ltn) { + ltn.setClass("wb-drop-target wb-drop-over wb-drop-after wb-drop-before", false); + this.lastTargetNode = null; + } + } + /** */ + unifyDragover(res) { + if (res === false) { + return false; + } + else if (res instanceof Set) { + return res.size > 0 ? res : false; + } + else if (res === true) { + return new Set(["over", "before", "after"]); + } + else if (typeof res === "string" || isArray(res)) { + res = toSet(res); + return res.size > 0 ? res : false; + } + throw new Error("Unsupported drop region definition: " + res); + } + /** + * Calculates the drop region based on the drag event and the allowed drop regions. + */ + _calcDropRegion(e, allowed) { + const dy = e.offsetY; + if (!allowed) { + return false; + } + else if (allowed.size === 3) { + return dy < 0.25 * ROW_HEIGHT + ? "before" + : dy > 0.75 * ROW_HEIGHT + ? "after" + : "over"; + } + else if (allowed.size === 1 && allowed.has("over")) { + return "over"; + } + else { + // Only 'before' and 'after': + return dy > ROW_HEIGHT / 2 ? "after" : "before"; + } + // return "over"; + } + /** + * Guess drop effect (copy/link/move) using opinionated conventions. + * + * Default: dnd.dropEffectDefault + */ + _guessDropEffect(e) { + // const nativeDropEffect = e.dataTransfer?.dropEffect; + var _a; + // if (nativeDropEffect && nativeDropEffect !== "none") { + // return nativeDropEffect; + // } + const dndOpts = this.treeOpts.dnd; + const ea = (_a = dndOpts.effectAllowed) !== null && _a !== void 0 ? _a : "all"; + const canCopy = ["all", "copy", "copyLink", "copyMove"].includes(ea); + const canLink = ["all", "link", "copyLink", "linkMove"].includes(ea); + const canMove = ["all", "move", "copyMove", "linkMove"].includes(ea); + let res = dndOpts.dropEffectDefault; + if (dndOpts.guessDropEffect) { + if (isMac) { + if (e.altKey && canCopy) { + res = "copy"; + } + if (e.metaKey && canMove) { + res = "move"; // command key + } + if (e.altKey && e.metaKey && canLink) { + res = "link"; + } + } + else { + if (e.ctrlKey && canCopy) { + res = "copy"; + } + if (e.shiftKey && canMove) { + res = "move"; + } + if (e.altKey && canLink) { + res = "link"; + } + } + } + return res; + } + /** Don't allow void operation ('drop on self').*/ + _isVoidDrop(targetNode, srcNode, dropRegion) { + // this.tree.logDebug( + // `_isVoidDrop: ${srcNode} -> ${dropRegion} ${targetNode}` + // ); + // TODO: should be checked on move only + if (!this.treeOpts.dnd.preventVoidMoves || !srcNode) { + return false; + } + if ((dropRegion === "before" && targetNode === srcNode.getNextSibling()) || + (dropRegion === "after" && targetNode === srcNode.getPrevSibling())) { + // this.tree.logDebug("Prevented before/after self"); + return true; + } + // Don't allow dropping nodes on own parent (or self) + return srcNode === targetNode || srcNode.parent === targetNode; + } + /* Implement auto scrolling when drag cursor is in top/bottom area of scroll parent. */ + _applyScrollDir() { + if (this.isDragging() && this.currentScrollDir) { + const dndOpts = this.tree.options.dnd; + const sp = this.tree.element; // scroll parent + const scrollTop = sp.scrollTop; + if (this.currentScrollDir < 0) { + sp.scrollTop = Math.max(0, scrollTop - dndOpts.scrollSpeed); + } + else if (this.currentScrollDir > 0) { + sp.scrollTop = scrollTop + dndOpts.scrollSpeed; + } + } + } + /* Implement auto scrolling when drag cursor is in top/bottom area of scroll parent. */ + _autoScroll(viewportY) { + const tree = this.tree; + const dndOpts = tree.options.dnd; + const sensitivity = dndOpts.scrollSensitivity; + const sp = tree.element; // scroll parent + const headerHeight = tree.headerElement.clientHeight; // May be 0 + // const height = sp.clientHeight - headerHeight; + // const height = sp.offsetHeight + headerHeight; + const height = sp.offsetHeight; + const scrollTop = sp.scrollTop; + // tree.logDebug( + // `autoScroll: height=${height}, scrollTop=${scrollTop}, viewportY=${viewportY}` + // ); + this.currentScrollDir = 0; + if (scrollTop > 0 && + viewportY > 0 && + viewportY <= sensitivity + headerHeight) { + // Mouse in top 20px area: scroll up + // sp.scrollTop = Math.max(0, scrollTop - dndOpts.scrollSpeed); + this.currentScrollDir = -1; + } + else if (scrollTop < sp.scrollHeight - height && + viewportY >= height - sensitivity) { + // Mouse in bottom 20px area: scroll down + // sp.scrollTop = scrollTop + dndOpts.scrollSpeed; + this.currentScrollDir = +1; + } + if (this.currentScrollDir) { + this.applyScrollDirThrottled(); + } + return sp.scrollTop - scrollTop; + } + /** Return true if a drag operation currently in progress. */ + isDragging() { + return !!this.srcNode; + } + /** + * Handle dragstart, drag and dragend events for the source node. + */ + onDragEvent(e) { + var _a; + // const tree = this.tree; + const dndOpts = this.treeOpts.dnd; + const srcNode = Wunderbaum.getNode(e); + if (!srcNode) { + this.tree.logWarn(`onDragEvent.${e.type}: no node`); + return; + } + if (["dragstart", "dragend"].includes(e.type)) { + this.tree.logDebug(`onDragEvent.${e.type} srcNode: ${srcNode}`, e); + } + // --- dragstart --- + if (e.type === "dragstart") { + // Set a default definition of allowed effects + e.dataTransfer.effectAllowed = dndOpts.effectAllowed; //"copyMove"; // "all"; + if (srcNode.isEditingTitle()) { + srcNode.logDebug("Prevented dragging node in edit mode."); + e.preventDefault(); + return false; + } + // Let user cancel the drag operation, override effectAllowed, etc.: + const res = srcNode._callEvent("dnd.dragStart", { event: e }); + if (!res) { + e.preventDefault(); + return false; + } + const nodeData = srcNode.toDict(true, (n) => { + // We don't want to re-use the key on drop: + n._orgKey = n.key; + delete n.key; + }); + nodeData._treeId = srcNode.tree.id; + if (dndOpts.serializeClipboardData) { + if (typeof dndOpts.serializeClipboardData === "function") { + e.dataTransfer.setData(nodeMimeType, dndOpts.serializeClipboardData(nodeData, srcNode)); + } + else { + e.dataTransfer.setData(nodeMimeType, JSON.stringify(nodeData)); + } + } + // e.dataTransfer!.setData("text/html", $(node.span).html()); + if (!((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.types.includes("text/plain"))) { + e.dataTransfer.setData("text/plain", srcNode.title); + } + this.srcNode = srcNode; + setTimeout(() => { + // Decouple this call, so the CSS is applied to the node, but not to + // the system generated drag image + srcNode.setClass("wb-drag-source"); + }, 0); + // --- drag --- + } + else if (e.type === "drag") { + if (dndOpts.drag) { + srcNode._callEvent("dnd.drag", { event: e }); + } + // --- dragend --- + } + else if (e.type === "dragend") { + srcNode.setClass("wb-drag-source", false); + this.srcNode = null; + if (this.lastTargetNode) { + this._leaveNode(); + } + srcNode._callEvent("dnd.dragEnd", { event: e }); + } + return true; + } + /** + * Handle dragenter, dragover, dragleave, drop events. + */ + onDropEvent(e) { + var _a; + // const isLink = event.dataTransfer.types.includes("text/uri-list"); + const srcNode = this.srcNode; + const srcTree = srcNode ? srcNode.tree : null; + const targetNode = Wunderbaum.getNode(e); + const dndOpts = this.treeOpts.dnd; + const dt = e.dataTransfer; + const dropRegion = this._calcDropRegion(e, this.lastAllowedDropRegions); + /** Helper to log a message if predicate is false. */ + const _t = (pred, msg) => { + if (pred) { + this.tree.log(`Prevented drop operation (${msg}).`); + } + return pred; + }; + if (!targetNode) { + this._leaveNode(); + return; + } + if (["drop"].includes(e.type)) { + this.tree.logDebug(`onDropEvent.${e.type} targetNode: ${targetNode}, ea: ${dt === null || dt === void 0 ? void 0 : dt.effectAllowed}, ` + + `de: ${dt === null || dt === void 0 ? void 0 : dt.dropEffect}, cy: ${e.offsetY}, r: ${dropRegion}, srcNode: ${srcNode}`, e); + } + // --- dragenter --- + if (e.type === "dragenter") { + // this.tree.logWarn(` onDropEvent.${e.type} targetNode: ${targetNode}`, e); + this.lastAllowedDropRegions = null; + // `dragleave` is not reliable with event delegation, so we generate it + // from dragenter: + if (this.lastTargetNode && this.lastTargetNode !== targetNode) { + this._leaveNode(); + } + this.lastTargetNode = targetNode; + this.lastEnterStamp = Date.now(); + if ( + // Don't drop on status node: + _t(targetNode.isStatusNode(), "is status node") || + // Prevent dropping nodes from different Wunderbaum trees: + _t(dndOpts.preventForeignNodes && targetNode.tree !== srcTree, "preventForeignNodes") || + // Prevent dropping items on unloaded lazy Wunderbaum tree nodes: + _t(dndOpts.preventLazyParents && !targetNode.isLoaded(), "preventLazyParents") || + // Prevent dropping items other than Wunderbaum tree nodes: + _t(dndOpts.preventNonNodes && !srcNode, "preventNonNodes") || + // Prevent dropping nodes on own descendants: + _t(dndOpts.preventRecursion && (srcNode === null || srcNode === void 0 ? void 0 : srcNode.isAncestorOf(targetNode)), "preventRecursion") || + // Prevent dropping nodes under same direct parent: + _t(dndOpts.preventSameParent && + srcNode && + targetNode.parent === srcNode.parent, "preventSameParent") || + // Don't allow void operation ('drop on self'): TODO: should be checked on move only + _t(dndOpts.preventVoidMoves && targetNode === srcNode, "preventVoidMoves")) { + dt.dropEffect = "none"; + // this.tree.log("Prevented drop operation"); + return true; // Prevent drop operation + } + // User may return a set of regions (or `false` to prevent drop) + // Figure out a drop effect (copy/link/move) using opinated conventions. + dt.dropEffect = this._guessDropEffect(e) || "none"; + let regionSet = targetNode._callEvent("dnd.dragEnter", { + event: e, + sourceNode: srcNode, + }); + // + regionSet = this.unifyDragover(regionSet); + if (!regionSet) { + dt.dropEffect = "none"; + return true; // Prevent drop operation + } + this.lastAllowedDropRegions = regionSet; + this.lastDropEffect = dt.dropEffect; + targetNode.setClass("wb-drop-target"); + e.preventDefault(); // Allow drop (Drop operation is denied by default) + return false; + // --- dragover --- + } + else if (e.type === "dragover") { + const viewportY = e.clientY - this.tree.element.offsetTop; + this._autoScroll(viewportY); + dt.dropEffect = this._guessDropEffect(e) || "none"; + targetNode._callEvent("dnd.dragOver", { event: e, sourceNode: srcNode }); + const region = this._calcDropRegion(e, this.lastAllowedDropRegions); + this.lastDropRegion = region; + this.lastDropEffect = dt.dropEffect; + if (dndOpts.autoExpandMS > 0 && + targetNode.isExpandable(true) && + !targetNode._isLoading && + Date.now() - this.lastEnterStamp > dndOpts.autoExpandMS && + targetNode._callEvent("dnd.dragExpand", { + event: e, + sourceNode: srcNode, + }) !== false) { + targetNode.setExpanded(); + } + if (!region || this._isVoidDrop(targetNode, srcNode, region)) { + return; // We already rejected in dragenter + } + targetNode.setClass("wb-drop-over", region === "over"); + targetNode.setClass("wb-drop-before", region === "before"); + targetNode.setClass("wb-drop-after", region === "after"); + e.preventDefault(); // Allow drop (Drop operation is denied by default) + return false; + // --- dragleave --- + } + else if (e.type === "dragleave") { + // NOTE: we cannot trust this event, since it is always fired, + // Instead we remove the marker on dragenter + targetNode._callEvent("dnd.dragLeave", { event: e, sourceNode: srcNode }); + // --- drop --- + } + else if (e.type === "drop") { + e.stopPropagation(); // prevent browser from opening links? + e.preventDefault(); // #69 prevent iOS browser from opening links + this._leaveNode(); + const region = this.lastDropRegion; + let nodeData = (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData(nodeMimeType); + nodeData = nodeData ? JSON.parse(nodeData) : null; + const srcNode = this.srcNode; + const lastDropEffect = this.lastDropEffect; + setTimeout(() => { + // Decouple this call, because drop actions may prevent the dragend event + // from being fired on some browsers + targetNode._callEvent("dnd.drop", { + event: e, + region: region, + suggestedDropMode: region === "over" ? "appendChild" : region, + suggestedDropEffect: lastDropEffect, + // suggestedDropEffect: e.dataTransfer?.dropEffect, + sourceNode: srcNode, + sourceNodeData: nodeData, + }); + }, 10); + } + return false; + } + } + + /*! + * Wunderbaum - drag_observer + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + /** + * Convert mouse- and touch events to 'dragstart', 'drag', and 'dragstop'. + */ + class DragObserver { + constructor(opts) { + this.start = { + x: 0, + y: 0, + altKey: false, + ctrlKey: false, + metaKey: false, + shiftKey: false, + }; + this.dragElem = null; + this.dragging = false; + // TODO: touch events + this.events = ["mousedown", "mouseup", "mousemove", "keydown"]; + if (!opts.root) { + throw new Error("Missing `root` option."); + } + this.opts = Object.assign({ thresh: 5 }, opts); + this.root = opts.root; + this._handler = this.handleEvent.bind(this); + this.events.forEach((type) => { + this.root.addEventListener(type, this._handler); + }); + } + /** Unregister all event listeners. */ + disconnect() { + this.events.forEach((type) => { + this.root.removeEventListener(type, this._handler); + }); + } + getDragElem() { + return this.dragElem; + } + isDragging() { + return this.dragging; + } + stopDrag(cb_event) { + if (this.dragging && this.opts.dragstop && cb_event) { + cb_event.type = "dragstop"; + this.opts.dragstop(cb_event); + } + this.dragElem = null; + this.dragging = false; + } + handleEvent(e) { + const type = e.type; + const opts = this.opts; + const cb_event = { + type: e.type, + event: e, + dragElem: this.dragElem, + dx: e.pageX - this.start.x, + dy: e.pageY - this.start.y, + apply: undefined, + }; + switch (type) { + case "keydown": + this.stopDrag(cb_event); + break; + case "mousedown": + if (this.dragElem) { + this.stopDrag(cb_event); + break; + } + if (opts.selector) { + let elem = e.target; + if (elem.matches(opts.selector)) { + this.dragElem = elem; + } + else { + elem = elem.closest(opts.selector); + if (elem) { + this.dragElem = elem; + } + else { + break; // no event delegation selector matched + } + } + } + this.start.x = e.pageX; + this.start.y = e.pageY; + this.start.altKey = e.altKey; + this.start.ctrlKey = e.ctrlKey; + this.start.metaKey = e.metaKey; + this.start.shiftKey = e.shiftKey; + break; + case "mousemove": + // TODO: debounce/throttle? + // TODO: horizontal mode: ignore if dx unchanged + if (!this.dragElem) { + break; + } + if (!this.dragging) { + if (opts.thresh) { + const dist2 = cb_event.dx * cb_event.dx + cb_event.dy * cb_event.dy; + if (dist2 < opts.thresh * opts.thresh) { + break; + } + } + cb_event.type = "dragstart"; + if (opts.dragstart(cb_event) === false) { + this.stopDrag(cb_event); + break; + } + this.dragging = true; + } + if (this.dragging && this.opts.drag) { + cb_event.type = "drag"; + this.opts.drag(cb_event); + } + break; + case "mouseup": + if (!this.dragging) { + this.stopDrag(cb_event); + break; + } + if (e.button === 0) { + cb_event.apply = true; + } + else { + cb_event.apply = false; + } + this.stopDrag(cb_event); + break; + } + } + } + + /*! + * Wunderbaum - ext-grid + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + class GridExtension extends WunderbaumExtension { + constructor(tree) { + super(tree, "grid", { + // throttle: 200, + }); + this.observer = new DragObserver({ + root: window.document, + selector: "span.wb-col-resizer", + thresh: 4, + // throttle: 400, + dragstart: (e) => { + return this.tree.element.contains(e.dragElem); + }, + drag: (e) => { + // TODO: throttle + return this.handleDrag(e); + }, + dragstop: (e) => { + return this.handleDrag(e); + }, + }); + } + init() { + super.init(); + } + handleDrag(e) { + const info = Wunderbaum.getEventInfo(e.event); + // this.tree.options. + this.tree.log(`${e.type}(${e.dx})`, e, info); + } + } + + /*! + * Wunderbaum - deferred + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + /** + * Implement a ES6 Promise, that exposes a resolve() and reject() method. + * + * Loosely mimics {@link https://api.jquery.com/category/deferred-object/ | jQuery.Deferred}. + * Example: + * ```js + * function foo() { + * let dfd = new Deferred(), + * ... + * dfd.resolve('foo') + * ... + * return dfd.promise(); + * } + * ``` + */ + class Deferred { + constructor() { + this._promise = new Promise((resolve, reject) => { + this._resolve = resolve; + this._reject = reject; + }); + } + /** Resolve the Promise. */ + resolve(value) { + this._resolve(value); + } + /** Reject the Promise. */ + reject(reason) { + this._reject(reason); + } + /** Return the native Promise instance.*/ + promise() { + return this._promise; + } + /** Call Promise.then on the embedded promise instance.*/ + then(cb) { + return this._promise.then(cb); + } + /** Call Promise.catch on the embedded promise instance.*/ + catch(cb) { + return this._promise.catch(cb); + } + /** Call Promise.finally on the embedded promise instance.*/ + finally(cb) { + return this._promise.finally(cb); + } + } + + /*! + * Wunderbaum - wunderbaum_node + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + /** WunderbaumNode properties that can be passed with source data. + * (Any other source properties will be stored as `node.data.PROP`.) + */ + const NODE_PROPS = new Set([ + "checkbox", + "classes", + "expanded", + "icon", + "iconTooltip", + "key", + "lazy", + "_partsel", + "radiogroup", + "refKey", + "selected", + "statusNodeType", + "title", + "tooltip", + "type", + "unselectable", + ]); + /** WunderbaumNode properties that will be returned by `node.toDict()`.) + */ + const NODE_DICT_PROPS = new Set(NODE_PROPS); + NODE_DICT_PROPS.delete("_partsel"); + NODE_DICT_PROPS.delete("unselectable"); + /** + * A single tree node. + * + * **NOTE:**
    + * Generally you should not modify properties directly, since this may break + * the internal bookkeeping. + */ + class WunderbaumNode { + constructor(tree, parent, data) { + var _a, _b; + /** Reference key. Unlike {@link key}, a `refKey` may occur multiple + * times within a tree (in this case we have 'clone nodes'). + * @see Use {@link setKey} to modify. + */ + this.refKey = undefined; + this.children = null; + /** Additional classes added to `div.wb-row`. + * @see {@link hasClass}, {@link setClass}. */ + this.classes = null; //new Set(); + /** Custom data that was passed to the constructor */ + this.data = {}; + this._isLoading = false; + this._requestId = 0; + this._errorInfo = null; + this._partsel = false; + this._partload = false; + this.subMatchCount = 0; + this._rowIdx = 0; + this._rowElem = undefined; + assert(!parent || parent.tree === tree, `Invalid parent: ${parent}`); + assert(!data.children, "'children' not allowed here"); + this.tree = tree; + this.parent = parent; + this.key = "" + ((_a = data.key) !== null && _a !== void 0 ? _a : ++WunderbaumNode.sequence); + this.title = "" + ((_b = data.title) !== null && _b !== void 0 ? _b : "<" + this.key + ">"); + data.refKey != null ? (this.refKey = "" + data.refKey) : 0; + data.type != null ? (this.type = "" + data.type) : 0; + this.expanded = data.expanded === true; + data.icon != null ? (this.icon = data.icon) : 0; + this.lazy = data.lazy === true; + data.statusNodeType != null + ? (this.statusNodeType = ("" + data.statusNodeType)) + : 0; + data.colspan != null ? (this.colspan = !!data.colspan) : 0; + // Selection + data.checkbox != null ? (this.checkbox = !!data.checkbox) : 0; + data.radiogroup != null ? (this.radiogroup = !!data.radiogroup) : 0; + this.selected = data.selected === true; + data.unselectable === true ? (this.unselectable = true) : 0; + if (data.classes) { + this.setClass(data.classes); + } + // Store custom fields as `node.data` + for (const [key, value] of Object.entries(data)) { + if (!NODE_PROPS.has(key)) { + this.data[key] = value; + } + } + if (parent && !this.statusNodeType) { + // Don't register root node or status nodes + tree._registerNode(this); + } + } + /** + * Return readable string representation for this instance. + * @internal + */ + toString() { + return `WunderbaumNode@${this.key}<'${this.title}'>`; + } + /** + * Iterate all descendant nodes depth-first, pre-order using `for ... of ...` syntax. + * More concise, but slightly slower than {@link WunderbaumNode.visit}. + * + * Example: + * ```js + * for(const n of node) { + * ... + * } + * ``` + */ + *[Symbol.iterator]() { + // let node: WunderbaumNode | null = this; + const cl = this.children; + if (cl) { + for (let i = 0, l = cl.length; i < l; i++) { + const n = cl[i]; + yield n; + if (n.children) { + yield* n; + } + } + // Slower: + // for (let node of this.children) { + // yield node; + // yield* node : 0; + // } + } + } + // /** Return an option value. */ + // protected _getOpt( + // name: string, + // nodeObject: any = null, + // treeOptions: any = null, + // defaultValue: any = null + // ): any { + // return evalOption( + // name, + // this, + // nodeObject || this, + // treeOptions || this.tree.options, + // defaultValue + // ); + // } + /** Call event handler if defined in tree.options. + * Example: + * ```js + * node._callEvent("edit.beforeEdit", {foo: 42}) + * ``` + */ + _callEvent(type, extra) { + return this.tree._callEvent(type, extend({ + node: this, + typeInfo: this.type ? this.tree.types[this.type] : {}, + }, extra)); + } + /** + * Append (or insert) a list of child nodes. + * + * Tip: pass `{ before: 0 }` to prepend new nodes as first children. + * + * @returns first child added + */ + addChildren(nodeData, options) { + const tree = this.tree; + let { before = null, applyMinExpanLevel = true, _level } = options !== null && options !== void 0 ? options : {}; + // let { before, loadLazy=true, _level } = options ?? {}; + // const isTopCall = _level == null; + _level !== null && _level !== void 0 ? _level : (_level = this.getLevel()); + const nodeList = []; + try { + tree.enableUpdate(false); + if (isPlainObject(nodeData)) { + nodeData = [nodeData]; + } + const forceExpand = applyMinExpanLevel && _level < tree.options.minExpandLevel; + for (const child of nodeData) { + const subChildren = child.children; + delete child.children; + const n = new WunderbaumNode(tree, this, child); + if (forceExpand && !n.isUnloaded()) { + n.expanded = true; + } + nodeList.push(n); + if (subChildren) { + n.addChildren(subChildren, { _level: _level + 1 }); + } + } + if (!this.children) { + this.children = nodeList; + } + else if (before == null || this.children.length === 0) { + this.children = this.children.concat(nodeList); + } + else { + // Returns null if before is not a direct child: + before = this.findDirectChild(before); + const pos = this.children.indexOf(before); + assert(pos >= 0, `options.before must be a direct child of ${this}`); + // insert nodeList after children[pos] + this.children.splice(pos, 0, ...nodeList); + } + // this.triggerModifyChild("add", nodeList.length === 1 ? nodeList[0] : null); + tree.update(ChangeType.structure); + } + finally { + // if (tree.options.selectMode === "hier") { + // if (this.parent && this.parent.children) { + // this.fixSelection3FromEndNodes(); + // } else { + // // may happen when loading __root__; + // } + // } + tree.enableUpdate(true); + } + // if(isTopCall && loadLazy){ + // this.logWarn("addChildren(): loadLazy is not yet implemented.") + // } + return nodeList[0]; + } + /** + * Append or prepend a node, or append a child node. + * + * This a convenience function that calls addChildren() + * + * @param nodeData node definition + * @param [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child') + * @returns new node + */ + addNode(nodeData, mode = "appendChild") { + if (mode === "over") { + mode = "appendChild"; // compatible with drop region + } + switch (mode) { + case "after": + return this.parent.addChildren(nodeData, { + before: this.getNextSibling(), + }); + case "before": + return this.parent.addChildren(nodeData, { before: this }); + case "prependChild": + // Insert before the first child if any + // let insertBefore = this.children ? this.children[0] : undefined; + return this.addChildren(nodeData, { before: 0 }); + case "appendChild": + return this.addChildren(nodeData); + } + assert(false, `Invalid mode: ${mode}`); + return undefined; + } + /** + * Apply a modification (or navigation) operation. + * + * @see {@link Wunderbaum.applyCommand} + */ + applyCommand(cmd, options) { + return this.tree.applyCommand(cmd, this, options); + } + /** + * Collapse all expanded sibling nodes if any. + * (Automatically called when `autoCollapse` is true.) + */ + collapseSiblings(options) { + for (const node of this.parent.children) { + if (node !== this && node.expanded) { + node.setExpanded(false, options); + } + } + } + /** + * Add/remove one or more classes to `
    `. + * + * This also maintains `node.classes`, so the class will survive a re-render. + * + * @param className one or more class names. Multiple classes can be passed + * as space-separated string, array of strings, or set of strings. + */ + setClass(className, flag = true) { + const cnSet = toSet(className); + if (flag) { + if (this.classes === null) { + this.classes = new Set(); + } + cnSet.forEach((cn) => { + var _a; + this.classes.add(cn); + (_a = this._rowElem) === null || _a === void 0 ? void 0 : _a.classList.toggle(cn, flag); + }); + } + else { + if (this.classes === null) { + return; + } + cnSet.forEach((cn) => { + var _a; + this.classes.delete(cn); + (_a = this._rowElem) === null || _a === void 0 ? void 0 : _a.classList.toggle(cn, flag); + }); + if (this.classes.size === 0) { + this.classes = null; + } + } + } + /** Start editing this node's title. */ + startEditTitle() { + this.tree._callMethod("edit.startEditTitle", this); + } + /** Call `setExpanded()` on all descendant nodes. */ + async expandAll(flag = true, options) { + const tree = this.tree; + const minExpandLevel = this.tree.options.minExpandLevel; + const { depth = 99, loadLazy, force, keepActiveNodeVisible = true, } = options !== null && options !== void 0 ? options : {}; + const expandOpts = { + scrollIntoView: false, + force: force, + loadLazy: loadLazy, + }; + // this.logInfo(`expandAll(${flag})`); + // Expand all direct children in parallel: + async function _iter(n, level) { + var _a; + // n.logInfo(` _iter(${level})`); + if (level === 0) { + return; + } + // if (!flag && minExpandLevel && !force && n.getLevel() <= minExpandLevel) { + // return; // Do not collapse until minExpandLevel + // } + const level_1 = level == null ? null : level - 1; + const promises = []; + (_a = n.children) === null || _a === void 0 ? void 0 : _a.forEach((cn) => { + if (flag) { + if (!cn.expanded && (cn.children || (loadLazy && cn.lazy))) { + // Node is collapsed and may be expanded (i.e. has children or is lazy) + // Expanding may be async, so we store the promise. + // Also the recursion is delayed until expansion finished. + const p = cn.setExpanded(true, expandOpts); + promises.push(p); + p.then(async () => { + await _iter(cn, level_1); + }); + } + else { + // We don't expand the node, but still visit descendants. + // There we may find lazy nodes, so we + promises.push(_iter(cn, level_1)); + } + } + else { + // Collapsing is always synchronous, so no promises required + if (!minExpandLevel || force || cn.getLevel() > minExpandLevel) { + // Do not collapse until minExpandLevel + cn.setExpanded(false, expandOpts); + } + _iter(cn, level_1); // recursion, even if cn was already collapsed + } + }); + return new Promise((resolve) => { + Promise.all(promises).then(() => { + resolve(true); + }); + }); + } + const tag = tree.logTime(`${this}.expandAll(${flag})`); + try { + tree.enableUpdate(false); + await _iter(this, depth); + } + finally { + tree.enableUpdate(true); + tree.logTimeEnd(tag); + } + if (tree.activeNode && keepActiveNodeVisible) { + tree.activeNode.scrollIntoView(); + } + } + /** + * Find all descendant nodes that match condition (excluding self). + * + * If `match` is a string, search for exact node title. + * If `match` is a RegExp expression, apply it to node.title, using + * [RegExp.test()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test). + * If `match` is a callback, match all nodes for that the callback(node) returns true. + * + * Returns an empty array if no nodes were found. + * + * Examples: + * ```js + * // Match all node titles that match exactly 'Joe': + * nodeList = node.findAll("Joe") + * // Match all node titles that start with 'Joe' case sensitive: + * nodeList = node.findAll(/^Joe/) + * // Match all node titles that contain 'oe', case insensitive: + * nodeList = node.findAll(/oe/i) + * // Match all nodes with `data.price` >= 99: + * nodeList = node.findAll((n) => { + * return n.data.price >= 99; + * }) + * ``` + */ + findAll(match) { + const matcher = typeof match === "function" ? match : makeNodeTitleMatcher(match); + const res = []; + this.visit((n) => { + if (matcher(n)) { + res.push(n); + } + }); + return res; + } + /** Return the direct child with a given key, index or null. */ + findDirectChild(ptr) { + const cl = this.children; + if (!cl) { + return null; + } + if (typeof ptr === "string") { + for (let i = 0, l = cl.length; i < l; i++) { + if (cl[i].key === ptr) { + return cl[i]; + } + } + } + else if (typeof ptr === "number") { + return cl[ptr]; + } + else if (ptr.parent === this) { + // Return null if `ptr` is not a direct child + return ptr; + } + return null; + } + /** + * Find first descendant node that matches condition (excluding self) or null. + * + * @see {@link WunderbaumNode.findAll} for examples. + */ + findFirst(match) { + const matcher = typeof match === "function" ? match : makeNodeTitleMatcher(match); + let res = null; + this.visit((n) => { + if (matcher(n)) { + res = n; + return false; + } + }); + return res; + } + /** Find a node relative to self. + * + * @see {@link Wunderbaum.findRelatedNode|tree.findRelatedNode()} + */ + findRelatedNode(where, includeHidden = false) { + return this.tree.findRelatedNode(this, where, includeHidden); + } + /** + * Iterator version of {@link WunderbaumNode.format}. + */ + *format_iter(name_cb, connectors) { + connectors !== null && connectors !== void 0 ? connectors : (connectors = [" ", " | ", " ╰─ ", " ├─ "]); + name_cb !== null && name_cb !== void 0 ? name_cb : (name_cb = (node) => "" + node); + function _is_last(node) { + const ca = node.parent.children; + return node === ca[ca.length - 1]; + } + const _format_line = (node) => { + // https://www.measurethat.net/Benchmarks/Show/12196/0/arr-unshift-vs-push-reverse-small-array + const parts = [name_cb(node)]; + parts.unshift(connectors[_is_last(node) ? 2 : 3]); + let p = node.parent; + while (p && p !== this) { + // `this` is the top node + parts.unshift(connectors[_is_last(p) ? 0 : 1]); + p = p.parent; + } + return parts.join(""); + }; + yield name_cb(this); + for (const node of this) { + yield _format_line(node); + } + } + /** + * Return a multiline string representation of a node/subnode hierarchy. + * Mostly useful for debugging. + * + * Example: + * ```js + * console.info(tree.getActiveNode().format((n)=>n.title)); + * ``` + * logs + * ``` + * Books + * ├─ Art of War + * ╰─ Don Quixote + * ``` + * @see {@link WunderbaumNode.format_iter} + */ + format(name_cb, connectors) { + const a = []; + for (const line of this.format_iter(name_cb, connectors)) { + a.push(line); + } + return a.join("\n"); + } + /** Return the `` element with a given index or id. + * @returns {WunderbaumNode | null} + */ + getColElem(colIdx) { + var _a; + if (typeof colIdx === "string") { + colIdx = this.tree.columns.findIndex((value) => value.id === colIdx); + } + const colElems = (_a = this._rowElem) === null || _a === void 0 ? void 0 : _a.querySelectorAll("span.wb-col"); + return colElems ? colElems[colIdx] : null; + } + /** + * Return all nodes with the same refKey. + * + * @param includeSelf Include this node itself. + * @see {@link Wunderbaum.findByRefKey} + */ + getCloneList(includeSelf = false) { + if (!this.refKey) { + return []; + } + const clones = this.tree.findByRefKey(this.refKey); + if (includeSelf) { + return clones; + } + return [...clones].filter((n) => n !== this); + } + /** Return the first child node or null. + * @returns {WunderbaumNode | null} + */ + getFirstChild() { + return this.children ? this.children[0] : null; + } + /** Return the last child node or null. + * @returns {WunderbaumNode | null} + */ + getLastChild() { + return this.children ? this.children[this.children.length - 1] : null; + } + /** Return node depth (starting with 1 for top level nodes). */ + getLevel() { + let i = 0, p = this.parent; + while (p) { + i++; + p = p.parent; + } + return i; + } + /** Return the successive node (under the same parent) or null. */ + getNextSibling() { + const ac = this.parent.children; + const idx = ac.indexOf(this); + return ac[idx + 1] || null; + } + /** Return the parent node (null for the system root node). */ + getParent() { + // TODO: return null for top-level nodes? + return this.parent; + } + /** Return an array of all parent nodes (top-down). + * @param includeRoot Include the invisible system root node. + * @param includeSelf Include the node itself. + */ + getParentList(includeRoot = false, includeSelf = false) { + const l = []; + let dtn = includeSelf ? this : this.parent; + while (dtn) { + if (includeRoot || dtn.parent) { + l.unshift(dtn); + } + dtn = dtn.parent; + } + return l; + } + /** Return a string representing the hierachical node path, e.g. "a/b/c". + * @param includeSelf + * @param node property name or callback + * @param separator + */ + getPath(includeSelf = true, part = "title", separator = "/") { + // includeSelf = includeSelf !== false; + // part = part || "title"; + // separator = separator || "/"; + let val; + const path = []; + const isFunc = typeof part === "function"; + this.visitParents((n) => { + if (n.parent) { + val = isFunc + ? part(n) + : n[part]; + path.unshift(val); + } + return undefined; // TODO remove this line + }, includeSelf); + return path.join(separator); + } + /** Return the preceeding node (under the same parent) or null. */ + getPrevSibling() { + const ac = this.parent.children; + const idx = ac.indexOf(this); + return ac[idx - 1] || null; + } + /** Return true if node has children. + * Return undefined if not sure, i.e. the node is lazy and not yet loaded. + */ + hasChildren() { + if (this.lazy) { + if (this.children == null) { + return undefined; // null or undefined: Not yet loaded + } + else if (this.children.length === 0) { + return false; // Loaded, but response was empty + } + else if (this.children.length === 1 && + this.children[0].isStatusNode()) { + return undefined; // Currently loading or load error + } + return true; // One or more child nodes + } + return !!(this.children && this.children.length); + } + /** Return true if node has className set. */ + hasClass(className) { + return this.classes ? this.classes.has(className) : false; + } + /** Return true if this node is the currently active tree node. */ + isActive() { + return this.tree.activeNode === this; + } + /** Return true if this node is a direct or indirect parent of `other`. + * @see {@link WunderbaumNode.isParentOf} + */ + isAncestorOf(other) { + return other && other.isDescendantOf(this); + } + /** Return true if this node is a **direct** subnode of `other`. + * @see {@link WunderbaumNode.isDescendantOf} + */ + isChildOf(other) { + return other && this.parent === other; + } + /** Return true if this node's refKey is used by at least one other node. + */ + isClone() { + return !!this.refKey && this.tree.findByRefKey(this.refKey).length > 1; + } + /** Return true if this node's title spans all columns, i.e. the node has no + * grid cells. + */ + isColspan() { + return !!this.getOption("colspan"); + } + /** Return true if this node is a direct or indirect subnode of `other`. + * @see {@link WunderbaumNode.isChildOf} + */ + isDescendantOf(other) { + if (!other || other.tree !== this.tree) { + return false; + } + let p = this.parent; + while (p) { + if (p === other) { + return true; + } + if (p === p.parent) { + error(`Recursive parent link: ${p}`); + } + p = p.parent; + } + return false; + } + /** Return true if this node has children, i.e. the node is generally expandable. + * If `andCollapsed` is set, we also check if this node is collapsed, i.e. + * an expand operation is currently possible. + */ + isExpandable(andCollapsed = false) { + // `false` is never expandable (unoffical) + if ((andCollapsed && this.expanded) || this.children === false) { + return false; + } + if (this.children == null) { + return !!this.lazy; // null or undefined can trigger lazy load + } + if (this.children.length === 0) { + return !!this.tree.options.emptyChildListExpandable; + } + return true; + } + /** Return true if _this_ node is currently in edit-title mode. + * + * See {@link Wunderbaum.startEditTitle} to check if any node is currently edited. + */ + isEditingTitle() { + return this.tree._callMethod("edit.isEditingTitle", this); + } + /** Return true if this node is currently expanded. */ + isExpanded() { + return !!this.expanded; + } + /** Return true if this node is the first node of its parent's children. */ + isFirstSibling() { + const p = this.parent; + return !p || p.children[0] === this; + } + /** Return true if this node is the last node of its parent's children. */ + isLastSibling() { + const p = this.parent; + return !p || p.children[p.children.length - 1] === this; + } + /** Return true if this node is lazy (even if data was already loaded) */ + isLazy() { + return !!this.lazy; + } + /** Return true if node is lazy and loaded. For non-lazy nodes always return true. */ + isLoaded() { + return !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node + } + /** Return true if node is currently loading, i.e. a GET request is pending. */ + isLoading() { + return this._isLoading; + } + /** Return true if this node is a temporarily generated status node of type 'paging'. */ + isPagingNode() { + return this.statusNodeType === "paging"; + } + /** Return true if this node is a **direct** parent of `other`. + * @see {@link WunderbaumNode.isAncestorOf} + */ + isParentOf(other) { + return other && other.parent === this; + } + /** (experimental) Return true if this node is partially loaded. */ + isPartload() { + return !!this._partload; + } + /** Return true if this node is partially selected (tri-state). */ + isPartsel() { + return !this.selected && !!this._partsel; + } + /** Return true if this node has DOM representaion, i.e. is displayed in the viewport. */ + isRadio() { + return !!this.parent.radiogroup || this.getOption("checkbox") === "radio"; + } + /** Return true if this node has DOM representaion, i.e. is displayed in the viewport. */ + isRendered() { + return !!this._rowElem; + } + /** Return true if this node is the (invisible) system root node. + * @see {@link WunderbaumNode.isTopLevel} + */ + isRootNode() { + return this.tree.root === this; + } + /** Return true if this node is selected, i.e. the checkbox is set. + * `undefined` if partly selected (tri-state), false otherwise. + */ + isSelected() { + return this.selected ? true : this._partsel ? undefined : false; + } + /** Return true if this node is a temporarily generated system node like + * 'loading', 'paging', or 'error' (node.statusNodeType contains the type). + */ + isStatusNode() { + return !!this.statusNodeType; + } + /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node. */ + isTopLevel() { + return this.tree.root === this.parent; + } + /** Return true if node is marked lazy but not yet loaded. + * For non-lazy nodes always return false. + */ + isUnloaded() { + // Also checks if the only child is a status node: + return this.hasChildren() === undefined; + } + /** Return true if all parent nodes are expanded. Note: this does not check + * whether the node is scrolled into the visible part of the screen or viewport. + */ + isVisible() { + const hasFilter = this.tree.filterMode === "hide"; + const parents = this.getParentList(false, false); + // TODO: check $(n.span).is(":visible") + // i.e. return false for nodes (but not parents) that are hidden + // by a filter + if (hasFilter && !this.match && !this.subMatchCount) { + // this.debug( "isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")" ); + return false; + } + for (let i = 0, l = parents.length; i < l; i++) { + const n = parents[i]; + if (!n.expanded) { + // this.debug("isVisible: HIDDEN (parent collapsed)"); + return false; + } + // if (hasFilter && !n.match && !n.subMatchCount) { + // this.debug("isVisible: HIDDEN (" + hasFilter + ", " + this.match + ", " + this.match + ")"); + // return false; + // } + } + // this.debug("isVisible: VISIBLE"); + return true; + } + _loadSourceObject(source, level) { + var _a; + const tree = this.tree; + level !== null && level !== void 0 ? level : (level = this.getLevel()); + // Let caller modify the parsed JSON response: + const res = this._callEvent("receive", { response: source }); + if (res != null) { + source = res; + } + if (isArray(source)) { + source = { children: source }; + } + assert(isPlainObject(source), `Expected an array or plain object: ${source}`); + const format = (_a = source.format) !== null && _a !== void 0 ? _a : "nested"; + assert(format === "nested" || format === "flat", `Expected source.format = 'nested' or 'flat': ${format}`); + // Pre-rocess for 'nested' or 'flat' format + decompressSourceData(source); + assert(source.children, "If `source` is an object, it must have a `children` property"); + if (source.types) { + tree.logInfo("Redefine types", source.columns); + tree.setTypes(source.types, false); + delete source.types; + } + if (source.columns) { + tree.logInfo("Redefine columns", source.columns); + tree.columns = source.columns; + delete source.columns; + tree.update(ChangeType.colStructure); + } + this.addChildren(source.children); + // Add extra data to `tree.data` + for (const [key, value] of Object.entries(source)) { + if (!RESERVED_TREE_SOURCE_KEYS.has(key)) { + tree.data[key] = value; + // tree.logDebug(`Add source.${key} to tree.data.${key}`); + } + } + if (tree.options.selectMode === "hier") { + this.fixSelection3FromEndNodes(); + } + this._callEvent("load"); + } + async _fetchWithOptions(source) { + var _a, _b; + // Either a URL string or an object with a `.url` property. + let url, params, body, options, rest; + let fetchOpts = {}; + if (typeof source === "string") { + // source is a plain URL string: assume GET request + url = source; + fetchOpts.method = "GET"; + } + else if (isPlainObject(source)) { + // source is a plain object with `.url` property. + ({ url, params, body, options, ...rest } = source); + assert(!rest || Object.keys(rest).length === 0, `Unexpected source properties: ${Object.keys(rest)}. Use 'options' instead.`); + assert(typeof url === "string", `expected source.url as string`); + if (isPlainObject(options)) { + fetchOpts = options; + } + if (isPlainObject(body)) { + // we also accept 'body' as object... + assert(!fetchOpts.body, "options.body should be passed as source.body"); + fetchOpts.body = JSON.stringify(fetchOpts.body); + (_a = fetchOpts.method) !== null && _a !== void 0 ? _a : (fetchOpts.method = "POST"); // set default + } + if (isPlainObject(params)) { + url += "?" + new URLSearchParams(params); + (_b = fetchOpts.method) !== null && _b !== void 0 ? _b : (fetchOpts.method = "GET"); // set default + } + } + else { + url = ""; // keep linter happy + error(`Unsupported source format: ${source}`); + } + this.setStatus(NodeStatusType.loading); + const response = await fetch(url, fetchOpts); + if (!response.ok) { + error(`GET ${url} returned ${response.status}, ${response}`); + } + return await response.json(); + } + /** Download data from the cloud, then call `.update()`. */ + async load(source) { + const tree = this.tree; + const requestId = Date.now(); + const prevParent = this.parent; + const start = Date.now(); + let elap = 0, elapLoad = 0, elapProcess = 0; + // Check for overlapping requests + if (this._requestId) { + this.logWarn(`Recursive load request #${requestId} while #${this._requestId} is pending.`); + // node.debug("Send load request #" + requestId); + } + this._requestId = requestId; + // const timerLabel = tree.logTime(this + ".load()"); + try { + const url = typeof source === "string" ? source : source.url; + if (!url) { + // An array or a plain object (that does NOT contain a `.url` property) + // will be treated as native Wunderbaum data + if (typeof source.then === "function") { + const msg = tree.logTime(`Resolve thenable ${source}`); + source = await Promise.resolve(source); + tree.logTimeEnd(msg); + } + this._loadSourceObject(source); + elapProcess = Date.now() - start; + } + else { + // Either a URL string or an object with a `.url` property. + const data = await this._fetchWithOptions(source); + elapLoad = Date.now() - start; + if (this._requestId && this._requestId > requestId) { + this.logWarn(`Ignored load response #${requestId} because #${this._requestId} is pending.`); + return; + } + else { + this.logDebug(`Received response for load request #${requestId}`); + } + if (this.parent === null && prevParent !== null) { + this.logWarn("Lazy parent node was removed while loading: discarding response."); + return; + } + this.setStatus(NodeStatusType.ok); + // if (data.columns) { + // tree.logInfo("Re-define columns", data.columns); + // util.assert(!this.parent); + // tree.columns = data.columns; + // delete data.columns; + // tree.updateColumns({ calculateCols: false }); + // } + const startProcess = Date.now(); + this._loadSourceObject(data); + elapProcess = Date.now() - startProcess; + } + } + catch (error) { + this.logError("Error during load()", source, error); + this._callEvent("error", { error: error }); + this.setStatus(NodeStatusType.error, { message: "" + error }); + throw error; + } + finally { + this._requestId = 0; + elap = Date.now() - start; + if (tree.options.debugLevel >= 3) { + tree.logInfo(`Load source took ${elap / 1000} seconds ` + + `(transfer: ${elapLoad / 1000}s, ` + + `processing: ${elapProcess / 1000}s)`); + } + } + } + /** + * Load content of a lazy node. + * If the node is already loaded, nothing happens. + * @param [forceReload=false] If true, reload even if already loaded. + */ + async loadLazy(forceReload = false) { + const wasExpanded = this.expanded; + assert(this.lazy, "load() requires a lazy node"); + if (!forceReload && !this.isUnloaded()) { + return; // Already loaded: nothing to do + } + if (this.isLoading()) { + this.logWarn("loadLazy() called while already loading: ignored."); + return; // Already loading: prevent duplicate requests + } + if (this.isLoaded()) { + this.resetLazy(); // Also collapses if currently expanded + } + // `lazyLoad` may be long-running, so mark node as loading now. `this.load()` + // will reset the status later. + this.setStatus(NodeStatusType.loading); + try { + const source = await this._callEvent("lazyLoad"); + if (source === false) { + this.setStatus(NodeStatusType.ok); + return; + } + assert(isArray(source) || (source && source.url), "The lazyLoad event must return a node list, `{url: ...}`, or false."); + await this.load(source); + this.setStatus(NodeStatusType.ok); // Also resets `this._isLoading` + if (wasExpanded) { + this.expanded = true; + this.tree.update(ChangeType.structure); + } + else { + this.update(); // Fix expander icon to 'loaded' + } + } + catch (e) { + this.logError("Error during loadLazy()", e); + this._callEvent("error", { error: e }); + // Also resets `this._isLoading`: + this.setStatus(NodeStatusType.error, { message: "" + e }); + } + return; + } + /** Write to `console.log` with node name as prefix if opts.debugLevel >= 4. + * @see {@link WunderbaumNode.logDebug} + */ + log(...args) { + if (this.tree.options.debugLevel >= 4) { + console.log(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Write to `console.debug` with node name as prefix if opts.debugLevel >= 4 + * and browser console level includes debug/verbose messages. + * @see {@link WunderbaumNode.log} + */ + logDebug(...args) { + if (this.tree.options.debugLevel >= 4) { + console.debug(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Write to `console.error` with node name as prefix if opts.debugLevel >= 1. */ + logError(...args) { + if (this.tree.options.debugLevel >= 1) { + console.error(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Write to `console.info` with node name as prefix if opts.debugLevel >= 3. */ + logInfo(...args) { + if (this.tree.options.debugLevel >= 3) { + console.info(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Write to `console.warn` with node name as prefix if opts.debugLevel >= 2. */ + logWarn(...args) { + if (this.tree.options.debugLevel >= 2) { + console.warn(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Expand all parents and optionally scroll into visible area as neccessary. + * Promise is resolved, when lazy loading and animations are done. + * @param {object} [options] passed to `setExpanded()`. + * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true} + */ + async makeVisible(options) { + let i; + const dfd = new Deferred(); + const deferreds = []; + const parents = this.getParentList(false, false); + const len = parents.length; + const noAnimation = getOption(options, "noAnimation", false); + const scroll = getOption(options, "scrollIntoView", true); + // Expand bottom-up, so only the top node is animated + for (i = len - 1; i >= 0; i--) { + // self.debug("pushexpand" + parents[i]); + const seOpts = { noAnimation: noAnimation }; + deferreds.push(parents[i].setExpanded(true, seOpts)); + } + Promise.all(deferreds).then(() => { + // All expands have finished + // self.debug("expand DONE", scroll); + // Note: this.tree may be none when switching demo trees + if (scroll && this.tree) { + // Make sure markup and _rowIdx is updated before we do the scroll calculations + this.tree.updatePendingModifications(); + this.scrollIntoView().then(() => { + // self.debug("scroll DONE"); + dfd.resolve(); + }); + } + else { + dfd.resolve(); + } + }); + return dfd.promise(); + } + /** Move this node to targetNode. */ + moveTo(targetNode, mode = "appendChild", map) { + if (mode === "over") { + mode = "appendChild"; // compatible with drop region + } + if (mode === "prependChild") { + if (targetNode.children && targetNode.children.length) { + mode = "before"; + targetNode = targetNode.children[0]; + } + else { + mode = "appendChild"; + } + } + let pos; + const tree = this.tree; + const prevParent = this.parent; + const targetParent = mode === "appendChild" ? targetNode : targetNode.parent; + if (this === targetNode) { + return; + } + else if (!this.parent) { + error("Cannot move system root"); + } + else if (targetParent.isDescendantOf(this)) { + error("Cannot move a node to its own descendant"); + } + if (targetParent !== prevParent) { + prevParent.triggerModifyChild("remove", this); + } + // Unlink this node from current parent + if (this.parent.children.length === 1) { + if (this.parent === targetParent) { + return; // #258 + } + this.parent.children = this.parent.lazy ? [] : null; + this.parent.expanded = false; + } + else { + pos = this.parent.children.indexOf(this); + assert(pos >= 0, "invalid source parent"); + this.parent.children.splice(pos, 1); + } + // Insert this node to target parent's child list + this.parent = targetParent; + if (targetParent.hasChildren()) { + switch (mode) { + case "appendChild": + // Append to existing target children + targetParent.children.push(this); + break; + case "before": + // Insert this node before target node + pos = targetParent.children.indexOf(targetNode); + assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos, 0, this); + break; + case "after": + // Insert this node after target node + pos = targetParent.children.indexOf(targetNode); + assert(pos >= 0, "invalid target parent"); + targetParent.children.splice(pos + 1, 0, this); + break; + default: + error(`Invalid mode '${mode}'.`); + } + } + else { + targetParent.children = [this]; + } + // Let caller modify the nodes + if (map) { + targetNode.visit(map, true); + } + if (targetParent === prevParent) { + targetParent.triggerModifyChild("move", this); + } + else { + // prevParent.triggerModifyChild("remove", this); + targetParent.triggerModifyChild("add", this); + } + // Handle cross-tree moves + if (tree !== targetNode.tree) { + // Fix node.tree for all source nodes + // util.assert(false, "Cross-tree move is not yet implemented."); + this.logWarn("Cross-tree moveTo is experimental!"); + this.visit((n) => { + // TODO: fix selection state and activation, ... + n.tree = targetNode.tree; + }, true); + } + // Make sure we update async, because discarding the markup would prevent + // DragAndDrop to generate a dragend event on the source node + setTimeout(() => { + // Even indentation may have changed: + tree.update(ChangeType.any); + }, 0); + // TODO: fix selection state + // TODO: fix active state + } + /** Set focus relative to this node and optionally activate. + * + * 'left' collapses the node if it is expanded, or move to the parent + * otherwise. + * 'right' expands the node if it is collapsed, or move to the first + * child otherwise. + * + * @param where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the `event.key` that would normally trigger this move, + * e.g. `ArrowLeft` = 'left'. + * @param options + */ + async navigate(where, options) { + // Allow to pass 'ArrowLeft' instead of 'left' + where = KEY_TO_ACTION_DICT[where] || where; + // Otherwise activate or focus the related node + const node = this.findRelatedNode(where); + if (!node) { + this.logWarn(`Could not find related node '${where}'.`); + return Promise.resolve(this); + } + // setFocus/setActive will scroll later (if autoScroll is specified) + try { + node.makeVisible({ scrollIntoView: false }); + } + catch (e) { + // ignore + } + node.setFocus(); + if ((options === null || options === void 0 ? void 0 : options.activate) === false) { + return Promise.resolve(this); + } + return node.setActive(true, { event: options === null || options === void 0 ? void 0 : options.event }); + } + /** Delete this node and all descendants. */ + remove() { + const tree = this.tree; + const pos = this.parent.children.indexOf(this); + this.triggerModify("remove"); + this.parent.children.splice(pos, 1); + this.visit((n) => { + n.removeMarkup(); + tree._unregisterNode(n); + }, true); + tree.update(ChangeType.structure); + } + /** Remove all descendants of this node. */ + removeChildren() { + var _a, _b; + const tree = this.tree; + if (!this.children) { + return; + } + if ((_a = tree.activeNode) === null || _a === void 0 ? void 0 : _a.isDescendantOf(this)) { + tree.activeNode.setActive(false); // TODO: don't fire events + } + if ((_b = tree.focusNode) === null || _b === void 0 ? void 0 : _b.isDescendantOf(this)) { + tree._setFocusNode(null); + } + // TODO: persist must take care to clear select and expand cookies + // Unlink children to support GC + // TODO: also delete this.children (not possible using visit()) + this.triggerModifyChild("remove", null); + this.visit((n) => { + tree._unregisterNode(n); + }); + if (this.lazy) { + // 'undefined' would be interpreted as 'not yet loaded' for lazy nodes + this.children = []; + } + else { + this.children = null; + } + // util.assert(this.parent); // don't call this for root node + if (!this.isRootNode()) { + this.expanded = false; + } + this.tree.update(ChangeType.structure); + } + /** Remove all HTML markup from the DOM. */ + removeMarkup() { + if (this._rowElem) { + delete this._rowElem._wb_node; + this._rowElem.remove(); + this._rowElem = undefined; + } + } + _getRenderInfo() { + const allColInfosById = {}; + const renderColInfosById = {}; + const isColspan = this.isColspan(); + const colElems = this._rowElem + ? (this._rowElem.querySelectorAll("span.wb-col")) + : null; + let idx = 0; + for (const col of this.tree.columns) { + allColInfosById[col.id] = { + id: col.id, + idx: idx, + elem: colElems ? colElems[idx] : null, + info: col, + }; + // renderColInfosById only contains columns that need rendering: + if (!isColspan && col.id !== "*") { + renderColInfosById[col.id] = allColInfosById[col.id]; + } + idx++; + } + return { + allColInfosById: allColInfosById, + renderColInfosById: renderColInfosById, + }; + } + _createIcon(iconMap, parentElem, replaceChild, showLoading) { + let iconSpan; + let icon = this.getOption("icon"); + if (this._errorInfo) { + icon = iconMap.error; + } + else if (this._isLoading && showLoading) { + // Status nodes, or nodes without expander (< minExpandLevel) should + // display the 'loading' status with the i.wb-icon span + icon = iconMap.loading; + } + if (icon === false) { + return null; // explicitly disabled: don't try default icons + } + if (typeof icon === "string") ; + else if (this.statusNodeType) { + icon = iconMap[this.statusNodeType]; + } + else if (this.expanded) { + icon = iconMap.folderOpen; + } + else if (this.children) { + icon = iconMap.folder; + } + else if (this.lazy) { + icon = iconMap.folderLazy; + } + else { + icon = iconMap.doc; + } + // this.log("_createIcon: " + icon); + if (!icon) { + iconSpan = document.createElement("i"); + iconSpan.className = "wb-icon"; + } + else if (icon.indexOf("<") >= 0) { + // HTML + iconSpan = elemFromHtml(icon); + } + else if (TEST_IMG.test(icon)) { + // Image URL + iconSpan = elemFromHtml(``); + } + else { + // Class name + iconSpan = document.createElement("i"); + iconSpan.className = "wb-icon " + icon; + } + if (replaceChild) { + parentElem.replaceChild(iconSpan, replaceChild); + } + else { + parentElem.appendChild(iconSpan); + } + // Event handler `tree.iconBadge` can return a badge text or HTMLSpanElement + const cbRes = this._callEvent("iconBadge", { iconSpan: iconSpan }); + let badge = null; + if (cbRes != null && cbRes !== false) { + let classes = ""; + let tooltip = ""; + if (isPlainObject(cbRes)) { + badge = "" + cbRes.badge; + classes = cbRes.badgeClass ? " " + cbRes.badgeClass : ""; + tooltip = cbRes.badgeTooltip ? ` title="${cbRes.badgeTooltip}"` : ""; + } + else if (typeof cbRes === "number") { + badge = "" + cbRes; + } + else { + badge = cbRes; // string or HTMLSpanElement + } + if (typeof badge === "string") { + badge = elemFromHtml(`${escapeHtml(badge)}`); + } + if (badge) { + iconSpan.append(badge); + } + } + // this.log("_createIcon: ", iconSpan); + return iconSpan; + } + /** + * Create a whole new `
    ` element. + * @see {@link WunderbaumNode._render} + */ + _render_markup(opts) { + const tree = this.tree; + const treeOptions = tree.options; + const checkbox = this.getOption("checkbox"); + const columns = tree.columns; + const level = this.getLevel(); + const activeColIdx = tree.isRowNav() ? null : tree.activeColIdx; + let elem; + let rowDiv = this._rowElem; + let checkboxSpan = null; + let expanderSpan = null; + const isNew = !rowDiv; + assert(isNew, "Expected unrendered node"); + assert(!isNew || (opts && opts.after), "opts.after expected, unless updating"); + assert(!this.isRootNode(), "Root node not allowed"); + rowDiv = document.createElement("div"); + rowDiv.classList.add("wb-row"); + rowDiv.style.top = this._rowIdx * ROW_HEIGHT + "px"; + this._rowElem = rowDiv; + // Attach a node reference to the DOM Element: + rowDiv._wb_node = this; + const nodeElem = document.createElement("span"); + nodeElem.classList.add("wb-node", "wb-col"); + rowDiv.appendChild(nodeElem); + let ofsTitlePx = 0; + if (checkbox) { + checkboxSpan = document.createElement("i"); + checkboxSpan.classList.add("wb-checkbox"); + if (checkbox === "radio" || this.parent.radiogroup) { + checkboxSpan.classList.add("wb-radio"); + } + nodeElem.appendChild(checkboxSpan); + ofsTitlePx += ICON_WIDTH; + } + for (let i = level - 1; i > 0; i--) { + elem = document.createElement("i"); + elem.classList.add("wb-indent"); + nodeElem.appendChild(elem); + ofsTitlePx += ICON_WIDTH; + } + if (!treeOptions.minExpandLevel || level > treeOptions.minExpandLevel) { + expanderSpan = document.createElement("i"); + expanderSpan.classList.add("wb-expander"); + nodeElem.appendChild(expanderSpan); + ofsTitlePx += ICON_WIDTH; + } + // Render the icon (show a 'loading' icon if we do not have an expander that + // we would prefer). + const iconSpan = this._createIcon(tree.iconMap, nodeElem, null, !expanderSpan); + if (iconSpan) { + ofsTitlePx += ICON_WIDTH; + } + const titleSpan = document.createElement("span"); + titleSpan.classList.add("wb-title"); + nodeElem.appendChild(titleSpan); + // this._callEvent("enhanceTitle", { titleSpan: titleSpan }); + // Store the width of leading icons with the node, so we can calculate + // the width of the embedded title span later + nodeElem._ofsTitlePx = ofsTitlePx; + // Support HTML5 drag-n-drop + if (tree.options.dnd.dragStart) { + nodeElem.draggable = true; + } + // Render columns + const isColspan = this.isColspan(); + if (!isColspan && columns.length > 1) { + let colIdx = 0; + for (const col of columns) { + colIdx++; + let colElem; + if (col.id === "*") { + colElem = nodeElem; + } + else { + colElem = document.createElement("span"); + colElem.classList.add("wb-col"); + rowDiv.appendChild(colElem); + } + if (colIdx === activeColIdx) { + colElem.classList.add("wb-active"); + } + // Add classes from `columns` definition to `` cells + col.classes ? colElem.classList.add(...col.classes.split(" ")) : 0; + colElem.style.left = col._ofsPx + "px"; + colElem.style.width = col._widthPx + "px"; + if (isNew && col.html) { + if (typeof col.html === "string") { + colElem.innerHTML = col.html; + } + } + } + } + // Attach to DOM as late as possible + const after = opts ? opts.after : "last"; + switch (after) { + case "first": + tree.nodeListElement.prepend(rowDiv); + break; + case "last": + tree.nodeListElement.appendChild(rowDiv); + break; + default: + opts.after.after(rowDiv); + } + // Now go on and fill in data and update classes + opts.isNew = true; + this._render_data(opts); + } + /** + * Render `node.title`, `.icon` into an existing row. + * + * @see {@link WunderbaumNode._render} + */ + _render_data(opts) { + assert(this._rowElem, "No _rowElem"); + const tree = this.tree; + const treeOptions = tree.options; + const rowDiv = this._rowElem; + const isNew = !!opts.isNew; // Called by _render_markup()? + const preventScroll = !!opts.preventScroll; + const columns = tree.columns; + const isColspan = this.isColspan(); + // Row markup already exists + const nodeElem = rowDiv.querySelector("span.wb-node"); + const titleSpan = nodeElem.querySelector("span.wb-title"); + const scrollTop = tree.element.scrollTop; + if (this.titleWithHighlight) { + titleSpan.innerHTML = this.titleWithHighlight; + } + else { + titleSpan.textContent = this.title; // TODO: this triggers scroll events + } + // NOTE: At least on Safari, this render call triggers a scroll event + // probably when a focused input is replaced. + if (preventScroll) { + tree.element.scrollTop = scrollTop; + } + // Set the width of the title span, so overflow ellipsis work + if (!treeOptions.skeleton) { + if (isColspan) { + const vpWidth = tree.element.clientWidth; + titleSpan.style.width = + vpWidth - nodeElem._ofsTitlePx - TITLE_SPAN_PAD_Y + "px"; + } + else { + titleSpan.style.width = + columns[0]._widthPx - + nodeElem._ofsTitlePx - + TITLE_SPAN_PAD_Y + + "px"; + } + } + // Update row classes + opts.isDataChange = true; + this._render_status(opts); + // Let user modify the result + if (this.statusNodeType) { + this._callEvent("renderStatusNode", { + isNew: isNew, + nodeElem: nodeElem, + isColspan: isColspan, + }); + } + else if (this.parent) { + // Skip root node + const renderInfo = this._getRenderInfo(); + this._callEvent("render", { + isNew: isNew, + nodeElem: nodeElem, + isColspan: isColspan, + allColInfosById: renderInfo.allColInfosById, + renderColInfosById: renderInfo.renderColInfosById, + }); + } + } + /** + * Update row classes to reflect active, focuses, etc. + * @see {@link WunderbaumNode._render} + */ + _render_status(opts) { + // this.log("_render_status", opts); + const tree = this.tree; + const iconMap = tree.iconMap; + const treeOptions = tree.options; + const typeInfo = this.type ? tree.types[this.type] : null; + const rowDiv = this._rowElem; + // Row markup already exists + const nodeElem = rowDiv.querySelector("span.wb-node"); + const expanderSpan = nodeElem.querySelector("i.wb-expander"); + const checkboxSpan = nodeElem.querySelector("i.wb-checkbox"); + const rowClasses = ["wb-row"]; + this.expanded ? rowClasses.push("wb-expanded") : 0; + this.lazy ? rowClasses.push("wb-lazy") : 0; + this.selected ? rowClasses.push("wb-selected") : 0; + this._partsel ? rowClasses.push("wb-partsel") : 0; + this === tree.activeNode ? rowClasses.push("wb-active") : 0; + this === tree.focusNode ? rowClasses.push("wb-focus") : 0; + this._errorInfo ? rowClasses.push("wb-error") : 0; + this._isLoading ? rowClasses.push("wb-loading") : 0; + this.isColspan() ? rowClasses.push("wb-colspan") : 0; + this.statusNodeType + ? rowClasses.push("wb-status-" + this.statusNodeType) + : 0; + this.match ? rowClasses.push("wb-match") : 0; + this.subMatchCount ? rowClasses.push("wb-submatch") : 0; + treeOptions.skeleton ? rowClasses.push("wb-skeleton") : 0; + // Replace previous classes: + rowDiv.className = rowClasses.join(" "); + // Add classes from `node.classes` + this.classes ? rowDiv.classList.add(...this.classes) : 0; + // Add classes from `tree.types[node.type]` + if (typeInfo && typeInfo.classes) { + rowDiv.classList.add(...typeInfo.classes); + } + if (expanderSpan) { + let image = null; + if (this._isLoading) { + image = iconMap.loading; + } + else if (this.isExpandable(false)) { + if (this.expanded) { + image = iconMap.expanderExpanded; + } + else { + image = iconMap.expanderCollapsed; + } + } + else if (this.lazy && this.children == null) { + image = iconMap.expanderLazy; + } + if (image == null) { + expanderSpan.classList.add("wb-indent"); + } + else if (TEST_IMG.test(image)) { + expanderSpan.style.backgroundImage = `url('${image}')`; + } + else { + expanderSpan.className = "wb-expander " + image; + } + } + if (checkboxSpan) { + let cbclass = "wb-checkbox "; + if (this.isRadio()) { + cbclass += "wb-radio "; + if (this.selected) { + cbclass += iconMap.radioChecked; + // } else if (this._partsel) { + // cbclass += iconMap.radioUnknown; + } + else { + cbclass += iconMap.radioUnchecked; + } + } + else { + if (this.selected) { + cbclass += iconMap.checkChecked; + } + else if (this._partsel) { + cbclass += iconMap.checkUnknown; + } + else { + cbclass += iconMap.checkUnchecked; + } + } + checkboxSpan.className = cbclass; + } + // Fix active cell in cell-nav mode + if (!opts.isNew) { + let i = 0; + for (const colSpan of rowDiv.children) { + colSpan.classList.toggle("wb-active", i++ === tree.activeColIdx); + colSpan.classList.remove("wb-error", "wb-invalid"); + } + // Update icon (if not opts.isNew, which would rebuild markup anyway) + const iconSpan = nodeElem.querySelector("i.wb-icon"); + if (iconSpan) { + this._createIcon(tree.iconMap, nodeElem, iconSpan, !expanderSpan); + } + } + // Adjust column width + if (opts.resizeCols !== false && !this.isColspan()) { + const colElems = rowDiv.querySelectorAll("span.wb-col"); + let idx = 0; + let ofs = 0; + for (const colDef of this.tree.columns) { + const colElem = colElems[idx]; + colElem.style.left = `${ofs}px`; + colElem.style.width = `${colDef._widthPx}px`; + idx++; + ofs += colDef._widthPx; + } + } + } + /* + * Create or update node's markup. + * + * `options.change` defaults to ChangeType.data, which updates the title, + * icon, and status. It also triggers the `render` event, that lets the user + * create or update the content of embeded cell elements. + * + * If only the status or other class-only modifications have changed, + * `options.change` should be set to ChangeType.status instead for best + * efficiency. + * + * Calling `update()` is almost always a better alternative. + * @see {@link WunderbaumNode.update} + */ + _render(options) { + // this.log("render", options); + const opts = Object.assign({ change: ChangeType.data }, options); + if (!this._rowElem) { + opts.change = ChangeType.row; + } + switch (opts.change) { + case "status": + this._render_status(opts); + break; + case "data": + this._render_data(opts); + break; + case "row": + // _rowElem is not yet created (asserted in _render_markup) + this._render_markup(opts); + break; + default: + error(`Invalid change type '${opts.change}'.`); + } + } + /** + * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad + * event is triggered on next expand. + */ + resetLazy() { + this.removeChildren(); + this.expanded = false; + this.lazy = true; + this.children = null; + this.tree.update(ChangeType.structure); + } + /** Convert node (or whole branch) into a plain object. + * + * The result is compatible with node.addChildren(). + * + * @param include child nodes + * @param callback(dict, node) is called for every node, in order to allow + * modifications. + * Return `false` to ignore this node or `"skip"` to include this node + * without its children. + * @see {@link Wunderbaum.toDictArray}. + */ + toDict(recursive = false, callback) { + const dict = {}; + NODE_DICT_PROPS.forEach((propName) => { + const val = this[propName]; + if (val instanceof Set) { + // Convert Set to string (or skip if set is empty) + val.size + ? (dict[propName] = Array.prototype.join.call(val.keys(), " ")) + : 0; + } + else if (val || val === false || val === 0) { + dict[propName] = val; + } + }); + if (!isEmptyObject(this.data)) { + dict.data = extend({}, this.data); + if (isEmptyObject(dict.data)) { + delete dict.data; + } + } + if (callback) { + const res = callback(dict, this); + if (res === false) { + // Note: a return value of `false` is only used internally + return false; // Don't include this node nor its children + } + if (res === "skip") { + recursive = false; // Include this node, but not the children + } + } + if (recursive) { + if (isArray(this.children)) { + dict.children = []; + for (let i = 0, l = this.children.length; i < l; i++) { + const node = this.children[i]; + if (!node.isStatusNode()) { + // Note: a return value of `false` is only used internally + const res = node.toDict(true, callback); + if (res !== false) { + dict.children.push(res); + } + } + } + } + } + return dict; + } + /** Return an option value that has a default, but may be overridden by a + * callback or a node instance attribute. + * + * Evaluation sequence: + * + * - If `tree.options.` is a callback that returns something, use that. + * - Else if `node.` is defined, use that. + * - Else if `tree.types[]` is a value, use that. + * - Else if `tree.options.` is a value, use that. + * - Else use `defaultValue`. + * + * @param name name of the option property (on node and tree) + * @param defaultValue return this if nothing else matched + * {@link Wunderbaum.getOption|Wunderbaum.getOption()} + */ + getOption(name, defaultValue) { + const tree = this.tree; + let opts = tree.options; + // Lookup `name` in options dict + if (name.indexOf(".") >= 0) { + [opts, name] = name.split("."); + } + const value = opts[name]; // ?? defaultValue; + // A callback resolver always takes precedence + if (typeof value === "function") { + const res = value.call(tree, { + type: "resolve", + tree: tree, + node: this, + // typeInfo: this.type ? tree.types[this.type] : {}, + }); + if (res !== undefined) { + return res; + } + } + // If this node has an explicit local setting, use it: + if (this[name] !== undefined) { + return this[name]; + } + // Use value from type definition if defined + const typeInfo = this.type ? tree.types[this.type] : undefined; + const res = typeInfo ? typeInfo[name] : undefined; + if (res !== undefined) { + return res; + } + // Use value from value options dict, fallback do default + return value !== null && value !== void 0 ? value : defaultValue; + } + /** Make sure that this node is visible in the viewport. + * @see {@link Wunderbaum.scrollTo|Wunderbaum.scrollTo()} + */ + async scrollIntoView(options) { + const opts = Object.assign({ node: this }, options); + return this.tree.scrollTo(opts); + } + /** + * Activate this node, deactivate previous, send events, activate column and + * scroll into viewport. + */ + async setActive(flag = true, options) { + const tree = this.tree; + const prev = tree.getActiveNode(); + const retrigger = options === null || options === void 0 ? void 0 : options.retrigger; // Default: false + const focusTree = options === null || options === void 0 ? void 0 : options.focusTree; // Default: false + // const focusNode = options?.focusNode !== false; // Default: true + const noEvents = options === null || options === void 0 ? void 0 : options.noEvents; // Default: false + const orgEvent = options === null || options === void 0 ? void 0 : options.event; // Default: null + const colIdx = options === null || options === void 0 ? void 0 : options.colIdx; // Default: null + const edit = options === null || options === void 0 ? void 0 : options.edit; // Default: false + assert(!colIdx || tree.isCellNav(), "colIdx requires cellNav"); + assert(!edit || colIdx != null, "edit requires colIdx"); + if (!noEvents) { + if (flag) { + if (prev !== this || retrigger) { + if ((prev === null || prev === void 0 ? void 0 : prev._callEvent("deactivate", { + nextNode: this, + event: orgEvent, + })) === false || + this._callEvent("beforeActivate", { + prevNode: prev, + event: orgEvent, + }) === false) { + return; + } + tree._setActiveNode(null); + prev === null || prev === void 0 ? void 0 : prev.update(ChangeType.status); + } + } + else if (prev === this || retrigger) { + this._callEvent("deactivate", { nextNode: null, event: orgEvent }); + } + } + if (prev !== this) { + if (flag) { + tree._setActiveNode(this); + } + prev === null || prev === void 0 ? void 0 : prev.update(ChangeType.status); + this.update(ChangeType.status); + } + return this.makeVisible().then(() => { + if (flag) { + if (focusTree || edit) { + tree.setFocus(); + tree._setFocusNode(this); + tree.focusNode.setFocus(); + } + // if (focusNode || edit) { + // tree.focusNode = this; + // tree.focusNode.setFocus(); + // } + if (colIdx != null && tree.isCellNav()) { + tree.setColumn(colIdx, { edit: edit }); + } + if (!noEvents) { + this._callEvent("activate", { prevNode: prev, event: orgEvent }); + } + } + }); + } + /** + * Expand or collapse this node. + */ + async setExpanded(flag = true, options) { + const { force, scrollIntoView, immediate } = options !== null && options !== void 0 ? options : {}; + const sendEvents = !(options === null || options === void 0 ? void 0 : options.noEvents); // Default: send events + if (!flag && + this.isExpanded() && + this.getLevel() <= this.tree.getOption("minExpandLevel") && + !force) { + this.logDebug("Ignored collapse request below minExpandLevel."); + return; + } + if (!flag === !this.expanded) { + return; // Nothing to do + } + if (sendEvents && + this._callEvent("beforeExpand", { flag: flag }) === false) { + return; + } + // this.log("setExpanded()"); + if (flag && this.getOption("autoCollapse")) { + this.collapseSiblings(options); + } + if (flag && this.lazy && this.children == null) { + await this.loadLazy(); + } + this.expanded = flag; + const updateOpts = { immediate: immediate }; + // const updateOpts = { immediate: !!util.getOption(options, "immediate") }; + this.tree.update(ChangeType.structure, updateOpts); + if (flag && scrollIntoView) { + const lastChild = this.getLastChild(); + if (lastChild) { + this.tree.updatePendingModifications(); + lastChild.scrollIntoView({ topNode: this }); + } + } + if (sendEvents) { + this._callEvent("expand", { flag: flag }); + } + } + /** + * Set keyboard focus here. + * @see {@link setActive} + */ + setFocus(flag = true) { + assert(!!flag, "Blur is not yet implemented"); + const prev = this.tree.focusNode; + this.tree._setFocusNode(this); + prev === null || prev === void 0 ? void 0 : prev.update(); + this.update(); + } + /** Set a new icon path or class. */ + setIcon(icon) { + this.icon = icon; + this.update(); + } + /** Change node's {@link key} and/or {@link refKey}. */ + setKey(key, refKey) { + throw new Error("Not yet implemented"); + } + /** + * Trigger a repaint, typically after a status or data change. + * + * `change` defaults to 'data', which handles modifcations of title, icon, + * and column content. It can be reduced to 'ChangeType.status' if only + * active/focus/selected state has changed. + * + * This method will eventually call {@link WunderbaumNode._render()} with + * default options, but may be more consistent with the tree's + * {@link Wunderbaum.update()} API. + */ + update(change = ChangeType.data) { + assert(change === ChangeType.status || change === ChangeType.data, `Invalid change type ${change}`); + this.tree.update(change, this); + } + /** + * Return an array of selected nodes. + * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier') + */ + getSelectedNodes(stopOnParents = false) { + const nodeList = []; + this.visit((node) => { + if (node.selected) { + nodeList.push(node); + if (stopOnParents === true) { + return "skip"; // stop processing this branch + } + } + }); + return nodeList; + } + /** Toggle the check/uncheck state. */ + toggleSelected(options) { + let flag = this.isSelected(); + if (flag === undefined && !this.isRadio()) { + flag = this._anySelectable(); + } + else { + flag = !flag; + } + return this.setSelected(flag, options); + } + /** Return true if at least on selectable descendant end-node is unselected. @internal */ + _anySelectable() { + let found = false; + this.visit((node) => { + if (node.selected === false && + !node.unselectable && + !node.hasChildren() && + !node.parent.radiogroup) { + found = true; + return false; // Stop iteration + } + }); + return found; + } + /* Apply selection state to a single node. */ + _changeSelectStatusProps(state) { + let changed = false; + switch (state) { + case false: + changed = this.selected || this._partsel; + this.selected = false; + this._partsel = false; + break; + case true: + changed = !this.selected || !this._partsel; + this.selected = true; + this._partsel = true; + break; + case undefined: + changed = this.selected || !this._partsel; + this.selected = false; + this._partsel = true; + break; + default: + error(`Invalid state: ${state}`); + } + if (changed) { + this.update(); + } + return changed; + } + /** + * Fix selection status, after this node was (de)selected in `selectMode: 'hier'`. + * This includes (de)selecting all descendants. + */ + fixSelection3AfterClick(opts) { + const force = !!(opts === null || opts === void 0 ? void 0 : opts.force); + const flag = this.isSelected(); + this.visit((node) => { + if (node.radiogroup) { + return "skip"; // Don't (de)select this branch + } + if (force || !node.getOption("unselectable")) { + node._changeSelectStatusProps(flag); + } + }); + this.fixSelection3FromEndNodes(); + } + /** + * Fix selection status for multi-hier mode. + * Only end-nodes are considered to update the descendants branch and parents. + * Should be called after this node has loaded new children or after + * children have been modified using the API. + */ + fixSelection3FromEndNodes(opts) { + const force = !!(opts === null || opts === void 0 ? void 0 : opts.force); + assert(this.tree.options.selectMode === "hier", "expected selectMode 'hier'"); + // Visit all end nodes and adjust their parent's `selected` and `_partsel` + // attributes. Return selection state true, false, or undefined. + const _walk = (node) => { + let state; + const children = node.children; + if (children && children.length) { + // check all children recursively + let allSelected = true; + let someSelected = false; + for (let i = 0, l = children.length; i < l; i++) { + const child = children[i]; + // the selection state of a node is not relevant; we need the end-nodes + const s = _walk(child); + if (s !== false) { + someSelected = true; + } + if (s !== true) { + allSelected = false; + } + } + state = allSelected ? true : someSelected ? undefined : false; + } + else { + // This is an end-node: simply report the status + state = !!node.selected; + } + // #939: Keep a `_partsel` flag that was explicitly set on a lazy node + if (node._partsel && + !node.selected && + node.lazy && + node.children == null) { + state = undefined; + } + if (force || !node.getOption("unselectable")) { + node._changeSelectStatusProps(state); + } + return state; + }; + _walk(this); + // Update parent's state + this.visitParents((node) => { + let state; + const children = node.children; + let allSelected = true; + let someSelected = false; + for (let i = 0, l = children.length; i < l; i++) { + const child = children[i]; + state = !!child.selected; + // When fixing the parents, we trust the sibling status (i.e. we don't recurse) + if (state || child._partsel) { + someSelected = true; + } + if (!state) { + allSelected = false; + } + } + state = allSelected ? true : someSelected ? undefined : false; + node._changeSelectStatusProps(state); + }); + } + /** Modify the check/uncheck state. */ + setSelected(flag = true, options) { + const tree = this.tree; + const sendEvents = !(options === null || options === void 0 ? void 0 : options.noEvents); // Default: send events + const prev = this.isSelected(); + const isRadio = this.parent && this.parent.radiogroup; + const selectMode = tree.options.selectMode; + const canSelect = (options === null || options === void 0 ? void 0 : options.force) || !this.getOption("unselectable"); + flag = !!flag; + // this.logDebug(`setSelected(${flag})`, this); + if (!canSelect) { + return prev; + } + if ((options === null || options === void 0 ? void 0 : options.propagateDown) && selectMode === "multi") { + tree.runWithDeferredUpdate(() => { + this.visit((node) => { + node.setSelected(flag); + }); + }); + return prev; + } + if (flag === prev || + (sendEvents && this._callEvent("beforeSelect", { flag: flag }) === false)) { + return prev; + } + tree.runWithDeferredUpdate(() => { + if (isRadio) { + // Radiobutton Group + if (!flag && !(options === null || options === void 0 ? void 0 : options.force)) { + return prev; // don't uncheck radio buttons + } + for (const sibling of this.parent.children) { + sibling.selected = sibling === this; + } + } + else { + this.selected = flag; + if (selectMode === "hier") { + this.fixSelection3AfterClick(); + } + else if (selectMode === "single") { + tree.visit((n) => { + n.selected = false; + }); + } + } + }); + if (sendEvents) { + this._callEvent("select", { flag: flag }); + } + return prev; + } + /** Display node status (ok, loading, error, noData) using styles and a dummy child node. */ + setStatus(status, options) { + const tree = this.tree; + const message = options === null || options === void 0 ? void 0 : options.message; + const details = options === null || options === void 0 ? void 0 : options.details; + let statusNode = null; + const _clearStatusNode = () => { + // Remove dedicated dummy node, if any + const children = this.children; + if (children && children.length && children[0].isStatusNode()) { + children[0].remove(); + } + }; + const _setStatusNode = (data) => { + // Create/modify the dedicated dummy node for 'loading...' or + // 'error!' status. (only called for direct child of the invisible + // system root) + const children = this.children; + const firstChild = children ? children[0] : null; + assert(data.statusNodeType, "Not a status node"); + assert(!firstChild || !firstChild.isStatusNode(), "Child must not be a status node"); + statusNode = this.addNode(data, "prependChild"); + statusNode.match = true; + tree.update(ChangeType.structure); + return statusNode; + }; + _clearStatusNode(); + switch (status) { + case "ok": + this._isLoading = false; + this._errorInfo = null; + break; + case "loading": + this._isLoading = true; + this._errorInfo = null; + if (this.parent) { + this.update(ChangeType.status); + } + else { + // If this is the invisible root, add a visible top-level node + _setStatusNode({ + statusNodeType: status, + title: tree.options.strings.loading + + (message ? " (" + message + ")" : ""), + checkbox: false, + colspan: true, + tooltip: details, + }); + } + // this.update(); + break; + case "error": + _setStatusNode({ + statusNodeType: status, + title: tree.options.strings.loadError + + (message ? " (" + message + ")" : ""), + checkbox: false, + colspan: true, + // classes: "wb-center", + tooltip: details, + }); + this._isLoading = false; + this._errorInfo = { message: message, details: details }; + break; + case "noData": + _setStatusNode({ + statusNodeType: status, + title: message || tree.options.strings.noData, + checkbox: false, + colspan: true, + tooltip: details, + }); + this._isLoading = false; + this._errorInfo = null; + break; + default: + error("invalid node status " + status); + } + tree.update(ChangeType.structure); + return statusNode; + } + /** Rename this node. */ + setTitle(title) { + this.title = title; + this.update(); + // this.triggerModify("rename"); // TODO + } + _sortChildren(cmp, deep) { + const cl = this.children; + if (!cl) { + return; + } + cl.sort(cmp); + if (deep) { + for (let i = 0, l = cl.length; i < l; i++) { + if (cl[i].children) { + cl[i]._sortChildren(cmp, deep); + } + } + } + } + /** + * Sort child list by title or custom criteria. + * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1 + * (defaults to sorting by title). + * @param {boolean} deep pass true to sort all descendant nodes recursively + */ + sortChildren(cmp = nodeTitleSorter, deep = false) { + this._sortChildren(cmp || nodeTitleSorter, deep); + this.tree.update(ChangeType.structure); + // this.triggerModify("sort"); // TODO + } + /** + * Trigger `modifyChild` event on a parent to signal that a child was modified. + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + */ + triggerModifyChild(operation, child, extra) { + this.logDebug(`modifyChild(${operation})`, extra, child); + if (!this.tree.options.modifyChild) { + return; + } + if (child && child.parent !== this) { + error("child " + child + " is not a child of " + this); + } + this._callEvent("modifyChild", extend({ operation: operation, child: child }, extra)); + } + /** + * Trigger `modifyChild` event on node.parent(!). + * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ... + * @param {object} [extra] + */ + triggerModify(operation, extra) { + // if (!this.parent) { + // return; + // } + this.parent.triggerModifyChild(operation, this, extra); + } + /** + * Call `callback(node)` for all descendant nodes in hierarchical order (depth-first, pre-order). + * + * Stop iteration, if fn() returns false. Skip current branch, if fn() + * returns "skip".
    + * Return false if iteration was stopped. + * + * @param {function} callback the callback function. + * Return false to stop iteration, return "skip" to skip this node and + * its children only. + * @see {@link IterableIterator}, {@link Wunderbaum.visit}. + */ + visit(callback, includeSelf = false) { + let res = true; + const children = this.children; + if (includeSelf === true) { + res = callback(this); + if (res === false || res === "skip") { + return res; + } + } + if (children) { + for (let i = 0, l = children.length; i < l; i++) { + res = children[i].visit(callback, true); + if (res === false) { + break; + } + } + } + return res; + } + /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.
    + * Stop iteration, if callback() returns false.
    + * Return false if iteration was stopped. + * + * @param callback the callback function. Return false to stop iteration + */ + visitParents(callback, includeSelf = false) { + if (includeSelf && callback(this) === false) { + return false; + } + let p = this.parent; + while (p) { + if (callback(p) === false) { + return false; + } + p = p.parent; + } + return true; + } + /** + * Call fn(node) for all sibling nodes.
    + * Stop iteration, if fn() returns false.
    + * Return false if iteration was stopped. + * + * @param {function} fn the callback function. + * Return false to stop iteration. + */ + visitSiblings(callback, includeSelf = false) { + const ac = this.parent.children; + for (let i = 0, l = ac.length; i < l; i++) { + const n = ac[i]; + if (includeSelf || n !== this) { + if (callback(n) === false) { + return false; + } + } + } + return true; + } + /** + * [ext-filter] Return true if this node is matched by current filter (or no filter is active). + */ + isMatched() { + return !(this.tree.filterMode && !this.match); + } + } + WunderbaumNode.sequence = 0; + + /*! + * Wunderbaum - ext-edit + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ + // const START_MARKER = "\uFFF7"; + class EditExtension extends WunderbaumExtension { + constructor(tree) { + super(tree, "edit", { + debounce: 100, + minlength: 1, + maxlength: null, + trigger: [], + trim: true, + select: true, + slowClickDelay: 1000, + validity: true, + // --- Events --- + // (note: there is also the `tree.change` event.) + beforeEdit: null, + edit: null, + apply: null, + }); + this.curEditNode = null; + this.relatedNode = null; + this.debouncedOnChange = debounce(this._onChange.bind(this), this.getPluginOption("debounce")); + } + /* + * Call an event handler, while marking the current node cell 'busy'. + * Deal with returned promises and ValidationError. + * Convert a ValidationError into a input.setCustomValidity() call and vice versa. + */ + async _applyChange(eventName, node, colElem, inputElem, extra) { + node.log(`_applyChange(${eventName})`, extra); + colElem.classList.add("wb-busy"); + colElem.classList.remove("wb-error", "wb-invalid"); + inputElem.setCustomValidity(""); + // Call event handler either ('change' or 'edit.appy'), which may return a + // promise or a scalar value or throw a ValidationError. + return new Promise((resolve, reject) => { + const res = node._callEvent(eventName, extra); + // normalize to promise, even if a scalar value was returned and await it + Promise.resolve(res) + .then((res) => { + resolve(res); + }) + .catch((err) => { + reject(err); + }); + }) + .then((res) => { + if (!inputElem.checkValidity()) { + // Native validation failed or handler called 'inputElem.setCustomValidity()' + node.logWarn("inputElem.checkValidity() failed: throwing...."); + throw new ValidationError(inputElem.validationMessage); + } + return res; + }) + .catch((err) => { + if (err instanceof ValidationError) { + node.logWarn("catched ", err); + colElem.classList.add("wb-invalid"); + if (inputElem.setCustomValidity && !inputElem.validationMessage) { + inputElem.setCustomValidity(err.message); + } + if (inputElem.validationMessage) { + inputElem.reportValidity(); + } + // throw err; + } + else { + node.logError(`Error in ${eventName} event handler (throw e.util.ValidationError instead if this was intended)`, err); + colElem.classList.add("wb-error"); + throw err; + } + }) + .finally(() => { + colElem.classList.remove("wb-busy"); + }); + } + /* + * Called for when a control that is embedded in a cell fires a `change` event. + */ + _onChange(e) { + const info = Wunderbaum.getEventInfo(e); + const node = info.node; + const colElem = info.colElem; + if (!node || info.colIdx === 0) { + this.tree.log("Ignored change event for removed element or node title"); + return; + } + // See also WbChangeEventType + this._applyChange("change", node, colElem, e.target, { + info: info, + event: e, + inputElem: e.target, + inputValue: Wunderbaum.util.getValueFromElem(e.target), + inputValid: e.target.checkValidity(), + }); + } + init() { + super.init(); + onEvent(this.tree.element, "change", //"change input", + ".contenteditable,input,textarea,select", + // #61: we must not debounce the `change`, event.target may be reset to null + // when the debounced handler is called. + // (e) => { + // this.debouncedOnChange(e); + // } + (e) => this._onChange(e)); + } + /* Called by ext_keynav to pre-process input. */ + _preprocessKeyEvent(data) { + const event = data.event; + const eventName = eventToString(event); + const tree = this.tree; + const trigger = this.getPluginOption("trigger"); + // const inputElem = + // event.target && event.target.closest("input,[contenteditable]"); + // tree.logDebug(`_preprocessKeyEvent: ${eventName}, editing:${this.isEditingTitle()}`); + // --- Title editing: apply/discard --- + // if (inputElem) { + if (this.isEditingTitle()) { + switch (eventName) { + case "Enter": + this._stopEditTitle(true, { event: event }); + return false; + case "Escape": + this._stopEditTitle(false, { event: event }); + return false; + } + // If the event target is an input element or `contenteditable="true"`, + // we ignore it as navigation command + return false; + } + // --- Trigger title editing + if (tree.isRowNav() || tree.activeColIdx === 0) { + switch (eventName) { + case "Enter": + if (trigger.indexOf("macEnter") >= 0 && isMac) { + this.startEditTitle(); + return false; + } + break; + case "F2": + if (trigger.indexOf("F2") >= 0) { + this.startEditTitle(); + return false; + } + break; + } + return true; + } + return true; + } + /** Return true if a title is currently being edited. */ + isEditingTitle(node) { + return node ? this.curEditNode === node : !!this.curEditNode; + } + /** Start renaming, i.e. replace the title with an embedded ``. */ + startEditTitle(node) { + node = node !== null && node !== void 0 ? node : this.tree.getActiveNode(); + const validity = this.getPluginOption("validity"); + const select = this.getPluginOption("select"); + if (!node) { + return; + } + this.tree.logDebug(`startEditTitle(node=${node})`); + let inputHtml = node._callEvent("edit.beforeEdit"); + if (inputHtml === false) { + node.logDebug("beforeEdit canceled operation."); + return; + } + // `beforeEdit(e)` may return an input HTML string. Otherwise use a default + // (we also treat a `true` return value as 'use default'): + if (inputHtml === true || !inputHtml) { + const title = escapeHtml(node.title); + let opt = this.getPluginOption("maxlength"); + const maxlength = opt ? ` maxlength="${opt}"` : ""; + opt = this.getPluginOption("minlength"); + const minlength = opt ? ` minlength="${opt}"` : ""; + const required = opt > 0 ? " required" : ""; + inputHtml = + ``; + } + const titleSpan = node + .getColElem(0) + .querySelector(".wb-title"); + titleSpan.innerHTML = inputHtml; + const inputElem = titleSpan.firstElementChild; + if (validity) { + // Permanently apply input validations (CSS and tooltip) + inputElem.addEventListener("keydown", (e) => { + inputElem.setCustomValidity(""); + if (!inputElem.reportValidity()) { + node.logWarn(`Invalid input: '${inputElem.value}'`); + } + }); + } + inputElem.focus(); + if (select) { + inputElem.select(); + } + this.curEditNode = node; + node._callEvent("edit.edit", { + inputElem: inputElem, + }); + } + /** + * + * @param apply + * @returns + */ + stopEditTitle(apply) { + return this._stopEditTitle(apply, {}); + } + /* + * + * @param apply + * @param opts.canKeepOpen + */ + _stopEditTitle(apply, options) { + options !== null && options !== void 0 ? options : (options = {}); + const focusElem = document.activeElement; + let newValue = focusElem ? getValueFromElem(focusElem) : null; + const node = this.curEditNode; + const forceClose = !!options.forceClose; + const validity = this.getPluginOption("validity"); + if (newValue && this.getPluginOption("trim")) { + newValue = newValue.trim(); + } + if (!node) { + this.tree.logDebug("stopEditTitle: not in edit mode."); + return; + } + node.logDebug(`stopEditTitle(${apply})`, options, focusElem, newValue); + if (apply && newValue !== null && newValue !== node.title) { + const errMsg = focusElem.validationMessage; + if (errMsg) { + // input element's native validation failed + throw new Error(`Input validation failed for "${newValue}": ${errMsg}.`); + } + const colElem = node.getColElem(0); + this._applyChange("edit.apply", node, colElem, focusElem, { + oldValue: node.title, + newValue: newValue, + inputElem: focusElem, + inputValid: focusElem.checkValidity(), + }).then((value) => { + const errMsg = focusElem.validationMessage; + if (validity && errMsg && value !== false) { + // Handler called 'inputElem.setCustomValidity()' to signal error + throw new Error(`Edit apply validation failed for "${newValue}": ${errMsg}.`); + } + // Discard the embedded `` + // node.logDebug("applyChange:", value, forceClose) + if (!forceClose && value === false) { + // Keep open + return; + } + node === null || node === void 0 ? void 0 : node.setTitle(newValue); + // NOTE: At least on Safari, this render call triggers a scroll event + // probably because the focused input is replaced. + this.curEditNode._render({ preventScroll: true }); + this.curEditNode = null; + this.relatedNode = null; + this.tree.setFocus(); // restore focus that was in the input element + }); + // .catch((err) => { + // node.logError(err); + // }); + // Trigger 'change' event for embedded `` + // focusElem.blur(); + } + else { + // Discard the embedded `` + // NOTE: At least on Safari, this render call triggers a scroll event + // probably because the focused input is replaced. + this.curEditNode._render({ preventScroll: true }); + this.curEditNode = null; + this.relatedNode = null; + // We discarded the , so we have to acquire keyboard focus again + this.tree.setFocus(); + } + } + /** + * Create a new child or sibling node and start edit mode. + */ + createNode(mode = "after", node, init) { + const tree = this.tree; + node = node !== null && node !== void 0 ? node : tree.getActiveNode(); + assert(node, "No node was passed, or no node is currently active."); + // const validity = this.getPluginOption("validity"); + mode = mode || "prependChild"; + if (init == null) { + init = { title: "" }; + } + else if (typeof init === "string") { + init = { title: init }; + } + else { + assert(isPlainObject(init), `Expected a plain object: ${init}`); + } + // Make sure node is expanded (and loaded) in 'child' mode + if ((mode === "prependChild" || mode === "appendChild") && + (node === null || node === void 0 ? void 0 : node.isExpandable(true))) { + node.setExpanded().then(() => { + this.createNode(mode, node, init); + }); + return; + } + const newNode = node.addNode(init, mode); + newNode.setClass("wb-edit-new"); + this.relatedNode = node; + // Don't filter new nodes: + newNode.match = true; + newNode.makeVisible({ noAnimation: true }).then(() => { + this.startEditTitle(newNode); + }); + } + } + + /*! + * wunderbaum.ts + * + * A treegrid control. + * + * Copyright (c) 2021-2023, Martin Wendt (https://wwWendt.de). + * https://github.com/mar10/wunderbaum + * + * Released under the MIT license. + * @version v0.8.2 + * @date Sat, 17 Feb 2024 07:32:06 GMT + */ + // import "./wunderbaum.scss"; + class WbSystemRoot extends WunderbaumNode { + constructor(tree) { + super(tree, null, { + key: "__root__", + title: tree.id, + }); + } + toString() { + return `WbSystemRoot@${this.key}<'${this.tree.id}'>`; + } + } + /** + * A persistent plain object or array. + * + * See also {@link WunderbaumOptions}. + */ + class Wunderbaum { + /** Currently active node if any. + * Use @link {WunderbaumNode.setActive|setActive} to modify. + */ + get activeNode() { + var _a; + // Check for deleted node, i.e. node.tree === null + return ((_a = this._activeNode) === null || _a === void 0 ? void 0 : _a.tree) ? this._activeNode : null; + } + /** Current node hat has keyboard focus if any. + * Use @link {WunderbaumNode.setFocus|setFocus()} to modify. + */ + get focusNode() { + var _a; + // Check for deleted node, i.e. node.tree === null + return ((_a = this._focusNode) === null || _a === void 0 ? void 0 : _a.tree) ? this._focusNode : null; + } + constructor(options) { + this.enabled = true; + /** Contains additional data that was sent as response to an Ajax source load request. */ + this.data = {}; + this.extensionList = []; + this.extensions = {}; + this.keyMap = new Map(); + this.refKeyMap = new Map(); + this.treeRowCount = 0; + this._disableUpdateCount = 0; + this._disableUpdateIgnoreCount = 0; + this._activeNode = null; + this._focusNode = null; + /** Shared properties, referenced by `node.type`. */ + this.types = {}; + /** List of column definitions. */ + this.columns = []; // any[] = []; + this._columnsById = {}; + // Modification Status + this.pendingChangeTypes = new Set(); + /** Expose some useful methods of the util.ts module as `tree._util`. */ + this._util = util; + // --- SELECT --- + // /** @internal */ + // public selectRangeAnchor: WunderbaumNode | null = null; + // --- FILTER --- + this.filterMode = null; + // --- KEYNAV --- + /** @internal Use `setColumn()`/`getActiveColElem()` to access. */ + this.activeColIdx = 0; + /** @internal */ + this._cellNavMode = false; + /** @internal */ + this.lastQuicksearchTime = 0; + /** @internal */ + this.lastQuicksearchTerm = ""; + // --- EDIT --- + this.lastClickTime = 0; + const opts = (this.options = extend({ + id: null, + source: null, + element: null, + debugLevel: DEFAULT_DEBUGLEVEL, + header: null, + // headerHeightPx: ROW_HEIGHT, + rowHeightPx: ROW_HEIGHT, + iconMap: "bootstrap", + columns: null, + types: null, + // escapeTitles: true, + enabled: true, + fixedCol: false, + showSpinner: false, + checkbox: false, + minExpandLevel: 0, + emptyChildListExpandable: false, + // updateThrottleWait: 200, + skeleton: false, + connectTopBreadcrumb: null, + selectMode: "multi", + // --- KeyNav --- + navigationModeOption: null, + quicksearch: true, + // --- Events --- + iconBadge: null, + change: null, + // enhanceTitle: null, + error: null, + receive: null, + // --- Strings --- + strings: { + loadError: "Error", + loading: "Loading...", + // loading: "Loading…", + noData: "No data", + }, + }, options)); + const readyDeferred = new Deferred(); + this.ready = readyDeferred.promise(); + let readyOk = false; + this.ready + .then(() => { + readyOk = true; + try { + this._callEvent("init"); + } + catch (error) { + // We re-raise in the reject handler, but Chrome resets the stack + // frame then, so we log it here: + this.logError("Exception inside `init(e)` event:", error); + } + }) + .catch((err) => { + if (readyOk) { + // Error occurred in `init` handler. We can re-raise, but Chrome + // resets the stack frame. + throw err; + } + else { + // Error in load process + this._callEvent("init", { error: err }); + } + }); + this.id = opts.id || "wb_" + ++Wunderbaum.sequence; + this.root = new WbSystemRoot(this); + this._registerExtension(new KeynavExtension(this)); + this._registerExtension(new EditExtension(this)); + this._registerExtension(new FilterExtension(this)); + this._registerExtension(new DndExtension(this)); + this._registerExtension(new GridExtension(this)); + this._registerExtension(new LoggerExtension(this)); + this._updateViewportThrottled = adaptiveThrottle(this._updateViewportImmediately.bind(this), {}); + // --- Evaluate options + this.columns = opts.columns; + delete opts.columns; + if (!this.columns || !this.columns.length) { + const title = typeof opts.header === "string" ? opts.header : this.id; + this.columns = [{ id: "*", title: title, width: "*" }]; + } + if (opts.types) { + this.setTypes(opts.types, true); + } + delete opts.types; + // --- Create Markup + this.element = elemFromSelector(opts.element); + assert(!!this.element, `Invalid 'element' option: ${opts.element}`); + this.element.classList.add("wunderbaum"); + if (!this.element.getAttribute("tabindex")) { + this.element.tabIndex = 0; + } + // Attach tree instance to
    + this.element._wb_tree = this; + // Create header markup, or take it from the existing html + this.headerElement = this.element.querySelector("div.wb-header"); + const wantHeader = opts.header == null ? this.columns.length > 1 : !!opts.header; + if (this.headerElement) { + // User existing header markup to define `this.columns` + assert(!this.columns, "`opts.columns` must not be set if markup already contains a header"); + this.columns = []; + const rowElement = this.headerElement.querySelector("div.wb-row"); + for (const colDiv of rowElement.querySelectorAll("div")) { + this.columns.push({ + id: colDiv.dataset.id || `col_${this.columns.length}`, + // id: colDiv.dataset.id || null, + title: "" + colDiv.textContent, + // text: "" + colDiv.textContent, + width: "*", // TODO: read from header span + }); + } + } + else { + // We need a row div, the rest will be computed from `this.columns` + const coldivs = "".repeat(this.columns.length); + this.element.innerHTML = ` +
    +
    + ${coldivs} +
    +
    `; + if (!wantHeader) { + const he = this.element.querySelector("div.wb-header"); + he.style.display = "none"; + } + } + // + this.element.innerHTML += ` +
    +
    +
    `; + this.listContainerElement = this.element.querySelector("div.wb-list-container"); + this.nodeListElement = this.listContainerElement.querySelector("div.wb-node-list"); + this.headerElement = this.element.querySelector("div.wb-header"); + this.element.classList.toggle("wb-grid", this.columns.length > 1); + this._initExtensions(); + // --- apply initial options + ["enabled", "fixedCol"].forEach((optName) => { + if (opts[optName] != null) { + this.setOption(optName, opts[optName]); + } + }); + // --- Load initial data + if (opts.source) { + if (opts.showSpinner) { + this.nodeListElement.innerHTML = + "loading..."; + } + this.load(opts.source) + .then(() => { + // The source may have defined columns, so we may adjust the nav mode + if (opts.navigationModeOption == null) { + if (this.isGrid()) { + this.setNavigationOption(NavModeEnum.cell); + } + else { + this.setNavigationOption(NavModeEnum.row); + } + } + else { + this.setNavigationOption(opts.navigationModeOption); + } + this.update(ChangeType.structure, { immediate: true }); + readyDeferred.resolve(); + }) + .catch((error) => { + readyDeferred.reject(error); + }) + .finally(() => { + var _a; + (_a = this.element.querySelector("progress.spinner")) === null || _a === void 0 ? void 0 : _a.remove(); + this.element.classList.remove("wb-initializing"); + }); + } + else { + readyDeferred.resolve(); + } + // Async mode is sometimes required, because this.element.clientWidth + // has a wrong value at start??? + this.update(ChangeType.any); + // --- Bind listeners + this.element.addEventListener("scroll", (e) => { + // this.log(`scroll, scrollTop:${e.target.scrollTop}`, e); + this.update(ChangeType.scroll); + }); + this.resizeObserver = new ResizeObserver((entries) => { + // this.log("ResizeObserver: Size changed", entries); + this.update(ChangeType.resize); + }); + this.resizeObserver.observe(this.element); + onEvent(this.nodeListElement, "click", "div.wb-row", (e) => { + const info = Wunderbaum.getEventInfo(e); + const node = info.node; + const mouseEvent = e; + // this.log("click", info); + // if (this._selectRange(info) === false) { + // return; + // } + if (this._callEvent("click", { event: e, node: node, info: info }) === false) { + this.lastClickTime = Date.now(); + return false; + } + if (node) { + if (mouseEvent.ctrlKey) { + node.toggleSelected(); + return; + } + // Edit title if 'clickActive' is triggered: + const trigger = this.getOption("edit.trigger"); + const slowClickDelay = this.getOption("edit.slowClickDelay"); + if (trigger.indexOf("clickActive") >= 0 && + info.region === "title" && + node.isActive() && + (!slowClickDelay || Date.now() - this.lastClickTime < slowClickDelay)) { + node.startEditTitle(); + } + if (info.colIdx >= 0) { + node.setActive(true, { colIdx: info.colIdx, event: e }); + } + else { + node.setActive(true, { event: e }); + } + if (info.region === NodeRegion.expander) { + node.setExpanded(!node.isExpanded(), { + scrollIntoView: options.scrollIntoViewOnExpandClick !== false, + }); + } + else if (info.region === NodeRegion.checkbox) { + node.toggleSelected(); + } + } + this.lastClickTime = Date.now(); + }); + onEvent(this.nodeListElement, "dblclick", "div.wb-row", (e) => { + const info = Wunderbaum.getEventInfo(e); + const node = info.node; + // this.log("dblclick", info, e); + if (this._callEvent("dblclick", { event: e, node: node, info: info }) === + false) { + return false; + } + if (node && info.colIdx === 0 && node.isExpandable()) { + this._callMethod("edit._stopEditTitle"); + node.setExpanded(!node.isExpanded()); + } + }); + onEvent(this.element, "keydown", (e) => { + const info = Wunderbaum.getEventInfo(e); + const eventName = eventToString(e); + const node = info.node || this.getFocusNode(); + this._callHook("onKeyEvent", { + event: e, + node: node, + info: info, + eventName: eventName, + }); + }); + onEvent(this.element, "focusin focusout", (e) => { + const flag = e.type === "focusin"; + const targetNode = Wunderbaum.getNode(e); + this._callEvent("focus", { flag: flag, event: e }); + if (flag && this.isRowNav() && !this.isEditingTitle()) { + if (opts.navigationModeOption === NavModeEnum.row) { + targetNode === null || targetNode === void 0 ? void 0 : targetNode.setActive(); + } + else { + this.setCellNav(); + } + } + if (!flag) { + this._callMethod("edit._stopEditTitle", true, { + event: e, + forceClose: true, + }); + } + }); + } + /** + * Return a Wunderbaum instance, from element, id, index, or event. + * + * ```js + * getTree(); // Get first Wunderbaum instance on page + * getTree(1); // Get second Wunderbaum instance on page + * getTree(event); // Get tree for this mouse- or keyboard event + * getTree("foo"); // Get tree for this `tree.options.id` + * getTree("#tree"); // Get tree for first matching element selector + * ``` + */ + static getTree(el) { + if (el instanceof Wunderbaum) { + return el; + } + else if (el instanceof WunderbaumNode) { + return el.tree; + } + if (el === undefined) { + el = 0; // get first tree + } + if (typeof el === "number") { + el = document.querySelectorAll(".wunderbaum")[el]; // el was an integer: return nth element + } + else if (typeof el === "string") { + // Search all trees for matching ID + for (const treeElem of document.querySelectorAll(".wunderbaum")) { + const tree = treeElem._wb_tree; + if (tree && tree.id === el) { + return tree; + } + } + // Search by selector + el = document.querySelector(el); + if (!el) { + return null; + } + } + else if (el.target) { + el = el.target; + } + assert(el instanceof Element, `Invalid el type: ${el}`); + if (!el.matches(".wunderbaum")) { + el = el.closest(".wunderbaum"); + } + if (el && el._wb_tree) { + return el._wb_tree; + } + return null; + } + /** + * Return the icon-function -> icon-definition mapping. + */ + get iconMap() { + const map = this.options.iconMap; + if (typeof map === "string") { + return iconMaps[map]; + } + return map; + } + /** + * Return a WunderbaumNode instance from element or event. + */ + static getNode(el) { + if (!el) { + return null; + } + else if (el instanceof WunderbaumNode) { + return el; + } + else if (el.target !== undefined) { + el = el.target; // el was an Event + } + // `el` is a DOM element + // let nodeElem = obj.closest("div.wb-row"); + while (el) { + if (el._wb_node) { + return el._wb_node; + } + el = el.parentElement; //.parentNode; + } + return null; + } + /** + * Iterate all descendant nodes depth-first, pre-order using `for ... of ...` syntax. + * More concise, but slightly slower than {@link Wunderbaum.visit}. + * + * Example: + * ```js + * for(const node of tree) { + * ... + * } + * ``` + */ + *[Symbol.iterator]() { + yield* this.root; + } + /** @internal */ + _registerExtension(extension) { + this.extensionList.push(extension); + this.extensions[extension.id] = extension; + // this.extensionMap.set(extension.id, extension); + } + /** Called on tree (re)init after markup is created, before loading. */ + _initExtensions() { + for (const ext of this.extensionList) { + ext.init(); + } + } + /** Add node to tree's bookkeeping data structures. */ + _registerNode(node) { + const key = node.key; + assert(key != null, `Missing key: '${node}'.`); + assert(!this.keyMap.has(key), `Duplicate key: '${key}': ${node}.`); + this.keyMap.set(key, node); + const rk = node.refKey; + if (rk != null) { + const rks = this.refKeyMap.get(rk); // Set of nodes with this refKey + if (rks) { + rks.add(node); + } + else { + this.refKeyMap.set(rk, new Set([node])); + } + } + } + /** Remove node from tree's bookkeeping data structures. */ + _unregisterNode(node) { + // Remove refKey reference from map (if any) + const rk = node.refKey; + if (rk != null) { + const rks = this.refKeyMap.get(rk); + if (rks && rks.delete(node) && !rks.size) { + // We just removed the last element + this.refKeyMap.delete(rk); + } + } + // Remove key reference from map + this.keyMap.delete(node.key); + // Mark as disposed + node.tree = null; + node.parent = null; + // Remove HTML markup + node.removeMarkup(); + } + /** Call all hook methods of all registered extensions.*/ + _callHook(hook, data = {}) { + let res; + const d = extend({}, { tree: this, options: this.options, result: undefined }, data); + for (const ext of this.extensionList) { + res = ext[hook].call(ext, d); + if (res === false) { + break; + } + if (d.result !== undefined) { + res = d.result; + } + } + return res; + } + /** + * Call tree method or extension method if defined. + * + * Example: + * ```js + * tree._callMethod("edit.startEdit", "arg1", "arg2") + * ``` + */ + _callMethod(name, ...args) { + const [p, n] = name.split("."); + const obj = n ? this.extensions[p] : this; + const func = obj[n]; + if (func) { + return func.apply(obj, args); + } + else { + this.logError(`Calling undefined method '${name}()'.`); + } + } + /** + * Call event handler if defined in tree or tree.EXTENSION options. + * + * Example: + * ```js + * tree._callEvent("edit.beforeEdit", {foo: 42}) + * ``` + */ + _callEvent(type, extra) { + const [p, n] = type.split("."); + const opts = this.options; + const func = n ? opts[p][n] : opts[p]; + if (func) { + return func.call(this, extend({ type: type, tree: this, util: this._util }, extra)); + // } else { + // this.logError(`Triggering undefined event '${type}'.`) + } + } + /** Return the node for given row index. */ + _getNodeByRowIdx(idx) { + // TODO: start searching from active node (reverse) + let node = null; + this.visitRows((n) => { + if (n._rowIdx === idx) { + node = n; + return false; + } + }); + return node; + } + /** Return the topmost visible node in the viewport. */ + getTopmostVpNode(complete = true) { + const gracePx = 1; // ignore subpixel scrolling + const scrollParent = this.element; + // const headerHeight = this.headerElement.clientHeight; // May be 0 + const scrollTop = scrollParent.scrollTop; // + headerHeight; + let topIdx; + if (complete) { + topIdx = Math.ceil((scrollTop - gracePx) / ROW_HEIGHT); + } + else { + topIdx = Math.floor(scrollTop / ROW_HEIGHT); + } + return this._getNodeByRowIdx(topIdx); + } + /** Return the lowest visible node in the viewport. */ + getLowestVpNode(complete = true) { + const scrollParent = this.element; + const headerHeight = this.headerElement.clientHeight; // May be 0 + const scrollTop = scrollParent.scrollTop; + const clientHeight = scrollParent.clientHeight - headerHeight; + let bottomIdx; + if (complete) { + bottomIdx = Math.floor((scrollTop + clientHeight) / ROW_HEIGHT) - 1; + } + else { + bottomIdx = Math.ceil((scrollTop + clientHeight) / ROW_HEIGHT) - 1; + } + bottomIdx = Math.min(bottomIdx, this.count(true) - 1); + return this._getNodeByRowIdx(bottomIdx); + } + /** Return preceeding visible node in the viewport. */ + _getPrevNodeInView(node, ofs = 1) { + this.visitRows((n) => { + node = n; + if (ofs-- <= 0) { + return false; + } + }, { reverse: true, start: node || this.getActiveNode() }); + return node; + } + /** Return following visible node in the viewport. */ + _getNextNodeInView(node, ofs = 1) { + this.visitRows((n) => { + node = n; + if (ofs-- <= 0) { + return false; + } + }, { reverse: false, start: node || this.getActiveNode() }); + return node; + } + /** + * Append (or insert) a list of toplevel nodes. + * + * @see {@link WunderbaumNode.addChildren} + */ + addChildren(nodeData, options) { + return this.root.addChildren(nodeData, options); + } + /** + * Apply a modification or navigation operation. + * + * Most of these commands simply map to a node or tree method. + * This method is especially useful when implementing keyboard mapping, + * context menus, or external buttons. + * + * Valid commands: + * - 'moveUp', 'moveDown' + * - 'indent', 'outdent' + * - 'remove' + * - 'edit', 'addChild', 'addSibling': (reqires ext-edit extension) + * - 'cut', 'copy', 'paste': (use an internal singleton 'clipboard') + * - 'down', 'first', 'last', 'left', 'parent', 'right', 'up': navigate + * + */ + applyCommand(cmd, nodeOrOpts, options) { + let // clipboard, + node, refNode; + // options = $.extend( + // { setActive: true, clipboard: CLIPBOARD }, + // options_ + // ); + if (nodeOrOpts instanceof WunderbaumNode) { + node = nodeOrOpts; + } + else { + node = this.getActiveNode(); + assert(options === undefined, `Unexpected options: ${options}`); + options = nodeOrOpts; + } + // clipboard = options.clipboard; + switch (cmd) { + // Sorting and indentation: + case "moveUp": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "before"); + node.setActive(); + } + break; + case "moveDown": + refNode = node.getNextSibling(); + if (refNode) { + node.moveTo(refNode, "after"); + node.setActive(); + } + break; + case "indent": + refNode = node.getPrevSibling(); + if (refNode) { + node.moveTo(refNode, "appendChild"); + refNode.setExpanded(); + node.setActive(); + } + break; + case "outdent": + if (!node.isTopLevel()) { + node.moveTo(node.getParent(), "after"); + node.setActive(); + } + break; + // Remove: + case "remove": + refNode = node.getPrevSibling() || node.getParent(); + node.remove(); + if (refNode) { + refNode.setActive(); + } + break; + // Add, edit (requires ext-edit): + case "addChild": + this._callMethod("edit.createNode", "prependChild"); + break; + case "addSibling": + this._callMethod("edit.createNode", "after"); + break; + case "rename": + node.startEditTitle(); + break; + // Simple clipboard simulation: + // case "cut": + // clipboard = { mode: cmd, data: node }; + // break; + // case "copy": + // clipboard = { + // mode: cmd, + // data: node.toDict(function(d, n) { + // delete d.key; + // }), + // }; + // break; + // case "clear": + // clipboard = null; + // break; + // case "paste": + // if (clipboard.mode === "cut") { + // // refNode = node.getPrevSibling(); + // clipboard.data.moveTo(node, "child"); + // clipboard.data.setActive(); + // } else if (clipboard.mode === "copy") { + // node.addChildren(clipboard.data).setActive(); + // } + // break; + // Navigation commands: + case "down": + case "first": + case "last": + case "left": + case "pageDown": + case "pageUp": + case "parent": + case "right": + case "up": + return node.navigate(cmd); + default: + error(`Unhandled command: '${cmd}'`); + } + } + /** Delete all nodes. */ + clear() { + this.root.removeChildren(); + this.root.children = null; + this.keyMap.clear(); + this.refKeyMap.clear(); + this.treeRowCount = 0; + this._activeNode = null; + this._focusNode = null; + // this.types = {}; + // this. columns =[]; + // this._columnsById = {}; + // Modification Status + // this.changedSince = 0; + // this.changes.clear(); + // this.changedNodes.clear(); + // // --- FILTER --- + // public filterMode: FilterModeType = null; + // // --- KEYNAV --- + // public activeColIdx = 0; + // public cellNavMode = false; + // public lastQuicksearchTime = 0; + // public lastQuicksearchTerm = ""; + this.update(ChangeType.structure); + } + /** + * Clear nodes and markup and detach events and observers. + * + * This method may be useful to free up resources before re-creating a tree + * on an existing div, for example in unittest suites. + * Note that this Wunderbaum instance becomes unusable afterwards. + */ + destroy() { + this.logInfo("destroy()..."); + this.clear(); + this.resizeObserver.disconnect(); + this.element.innerHTML = ""; + // Remove all event handlers + this.element.outerHTML = this.element.outerHTML; // eslint-disable-line + } + /** + * Return `tree.option.NAME` (also resolving if this is a callback). + * + * See also {@link WunderbaumNode.getOption|WunderbaumNode.getOption()} + * to evaluate `node.NAME` setting and `tree.types[node.type].NAME`. + * + * @param name option name (use dot notation to access extension option, e.g. + * `filter.mode`) + */ + getOption(name, defaultValue) { + let ext; + let opts = this.options; + // Lookup `name` in options dict + if (name.indexOf(".") >= 0) { + [ext, name] = name.split("."); + opts = opts[ext]; + } + let value = opts[name]; + // A callback resolver always takes precedence + if (typeof value === "function") { + value = value({ type: "resolve", tree: this }); + } + // Use value from value options dict, fallback do default + // console.info(name, value, opts) + return value !== null && value !== void 0 ? value : defaultValue; + } + /** + * Set tree option. + * Use dot notation to set plugin option, e.g. "filter.mode". + */ + setOption(name, value) { + // this.log(`setOption(${name}, ${value})`); + if (name.indexOf(".") >= 0) { + const parts = name.split("."); + const ext = this.extensions[parts[0]]; + ext.setPluginOption(parts[1], value); + return; + } + this.options[name] = value; + switch (name) { + case "checkbox": + this.update(ChangeType.any); + break; + case "enabled": + this.setEnabled(!!value); + break; + case "fixedCol": + this.element.classList.toggle("wb-fixed-col", !!value); + break; + } + } + /** Return true if the tree (or one of its nodes) has the input focus. */ + hasFocus() { + return this.element.contains(document.activeElement); + } + /** + * Return true if the tree displays a header. Grids have a header unless the + * `header` option is set to `false`. Plain trees have a header if the `header` + * option is a string or `true`. + */ + hasHeader() { + const header = this.options.header; + return this.isGrid() ? header !== false : !!header; + } + /** Run code, but defer rendering of viewport until done. + * + * ``` + * tree.runWithDeferredUpdate(() => { + * return someFuncThatWouldUpdateManyNodes(); + * }); + * ``` + */ + runWithDeferredUpdate(func, hint = null) { + try { + this.enableUpdate(false); + const res = func(); + assert(!(res instanceof Promise), `Promise return not allowed: ${res}`); + return res; + } + finally { + this.enableUpdate(true); + } + } + /** Recursively expand all expandable nodes (triggers lazy load if needed). */ + async expandAll(flag = true, options) { + await this.root.expandAll(flag, options); + } + /** Recursively select all nodes. */ + selectAll(flag = true) { + return this.root.setSelected(flag, { propagateDown: true }); + } + /** Toggle select all nodes. */ + toggleSelect() { + this.selectAll(this.root._anySelectable()); + } + /** + * Return an array of selected nodes. + * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier') + */ + getSelectedNodes(stopOnParents = false) { + return this.root.getSelectedNodes(stopOnParents); + } + /* + * Return an array of selected nodes. + */ + _selectRange(eventInfo) { + this.logDebug("_selectRange", eventInfo); + error("Not yet implemented."); + // const mode = this.options.selectMode!; + // if (mode !== "multi") { + // this.logDebug(`Range selection only available for selectMode 'multi'`); + // return; + // } + // if (eventInfo.canonicalName === "Meta+click") { + // eventInfo.node?.toggleSelected(); + // return false; // don't + // } else if (eventInfo.canonicalName === "Shift+click") { + // let from = this.activeNode; + // let to = eventInfo.node; + // if (!from || !to || from === to) { + // return; + // } + // this.runWithDeferredUpdate(() => { + // this.visitRows( + // (node) => { + // node.setSelected(); + // }, + // { + // includeHidden: true, + // includeSelf: false, + // start: from, + // reverse: from!._rowIdx! > to!._rowIdx!, + // } + // ); + // }); + // return false; + // } + } + /** Return the number of nodes in the data model. + * @param visible if true, nodes that are hidden due to collapsed parents are ignored. + */ + count(visible = false) { + return visible ? this.treeRowCount : this.keyMap.size; + } + /** @internal sanity check. */ + _check() { + let i = 0; + this.visit((n) => { + i++; + }); + if (this.keyMap.size !== i) { + this.logWarn(`_check failed: ${this.keyMap.size} !== ${i}`); + } + // util.assert(this.keyMap.size === i); + } + /** + * Find all nodes that match condition. + * + * @param match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @see {@link WunderbaumNode.findAll} + */ + findAll(match) { + return this.root.findAll(match); + } + /** + * Find all nodes with a given _refKey_ (aka a list of clones). + * + * @param refKey a `node.refKey` value to search for. + * @returns an array of matching nodes with at least two element or `[]` + * if nothing found. + * + * @see {@link WunderbaumNode.getCloneList} + */ + findByRefKey(refKey) { + const clones = this.refKeyMap.get(refKey); + return clones ? Array.from(clones) : []; + } + /** + * Find first node that matches condition. + * + * @param match title string to search for, or a + * callback function that returns `true` if a node is matched. + * @see {@link WunderbaumNode.findFirst} + */ + findFirst(match) { + return this.root.findFirst(match); + } + /** + * Find first node that matches condition. + * + * @see {@link WunderbaumNode.findFirst} + * + */ + findKey(key) { + return this.keyMap.get(key) || null; + } + /** + * Find the next visible node that starts with `match`, starting at `startNode` + * and wrap-around at the end. + * Used by quicksearch and keyboard navigation. + */ + findNextNode(match, startNode) { + //, visibleOnly) { + let res = null; + const firstNode = this.getFirstChild(); + const matcher = typeof match === "string" ? makeNodeTitleStartMatcher(match) : match; + startNode = startNode || firstNode; + function _checkNode(n) { + // console.log("_check " + n) + if (matcher(n)) { + res = n; + } + if (res || n === startNode) { + return false; + } + } + this.visitRows(_checkNode, { + start: startNode, + includeSelf: false, + }); + // Wrap around search + if (!res && startNode !== firstNode) { + this.visitRows(_checkNode, { + start: firstNode, + includeSelf: true, + }); + } + return res; + } + /** + * Find a node relative to another node. + * + * @param node + * @param where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'. + * (Alternatively the keyCode that would normally trigger this move, + * e.g. `$.ui.keyCode.LEFT` = 'left'. + * @param includeHidden Not yet implemented + */ + findRelatedNode(node, where, includeHidden = false) { + let res = null; + const pageSize = Math.floor(this.listContainerElement.clientHeight / ROW_HEIGHT); + switch (where) { + case "parent": + if (node.parent && node.parent.parent) { + res = node.parent; + } + break; + case "first": + // First visible node + this.visit((n) => { + if (n.isVisible()) { + res = n; + return false; + } + }); + break; + case "last": + this.visit((n) => { + // last visible node + if (n.isVisible()) { + res = n; + } + }); + break; + case "left": + if (node.parent && node.parent.parent) { + res = node.parent; + } + // if (node.expanded) { + // node.setExpanded(false); + // } else if (node.parent && node.parent.parent) { + // res = node.parent; + // } + break; + case "right": + if (node.children && node.children.length) { + res = node.children[0]; + } + // if (this.cellNavMode) { + // throw new Error("Not implemented"); + // } else { + // if (!node.expanded && (node.children || node.lazy)) { + // node.setExpanded(); + // res = node; + // } else if (node.children && node.children.length) { + // res = node.children[0]; + // } + // } + break; + case "up": + res = this._getPrevNodeInView(node); + break; + case "down": + res = this._getNextNodeInView(node); + break; + case "pageDown": + { + const bottomNode = this.getLowestVpNode(); + // this.logDebug(`${where}(${node}) -> ${bottomNode}`); + if (node._rowIdx < bottomNode._rowIdx) { + res = bottomNode; + } + else { + res = this._getNextNodeInView(node, pageSize); + } + } + break; + case "pageUp": + if (node._rowIdx === 0) { + res = node; + } + else { + const topNode = this.getTopmostVpNode(); + // this.logDebug(`${where}(${node}) -> ${topNode}`); + if (node._rowIdx > topNode._rowIdx) { + res = topNode; + } + else { + res = this._getPrevNodeInView(node, pageSize); + } + } + break; + default: + this.logWarn("Unknown relation '" + where + "'."); + } + return res; + } + /** + * Iterator version of {@link Wunderbaum.format}. + */ + *format_iter(name_cb, connectors) { + yield* this.root.format_iter(name_cb, connectors); + } + /** + * Return multiline string representation of the node hierarchy. + * Mostly useful for debugging. + * + * Example: + * ```js + * console.info(tree.format((n)=>n.title)); + * ``` + * logs + * ``` + * Playground + * ├─ Books + * | ├─ Art of War + * | ╰─ Don Quixote + * ├─ Music + * ... + * ``` + * + * @see {@link Wunderbaum.format_iter} and {@link WunderbaumNode.format}. + */ + format(name_cb, connectors) { + return this.root.format(name_cb, connectors); + } + /** + * Return the active cell (`span.wb-col`) of the currently active node or null. + */ + getActiveColElem() { + if (this.activeNode && this.activeColIdx >= 0) { + return this.activeNode.getColElem(this.activeColIdx); + } + return null; + } + /** + * Return the currently active node or null (alias for `tree.activeNode`). + * Alias for {@link Wunderbaum.activeNode}. + * + * @see {@link WunderbaumNode.setActive} + * @see {@link WunderbaumNode.isActive} + * @see {@link Wunderbaum.activeNode} + * @see {@link Wunderbaum.focusNode} + */ + getActiveNode() { + return this.activeNode; + } + /** + * Return the first top level node if any (not the invisible root node). + */ + getFirstChild() { + return this.root.getFirstChild(); + } + /** + * Return the node that currently has keyboard focus or null. + * Alias for {@link Wunderbaum.focusNode}. + * @see {@link WunderbaumNode.setFocus} + * @see {@link WunderbaumNode.hasFocus} + * @see {@link Wunderbaum.activeNode} + * @see {@link Wunderbaum.focusNode} + */ + getFocusNode() { + return this.focusNode; + } + /** Return a {node: WunderbaumNode, region: TYPE} object for a mouse event. + * + * @param {Event} event Mouse event, e.g. click, ... + * @returns {object} Return a {node: WunderbaumNode, region: TYPE} object + * TYPE: 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined + */ + static getEventInfo(event) { + const target = event.target; + const cl = target.classList; + const parentCol = target.closest("span.wb-col"); + const node = Wunderbaum.getNode(target); + const tree = node ? node.tree : Wunderbaum.getTree(event); + const res = { + event: event, + canonicalName: eventToString(event), + tree: tree, + node: node, + region: NodeRegion.unknown, + colDef: undefined, + colIdx: -1, + colId: undefined, + colElem: parentCol, + }; + if (cl.contains("wb-title")) { + res.region = NodeRegion.title; + } + else if (cl.contains("wb-expander")) { + res.region = node.isExpandable() + ? NodeRegion.expander + : NodeRegion.prefix; + } + else if (cl.contains("wb-checkbox")) { + res.region = NodeRegion.checkbox; + } + else if (cl.contains("wb-icon")) { + //|| cl.contains("wb-custom-icon")) { + res.region = NodeRegion.icon; + } + else if (cl.contains("wb-node")) { + res.region = NodeRegion.title; + } + else if (parentCol) { + res.region = NodeRegion.column; + const idx = Array.prototype.indexOf.call(parentCol.parentNode.children, parentCol); + res.colIdx = idx; + } + else if (cl.contains("wb-row")) { + // Plain tree + res.region = NodeRegion.title; + } + else { + // Somewhere near the title + if (event.type !== "mousemove" && !(event instanceof KeyboardEvent)) { + tree === null || tree === void 0 ? void 0 : tree.logWarn("getEventInfo(): not found", event, res); + } + return res; + } + if (res.colIdx === -1) { + res.colIdx = 0; + } + res.colDef = tree === null || tree === void 0 ? void 0 : tree.columns[res.colIdx]; + res.colDef != null ? (res.colId = res.colDef.id) : 0; + // this.log("Event", event, res); + return res; + } + /** + * Return readable string representation for this instance. + * @internal + */ + toString() { + return `Wunderbaum<'${this.id}'>`; + } + /** Return true if any node title or grid cell is currently beeing edited. + * + * See also {@link Wunderbaum.isEditingTitle}. + */ + isEditing() { + const focusElem = this.nodeListElement.querySelector("input:focus,select:focus"); + return !!focusElem; + } + /** Return true if any node is currently in edit-title mode. + * + * See also {@link WunderbaumNode.isEditingTitle} and {@link Wunderbaum.isEditing}. + */ + isEditingTitle() { + return this._callMethod("edit.isEditingTitle"); + } + /** + * Return true if any node is currently beeing loaded, i.e. a Ajax request is pending. + */ + isLoading() { + let res = false; + this.root.visit((n) => { + // also visit rootNode + if (n._isLoading || n._requestId) { + res = true; + return false; + } + }, true); + return res; + } + /** Write to `console.log` with tree name as prefix if opts.debugLevel >= 4. + * @see {@link Wunderbaum.logDebug} + */ + log(...args) { + if (this.options.debugLevel >= 4) { + console.log(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Write to `console.debug` with tree name as prefix if opts.debugLevel >= 4. + * and browser console level includes debug/verbose messages. + * @see {@link Wunderbaum.log} + */ + logDebug(...args) { + if (this.options.debugLevel >= 4) { + console.debug(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Write to `console.error` with tree name as prefix. */ + logError(...args) { + if (this.options.debugLevel >= 1) { + console.error(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** Write to `console.info` with tree name as prefix if opts.debugLevel >= 3. */ + logInfo(...args) { + if (this.options.debugLevel >= 3) { + console.info(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** @internal */ + logTime(label) { + if (this.options.debugLevel >= 4) { + console.time(this + ": " + label); // eslint-disable-line no-console + } + return label; + } + /** @internal */ + logTimeEnd(label) { + if (this.options.debugLevel >= 4) { + console.timeEnd(this + ": " + label); // eslint-disable-line no-console + } + } + /** Write to `console.warn` with tree name as prefix with if opts.debugLevel >= 2. */ + logWarn(...args) { + if (this.options.debugLevel >= 2) { + console.warn(this.toString(), ...args); // eslint-disable-line no-console + } + } + /** + * Make sure that this node is vertically scrolled into the viewport. + * + * Nodes that are above the visible area become the top row, nodes that are + * below the viewport become the bottom row. + */ + scrollTo(nodeOrOpts) { + const PADDING = 2; // leave some pixels between viewport bounds + let node; + let options; + if (nodeOrOpts instanceof WunderbaumNode) { + node = nodeOrOpts; + } + else { + options = nodeOrOpts; + node = options.node; + } + assert(node && node._rowIdx != null, `Invalid node: ${node}`); + const scrollParent = this.element; + const headerHeight = this.headerElement.clientHeight; // May be 0 + const scrollTop = scrollParent.scrollTop; + const vpHeight = scrollParent.clientHeight; + const rowTop = node._rowIdx * ROW_HEIGHT + headerHeight; + const vpTop = headerHeight; + const vpRowTop = rowTop - scrollTop; + const vpRowBottom = vpRowTop + ROW_HEIGHT; + const topNode = options === null || options === void 0 ? void 0 : options.topNode; + // this.log( `scrollTo(${node.title}), vpTop:${vpTop}px, scrollTop:${scrollTop}, vpHeight:${vpHeight}, rowTop:${rowTop}, vpRowTop:${vpRowTop}`, nodeOrOpts , options); + let newScrollTop = null; + if (vpRowTop >= vpTop) { + if (vpRowBottom <= vpHeight) ; + else { + // Node is below viewport + // this.log("Below viewport"); + newScrollTop = rowTop + ROW_HEIGHT - vpHeight + PADDING; // leave some pixels between viewport bounds + } + } + else { + // Node is above viewport + // this.log("Above viewport"); + newScrollTop = rowTop - vpTop - PADDING; // leave some pixels between viewport bounds + } + if (newScrollTop != null) { + this.log(`scrollTo(${rowTop}): ${scrollTop} => ${newScrollTop}`); + scrollParent.scrollTop = newScrollTop; + if (topNode) { + // Make sure the topNode is always visible + this.scrollTo(topNode); + } + // this.update(ChangeType.scroll); + } + } + /** + * Make sure that this node is horizontally scrolled into the viewport. + * Called by {@link setColumn}. + */ + scrollToHorz() { + // const PADDING = 1; + const fixedWidth = this.columns[0]._widthPx; + const vpWidth = this.element.clientWidth; + const scrollLeft = this.element.scrollLeft; + const colElem = this.getActiveColElem(); + const colLeft = Number.parseInt(colElem === null || colElem === void 0 ? void 0 : colElem.style.left, 10); + const colRight = colLeft + Number.parseInt(colElem === null || colElem === void 0 ? void 0 : colElem.style.width, 10); + let newLeft = scrollLeft; + if (colLeft - scrollLeft < fixedWidth) { + // The current column is scrolled behind the left fixed column + newLeft = colLeft - fixedWidth; + } + else if (colRight - scrollLeft > vpWidth) { + // The current column is scrolled outside the right side + newLeft = colRight - vpWidth; + } + newLeft = Math.max(0, newLeft); + // util.assert(node._rowIdx != null); + this.log(`scrollToHorz(${this.activeColIdx}): ${colLeft}..${colRight}, fixedOfs=${fixedWidth}, vpWidth=${vpWidth}, curLeft=${scrollLeft} -> ${newLeft}`); + this.element.scrollLeft = newLeft; + // this.update(ChangeType.scroll); + } + /** + * Set column #colIdx to 'active'. + * + * This higlights the column header and -cells by adding the `wb-active` + * class to all grid cells of the active column.
    + * Available in cell-nav mode only. + * + * If _options.edit_ is true, the embedded input element is focused, or if + * colIdx is 0, the node title is put into edit mode. + */ + setColumn(colIdx, options) { + var _a, _b, _c; + const edit = options === null || options === void 0 ? void 0 : options.edit; + const scroll = (options === null || options === void 0 ? void 0 : options.scrollIntoView) !== false; + assert(this.isCellNav(), "Expected cellNav mode"); + if (typeof colIdx === "string") { + const cid = colIdx; + colIdx = this.columns.findIndex((c) => c.id === colIdx); + assert(colIdx >= 0, `Invalid colId: ${cid}`); + } + assert(0 <= colIdx && colIdx < this.columns.length, `Invalid colIdx: ${colIdx}`); + this.activeColIdx = colIdx; + // Update `wb-active` class for all headers + if (this.hasHeader()) { + for (const rowDiv of this.headerElement.children) { + let i = 0; + for (const colDiv of rowDiv.children) { + colDiv.classList.toggle("wb-active", i++ === colIdx); + } + } + } + (_a = this.activeNode) === null || _a === void 0 ? void 0 : _a.update(ChangeType.status); + // Update `wb-active` class for all cell spans + for (const rowDiv of this.nodeListElement.children) { + let i = 0; + for (const colDiv of rowDiv.children) { + colDiv.classList.toggle("wb-active", i++ === colIdx); + } + } + // Horizontically scroll into view + if (scroll || edit) { + this.scrollToHorz(); + } + if (edit && this.activeNode) { + // this.activeNode.setFocus(); // Blur prev. input if any + if (colIdx === 0) { + this.activeNode.startEditTitle(); + } + else { + (_c = (_b = this.getActiveColElem()) === null || _b === void 0 ? void 0 : _b.querySelector("input,select")) === null || _c === void 0 ? void 0 : _c.focus(); + } + } + } + /* Set or remove keyboard focus to the tree container. @internal */ + _setActiveNode(node) { + this._activeNode = node; + } + /** Set or remove keyboard focus to the tree container. */ + setActiveNode(key, flag = true, options) { + var _a; + (_a = this.findKey(key)) === null || _a === void 0 ? void 0 : _a.setActive(flag, options); + } + /** Set or remove keyboard focus to the tree container. */ + setFocus(flag = true) { + if (flag) { + this.element.focus(); + } + else { + this.element.blur(); + } + } + /* Set or remove keyboard focus to the tree container. @internal */ + _setFocusNode(node) { + this._focusNode = node; + } + update(change, node, options) { + // this.log(`update(${change}) node=${node}`); + if (!(node instanceof WunderbaumNode)) { + options = node; + node = undefined; + } + const immediate = !!getOption(options, "immediate"); + const RF = RenderFlag; + const pending = this.pendingChangeTypes; + if (this._disableUpdateCount) { + // Assuming that we redraw all when enableUpdate() is re-enabled. + // this.log( + // `IGNORED update(${change}) node=${node} (disable level ${this._disableUpdateCount})` + // ); + this._disableUpdateIgnoreCount++; + return; + } + switch (change) { + case ChangeType.any: + case ChangeType.colStructure: + pending.add(RF.header); + pending.add(RF.clearMarkup); + pending.add(RF.redraw); + pending.add(RF.scroll); + break; + case ChangeType.resize: + // case ChangeType.colWidth: + pending.add(RF.header); + pending.add(RF.redraw); + break; + case ChangeType.structure: + pending.add(RF.redraw); + break; + case ChangeType.scroll: + pending.add(RF.scroll); + break; + case ChangeType.row: + case ChangeType.data: + case ChangeType.status: + assert(node, `Option '${change}' requires a node.`); + // Single nodes are immediately updated if already inside the viewport + // (otherwise we can ignore) + if (node._rowElem) { + node._render({ change: change }); + } + break; + default: + error(`Invalid change type '${change}'.`); + } + if (change === ChangeType.colStructure) { + const isGrid = this.isGrid(); + this.element.classList.toggle("wb-grid", isGrid); + if (!isGrid && this.isCellNav()) { + this.setCellNav(false); + } + } + if (pending.size > 0) { + if (immediate) { + this._updateViewportImmediately(); + } + else { + this._updateViewportThrottled(); + } + } + } + /** Disable mouse and keyboard interaction (return prev. state). */ + setEnabled(flag = true) { + const prev = this.enabled; + this.enabled = !!flag; + this.element.classList.toggle("wb-disabled", !flag); + return prev; + } + /** Return false if tree is disabled. */ + isEnabled() { + return this.enabled; + } + /** Return true if tree has more than one column, i.e. has additional data columns. */ + isGrid() { + return this.columns && this.columns.length > 1; + } + /** Return true if cell-navigation mode is active. */ + isCellNav() { + return !!this._cellNavMode; + } + /** Return true if row-navigation mode is active. */ + isRowNav() { + return !this._cellNavMode; + } + /** Set the tree's navigation mode. */ + setCellNav(flag = true) { + var _a; + const prev = this._cellNavMode; + // if (flag === prev) { + // return; + // } + this._cellNavMode = !!flag; + if (flag && !prev) { + // switch from row to cell mode + this.setColumn(0); + } + this.element.classList.toggle("wb-cell-mode", flag); + (_a = this.activeNode) === null || _a === void 0 ? void 0 : _a.update(ChangeType.status); + } + /** Set the tree's navigation mode option. */ + setNavigationOption(mode, reset = false) { + if (!this.isGrid() && mode !== NavModeEnum.row) { + this.logWarn("Plain trees only support row navigation mode."); + return; + } + this.options.navigationModeOption = mode; + switch (mode) { + case NavModeEnum.cell: + this.setCellNav(true); + break; + case NavModeEnum.row: + this.setCellNav(false); + break; + case NavModeEnum.startCell: + if (reset) { + this.setCellNav(true); + } + break; + case NavModeEnum.startRow: + if (reset) { + this.setCellNav(false); + } + break; + default: + error(`Invalid mode '${mode}'.`); + } + } + /** Display tree status (ok, loading, error, noData) using styles and a dummy root node. */ + setStatus(status, options) { + return this.root.setStatus(status, options); + } + /** Add or redefine node type definitions. */ + setTypes(types, replace = true) { + assert(isPlainObject(types), `Expected plain objext: ${types}`); + if (replace) { + this.types = types; + } + else { + extend(this.types, types); + } + // Convert `TYPE.classes` to a Set + for (const t of Object.values(this.types)) { + if (t.classes) { + t.classes = toSet(t.classes); + } + } + } + /** + * Sort nodes list by title or custom criteria. + * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1 + * (defaults to sorting by title). + * @param {boolean} deep pass true to sort all descendant nodes recursively + */ + sortChildren(cmp = nodeTitleSorter, deep = false) { + this.root.sortChildren(cmp, deep); + } + /** Convert tree to an array of plain objects. + * + * @param callback(dict, node) is called for every node, in order to allow + * modifications. + * Return `false` to ignore this node or `"skip"` to include this node + * without its children. + * @see {@link WunderbaumNode.toDict}. + */ + toDictArray(callback) { + var _a; + const res = this.root.toDict(true, callback); + return (_a = res.children) !== null && _a !== void 0 ? _a : []; + } + /** + * Update column headers and column width. + * Return true if at least one column width changed. + */ + // _updateColumnWidths(options?: UpdateColumnsOptions): boolean { + _updateColumnWidths() { + // options = Object.assign({ updateRows: true, renderMarkup: false }, options); + const defaultMinWidth = 4; + const vpWidth = this.element.clientWidth; + // Shorten last column width to avoid h-scrollbar + // (otherwise resizbing the demo would display a void scrollbar?) + const FIX_ADJUST_LAST_COL = 1; + const columns = this.columns; + const col0 = columns[0]; + let totalWidth = 0; + let totalWeight = 0; + let fixedWidth = 0; + let modified = false; + // this.element.classList.toggle("wb-grid", isGrid); + // if (!isGrid && this.isCellNav()) { + // this.setCellNav(false); + // } + // if (options.calculateCols) { + if (col0.id !== "*") { + throw new Error(`First column must have id '*': got '${col0.id}'.`); + } + // Gather width definitions + this._columnsById = {}; + for (const col of columns) { + this._columnsById[col.id] = col; + const cw = col.width; + if (col.id === "*" && col !== col0) { + throw new Error(`Column id '*' must be defined only once: '${col.title}'.`); + } + if (!cw || cw === "*") { + col._weight = 1.0; + totalWeight += 1.0; + } + else if (typeof cw === "number") { + col._weight = cw; + totalWeight += cw; + } + else if (typeof cw === "string" && cw.endsWith("px")) { + col._weight = 0; + const px = parseFloat(cw.slice(0, -2)); + if (col._widthPx != px) { + modified = true; + col._widthPx = px; + } + fixedWidth += px; + } + else { + error(`Invalid column width: ${cw} (expected string ending with 'px' or number, e.g. "px" or ).`); + } + } + // Share remaining space between non-fixed columns + const restPx = Math.max(0, vpWidth - fixedWidth); + let ofsPx = 0; + for (const col of columns) { + let minWidth; + if (col._weight) { + const cmw = col.minWidth; + if (typeof cmw === "number") { + minWidth = cmw; + } + else if (typeof cmw === "string" && cmw.endsWith("px")) { + minWidth = parseFloat(cmw.slice(0, -2)); + } + else { + minWidth = defaultMinWidth; + } + const px = Math.max(minWidth, (restPx * col._weight) / totalWeight); + if (col._widthPx != px) { + modified = true; + col._widthPx = px; + } + } + col._ofsPx = ofsPx; + ofsPx += col._widthPx; + } + columns[columns.length - 1]._widthPx -= FIX_ADJUST_LAST_COL; + totalWidth = ofsPx - FIX_ADJUST_LAST_COL; + const tw = `${totalWidth}px`; + this.headerElement.style.width = tw; + this.listContainerElement.style.width = tw; + // } + // Every column has now a calculated `_ofsPx` and `_widthPx` + // this.logInfo("UC", this.columns, vpWidth, this.element.clientWidth, this.element); + // console.trace(); + // util.error("BREAK"); + // if (modified) { + // this._renderHeaderMarkup(); + // if (options.renderMarkup) { + // this.update(ChangeType.header, { removeMarkup: true }); + // } else if (options.updateRows) { + // this._updateRows(); + // } + // } + return modified; + } + /** Create/update header markup from `this.columns` definition. + * @internal + */ + _renderHeaderMarkup() { + assert(this.headerElement, "Expected a headerElement"); + const wantHeader = this.hasHeader(); + setElemDisplay(this.headerElement, wantHeader); + if (!wantHeader) { + return; + } + const colCount = this.columns.length; + const headerRow = this.headerElement.querySelector(".wb-row"); + assert(headerRow, "Expected a row in header element"); + headerRow.innerHTML = "".repeat(colCount); + for (let i = 0; i < colCount; i++) { + const col = this.columns[i]; + const colElem = headerRow.children[i]; + colElem.style.left = col._ofsPx + "px"; + colElem.style.width = col._widthPx + "px"; + // Add classes from `columns` definition to `` cells + if (typeof col.headerClasses === "string") { + col.headerClasses + ? colElem.classList.add(...col.headerClasses.split(" ")) + : 0; + } + else { + col.classes ? colElem.classList.add(...col.classes.split(" ")) : 0; + } + const title = escapeHtml(col.title || col.id); + let tooltip = ""; + if (col.tooltip) { + tooltip = escapeTooltip(col.tooltip); + tooltip = ` title="${tooltip}"`; + } + let resizer = ""; + if (i < colCount - 1) { + resizer = ''; + } + colElem.innerHTML = `${title}${resizer}`; + if (this.isCellNav()) { + colElem.classList.toggle("wb-active", i === this.activeColIdx); + } + } + } + /** + * Render pending changes that were scheduled using {@link WunderbaumNode.update} if any. + * + * This is hardly ever neccessary, since we normally either + * - call `update(ChangeType.TYPE)` (async, throttled), or + * - call `update(ChangeType.TYPE, {immediate: true})` (synchronous) + * + * `updatePendingModifications()` will only force immediate execution of + * pending async changes if any. + */ + updatePendingModifications() { + if (this.pendingChangeTypes.size > 0) { + this._updateViewportImmediately(); + } + } + /** + * This is the actual update method, which is wrapped inside a throttle method. + * It calls `updateColumns()` and `_updateRows()`. + * + * This protected method should not be called directly but via + * {@link WunderbaumNode.update}`, {@link Wunderbaum.update}, + * or {@link Wunderbaum.updatePendingModifications}. + * @internal + */ + _updateViewportImmediately() { + var _a; + if (this._disableUpdateCount) { + this.log(`_updateViewportImmediately() IGNORED (disable level: ${this._disableUpdateCount}).`); + this._disableUpdateIgnoreCount++; + return; + } + if (this._updateViewportThrottled.pending()) { + // this.logWarn(`_updateViewportImmediately() cancel pending timer.`); + this._updateViewportThrottled.cancel(); + } + // Shorten container height to avoid v-scrollbar + const FIX_ADJUST_HEIGHT = 1; + const RF = RenderFlag; + const pending = new Set(this.pendingChangeTypes); + this.pendingChangeTypes.clear(); + const scrollOnly = pending.has(RF.scroll) && pending.size === 1; + if (scrollOnly) { + this._updateRows({ newNodesOnly: true }); + // this.log("_updateViewportImmediately(): scroll only."); + } + else { + this.log("_updateViewportImmediately():", pending); + if (this.options.adjustHeight !== false) { + let height = this.listContainerElement.clientHeight; + const headerHeight = this.headerElement.clientHeight; // May be 0 + const wantHeight = this.element.clientHeight - headerHeight - FIX_ADJUST_HEIGHT; + if (Math.abs(height - wantHeight) > 1.0) { + // this.log("resize", height, wantHeight); + this.listContainerElement.style.height = wantHeight + "px"; + height = wantHeight; + } + } + // console.profile(`_updateViewportImmediately()`) + if (pending.has(RF.clearMarkup)) { + this.visit((n) => { + n.removeMarkup(); + }); + } + // let widthModified = false; + if (pending.has(RF.header)) { + // widthModified = this._updateColumnWidths(); + this._updateColumnWidths(); + this._renderHeaderMarkup(); + } + this._updateRows(); + // console.profileEnd(`_updateViewportImmediately()`) + } + if (this.options.connectTopBreadcrumb) { + let path = (_a = this.getTopmostVpNode(true)) === null || _a === void 0 ? void 0 : _a.getPath(false, "title", " > "); + path = path ? path + " >" : ""; + this.options.connectTopBreadcrumb.textContent = path; + } + this._callEvent("update"); + } + // /** + // * Assert that TR order matches the natural node order + // * @internal + // */ + // protected _validateRows(): boolean { + // let trs = this.nodeListElement.childNodes; + // let i = 0; + // let prev = -1; + // let ok = true; + // trs.forEach((element) => { + // const tr = element as HTMLTableRowElement; + // const top = Number.parseInt(tr.style.top); + // const n = (tr)._wb_node; + // // if (i < 4) { + // // console.info( + // // `TR#${i}, rowIdx=${n._rowIdx} , top=${top}px: '${n.title}'` + // // ); + // // } + // if (prev >= 0 && top !== prev + ROW_HEIGHT) { + // n.logWarn( + // `TR order mismatch at index ${i}: top=${top}px != ${ + // prev + ROW_HEIGHT + // }` + // ); + // // throw new Error("fault"); + // ok = false; + // } + // prev = top; + // i++; + // }); + // return ok; + // } + /* + * - Traverse all *visible* nodes of the whole tree, i.e. skip collapsed nodes. + * - Store count of rows to `tree.treeRowCount`. + * - Renumber `node._rowIdx` for all visible nodes. + * - Calculate the index range that must be rendered to fill the viewport + * (including upper and lower prefetch) + * - + */ + _updateRows(options) { + // const label = this.logTime("_updateRows"); + // this.log("_updateRows", opts) + options = Object.assign({ newNodesOnly: false }, options); + const newNodesOnly = !!options.newNodesOnly; + const row_height = ROW_HEIGHT; + const vp_height = this.element.clientHeight; + const prefetch = RENDER_MAX_PREFETCH; + // const grace_prefetch = RENDER_MAX_PREFETCH - RENDER_MIN_PREFETCH; + const ofs = this.element.scrollTop; + let startIdx = Math.max(0, ofs / row_height - prefetch); + startIdx = Math.floor(startIdx); + // Make sure start is always even, so the alternating row colors don't + // change when scrolling: + if (startIdx % 2) { + startIdx--; + } + let endIdx = Math.max(0, (ofs + vp_height) / row_height + prefetch); + endIdx = Math.ceil(endIdx); + // this.debug("render", opts); + const obsoleteNodes = new Set(); + this.nodeListElement.childNodes.forEach((elem) => { + const tr = elem; + obsoleteNodes.add(tr._wb_node); + }); + let idx = 0; + let top = 0; + let modified = false; + let prevElem = "first"; + this.visitRows(function (node) { + // node.log("visit") + const rowDiv = node._rowElem; + // Renumber all expanded nodes + if (node._rowIdx !== idx) { + node._rowIdx = idx; + modified = true; + } + if (idx < startIdx || idx > endIdx) { + // row is outside viewport bounds + if (rowDiv) { + prevElem = rowDiv; + } + } + else if (rowDiv && newNodesOnly) { + obsoleteNodes.delete(node); + // no need to update existing node markup + rowDiv.style.top = idx * ROW_HEIGHT + "px"; + prevElem = rowDiv; + } + else { + obsoleteNodes.delete(node); + // Create new markup + if (rowDiv) { + rowDiv.style.top = idx * ROW_HEIGHT + "px"; + } + node._render({ top: top, after: prevElem }); + // node.log("render", top, prevElem, "=>", node._rowElem); + prevElem = node._rowElem; + } + idx++; + top += row_height; + }); + this.treeRowCount = idx; + for (const n of obsoleteNodes) { + n._callEvent("discard"); + n.removeMarkup(); + } + // Resize tree container + this.nodeListElement.style.height = `${top}px`; + // this.log( + // `_updateRows(scrollOfs:${ofs}, ${startIdx}..${endIdx})`, + // this.nodeListElement.style.height + // ); + // this.logTimeEnd(label); + // this._validateRows(); + return modified; + } + /** + * Call `callback(node)` for all nodes in hierarchical order (depth-first, pre-order). + * @see {@link IterableIterator}, {@link WunderbaumNode.visit}. + * + * @param {function} callback the callback function. + * Return false to stop iteration, return "skip" to skip this node and + * children only. + * @returns {boolean} false, if the iterator was stopped. + */ + visit(callback) { + return this.root.visit(callback, false); + } + /** + * Call callback(node) for all nodes in vertical order, top down (or bottom up). + * + * Note that this considers expansion state, i.e. filtered nodes and children + * of collapsed nodes are skipped, unless `includeHidden` is set. + * + * Stop iteration if callback() returns false.
    + * Return false if iteration was stopped. + * + * @returns {boolean} false if iteration was canceled + */ + visitRows(callback, options) { + if (!this.root.hasChildren()) { + return false; + } + if (options && options.reverse) { + delete options.reverse; + return this._visitRowsUp(callback, options); + } + options = options || {}; + let i, nextIdx, parent, res, siblings, stopNode, siblingOfs = 0, skipFirstNode = options.includeSelf === false, node = options.start || this.root.children[0]; + const includeHidden = !!options.includeHidden; + const checkFilter = !includeHidden && this.filterMode === "hide"; + parent = node.parent; + while (parent) { + // visit siblings + siblings = parent.children; + nextIdx = siblings.indexOf(node) + siblingOfs; + assert(nextIdx >= 0, `Could not find ${node} in parent's children: ${parent}`); + for (i = nextIdx; i < siblings.length; i++) { + node = siblings[i]; + if (node === stopNode) { + return false; + } + if (checkFilter && + !node.statusNodeType && + !node.match && + !node.subMatchCount) { + continue; + } + if (!skipFirstNode && callback(node) === false) { + return false; + } + skipFirstNode = false; + // Dive into node's child nodes + if (node.children && + node.children.length && + (includeHidden || node.expanded)) { + res = node.visit((n) => { + if (n === stopNode) { + return false; + } + if (checkFilter && !n.match && !n.subMatchCount) { + return "skip"; + } + if (callback(n) === false) { + return false; + } + if (!includeHidden && n.children && !n.expanded) { + return "skip"; + } + }, false); + if (res === false) { + return false; + } + } + } + // Visit parent nodes (bottom up) + node = parent; + parent = parent.parent; + siblingOfs = 1; // + if (!parent && options.wrap) { + this.logDebug("visitRows(): wrap around"); + assert(options.start, "`wrap` option requires `start`"); + stopNode = options.start; + options.wrap = false; + parent = this.root; + siblingOfs = 0; + } + } + return true; + } + /** + * Call fn(node) for all nodes in vertical order, bottom up. + * @internal + */ + _visitRowsUp(callback, options) { + let children, idx, parent, node = options.start || this.root.children[0]; + const includeHidden = !!options.includeHidden; + if (options.includeSelf !== false) { + if (callback(node) === false) { + return false; + } + } + while (true) { + parent = node.parent; + children = parent.children; + if (children[0] === node) { + // If this is already the first sibling, goto parent + node = parent; + if (!node.parent) { + break; // first node of the tree + } + children = parent.children; + } + else { + // Otherwise, goto prev. sibling + idx = children.indexOf(node); + node = children[idx - 1]; + // If the prev. sibling has children, follow down to last descendant + while ((includeHidden || node.expanded) && + node.children && + node.children.length) { + children = node.children; + parent = node; + node = children[children.length - 1]; + } + } + // Skip invisible + if (!includeHidden && !node.isVisible()) { + continue; + } + if (callback(node) === false) { + return false; + } + } + return true; + } + /** + * Reload the tree with a new source. + * + * Previous data is cleared. Note that also column- and type defintions may + * be passed with the `source` object. + */ + load(source) { + this.clear(); + return this.root.load(source); + } + /** + * Disable render requests during operations that would trigger many updates. + * + * ```js + * try { + * tree.enableUpdate(false); + * // ... (long running operation that would trigger many updates) + * foo(); + * // ... NOTE: make sure that async operations have finished, e.g. + * await foo(); + * } finally { + * tree.enableUpdate(true); + * } + * ``` + */ + enableUpdate(flag) { + /* + 5 7 9 20 25 30 + 1 >-------------------------------------< + 2 >--------------------< + 3 >--------------------------< + */ + if (flag) { + assert(this._disableUpdateCount > 0, "enableUpdate(true) was called too often"); + this._disableUpdateCount--; + // this.logDebug( + // `enableUpdate(${flag}): count -> ${this._disableUpdateCount}...` + // ); + if (this._disableUpdateCount === 0) { + this.logDebug(`enableUpdate(): active again. Re-painting to catch up with ${this._disableUpdateIgnoreCount} ignored update requests...`); + this._disableUpdateIgnoreCount = 0; + this.update(ChangeType.any, { immediate: true }); + } + } + else { + this._disableUpdateCount++; + // this.logDebug( + // `enableUpdate(${flag}): count -> ${this._disableUpdateCount}...` + // ); + // this._disableUpdate = Date.now(); + } + // return !flag; // return previous value + } + /* --------------------------------------------------------------------------- + * FILTER + * -------------------------------------------------------------------------*/ + /** + * Dim or hide nodes. + */ + filterNodes(filter, options) { + return this.extensions.filter.filterNodes(filter, options); + } + /** + * Dim or hide whole branches. + */ + filterBranches(filter, options) { + return this.extensions.filter.filterBranches(filter, options); + } + /** + * Reset the filter. + */ + clearFilter() { + return this.extensions.filter.clearFilter(); + } + /** + * Return true if a filter is currently applied. + */ + isFilterActive() { + return !!this.filterMode; + } + /** + * Re-apply current filter. + */ + updateFilter() { + return this.extensions.filter.updateFilter(); + } + } + Wunderbaum.sequence = 0; + /** Wunderbaum release version number "MAJOR.MINOR.PATCH". */ + Wunderbaum.version = "v0.8.2"; // Set to semver by 'grunt release' + /** Expose some useful methods of the util.ts module as `Wunderbaum.util`. */ + Wunderbaum.util = util; + + exports.Wunderbaum = Wunderbaum; + +})); diff --git a/orochi/static/js/wunderbaum/wunderbaum.umd.min.js b/orochi/static/js/wunderbaum/wunderbaum.umd.min.js new file mode 100644 index 00000000..31185e71 --- /dev/null +++ b/orochi/static/js/wunderbaum/wunderbaum.umd.min.js @@ -0,0 +1,86 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).mar10={})}(this,(function(e){"use strict"; +/*! + * debounce & throttle, taken from https://github.com/lodash/lodash v4.17.21 + * MIT License: https://raw.githubusercontent.com/lodash/lodash/4.17.21-npm/LICENSE + * Modified for TypeScript type annotations. + */const t="object"==typeof global&&null!==global&&global.Object===Object&&global,i="object"==typeof globalThis&&null!==globalThis&&globalThis.Object==Object&&globalThis,s="object"==typeof self&&null!==self&&self.Object===Object&&self,n=i||t||s||Function("return this")();function r(e){const t=typeof e;return null!=e&&("object"===t||"function"===t)}function o(e,t=0,i={}){let s,o,l,a,d,c,h=0,u=!1,p=!1,f=!0;const g=!t&&0!==t&&"function"==typeof n.requestAnimationFrame;if("function"!=typeof e)throw new TypeError("Expected a function");function v(t){const i=s,n=o;return s=o=void 0,h=t,a=e.apply(n,i),a}function m(e,t){return g?(n.cancelAnimationFrame(d),n.requestAnimationFrame(e)):setTimeout(e,t)}function y(e){const i=e-c;return void 0===c||i>=t||i<0||p&&e-h>=l}function b(){const e=Date.now();if(y(e))return w(e);d=m(b,function(e){const i=e-h,s=t-(e-c);return p?Math.min(s,l-i):s}(e))}function w(e){return d=void 0,f&&s?v(e):(s=o=void 0,a)}function E(...e){const i=Date.now(),n=y(i);if(s=e,o=this,c=i,n){if(void 0===d)return function(e){return h=e,d=m(b,t),u?v(e):a}(c);if(p)return d=m(b,t),v(c)}return void 0===d&&(d=m(b,t)),a}return t=+t||0,r(i)&&(u=!!i.leading,p="maxWait"in i,l=p?Math.max(+i.maxWait||0,t):l,f="trailing"in i?!!i.trailing:f),E.cancel=function(){void 0!==d&&function(e){if(g)return n.cancelAnimationFrame(e);clearTimeout(e)}(d),h=0,s=c=o=d=void 0},E.flush=function(){return void 0===d?a:w(Date.now())},E.pending=function(){return void 0!==d},E}function l(e,t=0,i={}){let s=!0,n=!0;if("function"!=typeof e)throw new TypeError("Expected a function");return r(i)&&(s="leading"in i?!!i.leading:s,n="trailing"in i?!!i.trailing:n),o(e,t,{leading:s,trailing:n,maxWait:t})} +/*! + * Wunderbaum - util + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */const a={0:"",1:"left",2:"middle",3:"right",4:"back",5:"forward"},d=function(){const e=navigator;return{isMac:/Mac/.test(e.platform)}}().isMac,c=/[&<>"'/]/g,h=/[<>"'/]/g,u={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};class p extends Error{constructor(e){super(e),this.name="ValidationError"}}function f(e,t){if(!e)throw t=t||"Assertion failed.",new Error(t)}function g(e){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e()}function v(e){throw new Error(e)}function m(e){return(""+e).replace(c,(function(e){return u[e]}))}function y(e){return(""+e).replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}function b(e){return(""+e).replace(h,(function(e){return u[e]}))}function w(e,t=!1){const i=e.tagName;let s=null;if("SPAN"===i&&e.classList.contains("wb-col")){const i=e,n=i.querySelector("input,select");if(n)return w(n,t);i.innerText=""+s}else if("INPUT"===i){const i=e;switch(i.type){case"button":case"reset":case"submit":case"image":break;case"checkbox":s=i.indeterminate?null:i.checked;break;case"date":case"datetime":case"datetime-local":case"month":case"time":case"week":s=t?i.valueAsDate:i.value;break;case"number":case"range":s=i.valueAsNumber;break;case"radio":{const e=i.name,t=i.parentElement.querySelector(`input[name="${e}"]:checked`);s=t?t.value:void 0}break;default:s=i.value}}else if("SELECT"===i){s=e.value}return s}function E(e,t){const i=k(e).style;t?"none"===i.display&&(i.display=""):""===i.display&&(i.display="none")}function _(e){const t=document.createElement("template");return t.innerHTML=e.trim(),t.content.firstElementChild}const x=new Set(["Alt","Control","Meta","Shift"]);function k(e){return e?"string"==typeof e?document.querySelector(e):e:null}function C(e){const t=e.key,i=e.type,s=[];return e.altKey&&s.push("Alt"),e.ctrlKey&&s.push("Control"),e.metaKey&&s.push("Meta"),e.shiftKey&&s.push("Shift"),"click"===i||"dblclick"===i?s.push(a[e.button]+i):"wheel"===i?s.push(i):x.has(t)||s.push(t),s.join("+")}function N(...e){for(let t=1;t{e.addEventListener(t,(function(e){if(!n)return r(e);if(e.target){let t=e.target;if(t.matches(n))return r(e);if(t=t.closest(n),t)return r(e)}}))}))}function I(e,t,i,s){let n,r;const o=s||e,l=e[t],a=(...e)=>l.apply(o,e),d=e=>l.apply(o,e);e[t]=(...e)=>{try{return n=o._super,r=o._superApply,o._super=a,o._superApply=d,i.apply(o,e)}finally{o._super=n,o._superApply=r}}}function M(e,t,i=void 0){let s;e&&t.indexOf(".")>=0&&([s,t]=t.split("."),e=e[s]);const n=e?e[t]:null;return null!=n?n:i}function A(e){if(e instanceof Set)return e;if("string"==typeof e){const t=new Set;for(const i of e.split(" "))t.add(i.trim());return t}if(Array.isArray(e))return new Set(e);throw new Error("Cannot convert to Set: "+e)}function O(e,t){const i=Object.assign({minDelay:16,defaultDelay:200,maxDelay:5e3,delayFactor:2},t),s=Math.max(16,+i.minDelay),n=+i.maxDelay;let r=0,o=null,l=null;const a=(...t)=>{if(r)o=t,r+=1;else{r=1;const d=t;o=null;const c=Date.now();try{e.apply(this,d)}catch(e){console.error(e)}const h=Date.now()-c,u=Math.min(Math.max(s,h*i.delayFactor),n),p=Math.max(s,u-h);l=setTimeout((()=>{l=null,r=0,null!=o&&a.apply(this,o)}),p)}};return a.cancel=()=>{l&&(clearTimeout(l),l=null),o=null,r=0},a.pending=()=>!!l,a.flush=()=>{throw new Error("Not implemented")},a}var $,P,R,F,z,U=Object.freeze({__proto__:null,Deferred:class{constructor(){this.thens=[],this.catches=[],this.status=""}resolve(e){if(this.status)throw new Error("already settled");this.status="resolved",this.resolvedValue=e,this.thens.forEach((t=>t(e))),this.thens=[]}reject(e){if(this.status)throw new Error("already settled");this.status="rejected",this.rejectedError=e,this.catches.forEach((t=>t(e))),this.catches=[]}then(e){"resolved"===status?e(this.resolvedValue):this.thens.unshift(e)}catch(e){"rejected"===this.status?e(this.rejectedError):this.catches.unshift(e)}promise(){return{then:this.then,catch:this.catch}}},MAX_INT:9007199254740991,MOUSE_BUTTONS:a,ValidationError:p,adaptiveThrottle:O,assert:f,debounce:o,documentReady:g,documentReadyPromise:function(){return new Promise((e=>{g(e)}))},each:function(e,t){if(null==e)return e;const i=e.length;let s=0;if("number"==typeof i)for(;s")>=0&&v("Not implemented"),e},getOption:M,getValueFromElem:w,isArray:S,isEmptyObject:D,isFunction:function(e){return"function"==typeof e},isMac:d,isPlainObject:T,noop:function(...e){},onEvent:L,overrideMethod:I,setElemDisplay:E,setTimeoutPromise:function(e,t){return new Promise(((i,s)=>{setTimeout((()=>{try{i(e.apply(this))}catch(e){s(e)}}),t)}))},setValueToElem:function e(t,i){const s=t.tagName;if("SPAN"===s&&t.classList.contains("wb-col")){const s=t,n=s.querySelector("input,select");if(n)return e(n,i);s.innerText=""+i}else if("INPUT"===s){const e=t,s=e.type;switch(s){case"checkbox":e.indeterminate=null===i,e.checked=!!i;break;case"date":case"month":case"time":case"week":case"datetime":case"datetime-local":e.valueAsDate=new Date(i);break;case"number":case"range":null==i?e.value=i:e.valueAsNumber=i;break;case"radio":v(`Not yet implemented: ${s}`);break;case"button":case"reset":case"submit":case"image":break;default:e.value=null!=i?i:""}}else if("SELECT"===s){const e=t;null==i?e.selectedIndex=-1:e.value=i}},sleep:async function(e){return new Promise((t=>setTimeout(t,e)))},throttle:l,toSet:A,toggleCheckbox:function(e,t,i){const s=k(e);if(f("checkbox"===s.type,`Expected a checkbox: ${s.type}`),null!=i||(i=s.classList.contains("wb-tristate")||s.indeterminate),void 0===t){switch(s.indeterminate?null:s.checked){case!0:t=!1;break;case!1:t=!i||null;break;case null:t=!0}}s.indeterminate=null==t,s.checked=!!t},type:function(e){return Object.prototype.toString.call(e).replace(/^\[object (.+)\]$/,"$1").toLowerCase()}}); +/*! + * Wunderbaum - types + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */!function(e){e.any="any",e.data="data",e.colStructure="colStructure",e.resize="resize",e.row="row",e.structure="structure",e.status="status",e.scroll="scroll"}($||($={})),function(e){e.clearMarkup="clearMarkup",e.header="header",e.redraw="redraw",e.scroll="scroll"}(P||(P={})),function(e){e.ok="ok",e.loading="loading",e.error="error",e.noData="noData",e.paging="paging"}(R||(R={})),function(e){e.unknown="",e.checkbox="checkbox",e.column="column",e.expander="expander",e.icon="icon",e.prefix="prefix",e.title="title"}(F||(F={})),function(e){e.startRow="startRow",e.cell="cell",e.startCell="startCell",e.row="row"}(z||(z={})); +/*! + * Wunderbaum - wb_extension_base + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */ +class V{constructor(e,t,i){this.enabled=!0,this.tree=e,this.id=t,this.treeOpts=e.options;const s=e.options;void 0===this.treeOpts[t]?s[t]=this.extensionOpts=N({},i):(this.extensionOpts=N({},i,s[t]),s[t]=this.extensionOpts),this.enabled=this.getPluginOption("enabled",!0)}init(){this.tree.element.classList.add("wb-ext-"+this.id)}getPluginOption(e,t){var i;return null!==(i=this.extensionOpts[e])&&void 0!==i?i:t}setPluginOption(e,t){this.extensionOpts[e]=t}setEnabled(e=!0){return this.setPluginOption("enabled",!!e)}onKeyEvent(e){}onRender(e){}} +/*! + * Wunderbaum - ext-filter + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */const q="￷",j="￸",K=new RegExp(y("￷"),"g"),H=new RegExp(y("￸"),"g");class W extends V{constructor(e){super(e,"filter",{connectInput:null,autoApply:!0,autoExpand:!1,counter:!0,fuzzy:!1,hideExpandedCounter:!0,hideExpanders:!1,highlight:!0,leavesOnly:!1,mode:"dim",noData:!0}),this.lastFilterArgs=null}init(){super.init();const e=this.getPluginOption("connectInput");e&&(this.queryInput=k(e),L(this.queryInput,"input",o((e=>{this.filterNodes(this.queryInput.value.trim(),{})}),700)))}setPluginOption(e,t){if(super.setPluginOption(e,t),"mode"===e)this.tree.filterMode="hide"===t?"hide":"dim",this.tree.updateFilter()}_applyFilterNoUpdate(e,t,i){return this.tree.runWithDeferredUpdate((()=>this._applyFilterImpl(e,t,i)))}_applyFilterImpl(e,t,i){let s,n,r=0;const o=Date.now(),l=this.tree,a=l.options,d=a.autoCollapse,c=N({},a.filter,i),h="hide"===c.mode,u=!!c.leavesOnly&&!t;if("string"==typeof e){if(""===e)return l.logInfo("Passing an empty string as a filter is handled as clearFilter()."),void this.clearFilter();s=c.fuzzy?e.split("").map(y).reduce((function(e,t){return e+"([^"+t+"]*)"+t}),""):y(e);const t=new RegExp(s,"i"),i=new RegExp(y(e),"gi");e=e=>{if(!e.title)return!1;const s=e.title,r=s.match(t);return r&&c.highlight&&(n=c.fuzzy?function(e,t,i=!0){const s=[];for(let e=1;e"+n[e]+""}));return n.join("")} +/*! + * Wunderbaum - ext-keynav + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */(s,r,!0):s.replace(i,(function(e){return q+e+j})),e.titleWithHighlight=m(n).replace(K,"").replace(H,"")),!!r}}return l.filterMode=c.mode,this.lastFilterArgs=arguments,l.element.classList.toggle("wb-ext-filter-hide",!!h),l.element.classList.toggle("wb-ext-filter-dim",!h),l.element.classList.toggle("wb-ext-filter-hide-expanders",!!c.hideExpanders),l.root.subMatchCount=0,l.visit((e=>{delete e.match,delete e.titleWithHighlight,e.subMatchCount=0})),l.setStatus(R.ok),a.autoCollapse=!1,l.visit((i=>{if(u&&null!=i.children)return;let s=e(i);if("skip"===s)return i.visit((function(e){e.match=!1}),!0),"skip";let n=!1;(t||"branch"===s)&&i.parent.match&&(s=!0,n=!0),s&&(r++,i.match=!0,i.visitParents((e=>{e!==i&&(e.subMatchCount+=1),!c.autoExpand||n||e.expanded||(e.setExpanded(!0,{noAnimation:!0,noEvents:!0}),e._filterAutoExpanded=!0)}),!0))})),a.autoCollapse=d,0===r&&c.noData&&h&&("string"==typeof c.noData?l.root.setStatus(R.noData,{message:c.noData}):l.root.setStatus(R.noData)),l.logInfo(`Filter '${s}' found ${r} nodes in ${Date.now()-o} ms.`),r}filterNodes(e,t){return this._applyFilterNoUpdate(e,!1,t)}filterBranches(e,t){return this._applyFilterNoUpdate(e,!0,t)}updateFilter(){var e;const t=this.tree;t.filterMode&&this.lastFilterArgs&&(null===(e=t.options.filter)||void 0===e?void 0:e.autoApply)?this._applyFilterNoUpdate.apply(this,this.lastFilterArgs):t.logWarn("updateFilter(): no filter active.")}clearFilter(){const e=this.tree;e.enableUpdate(!1),e.setStatus(R.ok),delete e.root.match,delete e.root.subMatchCount,e.visit((e=>{delete e.match,delete e.subMatchCount,delete e.titleWithHighlight,e._filterAutoExpanded&&e.expanded&&e.setExpanded(!1,{noAnimation:!0,noEvents:!0}),delete e._filterAutoExpanded})),e.filterMode=null,this.lastFilterArgs=null,e.element.classList.remove("wb-ext-filter-dim","wb-ext-filter-hide"),e.enableUpdate(!0)}}class B extends V{constructor(e){super(e,"keynav",{})}_getEmbeddedInputElem(e){var t;let i=null;if(e&&null!=e.type)i=e;else{const e=null===(t=this.tree.getActiveColElem())||void 0===t?void 0:t.querySelector("input,select");e&&(i=e)}return i}_isCurInputFocused(){var e;return!!(null===(e=this.tree.getActiveColElem())||void 0===e?void 0:e.querySelector("input:focus,select:focus"))}onKeyEvent(e){const t=e.event,i=this.tree,s=e.options,n=!t.ctrlKey||s.autoActivate,r=this._getEmbeddedInputElem(t.target),o=r&&this._isCurInputFocused(),l=s.navigationModeOption;let a,d=C(t),c=e.node,h=!0;if(!i.isEnabled())return!1;if(!1===i._callEvent("keydown",e))return!1;if(!1===i._callMethod("edit._preprocessKeyEvent",e))return!1;if(!c){const e=i.getFocusNode()||i.getActiveNode(),t=i.getFirstChild();if(!e&&t&&"ArrowDown"===d)return t.logInfo("Keydown: activate first node."),void t.setActive();a=e||t,a&&(a.setFocus(),c=i.getFocusNode(),c.logInfo("Keydown: force focus on active node."))}const u=c.isColspan();if(i.isRowNav()){if(o){switch(d){case"Enter":r.blur(),i.setFocus();break;case"Escape":c._render(),i.setFocus()}return}if(s.quicksearch&&1===d.length&&/^\w$/.test(d)&&!r){const e=Date.now();e-i.lastQuicksearchTime>500&&(i.lastQuicksearchTerm=""),i.lastQuicksearchTime=e,i.lastQuicksearchTerm+=d;const s=i.findNextNode(i.lastQuicksearchTerm,i.getActiveNode());return s&&s.setActive(!0,{event:t}),void t.preventDefault()}switch(d){case"Enter":c.isActive()&&(c.isExpanded()?d="Subtract":c.isExpandable(!0)&&(d="Add"));break;case"ArrowLeft":c.expanded&&(d="Subtract");break;case"ArrowRight":if(!c.expanded&&c.isExpandable(!0))d="Add";else if(l===z.startCell||l===z.startRow)return t.preventDefault(),i.setCellNav(),!1}switch(d){case"+":case"Add":c.setExpanded(!0);break;case"-":case"Subtract":c.setExpanded(!1);break;case" ":c.getOption("checkbox")?c.toggleSelected():c.setActive(!0,{event:t});break;case"Enter":c.setActive(!0,{event:t});break;case"ArrowDown":case"ArrowLeft":case"ArrowRight":case"ArrowUp":case"Backspace":case"End":case"Home":case"Control+End":case"Control+Home":case"Meta+ArrowDown":case"Meta+ArrowUp":case"PageDown":case"PageUp":c.navigate(d,{activate:n,event:t});break;default:h=!1}}else{const e=r?r.type||r.tagName:"",s=r&&"checkbox"!==e;if(o){if("Escape"===d)return c.logDebug("Reset focused input on Escape"),r.setCustomValidity(""),c._render(),i.setFocus(),void i.setColumn(i.activeColIdx);if("Enter"!==d)return r&&r.checkValidity&&!r.checkValidity()?(c.logDebug(`Ignored ${d} inside invalid input`),!1):void c.logDebug(`Ignored ${d} inside focused input`)}else if(r&&1===d.length&&s)return r.focus(),r.value="",c.logDebug(`Focus input: ${d}`),!1;switch("Tab"===d?(d="ArrowRight",h=!0):"Shift+Tab"===d&&(d=i.activeColIdx>0?"ArrowLeft":"",h=!0),d){case"+":case"Add":c.setExpanded(!0);break;case"-":case"Subtract":c.setExpanded(!1);break;case" ":0===i.activeColIdx&&c.getOption("checkbox")?(c.toggleSelected(),h=!0):r&&"checkbox"===e&&(r.click(),h=!0);break;case"F2":r&&!o&&s&&(r.focus(),h=!0);break;case"Enter":i.setFocus(),(0===i.activeColIdx||u)&&c.isExpandable()?(c.setExpanded(!c.isExpanded()),h=!0):r&&!o&&s&&(r.focus(),h=!0);break;case"Escape":i.setFocus(),c.log("keynav: focus tree..."),i.isCellNav()&&l!==z.cell&&(c.log("keynav: setCellNav(false)"),i.setCellNav(!1),i.setFocus(),h=!0);break;case"ArrowLeft":i.setFocus(),u&&c.isExpanded()?c.setExpanded(!1):!u&&i.activeColIdx>0?i.setColumn(i.activeColIdx-1):l!==z.cell&&i.setCellNav(!1),h=!0;break;case"ArrowRight":i.setFocus(),u&&!c.isExpanded()?c.setExpanded():!u&&i.activeColIdx0&&i.setColumn(0),h=!0;break;case"End":i.setFocus(),!u&&i.activeColIdx=4){const t=this.ignoreEvents,i=this.prefix;I(e,"callEvent",(function(s,n){if(t.has(s))return e._superApply(arguments);const r=Date.now(),o=e._superApply(arguments);return e.logDebug(`${i}: callEvent('${s}') took ${Date.now()-r} ms.`,arguments[1]),o}))}}onKeyEvent(e){this.tree.logDebug(`${this.prefix}: onKeyEvent()`,e)}} +/*! + * Wunderbaum - common + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */const Q=22,Y=new RegExp(/\.|\//),J={bootstrap:{error:"bi bi-exclamation-triangle",loading:"bi bi-chevron-right wb-busy",noData:"bi bi-question-circle",expanderExpanded:"bi bi-chevron-down",expanderCollapsed:"bi bi-chevron-right",expanderLazy:"bi bi-chevron-right wb-helper-lazy-expander",checkChecked:"bi bi-check-square",checkUnchecked:"bi bi-square",checkUnknown:"bi bi-dash-square-dotted",radioChecked:"bi bi-circle-fill",radioUnchecked:"bi bi-circle",radioUnknown:"bi bi-record-circle",folder:"bi bi-folder2",folderOpen:"bi bi-folder2-open",folderLazy:"bi bi-folder-symlink",doc:"bi bi-file-earmark"},fontawesome6:{error:"fa-solid fa-triangle-exclamation",loading:"fa-solid fa-chevron-right fa-beat",noData:"fa-solid fa-circle-question",expanderExpanded:"fa-solid fa-chevron-down",expanderCollapsed:"fa-solid fa-chevron-right",expanderLazy:"fa-solid fa-chevron-right wb-helper-lazy-expander",checkChecked:"fa-regular fa-square-check",checkUnchecked:"fa-regular fa-square",checkUnknown:"fa-regular fa-square-minus",radioChecked:"fa-solid fa-circle",radioUnchecked:"fa-regular fa-circle",radioUnknown:"fa-regular fa-circle-question",folder:"fa-solid fa-folder-closed",folderOpen:"fa-regular fa-folder-open",folderLazy:"fa-solid fa-folder-plus",doc:"fa-regular fa-file"}},X=new Set(["_format","_keyMap","_positional","_typeList","_valueMap","_version","children","columns","types"]),Z={" ":"toggleSelect","+":"expand",Add:"expand",ArrowDown:"down",ArrowLeft:"left",ArrowRight:"right",ArrowUp:"up",Backspace:"parent","/":"collapseAll",Divide:"collapseAll",End:"lastCol",Home:"firstCol","Control+End":"last","Control+Home":"first","Meta+ArrowDown":"last","Meta+ArrowUp":"first","*":"expandAll",Multiply:"expandAll",PageDown:"pageDown",PageUp:"pageUp","-":"collapse",Subtract:"collapse"};function ee(e){return e instanceof RegExp?function(t){return e.test(t.title)}:(f("string"==typeof e,`Expected a string or RegExp: ${e}`),function(t){return t.title===e})}function te(e,t){const i=e.title.toLowerCase(),s=t.title.toLowerCase();return i===s?0:i>s?1:-1}function ie(e){let{_format:t,_version:i=1,_keyMap:s,_valueMap:n}=e;f(1===i,`Expected file version 1 instead of ${i}`);let r=s,o={};if(r)for(const[e,t]of Object.entries(r))o[t]=e;if(r&&r.t){const e="source._keyMap maps from long to short since v0.7.0. Flip key/value!";console.warn(e),[r,o]=[o,r]}if(null!=e._typeList){const t='source._typeList is deprecated since v0.7.0: use source._valueMap: {"type": [...]} instead.';if(null!=n)throw new Error(t);console.warn(t),n={type:e._typeList},delete e._typeList}"flat"===t&&function(e){var t,i,s;const{_format:n,_keyMap:r={},_positional:o=[],children:l}=e;if("flat"!==n)throw new Error(`Expected source._format: "flat", but got ${n}`);if(o&&o.includes("children"))throw new Error(`source._positional must not include "children": ${o}`);let a=r;if(r.t){const e="source._keyMap maps from long to short since v0.7.0. Flip key/value!";console.warn(e),a={};for(const[e,t]of Object.entries(r))a[t]=e}const d=o.map((e=>a[e])),c=[],h={},u={},p=null!==(t=a.key)&&void 0!==t?t:"key",f=null!==(i=a.children)&&void 0!==i?i:"children";for(const[e,t]of l.entries()){const[i,n,r={}]=t;t[1]=null,null!=t[2]&&(t[2]=null),n.forEach(((e,t)=>{r[d[t]]=e})),u[e]=r;const o=r[p];null!=o&&(h[o]=r);let l=null;if(null===i);else if("number"==typeof i){if(l=u[i],void 0===l)throw new Error(`unflattenSource: Could not find parent node by index: ${i}.`)}else if(l=h[i],void 0===l)throw new Error(`unflattenSource: Could not find parent node by key: ${i}`);l?(null!==(s=l[f])&&void 0!==s||(l[f]=[]),l[f].push(r)):c.push(r)}e.children=c}(e),delete e._format,delete e._version,delete e._keyMap,delete e._valueMap,delete e._positional,(s||n)&&function e(t){for(const i of t)Object.getOwnPropertyNames(i).forEach((e=>{const t=i[e];let r=e;if(s&&null!=o[e]&&(r=o[e],r!==e&&(i[r]=t,delete i[e])),n&&"number"==typeof t&&null!=n[r]){const e=n[r][t];if(null==e)throw new Error(`Expected valueMap[${r}][${t}] entry in [${n[r]}]`);i[r]=e}})),i.children&&e(i.children)}(e.children)} +/*! + * Wunderbaum - ext-dnd + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */const se="application/x-wunderbaum-node";class ne extends V{constructor(e){super(e,"dnd",{autoExpandMS:1500,multiSource:!1,effectAllowed:"all",dropEffectDefault:"move",guessDropEffect:!0,preventForeignNodes:!1,preventLazyParents:!0,preventNonNodes:!1,preventRecursion:!0,preventSameParent:!1,preventVoidMoves:!0,serializeClipboardData:!0,scroll:!0,scrollSensitivity:20,scrollSpeed:5,sourceCopyHook:null,dragStart:null,drag:null,dragEnd:null,dragEnter:null,dragOver:null,dragExpand:null,drop:null,dragLeave:null}),this.srcNode=null,this.lastTargetNode=null,this.lastEnterStamp=0,this.lastAllowedDropRegions=null,this.lastDropEffect=null,this.lastDropRegion=!1,this.currentScrollDir=0,this.applyScrollDirThrottled=l(this._applyScrollDir,50)}init(){super.init();const e=this.tree,t=e.options.dnd;t.dragStart&&L(e.element,"dragstart drag dragend",this.onDragEvent.bind(this)),t.dragEnter&&L(e.element,"dragenter dragover dragleave drop",this.onDropEvent.bind(this))}_leaveNode(){const e=this.lastTargetNode;this.lastEnterStamp=0,e&&(e.setClass("wb-drop-target wb-drop-over wb-drop-after wb-drop-before",!1),this.lastTargetNode=null)}unifyDragover(e){if(!1===e)return!1;if(e instanceof Set)return e.size>0&&e;if(!0===e)return new Set(["over","before","after"]);if("string"==typeof e||S(e))return(e=A(e)).size>0&&e;throw new Error("Unsupported drop region definition: "+e)}_calcDropRegion(e,t){const i=e.offsetY;return!!t&&(3===t.size?i<5.5?"before":i>16.5?"after":"over":1===t.size&&t.has("over")?"over":i>11?"after":"before")}_guessDropEffect(e){var t;const i=this.treeOpts.dnd,s=null!==(t=i.effectAllowed)&&void 0!==t?t:"all",n=["all","copy","copyLink","copyMove"].includes(s),r=["all","link","copyLink","linkMove"].includes(s),o=["all","move","copyMove","linkMove"].includes(s);let l=i.dropEffectDefault;return i.guessDropEffect&&(d?(e.altKey&&n&&(l="copy"),e.metaKey&&o&&(l="move"),e.altKey&&e.metaKey&&r&&(l="link")):(e.ctrlKey&&n&&(l="copy"),e.shiftKey&&o&&(l="move"),e.altKey&&r&&(l="link"))),l}_isVoidDrop(e,t,i){return!(!this.treeOpts.dnd.preventVoidMoves||!t)&&("before"===i&&e===t.getNextSibling()||"after"===i&&e===t.getPrevSibling()||(t===e||t.parent===e))}_applyScrollDir(){if(this.isDragging()&&this.currentScrollDir){const e=this.tree.options.dnd,t=this.tree.element,i=t.scrollTop;this.currentScrollDir<0?t.scrollTop=Math.max(0,i-e.scrollSpeed):this.currentScrollDir>0&&(t.scrollTop=i+e.scrollSpeed)}}_autoScroll(e){const t=this.tree,i=t.options.dnd.scrollSensitivity,s=t.element,n=t.headerElement.clientHeight,r=s.offsetHeight,o=s.scrollTop;return this.currentScrollDir=0,o>0&&e>0&&e<=i+n?this.currentScrollDir=-1:o=r-i&&(this.currentScrollDir=1),this.currentScrollDir&&this.applyScrollDirThrottled(),s.scrollTop-o}isDragging(){return!!this.srcNode}onDragEvent(e){var t;const i=this.treeOpts.dnd,s=pe.getNode(e);if(s){if(["dragstart","dragend"].includes(e.type)&&this.tree.logDebug(`onDragEvent.${e.type} srcNode: ${s}`,e),"dragstart"===e.type){if(e.dataTransfer.effectAllowed=i.effectAllowed,s.isEditingTitle())return s.logDebug("Prevented dragging node in edit mode."),e.preventDefault(),!1;if(!s._callEvent("dnd.dragStart",{event:e}))return e.preventDefault(),!1;const n=s.toDict(!0,(e=>{e._orgKey=e.key,delete e.key}));n._treeId=s.tree.id,i.serializeClipboardData&&("function"==typeof i.serializeClipboardData?e.dataTransfer.setData(se,i.serializeClipboardData(n,s)):e.dataTransfer.setData(se,JSON.stringify(n))),(null===(t=e.dataTransfer)||void 0===t?void 0:t.types.includes("text/plain"))||e.dataTransfer.setData("text/plain",s.title),this.srcNode=s,setTimeout((()=>{s.setClass("wb-drag-source")}),0)}else"drag"===e.type?i.drag&&s._callEvent("dnd.drag",{event:e}):"dragend"===e.type&&(s.setClass("wb-drag-source",!1),this.srcNode=null,this.lastTargetNode&&this._leaveNode(),s._callEvent("dnd.dragEnd",{event:e}));return!0}this.tree.logWarn(`onDragEvent.${e.type}: no node`)}onDropEvent(e){var t;const i=this.srcNode,s=i?i.tree:null,n=pe.getNode(e),r=this.treeOpts.dnd,o=e.dataTransfer,l=this._calcDropRegion(e,this.lastAllowedDropRegions),a=(e,t)=>(e&&this.tree.log(`Prevented drop operation (${t}).`),e);if(n){if(["drop"].includes(e.type)&&this.tree.logDebug(`onDropEvent.${e.type} targetNode: ${n}, ea: ${null==o?void 0:o.effectAllowed}, de: ${null==o?void 0:o.dropEffect}, cy: ${e.offsetY}, r: ${l}, srcNode: ${i}`,e),"dragenter"===e.type){if(this.lastAllowedDropRegions=null,this.lastTargetNode&&this.lastTargetNode!==n&&this._leaveNode(),this.lastTargetNode=n,this.lastEnterStamp=Date.now(),a(n.isStatusNode(),"is status node")||a(r.preventForeignNodes&&n.tree!==s,"preventForeignNodes")||a(r.preventLazyParents&&!n.isLoaded(),"preventLazyParents")||a(r.preventNonNodes&&!i,"preventNonNodes")||a(r.preventRecursion&&(null==i?void 0:i.isAncestorOf(n)),"preventRecursion")||a(r.preventSameParent&&i&&n.parent===i.parent,"preventSameParent")||a(r.preventVoidMoves&&n===i,"preventVoidMoves"))return o.dropEffect="none",!0;o.dropEffect=this._guessDropEffect(e)||"none";let t=n._callEvent("dnd.dragEnter",{event:e,sourceNode:i});return t=this.unifyDragover(t),t?(this.lastAllowedDropRegions=t,this.lastDropEffect=o.dropEffect,n.setClass("wb-drop-target"),e.preventDefault(),!1):(o.dropEffect="none",!0)}if("dragover"===e.type){const t=e.clientY-this.tree.element.offsetTop;this._autoScroll(t),o.dropEffect=this._guessDropEffect(e)||"none",n._callEvent("dnd.dragOver",{event:e,sourceNode:i});const s=this._calcDropRegion(e,this.lastAllowedDropRegions);if(this.lastDropRegion=s,this.lastDropEffect=o.dropEffect,r.autoExpandMS>0&&n.isExpandable(!0)&&!n._isLoading&&Date.now()-this.lastEnterStamp>r.autoExpandMS&&!1!==n._callEvent("dnd.dragExpand",{event:e,sourceNode:i})&&n.setExpanded(),!s||this._isVoidDrop(n,i,s))return;return n.setClass("wb-drop-over","over"===s),n.setClass("wb-drop-before","before"===s),n.setClass("wb-drop-after","after"===s),e.preventDefault(),!1}if("dragleave"===e.type)n._callEvent("dnd.dragLeave",{event:e,sourceNode:i});else if("drop"===e.type){e.stopPropagation(),e.preventDefault(),this._leaveNode();const i=this.lastDropRegion;let s=null===(t=e.dataTransfer)||void 0===t?void 0:t.getData(se);s=s?JSON.parse(s):null;const r=this.srcNode,o=this.lastDropEffect;setTimeout((()=>{n._callEvent("dnd.drop",{event:e,region:i,suggestedDropMode:"over"===i?"appendChild":i,suggestedDropEffect:o,sourceNode:r,sourceNodeData:s})}),10)}return!1}this._leaveNode()}} +/*! + * Wunderbaum - drag_observer + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */class re{constructor(e){if(this.start={x:0,y:0,altKey:!1,ctrlKey:!1,metaKey:!1,shiftKey:!1},this.dragElem=null,this.dragging=!1,this.events=["mousedown","mouseup","mousemove","keydown"],!e.root)throw new Error("Missing `root` option.");this.opts=Object.assign({thresh:5},e),this.root=e.root,this._handler=this.handleEvent.bind(this),this.events.forEach((e=>{this.root.addEventListener(e,this._handler)}))}disconnect(){this.events.forEach((e=>{this.root.removeEventListener(e,this._handler)}))}getDragElem(){return this.dragElem}isDragging(){return this.dragging}stopDrag(e){this.dragging&&this.opts.dragstop&&e&&(e.type="dragstop",this.opts.dragstop(e)),this.dragElem=null,this.dragging=!1}handleEvent(e){const t=e.type,i=this.opts,s={type:e.type,event:e,dragElem:this.dragElem,dx:e.pageX-this.start.x,dy:e.pageY-this.start.y,apply:void 0};switch(t){case"keydown":this.stopDrag(s);break;case"mousedown":if(this.dragElem){this.stopDrag(s);break}if(i.selector){let t=e.target;if(t.matches(i.selector))this.dragElem=t;else{if(t=t.closest(i.selector),!t)break;this.dragElem=t}}this.start.x=e.pageX,this.start.y=e.pageY,this.start.altKey=e.altKey,this.start.ctrlKey=e.ctrlKey,this.start.metaKey=e.metaKey,this.start.shiftKey=e.shiftKey;break;case"mousemove":if(!this.dragElem)break;if(!this.dragging){if(i.thresh){if(s.dx*s.dx+s.dy*s.dythis.tree.element.contains(e.dragElem),drag:e=>this.handleDrag(e),dragstop:e=>this.handleDrag(e)})}init(){super.init()}handleDrag(e){const t=pe.getEventInfo(e.event);this.tree.log(`${e.type}(${e.dx})`,e,t)}} +/*! + * Wunderbaum - deferred + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */class le{constructor(){this._promise=new Promise(((e,t)=>{this._resolve=e,this._reject=t}))}resolve(e){this._resolve(e)}reject(e){this._reject(e)}promise(){return this._promise}then(e){return this._promise.then(e)}catch(e){return this._promise.catch(e)}finally(e){return this._promise.finally(e)}} +/*! + * Wunderbaum - wunderbaum_node + * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license. + * v0.8.2, Sat, 17 Feb 2024 07:32:06 GMT (https://github.com/mar10/wunderbaum) + */const ae=new Set(["checkbox","classes","expanded","icon","iconTooltip","key","lazy","_partsel","radiogroup","refKey","selected","statusNodeType","title","tooltip","type","unselectable"]),de=new Set(ae);de.delete("_partsel"),de.delete("unselectable");class ce{constructor(e,t,i){var s,n;this.refKey=void 0,this.children=null,this.classes=null,this.data={},this._isLoading=!1,this._requestId=0,this._errorInfo=null,this._partsel=!1,this._partload=!1,this.subMatchCount=0,this._rowIdx=0,this._rowElem=void 0,f(!t||t.tree===e,`Invalid parent: ${t}`),f(!i.children,"'children' not allowed here"),this.tree=e,this.parent=t,this.key=""+(null!==(s=i.key)&&void 0!==s?s:++ce.sequence),this.title=""+(null!==(n=i.title)&&void 0!==n?n:"<"+this.key+">"),null!=i.refKey&&(this.refKey=""+i.refKey),null!=i.type&&(this.type=""+i.type),this.expanded=!0===i.expanded,null!=i.icon&&(this.icon=i.icon),this.lazy=!0===i.lazy,null!=i.statusNodeType&&(this.statusNodeType=""+i.statusNodeType),null!=i.colspan&&(this.colspan=!!i.colspan),null!=i.checkbox&&(this.checkbox=!!i.checkbox),null!=i.radiogroup&&(this.radiogroup=!!i.radiogroup),this.selected=!0===i.selected,!0===i.unselectable&&(this.unselectable=!0),i.classes&&this.setClass(i.classes);for(const[e,t]of Object.entries(i))ae.has(e)||(this.data[e]=t);t&&!this.statusNodeType&&e._registerNode(this)}toString(){return`WunderbaumNode@${this.key}<'${this.title}'>`}*[Symbol.iterator](){const e=this.children;if(e)for(let t=0,i=e.length;t=0,`options.before must be a direct child of ${this}`),this.children.splice(e,0,...o)}else this.children=o;i.update($.structure)}finally{i.enableUpdate(!0)}return o[0]}addNode(e,t="appendChild"){switch("over"===t&&(t="appendChild"),t){case"after":return this.parent.addChildren(e,{before:this.getNextSibling()});case"before":return this.parent.addChildren(e,{before:this});case"prependChild":return this.addChildren(e,{before:0});case"appendChild":return this.addChildren(e)}f(!1,`Invalid mode: ${t}`)}applyCommand(e,t){return this.tree.applyCommand(e,this,t)}collapseSiblings(e){for(const t of this.parent.children)t!==this&&t.expanded&&t.setExpanded(!1,e)}setClass(e,t=!0){const i=A(e);if(t)null===this.classes&&(this.classes=new Set),i.forEach((e=>{var i;this.classes.add(e),null===(i=this._rowElem)||void 0===i||i.classList.toggle(e,t)}));else{if(null===this.classes)return;i.forEach((e=>{var i;this.classes.delete(e),null===(i=this._rowElem)||void 0===i||i.classList.toggle(e,t)})),0===this.classes.size&&(this.classes=null)}}startEditTitle(){this.tree._callMethod("edit.startEditTitle",this)}async expandAll(e=!0,t){const i=this.tree,s=this.tree.options.minExpandLevel,{depth:n=99,loadLazy:r,force:o,keepActiveNodeVisible:l=!0}=null!=t?t:{},a={scrollIntoView:!1,force:o,loadLazy:r};const d=i.logTime(`${this}.expandAll(${e})`);try{i.enableUpdate(!1),await async function t(i,n){var l;if(0===n)return;const d=null==n?null:n-1,c=[];return null===(l=i.children)||void 0===l||l.forEach((i=>{if(e)if(!i.expanded&&(i.children||r&&i.lazy)){const e=i.setExpanded(!0,a);c.push(e),e.then((async()=>{await t(i,d)}))}else c.push(t(i,d));else(!s||o||i.getLevel()>s)&&i.setExpanded(!1,a),t(i,d)})),new Promise((e=>{Promise.all(c).then((()=>{e(!0)}))}))}(this,n)}finally{i.enableUpdate(!0),i.logTimeEnd(d)}i.activeNode&&l&&i.activeNode.scrollIntoView()}findAll(e){const t="function"==typeof e?e:ee(e),i=[];return this.visit((e=>{t(e)&&i.push(e)})),i}findDirectChild(e){const t=this.children;if(!t)return null;if("string"==typeof e){for(let i=0,s=t.length;i{if(t(e))return i=e,!1})),i}findRelatedNode(e,t=!1){return this.tree.findRelatedNode(this,e,t)}*format_iter(e,t){function i(e){const t=e.parent.children;return e===t[t.length-1]}null!=t||(t=[" "," | "," ╰─ "," ├─ "]),null!=e||(e=e=>""+e);const s=s=>{const n=[e(s)];n.unshift(t[i(s)?2:3]);let r=s.parent;for(;r&&r!==this;)n.unshift(t[i(r)?0:1]),r=r.parent;return n.join("")};yield e(this);for(const e of this)yield s(e)}format(e,t){const i=[];for(const s of this.format_iter(e,t))i.push(s);return i.join("\n")}getColElem(e){var t;"string"==typeof e&&(e=this.tree.columns.findIndex((t=>t.id===e)));const i=null===(t=this._rowElem)||void 0===t?void 0:t.querySelectorAll("span.wb-col");return i?i[e]:null}getCloneList(e=!1){if(!this.refKey)return[];const t=this.tree.findByRefKey(this.refKey);return e?t:[...t].filter((e=>e!==this))}getFirstChild(){return this.children?this.children[0]:null}getLastChild(){return this.children?this.children[this.children.length-1]:null}getLevel(){let e=0,t=this.parent;for(;t;)e++,t=t.parent;return e}getNextSibling(){const e=this.parent.children,t=e.indexOf(this);return e[t+1]||null}getParent(){return this.parent}getParentList(e=!1,t=!1){const i=[];let s=t?this:this.parent;for(;s;)(e||s.parent)&&i.unshift(s),s=s.parent;return i}getPath(e=!0,t="title",i="/"){let s;const n=[],r="function"==typeof t;return this.visitParents((e=>{e.parent&&(s=r?t(e):e[t],n.unshift(s))}),e),n.join(i)}getPrevSibling(){const e=this.parent.children,t=e.indexOf(this);return e[t-1]||null}hasChildren(){if(this.lazy){if(null==this.children)return;if(0===this.children.length)return!1;if(1===this.children.length&&this.children[0].isStatusNode())return;return!0}return!(!this.children||!this.children.length)}hasClass(e){return!!this.classes&&this.classes.has(e)}isActive(){return this.tree.activeNode===this}isAncestorOf(e){return e&&e.isDescendantOf(this)}isChildOf(e){return e&&this.parent===e}isClone(){return!!this.refKey&&this.tree.findByRefKey(this.refKey).length>1}isColspan(){return!!this.getOption("colspan")}isDescendantOf(e){if(!e||e.tree!==this.tree)return!1;let t=this.parent;for(;t;){if(t===e)return!0;t===t.parent&&v(`Recursive parent link: ${t}`),t=t.parent}return!1}isExpandable(e=!1){return!(e&&this.expanded||!1===this.children)&&(null==this.children?!!this.lazy:0!==this.children.length||!!this.tree.options.emptyChildListExpandable)}isEditingTitle(){return this.tree._callMethod("edit.isEditingTitle",this)}isExpanded(){return!!this.expanded}isFirstSibling(){const e=this.parent;return!e||e.children[0]===this}isLastSibling(){const e=this.parent;return!e||e.children[e.children.length-1]===this}isLazy(){return!!this.lazy}isLoaded(){return!this.lazy||void 0!==this.hasChildren()}isLoading(){return this._isLoading}isPagingNode(){return"paging"===this.statusNodeType}isParentOf(e){return e&&e.parent===this}isPartload(){return!!this._partload}isPartsel(){return!this.selected&&!!this._partsel}isRadio(){return!!this.parent.radiogroup||"radio"===this.getOption("checkbox")}isRendered(){return!!this._rowElem}isRootNode(){return this.tree.root===this}isSelected(){return!!this.selected||!!this._partsel&&void 0}isStatusNode(){return!!this.statusNodeType}isTopLevel(){return this.tree.root===this.parent}isUnloaded(){return void 0===this.hasChildren()}isVisible(){const e="hide"===this.tree.filterMode,t=this.getParentList(!1,!1);if(e&&!this.match&&!this.subMatchCount)return!1;for(let e=0,i=t.length;ei)return void this.logWarn(`Ignored load response #${i} because #${this._requestId} is pending.`);if(this.logDebug(`Received response for load request #${i}`),null===this.parent&&null!==s)return void this.logWarn("Lazy parent node was removed while loading: discarding response.");this.setStatus(R.ok);const r=Date.now();this._loadSourceObject(t),l=Date.now()-r}else{if("function"==typeof e.then){const i=t.logTime(`Resolve thenable ${e}`);e=await Promise.resolve(e),t.logTimeEnd(i)}this._loadSourceObject(e),l=Date.now()-n}}catch(t){throw this.logError("Error during load()",e,t),this._callEvent("error",{error:t}),this.setStatus(R.error,{message:""+t}),t}finally{this._requestId=0,r=Date.now()-n,t.options.debugLevel>=3&&t.logInfo(`Load source took ${r/1e3} seconds (transfer: ${o/1e3}s, processing: ${l/1e3}s)`)}}async loadLazy(e=!1){const t=this.expanded;if(f(this.lazy,"load() requires a lazy node"),e||this.isUnloaded())if(this.isLoading())this.logWarn("loadLazy() called while already loading: ignored.");else{this.isLoaded()&&this.resetLazy(),this.setStatus(R.loading);try{const e=await this._callEvent("lazyLoad");if(!1===e)return void this.setStatus(R.ok);f(S(e)||e&&e.url,"The lazyLoad event must return a node list, `{url: ...}`, or false."),await this.load(e),this.setStatus(R.ok),t?(this.expanded=!0,this.tree.update($.structure)):this.update()}catch(e){this.logError("Error during loadLazy()",e),this._callEvent("error",{error:e}),this.setStatus(R.error,{message:""+e})}}}log(...e){this.tree.options.debugLevel>=4&&console.log(this.toString(),...e)}logDebug(...e){this.tree.options.debugLevel>=4&&console.debug(this.toString(),...e)}logError(...e){this.tree.options.debugLevel>=1&&console.error(this.toString(),...e)}logInfo(...e){this.tree.options.debugLevel>=3&&console.info(this.toString(),...e)}logWarn(...e){this.tree.options.debugLevel>=2&&console.warn(this.toString(),...e)}async makeVisible(e){let t;const i=new le,s=[],n=this.getParentList(!1,!1),r=n.length,o=M(e,"noAnimation",!1),l=M(e,"scrollIntoView",!0);for(t=r-1;t>=0;t--){const e={noAnimation:o};s.push(n[t].setExpanded(!0,e))}return Promise.all(s).then((()=>{l&&this.tree?(this.tree.updatePendingModifications(),this.scrollIntoView().then((()=>{i.resolve()}))):i.resolve()})),i.promise()}moveTo(e,t="appendChild",i){let s;"over"===t&&(t="appendChild"),"prependChild"===t&&(e.children&&e.children.length?(t="before",e=e.children[0]):t="appendChild");const n=this.tree,r=this.parent,o="appendChild"===t?e:e.parent;if(this!==e){if(this.parent?o.isDescendantOf(this)&&v("Cannot move a node to its own descendant"):v("Cannot move system root"),o!==r&&r.triggerModifyChild("remove",this),1===this.parent.children.length){if(this.parent===o)return;this.parent.children=this.parent.lazy?[]:null,this.parent.expanded=!1}else s=this.parent.children.indexOf(this),f(s>=0,"invalid source parent"),this.parent.children.splice(s,1);if(this.parent=o,o.hasChildren())switch(t){case"appendChild":o.children.push(this);break;case"before":s=o.children.indexOf(e),f(s>=0,"invalid target parent"),o.children.splice(s,0,this);break;case"after":s=o.children.indexOf(e),f(s>=0,"invalid target parent"),o.children.splice(s+1,0,this);break;default:v(`Invalid mode '${t}'.`)}else o.children=[this];i&&e.visit(i,!0),o===r?o.triggerModifyChild("move",this):o.triggerModifyChild("add",this),n!==e.tree&&(this.logWarn("Cross-tree moveTo is experimental!"),this.visit((t=>{t.tree=e.tree}),!0)),setTimeout((()=>{n.update($.any)}),0)}}async navigate(e,t){e=Z[e]||e;const i=this.findRelatedNode(e);if(!i)return this.logWarn(`Could not find related node '${e}'.`),Promise.resolve(this);try{i.makeVisible({scrollIntoView:!1})}catch(e){}return i.setFocus(),!1===(null==t?void 0:t.activate)?Promise.resolve(this):i.setActive(!0,{event:null==t?void 0:t.event})}remove(){const e=this.tree,t=this.parent.children.indexOf(this);this.triggerModify("remove"),this.parent.children.splice(t,1),this.visit((t=>{t.removeMarkup(),e._unregisterNode(t)}),!0),e.update($.structure)}removeChildren(){var e,t;const i=this.tree;this.children&&((null===(e=i.activeNode)||void 0===e?void 0:e.isDescendantOf(this))&&i.activeNode.setActive(!1),(null===(t=i.focusNode)||void 0===t?void 0:t.isDescendantOf(this))&&i._setFocusNode(null),this.triggerModifyChild("remove",null),this.visit((e=>{i._unregisterNode(e)})),this.lazy?this.children=[]:this.children=null,this.isRootNode()||(this.expanded=!1),this.tree.update($.structure))}removeMarkup(){this._rowElem&&(delete this._rowElem._wb_node,this._rowElem.remove(),this._rowElem=void 0)}_getRenderInfo(){const e={},t={},i=this.isColspan(),s=this._rowElem?this._rowElem.querySelectorAll("span.wb-col"):null;let n=0;for(const r of this.tree.columns)e[r.id]={id:r.id,idx:n,elem:s?s[n]:null,info:r},i||"*"===r.id||(t[r.id]=e[r.id]),n++;return{allColInfosById:e,renderColInfosById:t}}_createIcon(e,t,i,s){let n,r=this.getOption("icon");if(this._errorInfo?r=e.error:this._isLoading&&s&&(r=e.loading),!1===r)return null;"string"==typeof r||(r=this.statusNodeType?e[this.statusNodeType]:this.expanded?e.folderOpen:this.children?e.folder:this.lazy?e.folderLazy:e.doc),r?r.indexOf("<")>=0?n=_(r):Y.test(r)?n=_(``):(n=document.createElement("i"),n.className="wb-icon "+r):(n=document.createElement("i"),n.className="wb-icon"),i?t.replaceChild(n,i):t.appendChild(n);const o=this._callEvent("iconBadge",{iconSpan:n});let l=null;if(null!=o&&!1!==o){let e="",t="";T(o)?(l=""+o.badge,e=o.badgeClass?" "+o.badgeClass:"",t=o.badgeTooltip?` title="${o.badgeTooltip}"`:""):l="number"==typeof o?""+o:o,"string"==typeof l&&(l=_(`${m(l)}`)),l&&n.append(l)}return n}_render_markup(e){const t=this.tree,i=t.options,s=this.getOption("checkbox"),n=t.columns,r=this.getLevel(),o=t.isRowNav()?null:t.activeColIdx;let l,a=this._rowElem,d=null,c=null;const h=!a;f(h,"Expected unrendered node"),f(!h||e&&e.after,"opts.after expected, unless updating"),f(!this.isRootNode(),"Root node not allowed"),a=document.createElement("div"),a.classList.add("wb-row"),a.style.top=this._rowIdx*Q+"px",this._rowElem=a,a._wb_node=this;const u=document.createElement("span");u.classList.add("wb-node","wb-col"),a.appendChild(u);let p=0;s&&(d=document.createElement("i"),d.classList.add("wb-checkbox"),("radio"===s||this.parent.radiogroup)&&d.classList.add("wb-radio"),u.appendChild(d),p+=20);for(let e=r-1;e>0;e--)l=document.createElement("i"),l.classList.add("wb-indent"),u.appendChild(l),p+=20;(!i.minExpandLevel||r>i.minExpandLevel)&&(c=document.createElement("i"),c.classList.add("wb-expander"),u.appendChild(c),p+=20);this._createIcon(t.iconMap,u,null,!c)&&(p+=20);const g=document.createElement("span");g.classList.add("wb-title"),u.appendChild(g),u._ofsTitlePx=p,t.options.dnd.dragStart&&(u.draggable=!0);if(!this.isColspan()&&n.length>1){let e=0;for(const t of n){let i;e++,"*"===t.id?i=u:(i=document.createElement("span"),i.classList.add("wb-col"),a.appendChild(i)),e===o&&i.classList.add("wb-active"),t.classes&&i.classList.add(...t.classes.split(" ")),i.style.left=t._ofsPx+"px",i.style.width=t._widthPx+"px",h&&t.html&&"string"==typeof t.html&&(i.innerHTML=t.html)}}switch(e?e.after:"last"){case"first":t.nodeListElement.prepend(a);break;case"last":t.nodeListElement.appendChild(a);break;default:e.after.after(a)}e.isNew=!0,this._render_data(e)}_render_data(e){f(this._rowElem,"No _rowElem");const t=this.tree,i=t.options,s=this._rowElem,n=!!e.isNew,r=!!e.preventScroll,o=t.columns,l=this.isColspan(),a=s.querySelector("span.wb-node"),d=a.querySelector("span.wb-title"),c=t.element.scrollTop;if(this.titleWithHighlight?d.innerHTML=this.titleWithHighlight:d.textContent=this.title,r&&(t.element.scrollTop=c),!i.skeleton)if(l){const e=t.element.clientWidth;d.style.width=e-a._ofsTitlePx-7+"px"}else d.style.width=o[0]._widthPx-a._ofsTitlePx-7+"px";if(e.isDataChange=!0,this._render_status(e),this.statusNodeType)this._callEvent("renderStatusNode",{isNew:n,nodeElem:a,isColspan:l});else if(this.parent){const e=this._getRenderInfo();this._callEvent("render",{isNew:n,nodeElem:a,isColspan:l,allColInfosById:e.allColInfosById,renderColInfosById:e.renderColInfosById})}}_render_status(e){const t=this.tree,i=t.iconMap,s=t.options,n=this.type?t.types[this.type]:null,r=this._rowElem,o=r.querySelector("span.wb-node"),l=o.querySelector("i.wb-expander"),a=o.querySelector("i.wb-checkbox"),d=["wb-row"];if(this.expanded&&d.push("wb-expanded"),this.lazy&&d.push("wb-lazy"),this.selected&&d.push("wb-selected"),this._partsel&&d.push("wb-partsel"),this===t.activeNode&&d.push("wb-active"),this===t.focusNode&&d.push("wb-focus"),this._errorInfo&&d.push("wb-error"),this._isLoading&&d.push("wb-loading"),this.isColspan()&&d.push("wb-colspan"),this.statusNodeType&&d.push("wb-status-"+this.statusNodeType),this.match&&d.push("wb-match"),this.subMatchCount&&d.push("wb-submatch"),s.skeleton&&d.push("wb-skeleton"),r.className=d.join(" "),this.classes&&r.classList.add(...this.classes),n&&n.classes&&r.classList.add(...n.classes),l){let e=null;this._isLoading?e=i.loading:this.isExpandable(!1)?e=this.expanded?i.expanderExpanded:i.expanderCollapsed:this.lazy&&null==this.children&&(e=i.expanderLazy),null==e?l.classList.add("wb-indent"):Y.test(e)?l.style.backgroundImage=`url('${e}')`:l.className="wb-expander "+e}if(a){let e="wb-checkbox ";this.isRadio()?(e+="wb-radio ",this.selected?e+=i.radioChecked:e+=i.radioUnchecked):this.selected?e+=i.checkChecked:this._partsel?e+=i.checkUnknown:e+=i.checkUnchecked,a.className=e}if(!e.isNew){let e=0;for(const i of r.children)i.classList.toggle("wb-active",e++===t.activeColIdx),i.classList.remove("wb-error","wb-invalid");const i=o.querySelector("i.wb-icon");i&&this._createIcon(t.iconMap,o,i,!l)}if(!1!==e.resizeCols&&!this.isColspan()){const e=r.querySelectorAll("span.wb-col");let t=0,i=0;for(const s of this.tree.columns){const n=e[t];n.style.left=`${i}px`,n.style.width=`${s._widthPx}px`,t++,i+=s._widthPx}}}_render(e){const t=Object.assign({change:$.data},e);switch(this._rowElem||(t.change=$.row),t.change){case"status":this._render_status(t);break;case"data":this._render_data(t);break;case"row":this._render_markup(t);break;default:v(`Invalid change type '${t.change}'.`)}}resetLazy(){this.removeChildren(),this.expanded=!1,this.lazy=!0,this.children=null,this.tree.update($.structure)}toDict(e=!1,t){const i={};if(de.forEach((e=>{const t=this[e];t instanceof Set?t.size&&(i[e]=Array.prototype.join.call(t.keys()," ")):(t||!1===t||0===t)&&(i[e]=t)})),D(this.data)||(i.data=N({},this.data),D(i.data)&&delete i.data),t){const s=t(i,this);if(!1===s)return!1;"skip"===s&&(e=!1)}if(e&&S(this.children)){i.children=[];for(let e=0,s=this.children.length;e=0&&([s,e]=e.split("."));const n=s[e];if("function"==typeof n){const e=n.call(i,{type:"resolve",tree:i,node:this});if(void 0!==e)return e}if(void 0!==this[e])return this[e];const r=this.type?i.types[this.type]:void 0,o=r?r[e]:void 0;return void 0!==o?o:null!=n?n:t}async scrollIntoView(e){const t=Object.assign({node:this},e);return this.tree.scrollTo(t)}async setActive(e=!0,t){const i=this.tree,s=i.getActiveNode(),n=null==t?void 0:t.retrigger,r=null==t?void 0:t.focusTree,o=null==t?void 0:t.noEvents,l=null==t?void 0:t.event,a=null==t?void 0:t.colIdx,d=null==t?void 0:t.edit;if(f(!a||i.isCellNav(),"colIdx requires cellNav"),f(!d||null!=a,"edit requires colIdx"),!o)if(e){if(s!==this||n){if(!1===(null==s?void 0:s._callEvent("deactivate",{nextNode:this,event:l}))||!1===this._callEvent("beforeActivate",{prevNode:s,event:l}))return;i._setActiveNode(null),null==s||s.update($.status)}}else(s===this||n)&&this._callEvent("deactivate",{nextNode:null,event:l});return s!==this&&(e&&i._setActiveNode(this),null==s||s.update($.status),this.update($.status)),this.makeVisible().then((()=>{e&&((r||d)&&(i.setFocus(),i._setFocusNode(this),i.focusNode.setFocus()),null!=a&&i.isCellNav()&&i.setColumn(a,{edit:d}),o||this._callEvent("activate",{prevNode:s,event:l}))}))}async setExpanded(e=!0,t){const{force:i,scrollIntoView:s,immediate:n}=null!=t?t:{},r=!(null==t?void 0:t.noEvents);if(!e&&this.isExpanded()&&this.getLevel()<=this.tree.getOption("minExpandLevel")&&!i)return void this.logDebug("Ignored collapse request below minExpandLevel.");if(!e==!this.expanded)return;if(r&&!1===this._callEvent("beforeExpand",{flag:e}))return;e&&this.getOption("autoCollapse")&&this.collapseSiblings(t),e&&this.lazy&&null==this.children&&await this.loadLazy(),this.expanded=e;const o={immediate:n};if(this.tree.update($.structure,o),e&&s){const e=this.getLastChild();e&&(this.tree.updatePendingModifications(),e.scrollIntoView({topNode:this}))}r&&this._callEvent("expand",{flag:e})}setFocus(e=!0){f(!!e,"Blur is not yet implemented");const t=this.tree.focusNode;this.tree._setFocusNode(this),null==t||t.update(),this.update()}setIcon(e){this.icon=e,this.update()}setKey(e,t){throw new Error("Not yet implemented")}update(e=$.data){f(e===$.status||e===$.data,`Invalid change type ${e}`),this.tree.update(e,this)}getSelectedNodes(e=!1){const t=[];return this.visit((i=>{if(i.selected&&(t.push(i),!0===e))return"skip"})),t}toggleSelected(e){let t=this.isSelected();return t=void 0!==t||this.isRadio()?!t:this._anySelectable(),this.setSelected(t,e)}_anySelectable(){let e=!1;return this.visit((t=>{if(!1===t.selected&&!t.unselectable&&!t.hasChildren()&&!t.parent.radiogroup)return e=!0,!1})),e}_changeSelectStatusProps(e){let t=!1;switch(e){case!1:t=this.selected||this._partsel,this.selected=!1,this._partsel=!1;break;case!0:t=!this.selected||!this._partsel,this.selected=!0,this._partsel=!0;break;case void 0:t=this.selected||!this._partsel,this.selected=!1,this._partsel=!0;break;default:v(`Invalid state: ${e}`)}return t&&this.update(),t}fixSelection3AfterClick(e){const t=!!(null==e?void 0:e.force),i=this.isSelected();this.visit((e=>{if(e.radiogroup)return"skip";!t&&e.getOption("unselectable")||e._changeSelectStatusProps(i)})),this.fixSelection3FromEndNodes()}fixSelection3FromEndNodes(e){const t=!!(null==e?void 0:e.force);f("hier"===this.tree.options.selectMode,"expected selectMode 'hier'");const i=e=>{let s;const n=e.children;if(n&&n.length){let e=!0,t=!1;for(let s=0,r=n.length;s{let t;const i=e.children;let s=!0,n=!1;for(let e=0,r=i.length;e{this.visit((t=>{t.setSelected(e)}))})),n):(e===n||s&&!1===this._callEvent("beforeSelect",{flag:e})||(i.runWithDeferredUpdate((()=>{if(r){if(!e&&!(null==t?void 0:t.force))return n;for(const e of this.parent.children)e.selected=e===this}else this.selected=e,"hier"===o?this.fixSelection3AfterClick():"single"===o&&i.visit((e=>{e.selected=!1}))})),s&&this._callEvent("select",{flag:e})),n):n}setStatus(e,t){const i=this.tree,s=null==t?void 0:t.message,n=null==t?void 0:t.details;let r=null;const o=e=>{const t=this.children,s=t?t[0]:null;return f(e.statusNodeType,"Not a status node"),f(!s||!s.isStatusNode(),"Child must not be a status node"),r=this.addNode(e,"prependChild"),r.match=!0,i.update($.structure),r};switch((()=>{const e=this.children;e&&e.length&&e[0].isStatusNode()&&e[0].remove()})(),e){case"ok":this._isLoading=!1,this._errorInfo=null;break;case"loading":this._isLoading=!0,this._errorInfo=null,this.parent?this.update($.status):o({statusNodeType:e,title:i.options.strings.loading+(s?" ("+s+")":""),checkbox:!1,colspan:!0,tooltip:n});break;case"error":o({statusNodeType:e,title:i.options.strings.loadError+(s?" ("+s+")":""),checkbox:!1,colspan:!0,tooltip:n}),this._isLoading=!1,this._errorInfo={message:s,details:n};break;case"noData":o({statusNodeType:e,title:s||i.options.strings.noData,checkbox:!1,colspan:!0,tooltip:n}),this._isLoading=!1,this._errorInfo=null;break;default:v("invalid node status "+e)}return i.update($.structure),r}setTitle(e){this.title=e,this.update()}_sortChildren(e,t){const i=this.children;if(i&&(i.sort(e),t))for(let s=0,n=i.length;s{const r=t._callEvent(e,n);Promise.resolve(r).then((e=>{i(e)})).catch((e=>{s(e)}))})).then((e=>{if(!s.checkValidity())throw t.logWarn("inputElem.checkValidity() failed: throwing...."),new p(s.validationMessage);return e})).catch((n=>{if(!(n instanceof p))throw t.logError(`Error in ${e} event handler (throw e.util.ValidationError instead if this was intended)`,n),i.classList.add("wb-error"),n;t.logWarn("catched ",n),i.classList.add("wb-invalid"),s.setCustomValidity&&!s.validationMessage&&s.setCustomValidity(n.message),s.validationMessage&&s.reportValidity()})).finally((()=>{i.classList.remove("wb-busy")}))}_onChange(e){const t=pe.getEventInfo(e),i=t.node,s=t.colElem;i&&0!==t.colIdx?this._applyChange("change",i,s,e.target,{info:t,event:e,inputElem:e.target,inputValue:pe.util.getValueFromElem(e.target),inputValid:e.target.checkValidity()}):this.tree.log("Ignored change event for removed element or node title")}init(){super.init(),L(this.tree.element,"change",".contenteditable,input,textarea,select",(e=>this._onChange(e)))}_preprocessKeyEvent(e){const t=e.event,i=C(t),s=this.tree,n=this.getPluginOption("trigger");if(this.isEditingTitle()){switch(i){case"Enter":return this._stopEditTitle(!0,{event:t}),!1;case"Escape":return this._stopEditTitle(!1,{event:t}),!1}return!1}if(s.isRowNav()||0===s.activeColIdx){switch(i){case"Enter":if(n.indexOf("macEnter")>=0&&d)return this.startEditTitle(),!1;break;case"F2":if(n.indexOf("F2")>=0)return this.startEditTitle(),!1}return!0}return!0}isEditingTitle(e){return e?this.curEditNode===e:!!this.curEditNode}startEditTitle(e){e=null!=e?e:this.tree.getActiveNode();const t=this.getPluginOption("validity"),i=this.getPluginOption("select");if(!e)return;this.tree.logDebug(`startEditTitle(node=${e})`);let s=e._callEvent("edit.beforeEdit");if(!1===s)return void e.logDebug("beforeEdit canceled operation.");if(!0===s||!s){const t=m(e.title);let i=this.getPluginOption("maxlength");const n=i?` maxlength="${i}"`:"";i=this.getPluginOption("minlength");s=`0?" required":""}${i?` minlength="${i}"`:""}${n} >`}const n=e.getColElem(0).querySelector(".wb-title");n.innerHTML=s;const r=n.firstElementChild;t&&r.addEventListener("keydown",(t=>{r.setCustomValidity(""),r.reportValidity()||e.logWarn(`Invalid input: '${r.value}'`)})),r.focus(),i&&r.select(),this.curEditNode=e,e._callEvent("edit.edit",{inputElem:r})}stopEditTitle(e){return this._stopEditTitle(e,{})}_stopEditTitle(e,t){null!=t||(t={});const i=document.activeElement;let s=i?w(i):null;const n=this.curEditNode,r=!!t.forceClose,o=this.getPluginOption("validity");if(s&&this.getPluginOption("trim")&&(s=s.trim()),n)if(n.logDebug(`stopEditTitle(${e})`,t,i,s),e&&null!==s&&s!==n.title){const e=i.validationMessage;if(e)throw new Error(`Input validation failed for "${s}": ${e}.`);const t=n.getColElem(0);this._applyChange("edit.apply",n,t,i,{oldValue:n.title,newValue:s,inputElem:i,inputValid:i.checkValidity()}).then((e=>{const t=i.validationMessage;if(o&&t&&!1!==e)throw new Error(`Edit apply validation failed for "${s}": ${t}.`);(r||!1!==e)&&(null==n||n.setTitle(s),this.curEditNode._render({preventScroll:!0}),this.curEditNode=null,this.relatedNode=null,this.tree.setFocus())}))}else this.curEditNode._render({preventScroll:!0}),this.curEditNode=null,this.relatedNode=null,this.tree.setFocus();else this.tree.logDebug("stopEditTitle: not in edit mode.")}createNode(e="after",t,i){const s=this.tree;if(f(t=null!=t?t:s.getActiveNode(),"No node was passed, or no node is currently active."),e=e||"prependChild",null==i?i={title:""}:"string"==typeof i?i={title:i}:f(T(i),`Expected a plain object: ${i}`),("prependChild"===e||"appendChild"===e)&&(null==t?void 0:t.isExpandable(!0)))return void t.setExpanded().then((()=>{this.createNode(e,t,i)}));const n=t.addNode(i,e);n.setClass("wb-edit-new"),this.relatedNode=t,n.match=!0,n.makeVisible({noAnimation:!0}).then((()=>{this.startEditTitle(n)}))}} +/*! + * wunderbaum.ts + * + * A treegrid control. + * + * Copyright (c) 2021-2023, Martin Wendt (https://wwWendt.de). + * https://github.com/mar10/wunderbaum + * + * Released under the MIT license. + * @version v0.8.2 + * @date Sat, 17 Feb 2024 07:32:06 GMT + */class ue extends ce{constructor(e){super(e,null,{key:"__root__",title:e.id})}toString(){return`WbSystemRoot@${this.key}<'${this.tree.id}'>`}}class pe{get activeNode(){var e;return(null===(e=this._activeNode)||void 0===e?void 0:e.tree)?this._activeNode:null}get focusNode(){var e;return(null===(e=this._focusNode)||void 0===e?void 0:e.tree)?this._focusNode:null}constructor(e){this.enabled=!0,this.data={},this.extensionList=[],this.extensions={},this.keyMap=new Map,this.refKeyMap=new Map,this.treeRowCount=0,this._disableUpdateCount=0,this._disableUpdateIgnoreCount=0,this._activeNode=null,this._focusNode=null,this.types={},this.columns=[],this._columnsById={},this.pendingChangeTypes=new Set,this._util=U,this.filterMode=null,this.activeColIdx=0,this._cellNavMode=!1,this.lastQuicksearchTime=0,this.lastQuicksearchTerm="",this.lastClickTime=0;const t=this.options=N({id:null,source:null,element:null,debugLevel:3,header:null,rowHeightPx:Q,iconMap:"bootstrap",columns:null,types:null,enabled:!0,fixedCol:!1,showSpinner:!1,checkbox:!1,minExpandLevel:0,emptyChildListExpandable:!1,skeleton:!1,connectTopBreadcrumb:null,selectMode:"multi",navigationModeOption:null,quicksearch:!0,iconBadge:null,change:null,error:null,receive:null,strings:{loadError:"Error",loading:"Loading...",noData:"No data"}},e),i=new le;this.ready=i.promise();let s=!1;if(this.ready.then((()=>{s=!0;try{this._callEvent("init")}catch(e){this.logError("Exception inside `init(e)` event:",e)}})).catch((e=>{if(s)throw e;this._callEvent("init",{error:e})})),this.id=t.id||"wb_"+ ++pe.sequence,this.root=new ue(this),this._registerExtension(new B(this)),this._registerExtension(new he(this)),this._registerExtension(new W(this)),this._registerExtension(new ne(this)),this._registerExtension(new oe(this)),this._registerExtension(new G(this)),this._updateViewportThrottled=O(this._updateViewportImmediately.bind(this),{}),this.columns=t.columns,delete t.columns,!this.columns||!this.columns.length){const e="string"==typeof t.header?t.header:this.id;this.columns=[{id:"*",title:e,width:"*"}]}t.types&&this.setTypes(t.types,!0),delete t.types,this.element=k(t.element),f(!!this.element,`Invalid 'element' option: ${t.element}`),this.element.classList.add("wunderbaum"),this.element.getAttribute("tabindex")||(this.element.tabIndex=0),this.element._wb_tree=this,this.headerElement=this.element.querySelector("div.wb-header");const n=null==t.header?this.columns.length>1:!!t.header;if(this.headerElement){f(!this.columns,"`opts.columns` must not be set if markup already contains a header"),this.columns=[];const e=this.headerElement.querySelector("div.wb-row");for(const t of e.querySelectorAll("div"))this.columns.push({id:t.dataset.id||`col_${this.columns.length}`,title:""+t.textContent,width:"*"})}else{const e="".repeat(this.columns.length);if(this.element.innerHTML=`\n
    \n
    \n ${e}\n
    \n
    `,!n){this.element.querySelector("div.wb-header").style.display="none"}}this.element.innerHTML+='\n
    \n
    \n
    ',this.listContainerElement=this.element.querySelector("div.wb-list-container"),this.nodeListElement=this.listContainerElement.querySelector("div.wb-node-list"),this.headerElement=this.element.querySelector("div.wb-header"),this.element.classList.toggle("wb-grid",this.columns.length>1),this._initExtensions(),["enabled","fixedCol"].forEach((e=>{null!=t[e]&&this.setOption(e,t[e])})),t.source?(t.showSpinner&&(this.nodeListElement.innerHTML="loading..."),this.load(t.source).then((()=>{null==t.navigationModeOption?this.isGrid()?this.setNavigationOption(z.cell):this.setNavigationOption(z.row):this.setNavigationOption(t.navigationModeOption),this.update($.structure,{immediate:!0}),i.resolve()})).catch((e=>{i.reject(e)})).finally((()=>{var e;null===(e=this.element.querySelector("progress.spinner"))||void 0===e||e.remove(),this.element.classList.remove("wb-initializing")}))):i.resolve(),this.update($.any),this.element.addEventListener("scroll",(e=>{this.update($.scroll)})),this.resizeObserver=new ResizeObserver((e=>{this.update($.resize)})),this.resizeObserver.observe(this.element),L(this.nodeListElement,"click","div.wb-row",(t=>{const i=pe.getEventInfo(t),s=i.node,n=t;if(!1===this._callEvent("click",{event:t,node:s,info:i}))return this.lastClickTime=Date.now(),!1;if(s){if(n.ctrlKey)return void s.toggleSelected();const r=this.getOption("edit.trigger"),o=this.getOption("edit.slowClickDelay");r.indexOf("clickActive")>=0&&"title"===i.region&&s.isActive()&&(!o||Date.now()-this.lastClickTime=0?s.setActive(!0,{colIdx:i.colIdx,event:t}):s.setActive(!0,{event:t}),i.region===F.expander?s.setExpanded(!s.isExpanded(),{scrollIntoView:!1!==e.scrollIntoViewOnExpandClick}):i.region===F.checkbox&&s.toggleSelected()}this.lastClickTime=Date.now()})),L(this.nodeListElement,"dblclick","div.wb-row",(e=>{const t=pe.getEventInfo(e),i=t.node;if(!1===this._callEvent("dblclick",{event:e,node:i,info:t}))return!1;i&&0===t.colIdx&&i.isExpandable()&&(this._callMethod("edit._stopEditTitle"),i.setExpanded(!i.isExpanded()))})),L(this.element,"keydown",(e=>{const t=pe.getEventInfo(e),i=C(e),s=t.node||this.getFocusNode();this._callHook("onKeyEvent",{event:e,node:s,info:t,eventName:i})})),L(this.element,"focusin focusout",(e=>{const i="focusin"===e.type,s=pe.getNode(e);this._callEvent("focus",{flag:i,event:e}),i&&this.isRowNav()&&!this.isEditingTitle()&&(t.navigationModeOption===z.row?null==s||s.setActive():this.setCellNav()),i||this._callMethod("edit._stopEditTitle",!0,{event:e,forceClose:!0})}))}static getTree(e){if(e instanceof pe)return e;if(e instanceof ce)return e.tree;if(void 0===e&&(e=0),"number"==typeof e)e=document.querySelectorAll(".wunderbaum")[e];else if("string"==typeof e){for(const t of document.querySelectorAll(".wunderbaum")){const i=t._wb_tree;if(i&&i.id===e)return i}if(!(e=document.querySelector(e)))return null}else e.target&&(e=e.target);return f(e instanceof Element,`Invalid el type: ${e}`),e.matches(".wunderbaum")||(e=e.closest(".wunderbaum")),e&&e._wb_tree?e._wb_tree:null}get iconMap(){const e=this.options.iconMap;return"string"==typeof e?J[e]:e}static getNode(e){if(!e)return null;if(e instanceof ce)return e;for(void 0!==e.target&&(e=e.target);e;){if(e._wb_node)return e._wb_node;e=e.parentElement}return null}*[Symbol.iterator](){yield*this.root}_registerExtension(e){this.extensionList.push(e),this.extensions[e.id]=e}_initExtensions(){for(const e of this.extensionList)e.init()}_registerNode(e){const t=e.key;f(null!=t,`Missing key: '${e}'.`),f(!this.keyMap.has(t),`Duplicate key: '${t}': ${e}.`),this.keyMap.set(t,e);const i=e.refKey;if(null!=i){const t=this.refKeyMap.get(i);t?t.add(e):this.refKeyMap.set(i,new Set([e]))}}_unregisterNode(e){const t=e.refKey;if(null!=t){const i=this.refKeyMap.get(t);i&&i.delete(e)&&!i.size&&this.refKeyMap.delete(t)}this.keyMap.delete(e.key),e.tree=null,e.parent=null,e.removeMarkup()}_callHook(e,t={}){let i;const s=N({},{tree:this,options:this.options,result:void 0},t);for(const t of this.extensionList){if(i=t[e].call(t,s),!1===i)break;void 0!==s.result&&(i=s.result)}return i}_callMethod(e,...t){const[i,s]=e.split("."),n=s?this.extensions[i]:this,r=n[s];if(r)return r.apply(n,t);this.logError(`Calling undefined method '${e}()'.`)}_callEvent(e,t){const[i,s]=e.split("."),n=this.options,r=s?n[i][s]:n[i];if(r)return r.call(this,N({type:e,tree:this,util:this._util},t))}_getNodeByRowIdx(e){let t=null;return this.visitRows((i=>{if(i._rowIdx===e)return t=i,!1})),t}getTopmostVpNode(e=!0){const t=this.element.scrollTop;let i;return i=e?Math.ceil((t-1)/Q):Math.floor(t/Q),this._getNodeByRowIdx(i)}getLowestVpNode(e=!0){const t=this.element,i=this.headerElement.clientHeight,s=t.scrollTop,n=t.clientHeight-i;let r;return r=e?Math.floor((s+n)/Q)-1:Math.ceil((s+n)/Q)-1,r=Math.min(r,this.count(!0)-1),this._getNodeByRowIdx(r)}_getPrevNodeInView(e,t=1){return this.visitRows((i=>{if(e=i,t--<=0)return!1}),{reverse:!0,start:e||this.getActiveNode()}),e}_getNextNodeInView(e,t=1){return this.visitRows((i=>{if(e=i,t--<=0)return!1}),{reverse:!1,start:e||this.getActiveNode()}),e}addChildren(e,t){return this.root.addChildren(e,t)}applyCommand(e,t,i){let s,n;switch(t instanceof ce?s=t:(s=this.getActiveNode(),f(void 0===i,`Unexpected options: ${i}`),i=t),e){case"moveUp":n=s.getPrevSibling(),n&&(s.moveTo(n,"before"),s.setActive());break;case"moveDown":n=s.getNextSibling(),n&&(s.moveTo(n,"after"),s.setActive());break;case"indent":n=s.getPrevSibling(),n&&(s.moveTo(n,"appendChild"),n.setExpanded(),s.setActive());break;case"outdent":s.isTopLevel()||(s.moveTo(s.getParent(),"after"),s.setActive());break;case"remove":n=s.getPrevSibling()||s.getParent(),s.remove(),n&&n.setActive();break;case"addChild":this._callMethod("edit.createNode","prependChild");break;case"addSibling":this._callMethod("edit.createNode","after");break;case"rename":s.startEditTitle();break;case"down":case"first":case"last":case"left":case"pageDown":case"pageUp":case"parent":case"right":case"up":return s.navigate(e);default:v(`Unhandled command: '${e}'`)}}clear(){this.root.removeChildren(),this.root.children=null,this.keyMap.clear(),this.refKeyMap.clear(),this.treeRowCount=0,this._activeNode=null,this._focusNode=null,this.update($.structure)}destroy(){this.logInfo("destroy()..."),this.clear(),this.resizeObserver.disconnect(),this.element.innerHTML="",this.element.outerHTML=this.element.outerHTML}getOption(e,t){let i,s=this.options;e.indexOf(".")>=0&&([i,e]=e.split("."),s=s[i]);let n=s[e];return"function"==typeof n&&(n=n({type:"resolve",tree:this})),null!=n?n:t}setOption(e,t){if(e.indexOf(".")>=0){const i=e.split(".");this.extensions[i[0]].setPluginOption(i[1],t)}else switch(this.options[e]=t,e){case"checkbox":this.update($.any);break;case"enabled":this.setEnabled(!!t);break;case"fixedCol":this.element.classList.toggle("wb-fixed-col",!!t)}}hasFocus(){return this.element.contains(document.activeElement)}hasHeader(){const e=this.options.header;return this.isGrid()?!1!==e:!!e}runWithDeferredUpdate(e,t=null){try{this.enableUpdate(!1);const t=e();return f(!(t instanceof Promise),`Promise return not allowed: ${t}`),t}finally{this.enableUpdate(!0)}}async expandAll(e=!0,t){await this.root.expandAll(e,t)}selectAll(e=!0){return this.root.setSelected(e,{propagateDown:!0})}toggleSelect(){this.selectAll(this.root._anySelectable())}getSelectedNodes(e=!1){return this.root.getSelectedNodes(e)}_selectRange(e){this.logDebug("_selectRange",e),v("Not yet implemented.")}count(e=!1){return e?this.treeRowCount:this.keyMap.size}_check(){let e=0;this.visit((t=>{e++})),this.keyMap.size!==e&&this.logWarn(`_check failed: ${this.keyMap.size} !== ${e}`)}findAll(e){return this.root.findAll(e)}findByRefKey(e){const t=this.refKeyMap.get(e);return t?Array.from(t):[]}findFirst(e){return this.root.findFirst(e)}findKey(e){return this.keyMap.get(e)||null}findNextNode(e,t){let i=null;const s=this.getFirstChild(),n="string"==typeof e?function(e){e=y(e);const t=new RegExp("^"+e,"i");return function(e){return t.test(e.title)}}(e):e;function r(e){if(n(e)&&(i=e),i||e===t)return!1}return t=t||s,this.visitRows(r,{start:t,includeSelf:!1}),i||t===s||this.visitRows(r,{start:s,includeSelf:!0}),i}findRelatedNode(e,t,i=!1){let s=null;const n=Math.floor(this.listContainerElement.clientHeight/Q);switch(t){case"parent":case"left":e.parent&&e.parent.parent&&(s=e.parent);break;case"first":this.visit((e=>{if(e.isVisible())return s=e,!1}));break;case"last":this.visit((e=>{e.isVisible()&&(s=e)}));break;case"right":e.children&&e.children.length&&(s=e.children[0]);break;case"up":s=this._getPrevNodeInView(e);break;case"down":s=this._getNextNodeInView(e);break;case"pageDown":{const t=this.getLowestVpNode();s=e._rowIdxt._rowIdx?t:this._getPrevNodeInView(e,n)}break;default:this.logWarn("Unknown relation '"+t+"'.")}return s}*format_iter(e,t){yield*this.root.format_iter(e,t)}format(e,t){return this.root.format(e,t)}getActiveColElem(){return this.activeNode&&this.activeColIdx>=0?this.activeNode.getColElem(this.activeColIdx):null}getActiveNode(){return this.activeNode}getFirstChild(){return this.root.getFirstChild()}getFocusNode(){return this.focusNode}static getEventInfo(e){const t=e.target,i=t.classList,s=t.closest("span.wb-col"),n=pe.getNode(t),r=n?n.tree:pe.getTree(e),o={event:e,canonicalName:C(e),tree:r,node:n,region:F.unknown,colDef:void 0,colIdx:-1,colId:void 0,colElem:s};if(i.contains("wb-title"))o.region=F.title;else if(i.contains("wb-expander"))o.region=n.isExpandable()?F.expander:F.prefix;else if(i.contains("wb-checkbox"))o.region=F.checkbox;else if(i.contains("wb-icon"))o.region=F.icon;else if(i.contains("wb-node"))o.region=F.title;else if(s){o.region=F.column;const e=Array.prototype.indexOf.call(s.parentNode.children,s);o.colIdx=e}else{if(!i.contains("wb-row"))return"mousemove"===e.type||e instanceof KeyboardEvent||null==r||r.logWarn("getEventInfo(): not found",e,o),o;o.region=F.title}return-1===o.colIdx&&(o.colIdx=0),o.colDef=null==r?void 0:r.columns[o.colIdx],null!=o.colDef&&(o.colId=o.colDef.id),o}toString(){return`Wunderbaum<'${this.id}'>`}isEditing(){return!!this.nodeListElement.querySelector("input:focus,select:focus")}isEditingTitle(){return this._callMethod("edit.isEditingTitle")}isLoading(){let e=!1;return this.root.visit((t=>{if(t._isLoading||t._requestId)return e=!0,!1}),!0),e}log(...e){this.options.debugLevel>=4&&console.log(this.toString(),...e)}logDebug(...e){this.options.debugLevel>=4&&console.debug(this.toString(),...e)}logError(...e){this.options.debugLevel>=1&&console.error(this.toString(),...e)}logInfo(...e){this.options.debugLevel>=3&&console.info(this.toString(),...e)}logTime(e){return this.options.debugLevel>=4&&console.time(this+": "+e),e}logTimeEnd(e){this.options.debugLevel>=4&&console.timeEnd(this+": "+e)}logWarn(...e){this.options.debugLevel>=2&&console.warn(this.toString(),...e)}scrollTo(e){let t,i;e instanceof ce?t=e:(i=e,t=i.node),f(t&&null!=t._rowIdx,`Invalid node: ${t}`);const s=this.element,n=this.headerElement.clientHeight,r=s.scrollTop,o=s.clientHeight,l=t._rowIdx*Q+n,a=n,d=l-r,c=d+Q,h=null==i?void 0:i.topNode;let u=null;d>=a?c<=o||(u=l+Q-o+2):u=l-a-2,null!=u&&(this.log(`scrollTo(${l}): ${r} => ${u}`),s.scrollTop=u,h&&this.scrollTo(h))}scrollToHorz(){const e=this.columns[0]._widthPx,t=this.element.clientWidth,i=this.element.scrollLeft,s=this.getActiveColElem(),n=Number.parseInt(null==s?void 0:s.style.left,10),r=n+Number.parseInt(null==s?void 0:s.style.width,10);let o=i;n-it&&(o=r-t),o=Math.max(0,o),this.log(`scrollToHorz(${this.activeColIdx}): ${n}..${r}, fixedOfs=${e}, vpWidth=${t}, curLeft=${i} -> ${o}`),this.element.scrollLeft=o}setColumn(e,t){var i,s,n;const r=null==t?void 0:t.edit,o=!1!==(null==t?void 0:t.scrollIntoView);if(f(this.isCellNav(),"Expected cellNav mode"),"string"==typeof e){const t=e;f((e=this.columns.findIndex((t=>t.id===e)))>=0,`Invalid colId: ${t}`)}if(f(0<=e&&e0&&(s?this._updateViewportImmediately():this._updateViewportThrottled())}}setEnabled(e=!0){const t=this.enabled;return this.enabled=!!e,this.element.classList.toggle("wb-disabled",!e),t}isEnabled(){return this.enabled}isGrid(){return this.columns&&this.columns.length>1}isCellNav(){return!!this._cellNavMode}isRowNav(){return!this._cellNavMode}setCellNav(e=!0){var t;const i=this._cellNavMode;this._cellNavMode=!!e,e&&!i&&this.setColumn(0),this.element.classList.toggle("wb-cell-mode",e),null===(t=this.activeNode)||void 0===t||t.update($.status)}setNavigationOption(e,t=!1){if(this.isGrid()||e===z.row)switch(this.options.navigationModeOption=e,e){case z.cell:this.setCellNav(!0);break;case z.row:this.setCellNav(!1);break;case z.startCell:t&&this.setCellNav(!0);break;case z.startRow:t&&this.setCellNav(!1);break;default:v(`Invalid mode '${e}'.`)}else this.logWarn("Plain trees only support row navigation mode.")}setStatus(e,t){return this.root.setStatus(e,t)}setTypes(e,t=!0){f(T(e),`Expected plain objext: ${e}`),t?this.types=e:N(this.types,e);for(const e of Object.values(this.types))e.classes&&(e.classes=A(e.classes))}sortChildren(e=te,t=!1){this.root.sortChildren(e,t)}toDictArray(e){var t;return null!==(t=this.root.toDict(!0,e).children)&&void 0!==t?t:[]}_updateColumnWidths(){const e=this.element.clientWidth,t=this.columns,i=t[0];let s=0,n=0,r=0,o=!1;if("*"!==i.id)throw new Error(`First column must have id '*': got '${i.id}'.`);this._columnsById={};for(const e of t){this._columnsById[e.id]=e;const t=e.width;if("*"===e.id&&e!==i)throw new Error(`Column id '*' must be defined only once: '${e.title}'.`);if(t&&"*"!==t)if("number"==typeof t)e._weight=t,n+=t;else if("string"==typeof t&&t.endsWith("px")){e._weight=0;const i=parseFloat(t.slice(0,-2));e._widthPx!=i&&(o=!0,e._widthPx=i),r+=i}else v(`Invalid column width: ${t} (expected string ending with 'px' or number, e.g. "px" or ).`);else e._weight=1,n+=1}const l=Math.max(0,e-r);let a=0;for(const e of t){let t;if(e._weight){const i=e.minWidth;t="number"==typeof i?i:"string"==typeof i&&i.endsWith("px")?parseFloat(i.slice(0,-2)):4;const s=Math.max(t,l*e._weight/n);e._widthPx!=s&&(o=!0,e._widthPx=s)}e._ofsPx=a,a+=e._widthPx}t[t.length-1]._widthPx-=1,s=a-1;const d=`${s}px`;return this.headerElement.style.width=d,this.listContainerElement.style.width=d,o}_renderHeaderMarkup(){f(this.headerElement,"Expected a headerElement");const e=this.hasHeader();if(E(this.headerElement,e),!e)return;const t=this.columns.length,i=this.headerElement.querySelector(".wb-row");f(i,"Expected a row in header element"),i.innerHTML="".repeat(t);for(let e=0;e${r}${l}`,this.isCellNav()&&n.classList.toggle("wb-active",e===this.activeColIdx)}}updatePendingModifications(){this.pendingChangeTypes.size>0&&this._updateViewportImmediately()}_updateViewportImmediately(){var e;if(this._disableUpdateCount)return this.log(`_updateViewportImmediately() IGNORED (disable level: ${this._disableUpdateCount}).`),void this._disableUpdateIgnoreCount++;this._updateViewportThrottled.pending()&&this._updateViewportThrottled.cancel();const t=P,i=new Set(this.pendingChangeTypes);this.pendingChangeTypes.clear();if(i.has(t.scroll)&&1===i.size)this._updateRows({newNodesOnly:!0});else{if(this.log("_updateViewportImmediately():",i),!1!==this.options.adjustHeight){let e=this.listContainerElement.clientHeight;const t=this.headerElement.clientHeight,i=this.element.clientHeight-t-1;Math.abs(e-i)>1&&(this.listContainerElement.style.height=i+"px",e=i)}i.has(t.clearMarkup)&&this.visit((e=>{e.removeMarkup()})),i.has(t.header)&&(this._updateColumnWidths(),this._renderHeaderMarkup()),this._updateRows()}if(this.options.connectTopBreadcrumb){let t=null===(e=this.getTopmostVpNode(!0))||void 0===e?void 0:e.getPath(!1,"title"," > ");t=t?t+" >":"",this.options.connectTopBreadcrumb.textContent=t}this._callEvent("update")}_updateRows(e){const t=!!(e=Object.assign({newNodesOnly:!1},e)).newNodesOnly,i=this.element.clientHeight,s=this.element.scrollTop;let n=Math.max(0,s/22-5);n=Math.floor(n),n%2&&n--;let r=Math.max(0,(s+i)/22+5);r=Math.ceil(r);const o=new Set;this.nodeListElement.childNodes.forEach((e=>{const t=e;o.add(t._wb_node)}));let l=0,a=0,d=!1,c="first";this.visitRows((function(e){const i=e._rowElem;e._rowIdx!==l&&(e._rowIdx=l,d=!0),lr?i&&(c=i):i&&t?(o.delete(e),i.style.top=l*Q+"px",c=i):(o.delete(e),i&&(i.style.top=l*Q+"px"),e._render({top:a,after:c}),c=e._rowElem),l++,a+=22})),this.treeRowCount=l;for(const e of o)e._callEvent("discard"),e.removeMarkup();return this.nodeListElement.style.height=`${a}px`,d}visit(e){return this.root.visit(e,!1)}visitRows(e,t){if(!this.root.hasChildren())return!1;if(t&&t.reverse)return delete t.reverse,this._visitRowsUp(e,t);let i,s,n,r,o,l,a=0,d=!1===(t=t||{}).includeSelf,c=t.start||this.root.children[0];const h=!!t.includeHidden,u=!h&&"hide"===this.filterMode;for(n=c.parent;n;){for(o=n.children,s=o.indexOf(c)+a,f(s>=0,`Could not find ${c} in parent's children: ${n}`),i=s;it!==l&&(!u||t.match||t.subMatchCount?!1!==e(t)&&(h||!t.children||t.expanded?void 0:"skip"):"skip")),!1),!1===r))return!1}}c=n,n=n.parent,a=1,!n&&t.wrap&&(this.logDebug("visitRows(): wrap around"),f(t.start,"`wrap` option requires `start`"),l=t.start,t.wrap=!1,n=this.root,a=0)}return!0}_visitRowsUp(e,t){let i,s,n,r=t.start||this.root.children[0];const o=!!t.includeHidden;if(!1!==t.includeSelf&&!1===e(r))return!1;for(;;){if(n=r.parent,i=n.children,i[0]===r){if(r=n,!r.parent)break;i=n.children}else for(s=i.indexOf(r),r=i[s-1];(o||r.expanded)&&r.children&&r.children.length;)i=r.children,n=r,r=i[i.length-1];if((o||r.isVisible())&&!1===e(r))return!1}return!0}load(e){return this.clear(),this.root.load(e)}enableUpdate(e){e?(f(this._disableUpdateCount>0,"enableUpdate(true) was called too often"),this._disableUpdateCount--,0===this._disableUpdateCount&&(this.logDebug(`enableUpdate(): active again. Re-painting to catch up with ${this._disableUpdateIgnoreCount} ignored update requests...`),this._disableUpdateIgnoreCount=0,this.update($.any,{immediate:!0}))):this._disableUpdateCount++}filterNodes(e,t){return this.extensions.filter.filterNodes(e,t)}filterBranches(e,t){return this.extensions.filter.filterBranches(e,t)}clearFilter(){return this.extensions.filter.clearFilter()}isFilterActive(){return!!this.filterMode}updateFilter(){return this.extensions.filter.updateFilter()}}pe.sequence=0,pe.version="v0.8.2",pe.util=U,e.Wunderbaum=pe})); +//# sourceMappingURL=wunderbaum.umd.min.js.map diff --git a/orochi/static/js/wunderbaum/wunderbaum.umd.min.js.map b/orochi/static/js/wunderbaum/wunderbaum.umd.min.js.map new file mode 100644 index 00000000..d7535173 --- /dev/null +++ b/orochi/static/js/wunderbaum/wunderbaum.umd.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"wunderbaum.umd.js","names":["global","factory","exports","module","define","amd","globalThis","self","mar10","this","freeGlobal","Object","freeGlobalThis","freeSelf","root","Function","isObject","value","type","debounce","func","wait","options","lastArgs","lastThis","maxWait","result","timerId","lastCallTime","lastInvokeTime","leading","maxing","trailing","useRAF","requestAnimationFrame","TypeError","invokeFunc","time","args","thisArg","undefined","apply","startTimer","pendingFunc","cancelAnimationFrame","setTimeout","shouldInvoke","timeSinceLastCall","timerExpired","Date","now","trailingEdge","timeSinceLastInvoke","timeWaiting","Math","min","remainingWait","debounced","isInvoking","leadingEdge","max","cancel","id","clearTimeout","cancelTimer","flush","pending","throttle","MOUSE_BUTTONS","isMac","nav","navigator","test","platform","_getUserInfo","REX_HTML","REX_TOOLTIP","ENTITY_MAP","ValidationError","Error","constructor","message","super","name","assert","cond","msg","documentReady","callback","document","readyState","addEventListener","error","escapeHtml","s","replace","escapeRegex","escapeTooltip","getValueFromElem","elem","coerce","tag","tagName","classList","contains","span","embeddedInput","querySelector","innerText","input","indeterminate","checked","valueAsDate","valueAsNumber","parentElement","setElemDisplay","flag","style","elemFromSelector","display","elemFromHtml","html","t","createElement","innerHTML","trim","content","firstElementChild","_IGNORE_KEYS","Set","obj","eventToString","event","key","et","altKey","push","ctrlKey","metaKey","shiftKey","button","has","join","extend","i","length","arg","prototype","hasOwnProperty","call","isArray","Array","isEmptyObject","keys","isPlainObject","toString","onEvent","rootTarget","eventNames","selectorOrHandler","handlerOrNone","selector","handler","split","forEach","evn","e","target","matches","closest","overrideMethod","instance","methodName","ctx","prevSuper","prevSuperApply","prevFunc","_super","_superApply","argsArray","getOption","opts","defaultValue","ext","indexOf","toSet","val","set","c","add","adaptiveThrottle","assign","minDelay","defaultDelay","maxDelay","delayFactor","waiting","pendingArgs","pendingTimer","throttledFn","useArgs","start","console","elap","curDelay","useDelay","ChangeType","RenderFlag","NodeStatusType","NodeRegion","NavModeEnum","util","freeze","__proto__","Deferred","thens","catches","status","resolve","resolvedValue","reject","rejectedError","then","cb","unshift","promise","catch","MAX_INT","documentReadyPromise","Promise","each","k","extractHtmlText","isFunction","noop","setTimeoutPromise","ms","err","setValueToElem","select","selectedIndex","sleep","async","toggleCheckbox","element","tristate","toLowerCase","WunderbaumExtension","tree","defaults","enabled","treeOpts","extensionOpts","getPluginOption","init","_a","setPluginOption","setEnabled","onKeyEvent","data","onRender","START_MARKER","END_MARKER","RE_START_MARKER","RegExp","RE_END_MARTKER","FilterExtension","connectInput","autoApply","autoExpand","counter","fuzzy","hideExpandedCounter","hideExpanders","highlight","leavesOnly","mode","noData","lastFilterArgs","queryInput","filterNodes","filterMode","updateFilter","_applyFilterNoUpdate","filter","branchMode","_opts","runWithDeferredUpdate","_applyFilterImpl","match","temp","count","prevAutoCollapse","autoCollapse","hideMode","logInfo","clearFilter","map","reduce","a","b","re","reHighlight","node","title","text","res","escapeTitles","matchingIndices","_matchingArrIdx","_mIdx","textPoses","v","_markFuzzyMatchedChars","titleWithHighlight","arguments","toggle","subMatchCount","visit","setStatus","ok","children","matchedByBranch","parent","visitParents","p","expanded","setExpanded","noAnimation","noEvents","_filterAutoExpanded","filterBranches","logWarn","enableUpdate","remove","KeynavExtension","_getEmbeddedInputElem","ace","getActiveColElem","_isCurInputFocused","activate","autoActivate","curInput","inputHasFocus","navModeOption","navigationModeOption","focusNode","eventName","handled","isEnabled","_callEvent","_callMethod","currentNode","getFocusNode","getActiveNode","firstNode","getFirstChild","setActive","setFocus","isColspan","isRowNav","blur","_render","quicksearch","stamp","lastQuicksearchTime","lastQuicksearchTerm","matchNode","findNextNode","preventDefault","isActive","isExpanded","isExpandable","startCell","startRow","setCellNav","toggleSelected","navigate","curInputType","inputCanFocus","logDebug","setCustomValidity","setColumn","activeColIdx","checkValidity","focus","click","log","isCellNav","cell","columns","LoggerExtension","ignoreEvents","prefix","extra","ROW_HEIGHT","TEST_IMG","iconMaps","bootstrap","loading","expanderExpanded","expanderCollapsed","expanderLazy","checkChecked","checkUnchecked","checkUnknown","radioChecked","radioUnchecked","radioUnknown","folder","folderOpen","folderLazy","doc","fontawesome6","RESERVED_TREE_SOURCE_KEYS","KEY_TO_ACTION_DICT","Add","ArrowDown","ArrowLeft","ArrowRight","ArrowUp","Backspace","Divide","End","Home","Multiply","PageDown","PageUp","Subtract","makeNodeTitleMatcher","nodeTitleSorter","x","y","decompressSourceData","source","_format","_version","_keyMap","_valueMap","longToShort","shortToLong","entries","warn","_typeList","_b","_c","_positional","includes","positionalShort","newChildren","keyToNodeMap","indexToNodeMap","keyAttrName","childrenAttrName","index","nodeTuple","parentId","kwargs","positionalIdx","parentNode","unflattenSource","_iter","childList","getOwnPropertyNames","propName","longName","newValue","nodeMimeType","DndExtension","autoExpandMS","multiSource","effectAllowed","dropEffectDefault","guessDropEffect","preventForeignNodes","preventLazyParents","preventNonNodes","preventRecursion","preventSameParent","preventVoidMoves","serializeClipboardData","scroll","scrollSensitivity","scrollSpeed","sourceCopyHook","dragStart","drag","dragEnd","dragEnter","dragOver","dragExpand","drop","dragLeave","srcNode","lastTargetNode","lastEnterStamp","lastAllowedDropRegions","lastDropEffect","lastDropRegion","currentScrollDir","applyScrollDirThrottled","_applyScrollDir","dndOpts","dnd","onDragEvent","bind","onDropEvent","_leaveNode","ltn","setClass","unifyDragover","size","_calcDropRegion","allowed","dy","offsetY","_guessDropEffect","ea","canCopy","canLink","canMove","_isVoidDrop","targetNode","dropRegion","getNextSibling","getPrevSibling","isDragging","sp","scrollTop","_autoScroll","viewportY","sensitivity","headerHeight","headerElement","clientHeight","height","offsetHeight","scrollHeight","Wunderbaum","getNode","dataTransfer","isEditingTitle","nodeData","toDict","n","_orgKey","_treeId","setData","JSON","stringify","types","srcTree","dt","_t","pred","dropEffect","isStatusNode","isLoaded","isAncestorOf","regionSet","sourceNode","clientY","offsetTop","region","_isLoading","stopPropagation","getData","parse","suggestedDropMode","suggestedDropEffect","sourceNodeData","DragObserver","dragElem","dragging","events","thresh","_handler","handleEvent","disconnect","removeEventListener","getDragElem","stopDrag","cb_event","dragstop","dx","pageX","pageY","dragstart","GridExtension","observer","window","handleDrag","info","getEventInfo","_promise","_resolve","_reject","reason","finally","NODE_PROPS","NODE_DICT_PROPS","delete","WunderbaumNode","refKey","classes","_requestId","_errorInfo","_partsel","_partload","_rowIdx","_rowElem","sequence","icon","lazy","statusNodeType","colspan","checkbox","radiogroup","selected","unselectable","_registerNode","Symbol","iterator","cl","l","typeInfo","addChildren","before","applyMinExpanLevel","_level","getLevel","nodeList","forceExpand","minExpandLevel","child","subChildren","isUnloaded","concat","findDirectChild","pos","splice","update","structure","addNode","applyCommand","cmd","collapseSiblings","className","cnSet","cn","startEditTitle","expandAll","depth","loadLazy","force","keepActiveNodeVisible","expandOpts","scrollIntoView","logTime","level","level_1","promises","all","logTimeEnd","activeNode","findAll","matcher","ptr","findFirst","findRelatedNode","where","includeHidden","format_iter","name_cb","connectors","_is_last","ca","_format_line","parts","format","line","getColElem","colIdx","findIndex","colElems","querySelectorAll","getCloneList","includeSelf","clones","findByRefKey","getLastChild","ac","idx","getParent","getParentList","includeRoot","dtn","getPath","part","separator","path","isFunc","hasChildren","hasClass","other","isDescendantOf","isChildOf","isClone","andCollapsed","emptyChildListExpandable","isFirstSibling","isLastSibling","isLazy","isLoading","isPagingNode","isParentOf","isPartload","isPartsel","isRadio","isRendered","isRootNode","isSelected","isTopLevel","isVisible","hasFilter","parents","_loadSourceObject","response","setTypes","colStructure","selectMode","fixSelection3FromEndNodes","_fetchWithOptions","url","params","body","rest","fetchOpts","method","URLSearchParams","fetch","json","load","requestId","prevParent","elapLoad","elapProcess","startProcess","logError","debugLevel","forceReload","wasExpanded","resetLazy","debug","makeVisible","dfd","deferreds","len","seOpts","updatePendingModifications","moveTo","targetParent","triggerModifyChild","any","triggerModify","removeMarkup","_unregisterNode","removeChildren","_setFocusNode","_wb_node","_getRenderInfo","allColInfosById","renderColInfosById","col","_createIcon","iconMap","parentElem","replaceChild","showLoading","iconSpan","appendChild","cbRes","badge","tooltip","badgeClass","badgeTooltip","append","_render_markup","treeOptions","rowDiv","checkboxSpan","expanderSpan","isNew","after","top","nodeElem","ofsTitlePx","titleSpan","_ofsTitlePx","draggable","colElem","left","_ofsPx","width","_widthPx","nodeListElement","prepend","_render_data","preventScroll","textContent","skeleton","vpWidth","clientWidth","isDataChange","_render_status","renderInfo","rowClasses","image","backgroundImage","cbclass","colSpan","resizeCols","ofs","colDef","change","row","recursive","dict","scrollTo","prev","retrigger","focusTree","orgEvent","edit","nextNode","prevNode","_setActiveNode","immediate","sendEvents","updateOpts","lastChild","topNode","setIcon","setKey","getSelectedNodes","stopOnParents","_anySelectable","setSelected","found","_changeSelectStatusProps","state","changed","fixSelection3AfterClick","_walk","allSelected","someSelected","canSelect","propagateDown","sibling","details","statusNode","_setStatusNode","firstChild","_clearStatusNode","strings","loadError","setTitle","_sortChildren","cmp","deep","sort","sortChildren","operation","modifyChild","visitSiblings","isMatched","EditExtension","minlength","maxlength","trigger","slowClickDelay","validity","beforeEdit","curEditNode","relatedNode","debouncedOnChange","_onChange","_applyChange","inputElem","validationMessage","reportValidity","inputValue","inputValid","_preprocessKeyEvent","_stopEditTitle","inputHtml","opt","stopEditTitle","focusElem","activeElement","forceClose","errMsg","oldValue","createNode","newNode","WbSystemRoot","_activeNode","_focusNode","extensionList","extensions","keyMap","Map","refKeyMap","treeRowCount","_disableUpdateCount","_disableUpdateIgnoreCount","_columnsById","pendingChangeTypes","_util","_cellNavMode","lastClickTime","header","rowHeightPx","fixedCol","showSpinner","connectTopBreadcrumb","iconBadge","receive","readyDeferred","ready","readyOk","_registerExtension","_updateViewportThrottled","_updateViewportImmediately","getAttribute","tabIndex","_wb_tree","wantHeader","rowElement","colDiv","dataset","coldivs","repeat","listContainerElement","_initExtensions","optName","setOption","isGrid","setNavigationOption","resizeObserver","ResizeObserver","resize","observe","mouseEvent","expander","scrollIntoViewOnExpandClick","_callHook","getTree","el","treeElem","Element","extension","rk","rks","get","hook","d","_getNodeByRowIdx","visitRows","getTopmostVpNode","complete","topIdx","ceil","floor","getLowestVpNode","scrollParent","bottomIdx","_getPrevNodeInView","reverse","_getNextNodeInView","nodeOrOpts","refNode","clear","destroy","outerHTML","hasFocus","hasHeader","hint","selectAll","toggleSelect","_selectRange","eventInfo","visible","_check","from","findKey","startNode","reMatch","makeNodeTitleStartMatcher","_checkNode","pageSize","bottomNode","parentCol","canonicalName","unknown","colId","column","KeyboardEvent","isEditing","label","timeEnd","vpHeight","rowTop","vpTop","vpRowTop","vpRowBottom","newScrollTop","scrollToHorz","fixedWidth","scrollLeft","colLeft","Number","parseInt","colRight","newLeft","cid","setActiveNode","RF","clearMarkup","redraw","reset","values","toDictArray","_updateColumnWidths","col0","totalWidth","totalWeight","modified","cw","_weight","endsWith","px","parseFloat","slice","restPx","ofsPx","minWidth","cmw","tw","_renderHeaderMarkup","colCount","headerRow","headerClasses","resizer","_updateRows","newNodesOnly","adjustHeight","wantHeight","abs","vp_height","startIdx","endIdx","obsoleteNodes","childNodes","tr","prevElem","_visitRowsUp","nextIdx","siblings","stopNode","siblingOfs","skipFirstNode","checkFilter","wrap","isFilterActive","version"],"sources":["wunderbaum.umd.js"],"mappings":"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"} diff --git a/orochi/templates/base.html b/orochi/templates/base.html index d4aa82c5..70c59b71 100644 --- a/orochi/templates/base.html +++ b/orochi/templates/base.html @@ -1,4 +1,4 @@ -{% load static i18n %} +{% load static i18n custom_tags %} @@ -12,7 +12,7 @@ {% block css %} - + @@ -36,23 +36,30 @@ {% if request.user.is_authenticated %}