@darajs/components 1.9.5 → 1.10.0

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.
@@ -786,6 +786,11 @@
786
786
  icon: [448, 512, [61460, "trash-alt"], "f2ed", "M135.2 17.7C140.6 6.8 151.7 0 163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3zM32 128H416V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zm96 64c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16z"]
787
787
  };
788
788
  var faTrashAlt = faTrashCan;
789
+ var faDownLeftAndUpRightToCenter = {
790
+ prefix: "fas",
791
+ iconName: "down-left-and-up-right-to-center",
792
+ icon: [512, 512, ["compress-alt"], "f422", "M439 7c9.4-9.4 24.6-9.4 33.9 0l32 32c9.4 9.4 9.4 24.6 0 33.9l-87 87 39 39c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8H296c-13.3 0-24-10.7-24-24V72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l39 39L439 7zM72 272H216c13.3 0 24 10.7 24 24V440c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39L73 505c-9.4 9.4-24.6 9.4-33.9 0L7 473c-9.4-9.4-9.4-24.6 0-33.9l87-87L55 313c-6.9-6.9-8.9-17.2-5.2-26.2s12.5-14.8 22.2-14.8z"]
793
+ };
789
794
  var faToggleOff = {
790
795
  prefix: "fas",
791
796
  iconName: "toggle-off",
@@ -933,6 +938,11 @@
933
938
  iconName: "moon",
934
939
  icon: [384, 512, [127769, 9214], "f186", "M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"]
935
940
  };
941
+ var faUpRightAndDownLeftFromCenter = {
942
+ prefix: "fas",
943
+ iconName: "up-right-and-down-left-from-center",
944
+ icon: [512, 512, ["expand-alt"], "f424", "M344 0H488c13.3 0 24 10.7 24 24V168c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39-87 87c-9.4 9.4-24.6 9.4-33.9 0l-32-32c-9.4-9.4-9.4-24.6 0-33.9l87-87L327 41c-6.9-6.9-8.9-17.2-5.2-26.2S334.3 0 344 0zM168 512H24c-13.3 0-24-10.7-24-24V344c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l39 39 87-87c9.4-9.4 24.6-9.4 33.9 0l32 32c9.4 9.4 9.4 24.6 0 33.9l-87 87 39 39c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8z"]
945
+ };
936
946
  var faCheck = {
937
947
  prefix: "fas",
938
948
  iconName: "check",
@@ -4055,6 +4065,9 @@
4055
4065
  const TrashAlt = (props) => {
4056
4066
  return jsxRuntime.exports.jsx(StyledFAIcon, Object.assign({ icon: faTrashAlt }, props));
4057
4067
  };
4068
+ const DownLeftAndUpRightToCenter = (props) => {
4069
+ return jsxRuntime.exports.jsx(StyledFAIcon, Object.assign({ icon: faDownLeftAndUpRightToCenter }, props));
4070
+ };
4058
4071
  const PenToSquare = (props) => {
4059
4072
  return jsxRuntime.exports.jsx(StyledFAIcon, Object.assign({ icon: faPenToSquare }, props));
4060
4073
  };
@@ -4070,6 +4083,9 @@
4070
4083
  const Xmark = (props) => {
4071
4084
  return jsxRuntime.exports.jsx(StyledFAIcon, Object.assign({ icon: faXmark }, props));
4072
4085
  };
4086
+ const UpRightAndDownLeftFromCenter = (props) => {
4087
+ return jsxRuntime.exports.jsx(StyledFAIcon, Object.assign({ icon: faUpRightAndDownLeftFromCenter }, props));
4088
+ };
4073
4089
  const TriangleExclamation = (props) => {
4074
4090
  return jsxRuntime.exports.jsx(StyledFAIcon, Object.assign({ icon: faTriangleExclamation }, props));
4075
4091
  };
@@ -5521,55 +5537,6 @@
5521
5537
  var step2 = (stop - start2) / Math.max(0, count2), power = Math.floor(Math.log(step2) / Math.LN10), error2 = step2 / Math.pow(10, power);
5522
5538
  return power >= 0 ? (error2 >= e10 ? 10 : error2 >= e5 ? 5 : error2 >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error2 >= e10 ? 10 : error2 >= e5 ? 5 : error2 >= e2 ? 2 : 1);
5523
5539
  }
