diff --git a/capellambse_context_diagrams/__init__.py b/capellambse_context_diagrams/__init__.py
index 34febf92..d142e28e 100644
--- a/capellambse_context_diagrams/__init__.py
+++ b/capellambse_context_diagrams/__init__.py
@@ -81,7 +81,11 @@ def register_classes() -> None:
(
ctx.SystemFunction,
DiagramType.SAB,
- {"render_styles": styling.BLUE_ACTOR_FNCS},
+ {
+ "display_symbols_as_boxes": True,
+ "display_parent_relation": True,
+ "render_styles": styling.BLUE_ACTOR_FNCS,
+ },
),
(
la.LogicalComponent,
@@ -112,7 +116,10 @@ def register_classes() -> None:
(
pa.PhysicalFunction,
DiagramType.PAB,
- {"render_styles": styling.BLUE_ACTOR_FNCS},
+ {
+ "display_parent_relation": True,
+ "render_styles": styling.BLUE_ACTOR_FNCS,
+ },
),
]
patch_styles(supported_classes)
diff --git a/capellambse_context_diagrams/collectors/default.py b/capellambse_context_diagrams/collectors/default.py
index e94b33d9..aba09d7e 100644
--- a/capellambse_context_diagrams/collectors/default.py
+++ b/capellambse_context_diagrams/collectors/default.py
@@ -25,12 +25,6 @@ def collector(
diagram: context.ContextDiagram, params: dict[str, t.Any] | None = None
) -> _elkjs.ELKInputData:
"""Collect context data from ports of centric box."""
- diagram.display_parent_relation = (params or {}).pop(
- "display_parent_relation", diagram.display_parent_relation
- )
- diagram.display_derived_interfaces = (params or {}).pop(
- "display_derived_interfaces", diagram.display_derived_interfaces
- )
data = generic.collector(diagram, no_symbol=True)
ports = port_collector(diagram.target, diagram.type)
centerbox = data["children"][0]
@@ -41,7 +35,6 @@ def collector(
ex_datas: list[generic.ExchangeData] = []
edges: common.ElementList[fa.AbstractExchange]
for ex in (edges := list(chain.from_iterable(connections.values()))):
-
if is_hierarchical := exchanges.is_hierarchical(ex, centerbox):
if not diagram.display_parent_relation:
continue
@@ -61,8 +54,7 @@ def collector(
continue
global_boxes = {centerbox["id"]: centerbox}
made_boxes = {centerbox["id"]: centerbox}
- to_delete = set()
- to_delete.add(centerbox["id"])
+ boxes_to_delete = {centerbox["id"]}
def _make_box_and_update_globals(
obj: t.Any,
@@ -77,17 +69,19 @@ def _make_box_and_update_globals(
return box
if diagram.display_parent_relation:
- if diagram.target.owner:
- box = _make_box_and_update_globals(
- diagram.target.owner,
- no_symbol=diagram.display_symbols_as_boxes,
- layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS,
- )
- box["children"] = [centerbox]
- del data["children"][0]
- all_owners = generic.get_all_owners(diagram.target)
- start = 0
- common_owner = diagram.target
+ try:
+ if not isinstance(diagram.target.owner, generic.PackageTypes):
+ box = _make_box_and_update_globals(
+ diagram.target.owner,
+ no_symbol=diagram.display_symbols_as_boxes,
+ layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS,
+ )
+ box["children"] = [centerbox]
+ del data["children"][0]
+ except AttributeError:
+ pass
+ diagram_target_owners = generic.get_all_owners(diagram.target)
+ common_owners = []
stack_heights: dict[str, float | int] = {
"input": -makers.NEIGHBOR_VMARGIN,
@@ -117,57 +111,63 @@ def _make_box_and_update_globals(
if diagram.display_parent_relation:
current = child
- while (
- current
- and not isinstance(current, generic.PackageTypes)
- and current.uuid not in all_owners
- ):
+ while current and current.uuid not in diagram_target_owners:
+ try:
+ if isinstance(current.owner, generic.PackageTypes):
+ break
+ if not (
+ parent_box := global_boxes.get(current.owner.uuid)
+ ):
+ parent_box = _make_box_and_update_globals(
+ current.owner,
+ no_symbol=diagram.display_symbols_as_boxes,
+ layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS,
+ )
+ new_box = global_boxes.get(current.uuid, current)
+ for box in (
+ children := parent_box.setdefault("children", [])
+ ):
+ if box["id"] == current.uuid:
+ box = new_box
+ break
+ else:
+ children.append(new_box)
+ boxes_to_delete.add(current.uuid)
+ current = current.owner
+ except AttributeError:
+ break
+ common_owners.append(current.uuid)
+
+ stack_heights[side] += makers.NEIGHBOR_VMARGIN + height
+
+ if diagram.display_parent_relation and diagram.target.owner:
+ current = diagram.target.owner
+ common_owner_uuid = current.uuid
+ for owner in diagram_target_owners[::-1]:
+ if owner in common_owners:
+ common_owner_uuid = owner
+ break
+ while current and current.uuid != common_owner_uuid:
+ try:
+ if isinstance(current.owner, generic.PackageTypes):
+ break
if not (parent_box := global_boxes.get(current.owner.uuid)):
parent_box = _make_box_and_update_globals(
current.owner,
no_symbol=diagram.display_symbols_as_boxes,
layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS,
)
- new_box = global_boxes.get(current.uuid, current)
for box in (children := parent_box.setdefault("children", [])):
if box["id"] == current.uuid:
- box = new_box
+ box = global_boxes.pop(current.uuid)
break
else:
- children.append(new_box)
- to_delete.add(current.uuid)
+ children.append(global_boxes.pop(current.uuid))
current = current.owner
- try:
- if all_owners.index(current.uuid, start) > start:
- common_owner = current
- except ValueError:
- pass
-
- stack_heights[side] += makers.NEIGHBOR_VMARGIN + height
-
- if diagram.display_parent_relation and diagram.target.owner:
- current = diagram.target.owner
- while (
- current
- and not isinstance(current, generic.PackageTypes)
- and current != common_owner
- ):
- if not (parent_box := global_boxes.get(current.owner.uuid)):
- parent_box = _make_box_and_update_globals(
- current.owner,
- no_symbol=diagram.display_symbols_as_boxes,
- layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS,
- )
- for box in (children := parent_box.setdefault("children", [])):
- if box["id"] == current.uuid:
- box = global_boxes.pop(current.uuid)
- break
- else:
- children.append(global_boxes.pop(current.uuid))
-
- current = current.owner
+ except AttributeError:
+ break
- for uuid in to_delete:
+ for uuid in boxes_to_delete:
del global_boxes[uuid]
data["children"].extend(global_boxes.values())
if diagram.display_parent_relation:
diff --git a/capellambse_context_diagrams/collectors/generic.py b/capellambse_context_diagrams/collectors/generic.py
index bddf57e7..51e9f3c3 100644
--- a/capellambse_context_diagrams/collectors/generic.py
+++ b/capellambse_context_diagrams/collectors/generic.py
@@ -234,7 +234,7 @@ def move_edges(
target_owner_uuids = get_all_owners(c.target)
common_owner_uuid = None
for owner in source_owner_uuids:
- if owner in set(target_owner_uuids):
+ if owner in target_owner_uuids:
common_owner_uuid = owner
break
@@ -247,7 +247,6 @@ def move_edges(
if edge["id"] == c.uuid:
owner_box.setdefault("edges", []).append(edge)
edges_to_remove.append(edge["id"])
-
data["edges"] = [
e for e in data["edges"] if e["id"] not in edges_to_remove
]
diff --git a/capellambse_context_diagrams/context.py b/capellambse_context_diagrams/context.py
index 13904739..a5072bdc 100644
--- a/capellambse_context_diagrams/context.py
+++ b/capellambse_context_diagrams/context.py
@@ -343,6 +343,18 @@ def render(self, fmt: str | None, /, **params) -> t.Any:
def _create_diagram(self, params: dict[str, t.Any]) -> cdiagram.Diagram:
transparent_background = params.pop("transparent_background", False)
+ self.display_parent_relation = params.pop(
+ "display_parent_relation", self.display_parent_relation
+ )
+ self.display_derived_interfaces = params.pop(
+ "display_derived_interfaces", self.display_derived_interfaces
+ )
+ self.display_symbols_as_boxes = params.pop(
+ "display_symbols_as_boxes", self.display_symbols_as_boxes
+ )
+ self.slim_center_box = params.pop(
+ "slim_center_box", self.slim_center_box
+ )
data = params.get("elkdata") or get_elkdata(self, params)
layout = try_to_layout(data)
add_context(layout, params.get("is_legend", False))
diff --git a/capellambse_context_diagrams/serializers.py b/capellambse_context_diagrams/serializers.py
index 36a91389..42d5adc3 100644
--- a/capellambse_context_diagrams/serializers.py
+++ b/capellambse_context_diagrams/serializers.py
@@ -257,7 +257,7 @@ class type that stores all previously named classes.
for i in child.get("children", []): # type: ignore
if i["type"] == "edge":
- self._edges.setdefault(i["id"], (i, ref, element))
+ self._edges.setdefault(i["id"], (i, ref, parent))
else:
self.deserialize_child(i, ref, element)
diff --git a/tests/data/ContextDiagram.aird b/tests/data/ContextDiagram.aird
index 4593a8de..1437a998 100644
--- a/tests/data/ContextDiagram.aird
+++ b/tests/data/ContextDiagram.aird
@@ -62,7 +62,7 @@
-
+
@@ -70,7 +70,7 @@
-
+
@@ -86,7 +86,7 @@
-
+
@@ -102,21 +102,17 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
@@ -2057,7 +2053,7 @@
-
+
@@ -2068,7 +2064,7 @@
-
+
@@ -2079,10 +2075,10 @@
-
+
-
+
@@ -2099,7 +2095,7 @@
-
+
@@ -2144,6 +2140,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2162,17 +2174,17 @@
-
+
-
+
-
+
-
+
@@ -2224,6 +2236,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2242,17 +2270,17 @@
-
+
-
+
-
+
-
+
@@ -2274,17 +2302,17 @@
-
+
-
+
-
+
@@ -2306,17 +2334,17 @@
-
+
-
+
-
+
-
+
@@ -2432,38 +2460,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2516,7 +2512,7 @@
-
+
@@ -2557,7 +2553,7 @@
-
+
@@ -2687,7 +2683,7 @@
-
+
@@ -2697,7 +2693,7 @@
-
+
@@ -2707,7 +2703,7 @@
-
+
@@ -2771,7 +2767,7 @@
-
+
@@ -2781,7 +2777,7 @@
-
+
@@ -2936,6 +2932,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -2973,28 +2980,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -3452,6 +3437,15 @@
+
+
+
+
+
+
+
+
+
@@ -3479,24 +3473,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
@@ -3544,8 +3520,8 @@
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
@@ -7816,7 +7792,7 @@
-
+
@@ -9022,922 +8998,1688 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
-
+
-
-
-
-
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
-
-
-
-
-
-
-
-
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
-
-
-
-
+
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
-
+
-
-
-
-
-
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
-
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_RATIO
+ KEEP_SIZE
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
-
-
-
-
+
+
+
KEEP_LOCATION
- KEEP_SIZE
KEEP_RATIO
-
-
+ KEEP_SIZE
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_RATIO
+ KEEP_SIZE
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_RATIO
+ KEEP_SIZE
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_RATIO
+ KEEP_SIZE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+
+
@@ -9945,176 +10687,305 @@
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
-
-
-
-
-
-
-
-
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
-
+
+
-
-
-
-
-
-
-
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
-
-
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- KEEP_LOCATION
- KEEP_SIZE
- KEEP_RATIO
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+
+
+
+
@@ -10122,140 +10993,225 @@
KEEP_LOCATION
KEEP_SIZE
KEEP_RATIO
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
-
+
+
+
+
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+ KEEP_LOCATION
+ KEEP_SIZE
+ KEEP_RATIO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/ContextDiagram.capella b/tests/data/ContextDiagram.capella
index 135025e1..617d710f 100644
--- a/tests/data/ContextDiagram.capella
+++ b/tests/data/ContextDiagram.capella
@@ -3100,60 +3100,50 @@ The predator is far away
id="fa1b9f3b-0770-4aab-b5a9-2843af69706f" name="FIP 1"/>
+ id="77c9db12-29c7-4ced-822d-3a154726f2be" name="Hierarchy Function">
+ id="28ab3abb-3071-4727-bbf4-fed671a5c48d" name="FIP 1"/>
+
+ id="34450485-578a-4bce-b74c-4723d470257f" name="FOP 1"/>
+ id="cda7f626-9829-48a7-990b-7db9a50416e4" name="Left Function">
-
-
-
-
-
+ id="f212bec3-9e5f-4860-9be8-fc3a32e6642c" name="FOP 1"/>
+ id="10816ee5-d960-42a5-8b00-5b2774ea86e6" name="FOP 2"/>
+ id="4fd46193-95cc-4295-8672-94a0cab06bef" name="Right Function 2">
-
-
+ id="da3e108d-c8b1-4beb-896a-bbb6618acf22" name="FIP 1"/>
+ id="d880486c-d917-47d8-b098-8e2b8db9ea5a" name="FOP 1"/>
+ id="4904b56b-f82f-41f4-a5b6-aa8ccc64a9b5" name="Right Function 1">
+ id="ba26d020-30cc-4d79-ac9a-b4729663a9e5" name="FIP 1"/>
+ id="861b9be3-a7b2-4e1d-b34b-8e857062b3df" name="Inner Function 2">
-
-
-
+ id="aed02601-7d03-4ed8-bd19-83faa0df3d71" name="FIP 1"/>
+ id="7ae51ce0-31d3-4811-b921-ded78588922c" name="FIP 2"/>
+
+
+ id="f0bc11ba-89aa-4297-98d2-076440e9117f" name="Inner Function 1">
+ id="03c975d1-cda4-4e5d-be9a-5c76a06aecba" name="FIP 1"/>
+ id="9fefbe1e-3f74-4544-833c-bb040bcfeac7" name="FOP 1"/>
id="0fe9e999-3bd8-4590-9dc2-f51d2c1af173" name="FunctionalExchange 11"
target="#494979bd-d301-419b-8a91-fd1c28dec21c" source="#aaf1f13c-270f-4d67-bc65-37a1c9afb17a"/>
-
+
@@ -3243,26 +3233,26 @@ The predator is far away
id="fe86c5d6-7666-4537-af07-5817b2f12d1c" name="woa" target="#fa1b9f3b-0770-4aab-b5a9-2843af69706f"
source="#9c2fab55-c507-4250-aaa1-9a3d5111ef43"/>
+ id="d3b412f4-91cc-4f1c-a32d-3a56459a108d" name="IF1 to IF2" target="#aed02601-7d03-4ed8-bd19-83faa0df3d71"
+ source="#9fefbe1e-3f74-4544-833c-bb040bcfeac7"/>
+ id="a2dfec73-81aa-4742-86b7-8d510a78ccea" name="Hier to IF2" target="#7ae51ce0-31d3-4811-b921-ded78588922c"
+ source="#34450485-578a-4bce-b74c-4723d470257f"/>
+ id="edf1603a-15ce-4211-82d5-8d0ca90921fc" name="Left to inner" target="#03c975d1-cda4-4e5d-be9a-5c76a06aecba"
+ source="#f212bec3-9e5f-4860-9be8-fc3a32e6642c"/>
+ id="fe7a5498-e966-44de-9bbd-369da9191344" name="Left to Hier" target="#28ab3abb-3071-4727-bbf4-fed671a5c48d"
+ source="#10816ee5-d960-42a5-8b00-5b2774ea86e6"/>
+ id="209d39e3-d6d9-4d87-8e48-a85b3a4565ab" name="IF2 to RF2" target="#da3e108d-c8b1-4beb-896a-bbb6618acf22"
+ source="#ad194d39-1467-490f-9825-a7bafcd3e952"/>
+ id="0b97879b-08f5-4fc2-bc3b-66e73e7c2158" name="IF2 to RF1" target="#ba26d020-30cc-4d79-ac9a-b4729663a9e5"
+ source="#09ad0a10-a06b-401e-a31b-3ca0e33ede8e"/>
+ id="867be9ff-4973-4320-9d3f-89009ab04a6b" name="Hier to RF 2" target="#13b6ebe6-6f3a-49a4-9085-da4053556cf5"
+ source="#d880486c-d917-47d8-b098-8e2b8db9ea5a"/>
name="Multiport" abstractType="#b3888dad-a870-4b8b-97d4-0ddb83ef9251"/>
-
-
-
-
-
-
-
-
-
name="Left 1" abstractType="#1c416771-64bc-4d0c-99eb-296ce27d0a35"/>
-
-
-
-
-
-
+
@@ -4073,95 +4030,6 @@ The predator is far away
kind="FLOW"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
id="3e0a3791-cc99-4af5-b789-5b33451ca743" name="CP 1" orientation="OUT"
kind="FLOW"/>
-
-
-
-
-
-