@yuneta/gobj-ui 7.23.83 → 7.23.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13982,7 +13982,7 @@ function ac_json_item_clicked(gobj, event, kw, src) {
13982
13982
  /************************************************************
13983
13983
  * EV_LANGUAGE_CHANGED — re-translate chrome + re-render
13984
13984
  ************************************************************/
13985
- function ac_language_changed$6(gobj, event, kw, src) {
13985
+ function ac_language_changed$8(gobj, event, kw, src) {
13986
13986
  let priv = gobj.priv;
13987
13987
  let $container = gobj_read_attr(gobj, "$container");
13988
13988
  if ($container) {
@@ -14043,7 +14043,7 @@ function create_gclass$12(gclass_name) {
14043
14043
  ],
14044
14044
  [
14045
14045
  "EV_LANGUAGE_CHANGED",
14046
- ac_language_changed$6,
14046
+ ac_language_changed$8,
14047
14047
  null
14048
14048
  ],
14049
14049
  [
@@ -14119,7 +14119,7 @@ function create_gclass$12(gclass_name) {
14119
14119
  ],
14120
14120
  [
14121
14121
  "EV_LANGUAGE_CHANGED",
14122
- ac_language_changed$6,
14122
+ ac_language_changed$8,
14123
14123
  null
14124
14124
  ],
14125
14125
  [
@@ -15058,7 +15058,7 @@ function ac_theme_changed(gobj, event, kw, src) {
15058
15058
  * inside an innerHTML string, where refresh_language()
15059
15059
  * cannot reach.
15060
15060
  ************************************************************/
15061
- function ac_language_changed$5(gobj, event, kw, src) {
15061
+ function ac_language_changed$7(gobj, event, kw, src) {
15062
15062
  let $container = gobj_read_attr(gobj, "$container");
15063
15063
  if ($container) refresh_language($container, t);
15064
15064
  load_fsm(gobj);
@@ -15165,7 +15165,7 @@ function create_gclass$11(gclass_name) {
15165
15165
  ],
15166
15166
  [
15167
15167
  "EV_LANGUAGE_CHANGED",
15168
- ac_language_changed$5,
15168
+ ac_language_changed$7,
15169
15169
  null
15170
15170
  ],
15171
15171
  [
@@ -16722,7 +16722,7 @@ function ac_copy_all(gobj, event, kw, src) {
16722
16722
  * is. Re-rendering is the only way both end up in the same
16723
16723
  * language.
16724
16724
  ************************************************************/
16725
- function ac_language_changed$4(gobj, event, kw, src) {
16725
+ function ac_language_changed$6(gobj, event, kw, src) {
16726
16726
  let priv = gobj.priv;
16727
16727
  let $container = gobj_read_attr(gobj, "$container");
16728
16728
  if ($container) {
@@ -16814,7 +16814,7 @@ function create_gclass$10(gclass_name) {
16814
16814
  ],
16815
16815
  [
16816
16816
  "EV_LANGUAGE_CHANGED",
16817
- ac_language_changed$4,
16817
+ ac_language_changed$6,
16818
16818
  null
16819
16819
  ],
16820
16820
  [
@@ -19398,7 +19398,7 @@ function ac_gclass_closed(gobj, event, kw, src) {
19398
19398
  * A rebuild, not a re-translation: the words live inside the
19399
19399
  * innerHTML of G6 nodes, where refresh_language() cannot go.
19400
19400
  ************************************************************/
19401
- function ac_language_changed$3(gobj, event, kw, src) {
19401
+ function ac_language_changed$5(gobj, event, kw, src) {
19402
19402
  let $container = gobj_read_attr(gobj, "$container");
19403
19403
  if ($container) refresh_language($container, t);
19404
19404
  hide_popover(gobj);
@@ -19542,7 +19542,7 @@ function create_gclass$9(gclass_name) {
19542
19542
  ],
19543
19543
  [
19544
19544
  "EV_LANGUAGE_CHANGED",
19545
- ac_language_changed$3,
19545
+ ac_language_changed$5,
19546
19546
  null
19547
19547
  ]
19548
19548
  ]]], gmt$9, 0, attrs_table$9, PRIVATE_DATA$9, 0, 0, 0, 0);
@@ -25730,7 +25730,7 @@ function refuse_if_readonly$2(gobj, event) {
25730
25730
  * placeholder, its loading/error notices — drawn once, from its own lang
25731
25731
  * dict. Re-apply it in the new language.
25732
25732
  ***************************************************************/
25733
- function ac_language_changed$2(gobj, event, kw, src) {
25733
+ function ac_language_changed$4(gobj, event, kw, src) {
25734
25734
  let bar = gobj_read_attr(gobj, "selection_bar");
25735
25735
  if (bar) bar.refresh();
25736
25736
  let tabulator = gobj_read_attr(gobj, "tabulator");
@@ -26568,7 +26568,7 @@ function create_gclass$5(gclass_name) {
26568
26568
  const states = [["ST_IDLE", [
26569
26569
  [
26570
26570
  "EV_LANGUAGE_CHANGED",
26571
- ac_language_changed$2,
26571
+ ac_language_changed$4,
26572
26572
  null
26573
26573
  ],
26574
26574
  [
@@ -27415,8 +27415,10 @@ function fold_reveal(model, state, node_key) {
27415
27415
  *
27416
27416
  * `radial`: the root in the middle and a ring per depth, each
27417
27417
  * subtree owning a sector proportional to its leaves; the radius
27418
- * of a ring grows until its neighbours sit side by side, so
27419
- * nothing overlaps by construction (see `layout_radial`).
27418
+ * of a ring grows until its neighbours sit side by side AND
27419
+ * until it clears the ring inside it, so nothing overlaps by
27420
+ * construction, across the ring or along the radius (see
27421
+ * `layout_radial`).
27420
27422
  *
27421
27423
  * Pure: takes plain nodes and edges, returns positions. The G6
27422
27424
  * classes in c_g6_nodes_tree.js are two thin adapters over it.
@@ -27596,6 +27598,10 @@ function tidy_tree_lr(nodes, edges, o) {
27596
27598
  }
27597
27599
  return pos;
27598
27600
  }
27601
+ function extent_at(n, a) {
27602
+ if (!n) return 0;
27603
+ return Math.abs(n.w * Math.cos(a)) + Math.abs(n.h * Math.sin(a));
27604
+ }
27599
27605
  /************************************************************
27600
27606
  * The radial tree: the root in the middle, a ring per depth.
27601
27607
  *
@@ -27638,14 +27644,15 @@ function layout_radial(nodes, edges, opts) {
27638
27644
  let ring_of = (id) => t.depth.get(id) + (single ? 0 : 1);
27639
27645
  let angle = /* @__PURE__ */ new Map();
27640
27646
  let rings = [];
27641
- let sector = (root_id, root_from, root_span) => {
27647
+ let sector = (root_id, root_from, root_span, root_parent) => {
27642
27648
  let stack = [{
27643
27649
  id: root_id,
27644
27650
  from: root_from,
27645
- span: root_span
27651
+ span: root_span,
27652
+ parent: root_parent
27646
27653
  }];
27647
27654
  while (stack.length) {
27648
- let { id, from, span } = stack.pop();
27655
+ let { id, from, span, parent } = stack.pop();
27649
27656
  let a = from + span / 2;
27650
27657
  angle.set(id, a);
27651
27658
  let ring = ring_of(id);
@@ -27654,7 +27661,9 @@ function layout_radial(nodes, edges, opts) {
27654
27661
  rings[ring].push({
27655
27662
  id,
27656
27663
  angle: a,
27657
- diag: Math.hypot(n.w, n.h)
27664
+ diag: Math.hypot(n.w, n.h),
27665
+ ext: extent_at(n, a),
27666
+ parent_ext: parent ? extent_at(t.by_id.get(parent), a) : 0
27658
27667
  });
27659
27668
  let cursor = from;
27660
27669
  for (let kid of t.children.get(id) || []) {
@@ -27662,7 +27671,8 @@ function layout_radial(nodes, edges, opts) {
27662
27671
  stack.push({
27663
27672
  id: kid,
27664
27673
  from: cursor,
27665
- span: part
27674
+ span: part,
27675
+ parent: id
27666
27676
  });
27667
27677
  cursor += part;
27668
27678
  }
@@ -27674,20 +27684,21 @@ function layout_radial(nodes, edges, opts) {
27674
27684
  let cursor = -Math.PI / 2;
27675
27685
  for (let kid of t.children.get(root) || []) {
27676
27686
  let part = 2 * Math.PI * leaves.get(kid) / leaves.get(root);
27677
- sector(kid, cursor, part);
27687
+ sector(kid, cursor, part, root);
27678
27688
  cursor += part;
27679
27689
  }
27680
27690
  } else {
27681
27691
  let cursor = -Math.PI / 2;
27682
27692
  for (let root of t.roots) {
27683
27693
  let part = 2 * Math.PI * leaves.get(root) / total;
27684
- sector(root, cursor, part);
27694
+ sector(root, cursor, part, null);
27685
27695
  cursor += part;
27686
27696
  }
27687
27697
  }
27688
27698
  let radius = [0];
27689
27699
  for (let ring = 1; ring < rings.length; ring++) {
27690
27700
  let r = radius[ring - 1] + o.ranksep;
27701
+ for (let n of rings[ring] || []) r = Math.max(r, radius[ring - 1] + (n.parent_ext + n.ext) / 2 + o.nodesep);
27691
27702
  let list = (rings[ring] || []).slice().sort((a, b) => a.angle - b.angle);
27692
27703
  for (let i = 0; i < list.length && list.length > 1; i++) {
27693
27704
  let a = list[i];
@@ -54673,11 +54684,14 @@ var PRIVATE_DATA$4 = {
54673
54684
  _edge_icon_el: null,
54674
54685
  _edge_delete_el: null,
54675
54686
  _edge_popover_el: null,
54687
+ _edge_preview_undo: null,
54676
54688
  _port_icon_el: null,
54677
54689
  _port_popover_el: null,
54690
+ _port_preview_undo: null,
54678
54691
  _node_icon_el: null,
54679
54692
  _node_delete_el: null,
54680
54693
  _node_popover_el: null,
54694
+ _node_preview_undo: null,
54681
54695
  _node_detail_el: null,
54682
54696
  _detail_node_id: null,
54683
54697
  _delete_confirm_el: null,
@@ -54761,12 +54775,16 @@ function mt_writing$1(gobj, path) {
54761
54775
  * Framework Method: Start
54762
54776
  ***************************************************************/
54763
54777
  function mt_start$4(gobj) {
54778
+ let shell = yui_shell_of(gobj);
54779
+ if (shell) gobj_subscribe_event(shell, "EV_LANGUAGE_CHANGED", {}, gobj);
54764
54780
  return 0;
54765
54781
  }
54766
54782
  /***************************************************************
54767
54783
  * Framework Method: Stop
54768
54784
  ***************************************************************/
54769
54785
  function mt_stop$4(gobj) {
54786
+ let shell = yui_shell_of(gobj);
54787
+ if (shell) gobj_unsubscribe_event(shell, "EV_LANGUAGE_CHANGED", {}, gobj);
54770
54788
  return 0;
54771
54789
  }
54772
54790
  /***************************************************************
@@ -54774,10 +54792,6 @@ function mt_stop$4(gobj) {
54774
54792
  ***************************************************************/
54775
54793
  function mt_destroy$4(gobj) {
54776
54794
  let priv = gobj.priv;
54777
- if (priv._on_language_changed) {
54778
- i18next.off("languageChanged", priv._on_language_changed);
54779
- priv._on_language_changed = null;
54780
- }
54781
54795
  uninstall_fold_listener(gobj);
54782
54796
  if (priv._on_pointerdown_focus) {
54783
54797
  priv.$container.removeEventListener("pointerdown", priv._on_pointerdown_focus, true);
@@ -54972,11 +54986,6 @@ function configure_events(gobj) {
54972
54986
  priv.last_zoom = z;
54973
54987
  if (priv.anchor_state === "on" && priv.anchor_id) yui_graph_center_on(priv.graph, priv.anchor_id);
54974
54988
  });
54975
- priv._on_language_changed = () => {
54976
- update_toolbar(gobj);
54977
- repaint_more_chips(gobj);
54978
- };
54979
- i18next.on("languageChanged", priv._on_language_changed);
54980
54989
  priv._on_pointerdown_focus = (ev) => {
54981
54990
  let target = ev.target;
54982
54991
  if (target && typeof target.closest === "function") {
@@ -55494,12 +55503,23 @@ var LR_LAYOUTS = ["dagre"];
55494
55503
  * toolbar's +/-, and the two-finger pinch of g6_touch_gestures.
55495
55504
  * `enable` on the scroll keeps the two apart: a Ctrl wheel is
55496
55505
  * the zoom's, so the scroll stands aside for it.
55506
+ *
55507
+ * And the two have to name the SAME key, or the gesture falls
55508
+ * between them: the scroll stood aside for Meta as well, while
55509
+ * the zoom listened for Control alone, so Cmd + wheel neither
55510
+ * scrolled nor zoomed. It is ONE key and not two because a G6
55511
+ * `trigger` is a CHORD, not a list of alternatives -- its
55512
+ * `Shortcut.match()` compares the held keys to the bound ones
55513
+ * as a SET, so ["Control", "Meta"] means both keys down at
55514
+ * once. Control it is, on every platform: it is what a
55515
+ * trackpad pinch arrives as, so a Mac keeps its pinch and
55516
+ * gains nothing to press by mistake.
55497
55517
  ************************************************************/
55498
55518
  function camera_behaviors() {
55499
55519
  return [{
55500
55520
  type: "scroll-canvas",
55501
55521
  key: "scroll-canvas",
55502
- enable: (event) => !(event && (event.ctrlKey || event.metaKey))
55522
+ enable: (event) => !(event && event.ctrlKey)
55503
55523
  }, {
55504
55524
  type: "zoom-canvas",
55505
55525
  key: "zoom-canvas",
@@ -55631,6 +55651,52 @@ function topic_defaults_of(gobj, topic_name) {
55631
55651
  return is_object(topic_props) && is_object(topic_props.defaults) ? topic_props.defaults : null;
55632
55652
  }
55633
55653
  /************************************************************
55654
+ * What a node is PAINTED with: its own colours, then the
55655
+ * topic's default, then the topic's colour.
55656
+ *
55657
+ * A card is html, and its html was built with `desc.color`
55658
+ * every time it was repainted -- so a colour chosen in the node
55659
+ * properties popover lasted until the next selection, focus,
55660
+ * theme or pill change, and was never written to `__graphs__`
55661
+ * at all. Only the `shape` view kept it, because a figure is a
55662
+ * native G6 node and `style.fill` is what paints it. The FIGURE
55663
+ * was already remembered (`node_shape`); this is the wiring the
55664
+ * colour was missing.
55665
+ ************************************************************/
55666
+ function node_paint_of(gobj, desc, geometry) {
55667
+ let defaults = topic_defaults_of(gobj, desc.topic_name);
55668
+ let g = is_object(geometry) ? geometry : {};
55669
+ let fill = g.fill || defaults && defaults.fill || desc.color;
55670
+ return {
55671
+ fill,
55672
+ stroke: g.stroke || defaults && defaults.stroke || getStrokeColor(fill),
55673
+ lineWidth: g.lineWidth || defaults && defaults.lineWidth || 1
55674
+ };
55675
+ }
55676
+ /************************************************************
55677
+ * Write a chosen paint into an entry of `__graphs__` -- a
55678
+ * node's or a topic's defaults.
55679
+ *
55680
+ * A colour nobody chose is not saved: the topic's own colour,
55681
+ * with the stroke and the line width that go with it, is what a
55682
+ * card wears anyway, and writing it down would freeze today's
55683
+ * palette on that card -- the trap the SIZES fell into in
55684
+ * 7.23.80, and the palette is assigned by POSITION (`ac_descs`),
55685
+ * so it moves when a topic is added. Choosing it back MEANS
55686
+ * forgetting the entry.
55687
+ ************************************************************/
55688
+ function paint_into(entry, desc, fill, stroke, line_width) {
55689
+ if (fill === desc.color && stroke === getStrokeColor(desc.color) && line_width === 1) {
55690
+ delete entry.fill;
55691
+ delete entry.stroke;
55692
+ delete entry.lineWidth;
55693
+ return;
55694
+ }
55695
+ entry.fill = fill;
55696
+ entry.stroke = stroke;
55697
+ entry.lineWidth = line_width;
55698
+ }
55699
+ /************************************************************
55634
55700
  * The CARD: an html node, the tier's size, the ports, the
55635
55701
  * saved geometry on top. The flags (focus, selection, anchor)
55636
55702
  * are not painted here: repaint_cards() reads them where they
@@ -55641,10 +55707,11 @@ function card_shape_of(gobj, desc, record, geometry, pills_html) {
55641
55707
  let node_treedb_type = desc.node_treedb_type;
55642
55708
  let label = node_label(desc, record);
55643
55709
  let ports = build_ports(gobj, desc);
55710
+ let paint = node_paint_of(gobj, desc, geometry);
55644
55711
  let style = {
55645
- fill: desc.color,
55646
- stroke: getStrokeColor(desc.color),
55647
- lineWidth: 1,
55712
+ fill: paint.fill,
55713
+ stroke: paint.stroke,
55714
+ lineWidth: paint.lineWidth,
55648
55715
  lineDash: [],
55649
55716
  halo: false,
55650
55717
  labelText: ""
@@ -55653,9 +55720,9 @@ function card_shape_of(gobj, desc, record, geometry, pills_html) {
55653
55720
  style.size = size;
55654
55721
  style.dx = -size[0] / 2;
55655
55722
  style.dy = -size[1] / 2;
55656
- if (node_treedb_type === "child") style.innerHTML = build_chip_innerHTML(desc.color, priv.theme, record.icon, label, record.id);
55657
- else if (node_treedb_type === "extended") style.innerHTML = build_node_innerHTML(desc.color, priv.theme, record.icon, label, desc.topic_name, true, record.id, false, false, false, pills_html);
55658
- else style.innerHTML = build_node_innerHTML(desc.color, priv.theme, record.icon, label, desc.topic_name, false, record.id, false, false, false, pills_html);
55723
+ if (node_treedb_type === "child") style.innerHTML = build_chip_innerHTML(paint.fill, priv.theme, record.icon, label, record.id);
55724
+ else if (node_treedb_type === "extended") style.innerHTML = build_node_innerHTML(paint.fill, priv.theme, record.icon, label, desc.topic_name, true, record.id, false, false, false, pills_html);
55725
+ else style.innerHTML = build_node_innerHTML(paint.fill, priv.theme, record.icon, label, desc.topic_name, false, record.id, false, false, false, pills_html);
55659
55726
  let topic_props = priv._graph_properties[desc.topic_name];
55660
55727
  let topic_defaults = is_object(topic_props) && is_object(topic_props.defaults) ? topic_props.defaults : null;
55661
55728
  if (topic_defaults) {
@@ -55727,17 +55794,18 @@ function pill_shape_of(gobj, desc, record, geometry) {
55727
55794
  let priv = gobj.priv;
55728
55795
  let size = PILL_SIZE[desc.node_treedb_type] || PILL_SIZE.hierarchical;
55729
55796
  let ports = build_ports(gobj, desc);
55797
+ let paint = node_paint_of(gobj, desc, geometry);
55730
55798
  let style = {
55731
- fill: desc.color,
55732
- stroke: getStrokeColor(desc.color),
55733
- lineWidth: 1,
55799
+ fill: paint.fill,
55800
+ stroke: paint.stroke,
55801
+ lineWidth: paint.lineWidth,
55734
55802
  lineDash: [],
55735
55803
  halo: false,
55736
55804
  labelText: "",
55737
55805
  size: [...size],
55738
55806
  dx: -size[0] / 2,
55739
55807
  dy: -size[1] / 2,
55740
- innerHTML: build_chip_innerHTML(desc.color, priv.theme, record.icon, node_label(desc, record), record.id)
55808
+ innerHTML: build_chip_innerHTML(paint.fill, priv.theme, record.icon, node_label(desc, record), record.id)
55741
55809
  };
55742
55810
  dress_ports(gobj, style, ports, geometry, topic_defaults_of(gobj, desc.topic_name), PORT_R_PILL, true);
55743
55811
  return {
@@ -55748,7 +55816,7 @@ function pill_shape_of(gobj, desc, record, geometry) {
55748
55816
  function pill_innerHTML_of(gobj, nd, theme, highlight, selected, anchored) {
55749
55817
  let desc = nd.data.desc;
55750
55818
  let record = nd.data.record || {};
55751
- return build_chip_innerHTML(desc.color, theme, record.icon, node_label(desc, record), record.id, highlight, selected, anchored);
55819
+ return build_chip_innerHTML(node_fill_of(nd), theme, record.icon, node_label(desc, record), record.id, highlight, selected, anchored);
55752
55820
  }
55753
55821
  function node_figure_of(gobj, desc, geometry) {
55754
55822
  let shape = geometry ? geometry.node_shape : null;
@@ -55775,8 +55843,9 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
55775
55843
  let side = SHAPE_SIZE[tier] || SHAPE_SIZE.hierarchical;
55776
55844
  let labels = gobj_read_bool_attr(gobj, "node_labels");
55777
55845
  let figure = node_figure_of(gobj, desc, geometry || {});
55778
- let stroke = getStrokeColor(desc.color);
55779
- let line_width = 1.5;
55846
+ let paint = node_paint_of(gobj, desc, geometry);
55847
+ let stroke = paint.stroke;
55848
+ let line_width = Math.max(paint.lineWidth, 1.5);
55780
55849
  if (f.selected) {
55781
55850
  stroke = SELECT_RING;
55782
55851
  line_width = 3;
@@ -55794,7 +55863,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
55794
55863
  let style = {
55795
55864
  size: [side, side],
55796
55865
  radius: figure === "square" ? Math.round(side / 5) : 0,
55797
- fill: desc.color,
55866
+ fill: paint.fill,
55798
55867
  stroke,
55799
55868
  lineWidth: line_width,
55800
55869
  lineDash: dash,
@@ -56967,6 +57036,34 @@ function hide_overlay(gobj, ...keys) {
56967
57036
  /************************************************************
56968
57037
  * Enable the save button (mark graph as dirty).
56969
57038
  ************************************************************/
57039
+ /************************************************************
57040
+ * A popover that PREVIEWS its changes owes an undo.
57041
+ *
57042
+ * What the preview writes is not the reader's answer until
57043
+ * `apply` is pressed, and `cancel` used to be the only way
57044
+ * back: every other way out of the popover -- a click on the
57045
+ * canvas, the icon pressed again, the element going away --
57046
+ * left the preview standing on the element, and the next Save
57047
+ * wrote it to `__graphs__`. So the undo is kept beside the
57048
+ * popover and run by whoever hides it; `apply` drops it first,
57049
+ * because then the preview IS the answer.
57050
+ ************************************************************/
57051
+ function set_preview_undo(gobj, key, undo) {
57052
+ gobj.priv[key] = undo;
57053
+ }
57054
+ function drop_preview_undo(gobj, key) {
57055
+ gobj.priv[key] = null;
57056
+ }
57057
+ function run_preview_undo(gobj, key) {
57058
+ let undo = gobj.priv[key];
57059
+ gobj.priv[key] = null;
57060
+ if (!undo || gobj_is_destroying(gobj)) return;
57061
+ try {
57062
+ undo();
57063
+ } catch (e) {
57064
+ log_error(`${gobj_short_name(gobj)}: cannot undo the preview: ${e}`);
57065
+ }
57066
+ }
56970
57067
  function mark_graph_dirty(gobj) {
56971
57068
  let $container = gobj_read_attr(gobj, "$container");
56972
57069
  enableElements($container, ".EV_SAVE_GRAPH");
@@ -57564,6 +57661,26 @@ function port_hit_slop_world(graph) {
57564
57661
  return slop / zoom;
57565
57662
  }
57566
57663
  /************************************************************
57664
+ * Whether a point landed on a port, by the port's SHAPE.
57665
+ *
57666
+ * A port was a circle and the test was a radius; since 7.23.81
57667
+ * it can be a square, a diamond or a triangle too, and a circle
57668
+ * around a diamond answers for the air off its corners while
57669
+ * missing the middle of its edges. `r` is the drawn radius with
57670
+ * the hit slop already added, and the shapes are the ones
57671
+ * TreedbCard.drawPortShapes() draws from it.
57672
+ *
57673
+ * dx, dy the point, relative to the port's centre
57674
+ ************************************************************/
57675
+ function port_shape_hit(shape, dx, dy, r) {
57676
+ switch (shape) {
57677
+ case "square": return Math.abs(dx) <= r && Math.abs(dy) <= r;
57678
+ case "diamond": return Math.abs(dx) + Math.abs(dy) <= r;
57679
+ case "triangle": return dy <= r && 2 * Math.abs(dx) - dy <= r;
57680
+ default: return Math.hypot(dx, dy) <= r;
57681
+ }
57682
+ }
57683
+ /************************************************************
57567
57684
  * Detect if a click in canvas coordinates hits a port.
57568
57685
  * Returns the port key string, or null if no port hit.
57569
57686
  ************************************************************/
@@ -57585,7 +57702,7 @@ function detect_port_click(gobj, node_id, canvasX, canvasY) {
57585
57702
  let dx = canvasX - px;
57586
57703
  let dy = canvasY - py;
57587
57704
  let dist = Math.sqrt(dx * dx + dy * dy);
57588
- if (dist <= r + slop && dist < best_dist) {
57705
+ if (port_shape_hit(ports[i].shape, dx, dy, r + slop) && dist < best_dist) {
57589
57706
  best_dist = dist;
57590
57707
  best_key = ports[i].key;
57591
57708
  }
@@ -57726,6 +57843,7 @@ function toggle_port_popover(gobj) {
57726
57843
  else show_port_popover(gobj);
57727
57844
  }
57728
57845
  function hide_port_popover(gobj) {
57846
+ run_preview_undo(gobj, "_port_preview_undo");
57729
57847
  hide_overlay(gobj, "_port_popover_el");
57730
57848
  }
57731
57849
  function ports_with(ports, port_key, changes) {
@@ -57747,6 +57865,18 @@ function show_port_popover(gobj) {
57747
57865
  let xy = port_icon_xy(gobj);
57748
57866
  if (!xy) return;
57749
57867
  const popover = create_popover_base(xy.x + floating_popover_dx(), xy.y, "g6-port-popover", "#d9d9d9", 180);
57868
+ let undo_port = () => {
57869
+ graph.updateNodeData([{
57870
+ id: node_id,
57871
+ style: { ports: ports_with(nodeData.style.ports, port_key, {
57872
+ shape: orig_shape,
57873
+ r: orig_r
57874
+ }) }
57875
+ }]);
57876
+ graph.draw().then(() => {
57877
+ update_port_resize_handles_position(gobj);
57878
+ });
57879
+ };
57750
57880
  function preview_port() {
57751
57881
  let r = parseInt(rInput.value) || orig_r;
57752
57882
  graph.updateNodeData([{
@@ -57790,27 +57920,19 @@ function show_port_popover(gobj) {
57790
57920
  text: "cancel",
57791
57921
  style: BTN_STYLE_CANCEL,
57792
57922
  onClick: () => {
57793
- graph.updateNodeData([{
57794
- id: node_id,
57795
- style: { ports: ports_with(nodeData.style.ports, port_key, {
57796
- shape: orig_shape,
57797
- r: orig_r
57798
- }) }
57799
- }]);
57800
- graph.draw().then(() => {
57801
- update_port_resize_handles_position(gobj);
57802
- });
57803
57923
  hide_port_popover(gobj);
57804
57924
  }
57805
57925
  }, {
57806
57926
  text: "apply",
57807
57927
  style: "flex:1;padding:6px;background:#1890ff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;font-weight:500;",
57808
57928
  onClick: () => {
57929
+ drop_preview_undo(gobj, "_port_preview_undo");
57809
57930
  apply_port_properties(gobj, node_id, port_key, shapeSelect.value, parseInt(rInput.value) || orig_r, scopeSelect.value);
57810
57931
  }
57811
57932
  }]);
57812
57933
  priv.$container.appendChild(popover);
57813
57934
  priv._port_popover_el = popover;
57935
+ set_preview_undo(gobj, "_port_preview_undo", undo_port);
57814
57936
  clamp_popover_position(gobj, popover);
57815
57937
  }
57816
57938
  /************************************************************
@@ -58412,6 +58534,16 @@ function show_edge_popover(gobj) {
58412
58534
  let mid = get_edge_viewport_midpoint(gobj, edge_id);
58413
58535
  if (!mid) return;
58414
58536
  const popover = create_popover_base(mid.x + floating_popover_dx(), mid.y + floating_icon_dy(), "g6-edge-popover", "#d9d9d9", 180);
58537
+ let undo_edge = () => {
58538
+ graph.updateEdgeData([{
58539
+ id: edge_id,
58540
+ style: {
58541
+ lineWidth: origLW,
58542
+ stroke: origStroke
58543
+ }
58544
+ }]);
58545
+ graph.draw();
58546
+ };
58415
58547
  function preview_edge() {
58416
58548
  let lw = parseInt(lwInput.value) || 2;
58417
58549
  let color = colorInput.value;
@@ -58447,25 +58579,19 @@ function show_edge_popover(gobj) {
58447
58579
  text: "cancel",
58448
58580
  style: BTN_STYLE_CANCEL,
58449
58581
  onClick: () => {
58450
- graph.updateEdgeData([{
58451
- id: edge_id,
58452
- style: {
58453
- lineWidth: origLW,
58454
- stroke: origStroke
58455
- }
58456
- }]);
58457
- graph.draw();
58458
58582
  deselect_edge(gobj);
58459
58583
  }
58460
58584
  }, {
58461
58585
  text: "apply",
58462
58586
  style: "flex:1;padding:6px;background:#52c41a;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;font-weight:500;",
58463
58587
  onClick: () => {
58588
+ drop_preview_undo(gobj, "_edge_preview_undo");
58464
58589
  apply_edge_properties(gobj, edge_id, parseInt(lwInput.value) || 2, colorInput.value, scopeSelect.value);
58465
58590
  }
58466
58591
  }]);
58467
58592
  priv.$container.appendChild(popover);
58468
58593
  priv._edge_popover_el = popover;
58594
+ set_preview_undo(gobj, "_edge_preview_undo", undo_edge);
58469
58595
  clamp_popover_position(gobj, popover);
58470
58596
  }
58471
58597
  /************************************************************
@@ -58487,6 +58613,7 @@ function clamp_popover_position(gobj, popover) {
58487
58613
  popover.style.top = top + "px";
58488
58614
  }
58489
58615
  function hide_edge_popover(gobj) {
58616
+ run_preview_undo(gobj, "_edge_preview_undo");
58490
58617
  hide_overlay(gobj, "_edge_popover_el");
58491
58618
  }
58492
58619
  /************************************************************
@@ -58561,23 +58688,23 @@ function show_node_popover(gobj) {
58561
58688
  let rect = get_node_viewport_rect(gobj, node_id);
58562
58689
  if (!rect) return;
58563
58690
  const popover = create_popover_base(rect.right + floating_popover_dx(), rect.top + floating_icon_dy(), "g6-node-popover", "#d9d9d9", 180);
58564
- let node_graph_type = nodeData.data && nodeData.data.desc ? nodeData.data.desc.node_treedb_type : null;
58565
- function preview_node() {
58566
- let fill = fillInput.value;
58567
- let updateStyle = {
58568
- fill,
58569
- stroke: strokeInput.value,
58570
- lineWidth: parseInt(lwInput.value) || 1
58571
- };
58572
- if (node_graph_type === "hierarchical") {
58573
- let record = nodeData.data.record || {};
58574
- updateStyle.innerHTML = build_node_innerHTML(fill, priv.theme, record.icon, node_label(nodeData.data.desc, record), nodeData.data.desc.topic_name, false, record.id, false, false, false, pills_html_of(gobj, nodeData));
58575
- }
58691
+ let paint_node = (fill, stroke, lw) => {
58576
58692
  graph.updateNodeData([{
58577
58693
  id: node_id,
58578
- style: updateStyle
58694
+ style: {
58695
+ fill,
58696
+ stroke,
58697
+ lineWidth: lw
58698
+ }
58579
58699
  }]);
58700
+ repaint_cards(gobj, /* @__PURE__ */ new Set([node_id]));
58580
58701
  graph.draw();
58702
+ };
58703
+ let undo_node = () => {
58704
+ paint_node(origFill, origStroke, origLW);
58705
+ };
58706
+ function preview_node() {
58707
+ paint_node(fillInput.value, strokeInput.value, parseInt(lwInput.value) || 1);
58581
58708
  }
58582
58709
  create_form_label(popover, "fill color");
58583
58710
  let fillInput = create_form_color_input(popover, currentFill, preview_node);
@@ -58612,34 +58739,23 @@ function show_node_popover(gobj) {
58612
58739
  text: "cancel",
58613
58740
  style: BTN_STYLE_CANCEL,
58614
58741
  onClick: () => {
58615
- let restoreStyle = {
58616
- fill: origFill,
58617
- stroke: origStroke,
58618
- lineWidth: origLW
58619
- };
58620
- if (node_graph_type === "hierarchical") {
58621
- let record = nodeData.data.record || {};
58622
- restoreStyle.innerHTML = build_node_innerHTML(origFill, priv.theme, record.icon, node_label(nodeData.data.desc, record), nodeData.data.desc.topic_name, false, record.id, false, false, false, pills_html_of(gobj, nodeData));
58623
- }
58624
- graph.updateNodeData([{
58625
- id: node_id,
58626
- style: restoreStyle
58627
- }]);
58628
- graph.draw();
58629
58742
  hide_node_popover(gobj);
58630
58743
  }
58631
58744
  }, {
58632
58745
  text: "apply",
58633
58746
  style: "flex:1;padding:6px;background:#1890ff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:13px;font-weight:500;",
58634
58747
  onClick: () => {
58748
+ drop_preview_undo(gobj, "_node_preview_undo");
58635
58749
  apply_node_properties(gobj, node_id, fillInput.value, strokeInput.value, parseInt(lwInput.value) || 1, scopeSelect.value, shapeSelect.value);
58636
58750
  }
58637
58751
  }]);
58638
58752
  priv.$container.appendChild(popover);
58639
58753
  priv._node_popover_el = popover;
58754
+ set_preview_undo(gobj, "_node_preview_undo", undo_node);
58640
58755
  clamp_popover_position(gobj, popover);
58641
58756
  }
58642
58757
  function hide_node_popover(gobj) {
58758
+ run_preview_undo(gobj, "_node_preview_undo");
58643
58759
  hide_overlay(gobj, "_node_popover_el");
58644
58760
  }
58645
58761
  /************************************************************
@@ -58827,15 +58943,19 @@ function refresh_minimap(gobj) {
58827
58943
  * same three-way choice — it lived inline in the theme refresh and is
58828
58944
  * shared now. Returns null for a node that carries no desc.
58829
58945
  ************************************************************/
58946
+ function node_fill_of(nd) {
58947
+ return nd && nd.style && nd.style.fill || nd.data.desc.color;
58948
+ }
58830
58949
  function node_innerHTML_of(nd, theme, highlight, selected, anchored, pills_html) {
58831
58950
  if (!nd || !nd.data || !nd.data.desc) return null;
58832
58951
  let desc = nd.data.desc;
58833
58952
  let record = nd.data.record || {};
58834
58953
  let label = node_label(desc, record);
58954
+ let fill = node_fill_of(nd);
58835
58955
  switch (desc.node_treedb_type) {
58836
- case "child": return build_chip_innerHTML(desc.color, theme, record.icon, label, record.id, highlight, selected, anchored);
58837
- case "extended": return build_node_innerHTML(desc.color, theme, record.icon, label, desc.topic_name, true, record.id, highlight, selected, anchored, pills_html);
58838
- case "hierarchical": return build_node_innerHTML(desc.color, theme, record.icon, label, desc.topic_name, false, record.id, highlight, selected, anchored, pills_html);
58956
+ case "child": return build_chip_innerHTML(fill, theme, record.icon, label, record.id, highlight, selected, anchored);
58957
+ case "extended": return build_node_innerHTML(fill, theme, record.icon, label, desc.topic_name, true, record.id, highlight, selected, anchored, pills_html);
58958
+ case "hierarchical": return build_node_innerHTML(fill, theme, record.icon, label, desc.topic_name, false, record.id, highlight, selected, anchored, pills_html);
58839
58959
  }
58840
58960
  return null;
58841
58961
  }
@@ -59390,15 +59510,19 @@ function apply_node_properties(gobj, node_id, fill, stroke, lineWidth, scope, sh
59390
59510
  if (!nodeData || !nodeData.data) return;
59391
59511
  let source_topic = nodeData.data.desc ? nodeData.data.desc.topic_name : null;
59392
59512
  let updates = [];
59513
+ let repaint = /* @__PURE__ */ new Set();
59393
59514
  const nodes = graph.getData().nodes;
59394
59515
  let figure = shape && str_in_list(NODE_SHAPES, shape) ? shape : "";
59395
59516
  let reshaped = [];
59396
- if (figure && scope !== "this") {
59517
+ if (scope !== "this") {
59397
59518
  let topics = scope === "same_topic" ? [source_topic] : Object.keys(priv.descs || {});
59398
59519
  for (let topic_name of topics) {
59520
+ let desc = priv.descs[topic_name];
59521
+ if (!desc) continue;
59399
59522
  if (!is_object(priv._graph_properties[topic_name])) priv._graph_properties[topic_name] = {};
59400
59523
  let defaults = priv._graph_properties[topic_name].defaults || {};
59401
- defaults.node_shape = figure;
59524
+ if (figure) defaults.node_shape = figure;
59525
+ paint_into(defaults, desc, fill, stroke, lineWidth);
59402
59526
  priv._graph_properties[topic_name].defaults = defaults;
59403
59527
  }
59404
59528
  }
@@ -59407,27 +59531,27 @@ function apply_node_properties(gobj, node_id, fill, stroke, lineWidth, scope, sh
59407
59531
  if (!nd || !nd.data || !nd.data.desc) continue;
59408
59532
  if (scope === "this" && nodes[i].id !== node_id) continue;
59409
59533
  if (scope === "same_topic" && nd.data.desc.topic_name !== source_topic) continue;
59534
+ let entry = node_props_entry(gobj, nd);
59410
59535
  if (figure) {
59411
- node_props_entry(gobj, nd).node_shape = figure;
59536
+ entry.node_shape = figure;
59412
59537
  if (node_mode_of(gobj, nodes[i].id) === "shape") reshaped.push(nodes[i].id);
59413
59538
  }
59539
+ paint_into(entry, nd.data.desc, fill, stroke, lineWidth);
59414
59540
  let updateStyle = {
59415
59541
  fill,
59416
59542
  stroke,
59417
59543
  lineWidth
59418
59544
  };
59419
- if (nd.data.desc.node_treedb_type === "hierarchical") {
59420
- let record = nd.data.record || {};
59421
- updateStyle.innerHTML = build_node_innerHTML(fill, priv.theme, record.icon, node_label(nd.data.desc, record), nd.data.desc.topic_name, false, record.id, false, false, false, pills_html_of(gobj, nd));
59422
- }
59423
59545
  updates.push({
59424
59546
  id: nodes[i].id,
59425
59547
  style: updateStyle
59426
59548
  });
59549
+ repaint.add(nodes[i].id);
59427
59550
  }
59428
59551
  if (updates.length > 0) {
59429
59552
  graph.updateNodeData(updates);
59430
59553
  if (reshaped.length) reshape_nodes(gobj, reshaped);
59554
+ repaint_cards(gobj, repaint);
59431
59555
  graph.draw().then(() => {
59432
59556
  mark_graph_dirty(gobj);
59433
59557
  });
@@ -60282,6 +60406,17 @@ async function reconcile_fold_apply(gobj, opts, visible) {
60282
60406
  return changed;
60283
60407
  }
60284
60408
  /************************************************************
60409
+ * The application changed language: what this gclass DRAWS has
60410
+ * to be drawn again. `refresh_language()` reaches what carries
60411
+ * an i18n key in the DOM; a G6 toolbar and the html of a chip
60412
+ * are built here and carry none.
60413
+ ************************************************************/
60414
+ function ac_language_changed$3(gobj, event, kw, src) {
60415
+ update_toolbar(gobj);
60416
+ repaint_more_chips(gobj);
60417
+ return 0;
60418
+ }
60419
+ /************************************************************
60285
60420
  * Repaint the `+N` chips (theme or language changed).
60286
60421
  ************************************************************/
60287
60422
  function repaint_more_chips(gobj) {
@@ -61517,6 +61652,11 @@ function create_gclass$4(gclass_name) {
61517
61652
  "EV_THEME",
61518
61653
  ac_theme$1,
61519
61654
  null
61655
+ ],
61656
+ [
61657
+ "EV_LANGUAGE_CHANGED",
61658
+ ac_language_changed$3,
61659
+ null
61520
61660
  ]
61521
61661
  ]]];
61522
61662
  const event_types = [
@@ -61577,7 +61717,8 @@ function create_gclass$4(gclass_name) {
61577
61717
  ["EV_SHOW", 0],
61578
61718
  ["EV_HIDE", 0],
61579
61719
  ["EV_RESIZE", 0],
61580
- ["EV_THEME", 0]
61720
+ ["EV_THEME", 0],
61721
+ ["EV_LANGUAGE_CHANGED", 0]
61581
61722
  ];
61582
61723
  __gclass__$4 = gclass_create(gclass_name, event_types, states, gmt$4, 0, attrs_table$4, PRIVATE_DATA$4, 0, 0, 0, gclass_flag_t.gcflag_manual_start);
61583
61724
  if (!__gclass__$4) return -1;
@@ -61665,6 +61806,7 @@ var PRIVATE_DATA$3 = {
61665
61806
  layout: null,
61666
61807
  _topics_subscribed: {},
61667
61808
  _legend_state: null,
61809
+ _find_result: null,
61668
61810
  _links_subscribed: false,
61669
61811
  is_pinhold_window: false
61670
61812
  };
@@ -61718,6 +61860,8 @@ function mt_writing(gobj, path) {
61718
61860
  ***************************************************************/
61719
61861
  function mt_start$3(gobj) {
61720
61862
  let priv = gobj.priv;
61863
+ let shell = yui_shell_of(gobj);
61864
+ if (shell) gobj_subscribe_event(shell, "EV_LANGUAGE_CHANGED", {}, gobj);
61721
61865
  if (priv.gobj_nodes_tree) gobj_start(priv.gobj_nodes_tree);
61722
61866
  if (priv.gobj_treedb_tables) gobj_start(priv.gobj_treedb_tables);
61723
61867
  request_treedb_descs(gobj);
@@ -61728,7 +61872,10 @@ function mt_start$3(gobj) {
61728
61872
  ***************************************************************/
61729
61873
  function mt_stop$3(gobj) {
61730
61874
  let shell = yui_shell_of(gobj);
61731
- if (shell) yui_shell_set_sub_routes(shell, gobj_read_str_attr(gobj, "base_route"), null);
61875
+ if (shell) {
61876
+ yui_shell_set_sub_routes(shell, gobj_read_str_attr(gobj, "base_route"), null);
61877
+ gobj_unsubscribe_event(shell, "EV_LANGUAGE_CHANGED", {}, gobj);
61878
+ }
61732
61879
  close_json_viewer(gobj);
61733
61880
  gobj_stop_children(gobj);
61734
61881
  }
@@ -63130,11 +63277,13 @@ function refresh_legend(gobj) {
63130
63277
  },
63131
63278
  hidden ? `${entry.total}` : `${entry.visible}/${entry.total}`
63132
63279
  ]);
63280
+ let body_key = is_main ? "main topic" : hidden ? "show topic" : "hide topic";
63133
63281
  let body_attrs = {
63134
63282
  class: "GRAPH_LEGEND_ITEM button is-small" + (focused ? " GRAPH_LEGEND_FOCUSED" : "") + (is_main ? " GRAPH_LEGEND_MAIN" : ""),
63135
63283
  type: "button",
63136
63284
  style: "gap:0; flex:0 0 auto;" + (focused ? " box-shadow: inset 0 0 0 2px var(--bulma-text, #2e333d);" : ""),
63137
- title: is_main ? t("main topic") : hidden ? t("show topic") : t("hide topic"),
63285
+ title: t(body_key),
63286
+ "data-i18n-title": body_key,
63138
63287
  "aria-label": topic_name,
63139
63288
  "aria-pressed": hidden ? "false" : "true"
63140
63289
  };
@@ -63161,6 +63310,7 @@ function refresh_legend(gobj) {
63161
63310
  title: t("main topic"),
63162
63311
  "data-i18n-title": "main topic",
63163
63312
  "aria-label": t("main topic"),
63313
+ "data-i18n-aria-label": "main topic",
63164
63314
  "aria-pressed": "true"
63165
63315
  },
63166
63316
  [[
@@ -63198,7 +63348,8 @@ function refresh_legend(gobj) {
63198
63348
  style: "padding:0 .4rem;",
63199
63349
  title: t("main topic"),
63200
63350
  "data-i18n-title": "main topic",
63201
- "aria-label": t("main topic")
63351
+ "aria-label": t("main topic"),
63352
+ "data-i18n-aria-label": "main topic"
63202
63353
  },
63203
63354
  [[
63204
63355
  "span",
@@ -63222,6 +63373,7 @@ function refresh_legend(gobj) {
63222
63373
  title: t("loose records"),
63223
63374
  "data-i18n-title": "loose records",
63224
63375
  "aria-label": t("loose records"),
63376
+ "data-i18n-aria-label": "loose records",
63225
63377
  "aria-pressed": entry.loose_shown ? "true" : "false"
63226
63378
  },
63227
63379
  `+${entry.loose}`,
@@ -63242,6 +63394,7 @@ function refresh_legend(gobj) {
63242
63394
  title: t("highlight topic"),
63243
63395
  "data-i18n-title": "highlight topic",
63244
63396
  "aria-label": t("highlight topic"),
63397
+ "data-i18n-aria-label": "highlight topic",
63245
63398
  "aria-pressed": focused ? "true" : "false"
63246
63399
  },
63247
63400
  [["i", {
@@ -63268,6 +63421,18 @@ function refresh_legend(gobj) {
63268
63421
  }
63269
63422
  }
63270
63423
  /************************************************************
63424
+ * The application changed language. `refresh_language()` has
63425
+ * already been over the document by now (the shell runs it
63426
+ * before publishing), so what is left is what carries no key:
63427
+ * the legend, whose chips say an ACTION that depends on the
63428
+ * state, and the find box's counted line.
63429
+ ************************************************************/
63430
+ function ac_language_changed$2(gobj, event, kw, src) {
63431
+ refresh_legend(gobj);
63432
+ refresh_find_result(gobj);
63433
+ return 0;
63434
+ }
63435
+ /************************************************************
63271
63436
  * The engine said what is drawn: repaint the strip.
63272
63437
  ************************************************************/
63273
63438
  function ac_legend_state(gobj, event, kw, src) {
@@ -63409,6 +63574,12 @@ function ac_toggle_node_labels(gobj, event, kw, src) {
63409
63574
  * term typed is an ANSWER and is shown; an empty box shows nothing.
63410
63575
  ************************************************************/
63411
63576
  function ac_find_result(gobj, event, kw, src) {
63577
+ gobj.priv._find_result = kw || null;
63578
+ refresh_find_result(gobj);
63579
+ return 0;
63580
+ }
63581
+ function refresh_find_result(gobj) {
63582
+ let kw = gobj.priv._find_result;
63412
63583
  let $container = gobj_read_attr(gobj, "$container");
63413
63584
  if (!$container) return 0;
63414
63585
  let $result = $container.querySelector(".GRAPH_FIND_RESULT");
@@ -63662,6 +63833,11 @@ function create_gclass$3(gclass_name) {
63662
63833
  "EV_TRANSPORT_STATE",
63663
63834
  ac_transport_state$1,
63664
63835
  null
63836
+ ],
63837
+ [
63838
+ "EV_LANGUAGE_CHANGED",
63839
+ ac_language_changed$2,
63840
+ null
63665
63841
  ]
63666
63842
  ]]];
63667
63843
  const event_types = [
@@ -63703,6 +63879,7 @@ function create_gclass$3(gclass_name) {
63703
63879
  ["EV_RECORD_WRITTEN", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
63704
63880
  ["EV_SHOW", 0],
63705
63881
  ["EV_HIDE", 0],
63882
+ ["EV_LANGUAGE_CHANGED", 0],
63706
63883
  ["EV_TRANSPORT_STATE", 0]
63707
63884
  ];
63708
63885
  __gclass__$3 = gclass_create(gclass_name, event_types, states, gmt$3, 0, attrs_table$3, PRIVATE_DATA$3, 0, 0, 0, 0);