@yuneta/gobj-ui 7.23.185 → 7.23.187

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.
@@ -23714,7 +23714,7 @@ function build_ui$6(gobj) {
23714
23714
  [[
23715
23715
  "span",
23716
23716
  { class: "icon" },
23717
- [yui_toolbar_icon("yi-hexagon-nodes")]
23717
+ [yui_toolbar_icon("yi-compass-drafting")]
23718
23718
  ], [
23719
23719
  "span",
23720
23720
  { i18n: "schema" },
@@ -23725,6 +23725,29 @@ function build_ui$6(gobj) {
23725
23725
  (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_LANDING_VIEW", {}, gobj);
23726
23726
  } }
23727
23727
  ],
23728
+ [
23729
+ "button",
23730
+ {
23731
+ class: "button TREEDB_SCHEMA_JSON_BTN is-hidden",
23732
+ title: (0, i18next.t)("schema json"),
23733
+ "aria-label": (0, i18next.t)("schema json"),
23734
+ "data-i18n-title": "schema json",
23735
+ "data-i18n-aria-label": "schema json"
23736
+ },
23737
+ [[
23738
+ "span",
23739
+ { class: "icon" },
23740
+ [yui_toolbar_icon("yi-code")]
23741
+ ], [
23742
+ "span",
23743
+ { i18n: "schema json" },
23744
+ "schema json"
23745
+ ]],
23746
+ { click: (evt) => {
23747
+ evt.stopPropagation();
23748
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_OPEN_SCHEMA_JSON", {}, gobj);
23749
+ } }
23750
+ ],
23728
23751
  [
23729
23752
  "div",
23730
23753
  {
@@ -24168,6 +24191,7 @@ function show_topics_landing(gobj) {
24168
24191
  let $info = $container.querySelector(".TREEDB_TOPIC_INFO");
24169
24192
  let $back = $container.querySelector(".TREEDB_TOPICS_BACK");
24170
24193
  let $toggle = $container.querySelector(".TREEDB_LANDING_TOGGLE");
24194
+ let $schema_json = $container.querySelector(".TREEDB_SCHEMA_JSON_BTN");
24171
24195
  if ($tabs) $tabs.classList.add("is-hidden");
24172
24196
  if ($sub) $sub.classList.add("is-hidden");
24173
24197
  if ($info) $info.classList.add("is-hidden");
@@ -24177,6 +24201,7 @@ function show_topics_landing(gobj) {
24177
24201
  $toggle.classList.remove("is-hidden");
24178
24202
  $toggle.classList.toggle("is-primary", schema_mode);
24179
24203
  }
24204
+ if ($schema_json) $schema_json.classList.toggle("is-hidden", !schema_mode);
24180
24205
  if (schema_mode) {
24181
24206
  if ($landing) $landing.classList.add("is-hidden");
24182
24207
  if ($schema) $schema.classList.remove("is-hidden");
@@ -24246,9 +24271,11 @@ function show_topic_detail(gobj) {
24246
24271
  let $info = $container.querySelector(".TREEDB_TOPIC_INFO");
24247
24272
  let $back = $container.querySelector(".TREEDB_TOPICS_BACK");
24248
24273
  let $toggle = $container.querySelector(".TREEDB_LANDING_TOGGLE");
24274
+ let $schema_json = $container.querySelector(".TREEDB_SCHEMA_JSON_BTN");
24249
24275
  if ($landing) $landing.classList.add("is-hidden");
24250
24276
  if ($schema) $schema.classList.add("is-hidden");
24251
24277
  if ($info) $info.classList.add("is-hidden");
24278
+ if ($schema_json) $schema_json.classList.add("is-hidden");
24252
24279
  if ($toggle) $toggle.classList.add("is-hidden");
24253
24280
  if ($tabs) $tabs.classList.remove("is-hidden");
24254
24281
  if ($sub) $sub.classList.remove("is-hidden");
@@ -24289,8 +24316,10 @@ function show_topic_info(gobj, topic) {
24289
24316
  let $schema = $container.querySelector(".TREEDB_TOPICS_SCHEMA");
24290
24317
  let $back = $container.querySelector(".TREEDB_TOPICS_BACK");
24291
24318
  let $toggle = $container.querySelector(".TREEDB_LANDING_TOGGLE");
24319
+ let $schema_json = $container.querySelector(".TREEDB_SCHEMA_JSON_BTN");
24292
24320
  if ($landing) $landing.classList.add("is-hidden");
24293
24321
  if ($schema) $schema.classList.add("is-hidden");
24322
+ if ($schema_json) $schema_json.classList.add("is-hidden");
24294
24323
  if ($toggle) $toggle.classList.add("is-hidden");
24295
24324
  if ($tabs) $tabs.classList.add("is-hidden");
24296
24325
  if ($sub) $sub.classList.add("is-hidden");
@@ -24565,7 +24594,7 @@ function register_sub_routes$1(gobj) {
24565
24594
  if ((0, _yuneta_gobj_js.is_object)((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "landing_routes"))) nodes.push({
24566
24595
  route: base + "/schema",
24567
24596
  label: "schema",
24568
- icon: "yi-hexagon-nodes",
24597
+ icon: "yi-compass-drafting",
24569
24598
  gclass: "C_YUI_TREEDB_SCHEMA"
24570
24599
  });
24571
24600
  if ((0, _yuneta_gobj_js.is_object)(descs)) for (let topic of Object.keys(descs)) {
@@ -24708,10 +24737,11 @@ function is_mobile$2() {
24708
24737
  * whole service (lazy drill). CHILD model: the viewer publishes
24709
24738
  * EV_EXPAND_PATH to us.
24710
24739
  ************************************************************/
24711
- function open_json_viewer$1(gobj) {
24740
+ function open_json_viewer$1(gobj, opts) {
24712
24741
  let priv = gobj.priv;
24742
+ let schema = !!(opts && opts.schema);
24713
24743
  if (priv.json_win || priv.json_modal) {
24714
- request_print_tranger$1(gobj, "");
24744
+ if (!schema) request_print_tranger$1(gobj, "");
24715
24745
  return;
24716
24746
  }
24717
24747
  if (!(0, _yuneta_gobj_js.gclass_find_by_name)("C_YUI_JSON")) {
@@ -24721,7 +24751,10 @@ function open_json_viewer$1(gobj) {
24721
24751
  }
24722
24752
  let mobile = is_mobile$2();
24723
24753
  let shell = yui_shell_of(gobj);
24724
- let jv = (0, _yuneta_gobj_js.gobj_create_service)(`treedb-topics-json-${(0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj))}`, "C_YUI_JSON", { subscriber: gobj }, gobj);
24754
+ let jv = (0, _yuneta_gobj_js.gobj_create_service)(`treedb-topics-json-${(0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj))}`, "C_YUI_JSON", {
24755
+ subscriber: gobj,
24756
+ json_data: schema ? (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "descs") : null
24757
+ }, gobj);
24725
24758
  if (!jv) {
24726
24759
  (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot create the JSON viewer`);
24727
24760
  return;
@@ -24739,7 +24772,7 @@ function open_json_viewer$1(gobj) {
24739
24772
  dialog: true,
24740
24773
  logical_class: "TREEDB_JSON_SHEET",
24741
24774
  title_prefix: priv.treedb_name,
24742
- title: "raw json",
24775
+ title: schema ? "schema json" : "raw json",
24743
24776
  t: i18next.t,
24744
24777
  on_close: () => {
24745
24778
  if ((0, _yuneta_gobj_js.gobj_is_destroying)(gobj)) return;
@@ -24761,8 +24794,8 @@ function open_json_viewer$1(gobj) {
24761
24794
  height: 620,
24762
24795
  logical_class: "TREEDB_JSON_WINDOW",
24763
24796
  title_prefix: priv.treedb_name,
24764
- title: "raw json",
24765
- icon: "yi-eye",
24797
+ title: schema ? "schema json" : "raw json",
24798
+ icon: schema ? "yi-code" : "yi-eye",
24766
24799
  body: $box,
24767
24800
  manager: null,
24768
24801
  on_close: () => {
@@ -24777,7 +24810,7 @@ function open_json_viewer$1(gobj) {
24777
24810
  }
24778
24811
  (0, _yuneta_gobj_js.gobj_start)(priv.json_win);
24779
24812
  }
24780
- request_print_tranger$1(gobj, "");
24813
+ if (!schema) request_print_tranger$1(gobj, "");
24781
24814
  }
24782
24815
  /************************************************************
24783
24816
  * Close the JSON viewer (user dismiss / teardown).
@@ -25371,6 +25404,19 @@ function ac_open_json$1(gobj, event, kw, src) {
25371
25404
  return 0;
25372
25405
  }
25373
25406
  /********************************************
25407
+ * The schema, as the json it is: the `descs` the schema graph is
25408
+ * drawing. Same viewer and same host as the tranger's raw json --
25409
+ * one at a time, so it closes whatever was open first.
25410
+ ********************************************/
25411
+ function ac_open_schema_json(gobj, event, kw, src) {
25412
+ if (!(0, _yuneta_gobj_js.is_object)((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "descs"))) {
25413
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: schema json with no descs`);
25414
+ return -1;
25415
+ }
25416
+ open_json_viewer$1(gobj, { schema: true });
25417
+ return 0;
25418
+ }
25419
+ /********************************************
25374
25420
  * Open the graph where the reader left it: its last visited
25375
25421
  * route under the graph's base -- `<graph>/<topic>` when a topic
25376
25422
  * was focused there -- or the bare base when the graph was never
@@ -25504,6 +25550,11 @@ function create_gclass$6(gclass_name) {
25504
25550
  ac_open_json$1,
25505
25551
  null
25506
25552
  ],
25553
+ [
25554
+ "EV_OPEN_SCHEMA_JSON",
25555
+ ac_open_schema_json,
25556
+ null
25557
+ ],
25507
25558
  [
25508
25559
  "EV_OPEN_GRAPH",
25509
25560
  ac_open_graph,
@@ -25576,6 +25627,7 @@ function create_gclass$6(gclass_name) {
25576
25627
  ["EV_RECORD_WRITTEN", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
25577
25628
  ["EV_REFRESH_TOPIC", 0],
25578
25629
  ["EV_OPEN_JSON", 0],
25630
+ ["EV_OPEN_SCHEMA_JSON", 0],
25579
25631
  ["EV_OPEN_GRAPH", 0],
25580
25632
  ["EV_EXPAND_PATH", 0],
25581
25633
  ["EV_JSON_CLOSED", 0],
@@ -30260,6 +30312,88 @@ function register_c_yui_treedb_topic_with_form() {
30260
30312
  return create_gclass$5(GCLASS_NAME$5);
30261
30313
  }
30262
30314
  //#endregion
30315
+ //#region src/graph_save_plan.js
30316
+ /***********************************************************************
30317
+ * graph_save_plan.js
30318
+ *
30319
+ * Which topics a Save of the graph has to write, and which it
30320
+ * must leave alone.
30321
+ *
30322
+ * The arrangement of a treedb graph lives in `__graphs__`, ONE
30323
+ * record per topic. The Save collected every topic the view had
30324
+ * loaded and wrote all of them, whatever had moved: on a treedb
30325
+ * of five topics, dragging one card appended five records, four
30326
+ * of them saying exactly what the record under them said. The
30327
+ * store is append-only, so those four are there for ever.
30328
+ *
30329
+ * This module is the decision, and nothing else: no G6, no DOM,
30330
+ * no gobj. Give it what the view is holding and what the backend
30331
+ * already has, and it answers which topics differ.
30332
+ *
30333
+ * Two things it deliberately does NOT do:
30334
+ *
30335
+ * - It does not ask the history plugin. The Save button lights
30336
+ * from two places -- `history.canUndo()` for what G6 records
30337
+ * (a move, a resize) and `mark_graph_dirty()` for what it does
30338
+ * not (a colour, a pill, a per-topic default) -- so the undo
30339
+ * stack is not the list of what changed, and reading it as one
30340
+ * would silently drop half the changes. A value comparison
30341
+ * sees both, and keeps working through undo, redo and a
30342
+ * history that was just cleared.
30343
+ *
30344
+ * - It does not compare `__origin__`. That key is the node_uuid
30345
+ * of whoever wrote the record, bookkeeping about the write and
30346
+ * not about the arrangement; comparing it would make every
30347
+ * topic differ the first time a second browser saved, and the
30348
+ * record it forces would say nothing new.
30349
+ *
30350
+ * Copyright (c) 2026, ArtGins.
30351
+ * All Rights Reserved.
30352
+ ***********************************************************************/
30353
+ /***************************************************************
30354
+ * The properties as they are worth comparing: everything
30355
+ * except who wrote them.
30356
+ ***************************************************************/
30357
+ function arrangement_of(properties) {
30358
+ if (!(0, _yuneta_gobj_js.is_object)(properties)) return {};
30359
+ let out = {};
30360
+ for (const [key, value] of Object.entries(properties)) {
30361
+ if (key === "__origin__") continue;
30362
+ out[key] = value;
30363
+ }
30364
+ return out;
30365
+ }
30366
+ /***************************************************************
30367
+ * TRUE when the arrangement the view holds for `topic_name`
30368
+ * is not the one the backend already has.
30369
+ *
30370
+ * A topic with no saved record has never been written, so
30371
+ * anything it holds is a change -- and an EMPTY arrangement
30372
+ * is not: a topic the view loaded and nobody ever arranged
30373
+ * has nothing to say, and saying it would create a record
30374
+ * that means "no layout".
30375
+ ***************************************************************/
30376
+ function topic_arrangement_changed(live, saved) {
30377
+ let a = arrangement_of(live);
30378
+ if (!saved) return Object.keys(a).length > 0;
30379
+ return !(0, _yuneta_gobj_js.json_is_identical)(a, arrangement_of(saved));
30380
+ }
30381
+ /***************************************************************
30382
+ * The topics a Save has to write.
30383
+ *
30384
+ * live {topic_name: properties} what the view holds
30385
+ * saved {topic_name: properties} what the backend has
30386
+ *
30387
+ * Returns their names, in the order the view holds them.
30388
+ ***************************************************************/
30389
+ function plan_graph_saves(live, saved) {
30390
+ let plan = [];
30391
+ if (!(0, _yuneta_gobj_js.is_object)(live)) return plan;
30392
+ let have = (0, _yuneta_gobj_js.is_object)(saved) ? saved : {};
30393
+ for (const [topic_name, properties] of Object.entries(live)) if (topic_arrangement_changed(properties, have[topic_name])) plan.push(topic_name);
30394
+ return plan;
30395
+ }
30396
+ //#endregion
30263
30397
  //#region src/treedb_node_label.js
30264
30398
  /***********************************************************************
30265
30399
  * treedb_node_label.js
@@ -58487,6 +58621,7 @@ var PRIVATE_DATA$4 = {
58487
58621
  graph: null,
58488
58622
  __graphs__: [],
58489
58623
  _graph_properties: {},
58624
+ _saved_graph_properties: {},
58490
58625
  yet_showed: false,
58491
58626
  edit_mode: false,
58492
58627
  operation_mode: null,
@@ -58737,7 +58872,7 @@ function build_graph$1(gobj) {
58737
58872
  container: priv.$container,
58738
58873
  animation: false,
58739
58874
  autoResize: false,
58740
- zoomRange: [.2, 4],
58875
+ zoomRange: [.02, 4],
58741
58876
  node: {
58742
58877
  palette: {
58743
58878
  type: "group",
@@ -59993,6 +60128,7 @@ function draw_link(gobj, child_topic, child_id, source_col, fkey, verbose) {
59993
60128
  parent_topic,
59994
60129
  parent_id,
59995
60130
  hook_name,
60131
+ child_topic,
59996
60132
  child_id,
59997
60133
  is_tree
59998
60134
  });
@@ -60072,11 +60208,15 @@ function clear_link(gobj, child_topic, child_id, source_col, fkey, verbose) {
60072
60208
  function build_graph_properties(gobj) {
60073
60209
  let priv = gobj.priv;
60074
60210
  priv._graph_properties = {};
60211
+ priv._saved_graph_properties = {};
60075
60212
  for (let i = 0; i < priv.__graphs__.length; i++) {
60076
60213
  let rec = priv.__graphs__[i];
60077
60214
  if (!rec.active || !rec.topic) continue;
60078
60215
  let props = rec.properties;
60079
- if ((0, _yuneta_gobj_js.is_object)(props)) priv._graph_properties[rec.topic] = props;
60216
+ if ((0, _yuneta_gobj_js.is_object)(props)) {
60217
+ priv._graph_properties[rec.topic] = props;
60218
+ priv._saved_graph_properties[rec.topic] = (0, _yuneta_gobj_js.json_deep_copy)(props);
60219
+ }
60080
60220
  }
60081
60221
  }
60082
60222
  /************************************************************
@@ -60161,35 +60301,22 @@ function save_geometry(gobj) {
60161
60301
  }
60162
60302
  const edges = graph.getData().edges;
60163
60303
  for (let i = 0; i < edges.length; i++) update_edge_geometry(gobj, edges[i].id);
60164
- let origin = (0, _yuneta_gobj_js.gobj_read_str_attr)((0, _yuneta_gobj_js.gobj_yuno)(), "node_uuid");
60165
- for (const [topic_name, properties] of Object.entries(priv._graph_properties)) {
60166
- properties.__origin__ = origin;
60167
- let kw_update = {
60168
- treedb_name: priv.treedb_name,
60169
- topic_name: "__graphs__",
60170
- record: {
60171
- id: topic_name,
60172
- topic: topic_name,
60173
- active: true,
60174
- properties
60175
- },
60176
- options: {
60177
- list_dict: true,
60178
- autolink: false,
60179
- create: true
60180
- }
60181
- };
60182
- (0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_UPDATE_NODE", kw_update);
60183
- }
60304
+ let plan = plan_graph_saves(priv._graph_properties, priv._saved_graph_properties);
60305
+ for (let i = 0; i < plan.length; i++) save_topic_graph_properties(gobj, plan[i]);
60184
60306
  }
60185
60307
  /************************************************************
60186
60308
  * Save __graphs__ properties for a single topic to backend.
60309
+ *
60310
+ * The ONE door to `__graphs__`: a caller that knows a topic moved
60311
+ * says so, and this decides whether the backend needs telling.
60187
60312
  ************************************************************/
60188
60313
  function save_topic_graph_properties(gobj, topic_name) {
60189
60314
  let priv = gobj.priv;
60190
60315
  let properties = priv._graph_properties[topic_name];
60191
60316
  if (!properties) return;
60317
+ if (!topic_arrangement_changed(properties, priv._saved_graph_properties[topic_name])) return;
60192
60318
  properties.__origin__ = (0, _yuneta_gobj_js.gobj_read_str_attr)((0, _yuneta_gobj_js.gobj_yuno)(), "node_uuid");
60319
+ priv._saved_graph_properties[topic_name] = (0, _yuneta_gobj_js.json_deep_copy)(properties);
60193
60320
  let kw_update = {
60194
60321
  treedb_name: priv.treedb_name,
60195
60322
  topic_name: "__graphs__",
@@ -60508,7 +60635,7 @@ async function graph_fit_selection(gobj, ids) {
60508
60635
  let bw = Math.max(1, maxx - minx);
60509
60636
  let bh = Math.max(1, maxy - miny);
60510
60637
  let zoom = Math.min(vw / bw, vh / bh);
60511
- let range = graph.getZoomRange() || [.2, 4];
60638
+ let range = graph.getZoomRange() || [.02, 4];
60512
60639
  zoom = Math.max(range[0], Math.min(range[1], zoom));
60513
60640
  await graph.zoomTo(zoom);
60514
60641
  await graph.focusElement(ids);
@@ -63245,16 +63372,14 @@ function refresh_html_nodes_theme(gobj, theme) {
63245
63372
  function refresh_default_edges_theme(gobj, theme) {
63246
63373
  let graph = gobj.priv.graph;
63247
63374
  if (!graph) return;
63248
- let dark = theme === "dark";
63249
63375
  let edges = graph.getData().edges || [];
63250
63376
  let updates = [];
63251
63377
  for (let i = 0; i < edges.length; i++) {
63252
63378
  let d = edges[i].data || {};
63253
63379
  if (!d.themed_default) continue;
63254
- let stroke = d.is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280";
63255
63380
  updates.push({
63256
63381
  id: edges[i].id,
63257
- style: { stroke }
63382
+ style: { stroke: default_edge_stroke(gobj, d, theme) }
63258
63383
  });
63259
63384
  }
63260
63385
  if (updates.length > 0) graph.updateEdgeData(updates);
@@ -63826,21 +63951,54 @@ function apply_edge_properties(gobj, edge_id, lineWidth, stroke, scope) {
63826
63951
  deselect_edge(gobj);
63827
63952
  }
63828
63953
  /************************************************************
63954
+ * The colour a link is DRAWN in: the colour of the two knobs it
63955
+ * joins.
63956
+ *
63957
+ * Both ends of a link wear the CHILD topic's colour -- the
63958
+ * parent's hook port is painted with the colour of whatever may
63959
+ * hang there, and the child's fkey port with its own (see
63960
+ * build_ports) -- so the line between them has one obvious
63961
+ * colour, and a reader follows a link by its hue instead of
63962
+ * tracing a grey thread across the canvas.
63963
+ *
63964
+ * It goes through port_rim(): the FILL of a port says which
63965
+ * topic, and a line on the canvas is a graphical object that
63966
+ * needs 3:1 against it, which that mix clears in both themes
63967
+ * (9.11 dark, 3.80 light) while keeping the hue. So a link is
63968
+ * drawn in exactly the colour of the rim of the two knobs it
63969
+ * ends on.
63970
+ *
63971
+ * The containment/tree relation (parent and child of the same
63972
+ * topic) is no longer marked by a teal of its own -- it is that
63973
+ * topic's colour like any other link, and what still tells it
63974
+ * apart is its WIDTH.
63975
+ *
63976
+ * A topic with no colour, or an edge of a graph with no schema
63977
+ * yet, keeps the neutral grey this used to give everything.
63978
+ ************************************************************/
63979
+ function default_edge_stroke(gobj, d, theme) {
63980
+ let priv = gobj.priv;
63981
+ let desc = (0, _yuneta_gobj_js.is_object)(priv.descs) ? priv.descs[d.child_topic] : null;
63982
+ if (desc && desc.color) return port_rim(desc.color, theme);
63983
+ let dark = theme === "dark";
63984
+ return d.is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280";
63985
+ }
63986
+ /************************************************************
63829
63987
  * The style an edge INHERITS, before anything saved for the
63830
63988
  * edge itself: its hook's default in the parent topic, else the
63831
63989
  * parent topic's default for every edge, else the library's.
63832
63990
  *
63833
- * The library's: neutral grey, teal for the containment/tree
63834
- * relation (parent and child of the same topic, a
63835
- * self-hierarchy). `themed_default` says the colour is still the
63836
- * library's, so a theme toggle re-themes it and leaves a chosen
63837
- * one alone.
63991
+ * The library's: the colour of the ports it joins (see
63992
+ * default_edge_stroke), and a wider line for the
63993
+ * containment/tree relation. `themed_default` says the colour is
63994
+ * still the library's, so a theme toggle re-themes it and leaves
63995
+ * a chosen one alone.
63838
63996
  ************************************************************/
63839
63997
  function edge_inherited_style_of(gobj, d) {
63840
- let dark = gobj.priv.theme === "dark";
63998
+ let priv = gobj.priv;
63841
63999
  let style = {
63842
64000
  lineWidth: d.is_tree ? 2 : 1.6,
63843
- stroke: d.is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280",
64001
+ stroke: default_edge_stroke(gobj, d, priv.theme),
63844
64002
  themed_default: true
63845
64003
  };
63846
64004
  let defs = topic_defaults_of(gobj, d.parent_topic);
@@ -71661,7 +71819,7 @@ function render_toolbar(gobj) {
71661
71819
  ]);
71662
71820
  let $right = [];
71663
71821
  if (priv.treedb_id && has_model) {
71664
- $right.push(toolbar_button("SCHEMA_DIAGRAM_BTN", "yi-hexagon-nodes", priv.diagram ? "topics" : "diagram", "EV_TOGGLE_DIAGRAM", false));
71822
+ $right.push(toolbar_button("SCHEMA_DIAGRAM_BTN", "yi-compass-drafting", priv.diagram ? "topics" : "diagram", "EV_TOGGLE_DIAGRAM", false));
71665
71823
  $right.push(toolbar_button("SCHEMA_VALIDATE_BTN", "yi-square-check", "check", "EV_VALIDATE", false));
71666
71824
  $right.push(toolbar_button("SCHEMA_EXPORT_BTN", "yi-download", "export", "EV_EXPORT", false));
71667
71825
  if (!readonly) $right.push(toolbar_button("SCHEMA_IMPORT_BTN", "yi-upload", "import", "EV_IMPORT", false));