5524
- function initRange(domain2, range2) {
5525
- switch (arguments.length) {
5526
- case 0:
5527
- break;
5528
- case 1:
5529
- this.range(domain2);
5530
- break;
5531
- default:
5532
- this.range(range2).domain(domain2);
5533
- break;
5534
- }
5535
- return this;
5536
- }
5537
- const implicit = Symbol("implicit");
5538
- function ordinal() {
5539
- var index2 = /* @__PURE__ */ new Map(), domain2 = [], range2 = [], unknown2 = implicit;
5540
- function scale(d2) {
5541
- var key = d2 + "", i2 = index2.get(key);
5542
- if (!i2) {
5543
- if (unknown2 !== implicit)
5544
- return unknown2;
5545
- index2.set(key, i2 = domain2.push(d2));
5546
- }
5547
- return range2[(i2 - 1) % range2.length];
5548
- }
5549
- scale.domain = function(_2) {
5550
- if (!arguments.length)
5551
- return domain2.slice();
5552
- domain2 = [], index2 = /* @__PURE__ */ new Map();
5553
- for (const value of _2) {
5554
- const key = value + "";
5555
- if (index2.has(key))
5556
- continue;
5557
- index2.set(key, domain2.push(value));
5558
- }
5559
- return scale;
5560
- };
5561
- scale.range = function(_2) {
5562
- return arguments.length ? (range2 = Array.from(_2), scale) : range2.slice();
5563
- };
5564
- scale.unknown = function(_2) {
5565
- return arguments.length ? (unknown2 = _2, scale) : unknown2;
5566
- };
5567
- scale.copy = function() {
5568
- return ordinal(domain2, range2).unknown(unknown2);
5569
- };
5570
- initRange.apply(scale, arguments);
5571
- return scale;
5572
- }
5573
5540
  function useIntersectionObserver(ref2, rootMargin = "0px", threshold = 1) {
5574
5541
  const [isIntersecting, setIntersecting] = React.useState(false);
5575
5542
  React.useEffect(() => {
@@ -24722,13 +24689,13 @@
24722
24689
  }
24723
24690
  function imageReference$1(state, node2) {
24724
24691
  const id2 = String(node2.identifier).toUpperCase();
24725
- const def = state.definitionById.get(id2);
24726
- if (!def) {
24692
+ const definition2 = state.definitionById.get(id2);
24693
+ if (!definition2) {
24727
24694
  return revert(state, node2);
24728
24695
  }
24729
- const properties = { src: normalizeUri(def.url || ""), alt: node2.alt };
24730
- if (def.title !== null && def.title !== void 0) {
24731
- properties.title = def.title;
24696
+ const properties = { src: normalizeUri(definition2.url || ""), alt: node2.alt };
24697
+ if (definition2.title !== null && definition2.title !== void 0) {
24698
+ properties.title = definition2.title;
24732
24699
  }
24733
24700
  const result = { type: "element", tagName: "img", properties, children: [] };
24734
24701
  state.patch(node2, result);
@@ -24760,13 +24727,13 @@
24760
24727
  }
24761
24728
  function linkReference$1(state, node2) {
24762
24729
  const id2 = String(node2.identifier).toUpperCase();
24763
- const def = state.definitionById.get(id2);
24764
- if (!def) {
24730
+ const definition2 = state.definitionById.get(id2);
24731
+ if (!definition2) {
24765
24732
  return revert(state, node2);
24766
24733
  }
24767
- const properties = { href: normalizeUri(def.url || "") };
24768
- if (def.title !== null && def.title !== void 0) {
24769
- properties.title = def.title;
24734
+ const properties = { href: normalizeUri(definition2.url || "") };
24735
+ if (definition2.title !== null && definition2.title !== void 0) {
24736
+ properties.title = definition2.title;
24770
24737
  }
24771
24738
  const result = {
24772
24739
  type: "element",
@@ -25281,12 +25248,14 @@
25281
25248
  const listItems = [];
25282
25249
  let referenceIndex = -1;
25283
25250
  while (++referenceIndex < state.footnoteOrder.length) {
25284
- const def = state.footnoteById.get(state.footnoteOrder[referenceIndex]);
25285
- if (!def) {
25251
+ const definition2 = state.footnoteById.get(
25252
+ state.footnoteOrder[referenceIndex]
25253
+ );
25254
+ if (!definition2) {
25286
25255
  continue;
25287
25256
  }
25288
- const content2 = state.all(def);
25289
- const id2 = String(def.identifier).toUpperCase();
25257
+ const content2 = state.all(definition2);
25258
+ const id2 = String(definition2.identifier).toUpperCase();
25290
25259
  const safeId = normalizeUri(id2.toLowerCase());
25291
25260
  let rereferenceIndex = 0;
25292
25261
  const backReferences = [];
@@ -25329,7 +25298,7 @@
25329
25298
  properties: { id: clobberPrefix + "fn-" + safeId },
25330
25299
  children: state.wrap(content2, true)
25331
25300
  };
25332
- state.patch(def, listItem2);
25301
+ state.patch(definition2, listItem2);
25333
25302
  listItems.push(listItem2);
25334
25303
  }
25335
25304
  if (listItems.length === 0) {
@@ -291946,6 +291915,55 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
291946
291915
  };
291947
291916
  return treemap;
291948
291917
  }
291918
+ function initRange(domain2, range2) {
291919
+ switch (arguments.length) {
291920
+ case 0:
291921
+ break;
291922
+ case 1:
291923
+ this.range(domain2);
291924
+ break;
291925
+ default:
291926
+ this.range(range2).domain(domain2);
291927
+ break;
291928
+ }
291929
+ return this;
291930
+ }
291931
+ const implicit = Symbol("implicit");
291932
+ function ordinal() {
291933
+ var index2 = /* @__PURE__ */ new Map(), domain2 = [], range2 = [], unknown2 = implicit;
291934
+ function scale(d2) {
291935
+ var key = d2 + "", i2 = index2.get(key);
291936
+ if (!i2) {
291937
+ if (unknown2 !== implicit)
291938
+ return unknown2;
291939
+ index2.set(key, i2 = domain2.push(d2));
291940
+ }
291941
+ return range2[(i2 - 1) % range2.length];
291942
+ }
291943
+ scale.domain = function(_2) {
291944
+ if (!arguments.length)
291945
+ return domain2.slice();
291946
+ domain2 = [], index2 = /* @__PURE__ */ new Map();
291947
+ for (const value of _2) {
291948
+ const key = value + "";
291949
+ if (index2.has(key))
291950
+ continue;
291951
+ index2.set(key, domain2.push(value));
291952
+ }
291953
+ return scale;
291954
+ };
291955
+ scale.range = function(_2) {
291956
+ return arguments.length ? (range2 = Array.from(_2), scale) : range2.slice();
291957
+ };
291958
+ scale.unknown = function(_2) {
291959
+ return arguments.length ? (unknown2 = _2, scale) : unknown2;
291960
+ };
291961
+ scale.copy = function() {
291962
+ return ordinal(domain2, range2).unknown(unknown2);
291963
+ };
291964
+ initRange.apply(scale, arguments);
291965
+ return scale;
291966
+ }
291949
291967
  function Transform$1(k2, x2, y2) {
291950
291968
  this.k = k2;
291951
291969
  this.x = x2;
@@ -297073,6 +297091,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
297073
297091
  }
297074
297092
  }
297075
297093
  const scrollIntoView = /* @__PURE__ */ StateEffect.define({ map: (t2, ch) => t2.map(ch) });
297094
+ const setEditContextFormatting = /* @__PURE__ */ StateEffect.define();
297076
297095
  function logException(state, exception, context2) {
297077
297096
  let handler = state.facet(exceptionSink);
297078
297097
  if (handler.length)
@@ -297312,10 +297331,11 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
297312
297331
  super();
297313
297332
  this.view = view;
297314
297333
  this.decorations = [];
297315
- this.dynamicDecorationMap = [];
297334
+ this.dynamicDecorationMap = [false];
297316
297335
  this.domChanged = null;
297317
297336
  this.hasComposition = null;
297318
297337
  this.markedForComposition = /* @__PURE__ */ new Set();
297338
+ this.editContextFormatting = Decoration.none;
297319
297339
  this.lastCompositionAfterCursor = false;
297320
297340
  this.minWidth = 0;
297321
297341
  this.minWidthFrom = 0;
@@ -297341,8 +297361,9 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
297341
297361
  this.minWidthTo = update2.changes.mapPos(this.minWidthTo, 1);
297342
297362
  }
297343
297363
  }
297364
+ this.updateEditContextFormatting(update2);
297344
297365
  let readCompositionAt = -1;
297345
- if (this.view.inputState.composing >= 0) {
297366
+ if (this.view.inputState.composing >= 0 && !this.view.observer.editContext) {
297346
297367
  if ((_a3 = this.domChanged) === null || _a3 === void 0 ? void 0 : _a3.newSel)
297347
297368
  readCompositionAt = this.domChanged.newSel.head;
297348
297369
  else if (!touchesComposition(update2.changes, this.hasComposition) && !update2.selectionSet)
@@ -297428,6 +297449,14 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
297428
297449
  if (composition)
297429
297450
  this.fixCompositionDOM(composition);
297430
297451
  }
297452
+ updateEditContextFormatting(update2) {
297453
+ this.editContextFormatting = this.editContextFormatting.map(update2.changes);
297454
+ for (let tr2 of update2.transactions)
297455
+ for (let effect2 of tr2.effects)
297456
+ if (effect2.is(setEditContextFormatting)) {
297457
+ this.editContextFormatting = effect2.value;
297458
+ }
297459
+ }
297431
297460
  compositionView(composition) {
297432
297461
  let cur = new TextView(composition.text.nodeValue);
297433
297462
  cur.flags |= 8;
@@ -297722,7 +297751,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
297722
297751
  return Decoration.set(deco);
297723
297752
  }
297724
297753
  updateDeco() {
297725
- let i2 = 0;
297754
+ let i2 = 1;
297726
297755
  let allDeco = this.view.state.facet(decorations).map((d2) => {
297727
297756
  let dynamic = this.dynamicDecorationMap[i2++] = typeof d2 == "function";
297728
297757
  return dynamic ? d2(this.view) : d2;
@@ -297738,6 +297767,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
297738
297767
  allDeco.push(RangeSet.join(outerDeco));
297739
297768
  }
297740
297769
  this.decorations = [
297770
+ this.editContextFormatting,
297741
297771
  ...allDeco,
297742
297772
  this.computeBlockGapDeco(),
297743
297773
  this.view.viewState.lineGapDeco
@@ -298358,6 +298388,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
298358
298388
  this.mouseSelection = mouseSelection;
298359
298389
  }
298360
298390
  update(update2) {
298391
+ this.view.observer.update(update2);
298361
298392
  if (this.mouseSelection)
298362
298393
  this.mouseSelection.update(update2);
298363
298394
  if (this.draggedContent && update2.docChanged)
@@ -298924,6 +298955,8 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
298924
298955
  updateForFocusChange(view);
298925
298956
  };
298926
298957
  observers.compositionstart = observers.compositionupdate = (view) => {
298958
+ if (view.observer.editContext)
298959
+ return;
298927
298960
  if (view.inputState.compositionFirstChange == null)
298928
298961
  view.inputState.compositionFirstChange = true;
298929
298962
  if (view.inputState.composing < 0) {
@@ -298931,6 +298964,8 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
298931
298964
  }
298932
298965
  };
298933
298966
  observers.compositionend = (view) => {
298967
+ if (view.observer.editContext)
298968
+ return;
298934
298969
  view.inputState.composing = -1;
298935
298970
  view.inputState.compositionEndedAt = Date.now();
298936
298971
  view.inputState.compositionPendingKey = true;
@@ -299986,12 +300021,12 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
299986
300021
  }
299987
300022
  gaps.push(gap);
299988
300023
  };
299989
- for (let line of this.viewportLines) {
299990
- if (line.length < doubleMargin)
299991
- continue;
300024
+ let checkLine = (line) => {
300025
+ if (line.length < doubleMargin || line.type != BlockType.Text)
300026
+ return;
299992
300027
  let structure = lineStructure(line.from, line.to, this.stateDeco);
299993
300028
  if (structure.total < doubleMargin)
299994
- continue;
300029
+ return;
299995
300030
  let target = this.scrollTarget ? this.scrollTarget.range.head : null;
299996
300031
  let viewFrom, viewTo;
299997
300032
  if (wrapping) {
@@ -300028,6 +300063,12 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
300028
300063
  addGap(line.from, viewFrom, line, structure);
300029
300064
  if (viewTo < line.to)
300030
300065
  addGap(viewTo, line.to, line, structure);
300066
+ };
300067
+ for (let line of this.viewportLines) {
300068
+ if (Array.isArray(line.type))
300069
+ line.type.forEach(checkLine);
300070
+ else
300071
+ checkLine(line);
300031
300072
  }
300032
300073
  return gaps;
300033
300074
  }
@@ -300634,18 +300675,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
300634
300675
  change = { from: sel.from, to: sel.to, insert: Text$1.of([" "]) };
300635
300676
  }
300636
300677
  if (change) {
300637
- if (browser.ios && view.inputState.flushIOSKey(change))
300638
- return true;
300639
- if (browser.android && (change.to == sel.to && (change.from == sel.from || change.from == sel.from - 1 && view.state.sliceDoc(change.from, sel.from) == " ") && change.insert.length == 1 && change.insert.lines == 2 && dispatchKey(view.contentDOM, "Enter", 13) || (change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 || lastKey == 8 && change.insert.length < change.to - change.from && change.to > sel.head) && dispatchKey(view.contentDOM, "Backspace", 8) || change.from == sel.from && change.to == sel.to + 1 && change.insert.length == 0 && dispatchKey(view.contentDOM, "Delete", 46)))
300640
- return true;
300641
- let text2 = change.insert.toString();
300642
- if (view.inputState.composing >= 0)
300643
- view.inputState.composing++;
300644
- let defaultTr;
300645
- let defaultInsert = () => defaultTr || (defaultTr = applyDefaultInsert(view, change, newSel));
300646
- if (!view.state.facet(inputHandler$1).some((h2) => h2(view, change.from, change.to, text2, defaultInsert)))
300647
- view.dispatch(defaultInsert());
300648
- return true;
300678
+ return applyDOMChangeInner(view, change, newSel, lastKey);
300649
300679
  } else if (newSel && !newSel.main.eq(sel)) {
300650
300680
  let scrollIntoView2 = false, userEvent = "select";
300651
300681
  if (view.inputState.lastSelectionTime > Date.now() - 50) {
@@ -300659,6 +300689,21 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
300659
300689
  return false;
300660
300690
  }
300661
300691
  }
300692
+ function applyDOMChangeInner(view, change, newSel, lastKey = -1) {
300693
+ if (browser.ios && view.inputState.flushIOSKey(change))
300694
+ return true;
300695
+ let sel = view.state.selection.main;
300696
+ if (browser.android && (change.to == sel.to && (change.from == sel.from || change.from == sel.from - 1 && view.state.sliceDoc(change.from, sel.from) == " ") && change.insert.length == 1 && change.insert.lines == 2 && dispatchKey(view.contentDOM, "Enter", 13) || (change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 || lastKey == 8 && change.insert.length < change.to - change.from && change.to > sel.head) && dispatchKey(view.contentDOM, "Backspace", 8) || change.from == sel.from && change.to == sel.to + 1 && change.insert.length == 0 && dispatchKey(view.contentDOM, "Delete", 46)))
300697
+ return true;
300698
+ let text2 = change.insert.toString();
300699
+ if (view.inputState.composing >= 0)
300700
+ view.inputState.composing++;
300701
+ let defaultTr;
300702
+ let defaultInsert = () => defaultTr || (defaultTr = applyDefaultInsert(view, change, newSel));
300703
+ if (!view.state.facet(inputHandler$1).some((h2) => h2(view, change.from, change.to, text2, defaultInsert)))
300704
+ view.dispatch(defaultInsert());
300705
+ return true;
300706
+ }
300662
300707
  function applyDefaultInsert(view, change, newSel) {
300663
300708
  let tr2, startState = view.state, sel = startState.selection.main;
300664
300709
  if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 && (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) && view.inputState.composing < 0) {
@@ -300767,6 +300812,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
300767
300812
  constructor(view) {
300768
300813
  this.view = view;
300769
300814
  this.active = false;
300815
+ this.editContext = null;
300770
300816
  this.selectionRange = new DOMSelectionState();
300771
300817
  this.selectionChanged = false;
300772
300818
  this.delayedFlush = -1;
@@ -300792,6 +300838,10 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
300792
300838
  else
300793
300839
  this.flush();
300794
300840
  });
300841
+ if (window.EditContext && view.constructor.EDIT_CONTEXT !== false) {
300842
+ this.editContext = new EditContextManager(view);
300843
+ view.contentDOM.editContext = this.editContext.editContext;
300844
+ }
300795
300845
  if (useCharData)
300796
300846
  this.onCharData = (event2) => {
300797
300847
  this.queue.push({
@@ -300844,6 +300894,8 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
300844
300894
  onScroll(e3) {
300845
300895
  if (this.intersecting)
300846
300896
  this.flush(false);
300897
+ if (this.editContext)
300898
+ this.view.requestMeasure(this.editContext.measureReq);
300847
300899
  this.onScrollChanged(e3);
300848
300900
  }
300849
300901
  onResize() {
@@ -301116,6 +301168,10 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
301116
301168
  win.removeEventListener("beforeprint", this.onPrint);
301117
301169
  win.document.removeEventListener("selectionchange", this.onSelectionChange);
301118
301170
  }
301171
+ update(update2) {
301172
+ if (this.editContext)
301173
+ this.editContext.update(update2);
301174
+ }
301119
301175
  destroy() {
301120
301176
  var _a3, _b, _c;
301121
301177
  this.stop();
@@ -301166,6 +301222,147 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
301166
301222
  view.contentDOM.removeEventListener("beforeinput", read2, true);
301167
301223
  return found ? buildSelectionRangeFromRange(view, found) : null;
301168
301224
  }
301225
+ class EditContextManager {
301226
+ constructor(view) {
301227
+ this.from = 0;
301228
+ this.to = 0;
301229
+ this.pendingContextChange = null;
301230
+ this.resetRange(view.state);
301231
+ let context2 = this.editContext = new window.EditContext({
301232
+ text: view.state.doc.sliceString(this.from, this.to),
301233
+ selectionStart: this.toContextPos(Math.max(this.from, Math.min(this.to, view.state.selection.main.anchor))),
301234
+ selectionEnd: this.toContextPos(view.state.selection.main.head)
301235
+ });
301236
+ context2.addEventListener("textupdate", (e3) => {
301237
+ let { anchor } = view.state.selection.main;
301238
+ let change = {
301239
+ from: this.toEditorPos(e3.updateRangeStart),
301240
+ to: this.toEditorPos(e3.updateRangeEnd),
301241
+ insert: Text$1.of(e3.text.split("\n"))
301242
+ };
301243
+ if (change.from == this.from && anchor < this.from)
301244
+ change.from = anchor;
301245
+ else if (change.to == this.to && anchor > this.to)
301246
+ change.to = anchor;
301247
+ if (change.from == change.to && !change.insert.length)
301248
+ return;
301249
+ this.pendingContextChange = change;
301250
+ applyDOMChangeInner(view, change, EditorSelection.single(this.toEditorPos(e3.selectionStart), this.toEditorPos(e3.selectionEnd)));
301251
+ if (this.pendingContextChange)
301252
+ this.revertPending(view.state);
301253
+ });
301254
+ context2.addEventListener("characterboundsupdate", (e3) => {
301255
+ let rects = [], prev = null;
301256
+ for (let i2 = this.toEditorPos(e3.rangeStart), end2 = this.toEditorPos(e3.rangeEnd); i2 < end2; i2++) {
301257
+ let rect = view.coordsForChar(i2);
301258
+ prev = rect && new DOMRect(rect.left, rect.right, rect.right - rect.left, rect.bottom - rect.top) || prev || new DOMRect();
301259
+ rects.push(prev);
301260
+ }
301261
+ context2.updateCharacterBounds(e3.rangeStart, rects);
301262
+ });
301263
+ context2.addEventListener("textformatupdate", (e3) => {
301264
+ let deco = [];
301265
+ for (let format2 of e3.getTextFormats()) {
301266
+ let lineStyle = format2.underlineStyle, thickness = format2.underlineThickness;
301267
+ if (lineStyle != "None" && thickness != "None") {
301268
+ let style2 = `text-decoration: underline ${lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${thickness == "Thin" ? 1 : 2}px`;
301269
+ deco.push(Decoration.mark({ attributes: { style: style2 } }).range(this.toEditorPos(format2.rangeStart), this.toEditorPos(format2.rangeEnd)));
301270
+ }
301271
+ }
301272
+ view.dispatch({ effects: setEditContextFormatting.of(Decoration.set(deco)) });
301273
+ });
301274
+ context2.addEventListener("compositionstart", () => {
301275
+ if (view.inputState.composing < 0) {
301276
+ view.inputState.composing = 0;
301277
+ view.inputState.compositionFirstChange = true;
301278
+ }
301279
+ });
301280
+ context2.addEventListener("compositionend", () => {
301281
+ view.inputState.composing = -1;
301282
+ view.inputState.compositionFirstChange = null;
301283
+ });
301284
+ this.measureReq = { read: (view2) => {
301285
+ this.editContext.updateControlBounds(view2.contentDOM.getBoundingClientRect());
301286
+ let sel = getSelection(view2.root);
301287
+ if (sel && sel.rangeCount)
301288
+ this.editContext.updateSelectionBounds(sel.getRangeAt(0).getBoundingClientRect());
301289
+ } };
301290
+ }
301291
+ applyEdits(update2) {
301292
+ let off = 0, abort = false, pending = this.pendingContextChange;
301293
+ update2.changes.iterChanges((fromA, toA, _fromB, _toB, insert2) => {
301294
+ if (abort)
301295
+ return;
301296
+ let dLen = insert2.length - (toA - fromA);
301297
+ if (pending && toA >= pending.to) {
301298
+ if (pending.from == fromA && pending.to == toA && pending.insert.eq(insert2)) {
301299
+ pending = this.pendingContextChange = null;
301300
+ off += dLen;
301301
+ return;
301302
+ } else {
301303
+ pending = null;
301304
+ this.revertPending(update2.state);
301305
+ }
301306
+ }
301307
+ fromA += off;
301308
+ toA += off;
301309
+ if (toA <= this.from) {
301310
+ this.from += dLen;
301311
+ this.to += dLen;
301312
+ } else if (fromA < this.to) {
301313
+ if (fromA < this.from || toA > this.to || this.to - this.from + insert2.length > 3e4) {
301314
+ abort = true;
301315
+ return;
301316
+ }
301317
+ this.editContext.updateText(this.toContextPos(fromA), this.toContextPos(toA), insert2.toString());
301318
+ this.to += dLen;
301319
+ }
301320
+ off += dLen;
301321
+ });
301322
+ if (pending && !abort)
301323
+ this.revertPending(update2.state);
301324
+ return !abort;
301325
+ }
301326
+ update(update2) {
301327
+ if (!this.applyEdits(update2) || !this.rangeIsValid(update2.state)) {
301328
+ this.pendingContextChange = null;
301329
+ this.resetRange(update2.state);
301330
+ this.editContext.updateText(0, this.editContext.text.length, update2.state.doc.sliceString(this.from, this.to));
301331
+ this.setSelection(update2.state);
301332
+ } else if (update2.docChanged || update2.selectionSet) {
301333
+ this.setSelection(update2.state);
301334
+ }
301335
+ if (update2.geometryChanged || update2.docChanged || update2.selectionSet)
301336
+ update2.view.requestMeasure(this.measureReq);
301337
+ }
301338
+ resetRange(state) {
301339
+ let { head } = state.selection.main;
301340
+ this.from = Math.max(0, head - 1e4);
301341
+ this.to = Math.min(state.doc.length, head + 1e4);
301342
+ }
301343
+ revertPending(state) {
301344
+ let pending = this.pendingContextChange;
301345
+ this.pendingContextChange = null;
301346
+ this.editContext.updateText(this.toContextPos(pending.from), this.toContextPos(pending.to + pending.insert.length), state.doc.sliceString(pending.from, pending.to));
301347
+ }
301348
+ setSelection(state) {
301349
+ let { main: main2 } = state.selection;
301350
+ let start2 = this.toContextPos(Math.max(this.from, Math.min(this.to, main2.anchor)));
301351
+ let end2 = this.toContextPos(main2.head);
301352
+ if (this.editContext.selectionStart != start2 || this.editContext.selectionEnd != end2)
301353
+ this.editContext.updateSelection(start2, end2);
301354
+ }
301355
+ rangeIsValid(state) {
301356
+ let { head } = state.selection.main;
301357
+ return !(this.from > 0 && head - this.from < 500 || this.to < state.doc.length && this.to - head < 500 || this.to - this.from > 1e4 * 3);
301358
+ }
301359
+ toEditorPos(contextPos) {
301360
+ return contextPos + this.from;
301361
+ }
301362
+ toContextPos(editorPos) {
301363
+ return editorPos - this.from;
301364
+ }
301365
+ }
301169
301366
  class EditorView {
301170
301367
  get state() {
301171
301368
  return this.viewState.state;
@@ -301698,6 +301895,8 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
301698
301895
  }
301699
301896
  }
301700
301897
  destroy() {
301898
+ if (this.root.activeElement == this.contentDOM)
301899
+ this.contentDOM.blur();
301701
301900
  for (let plugin of this.plugins)
301702
301901
  plugin.destroy(this);
301703
301902
  this.plugins = [];
@@ -311364,6 +311563,11 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
311364
311563
  function SoftEdgeArrowButton() {
311365
311564
  return jsxRuntime.exports.jsxs("svg", { fill: "none", height: "15", viewBox: "0 0 16 15", width: "16", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntime.exports.jsx("path", { d: "M9.1333 0.867188C10.9545 0.867188 12.701 1.59064 13.9888 2.87839C15.2765 4.16614 16 5.9127 16 7.73385C16 9.55501 15.2765 11.3016 13.9888 12.5893C12.701 13.8771 10.9545 14.6005 9.1333 14.6005L9.1333 12.2659C10.3353 12.2659 11.488 11.7884 12.3379 10.9385C13.1878 10.0885 13.6653 8.93581 13.6653 7.73385C13.6653 6.53189 13.1878 5.37916 12.3379 4.52925C11.488 3.67933 10.3353 3.20185 9.1333 3.20185V0.867188Z", fill: "currentColor" }), jsxRuntime.exports.jsx("path", { d: "M1.14286 6.59375H14.1667V8.87946H1.14286C0.510714 8.87946 0 8.36875 0 7.73661C0 7.10446 0.510714 6.59375 1.14286 6.59375Z", fill: "currentColor" }), jsxRuntime.exports.jsx("circle", { cx: "9.13389", cy: "2.03452", fill: "currentColor", r: "1.16733" }), jsxRuntime.exports.jsx("circle", { cx: "9.13389", cy: "13.4344", fill: "currentColor", r: "1.16733" })] });
311366
311565
  }
311566
+ function CollapseExpandGroupButton(props) {
311567
+ const { disablePointerEvents } = React.useContext(pointerCtx);
311568
+ const buttonText = props.showExpandAll ? "Collapse All" : "Expand All";
311569
+ return jsxRuntime.exports.jsx(Tooltip$1, { content: buttonText, placement: "bottom", children: jsxRuntime.exports.jsx(FloatingButton, { "aria-label": buttonText, disableEvents: disablePointerEvents, fixedSize: true, onClick: props.showExpandAll ? props.onCollapseAll : props.onExpandAll, style: { padding: "0 0.75rem" }, children: props.showExpandAll ? jsxRuntime.exports.jsx(DownLeftAndUpRightToCenter, {}) : jsxRuntime.exports.jsx(UpRightAndDownLeftFromCenter, {}) }) });
311570
+ }
311367
311571
  function SaveImageButton(props) {
311368
311572
  const [hovered, setHovered] = React.useState(false);
311369
311573
  const { disablePointerEvents } = React.useContext(pointerCtx);
@@ -311818,6 +312022,8 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
311818
312022
  return deque;
311819
312023
  };
311820
312024
  var hasCycle = hasCycle$1;
312025
+ const DEFAULT_NODE_SIZE$1 = 64;
312026
+ const TARGET_NODE_MULTIPLIER = 1.25;
311821
312027
  function willCreateCycle(graphOriginal, edge) {
311822
312028
  const graph = graphOriginal.copy();
311823
312029
  try {
@@ -311854,14 +312060,14 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
311854
312060
  function getTooltipContent(id2, data2, theme2, label, tooltipSize) {
311855
312061
  return jsxRuntime.exports.jsxs("div", { children: [jsxRuntime.exports.jsx("div", { style: { display: "flex", flexDirection: "row", justifyContent: "center" }, children: jsxRuntime.exports.jsx("h2", { style: { fontSize: tooltipSize ? `${tooltipSize}px` : theme2.font.size }, children: label !== null && label !== void 0 ? label : id2 }) }), data2 && typeof data2 === "object" && jsxRuntime.exports.jsx("ul", { style: { margin: 0, padding: 0, paddingLeft: "1rem", paddingTop: "1rem" }, children: Object.keys(data2).map((key) => jsxRuntime.exports.jsx("li", { children: jsxRuntime.exports.jsxs("p", { style: { fontSize: tooltipSize ? `${tooltipSize}px` : theme2.font.size }, children: [jsxRuntime.exports.jsxs("strong", { children: [key, ": "] }), data2[key]] }) }, `${id2}-${String(data2[key])}`)) }), data2 && typeof data2 === "string" && jsxRuntime.exports.jsx("span", { style: { margin: 0, padding: 0, paddingTop: "1rem" }, children: data2 })] });
311856
312062
  }
311857
- function getNodeGroup(graph, id2, isLatent) {
311858
- let group = "other";
312063
+ function getNodeCategory(graph, id2, isLatent) {
312064
+ let category = "other";
311859
312065
  if (isLatent) {
311860
- group = "latent";
311861
- } else if (graph.inDegree(id2) > 0 && graph.outDegree(id2) === 0) {
311862
- group = "target";
312066
+ category = "latent";
312067
+ } else if (graph.hasNode(id2) && graph.inDegree(id2) > 0 && graph.outDegree(id2) === 0) {
312068
+ category = "target";
311863
312069
  }
311864
- return group;
312070
+ return category;
311865
312071
  }
311866
312072
  function isDag(graph) {
311867
312073
  if (hasCycle(graph)) {
@@ -311891,7 +312097,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
311891
312097
  }
311892
312098
  return void 0;
311893
312099
  }
311894
- function getNodeGroups(nodes, group, graph) {
312100
+ function getGroupToNodesMap(nodes, group, graph) {
311895
312101
  const attributePathArray = group.split(".");
311896
312102
  return nodes.reduce((groupAccumulator, node2) => {
311897
312103
  const nodeAttributes = graph.getNodeAttributes(node2);
@@ -311907,6 +312113,18 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
311907
312113
  return groupAccumulator;
311908
312114
  }, {});
311909
312115
  }
312116
+ function getNodeToGroupMap(nodes, group, graph) {
312117
+ const attributePathArray = group.split(".");
312118
+ return nodes.reduce((nodeToGroupMap, node2) => {
312119
+ const nodeAttributes = graph.getNodeAttributes(node2);
312120
+ const nodeGroup = attributePathArray.reduce(getPathInNodeAttribute, nodeAttributes);
312121
+ if (nodeGroup !== void 0) {
312122
+ const groupKey = String(nodeGroup);
312123
+ nodeToGroupMap[node2] = groupKey;
312124
+ }
312125
+ return nodeToGroupMap;
312126
+ }, {});
312127
+ }
311910
312128
  function getNodeOrder(nodes, orderPath, graph) {
311911
312129
  const attributePathArray = orderPath.split(".");
311912
312130
  return nodes.reduce((groupAccumulator, node2) => {
@@ -311924,7 +312142,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
311924
312142
  if (!Array.isArray(tiers)) {
311925
312143
  const { group, rank } = tiers;
311926
312144
  const nodes = graph.nodes();
311927
- const tieredNodes = getNodeGroups(nodes, group, graph);
312145
+ const tieredNodes = getGroupToNodesMap(nodes, group, graph);
311928
312146
  if (rank) {
311929
312147
  const missingGroups = [];
311930
312148
  tiersArray = rank.map((key) => {
@@ -312453,7 +312671,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
312453
312671
  function LegendList({ listItems }) {
312454
312672
  return jsxRuntime.exports.jsx(Ul, { children: listItems.map((_a3) => {
312455
312673
  var { label } = _a3, props = __rest$5(_a3, ["label"]);
312456
- return jsxRuntime.exports.jsxs(Li, { children: [jsxRuntime.exports.jsx(LegendSymbol, Object.assign({}, props)), jsxRuntime.exports.jsx(LegendText, { children: label })] }, label);
312674
+ return jsxRuntime.exports.jsxs(Li, { children: [jsxRuntime.exports.jsx(LegendSymbol, Object.assign({}, props)), jsxRuntime.exports.jsx(LegendText, { children: label })] }, `${label}-${props.type}`);
312457
312675
  }) });
312458
312676
  }
312459
312677
  const LegendWrapper = styled__default.default.div`
@@ -340194,7 +340412,7 @@ ${e3}`);
340194
340412
  }
340195
340413
  class GraphLayoutBuilder {
340196
340414
  constructor() {
340197
- this._nodeSize = 64;
340415
+ this._nodeSize = DEFAULT_NODE_SIZE$1;
340198
340416
  this._nodeFontSize = 16;
340199
340417
  }
340200
340418
  nodeSize(size2) {
@@ -347421,22 +347639,22 @@ ${e3}`);
347421
347639
  }
347422
347640
  const nodes = graph.mapNodes((id2, attributes2) => {
347423
347641
  const parentIds = graph.inboundNeighbors(id2);
347424
- let nodeGroup = "latent";
347642
+ let nodeType = "latent";
347425
347643
  let nodeOrder;
347426
347644
  let nodeRank;
347427
347645
  if (tiers) {
347428
347646
  const nodeData = nodeTiersMap.get(id2);
347429
- nodeGroup = nodeData === null || nodeData === void 0 ? void 0 : nodeData.group;
347647
+ nodeType = nodeData === null || nodeData === void 0 ? void 0 : nodeData.group;
347430
347648
  nodeOrder = nodeData === null || nodeData === void 0 ? void 0 : nodeData.order;
347431
347649
  nodeRank = nodeData === null || nodeData === void 0 ? void 0 : nodeData.rank;
347432
347650
  }
347433
- return Object.assign(Object.assign({}, attributes2), { group: nodeGroup, ord: nodeOrder, parentIds, rank: nodeRank });
347651
+ return Object.assign(Object.assign({}, attributes2), { group: nodeType, ord: nodeOrder, parentIds, rank: nodeRank });
347434
347652
  });
347435
347653
  const stratify = ai();
347436
347654
  return stratify(nodes);
347437
347655
  }
347438
347656
  function getD3Data(graph) {
347439
- const nodes = graph.reduceNodes((acc, id2, attrs2) => Object.assign(Object.assign({}, acc), { [id2]: Object.assign(Object.assign({}, attrs2), { group: getNodeGroup(graph, id2, attrs2["meta.rendering_properties.latent"]) }) }), {});
347657
+ const nodes = graph.reduceNodes((acc, id2, attrs2) => Object.assign(Object.assign({}, acc), { [id2]: Object.assign(Object.assign({}, attrs2), { category: getNodeCategory(graph, id2, attrs2["meta.rendering_properties.latent"]) }) }), {});
347440
347658
  const edges = graph.mapEdges((edgeKey, attrs2, source, target) => {
347441
347659
  return Object.assign(Object.assign({}, attrs2), { source: nodes[source], target: nodes[target] });
347442
347660
  });
@@ -347581,6 +347799,7 @@ ${e3}`);
347581
347799
  this._linkForce = 5;
347582
347800
  this._warmupTicks = 100;
347583
347801
  this._tierSeparation = 300;
347802
+ this._groupRepelStrength = 2e3;
347584
347803
  this.orientation = "horizontal";
347585
347804
  }
347586
347805
  collisionForce(force) {
@@ -347603,6 +347822,10 @@ ${e3}`);
347603
347822
  this._tierSeparation = separation;
347604
347823
  return this;
347605
347824
  }
347825
+ groupRepelStrength(force) {
347826
+ this._groupRepelStrength = force;
347827
+ return this;
347828
+ }
347606
347829
  build() {
347607
347830
  return new SpringLayout(this);
347608
347831
  }
@@ -347615,12 +347838,12 @@ ${e3}`);
347615
347838
  function force(alpha) {
347616
347839
  sortedNodesOrderArray.forEach((nodeName, index2) => {
347617
347840
  const targetPosition = index2 * nodeSeparation;
347618
- const targettedNode = nodesMap.get(nodeName);
347619
- if (targettedNode) {
347841
+ const targetedNode = nodesMap.get(nodeName);
347842
+ if (targetedNode) {
347620
347843
  if (orientation === "horizontal") {
347621
- targettedNode.vy += (targetPosition - targettedNode.y) * alpha;
347844
+ targetedNode.vy += (targetPosition - targetedNode.y) * alpha;
347622
347845
  } else {
347623
- targettedNode.vx += (targetPosition - targettedNode.x) * alpha;
347846
+ targetedNode.vx += (targetPosition - targetedNode.x) * alpha;
347624
347847
  }
347625
347848
  }
347626
347849
  });
@@ -347645,12 +347868,12 @@ ${e3}`);
347645
347868
  tiersArray.forEach((tier, index2) => {
347646
347869
  const targetPosition = index2 * tiersSeparation;
347647
347870
  tier.forEach((nodeName) => {
347648
- const targettedNode = nodesMapping.get(nodeName);
347649
- if (targettedNode) {
347871
+ const targetedNode = nodesMapping.get(nodeName);
347872
+ if (targetedNode) {
347650
347873
  if (orientation === "horizontal") {
347651
- targettedNode.x = targetPosition + (targettedNode.x - targetPosition) * alpha;
347874
+ targetedNode.x = targetPosition + (targetedNode.x - targetPosition) * alpha;
347652
347875
  } else {
347653
- targettedNode.y = targetPosition + (targettedNode.y - targetPosition) * alpha;
347876
+ targetedNode.y = targetPosition + (targetedNode.y - targetPosition) * alpha;
347654
347877
  }
347655
347878
  }
347656
347879
  });
@@ -347660,6 +347883,33 @@ ${e3}`);
347660
347883
  }
347661
347884
  simulation2.force("layer", forceLayer());
347662
347885
  }
347886
+ function createGroupEdges(nodeList) {
347887
+ const edges = [];
347888
+ if (nodeList.length > 1) {
347889
+ for (let i2 = 0; i2 < nodeList.length; i2++) {
347890
+ for (let j2 = i2 + 1; j2 < nodeList.length; j2++) {
347891
+ edges.push({
347892
+ source: nodeList[i2],
347893
+ target: nodeList[j2],
347894
+ originalMeta: {},
347895
+ edge_type: EdgeType.UNDIRECTED_EDGE
347896
+ });
347897
+ }
347898
+ }
347899
+ }
347900
+ return edges;
347901
+ }
347902
+ function createEdgesWithinAllGroups(group, graph, nodes) {
347903
+ const groupsToNodes = getGroupToNodesMap(graph.nodes(), group, graph);
347904
+ const edges = [];
347905
+ Object.keys(groupsToNodes).forEach((groupName) => {
347906
+ const nodeStringsList = groupsToNodes[groupName];
347907
+ const nodeList = nodeStringsList.map((nodeString) => nodes.find((node2) => node2.id === nodeString));
347908
+ const groupEdges = createGroupEdges(nodeList);
347909
+ edges.push(...groupEdges);
347910
+ });
347911
+ return edges;
347912
+ }
347663
347913
  class SpringLayout extends GraphLayout {
347664
347914
  constructor(builder) {
347665
347915
  super(builder);
@@ -347668,12 +347918,56 @@ ${e3}`);
347668
347918
  this.gravity = builder._gravity;
347669
347919
  this.warmupTicks = builder._warmupTicks;
347670
347920
  this.tierSeparation = builder._tierSeparation;
347921
+ this.groupRepelStrength = builder._groupRepelStrength;
347671
347922
  this.orientation = builder.orientation;
347672
347923
  this.tiers = builder.tiers;
347924
+ this.group = builder.group;
347673
347925
  }
347674
347926
  applyLayout(graph, forceUpdate) {
347675
- let [edges, nodes] = getD3Data(graph);
347676
- const simulation$1 = simulation(nodes).force("links", link(edges).id((d2) => d2.id).distance(() => this.nodeSize * this.linkForce)).force("charge", manyBody().strength(this.gravity)).force("collide", collide(this.nodeSize * this.collisionForce)).force("center", center()).stop();
347927
+ const [edges, nodes] = getD3Data(graph);
347928
+ const { group, groupRepelStrength } = this;
347929
+ let simulation$1;
347930
+ if (group) {
347931
+ let clusterRepelForce = function(alpha) {
347932
+ for (let i2 = 0; i2 < groupKeys.length; i2++) {
347933
+ const groupA = groupKeys[i2];
347934
+ const nodeA = firstNodes[groupA];
347935
+ const groupASize = groupsToNodes[groupA].length;
347936
+ for (let j2 = i2 + 1; j2 < groupKeys.length; j2++) {
347937
+ const groupB = groupKeys[j2];
347938
+ const nodeB = firstNodes[groupB];
347939
+ const groupBSize = groupsToNodes[groupB].length;
347940
+ const dx = nodeA.x - nodeB.x;
347941
+ const dy = nodeA.y - nodeB.y;
347942
+ const distance = Math.sqrt(dx * dx + dy * dy);
347943
+ if (distance > 3e3) {
347944
+ continue;
347945
+ }
347946
+ const cappedDistance = Math.max(distance, 1);
347947
+ const strengthFactor = groupASize * groupBSize;
347948
+ const strength = groupRepelStrength * strengthFactor * alpha / (cappedDistance * cappedDistance);
347949
+ if (strength < 0.01) {
347950
+ continue;
347951
+ }
347952
+ nodeA.vx += nodeA.x * strength;
347953
+ nodeA.vy += nodeA.y * strength;
347954
+ nodeB.vx -= nodeB.x * strength;
347955
+ nodeB.vy -= nodeB.y * strength;
347956
+ }
347957
+ }
347958
+ };
347959
+ const groupsToNodes = getGroupToNodesMap(graph.nodes(), group, graph);
347960
+ const groupKeys = Object.keys(groupsToNodes);
347961
+ const firstNodes = {};
347962
+ groupKeys.forEach((groupKey) => {
347963
+ const nodeId = groupsToNodes[groupKey][0];
347964
+ firstNodes[groupKey] = nodes.find((node2) => node2.id === nodeId);
347965
+ });
347966
+ const groupEdges = createEdgesWithinAllGroups(this.group, graph, nodes);
347967
+ simulation$1 = simulation(nodes).force("clusterRepel", clusterRepelForce).force("groupLinks", link(groupEdges).id((d2) => d2.id).distance(() => this.nodeSize * this.linkForce)).force("collide", collide(this.nodeSize * this.collisionForce)).force("center", center()).stop();
347968
+ } else {
347969
+ simulation$1 = simulation(nodes).force("links", link(edges).id((d2) => d2.id).distance(() => this.nodeSize * this.linkForce)).force("charge", manyBody().strength(this.gravity)).force("collide", collide(this.nodeSize * this.collisionForce)).force("center", center()).stop();
347970
+ }
347677
347971
  if (this.tiers) {
347678
347972
  applyTierForces(simulation$1, graph, nodes, this.tiers, this.tierSeparation, this.orientation);
347679
347973
  }
@@ -347683,7 +347977,6 @@ ${e3}`);
347683
347977
  forceUpdate(newNodes);
347684
347978
  }).restart();
347685
347979
  const onAddNode = debounce_1$1(() => {
347686
- [edges, nodes] = getD3Data(graph);
347687
347980
  simulation$1.nodes(nodes).force("links", link(edges).id((d2) => d2.id).distance(() => this.nodeSize * this.linkForce)).alpha(0.8).alphaTarget(0).restart();
347688
347981
  }, 100);
347689
347982
  return Promise.resolve({
@@ -347740,18 +348033,18 @@ ${e3}`);
347740
348033
  applyLayout(graph) {
347741
348034
  const [edges, nodes] = getD3Data(graph);
347742
348035
  const simulation$1 = simulation(nodes).alphaMin(1e-3).force("link", link(edges).id((d2) => d2.id).distance(() => this.nodeSize * 3).strength(this.targetLocation === "center" ? 0.7 : 0.1)).force("charge", manyBody().strength(this.targetLocation === "center" ? -1e3 : -2e3)).force("y", y$3().y((node2) => {
347743
- if (node2.group === "target") {
348036
+ if (node2.category === "target") {
347744
348037
  return this.nodeSize * 10;
347745
348038
  }
347746
- if (node2.group === "latent") {
348039
+ if (node2.category === "latent") {
347747
348040
  return this.nodeSize * 2;
347748
348041
  }
347749
348042
  return this.nodeSize * 6;
347750
348043
  }).strength(this.targetLocation === "center" ? 0 : 0.3)).force("collide", collide(this.nodeSize + 10)).force("radial", radial((node2) => {
347751
- if (node2.group === "target") {
348044
+ if (node2.category === "target") {
347752
348045
  return 0;
347753
348046
  }
347754
- if (node2.group === "latent") {
348047
+ if (node2.category === "latent") {
347755
348048
  return this.nodeSize * 8;
347756
348049
  }
347757
348050
  return this.nodeSize * 4;
@@ -347759,7 +348052,7 @@ ${e3}`);
347759
348052
  if (this.targetLocation === "center") {
347760
348053
  return 1;
347761
348054
  }
347762
- return node2.group === "other" ? 0.7 : 1;
348055
+ return node2.category === "other" ? 0.7 : 1;
347763
348056
  })).stop();
347764
348057
  if (this.tiers) {
347765
348058
  applyTierForces(simulation$1, graph, nodes, this.tiers, this.tierSeparation, this.orientation);
@@ -383457,6 +383750,20 @@ ${e3}`);
383457
383750
  relativePlacementConstraint: getRelativeTieredArrayPlacement(tiersArray, orientation, tierSeparation, nodesOrder)
383458
383751
  };
383459
383752
  }
383753
+ function assignParents(elements, relationships) {
383754
+ const elementLookup = {};
383755
+ elements.forEach((element2) => {
383756
+ elementLookup[element2.data.id] = element2;
383757
+ });
383758
+ for (const [parent, children2] of Object.entries(relationships)) {
383759
+ children2.forEach((childId) => {
383760
+ const node2 = elementLookup[childId];
383761
+ if (node2) {
383762
+ node2.data.parent = parent;
383763
+ }
383764
+ });
383765
+ }
383766
+ }
383460
383767
  class FcoseLayout extends GraphLayout {
383461
383768
  constructor(builder) {
383462
383769
  super(builder);
@@ -383472,6 +383779,7 @@ ${e3}`);
383472
383779
  this.tierSeparation = builder._tierSeparation;
383473
383780
  this.orientation = builder.orientation;
383474
383781
  this.tiers = builder.tiers;
383782
+ this.group = builder.group;
383475
383783
  }
383476
383784
  get requiresPosition() {
383477
383785
  return false;
@@ -383496,6 +383804,16 @@ ${e3}`);
383496
383804
  group: "edges"
383497
383805
  }))
383498
383806
  ];
383807
+ if (this.group) {
383808
+ const groupedNodes = getGroupToNodesMap(graph.nodes(), this.group, graph);
383809
+ Object.keys(groupedNodes).forEach((groupLabel) => {
383810
+ elements.push({
383811
+ data: { id: groupLabel, height: size2, width: size2 },
383812
+ group: "nodes"
383813
+ });
383814
+ });
383815
+ assignParents(elements, groupedNodes);
383816
+ }
383499
383817
  cytoscape$1({
383500
383818
  elements,
383501
383819
  headless: true,
@@ -386268,6 +386586,9 @@ if (vType < 0.5) {
386268
386586
  function isGraphLayoutWithTiers(layout2) {
386269
386587
  return layout2.tiers !== void 0;
386270
386588
  }
386589
+ function isGraphLayoutWithGroups(layout2) {
386590
+ return layout2.group !== void 0;
386591
+ }
386271
386592
  const DOT_DISTANCE = 20;
386272
386593
  const SCALE = 0.5;
386273
386594
  class Background extends EventEmitter$1 {
@@ -388956,12 +389277,75 @@ void main(void){
388956
389277
  }
388957
389278
  return gfx;
388958
389279
  }
389280
+ function calculateSourceBoundPosition(centerX, centerY, rotation2, width) {
389281
+ const halfSize = width / 2;
389282
+ let x2;
389283
+ let y2;
389284
+ if (rotation2 >= 0 && rotation2 < Math.PI / 4) {
389285
+ x2 = centerX + halfSize;
389286
+ y2 = centerY + Math.tan(rotation2) * halfSize;
389287
+ } else if (rotation2 >= Math.PI / 4 && rotation2 < Math.PI / 2) {
389288
+ x2 = centerX + Math.tan(Math.PI / 2 - rotation2) * halfSize;
389289
+ y2 = centerY + halfSize;
389290
+ } else if (rotation2 >= Math.PI / 2 && rotation2 < 3 * Math.PI / 4) {
389291
+ x2 = centerX - Math.tan(rotation2 - Math.PI / 2) * halfSize;
389292
+ y2 = centerY + halfSize;
389293
+ } else if (rotation2 >= Math.PI / 4 && rotation2 < 3 * Math.PI) {
389294
+ x2 = centerX - halfSize;
389295
+ y2 = centerY + Math.tan(Math.PI - rotation2) * halfSize;
389296
+ } else if (rotation2 <= 0 && rotation2 > -Math.PI / 4) {
389297
+ y2 = centerY + Math.tan(Math.PI + rotation2) * halfSize;
389298
+ x2 = centerX + halfSize;
389299
+ } else if (rotation2 <= -Math.PI / 4 && rotation2 > -Math.PI / 2) {
389300
+ x2 = centerX - Math.tan(-rotation2 - Math.PI / 2) * halfSize;
389301
+ y2 = centerY - halfSize;
389302
+ } else if (rotation2 <= -Math.PI / 2 && rotation2 > -3 * Math.PI / 4) {
389303
+ x2 = centerX + Math.tan(Math.PI / 2 + rotation2) * halfSize;
389304
+ y2 = centerY - halfSize;
389305
+ } else {
389306
+ x2 = centerX - halfSize;
389307
+ y2 = centerY + Math.tan(-rotation2) * halfSize;
389308
+ }
389309
+ return { x: x2, y: y2 };
389310
+ }
389311
+ function calculateTargetBoundPosition(centerX, centerY, rotation2, width) {
389312
+ const halfSize = width / 2;
389313
+ let x2;
389314
+ let y2;
389315
+ if (rotation2 >= 0 && rotation2 < Math.PI / 4) {
389316
+ x2 = centerX - halfSize;
389317
+ y2 = centerY - Math.tan(rotation2) * halfSize;
389318
+ } else if (rotation2 >= Math.PI / 4 && rotation2 < Math.PI / 2) {
389319
+ x2 = centerX - Math.tan(Math.PI / 2 - rotation2) * halfSize;
389320
+ y2 = centerY - halfSize;
389321
+ } else if (rotation2 >= Math.PI / 2 && rotation2 < 3 * Math.PI / 4) {
389322
+ x2 = centerX + Math.tan(rotation2 - Math.PI / 2) * halfSize;
389323
+ y2 = centerY - halfSize;
389324
+ } else if (rotation2 >= Math.PI / 4 && rotation2 < 3 * Math.PI) {
389325
+ x2 = centerX + halfSize;
389326
+ y2 = centerY - Math.tan(Math.PI - rotation2) * halfSize;
389327
+ } else if (rotation2 <= 0 && rotation2 > -Math.PI / 4) {
389328
+ x2 = centerX - halfSize;
389329
+ y2 = centerY - Math.tan(Math.PI + rotation2) * halfSize;
389330
+ } else if (rotation2 <= -Math.PI / 4 && rotation2 > -Math.PI / 2) {
389331
+ x2 = centerX + Math.tan(-rotation2 - Math.PI / 2) * halfSize;
389332
+ y2 = centerY + halfSize;
389333
+ } else if (rotation2 <= -Math.PI / 2 && rotation2 > -3 * Math.PI / 4) {
389334
+ x2 = centerX - Math.tan(Math.PI / 2 + rotation2) * halfSize;
389335
+ y2 = centerY + halfSize;
389336
+ } else {
389337
+ x2 = centerX + halfSize;
389338
+ y2 = centerY - Math.tan(-rotation2) * halfSize;
389339
+ }
389340
+ return { x: x2, y: y2 };
389341
+ }
388959
389342
  const EDGE_LINE_SPRITE = "EDGE_LINE_SPRITE";
388960
389343
  const EDGE_LINE_GFX = "EDGE_LINE_GFX";
388961
389344
  const EDGE_TOP_SYMBOL = "EDGE_TOP_SYMBOL";
388962
389345
  const EDGE_CENTER_SYMBOL = "EDGE_CENTER_SYMBOL";
388963
389346
  const EDGE_BOTTOM_SYMBOL = "EDGE_BOTTOM_SYMBOL";
388964
389347
  const EDGE_STRENGTH_SYMBOL = "EDGE_STRENGTH_SYMBOL";
389348
+ const EDGE_NUMBER_SYMBOL = "EDGE_NUMBER_SYMBOL";
388965
389349
  const EDGE_OFFSET = 10;
388966
389350
  const LOCAL_MULTIPLIER = 1.5;
388967
389351
  class EdgeObject extends EventEmitter$1 {
@@ -389016,6 +389400,10 @@ void main(void){
389016
389400
  edgeStrengthSymbol.name = EDGE_STRENGTH_SYMBOL;
389017
389401
  edgeStrengthSymbol.anchor.set(0.5, 1);
389018
389402
  edgeSymbolsGfx.addChild(edgeStrengthSymbol);
389403
+ const edgeSourceNumberSymbol = new Sprite();
389404
+ edgeSourceNumberSymbol.name = EDGE_NUMBER_SYMBOL;
389405
+ edgeSourceNumberSymbol.anchor.set(0.5);
389406
+ edgeSymbolsGfx.addChild(edgeSourceNumberSymbol);
389019
389407
  return edgeSymbolsGfx;
389020
389408
  }
389021
389409
  static updateEdgeStyle(edgeGfx, edgeStyle, textureCache) {
@@ -389126,6 +389514,24 @@ void main(void){
389126
389514
  edgeStrengthSymbol.position.y = edgeTopSymbol.position.y - 5;
389127
389515
  [edgeStrengthSymbol.tint] = colorToPixi(edgeStyle.color);
389128
389516
  edgeStrengthSymbol.alpha = 1;
389517
+ const edgeNumberSymbol = edgeSymbolsGfx.getChildByName(EDGE_NUMBER_SYMBOL);
389518
+ const numberSymbolTexture = textureCache.get(createKey(EDGE_NUMBER_SYMBOL, edgeStyle.collapsedEdgesCount), () => {
389519
+ if (edgeStyle.collapsedEdgesCount === void 0) {
389520
+ return new Graphics();
389521
+ }
389522
+ const textStyle = new TextStyle({
389523
+ fontFamily: "Manrope",
389524
+ fontSize: 18,
389525
+ fill: colorToPixi(edgeStyle.color)
389526
+ });
389527
+ const text2 = new Text(edgeStyle.collapsedEdgesCount, textStyle);
389528
+ return text2;
389529
+ });
389530
+ edgeNumberSymbol.texture = numberSymbolTexture;
389531
+ edgeNumberSymbol.position.y = edgeTopSymbol.position.y - 30;
389532
+ edgeNumberSymbol.rotation = edgeGfx.rotation <= Math.PI / 2 && edgeGfx.rotation > 0 || edgeGfx.rotation >= -3 * Math.PI / 2 && edgeGfx.rotation < -Math.PI ? -Math.PI / 2 : Math.PI / 2;
389533
+ [edgeStrengthSymbol.tint] = colorToPixi(edgeStyle.color);
389534
+ edgeNumberSymbol.alpha = 1;
389129
389535
  if (edgeStyle.isEdgeSelected && !edgeStyle.state.selected && !edgeStyle.state.hover) {
389130
389536
  edgeCenterSymbol.alpha = 0.3;
389131
389537
  edgeBottomSymbol.alpha = 0.3;
@@ -389160,28 +389566,38 @@ void main(void){
389160
389566
  edgeBottomSymbol.visible = !hasPoints && edgeBottomSymbol.visible && zoomState.symbol;
389161
389567
  edgeStrengthSymbol.visible = !hasPoints && edgeStrengthSymbol.visible && zoomState.symbol;
389162
389568
  }
389163
- updatePosition(edgeStyle, sourceNodePosition, targetNodePosition, sourceSize, targetSize, viewport2, textureCache) {
389569
+ updatePosition(edgeStyle, sourceNodePosition, targetNodePosition, sourceSize, targetSize, viewport2, textureCache, isSourceSquare, isTargetSquare) {
389164
389570
  var _a3;
389165
- const rotation2 = -Math.atan2(targetNodePosition.x - sourceNodePosition.x, targetNodePosition.y - sourceNodePosition.y);
389166
- const targetRadius = (targetSize - BORDER_PADDING) / 2;
389167
- const targetBoundPosition = {
389168
- x: targetNodePosition.x + Math.sin(rotation2) * targetRadius,
389169
- y: targetNodePosition.y - Math.cos(rotation2) * targetRadius
389170
- };
389571
+ const rotation2 = Math.atan2(targetNodePosition.y - sourceNodePosition.y, targetNodePosition.x - sourceNodePosition.x);
389171
389572
  const sourceRadius = (sourceSize - BORDER_PADDING) / 2;
389172
- const sourceBoundPosition = {
389173
- x: sourceNodePosition.x - Math.sin(rotation2) * sourceRadius,
389174
- y: sourceNodePosition.y + Math.cos(rotation2) * sourceRadius
389175
- };
389573
+ const targetRadius = (targetSize - BORDER_PADDING) / 2;
389574
+ let targetBoundPosition;
389575
+ let sourceBoundPosition;
389576
+ if (isTargetSquare) {
389577
+ targetBoundPosition = calculateTargetBoundPosition(targetNodePosition.x, targetNodePosition.y, rotation2, targetSize - BORDER_PADDING);
389578
+ } else {
389579
+ targetBoundPosition = {
389580
+ x: targetNodePosition.x - Math.cos(rotation2) * targetRadius,
389581
+ y: targetNodePosition.y - Math.sin(rotation2) * targetRadius
389582
+ };
389583
+ }
389584
+ if (isSourceSquare) {
389585
+ sourceBoundPosition = calculateSourceBoundPosition(sourceNodePosition.x, sourceNodePosition.y, rotation2, sourceSize - BORDER_PADDING);
389586
+ } else {
389587
+ sourceBoundPosition = {
389588
+ x: sourceNodePosition.x + Math.cos(rotation2) * sourceRadius,
389589
+ y: sourceNodePosition.y + Math.sin(rotation2) * sourceRadius
389590
+ };
389591
+ }
389176
389592
  const position2 = {
389177
389593
  x: (sourceBoundPosition.x + targetBoundPosition.x) / 2,
389178
389594
  y: (sourceBoundPosition.y + targetBoundPosition.y) / 2
389179
389595
  };
389180
389596
  const length = Math.hypot(targetBoundPosition.x - sourceBoundPosition.x, targetBoundPosition.y - sourceBoundPosition.y);
389181
389597
  this.edgeGfx.position.copyFrom(position2);
389182
- this.edgeGfx.rotation = rotation2;
389598
+ this.edgeGfx.rotation = rotation2 - Math.PI / 2;
389183
389599
  this.edgeSymbolsGfx.position.copyFrom(position2);
389184
- this.edgeSymbolsGfx.rotation = rotation2;
389600
+ this.edgeSymbolsGfx.rotation = rotation2 - Math.PI / 2;
389185
389601
  (_a3 = edgeStyle.color) !== null && _a3 !== void 0 ? _a3 : edgeStyle.color = edgeStyle.theme.colors.grey5;
389186
389602
  if (edgeStyle.points) {
389187
389603
  this.edgeGfx.scale.x = 1;
@@ -389309,6 +389725,89 @@ void main(void){
389309
389725
  thickness: 4
389310
389726
  }
389311
389727
  ];
389728
+ const GROUP_RECTANGLE = "GROUP_RECTANGLE";
389729
+ const GROUP_BORDER = "GROUP_BORDER";
389730
+ class GroupContainerObject extends EventEmitter$1 {
389731
+ constructor() {
389732
+ super();
389733
+ this.state = {
389734
+ hover: false
389735
+ };
389736
+ this.groupContainerGfx = this.createGroupContainer();
389737
+ }
389738
+ createGroupContainer() {
389739
+ const groupContainerGfx = new Container();
389740
+ groupContainerGfx.interactive = true;
389741
+ groupContainerGfx.cursor = "pointer";
389742
+ groupContainerGfx.hitArea = new Rectangle(0, 0);
389743
+ MOUSE_EVENTS.forEach((eventName) => {
389744
+ groupContainerGfx.addEventListener(eventName, (event2) => this.emit(eventName, event2));
389745
+ });
389746
+ const containerRectangle = new Sprite();
389747
+ containerRectangle.name = GROUP_RECTANGLE;
389748
+ containerRectangle.anchor.set(0.5);
389749
+ groupContainerGfx.addChild(containerRectangle);
389750
+ const containerBorder = new Sprite();
389751
+ containerBorder.name = GROUP_BORDER;
389752
+ containerBorder.anchor.set(0.5);
389753
+ groupContainerGfx.addChild(containerBorder);
389754
+ return groupContainerGfx;
389755
+ }
389756
+ static updateContainerStyle(groupContainerGfx, nodes, textureCache, theme2) {
389757
+ let minX = Infinity;
389758
+ let maxX = -Infinity;
389759
+ let minY = Infinity;
389760
+ let maxY = -Infinity;
389761
+ nodes.forEach((node2) => {
389762
+ var _a3;
389763
+ let radius2 = (_a3 = node2["meta.rendering_properties.size"]) !== null && _a3 !== void 0 ? _a3 : DEFAULT_NODE_SIZE$1 * TARGET_NODE_MULTIPLIER;
389764
+ radius2 += 20;
389765
+ minX = Math.min(minX, node2.x - radius2);
389766
+ maxX = Math.max(maxX, node2.x + radius2);
389767
+ minY = Math.min(minY, node2.y - radius2);
389768
+ maxY = Math.max(maxY, node2.y + radius2);
389769
+ });
389770
+ const height = maxY - minY;
389771
+ const width = maxX - minX;
389772
+ groupContainerGfx.hitArea.x = -width / 2;
389773
+ groupContainerGfx.hitArea.y = -height / 2;
389774
+ groupContainerGfx.hitArea.width = width;
389775
+ groupContainerGfx.hitArea.height = height;
389776
+ const rectangleTexture = textureCache.get(createKey(GROUP_RECTANGLE, minX, maxX, minY, maxY), () => {
389777
+ const graphics = new Graphics();
389778
+ graphics.lineStyle(2, theme2.colors.primary.replace("#", "0x"), 0.5);
389779
+ graphics.beginFill(theme2.colors.blue2.replace("#", "0x"), 1);
389780
+ graphics.drawRoundedRect(minX, minY, width, height, 8);
389781
+ graphics.endFill();
389782
+ return graphics;
389783
+ });
389784
+ const rectangle = groupContainerGfx.getChildByName(GROUP_RECTANGLE);
389785
+ rectangle.texture = rectangleTexture;
389786
+ [rectangle.tint, rectangle.alpha] = colorToPixi(theme2.colors.blue2);
389787
+ }
389788
+ updatePosition(position2) {
389789
+ this.groupContainerGfx.position.copyFrom(position2);
389790
+ }
389791
+ updateStyle(nodes, textureCache, theme2) {
389792
+ let minX = Infinity;
389793
+ let maxX = -Infinity;
389794
+ let minY = Infinity;
389795
+ let maxY = -Infinity;
389796
+ nodes.forEach((node2) => {
389797
+ var _a3;
389798
+ let radius2 = (_a3 = node2["meta.rendering_properties.size"]) !== null && _a3 !== void 0 ? _a3 : DEFAULT_NODE_SIZE$1 * TARGET_NODE_MULTIPLIER;
389799
+ radius2 += 20;
389800
+ minX = Math.min(minX, node2.x - radius2);
389801
+ maxX = Math.max(maxX, node2.x + radius2);
389802
+ minY = Math.min(minY, node2.y - radius2);
389803
+ maxY = Math.max(maxY, node2.y + radius2);
389804
+ });
389805
+ const centerX = minX + (maxX - minX) / 2;
389806
+ const centerY = minY + (maxY - minY) / 2;
389807
+ GroupContainerObject.updateContainerStyle(this.groupContainerGfx, nodes, textureCache, theme2);
389808
+ this.groupContainerGfx.position.copyFrom({ x: centerX, y: centerY });
389809
+ }
389810
+ }
389312
389811
  const SHADOWS = {
389313
389812
  dark: {
389314
389813
  shadowHover: "rgba(255, 255, 255, 0.3)",
@@ -389383,8 +389882,8 @@ ${letters.join("\n")}`;
389383
389882
  }
389384
389883
  return finalText.join(" ");
389385
389884
  }
389386
- function getNodeColor(group, theme2) {
389387
- switch (group) {
389885
+ function getNodeColor(category, theme2) {
389886
+ switch (category) {
389388
389887
  case "target":
389389
389888
  return [theme2.colors.secondary, theme2.colors.blue1];
389390
389889
  case "latent":
@@ -389393,13 +389892,15 @@ ${letters.join("\n")}`;
389393
389892
  return [theme2.colors.blue4, theme2.colors.text];
389394
389893
  }
389395
389894
  }
389396
- function getNodeSize(size2, group) {
389397
- const sizeMultiplier = group === "target" ? 1.25 : 1;
389895
+ function getNodeSize(size2, category) {
389896
+ const sizeMultiplier = category === "target" ? TARGET_NODE_MULTIPLIER : 1;
389398
389897
  return size2 * sizeMultiplier;
389399
389898
  }
389400
389899
  const NODE_CIRCLE = "NODE_CIRCLE";
389401
389900
  const NODE_BORDER = "NODE_BORDER";
389402
389901
  const NODE_LABEL = "NODE_LABEL";
389902
+ const NODE_SQUARE = "NODE_SQUARE";
389903
+ const NODE_SQUARE_BORDER = "NODE_SQUARE_BORDER";
389403
389904
  class NodeObject extends EventEmitter$1 {
389404
389905
  constructor() {
389405
389906
  super();
@@ -389424,10 +389925,18 @@ ${letters.join("\n")}`;
389424
389925
  nodeCircle.name = NODE_CIRCLE;
389425
389926
  nodeCircle.anchor.set(0.5);
389426
389927
  nodeGfx.addChild(nodeCircle);
389928
+ const nodeSquare = new Sprite();
389929
+ nodeSquare.name = NODE_SQUARE;
389930
+ nodeSquare.anchor.set(0.5);
389931
+ nodeGfx.addChild(nodeSquare);
389427
389932
  const nodeBorder = new Sprite();
389428
389933
  nodeBorder.name = NODE_BORDER;
389429
389934
  nodeBorder.anchor.set(0.5);
389430
389935
  nodeGfx.addChild(nodeBorder);
389936
+ const nodeSquareBorder = new Sprite();
389937
+ nodeSquareBorder.name = NODE_SQUARE_BORDER;
389938
+ nodeSquareBorder.anchor.set(0.5);
389939
+ nodeGfx.addChild(nodeSquareBorder);
389431
389940
  return nodeGfx;
389432
389941
  }
389433
389942
  createNodeLabel() {
@@ -389451,22 +389960,32 @@ ${letters.join("\n")}`;
389451
389960
  nodeGfx.filters = [new F({ offset: { x: 0, y: 0 } })];
389452
389961
  }
389453
389962
  const dropShadow = nodeGfx.filters[0];
389454
- const circleTexture = textureCache.get(createKey(NODE_CIRCLE, nodeStyle.size), () => {
389963
+ const nodeTextureKey = nodeStyle.isGroupNode ? NODE_SQUARE : NODE_CIRCLE;
389964
+ const nodeBorderTextureKey = nodeStyle.isGroupNode ? NODE_SQUARE_BORDER : NODE_BORDER;
389965
+ const nodeTexture = textureCache.get(createKey(nodeTextureKey, nodeStyle.size), () => {
389455
389966
  const graphics = new SmoothGraphics();
389456
389967
  graphics.beginFill(16777215, 1, true);
389457
- graphics.drawCircle(nodeStyle.size, nodeStyle.size, nodeStyle.size);
389968
+ if (nodeStyle.isGroupNode) {
389969
+ graphics.drawRoundedRect(nodeStyle.size, nodeStyle.size, 2 * nodeStyle.size, 2 * nodeStyle.size, 8);
389970
+ } else {
389971
+ graphics.drawCircle(nodeStyle.size, nodeStyle.size, nodeStyle.size);
389972
+ }
389458
389973
  return graphics;
389459
389974
  });
389460
- const circle2 = nodeGfx.getChildByName(NODE_CIRCLE);
389461
- circle2.texture = circleTexture;
389462
- [circle2.tint, circle2.alpha] = colorToPixi(nodeStyle.color);
389463
- const borderTexture = textureCache.get(createKey(NODE_BORDER, outerRadius, borderWidth, nodeStyle.size), () => {
389975
+ const nodeBody = nodeGfx.getChildByName(nodeTextureKey);
389976
+ nodeBody.texture = nodeTexture;
389977
+ [nodeBody.tint, nodeBody.alpha] = colorToPixi(nodeStyle.color);
389978
+ const borderTexture = textureCache.get(createKey(nodeBorderTextureKey, outerRadius, borderWidth, nodeStyle.size), () => {
389464
389979
  const graphics = new SmoothGraphics();
389465
389980
  graphics.lineStyle({ color: 16777215, width: borderWidth });
389466
- graphics.drawCircle(outerRadius, outerRadius, nodeStyle.size);
389981
+ if (nodeStyle.isGroupNode) {
389982
+ graphics.drawRoundedRect(outerRadius, outerRadius, 2 * nodeStyle.size, 2 * nodeStyle.size, 8);
389983
+ } else {
389984
+ graphics.drawCircle(outerRadius, outerRadius, nodeStyle.size);
389985
+ }
389467
389986
  return graphics;
389468
389987
  }, BORDER_PADDING);
389469
- const border = nodeGfx.getChildByName(NODE_BORDER);
389988
+ const border = nodeGfx.getChildByName(nodeBorderTextureKey);
389470
389989
  border.texture = borderTexture;
389471
389990
  [border.tint, border.alpha] = colorToPixi(nodeStyle.highlight_color);
389472
389991
  const themeShadows = SHADOWS[nodeStyle.theme.themeType];
@@ -389483,13 +390002,13 @@ ${letters.join("\n")}`;
389483
390002
  dropShadow.blur = blur;
389484
390003
  dropShadow.padding = 10;
389485
390004
  if (nodeStyle.isEdgeSelected && !nodeStyle.state.selected && !nodeStyle.state.attachedEdgeSelected && !nodeStyle.state.hover && !nodeStyle.isSourceOfNewEdge) {
389486
- circle2.alpha = 0.3;
390005
+ nodeBody.alpha = 0.3;
389487
390006
  border.alpha = 0.3;
389488
390007
  }
389489
390008
  }
389490
390009
  static updateNodeLabelStyle(nodeLabelGfx, nodeStyle, textureCache) {
389491
- const labelTexture = textureCache.get(createKey(NODE_LABEL, nodeStyle.label, nodeStyle.size, nodeStyle.group), () => {
389492
- const nodeRadius = getNodeSize(nodeStyle.size, nodeStyle.group);
390010
+ const labelTexture = textureCache.get(createKey(NODE_LABEL, nodeStyle.label, nodeStyle.size, nodeStyle.category), () => {
390011
+ const nodeRadius = getNodeSize(nodeStyle.size, nodeStyle.category);
389493
390012
  const nodeSize2 = nodeRadius * 2;
389494
390013
  const maxSize = nodeSize2 - 10;
389495
390014
  const textStyle = getTextStyle(nodeStyle.label_size);
@@ -389519,7 +390038,7 @@ ${letters.join("\n")}`;
389519
390038
  }
389520
390039
  updateStyle(nodeStyle, textureCache) {
389521
390040
  var _a3, _b, _c;
389522
- const [defaultColor, defaultFontColor] = getNodeColor(nodeStyle.group, nodeStyle.theme);
390041
+ const [defaultColor, defaultFontColor] = getNodeColor(nodeStyle.category, nodeStyle.theme);
389523
390042
  (_a3 = nodeStyle.color) !== null && _a3 !== void 0 ? _a3 : nodeStyle.color = defaultColor;
389524
390043
  (_b = nodeStyle.highlight_color) !== null && _b !== void 0 ? _b : nodeStyle.highlight_color = nodeStyle.theme.colors.primary;
389525
390044
  (_c = nodeStyle.label_color) !== null && _c !== void 0 ? _c : nodeStyle.label_color = defaultFontColor;
@@ -389611,7 +390130,9 @@ ${letters.join("\n")}`;
389611
390130
  "nodeMouseover",
389612
390131
  "nodeMouseout",
389613
390132
  "edgeMouseout",
389614
- "edgeMouseover"
390133
+ "edgeMouseover",
390134
+ "groupMouseout",
390135
+ "groupMouseover"
389615
390136
  ];
389616
390137
  class Engine extends EventEmitter$1 {
389617
390138
  constructor(graph, layout2, editable2, editorMode, theme2, constraints, zoomThresholds, errorHandler, processEdgeStyle, requireFocusToZoom) {
@@ -389630,6 +390151,8 @@ ${letters.join("\n")}`;
389630
390151
  this.onAddNode = null;
389631
390152
  this.onAddEdge = null;
389632
390153
  this.onCleanup = null;
390154
+ this.groupContainerMap = /* @__PURE__ */ new Map();
390155
+ this.collapsedEdgesMap = /* @__PURE__ */ new Map();
389633
390156
  this.onGraphAttributesUpdatedBound = this.onGraphAttributesUpdated.bind(this);
389634
390157
  this.onGraphNodeAddedBound = this.onGraphNodeAdded.bind(this);
389635
390158
  this.onGraphEdgeAddedBound = this.onGraphEdgeAdded.bind(this);
@@ -389707,10 +390230,28 @@ ${letters.join("\n")}`;
389707
390230
  resetViewport() {
389708
390231
  const nodesX = this.graph.mapNodes((nodeKey) => this.graph.getNodeAttribute(nodeKey, "x"));
389709
390232
  const nodesY = this.graph.mapNodes((nodeKey) => this.graph.getNodeAttribute(nodeKey, "y"));
389710
- const minX = Math.min(...nodesX);
389711
- const maxX = Math.max(...nodesX);
389712
- const minY = Math.min(...nodesY);
389713
- const maxY = Math.max(...nodesY);
390233
+ let minX = Math.min(...nodesX);
390234
+ let maxX = Math.max(...nodesX);
390235
+ let minY = Math.min(...nodesY);
390236
+ let maxY = Math.max(...nodesY);
390237
+ if (isGraphLayoutWithGroups(this.layout)) {
390238
+ const nodes = this.graph.mapNodes((nodeKey) => this.graph.getNodeAttributes(nodeKey));
390239
+ const nodesInGroups = Object.values(getGroupToNodesMap(this.graph.nodes(), this.layout.group, this.graph)).flat();
390240
+ const updateBoundary = (node2, delta) => {
390241
+ if (nodesInGroups.includes(node2 === null || node2 === void 0 ? void 0 : node2.id)) {
390242
+ return delta;
390243
+ }
390244
+ return 0;
390245
+ };
390246
+ const nodeWithMinX = nodes.find((node2) => node2.x === minX);
390247
+ const nodeWithMaxX = nodes.find((node2) => node2.x === maxX);
390248
+ const nodeWithMinY = nodes.find((node2) => node2.y === minY);
390249
+ const nodeWithMaxY = nodes.find((node2) => node2.y === maxY);
390250
+ minX += updateBoundary(nodeWithMinX, -20);
390251
+ maxX += updateBoundary(nodeWithMaxX, 20);
390252
+ minY += updateBoundary(nodeWithMinY, -20);
390253
+ maxY += updateBoundary(nodeWithMaxY, 20);
390254
+ }
389714
390255
  const graphWidth = Math.abs(maxX - minX);
389715
390256
  const graphHeight = Math.abs(maxY - minY);
389716
390257
  const graphCenter = new Point$1(minX + graphWidth / 2, minY + graphHeight / 2);
@@ -389726,6 +390267,111 @@ ${letters.join("\n")}`;
389726
390267
  console.error("Error resetting viewport", err);
389727
390268
  }
389728
390269
  }
390270
+ collapseAllGroups() {
390271
+ if (isGraphLayoutWithGroups(this.layout)) {
390272
+ const layoutGroup = this.layout.group;
390273
+ const groupsObject = getGroupToNodesMap(this.graph.nodes(), layoutGroup, this.graph);
390274
+ const nodeToGroup = getNodeToGroupMap(this.graph.nodes(), layoutGroup, this.graph);
390275
+ const groupsArray = Object.keys(groupsObject);
390276
+ groupsArray.forEach((group) => {
390277
+ const groupNodeAttributes = {
390278
+ id: group,
390279
+ originalMeta: {},
390280
+ variable_type: "groupNode"
390281
+ };
390282
+ this.dropGroupContainer(group);
390283
+ if (!this.graph.hasNode(group)) {
390284
+ this.graph.addNode(group, groupNodeAttributes);
390285
+ } else {
390286
+ this.createNode(group, groupNodeAttributes);
390287
+ }
390288
+ });
390289
+ groupsArray.forEach((group) => {
390290
+ const collapsedEdges = [];
390291
+ this.graph.forEachEdge((edgeKey) => {
390292
+ var _a3, _b;
390293
+ const initialSource = this.graph.source(edgeKey);
390294
+ const initialTarget = this.graph.target(edgeKey);
390295
+ if (nodeToGroup[initialSource] === group || nodeToGroup[initialTarget] === group || groupsArray.includes(initialSource) || groupsArray.includes(initialTarget)) {
390296
+ const finalTarget = (_a3 = nodeToGroup[initialTarget]) !== null && _a3 !== void 0 ? _a3 : initialTarget;
390297
+ const finalSource = (_b = nodeToGroup[initialSource]) !== null && _b !== void 0 ? _b : initialSource;
390298
+ const edgeHasChanged = !(initialSource === finalSource && initialTarget === finalTarget);
390299
+ const edgeIsNotWithinTheGroup = finalSource !== finalTarget;
390300
+ const graphHasFinalEdge = this.graph.hasEdge(finalSource, finalTarget);
390301
+ const finalSourceAttributes = this.graph.getNodeAttributes(finalSource);
390302
+ const finalTargetAttributes = this.graph.getNodeAttributes(finalTarget);
390303
+ const currentEdgeAttributes = this.graph.getEdgeAttributes(edgeKey);
390304
+ let numberOfCollapsedEdges = graphHasFinalEdge ? this.graph.getEdgeAttributes(finalSource, finalTarget)["meta.rendering_properties.collapsedEdgesCount"] : 0;
390305
+ if (graphHasFinalEdge && edgeHasChanged && group === finalSource) {
390306
+ numberOfCollapsedEdges += 1;
390307
+ }
390308
+ const edgeAttributes = Object.assign(Object.assign({}, currentEdgeAttributes), { "meta.rendering_properties.collapsedEdgesCount": numberOfCollapsedEdges });
390309
+ if (initialSource !== finalSource || initialTarget !== finalTarget) {
390310
+ collapsedEdges.push(Object.assign({ id: edgeKey }, edgeAttributes));
390311
+ this.dropEdge(edgeKey);
390312
+ }
390313
+ if (edgeIsNotWithinTheGroup) {
390314
+ if (!graphHasFinalEdge && group === finalSource) {
390315
+ edgeAttributes["meta.rendering_properties.collapsedEdgesCount"] = 1;
390316
+ this.graph.addEdge(finalSource, finalTarget, edgeAttributes);
390317
+ } else if (!this.edgeMap.has(edgeKey) && !edgeHasChanged) {
390318
+ this.createEdge(edgeKey, edgeAttributes, finalSource, finalTarget, finalSourceAttributes, finalTargetAttributes);
390319
+ } else if (graphHasFinalEdge) {
390320
+ this.graph.setEdgeAttribute(finalSource, finalTarget, "meta.rendering_properties.collapsedEdgesCount", numberOfCollapsedEdges);
390321
+ }
390322
+ }
390323
+ }
390324
+ });
390325
+ this.collapsedEdgesMap.set(group, collapsedEdges);
390326
+ });
390327
+ Object.values(groupsObject).forEach((nodes) => {
390328
+ nodes.forEach((node2) => {
390329
+ if (this.nodeMap.has(node2)) {
390330
+ this.dropNode(node2);
390331
+ }
390332
+ });
390333
+ });
390334
+ this.requestRender();
390335
+ }
390336
+ }
390337
+ expandAllGroups() {
390338
+ if (this.graph.nodes().some((node2) => this.graph.getNodeAttribute(node2, "variable_type") === "groupNode")) {
390339
+ this.graph.forEachEdge((edgeKey) => {
390340
+ const source = this.graph.source(edgeKey);
390341
+ const target = this.graph.target(edgeKey);
390342
+ const isSourceGroupNode = this.graph.getNodeAttribute(source, "variable_type") === "groupNode";
390343
+ const isTargetGroupNode = this.graph.getNodeAttribute(target, "variable_type") === "groupNode";
390344
+ if (isSourceGroupNode || isTargetGroupNode) {
390345
+ this.dropEdge(edgeKey);
390346
+ this.graph.setEdgeAttribute(source, target, "meta.rendering_properties.collapsedEdgesCount", 0);
390347
+ }
390348
+ });
390349
+ this.graph.forEachNode((node2, attributes2) => {
390350
+ if (this.graph.getNodeAttribute(node2, "variable_type") !== "groupNode") {
390351
+ if (!this.nodeMap.has(node2)) {
390352
+ this.createNode(node2, attributes2);
390353
+ }
390354
+ } else {
390355
+ this.dropNode(node2);
390356
+ }
390357
+ });
390358
+ this.collapsedEdgesMap.forEach((edges) => {
390359
+ edges.forEach((edge) => {
390360
+ var _a3, _b;
390361
+ if (!this.edgeMap.has(edge.id)) {
390362
+ const source = (_a3 = edge.extras) === null || _a3 === void 0 ? void 0 : _a3.source.identifier;
390363
+ const target = (_b = edge.extras) === null || _b === void 0 ? void 0 : _b.destination.identifier;
390364
+ const sourceNodeAttributes = this.graph.getNodeAttributes(source);
390365
+ const targetNodeAttributes = this.graph.getNodeAttributes(target);
390366
+ this.createEdge(edge.id, edge, source, target, sourceNodeAttributes, targetNodeAttributes);
390367
+ }
390368
+ });
390369
+ });
390370
+ this.createGroupContainers();
390371
+ this.debouncedUpdateLayout();
390372
+ this.requestRender();
390373
+ }
390374
+ }
389729
390375
  searchNodes(ids) {
389730
390376
  const newNodes = ids.filter((newId2) => !this.searchResults.includes(newId2));
389731
390377
  const removedNodes = this.searchResults.filter((oldId) => !ids.includes(oldId));
@@ -389848,10 +390494,12 @@ ${letters.join("\n")}`;
389848
390494
  this.background.updatePosition(this.container);
389849
390495
  this.app.stage.addChild(this.background.sprite);
389850
390496
  this.app.stage.addChild(this.viewport);
390497
+ this.groupContainerLayer = new Container();
389851
390498
  this.edgeLayer = new Container();
389852
390499
  this.edgeSymbolsLayer = new Container();
389853
390500
  this.nodeLayer = new Container();
389854
390501
  this.nodeLabelLayer = new Container();
390502
+ this.viewport.addChild(this.groupContainerLayer);
389855
390503
  this.viewport.addChild(this.edgeLayer);
389856
390504
  this.viewport.addChild(this.edgeSymbolsLayer);
389857
390505
  this.viewport.addChild(this.nodeLayer);
@@ -389972,12 +390620,19 @@ ${letters.join("\n")}`;
389972
390620
  });
389973
390621
  edge.addListener("mouseup", (event2) => {
389974
390622
  if (this.mousedownEdgeKey === id2) {
390623
+ if (isGraphLayoutWithGroups(this.layout)) {
390624
+ const groupsObject = getGroupToNodesMap(this.graph.nodes(), this.layout.group, this.graph);
390625
+ if (Object.keys(groupsObject).includes(source) || Object.keys(groupsObject).includes(target)) {
390626
+ return;
390627
+ }
390628
+ }
389975
390629
  this.emit("edgeClick", event2, source, target);
389976
390630
  }
389977
390631
  });
389978
390632
  this.updateEdgeStyle(id2, attributes2, source, target, sourceAttributes, targetAttributes);
389979
390633
  }
389980
390634
  createGraph() {
390635
+ this.createGroupContainers();
389981
390636
  this.graph.forEachNode(this.createNode.bind(this));
389982
390637
  this.graph.forEachEdge(this.createEdge.bind(this));
389983
390638
  this.updateStrengthRange();
@@ -390018,6 +390673,12 @@ ${letters.join("\n")}`;
390018
390673
  const xOffset = Math.abs(this.nodeMousedownPosition.x - event2.global.x);
390019
390674
  const yOffset = Math.abs(this.nodeMousedownPosition.y - event2.global.y);
390020
390675
  if (xOffset <= 2 && yOffset <= 2) {
390676
+ if (isGraphLayoutWithGroups(this.layout)) {
390677
+ const groupsObject = getGroupToNodesMap(this.graph.nodes(), this.layout.group, this.graph);
390678
+ if (Object.keys(groupsObject).includes(id2)) {
390679
+ return;
390680
+ }
390681
+ }
390021
390682
  this.emit("nodeClick", event2, id2);
390022
390683
  }
390023
390684
  }
@@ -390032,6 +390693,39 @@ ${letters.join("\n")}`;
390032
390693
  });
390033
390694
  this.updateNodeStyle(id2, attributes2);
390034
390695
  }
390696
+ createGroupContainer(id2, nodes) {
390697
+ const groupContainer = new GroupContainerObject();
390698
+ this.groupContainerLayer.addChild(groupContainer.groupContainerGfx);
390699
+ this.groupContainerMap.set(id2, groupContainer);
390700
+ groupContainer.addListener("mouseover", (event2) => {
390701
+ this.hoverGroupContainer(id2, nodes);
390702
+ if (!this.mousedownNodeKey) {
390703
+ this.emit("groupMouseover", event2, id2);
390704
+ }
390705
+ });
390706
+ groupContainer.addListener("mouseout", (event2) => {
390707
+ const local = groupContainer.groupContainerGfx.toLocal(event2.global);
390708
+ const isInGroupContainer = groupContainer.groupContainerGfx.hitArea.contains(local.x, local.y);
390709
+ if (!isInGroupContainer) {
390710
+ this.unhoverGroupContainer(id2, nodes);
390711
+ this.emit("groupMouseout", event2, id2);
390712
+ }
390713
+ if (!this.editable && !this.isMovingNode && !this.isCreatingEdge) {
390714
+ this.mousedownNodeKey = null;
390715
+ }
390716
+ });
390717
+ this.updateGroupContainerStyle(id2, nodes);
390718
+ }
390719
+ createGroupContainers() {
390720
+ if (isGraphLayoutWithGroups(this.layout)) {
390721
+ const { group } = this.layout;
390722
+ const groups = getGroupToNodesMap(this.graph.nodes(), group, this.graph);
390723
+ Object.keys(groups).forEach((gr) => {
390724
+ const nodesIngroup = groups[gr].map((node2) => this.graph.getNodeAttributes(node2));
390725
+ this.createGroupContainer(gr, nodesIngroup);
390726
+ });
390727
+ }
390728
+ }
390035
390729
  dropEdge(id2) {
390036
390730
  const edge = this.edgeMap.get(id2);
390037
390731
  if (edge) {
@@ -390049,6 +390743,14 @@ ${letters.join("\n")}`;
390049
390743
  this.requestRender();
390050
390744
  }
390051
390745
  }
390746
+ dropGroupContainer(id2) {
390747
+ const container = this.groupContainerMap.get(id2);
390748
+ if (container) {
390749
+ this.groupContainerLayer.removeChild(container.groupContainerGfx);
390750
+ this.groupContainerMap.delete(id2);
390751
+ this.requestRender();
390752
+ }
390753
+ }
390052
390754
  enableDragBehaviour() {
390053
390755
  var _a3;
390054
390756
  if (this.dragMode === "move_node") {
@@ -390084,7 +390786,8 @@ ${letters.join("\n")}`;
390084
390786
  strength: this.getRelativeStrength(attributes2),
390085
390787
  theme: this.theme,
390086
390788
  thickness: attributes2["meta.rendering_properties.thickness"],
390087
- type: attributes2.edge_type
390789
+ type: attributes2.edge_type,
390790
+ collapsedEdges: attributes2["meta.rendering_properties.collapsedEdgesCount"]
390088
390791
  };
390089
390792
  if (this.processEdgeStyle) {
390090
390793
  return this.processEdgeStyle(edgeStyle, attributes2);
@@ -390093,10 +390796,10 @@ ${letters.join("\n")}`;
390093
390796
  }
390094
390797
  getNodeStyle(node2, attributes2) {
390095
390798
  var _a3, _b, _c, _d;
390096
- const group = getNodeGroup(this.graph, attributes2.id, attributes2["meta.rendering_properties.latent"]);
390799
+ const group = getNodeCategory(this.graph, attributes2.id, attributes2["meta.rendering_properties.latent"]);
390097
390800
  return {
390098
390801
  color: attributes2["meta.rendering_properties.color"],
390099
- group,
390802
+ category: group,
390100
390803
  highlight_color: attributes2["meta.rendering_properties.highlight_color"],
390101
390804
  isEdgeSelected: !!this.selectedEdge,
390102
390805
  isSourceOfNewEdge: this.isCreatingEdge && this.mousedownNodeKey === attributes2.id,
@@ -390105,7 +390808,8 @@ ${letters.join("\n")}`;
390105
390808
  label_size: (_b = attributes2["meta.rendering_properties.label_size"]) !== null && _b !== void 0 ? _b : this.layout.nodeFontSize,
390106
390809
  size: (_c = attributes2["meta.rendering_properties.size"]) !== null && _c !== void 0 ? _c : getNodeSize((_d = attributes2["meta.rendering_properties.size"]) !== null && _d !== void 0 ? _d : this.layout.nodeSize, group),
390107
390810
  state: node2.state,
390108
- theme: this.theme
390811
+ theme: this.theme,
390812
+ isGroupNode: attributes2.variable_type === "groupNode"
390109
390813
  };
390110
390814
  }
390111
390815
  hoverEdge(id2) {
@@ -390117,6 +390821,15 @@ ${letters.join("\n")}`;
390117
390821
  this.updateEdgeStyleByKey(id2);
390118
390822
  this.requestRender();
390119
390823
  }
390824
+ hoverGroupContainer(id2, nodes) {
390825
+ const groupContainer = this.groupContainerMap.get(id2);
390826
+ if (groupContainer.state.hover) {
390827
+ return;
390828
+ }
390829
+ groupContainer.state.hover = true;
390830
+ this.updateGroupContainerStyle(id2, nodes);
390831
+ this.requestRender();
390832
+ }
390120
390833
  hoverNode(id2) {
390121
390834
  const node2 = this.nodeMap.get(id2);
390122
390835
  if (node2.state.hover) {
@@ -390260,15 +390973,26 @@ ${letters.join("\n")}`;
390260
390973
  this.updateNodeStyleByKey(id2);
390261
390974
  this.requestRender();
390262
390975
  }
390976
+ unhoverGroupContainer(id2, nodes) {
390977
+ const groupContainer = this.groupContainerMap.get(id2);
390978
+ if (!groupContainer.state.hover) {
390979
+ return;
390980
+ }
390981
+ groupContainer.state.hover = false;
390982
+ this.updateGroupContainerStyle(id2, nodes);
390983
+ this.requestRender();
390984
+ }
390263
390985
  updateEdgeStyle(id2, attributes2, source, target, sourceNodeAttributes, targetNodeAttributes) {
390264
390986
  const edge = this.edgeMap.get(id2);
390265
390987
  if (edge && this.viewport) {
390266
390988
  const sourceNode = this.nodeMap.get(source);
390267
390989
  const targetNode = this.nodeMap.get(target);
390990
+ const isSourceGroupNode = sourceNodeAttributes.variable_type === "groupNode";
390991
+ const isTargetGroupNode = targetNodeAttributes.variable_type === "groupNode";
390268
390992
  const sourceNodePosition = { x: sourceNodeAttributes.x, y: sourceNodeAttributes.y };
390269
390993
  const targetNodePosition = { x: targetNodeAttributes.x, y: targetNodeAttributes.y };
390270
390994
  const edgeStyle = this.getEdgeStyle(edge, attributes2, this.getConstraint(source, target));
390271
- edge.updatePosition(edgeStyle, sourceNodePosition, targetNodePosition, sourceNode.nodeGfx.width, targetNode.nodeGfx.width, this.viewport, this.textureCache);
390995
+ edge.updatePosition(edgeStyle, sourceNodePosition, targetNodePosition, sourceNode.nodeGfx.width, targetNode.nodeGfx.width, this.viewport, this.textureCache, isSourceGroupNode, isTargetGroupNode);
390272
390996
  }
390273
390997
  }
390274
390998
  updateEdgeStyleByKey(edgeKey) {
@@ -390346,6 +391070,12 @@ ${letters.join("\n")}`;
390346
391070
  node2.updateStyle(this.getNodeStyle(node2, attributes2), this.textureCache);
390347
391071
  }
390348
391072
  }
391073
+ updateGroupContainerStyle(id2, nodes) {
391074
+ const groupContainer = this.groupContainerMap.get(id2);
391075
+ if (groupContainer) {
391076
+ groupContainer.updateStyle(nodes, this.textureCache, this.theme);
391077
+ }
391078
+ }
390349
391079
  updateNodeStyleByKey(nodeKey) {
390350
391080
  const nodeAttributes = this.graph.getNodeAttributes(nodeKey);
390351
391081
  this.updateNodeStyle(nodeKey, nodeAttributes);
@@ -390363,6 +391093,14 @@ ${letters.join("\n")}`;
390363
391093
  updateStyles() {
390364
391094
  this.graph.forEachNode(this.updateNodeStyle.bind(this));
390365
391095
  this.graph.forEachEdge(this.updateEdgeStyle.bind(this));
391096
+ if (isGraphLayoutWithGroups(this.layout)) {
391097
+ const { group } = this.layout;
391098
+ const groupsObject = getGroupToNodesMap(this.graph.nodes(), group, this.graph);
391099
+ Object.keys(groupsObject).forEach((gr) => {
391100
+ const nodesIngroup = groupsObject[gr].map((node2) => this.graph.getNodeAttributes(node2));
391101
+ this.updateGroupContainerStyle(gr, nodesIngroup);
391102
+ });
391103
+ }
390366
391104
  }
390367
391105
  }
390368
391106
  function useRenderEngine({ parentRef, graph, layout: layout2, editable: editable2, editorMode, constraints, errorHandler, processEdgeStyle, zoomThresholds, requireFocusToZoom }) {
@@ -390438,6 +391176,16 @@ ${letters.join("\n")}`;
390438
391176
  engine.current.resetViewport();
390439
391177
  }
390440
391178
  },
391179
+ collapseGroups: () => {
391180
+ if (engine.current.initialized) {
391181
+ engine.current.collapseAllGroups();
391182
+ }
391183
+ },
391184
+ expandGroups: () => {
391185
+ if (engine.current.initialized) {
391186
+ engine.current.expandAllGroups();
391187
+ }
391188
+ },
390441
391189
  extractImage: () => {
390442
391190
  if (engine.current.initialized) {
390443
391191
  return engine.current.extractImage();
@@ -391644,7 +392392,8 @@ ${letters.join("\n")}`;
391644
392392
  const handleError = (e3) => {
391645
392393
  setError(e3);
391646
392394
  };
391647
- const { getCenterPosition, useEngineEvent, resetViewport, resetLayout, extractImage, onSetDragMode, onNodeSelected, onEdgeSelected, onSearchResults, onUpdateConstraints, onSetFocus } = useRenderEngine({
392395
+ const layoutHasGroup = React.useMemo(() => layout2.group !== void 0, [layout2]);
392396
+ const { getCenterPosition, useEngineEvent, resetViewport, collapseGroups, expandGroups, resetLayout, extractImage, onSetDragMode, onNodeSelected, onEdgeSelected, onSearchResults, onUpdateConstraints, onSetFocus } = useRenderEngine({
391648
392397
  constraints: props.initialConstraints,
391649
392398
  editable: props.editable,
391650
392399
  editorMode: state.editorMode,
@@ -391665,6 +392414,7 @@ ${letters.join("\n")}`;
391665
392414
  localStorage.setItem("showGraphZoomPrompt", "false");
391666
392415
  }
391667
392416
  const [hasFocus, setHasFocus] = React.useState(false);
392417
+ const [showCollapseAll, setShowCollapseAll] = React.useState(true);
391668
392418
  function onPaneFocus(focus) {
391669
392419
  setHasFocus(focus);
391670
392420
  onSetFocus(focus);
@@ -391709,6 +392459,22 @@ ${letters.join("\n")}`;
391709
392459
  }
391710
392460
  }, [state.editorMode, selectedEdge, constraints]);
391711
392461
  function onRemoveNode() {
392462
+ var _a4, _b2;
392463
+ if (layoutHasGroup) {
392464
+ const layoutGroup = layout2.group;
392465
+ const groupsObject = getGroupToNodesMap(state.graph.nodes(), layoutGroup, state.graph);
392466
+ const nodesToGroups = getNodeToGroupMap(state.graph.nodes(), layoutGroup, state.graph);
392467
+ const group = nodesToGroups[selectedNode];
392468
+ if (((_a4 = groupsObject[group]) === null || _a4 === void 0 ? void 0 : _a4.length) === 1) {
392469
+ (_b2 = props.onNotify) === null || _b2 === void 0 ? void 0 : _b2.call(props, {
392470
+ key: "delete-group",
392471
+ message: "Cannot delete the last node in a group",
392472
+ status: Status.WARNING,
392473
+ title: "Group deletion"
392474
+ });
392475
+ return;
392476
+ }
392477
+ }
391712
392478
  api2.removeNode(selectedNode);
391713
392479
  setSelectedNode(null);
391714
392480
  }
@@ -391741,9 +392507,23 @@ ${letters.join("\n")}`;
391741
392507
  }
391742
392508
  }
391743
392509
  function onAddEdge(edge) {
391744
- var _a4;
392510
+ var _a4, _b2;
392511
+ if (layoutHasGroup) {
392512
+ const layoutGroup = layout2.group;
392513
+ const groupsObject = getGroupToNodesMap(state.graph.nodes(), layoutGroup, state.graph);
392514
+ const groups = Object.keys(groupsObject);
392515
+ if (groups.includes(edge[0]) && groups.includes(edge[1])) {
392516
+ (_a4 = props.onNotify) === null || _a4 === void 0 ? void 0 : _a4.call(props, {
392517
+ key: "create-edge-group",
392518
+ message: "Adding edge between groups is not allowed",
392519
+ status: Status.WARNING,
392520
+ title: "Group edge detected"
392521
+ });
392522
+ return;
392523
+ }
392524
+ }
391745
392525
  if (willCreateCycle(state.graph, edge)) {
391746
- (_a4 = props.onNotify) === null || _a4 === void 0 ? void 0 : _a4.call(props, {
392526
+ (_b2 = props.onNotify) === null || _b2 === void 0 ? void 0 : _b2.call(props, {
391747
392527
  key: "create-edge-cycle",
391748
392528
  message: "Could not create an edge as it would create a cycle",
391749
392529
  status: Status.WARNING,
@@ -391845,6 +392625,20 @@ ${letters.join("\n")}`;
391845
392625
  });
391846
392626
  setTooltipContent(edgeTooltipContent);
391847
392627
  });
392628
+ useEngineEvent("groupMouseover", (event2, groupId) => {
392629
+ tooltipRef.current = () => ({
392630
+ bottom: event2.clientY,
392631
+ height: 0,
392632
+ left: event2.clientX,
392633
+ right: event2.clientX,
392634
+ top: event2.clientY,
392635
+ width: 0
392636
+ });
392637
+ setTooltipContent(getTooltipContent(groupId, "", theme2));
392638
+ });
392639
+ useEngineEvent("groupMouseout", () => {
392640
+ setTooltipContent(null);
392641
+ });
391848
392642
  useEngineEvent("edgeMouseout", () => {
391849
392643
  setTooltipContent(null);
391850
392644
  });
@@ -391969,7 +392763,19 @@ ${letters.join("\n")}`;
391969
392763
  editorMode: state.editorMode,
391970
392764
  onNotify: props.onNotify,
391971
392765
  verboseDescriptions: props.verboseDescriptions
391972
- }, children: jsxRuntime.exports.jsx(pointerCtx.Provider, { value: { disablePointerEvents: isDragging, onPanelEnter, onPanelExit }, children: jsxRuntime.exports.jsx(GraphPane, { "$hasFocus": hasFocus, onClick: () => onPaneFocus(true), ref: paneRef, style: props.style, children: jsxRuntime.exports.jsxs(Graph, { onMouseEnter, onMouseLeave, children: [jsxRuntime.exports.jsx(EditorOverlay, { bottomLeft: jsxRuntime.exports.jsx(Legend, { listItems: getLegendData(props.defaultLegends, state.editorMode, props.additionalLegends) }), onDelete, onNext, onPrev, showFrameButtons: !isDragging && (showFrameButtons || hasFocus), title: panelTitle, topCenter: jsxRuntime.exports.jsx(jsxRuntime.exports.Fragment, { children: showZoomPrompt && jsxRuntime.exports.jsx(ZoomPrompt, { hasFocus, onClose: () => setShowZoomPrompt(false), onDismiss }) }), topLeft: jsxRuntime.exports.jsx(RecalculateLayoutButton, { onResetLayout: resetLayout }), topRight: jsxRuntime.exports.jsxs(jsxRuntime.exports.Fragment, { children: [jsxRuntime.exports.jsx(FloatingSearchBar, { onChange: onSearchBarChange, onClose: () => setSelectedNode(null), onNext: onNextSearchResult, onPrev: onPrevSearchResult, selectedResult: currentSearchNode + 1, totalNumberOfResults: searchResults.length }), jsxRuntime.exports.jsx(CenterGraphButton, { onResetZoom: resetViewport }), jsxRuntime.exports.jsx(EditControls, { onAddNode }), jsxRuntime.exports.jsx(DragModeButton, { dragMode, setDragMode }), jsxRuntime.exports.jsx(SaveImageButton, { onSave: saveImage })] }), validContentSelected: contentSelected, children: jsxRuntime.exports.jsxs(graphCtx.Provider, { value: {
392766
+ }, children: jsxRuntime.exports.jsx(pointerCtx.Provider, { value: { disablePointerEvents: isDragging, onPanelEnter, onPanelExit }, children: jsxRuntime.exports.jsx(GraphPane, { "$hasFocus": hasFocus, onClick: () => onPaneFocus(true), ref: paneRef, style: props.style, children: jsxRuntime.exports.jsxs(Graph, { onMouseEnter, onMouseLeave, children: [jsxRuntime.exports.jsx(EditorOverlay, { bottomLeft: jsxRuntime.exports.jsx(Legend, { listItems: getLegendData(props.defaultLegends, state.editorMode, props.additionalLegends) }), onDelete, onNext, onPrev, showFrameButtons: !isDragging && (showFrameButtons || hasFocus), title: panelTitle, topCenter: jsxRuntime.exports.jsx(jsxRuntime.exports.Fragment, { children: showZoomPrompt && jsxRuntime.exports.jsx(ZoomPrompt, { hasFocus, onClose: () => setShowZoomPrompt(false), onDismiss }) }), topLeft: jsxRuntime.exports.jsx(RecalculateLayoutButton, { onResetLayout: resetLayout }), topRight: jsxRuntime.exports.jsxs(jsxRuntime.exports.Fragment, { children: [jsxRuntime.exports.jsx(FloatingSearchBar, { onChange: (value) => {
392767
+ onSearchBarChange(value);
392768
+ if (layoutHasGroup) {
392769
+ expandGroups();
392770
+ setShowCollapseAll(true);
392771
+ }
392772
+ }, onClose: () => setSelectedNode(null), onNext: onNextSearchResult, onPrev: onPrevSearchResult, selectedResult: currentSearchNode + 1, totalNumberOfResults: searchResults.length }), layoutHasGroup && jsxRuntime.exports.jsx(CollapseExpandGroupButton, { onCollapseAll: () => {
392773
+ setShowCollapseAll(false);
392774
+ collapseGroups();
392775
+ }, onExpandAll: () => {
392776
+ expandGroups();
392777
+ setShowCollapseAll(true);
392778
+ }, showExpandAll: showCollapseAll }), jsxRuntime.exports.jsx(CenterGraphButton, { onResetZoom: resetViewport }), jsxRuntime.exports.jsx(EditControls, { onAddNode }), jsxRuntime.exports.jsx(DragModeButton, { dragMode, setDragMode }), jsxRuntime.exports.jsx(SaveImageButton, { onSave: saveImage })] }), validContentSelected: contentSelected, children: jsxRuntime.exports.jsxs(graphCtx.Provider, { value: {
391973
392779
  api: api2,
391974
392780
  constraints,
391975
392781
  editable: props.editable,
@@ -396789,6 +397595,9 @@ ${letters.join("\n")}`;
396789
397595
  function isDefinitionWithTiers(obj) {
396790
397596
  return obj && typeof obj === "object" && "tiers" in obj;
396791
397597
  }
397598
+ function isDefinitionWithGroup(obj) {
397599
+ return obj && typeof obj === "object" && "group" in obj;
397600
+ }
396792
397601
  function parseLayoutDefinition(definition2) {
396793
397602
  let builder;
396794
397603
  switch (definition2.layout_type) {
@@ -396881,13 +397690,25 @@ ${letters.join("\n")}`;
396881
397690
  }
396882
397691
  case "spring": {
396883
397692
  builder = SpringLayout.Builder;
397693
+ if (definition2.collision_force) {
397694
+ builder.collisionForce(definition2.collision_force);
397695
+ }
397696
+ if (definition2.gravity) {
397697
+ builder.gravity(definition2.gravity);
397698
+ }
397699
+ if (definition2.link_force) {
397700
+ builder.linkForce(definition2.link_force);
397701
+ }
396884
397702
  if (definition2.warmup_ticks) {
396885
397703
  builder.warmupTicks(definition2.warmup_ticks);
396886
397704
  }
397705
+ if (definition2.group_repel_strength) {
397706
+ builder.groupRepelStrength(definition2.group_repel_strength);
397707
+ }
396887
397708
  break;
396888
397709
  }
396889
397710
  default: {
396890
- throw new Error(`Unrecognised layout type: ${String(definition2.layout_type)}`);
397711
+ throw new Error(`Unrecognized layout type: ${String(definition2.layout_type)}`);
396891
397712
  }
396892
397713
  }
396893
397714
  if (isDefinitionWithTiers(definition2)) {
@@ -396902,6 +397723,12 @@ ${letters.join("\n")}`;
396902
397723
  builderWithTiers.tierSeparation(definition2.tier_separation);
396903
397724
  }
396904
397725
  }
397726
+ if (isDefinitionWithGroup(definition2)) {
397727
+ const builderWithGroup = builder;
397728
+ if (definition2.group) {
397729
+ builderWithGroup.group = definition2.group;
397730
+ }
397731
+ }
396905
397732
  if (definition2.node_size) {
396906
397733
  builder.nodeSize(definition2.node_size);
396907
397734
  }