From dc11fa26e7ba899f0e6ae16d81beccf497f2e9da Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Mon, 15 Apr 2024 22:15:29 -0400 Subject: [PATCH] rename to daggre --- .bumpversion.cfg | 2 +- LICENSE | 2 +- README.md | 14 +- examples/ipc/main.py | 6 +- examples/js/index.html | 4 +- examples/js/index.js | 4 +- examples/python/index.html | 4 +- examples/python/index.js | 4 +- examples/python/server.py | 4 +- js/package.json | 6 +- js/src/core/graph.js | 2 +- js/src/index.css | 38 +- package.json | 4 +- python/LICENSE | 2 +- python/MANIFEST.in | 4 +- python/Makefile | 14 +- python/README.md | 14 +- python/{dagred3 => daggre}/__init__.py | 0 python/{dagred3 => daggre}/core/__init__.py | 0 python/{dagred3 => daggre}/core/common.py | 0 python/{dagred3 => daggre}/core/edge.py | 0 python/{dagred3 => daggre}/core/exceptions.py | 0 python/{dagred3 => daggre}/core/graph.py | 0 python/{dagred3 => daggre}/core/node.py | 0 python/daggre/static/index.css | 33 + python/{dagred3 => daggre}/static/index.js | 1165 ++++++++++++----- python/{dagred3 => daggre}/tests/__init__.py | 0 python/{dagred3 => daggre}/tests/conftest.py | 2 +- python/{dagred3 => daggre}/tests/test_core.py | 4 +- .../tests/test_graph_generator_helper.py | 2 +- .../tests/test_transport.py | 2 +- .../transports/__init__.py | 0 .../{dagred3 => daggre}/transports/client.py | 0 .../transports/connection.py | 0 .../transports/exceptions.py | 0 .../transports/handlers/__init__.py | 0 .../transports/handlers/aiohttp_client.py | 0 .../transports/handlers/starlette.py | 0 python/{dagred3 => daggre}/transports/json.py | 0 .../{dagred3 => daggre}/transports/model.py | 0 .../{dagred3 => daggre}/transports/server.py | 0 .../transports/transport.py | 0 .../{dagred3 => daggre}/transports/update.py | 0 .../{dagred3 => daggre}/transports/utils.py | 0 python/dagred3/static/index.css | 33 - python/pyproject.toml | 24 +- 46 files changed, 926 insertions(+), 467 deletions(-) rename python/{dagred3 => daggre}/__init__.py (100%) rename python/{dagred3 => daggre}/core/__init__.py (100%) rename python/{dagred3 => daggre}/core/common.py (100%) rename python/{dagred3 => daggre}/core/edge.py (100%) rename python/{dagred3 => daggre}/core/exceptions.py (100%) rename python/{dagred3 => daggre}/core/graph.py (100%) rename python/{dagred3 => daggre}/core/node.py (100%) create mode 100644 python/daggre/static/index.css rename python/{dagred3 => daggre}/static/index.js (95%) rename python/{dagred3 => daggre}/tests/__init__.py (100%) rename python/{dagred3 => daggre}/tests/conftest.py (87%) rename python/{dagred3 => daggre}/tests/test_core.py (93%) rename python/{dagred3 => daggre}/tests/test_graph_generator_helper.py (97%) rename python/{dagred3 => daggre}/tests/test_transport.py (97%) rename python/{dagred3 => daggre}/transports/__init__.py (100%) rename python/{dagred3 => daggre}/transports/client.py (100%) rename python/{dagred3 => daggre}/transports/connection.py (100%) rename python/{dagred3 => daggre}/transports/exceptions.py (100%) rename python/{dagred3 => daggre}/transports/handlers/__init__.py (100%) rename python/{dagred3 => daggre}/transports/handlers/aiohttp_client.py (100%) rename python/{dagred3 => daggre}/transports/handlers/starlette.py (100%) rename python/{dagred3 => daggre}/transports/json.py (100%) rename python/{dagred3 => daggre}/transports/model.py (100%) rename python/{dagred3 => daggre}/transports/server.py (100%) rename python/{dagred3 => daggre}/transports/transport.py (100%) rename python/{dagred3 => daggre}/transports/update.py (100%) rename python/{dagred3 => daggre}/transports/utils.py (100%) delete mode 100644 python/dagred3/static/index.css diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 87dcb83..3ed66a2 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -3,7 +3,7 @@ current_version = 0.1.0 commit = True tag = False -[bumpversion:file:python/dagred3/__init__.py] +[bumpversion:file:python/daggre/__init__.py] search = __version__ = "{current_version}" replace = __version__ = "{new_version}" diff --git a/LICENSE b/LICENSE index 1e4da80..6336844 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2023 the dagre-d3-lite authors + Copyright 2023 the daggre authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 8ddf8b5..22e2cfd 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# dagre-d3-lite -A convenience layer on top of `dagre-d3` (`dagre-d3-es`), for use in [ipydagred3](https://github.com/timkpaine/ipydagred3). Built on [transports](https://github.com/timkpaine/transports). +# daggre +A convenience layer on top of `dagre-d3` (`dagre-d3-es`), for use in [ipydagred3](https://github.com/timkpaine/ipydaggre). Built on [transports](https://github.com/timkpaine/transports). -[![Build Status](https://github.com/timkpaine/dagre-d3-lite/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/timkpaine/dagre-d3-lite/actions?query=workflow%3A%22Build+Status%22) -[![codecov](https://codecov.io/gh/timkpaine/dagre-d3-lite/branch/main/graph/badge.svg?token=3N6NOPL4RE)](https://codecov.io/gh/timkpaine/dagre-d3-lite) -[![License](https://img.shields.io/github/license/timkpaine/dagre-d3-lite)](https://github.com/timkpaine/dagre-d3-lite) -[![PyPI](https://img.shields.io/pypi/v/dagred3.svg)](https://pypi.python.org/pypi/dagred3) -[![npm](https://img.shields.io/npm/v/dagre-d3-lite.svg)](https://www.npmjs.com/package/dagre-d3-lite) +[![Build Status](https://github.com/timkpaine/daggre/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/timkpaine/daggre/actions?query=workflow%3A%22Build+Status%22) +[![codecov](https://codecov.io/gh/timkpaine/daggre/branch/main/graph/badge.svg?token=3N6NOPL4RE)](https://codecov.io/gh/timkpaine/daggre) +[![License](https://img.shields.io/github/license/timkpaine/daggre)](https://github.com/timkpaine/daggre) +[![PyPI](https://img.shields.io/pypi/v/daggre.svg)](https://pypi.python.org/pypi/daggre) +[![npm](https://img.shields.io/npm/v/daggre.svg)](https://www.npmjs.com/package/daggre) diff --git a/examples/ipc/main.py b/examples/ipc/main.py index 48d5953..aa374a7 100644 --- a/examples/ipc/main.py +++ b/examples/ipc/main.py @@ -8,9 +8,9 @@ from fastapi import FastAPI, WebSocket sys.path.append("../../python") # noqa -from dagred3 import Graph # noqa: E402 -from dagred3 import (AioHttpWebSocketClient, JSONTransport, - StarletteWebSocketServer) +from daggre import Graph # noqa: E402 +from daggre import (AioHttpWebSocketClient, JSONTransport, + StarletteWebSocketServer) def run_server(): diff --git a/examples/js/index.html b/examples/js/index.html index bc2300a..3e35c90 100644 --- a/examples/js/index.html +++ b/examples/js/index.html @@ -7,11 +7,11 @@ -
+
diff --git a/examples/js/index.js b/examples/js/index.js index 4f255bc..24ab5d3 100644 --- a/examples/js/index.js +++ b/examples/js/index.js @@ -1,10 +1,10 @@ // eslint-disable-next-line import/no-extraneous-dependencies -import { Graph } from "dagre-d3-lite"; +import { Graph } from "daggre"; const SCALE = 10; document.addEventListener("DOMContentLoaded", () => { - const div = document.querySelector("div.dagred3"); + const div = document.querySelector("div.daggre"); const graph = new Graph({ direction: "left-to-right" }); let begin = 0; diff --git a/examples/python/index.html b/examples/python/index.html index bc2300a..3e35c90 100644 --- a/examples/python/index.html +++ b/examples/python/index.html @@ -7,11 +7,11 @@ -
+
diff --git a/examples/python/index.js b/examples/python/index.js index 2b57fca..c2df5b5 100644 --- a/examples/python/index.js +++ b/examples/python/index.js @@ -1,5 +1,5 @@ // eslint-disable-next-line import/no-extraneous-dependencies -import { Graph, WebSocketClient, JSONTransport } from "dagre-d3-lite"; +import { Graph, WebSocketClient, JSONTransport } from "daggre"; document.addEventListener("DOMContentLoaded", async () => { const jst = new JSONTransport(); @@ -8,7 +8,7 @@ document.addEventListener("DOMContentLoaded", async () => { jst.hosts(Graph); try { const graph = await handler.initial(); - const div = document.querySelector("div.dagred3"); + const div = document.querySelector("div.daggre"); graph.render(div); await handler.handle(); } catch { diff --git a/examples/python/server.py b/examples/python/server.py index 697705f..dd9e9a3 100644 --- a/examples/python/server.py +++ b/examples/python/server.py @@ -10,8 +10,8 @@ from fastapi.staticfiles import StaticFiles sys.path.append("../../python") # noqa -from dagred3 import JSONTransport # noqa: E402 -from dagred3 import Graph, StarletteWebSocketServer +from daggre import JSONTransport # noqa: E402 +from daggre import Graph, StarletteWebSocketServer def build_app(): diff --git a/js/package.json b/js/package.json index 379d3d0..1ef9746 100644 --- a/js/package.json +++ b/js/package.json @@ -1,9 +1,9 @@ { - "name": "dagre-d3-lite", + "name": "daggre", "version": "0.1.0", "description": "Convenience layer for dagre-d3", "main": "dist/iexjs.js", - "repository": "git@github.com:timkpaine/dagre-d3-lite.git", + "repository": "git@github.com:timkpaine/daggre.git", "author": "Tim Paine ", "license": "Apache-2.0", "type": "module", @@ -16,7 +16,7 @@ ], "scripts": { "build:esbuild": "esbuild src/index.js --bundle --format=esm --outdir=dist/", - "build:python": "esbuild src/index.js --bundle --format=esm --outdir=../python/dagred3/static/", + "build:python": "esbuild src/index.js --bundle --format=esm --outdir=../python/daggre/static/", "build": "npm-run-all -p build:*", "clean": "rimraf dist lib", "fix": "yarn lint --fix", diff --git a/js/src/core/graph.js b/js/src/core/graph.js index 19cf5e2..4d9663c 100644 --- a/js/src/core/graph.js +++ b/js/src/core/graph.js @@ -256,7 +256,7 @@ export class Graph extends Model { // only run on first rendering if (!this._rendered) { // add class to `renderpoint` - renderpoint.classList.add("dagred3-container"); + renderpoint.classList.add("daggre-container"); // create svg and g elements this._graph_svg_inst = d3.select(renderpoint).append("svg"); diff --git a/js/src/index.css b/js/src/index.css index 65e6b89..9c0c817 100644 --- a/js/src/index.css +++ b/js/src/index.css @@ -1,42 +1,42 @@ -div.dagred3-container { +div.daggre-container { /* min-height: 600px; */ /* min-width: 800px; */ /* resize: both; */ } - - div.dagred3-container > svg { + + div.daggre-container > svg { height: 100%; width: 100%; } - - .dagred3-container .node rect, - .dagred3-container .node circle, - .dagred3-container .node ellipse, - .dagred3-container .node polygon { + + .daggre-container .node rect, + .daggre-container .node circle, + .daggre-container .node ellipse, + .daggre-container .node polygon { stroke: #555; fill: #fff; } - - .dagred3-container .edgePath path { + + .daggre-container .edgePath path { stroke: #555; fill: transparent; stroke-width: 1.5px; } - - .dagred3-container .edgeLabel foreignObject { + + .daggre-container .edgeLabel foreignObject { overflow: visible; } - - .dagred3-container .edgeLabel foreignObject u { + + .daggre-container .edgeLabel foreignObject u { text-decoration: none; } - - .dagred3-container .node text { + + .daggre-container .node text { pointer-events: none; } - - - div.dagred3-tooltip { + + + div.daggre-tooltip { background-color: rgba(255, 255, 255, .8); border: 1px solid #555; padding: 15px; diff --git a/package.json b/package.json index 1702de8..147d05c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, - "name": "dagre-d3-lite", - "repository": "git@github.com:timkpaine/dagre-d3-lite.git", + "name": "daggre", + "repository": "git@github.com:timkpaine/daggre.git", "author": "Tim Paine ", "license": "Apache-2.0", "type": "module", diff --git a/python/LICENSE b/python/LICENSE index 1e4da80..6336844 100644 --- a/python/LICENSE +++ b/python/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2023 the dagre-d3-lite authors + Copyright 2023 the daggre authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/python/MANIFEST.in b/python/MANIFEST.in index 2d94ef3..082126d 100644 --- a/python/MANIFEST.in +++ b/python/MANIFEST.in @@ -3,8 +3,8 @@ include README.md include pyproject.toml -graft dagred3 -graft dagred3/static +graft daggre +graft daggre/static # get rid of test and lint artifacts prune .pytest_cache diff --git a/python/Makefile b/python/Makefile index 0a4fec9..26735ec 100644 --- a/python/Makefile +++ b/python/Makefile @@ -20,7 +20,7 @@ install: prebuild ## install to site-packages # Testing # ########### test: ## Clean and Make unit tests - python -m pytest -v dagred3/tests --junitxml=junit.xml --cov=dagred3 --cov-branch --cov-fail-under=75 --cov-report term-missing --cov-report xml + python -m pytest -v daggre/tests --junitxml=junit.xml --cov=daggre --cov-branch --cov-fail-under=75 --cov-report term-missing --cov-report xml tests: test @@ -28,16 +28,16 @@ tests: test # Linting # ########### lint: ## Black/flake8 python - python -m ruff check dagred3 setup.py + python -m ruff check daggre setup.py python -m ruff check ../examples/*/*.py - python -m isort dagred3 setup.py --check + python -m isort daggre setup.py --check python -m isort ../examples/*/*.py --check fix: ## Black python - python -m ruff format dagred3 setup.py + python -m ruff format daggre setup.py python -m ruff format ../examples/*/*.py - python -m isort dagred3 setup.py + python -m isort daggre setup.py python -m isort ../examples/*/*.py format: fix @@ -53,7 +53,7 @@ check-manifest: prebuild ## run manifest checker for sdist check-manifest -v annotate: ## run mypy type annotation - mypy dagred3/ + mypy daggre/ ################ # Distribution # @@ -72,7 +72,7 @@ clean: ## clean the repository find . -name "*.pyc" | xargs rm -rf find . -name ".ipynb_checkpoints" | xargs rm -rf rm -rf .coverage coverage *.xml build dist *.egg-info lib node_modules .pytest_cache *.egg-info - rm -rf dagred3/labextension dagred3/nbextension/static/index* + rm -rf daggre/labextension daggre/nbextension/static/index* git clean -fd ########### diff --git a/python/README.md b/python/README.md index 83d2165..c2d762c 100644 --- a/python/README.md +++ b/python/README.md @@ -1,8 +1,8 @@ -# dagre-d3-lite -A convenience layer on top of `dagre-d3` (`dagre-d3-es`), for use in [ipydagred3](https://github.com/timkpaine/ipydagred3). Built on [transports](https://github.com/timkpaine/transports). +# daggre +A convenience layer on top of `dagre-d3` (`dagre-d3-es`), for use in [ipydagred3](https://github.com/timkpaine/ipydaggre). Built on [transports](https://github.com/timkpaine/transports). -[![Build Status](https://github.com/timkpaine/dagre-d3-lite/workflows/Build%20Status/badge.svg?branch=main)](https://github.com/timkpaine/dagre-d3-lite/actions?query=workflow%3A%22Build+Status%22) -[![codecov](https://codecov.io/gh/timkpaine/dagre-d3-lite/branch/main/graph/badge.svg?token=3N6NOPL4RE)](https://codecov.io/gh/timkpaine/dagre-d3-lite) -[![License](https://img.shields.io/github/license/timkpaine/dagre-d3-lite)](https://github.com/timkpaine/dagre-d3-lite) -[![PyPI](https://img.shields.io/pypi/v/dagred3.svg)](https://pypi.python.org/pypi/dagred3) -[![npm](https://img.shields.io/npm/v/dagre-d3-lite.svg)](https://www.npmjs.com/package/dagre-d3-lite) +[![Build Status](https://github.com/timkpaine/daggre/workflows/Build%20Status/badge.svg?branch=main)](https://github.com/timkpaine/daggre/actions?query=workflow%3A%22Build+Status%22) +[![codecov](https://codecov.io/gh/timkpaine/daggre/branch/main/graph/badge.svg?token=3N6NOPL4RE)](https://codecov.io/gh/timkpaine/daggre) +[![License](https://img.shields.io/github/license/timkpaine/daggre)](https://github.com/timkpaine/daggre) +[![PyPI](https://img.shields.io/pypi/v/daggre.svg)](https://pypi.python.org/pypi/daggre) +[![npm](https://img.shields.io/npm/v/daggre.svg)](https://www.npmjs.com/package/daggre) diff --git a/python/dagred3/__init__.py b/python/daggre/__init__.py similarity index 100% rename from python/dagred3/__init__.py rename to python/daggre/__init__.py diff --git a/python/dagred3/core/__init__.py b/python/daggre/core/__init__.py similarity index 100% rename from python/dagred3/core/__init__.py rename to python/daggre/core/__init__.py diff --git a/python/dagred3/core/common.py b/python/daggre/core/common.py similarity index 100% rename from python/dagred3/core/common.py rename to python/daggre/core/common.py diff --git a/python/dagred3/core/edge.py b/python/daggre/core/edge.py similarity index 100% rename from python/dagred3/core/edge.py rename to python/daggre/core/edge.py diff --git a/python/dagred3/core/exceptions.py b/python/daggre/core/exceptions.py similarity index 100% rename from python/dagred3/core/exceptions.py rename to python/daggre/core/exceptions.py diff --git a/python/dagred3/core/graph.py b/python/daggre/core/graph.py similarity index 100% rename from python/dagred3/core/graph.py rename to python/daggre/core/graph.py diff --git a/python/dagred3/core/node.py b/python/daggre/core/node.py similarity index 100% rename from python/dagred3/core/node.py rename to python/daggre/core/node.py diff --git a/python/daggre/static/index.css b/python/daggre/static/index.css new file mode 100644 index 0000000..a2aa5ee --- /dev/null +++ b/python/daggre/static/index.css @@ -0,0 +1,33 @@ +/* src/index.css */ +div.daggre-container { +} +div.daggre-container > svg { + height: 100%; + width: 100%; +} +.daggre-container .node rect, +.daggre-container .node circle, +.daggre-container .node ellipse, +.daggre-container .node polygon { + stroke: #555; + fill: #fff; +} +.daggre-container .edgePath path { + stroke: #555; + fill: transparent; + stroke-width: 1.5px; +} +.daggre-container .edgeLabel foreignObject { + overflow: visible; +} +.daggre-container .edgeLabel foreignObject u { + text-decoration: none; +} +.daggre-container .node text { + pointer-events: none; +} +div.daggre-tooltip { + background-color: rgba(255, 255, 255, .8); + border: 1px solid #555; + padding: 15px; +} diff --git a/python/dagred3/static/index.js b/python/daggre/static/index.js similarity index 95% rename from python/dagred3/static/index.js rename to python/daggre/static/index.js index 1ca16ea..132da53 100644 --- a/python/dagred3/static/index.js +++ b/python/daggre/static/index.js @@ -1,8 +1,615 @@ +var __create = Object.create; var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; +}; + +// ../node_modules/lodash/isObject.js +var require_isObject = __commonJS({ + "../node_modules/lodash/isObject.js"(exports2, module2) { + function isObject2(value) { + var type2 = typeof value; + return value != null && (type2 == "object" || type2 == "function"); + } + module2.exports = isObject2; + } +}); + +// ../node_modules/lodash/_freeGlobal.js +var require_freeGlobal = __commonJS({ + "../node_modules/lodash/_freeGlobal.js"(exports2, module2) { + var freeGlobal2 = typeof global == "object" && global && global.Object === Object && global; + module2.exports = freeGlobal2; + } +}); + +// ../node_modules/lodash/_root.js +var require_root = __commonJS({ + "../node_modules/lodash/_root.js"(exports2, module2) { + var freeGlobal2 = require_freeGlobal(); + var freeSelf2 = typeof self == "object" && self && self.Object === Object && self; + var root3 = freeGlobal2 || freeSelf2 || Function("return this")(); + module2.exports = root3; + } +}); + +// ../node_modules/lodash/now.js +var require_now = __commonJS({ + "../node_modules/lodash/now.js"(exports2, module2) { + var root3 = require_root(); + var now3 = function() { + return root3.Date.now(); + }; + module2.exports = now3; + } +}); + +// ../node_modules/lodash/_trimmedEndIndex.js +var require_trimmedEndIndex = __commonJS({ + "../node_modules/lodash/_trimmedEndIndex.js"(exports2, module2) { + var reWhitespace2 = /\s/; + function trimmedEndIndex2(string) { + var index = string.length; + while (index-- && reWhitespace2.test(string.charAt(index))) { + } + return index; + } + module2.exports = trimmedEndIndex2; + } +}); + +// ../node_modules/lodash/_baseTrim.js +var require_baseTrim = __commonJS({ + "../node_modules/lodash/_baseTrim.js"(exports2, module2) { + var trimmedEndIndex2 = require_trimmedEndIndex(); + var reTrimStart2 = /^\s+/; + function baseTrim2(string) { + return string ? string.slice(0, trimmedEndIndex2(string) + 1).replace(reTrimStart2, "") : string; + } + module2.exports = baseTrim2; + } +}); + +// ../node_modules/lodash/_Symbol.js +var require_Symbol = __commonJS({ + "../node_modules/lodash/_Symbol.js"(exports2, module2) { + var root3 = require_root(); + var Symbol3 = root3.Symbol; + module2.exports = Symbol3; + } +}); + +// ../node_modules/lodash/_getRawTag.js +var require_getRawTag = __commonJS({ + "../node_modules/lodash/_getRawTag.js"(exports2, module2) { + var Symbol3 = require_Symbol(); + var objectProto20 = Object.prototype; + var hasOwnProperty17 = objectProto20.hasOwnProperty; + var nativeObjectToString3 = objectProto20.toString; + var symToStringTag3 = Symbol3 ? Symbol3.toStringTag : void 0; + function getRawTag2(value) { + var isOwn = hasOwnProperty17.call(value, symToStringTag3), tag = value[symToStringTag3]; + try { + value[symToStringTag3] = void 0; + var unmasked = true; + } catch (e) { + } + var result = nativeObjectToString3.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag3] = tag; + } else { + delete value[symToStringTag3]; + } + } + return result; + } + module2.exports = getRawTag2; + } +}); + +// ../node_modules/lodash/_objectToString.js +var require_objectToString = __commonJS({ + "../node_modules/lodash/_objectToString.js"(exports2, module2) { + var objectProto20 = Object.prototype; + var nativeObjectToString3 = objectProto20.toString; + function objectToString2(value) { + return nativeObjectToString3.call(value); + } + module2.exports = objectToString2; + } +}); + +// ../node_modules/lodash/_baseGetTag.js +var require_baseGetTag = __commonJS({ + "../node_modules/lodash/_baseGetTag.js"(exports2, module2) { + var Symbol3 = require_Symbol(); + var getRawTag2 = require_getRawTag(); + var objectToString2 = require_objectToString(); + var nullTag2 = "[object Null]"; + var undefinedTag2 = "[object Undefined]"; + var symToStringTag3 = Symbol3 ? Symbol3.toStringTag : void 0; + function baseGetTag2(value) { + if (value == null) { + return value === void 0 ? undefinedTag2 : nullTag2; + } + return symToStringTag3 && symToStringTag3 in Object(value) ? getRawTag2(value) : objectToString2(value); + } + module2.exports = baseGetTag2; + } +}); + +// ../node_modules/lodash/isObjectLike.js +var require_isObjectLike = __commonJS({ + "../node_modules/lodash/isObjectLike.js"(exports2, module2) { + function isObjectLike2(value) { + return value != null && typeof value == "object"; + } + module2.exports = isObjectLike2; + } +}); + +// ../node_modules/lodash/isSymbol.js +var require_isSymbol = __commonJS({ + "../node_modules/lodash/isSymbol.js"(exports2, module2) { + var baseGetTag2 = require_baseGetTag(); + var isObjectLike2 = require_isObjectLike(); + var symbolTag5 = "[object Symbol]"; + function isSymbol2(value) { + return typeof value == "symbol" || isObjectLike2(value) && baseGetTag2(value) == symbolTag5; + } + module2.exports = isSymbol2; + } +}); + +// ../node_modules/lodash/toNumber.js +var require_toNumber = __commonJS({ + "../node_modules/lodash/toNumber.js"(exports2, module2) { + var baseTrim2 = require_baseTrim(); + var isObject2 = require_isObject(); + var isSymbol2 = require_isSymbol(); + var NAN2 = 0 / 0; + var reIsBadHex2 = /^[-+]0x[0-9a-f]+$/i; + var reIsBinary2 = /^0b[01]+$/i; + var reIsOctal2 = /^0o[0-7]+$/i; + var freeParseInt2 = parseInt; + function toNumber2(value) { + if (typeof value == "number") { + return value; + } + if (isSymbol2(value)) { + return NAN2; + } + if (isObject2(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject2(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = baseTrim2(value); + var isBinary = reIsBinary2.test(value); + return isBinary || reIsOctal2.test(value) ? freeParseInt2(value.slice(2), isBinary ? 2 : 8) : reIsBadHex2.test(value) ? NAN2 : +value; + } + module2.exports = toNumber2; + } +}); + +// ../node_modules/lodash/debounce.js +var require_debounce = __commonJS({ + "../node_modules/lodash/debounce.js"(exports2, module2) { + var isObject2 = require_isObject(); + var now3 = require_now(); + var toNumber2 = require_toNumber(); + var FUNC_ERROR_TEXT2 = "Expected a function"; + var nativeMax4 = Math.max; + var nativeMin = Math.min; + function debounce(func, wait, options) { + var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; + if (typeof func != "function") { + throw new TypeError(FUNC_ERROR_TEXT2); + } + wait = toNumber2(wait) || 0; + if (isObject2(options)) { + leading = !!options.leading; + maxing = "maxWait" in options; + maxWait = maxing ? nativeMax4(toNumber2(options.maxWait) || 0, wait) : maxWait; + trailing = "trailing" in options ? !!options.trailing : trailing; + } + function invokeFunc(time2) { + var args = lastArgs, thisArg = lastThis; + lastArgs = lastThis = void 0; + lastInvokeTime = time2; + result = func.apply(thisArg, args); + return result; + } + function leadingEdge(time2) { + lastInvokeTime = time2; + timerId = setTimeout(timerExpired, wait); + return leading ? invokeFunc(time2) : result; + } + function remainingWait(time2) { + var timeSinceLastCall = time2 - lastCallTime, timeSinceLastInvoke = time2 - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; + return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; + } + function shouldInvoke(time2) { + var timeSinceLastCall = time2 - lastCallTime, timeSinceLastInvoke = time2 - lastInvokeTime; + return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; + } + function timerExpired() { + var time2 = now3(); + if (shouldInvoke(time2)) { + return trailingEdge(time2); + } + timerId = setTimeout(timerExpired, remainingWait(time2)); + } + function trailingEdge(time2) { + timerId = void 0; + if (trailing && lastArgs) { + return invokeFunc(time2); + } + lastArgs = lastThis = void 0; + return result; + } + function cancel() { + if (timerId !== void 0) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = void 0; + } + function flush() { + return timerId === void 0 ? result : trailingEdge(now3()); + } + function debounced() { + var time2 = now3(), isInvoking = shouldInvoke(time2); + lastArgs = arguments; + lastThis = this; + lastCallTime = time2; + if (isInvoking) { + if (timerId === void 0) { + return leadingEdge(lastCallTime); + } + if (maxing) { + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === void 0) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + module2.exports = debounce; + } +}); + +// ../node_modules/lodash/throttle.js +var require_throttle = __commonJS({ + "../node_modules/lodash/throttle.js"(exports2, module2) { + var debounce = require_debounce(); + var isObject2 = require_isObject(); + var FUNC_ERROR_TEXT2 = "Expected a function"; + function throttle2(func, wait, options) { + var leading = true, trailing = true; + if (typeof func != "function") { + throw new TypeError(FUNC_ERROR_TEXT2); + } + if (isObject2(options)) { + leading = "leading" in options ? !!options.leading : leading; + trailing = "trailing" in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + "leading": leading, + "maxWait": wait, + "trailing": trailing + }); + } + module2.exports = throttle2; + } +}); + +// src/transports/connection.js +var Connection = class { + constructor() { + if (this.constructor === Connection) { + throw new Error("Abstract classes can't be instantiated."); + } + this.receiver.bind(this); + this.sender.bind(this); + } + async receiver() { + while (true) { + const update = await this.receive(); + await this._transport.receive(this._client_id, update); + } + } + async sender() { + while (true) { + const update = await this._transport.send(this._client_id); + await this.send(update); + } + } + // eslint-disable-next-line no-unused-vars + async connect(client_id = "") { + throw new Error("Method 'connect' must be implemented."); + } + async disconnect() { + throw new Error("Method 'disconnect' must be implemented."); + } + async receive() { + throw new Error("Method 'receive' must be implemented."); + } + // eslint-disable-next-line no-unused-vars + async send(update) { + throw new Error("Method 'send' must be implemented."); + } +}; + +// src/transports/client.js +var Client = class extends Connection { + constructor(options = {}) { + super(); + this._transport = options.transport; + this._client_id = options._client_id || ""; + this.open.bind(this); + this.close.bind(this); + this.initial.bind(this); + this.handle.bind(this); + } + async open() { + await this.connect(this._client_id); + await this._transport.connect(); + const initial = await this.receive(); + return this._transport.onInitial(initial); + } + async close() { + await this._transport.disconnect(); + await this.disconnect(); + } + async initial() { + return this.open(); + } + async handle() { + await this.receiver(); + await this.close(); + } +}; + +// src/transports/handler.js +var WebSocketClient = class extends Client { + constructor(options = {}) { + super(); + this._transport = options.transport; + this._model = options.model; + this._config = options.config; + this._protocol = options.protocol || window.location.protocol === "http:" ? "ws:" : "wss:"; + this._host = options.host || window.location.host; + this._path = options.path || "ws"; + this._connected = false; + this._data = new Array(); + this._datapromise = null; + this._datacallback = null; + this.connect.bind(this); + this.disconnect.bind(this); + this.receive.bind(this); + this.send.bind(this); + } + async connect() { + this._websocket = new WebSocket( + `${this._protocol}//${this._host}/${this._path}` + ); + this._connected = true; + this._websocket.onopen = this._on_open.bind(this); + this._websocket.onclose = this._on_close.bind(this); + this._websocket.onmessage = this._on_receive.bind(this); + } + async disconnect() { + this._websocket.close(); + } + async _on_open() { + this._connected = true; + } + async _on_close(event) { + this._connected = false; + if (this._datacallback) { + this._datacallback.reject(event); + this._datacallback = null; + } + } + async _on_receive(event) { + this._data.push(event.data); + if (this._datacallback) { + this._datacallback.resolve(this._data.shift()); + this._datacallback = null; + } + } + async receive() { + if (this._data.length !== 0) { + return Promise.resolve(this._data.shift()); + } + if (!this._connected) { + return Promise.reject(new Error("Disconnected")); + } + if (this._datacallback) { + return this._datapromise; + } + this._datapromise = new Promise((resolve, reject) => { + this._datacallback = { resolve, reject }; + }); + return this._datapromise; + } + async send(update) { + this._websocket.send(update); + } +}; + +// src/transports/transport.js +var Transport = class { + constructor() { + this.models = /* @__PURE__ */ new Map(); + this.server_models = /* @__PURE__ */ new Map(); + this.model_map = /* @__PURE__ */ new Map(); + this.hosts.bind(this); + } + hosts(model_type) { + if (!this.model_map.has(model_type.name)) { + console.info(`Registering type: ${model_type.name}`); + this.model_map.set(model_type.name, model_type); + model_type.submodels().forEach((submodel_type) => { + this.hosts(submodel_type); + }); + } + } + async connect() { + } + async disconnect() { + this.server_models = /* @__PURE__ */ new Map(); + } + async onInitial(update) { + const model = update.model; + this.server_models.set(model.id, model); + this.models.set("", model); + return model; + } + // ################# + // # Bidirectional # + // ################# + async send(client_id) { + const model = this.models.get(client_id); + return await model.get(); + } + async receive(client_id, update) { + const model = this.models.get(client_id); + await model.receive(update); + } +}; + +// src/transports/update.js +var Update = class { + constructor(data = {}) { + this.model = data.model; + this.model_target = data.model_target; + } +}; + +// src/transports/json.js +var JSONTransport = class extends Transport { + constructor() { + super(); + this.onInitial.bind(this); + this._update_to_model.bind(this); + this.send.bind(this); + this.receive.bind(this); + } + // ################## + // # Client methods # + // ################## + async onInitial(update) { + const update_inst = await this._update_to_model(update); + return super.onInitial(update_inst); + } + async _update_to_model(update) { + const data = JSON.parse(update); + if (Object.keys(data).indexOf("model_type") < 0) { + throw new Error(`Update data has no 'model_type'`); + } + if (Object.keys(data).indexOf("model_target") < 0) { + throw new Error(`Update data has no 'model_target'`); + } + if (!this.model_map.has(data.model_type)) { + throw new Error( + `Class type (${data.model_type}) not known, did you forget to call 'hosts'?"` + ); + } + const Class_type = this.model_map.get(data.model_type); + const model_inst = new Class_type(data.model); + data.model = model_inst; + return new Update(data); + } + // ################# + // # Bidirectional # + // ################# + async send(client_id) { + return (await super.send(client_id)).json(); + } + async receive(client_id, update) { + const update_inst = await this._update_to_model(update); + await super.receive(client_id, update_inst); + } +}; + +// src/transports/model.js +var Model = class { + constructor() { + this.receive.bind(this); + } + static submodels() { + return []; + } + // eslint-disable-next-line class-methods-use-this, no-unused-vars + receive(_data) { + } +}; + +// src/core/node.js +var Node = class extends Model { + constructor(data) { + super(); + Object.keys(data).forEach((key) => { + this[key] = data[key]; + }); + } +}; +__publicField(Node, "name", "Node"); + +// src/core/edge.js +var Edge = class extends Model { + constructor(data) { + super(); + Object.keys(data).forEach((key) => { + this[key] = data[key]; + }); + } + static submodels() { + return [Node]; + } +}; +__publicField(Edge, "name", "Edge"); // ../node_modules/d3-dispatch/src/dispatch.js var noop = { value: () => { @@ -9295,340 +9902,136 @@ function render() { return fn; }; fn.arrows = function(value) { - if (!arguments.length) - return arrows; - setArrows(value); - return fn; - }; - return fn; -} -var NODE_DEFAULT_ATTRS = { - paddingLeft: 10, - paddingRight: 10, - paddingTop: 10, - paddingBottom: 10, - rx: 0, - ry: 0, - shape: "rect" -}; -var EDGE_DEFAULT_ATTRS = { - arrowhead: "normal", - curve: linear_default -}; -function preProcessGraph(g) { - g.nodes().forEach(function(v) { - var node = g.node(v); - if (!has_default(node, "label") && !g.children(v).length) { - node.label = v; - } - if (has_default(node, "paddingX")) { - defaults_default(node, { - paddingLeft: node.paddingX, - paddingRight: node.paddingX - }); - } - if (has_default(node, "paddingY")) { - defaults_default(node, { - paddingTop: node.paddingY, - paddingBottom: node.paddingY - }); - } - if (has_default(node, "padding")) { - defaults_default(node, { - paddingLeft: node.padding, - paddingRight: node.padding, - paddingTop: node.padding, - paddingBottom: node.padding - }); - } - defaults_default(node, NODE_DEFAULT_ATTRS); - forEach_default(["paddingLeft", "paddingRight", "paddingTop", "paddingBottom"], function(k) { - node[k] = Number(node[k]); - }); - if (has_default(node, "width")) { - node._prevWidth = node.width; - } - if (has_default(node, "height")) { - node._prevHeight = node.height; - } - }); - g.edges().forEach(function(e) { - var edge = g.edge(e); - if (!has_default(edge, "label")) { - edge.label = ""; - } - defaults_default(edge, EDGE_DEFAULT_ATTRS); - }); -} -function postProcessGraph(g) { - forEach_default(g.nodes(), function(v) { - var node = g.node(v); - if (has_default(node, "_prevWidth")) { - node.width = node._prevWidth; - } else { - delete node.width; - } - if (has_default(node, "_prevHeight")) { - node.height = node._prevHeight; - } else { - delete node.height; - } - delete node._prevWidth; - delete node._prevHeight; - }); -} -function createOrSelectGroup(root3, name) { - var selection2 = root3.select("g." + name); - if (selection2.empty()) { - selection2 = root3.append("g").attr("class", name); - } - return selection2; -} - -// ../node_modules/dagre-d3-es/src/dagre-js/intersect/index.js -var intersect_exports = {}; -__export(intersect_exports, { - circle: () => intersect_circle_exports, - ellipse: () => intersect_ellipse_exports, - node: () => intersect_node_exports, - polygon: () => intersect_polygon_exports, - rect: () => intersect_rect_exports -}); - -// src/transports/connection.js -var Connection = class { - constructor() { - if (this.constructor === Connection) { - throw new Error("Abstract classes can't be instantiated."); - } - this.receiver.bind(this); - this.sender.bind(this); - } - async receiver() { - while (true) { - const update = await this.receive(); - await this._transport.receive(this._client_id, update); - } - } - async sender() { - while (true) { - const update = await this._transport.send(this._client_id); - await this.send(update); - } - } - // eslint-disable-next-line no-unused-vars - async connect(client_id = "") { - throw new Error("Method 'connect' must be implemented."); - } - async disconnect() { - throw new Error("Method 'disconnect' must be implemented."); - } - async receive() { - throw new Error("Method 'receive' must be implemented."); - } - // eslint-disable-next-line no-unused-vars - async send(update) { - throw new Error("Method 'send' must be implemented."); - } -}; - -// src/transports/client.js -var Client = class extends Connection { - constructor(options = {}) { - super(); - this._transport = options.transport; - this._client_id = options._client_id || ""; - this.open.bind(this); - this.close.bind(this); - this.initial.bind(this); - this.handle.bind(this); - } - async open() { - await this.connect(this._client_id); - await this._transport.connect(); - const initial = await this.receive(); - return this._transport.onInitial(initial); - } - async close() { - await this._transport.disconnect(); - await this.disconnect(); - } - async initial() { - return this.open(); - } - async handle() { - await this.receiver(); - await this.close(); - } -}; - -// src/transports/handler.js -var WebSocketClient = class extends Client { - constructor(options = {}) { - super(); - this._transport = options.transport; - this._model = options.model; - this._config = options.config; - this._protocol = options.protocol || window.location.protocol === "http:" ? "ws:" : "wss:"; - this._host = options.host || window.location.host; - this._path = options.path || "ws"; - this._connected = false; - this._data = new Array(); - this._datapromise = null; - this._datacallback = null; - this.connect.bind(this); - this.disconnect.bind(this); - this.receive.bind(this); - this.send.bind(this); - } - async connect() { - this._websocket = new WebSocket( - `${this._protocol}//${this._host}/${this._path}` - ); - this._connected = true; - this._websocket.onopen = this._on_open.bind(this); - this._websocket.onclose = this._on_close.bind(this); - this._websocket.onmessage = this._on_receive.bind(this); - } - async disconnect() { - this._websocket.close(); - } - async _on_open() { - this._connected = true; - } - async _on_close(event) { - this._connected = false; - if (this._datacallback) { - this._datacallback.reject(event); - this._datacallback = null; - } - } - async _on_receive(event) { - this._data.push(event.data); - if (this._datacallback) { - this._datacallback.resolve(this._data.shift()); + if (!arguments.length) + return arrows; + setArrows(value); + return fn; + }; + return fn; +} +var NODE_DEFAULT_ATTRS = { + paddingLeft: 10, + paddingRight: 10, + paddingTop: 10, + paddingBottom: 10, + rx: 0, + ry: 0, + shape: "rect" +}; +var EDGE_DEFAULT_ATTRS = { + arrowhead: "normal", + curve: linear_default +}; +function preProcessGraph(g) { + g.nodes().forEach(function(v) { + var node = g.node(v); + if (!has_default(node, "label") && !g.children(v).length) { + node.label = v; } - } - async receive() { - if (this._data.length !== 0) { - return Promise.resolve(this._data.shift()); + if (has_default(node, "paddingX")) { + defaults_default(node, { + paddingLeft: node.paddingX, + paddingRight: node.paddingX + }); } - if (!this._connected) { - return Promise.reject(new Error("Disconnected")); + if (has_default(node, "paddingY")) { + defaults_default(node, { + paddingTop: node.paddingY, + paddingBottom: node.paddingY + }); } - if (this._datacallback) { - return this._datapromise; + if (has_default(node, "padding")) { + defaults_default(node, { + paddingLeft: node.padding, + paddingRight: node.padding, + paddingTop: node.padding, + paddingBottom: node.padding + }); } - this._datapromise = new Promise((resolve, reject) => { - this._datacallback = { resolve, reject }; + defaults_default(node, NODE_DEFAULT_ATTRS); + forEach_default(["paddingLeft", "paddingRight", "paddingTop", "paddingBottom"], function(k) { + node[k] = Number(node[k]); }); - return this._datapromise; - } - async send(update) { - this._websocket.send(update); - } -}; - -// src/transports/transport.js -var Transport = class { - constructor() { - this.models = /* @__PURE__ */ new Map(); - this.server_models = /* @__PURE__ */ new Map(); - this.model_map = /* @__PURE__ */ new Map(); - this.hosts.bind(this); - } - hosts(model_name, model_type) { - this.model_map.set(model_name, model_type); - } - async connect() { - } - async disconnect() { - this.server_models = /* @__PURE__ */ new Map(); - } - async onInitial(update) { - const model = update.model; - this.server_models.set(model.id, model); - this.models.set("", model); - return model; - } - // ################# - // # Bidirectional # - // ################# - async send(client_id) { - const model = this.models.get(client_id); - return await model.get(); - } - async receive(client_id, update) { - const model = this.models.get(client_id); - await model.receive(update); - } -}; - -// src/transports/update.js -var Update = class { - constructor(data = {}) { - this.model = data.model; - this.model_target = data.model_target; - } -}; - -// src/transports/json.js -var JSONTransport = class extends Transport { - constructor() { - super(); - this.onInitial.bind(this); - this._update_to_model.bind(this); - this.send.bind(this); - this.receive.bind(this); - } - // ################## - // # Client methods # - // ################## - async onInitial(update) { - const update_inst = await this._update_to_model(update); - return super.onInitial(update_inst); - } - async _update_to_model(update) { - const data = JSON.parse(update); - if (Object.keys(data).indexOf("model_type") < 0) { - throw new Error(`Update data has no 'model_type'`); + if (has_default(node, "width")) { + node._prevWidth = node.width; } - if (Object.keys(data).indexOf("model_target") < 0) { - throw new Error(`Update data has no 'model_target'`); + if (has_default(node, "height")) { + node._prevHeight = node.height; } - if (!this.model_map.has(data.model_type)) { - throw new Error( - `Class type (${data.model_type}) not known, did you forget to call 'hosts'?"` - ); + }); + g.edges().forEach(function(e) { + var edge = g.edge(e); + if (!has_default(edge, "label")) { + edge.label = ""; } - const Class_type = this.model_map.get(data.model_type); - const model_inst = new Class_type(data.model); - data.model = model_inst; - return new Update(data); - } - // ################# - // # Bidirectional # - // ################# - async send(client_id) { - return (await super.send(client_id)).json(); - } - async receive(client_id, update) { - const update_inst = await this._update_to_model(update); - await super.receive(client_id, update_inst); + defaults_default(edge, EDGE_DEFAULT_ATTRS); + }); +} +function postProcessGraph(g) { + forEach_default(g.nodes(), function(v) { + var node = g.node(v); + if (has_default(node, "_prevWidth")) { + node.width = node._prevWidth; + } else { + delete node.width; + } + if (has_default(node, "_prevHeight")) { + node.height = node._prevHeight; + } else { + delete node.height; + } + delete node._prevWidth; + delete node._prevHeight; + }); +} +function createOrSelectGroup(root3, name) { + var selection2 = root3.select("g." + name); + if (selection2.empty()) { + selection2 = root3.append("g").attr("class", name); } -}; + return selection2; +} -// src/transports/model.js -var Model = class { - constructor() { - this.receive.bind(this); - this.submodels.bind(this); - } - submodels() { - return []; - } - receive(data) { - console.log(`receive: ${data}`); +// ../node_modules/dagre-d3-es/src/dagre-js/intersect/index.js +var intersect_exports = {}; +__export(intersect_exports, { + circle: () => intersect_circle_exports, + ellipse: () => intersect_ellipse_exports, + node: () => intersect_node_exports, + polygon: () => intersect_polygon_exports, + rect: () => intersect_rect_exports +}); + +// src/core/graph.js +var import_throttle = __toESM(require_throttle(), 1); + +// src/core/shapes.js +var house = (parent, bbox, node) => { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: w / 2, y: -h * 3 / 2 }, + { x: 0, y: -h } + ]; + const shapeSvg = parent.insert("polygon", ":first-child").attr("points", points.map((d) => `${d.x},${d.y}`).join(" ")).attr("transform", `translate(${-w / 2},${h * 3 / 4})`); + node.intersect = (point2) => intersect_exports.polygon.intersectPolygon(node, points, point2); + return shapeSvg; +}; +var hollowpoint = (parent, id2, edge, type2) => { + const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidget", 8).attr("markerHeight", 6).attr("orient", "auto"); + const path2 = marker.append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").style("stroke-width", 1).style("stroke-dasharray", "1,0").style("fill", "#fff").style("stroke", "#333"); + path2.attr("style", edge[`${type2}Style`]); + return marker; +}; +var Shapes = { + Node: { + house + }, + Arrow: { + hollowpoint } }; @@ -9687,12 +10090,38 @@ var _configureEdgeDefaults = (from, to, options, defaults2) => { return resolvedOptions; }; var Graph2 = class extends Model { + // flags + _rendered; + _ready; + // map of node name -> node + _nodes; + // list of edges + _edges; + // render point + _renderpoint; + // throttling renderer + _throttled_render; constructor(options = {}) { super(); - console.log(`here: ${this.constructor.name}`); + this.addNode.bind(this); + this.addNodeInst.bind(this); + this.addEdge.bind(this); + this.addEdgeInst.bind(this); + this.render.bind(this); + this._calculateInitialScale.bind(this); + this._throttled_render = (0, import_throttle.default)(() => this.render(), 200); this._defaults = _configureDefaults(options); this._renderer = render(); + Object.keys(Shapes.Node).forEach((name) => { + this._renderer.shapes()[name] = Shapes.Node[name]; + }); + Object.keys(Shapes.Arrow).forEach((name) => { + this._renderer.arrows()[name] = Shapes.Arrow[name]; + }); + this._renderpoint = null; this._graph = new graphlib_exports.Graph({ directed: this._defaults.directed }); + this._nodes = /* @__PURE__ */ new Map(); + this._edges = []; this._graph.setGraph({ nodesep: this._defaults.nodesep, ranksep: this._defaults.ranksep, @@ -9702,19 +10131,33 @@ var Graph2 = class extends Model { }); this._graph.setDefaultEdgeLabel(() => { }); + this._ready = false; this._rendered = false; this._graph_svg_inst = null; this._graph_g_inst = null; - this.addNode.bind(this); - this.addEdge.bind(this); - this.render.bind(this); - this._calculateInitialScale.bind(this); + Object.keys(options.nodes || {}).forEach((node_id) => { + this.addNodeInst(new Node(options.nodes[node_id])); + }); + options.edges?.forEach((edge) => { + this.addEdgeInst(new Edge(edge)); + }); + this._ready = true; + } + static submodels() { + return [Edge, Node]; } addNode(name, options = {}) { + this._nodes.set(name, name); this._graph.setNode( name, _configureNodeDefaults(name, options, this._defaults.node) ); + if (this._ready) { + this._throttled_render(); + } + } + addNodeInst(node) { + this.addNode(node.name, node); } addEdge(from, to, options = {}) { this._graph.setEdge( @@ -9722,11 +10165,40 @@ var Graph2 = class extends Model { to, _configureEdgeDefaults(from, to, options, this._defaults.edge) ); + if (this._ready) { + this._throttled_render(); + } + } + addEdgeInst(edge) { + const fromNode = new Node(edge.from_); + const toNode = new Node(edge.to_); + this.addNodeInst(fromNode); + this.addNodeInst(toNode); + this.addEdge(fromNode.name, toNode.name, edge); + } + receive(obj) { + if (obj.model instanceof Node) { + this.addNodeInst(obj.model); + } + if (obj.model instanceof Edge) { + this.addEdgeInst(obj.model); + } } render(onto) { + if (!this._ready) { + return; + } + if (this._nodes.size === 0) { + this._renderpoint = onto; + return; + } + const renderpoint = onto || this._renderpoint; + if (!renderpoint) { + return; + } if (!this._rendered) { - onto.classList.add("dagred3-container"); - this._graph_svg_inst = select_default2(onto).append("svg"); + renderpoint.classList.add("daggre-container"); + this._graph_svg_inst = select_default2(renderpoint).append("svg"); this._graph_g_inst = this._graph_svg_inst.append("g"); this._zoom = zoom_default2().on("zoom", (event) => { this._graph_g_inst.attr("transform", event.transform); @@ -9734,10 +10206,10 @@ var Graph2 = class extends Model { this._graph_svg_inst.call(this._zoom); } this._renderer(this._graph_g_inst, this._graph); - if (!this._rendered) { + if (!this._rendered && renderpoint) { this._calculateInitialScale(); - const width2 = onto.offsetWidth; - const height = onto.offsetHeight; + const width2 = renderpoint.offsetWidth; + const height = renderpoint.offsetHeight; this._graph_svg_inst.call( this._zoom.transform, identity2.translate( @@ -9745,8 +10217,8 @@ var Graph2 = class extends Model { (height - this._graph.graph().height * this._defaults.initialScale) / 2 ).scale(this._defaults.initialScale) ); + this._rendered = true; } - this._rendered = true; } _calculateInitialScale() { if (this._defaults.initialScale === void 0) { @@ -9772,32 +10244,19 @@ var Graph2 = class extends Model { } } }; - -// src/core/shapes.js -var house = (parent, bbox, node) => { - const w = bbox.width; - const h = bbox.height; - const points = [ - { x: 0, y: 0 }, - { x: w, y: 0 }, - { x: w, y: -h }, - { x: w / 2, y: -h * 3 / 2 }, - { x: 0, y: -h } - ]; - const shapeSvg = parent.insert("polygon", ":first-child").attr("points", points.map((d) => `${d.x},${d.y}`).join(" ")).attr("transform", `translate(${-w / 2},${h * 3 / 4})`); - node.intersect = (point2) => intersect_exports.polygon(node, points, point2); - return shapeSvg; -}; +__publicField(Graph2, "name", "Graph"); export { Client, Connection, + Edge, Graph2 as Graph, JSONTransport, Model, + Node, + Shapes, Transport, Update, - WebSocketClient, - house + WebSocketClient }; /*! Bundled license information: diff --git a/python/dagred3/tests/__init__.py b/python/daggre/tests/__init__.py similarity index 100% rename from python/dagred3/tests/__init__.py rename to python/daggre/tests/__init__.py diff --git a/python/dagred3/tests/conftest.py b/python/daggre/tests/conftest.py similarity index 87% rename from python/dagred3/tests/conftest.py rename to python/daggre/tests/conftest.py index 449252b..1c084c1 100644 --- a/python/dagred3/tests/conftest.py +++ b/python/daggre/tests/conftest.py @@ -1,6 +1,6 @@ from pytest import fixture -from dagred3 import Edge, Graph, Node +from daggre import Edge, Graph, Node @fixture diff --git a/python/dagred3/tests/test_core.py b/python/daggre/tests/test_core.py similarity index 93% rename from python/dagred3/tests/test_core.py rename to python/daggre/tests/test_core.py index af2ec9c..63724bd 100644 --- a/python/dagred3/tests/test_core.py +++ b/python/daggre/tests/test_core.py @@ -1,7 +1,7 @@ from datetime import datetime from unittest.mock import patch -from dagred3 import Graph, Node +from daggre import Graph, Node class TestBasic: @@ -11,7 +11,7 @@ def test_node_repr(self, a_node): def test_node_serialization(self, a_node): now = datetime.utcnow() - with patch("dagred3.transports.model.uuid4") as uuid4_mock, patch("dagred3.transports.model.datetime") as utcnow_mock: + with patch("daggre.transports.model.uuid4") as uuid4_mock, patch("daggre.transports.model.datetime") as utcnow_mock: uuid4_mock.return_value = "blerg" utcnow_mock.utcnow.return_value = now print(now.isoformat()) diff --git a/python/dagred3/tests/test_graph_generator_helper.py b/python/daggre/tests/test_graph_generator_helper.py similarity index 97% rename from python/dagred3/tests/test_graph_generator_helper.py rename to python/daggre/tests/test_graph_generator_helper.py index 34a268f..cd41aab 100644 --- a/python/dagred3/tests/test_graph_generator_helper.py +++ b/python/daggre/tests/test_graph_generator_helper.py @@ -1,4 +1,4 @@ -from dagred3 import Graph +from daggre import Graph def test_graph_generator_helper(): diff --git a/python/dagred3/tests/test_transport.py b/python/daggre/tests/test_transport.py similarity index 97% rename from python/dagred3/tests/test_transport.py rename to python/daggre/tests/test_transport.py index 4c85d6b..128b615 100644 --- a/python/dagred3/tests/test_transport.py +++ b/python/daggre/tests/test_transport.py @@ -2,7 +2,7 @@ import time from typing import Dict, List -from dagred3.transports import BaseModel, Transport +from daggre.transports import BaseModel, Transport class MyModel(BaseModel): ... diff --git a/python/dagred3/transports/__init__.py b/python/daggre/transports/__init__.py similarity index 100% rename from python/dagred3/transports/__init__.py rename to python/daggre/transports/__init__.py diff --git a/python/dagred3/transports/client.py b/python/daggre/transports/client.py similarity index 100% rename from python/dagred3/transports/client.py rename to python/daggre/transports/client.py diff --git a/python/dagred3/transports/connection.py b/python/daggre/transports/connection.py similarity index 100% rename from python/dagred3/transports/connection.py rename to python/daggre/transports/connection.py diff --git a/python/dagred3/transports/exceptions.py b/python/daggre/transports/exceptions.py similarity index 100% rename from python/dagred3/transports/exceptions.py rename to python/daggre/transports/exceptions.py diff --git a/python/dagred3/transports/handlers/__init__.py b/python/daggre/transports/handlers/__init__.py similarity index 100% rename from python/dagred3/transports/handlers/__init__.py rename to python/daggre/transports/handlers/__init__.py diff --git a/python/dagred3/transports/handlers/aiohttp_client.py b/python/daggre/transports/handlers/aiohttp_client.py similarity index 100% rename from python/dagred3/transports/handlers/aiohttp_client.py rename to python/daggre/transports/handlers/aiohttp_client.py diff --git a/python/dagred3/transports/handlers/starlette.py b/python/daggre/transports/handlers/starlette.py similarity index 100% rename from python/dagred3/transports/handlers/starlette.py rename to python/daggre/transports/handlers/starlette.py diff --git a/python/dagred3/transports/json.py b/python/daggre/transports/json.py similarity index 100% rename from python/dagred3/transports/json.py rename to python/daggre/transports/json.py diff --git a/python/dagred3/transports/model.py b/python/daggre/transports/model.py similarity index 100% rename from python/dagred3/transports/model.py rename to python/daggre/transports/model.py diff --git a/python/dagred3/transports/server.py b/python/daggre/transports/server.py similarity index 100% rename from python/dagred3/transports/server.py rename to python/daggre/transports/server.py diff --git a/python/dagred3/transports/transport.py b/python/daggre/transports/transport.py similarity index 100% rename from python/dagred3/transports/transport.py rename to python/daggre/transports/transport.py diff --git a/python/dagred3/transports/update.py b/python/daggre/transports/update.py similarity index 100% rename from python/dagred3/transports/update.py rename to python/daggre/transports/update.py diff --git a/python/dagred3/transports/utils.py b/python/daggre/transports/utils.py similarity index 100% rename from python/dagred3/transports/utils.py rename to python/daggre/transports/utils.py diff --git a/python/dagred3/static/index.css b/python/dagred3/static/index.css deleted file mode 100644 index df22434..0000000 --- a/python/dagred3/static/index.css +++ /dev/null @@ -1,33 +0,0 @@ -/* src/index.css */ -div.dagred3-container { -} -div.dagred3-container > svg { - height: 100%; - width: 100%; -} -.dagred3-container .node rect, -.dagred3-container .node circle, -.dagred3-container .node ellipse, -.dagred3-container .node polygon { - stroke: #555; - fill: #fff; -} -.dagred3-container .edgePath path { - stroke: #555; - fill: transparent; - stroke-width: 1.5px; -} -.dagred3-container .edgeLabel foreignObject { - overflow: visible; -} -.dagred3-container .edgeLabel foreignObject u { - text-decoration: none; -} -.dagred3-container .node text { - pointer-events: none; -} -div.dagred3-tooltip { - background-color: rgba(255, 255, 255, .8); - border: 1px solid #555; - padding: 15px; -} diff --git a/python/pyproject.toml b/python/pyproject.toml index 872092a..9063798 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "daggre" -description = "A convenience layer on top of `dagre-d3` (`dagre-d3-es`), for use in `dagre-d3-lite`" +description = "A convenience layer on top of `dagre-d3` (`dagre-d3-es`)." version = "0.1.0" readme = "README.md" license = { file = "LICENSE" } @@ -56,18 +56,18 @@ test = [ ] [project.urls] -Repository = "https://github.com/timkpaine/dagre-d3-lite" -Homepage = "https://github.com/timkpaine/dagre-d3-lite" +Repository = "https://github.com/timkpaine/daggre" +Homepage = "https://github.com/timkpaine/daggre" [tool.check-manifest] ignore = [ - "dagred3/static/**", + "daggre/static/**", "js/**" ] [tool.hatch.build] artifacts = [ - "dagred3/static", + "daggre/static", ] [tool.hatch.build.sources] @@ -75,7 +75,7 @@ src = "/" [tool.hatch.build.targets.sdist] include = [ - "/dagred3", + "/daggre", "/pyproject.toml", "/setup.py", "LICENSE", @@ -90,7 +90,7 @@ exclude = [ [tool.hatch.build.targets.wheel] include = [ - "/dagred3", + "/daggre", ] exclude = [ "/.mypy_cache", @@ -102,12 +102,12 @@ exclude = [ [tool.hatch.build.hooks.jupyter-builder] build-function = "hatch_jupyter_builder.npm_builder" ensured-targets = [ - "dagred3/static/index.js", - "dagred3/static/index.css", + "daggre/static/index.js", + "daggre/static/index.css", ] skip-if-exists = [ - "dagred3/static/index.js", - "dagred3/static/index.css", + "daggre/static/index.js", + "daggre/static/index.css", ] dependencies = [ "hatch-jupyter-builder>=0.5.0", @@ -124,7 +124,7 @@ line_length = 150 profile = "black" default_section = "THIRDPARTY" sections = "FUTURE,THIRDPARTY,FIRSTPARTY,LOCALFOLDER" -known_first_party = "dagred3" +known_first_party = "daggre" [tool.pytest.ini_options] asyncio_mode = 'strict'