@knowvah/dot-engine 1.2.1 → 1.2.3

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.
@@ -28,6 +28,14 @@ export declare function arrowheadPolygon(arrowTip: Point, arrowDir: Point, penwi
28
28
  /** Minimal edge shape exposing the arrow-related attributes. */
29
29
  interface ArrowAttrEdge {
30
30
  attrs: Map<string, string>;
31
+ /** Present on real edges; the curve generator needs the rankdir frame. */
32
+ tail?: {
33
+ root?: {
34
+ info?: {
35
+ rankdir?: number;
36
+ };
37
+ };
38
+ };
31
39
  }
32
40
  /** The arrowhead/arrowtail name for an edge end (default "normal"). */
33
41
  export declare function edgeArrowName(e: ArrowAttrEdge, end: 'head' | 'tail'): string;
@@ -1 +1 @@
1
- {"version":3,"file":"edge-route-arrow.d.ts","sourceRoot":"","sources":["../../../src/layout/dot/edge-route-arrow.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAIjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,gFAAgF;AAChF,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,SAAM,GAAG,KAAK,EAAE,CAe1F;AAOD,gEAAgE;AAChE,UAAU,aAAa;IAAG,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE;AAEtD,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5E;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAGtD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAC/E,WAAW,EAAE,CAKf"}
1
+ {"version":3,"file":"edge-route-arrow.d.ts","sourceRoot":"","sources":["../../../src/layout/dot/edge-route-arrow.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAIjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,gFAAgF;AAChF,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,SAAM,GAAG,KAAK,EAAE,CAe1F;AAOD,gEAAgE;AAChE,UAAU,aAAa;IACrB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,0EAA0E;IAC1E,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC;CACnD;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5E;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAGtD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAC/E,WAAW,EAAE,CAMf"}
@@ -1 +1 @@
1
- {"version":3,"file":"edge-route-helpers.d.ts","sourceRoot":"","sources":["../../../src/layout/dot/edge-route-helpers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAOjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzF;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAE/C;AAyBD,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAepD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAEvD;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAGrD;AAOD,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,GAAG,MAAM,CAM5E;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,GAAG,IAAI,CAYzF;AAaD,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,EAAE,CAM3D;AAED,gFAAgF;AAChF,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,YAAY,GAAG,SAAS,EAClC,QAAQ,SAAM,EACd,IAAI,CAAC,EAAE,SAAS,GACf,gBAAgB,CAIlB"}
1
+ {"version":3,"file":"edge-route-helpers.d.ts","sourceRoot":"","sources":["../../../src/layout/dot/edge-route-helpers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAI7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAOjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzF;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAE/C;AAyBD,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAgCpD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAEvD;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAGrD;AAOD,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,GAAG,MAAM,CAM5E;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,GAAG,IAAI,CAYzF;AAaD,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,GAAG,KAAK,EAAE,CAM3D;AAED,gFAAgF;AAChF,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,YAAY,GAAG,SAAS,EAClC,QAAQ,SAAM,EACd,IAAI,CAAC,EAAE,SAAS,GACf,gBAAgB,CAIlB"}
@@ -109,6 +109,11 @@ export type Port = {
109
109
  * @see lib/common/geom.c:ccwrotatepf
110
110
  */
111
111
  export declare function ccwrotatepf(p: Point, ccwrot: number): Point;
112
+ /**
113
+ * Clockwise counterpart — the exact inverse of {@link ccwrotatepf} per case.
114
+ * @see lib/common/geom.c:cwrotatepf
115
+ */
116
+ export declare function cwrotatepf(p: Point, cwrot: number): Point;
112
117
  /**
113
118
  * Returns true if box `b0` completely contains box `b1`.
114
119
  *
@@ -1 +1 @@
1
- {"version":3,"file":"geom.d.ts","sourceRoot":"","sources":["../../src/model/geom.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAMH;;;;GAIG;AACH,MAAM,MAAM,KAAK,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAM7C;;;;;;;;GAQG;AACH,MAAM,MAAM,GAAG,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAM3C;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,4CAA4C;IAC5C,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,EAAE,EAAE,KAAK,CAAC;IACV,yCAAyC;IACzC,EAAE,EAAE,KAAK,CAAC;CACX,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,EAAE,EAAE,GAAG,CAAC;CACT,CAAC;AAMF;;;;GAIG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,8EAA8E;IAC9E,CAAC,EAAE,KAAK,CAAC;IACT,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC;IACf,qFAAqF;IACrF,OAAO,EAAE,OAAO,CAAC;IACjB,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,IAAI,EAAE,OAAO,CAAC;IACd,oFAAoF;IACpF,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAUF;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAQ3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAOrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAOpD;AAMD;;;;GAIG;AACH,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;GAIG;AACH,eAAO,MAAM,WAAW,MAAO,CAAC"}
1
+ {"version":3,"file":"geom.d.ts","sourceRoot":"","sources":["../../src/model/geom.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAMH;;;;GAIG;AACH,MAAM,MAAM,KAAK,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAM7C;;;;;;;;GAQG;AACH,MAAM,MAAM,GAAG,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAM3C;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,4CAA4C;IAC5C,IAAI,EAAE,KAAK,EAAE,CAAC;IACd,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,EAAE,EAAE,KAAK,CAAC;IACV,yCAAyC;IACzC,EAAE,EAAE,KAAK,CAAC;CACX,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,EAAE,EAAE,GAAG,CAAC;CACT,CAAC;AAMF;;;;GAIG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,8EAA8E;IAC9E,CAAC,EAAE,KAAK,CAAC;IACT,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC;IACf,qFAAqF;IACrF,OAAO,EAAE,OAAO,CAAC;IACjB,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,IAAI,EAAE,OAAO,CAAC;IACd,oFAAoF;IACpF,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAUF;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAQ3D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAQzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAOrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAOpD;AAMD;;;;GAIG;AACH,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;GAIG;AACH,eAAO,MAAM,WAAW,MAAO,CAAC"}
package/dist/render.js CHANGED
@@ -7597,6 +7597,40 @@ function miterShape(baseLeft, P, baseRight, penwidth) {
7597
7597
  return [{ x: P1.x + l * a.cos, y: P1.y + l * a.sin }, P1, P2];
7598
7598
  }
7599
7599
 
7600
+ // src/model/geom.ts
7601
+ function ccwrotatepf(p, ccwrot) {
7602
+ switch (ccwrot) {
7603
+ case 0:
7604
+ return p;
7605
+ case 90:
7606
+ return { x: -p.y, y: p.x };
7607
+ case 180:
7608
+ return { x: p.x, y: -p.y };
7609
+ case 270:
7610
+ return { x: p.y, y: p.x };
7611
+ default:
7612
+ return p;
7613
+ }
7614
+ }
7615
+ function cwrotatepf(p, cwrot) {
7616
+ switch (cwrot) {
7617
+ case 0:
7618
+ return p;
7619
+ case 90:
7620
+ return { x: p.y, y: -p.x };
7621
+ case 180:
7622
+ return { x: p.x, y: -p.y };
7623
+ case 270:
7624
+ return { x: p.y, y: p.x };
7625
+ default:
7626
+ return p;
7627
+ }
7628
+ }
7629
+ function boxOverlap(b0, b1) {
7630
+ return b0.ur.x >= b1.ll.x && b1.ur.x >= b0.ll.x && b0.ur.y >= b1.ll.y && b1.ur.y >= b0.ll.y;
7631
+ }
7632
+ var POINTS_PER_INCH = 72;
7633
+
7600
7634
  // src/common/arrows-shapes-poly.ts
7601
7635
  var CROW_ARROWWIDTH = 0.45;
7602
7636
  function crowBasePoints(u, v, flag) {
@@ -7758,7 +7792,15 @@ function curveControlPoints(p, v, w, flag) {
7758
7792
  const AF2 = { x: p.x - 0.95 * v.x + w.x + s * w.x * (4 / 3), y: AF3.y + s * w.y * (4 / 3) };
7759
7793
  return [AF0, AF1, AF2, AF3];
7760
7794
  }
7761
- function genCurve(p0, u, _arrowsize, penwidth, flag) {
7795
+ function genCurve(p0, u, _arrowsize, penwidth, flag, rankdir = 0) {
7796
+ if (rankdir !== 0) {
7797
+ const rot = rankdir * 90;
7798
+ const fin = genCurve(ccwrotatepf(p0, rot), ccwrotatepf(u, rot), _arrowsize, penwidth, flag);
7799
+ return {
7800
+ ops: fin.ops.map((op) => "points" in op ? { ...op, points: op.points.map((pt) => cwrotatepf(pt, rot)) } : op),
7801
+ q: cwrotatepf(fin.q, rot)
7802
+ };
7803
+ }
7762
7804
  const arrowwidth = penwidth > 4 ? 0.5 * penwidth / 4 : 0.5;
7763
7805
  const noShift = flag & ARR_MOD_INV || u.x === 0 && u.y === 0;
7764
7806
  const p = noShift ? p0 : vsub(p0, backwardDelta(u, penwidth));
@@ -7973,7 +8015,7 @@ function arrowLength(comps, arrowsize, penwidth) {
7973
8015
  for (let i = 0; i < n; i++) length += arrowLengthOne(comps[i], arrowsize, penwidth);
7974
8016
  return length;
7975
8017
  }
7976
- function dispatchSimple(r, tip2, dir, arrowsize, penwidth) {
8018
+ function dispatchSimple(r, tip2, dir, arrowsize, penwidth, rankdir = 0) {
7977
8019
  const flag = arrowFlag(r);
7978
8020
  const u = componentU(dir, r.lenfact, arrowsize);
7979
8021
  switch (r.type & ARR_TYPE_MASK) {
@@ -7987,8 +8029,10 @@ function dispatchSimple(r, tip2, dir, arrowsize, penwidth) {
7987
8029
  return genDiamond(tip2, u, arrowsize, penwidth, flag);
7988
8030
  case ARR_TYPE_DOT:
7989
8031
  return genDot(tip2, u, arrowsize, penwidth, flag);
8032
+ // curve is the one generator that is not rotation-equivariant; it needs
8033
+ // the rankdir to reproduce C's render-time (final-frame) generation.
7990
8034
  case ARR_TYPE_CURVE:
7991
- return genCurve(tip2, u, arrowsize, penwidth, flag);
8035
+ return genCurve(tip2, u, arrowsize, penwidth, flag, rankdir);
7992
8036
  case ARR_TYPE_GAP:
7993
8037
  return genGap(tip2, u, arrowsize, penwidth, flag);
7994
8038
  case ARR_TYPE_NORM:
@@ -7996,14 +8040,14 @@ function dispatchSimple(r, tip2, dir, arrowsize, penwidth) {
7996
8040
  return genNormal(tip2, u, arrowsize, penwidth, flag);
7997
8041
  }
7998
8042
  }
7999
- function arrowDrawOps(comps, tip2, dir, arrowsize, penwidth) {
8043
+ function arrowDrawOps(comps, tip2, dir, arrowsize, penwidth, rankdir = 0) {
8000
8044
  const ops = [];
8001
8045
  let p = tip2;
8002
8046
  const n = Math.min(comps.length, 4);
8003
8047
  for (let i = 0; i < n; i++) {
8004
8048
  const r = comps[i];
8005
8049
  if ((r.type & ARR_TYPE_MASK) === ARR_TYPE_NONE) break;
8006
- const res = dispatchSimple(r, p, dir, arrowsize, penwidth);
8050
+ const res = dispatchSimple(r, p, dir, arrowsize, penwidth, rankdir);
8007
8051
  ops.push(...res.ops);
8008
8052
  p = res.q;
8009
8053
  }
@@ -8147,7 +8191,8 @@ function edgeArrowsize(e) {
8147
8191
  }
8148
8192
  function arrowDrawOpsForEnd(e, end, tip2, dir, penwidth) {
8149
8193
  const comps = parseArrow(edgeArrowName(e, end)).map(resolveArrowType);
8150
- return arrowDrawOps(comps, tip2, dir, edgeArrowsize(e), penwidth);
8194
+ const rankdir = (e.tail?.root?.info?.rankdir ?? 0) & 3;
8195
+ return arrowDrawOps(comps, tip2, dir, edgeArrowsize(e), penwidth, rankdir);
8151
8196
  }
8152
8197
 
8153
8198
  // src/model/layoutParams.ts
@@ -8501,26 +8546,6 @@ var RenderJob = class {
8501
8546
  }
8502
8547
  };
8503
8548
 
8504
- // src/model/geom.ts
8505
- function ccwrotatepf(p, ccwrot) {
8506
- switch (ccwrot) {
8507
- case 0:
8508
- return p;
8509
- case 90:
8510
- return { x: -p.y, y: p.x };
8511
- case 180:
8512
- return { x: p.x, y: -p.y };
8513
- case 270:
8514
- return { x: p.y, y: p.x };
8515
- default:
8516
- return p;
8517
- }
8518
- }
8519
- function boxOverlap(b0, b1) {
8520
- return b0.ur.x >= b1.ll.x && b1.ur.x >= b0.ll.x && b0.ur.y >= b1.ll.y && b1.ur.y >= b0.ll.y;
8521
- }
8522
- var POINTS_PER_INCH = 72;
8523
-
8524
8549
  // src/model/graphInfo.ts
8525
8550
  function makeGraphInfo() {
8526
8551
  return {
@@ -10025,11 +10050,22 @@ function generalPolyVertices(poly, w, h) {
10025
10050
  const sy = ymax !== 0 ? h / (2 * ymax) : 1;
10026
10051
  return verts.map((v) => ({ x: v.x * sx, y: v.y * sy }));
10027
10052
  }
10028
- function ellipseRings(w, h, peripheries) {
10053
+ function ellipseRings(w, h, peripheries, base) {
10054
+ if (base === void 0) {
10055
+ const out2 = [];
10056
+ for (let j = 0; j < peripheries; j++) {
10057
+ const inset = (peripheries - 1 - j) * GAP;
10058
+ out2.push(...ellipseVertices(w - 2 * inset, h - 2 * inset));
10059
+ }
10060
+ return out2;
10061
+ }
10029
10062
  const out = [];
10063
+ let px = base.w / 2;
10064
+ let py = base.h / 2;
10030
10065
  for (let j = 0; j < peripheries; j++) {
10031
- const inset = (peripheries - 1 - j) * GAP;
10032
- out.push(...ellipseVertices(w - 2 * inset, h - 2 * inset));
10066
+ out.push({ x: -px, y: -py }, { x: px, y: py });
10067
+ px += GAP;
10068
+ py += GAP;
10033
10069
  }
10034
10070
  return out;
10035
10071
  }
@@ -10093,10 +10129,16 @@ function starRings(box, peripheries) {
10093
10129
  }
10094
10130
  function computeVertices(poly, w, h, base) {
10095
10131
  const sides = poly.sides;
10132
+ if (poly.option.fixedshape && base !== void 0) {
10133
+ w = base.w;
10134
+ h = base.h;
10135
+ }
10096
10136
  if (poly.option.shape === CYLINDER) return cylinderVertices(w, h);
10097
10137
  const peripheries = Math.max(poly.peripheries, 1);
10098
10138
  if (poly.option.shape === STAR) return starRings({ w, h, base }, peripheries);
10099
- if (sides <= 2) return ellipseRings(w, h, peripheries);
10139
+ if (sides <= 2) {
10140
+ return ellipseRings(w, h, peripheries, poly.option.fixedshape ? base : void 0);
10141
+ }
10100
10142
  if (sides === 4 && Math.abs(poly.orientation % 90) < 0.5 && poly.distortion === 0 && poly.skew === 0) {
10101
10143
  return boxRings(w, h, peripheries, poly.orientation, base);
10102
10144
  }
@@ -10418,7 +10460,8 @@ function assembleResult(p, dimen, grown, fixedshape) {
10418
10460
  outlineW: Math.max(dimen.x, grown.outline.x),
10419
10461
  outlineH: Math.max(dimen.y, grown.outline.y),
10420
10462
  baseW: grown.base.x,
10421
- baseH: grown.base.y
10463
+ baseH: grown.base.y,
10464
+ fixedshape
10422
10465
  };
10423
10466
  }
10424
10467
  return {
@@ -10426,7 +10469,8 @@ function assembleResult(p, dimen, grown, fixedshape) {
10426
10469
  outlineW: grown.outline.x,
10427
10470
  outlineH: grown.outline.y,
10428
10471
  baseW: grown.base.x,
10429
- baseH: grown.base.y
10472
+ baseH: grown.base.y,
10473
+ fixedshape
10430
10474
  };
10431
10475
  }
10432
10476
 
@@ -14397,21 +14441,28 @@ function fixedShapeSize(poly) {
14397
14441
  }
14398
14442
  return { w: 2 * xmax, h: 2 * ymax };
14399
14443
  }
14400
- function insideDims(n, poly, xsize, ysize) {
14401
- if (poly.option.fixedshape) {
14402
- const { w: w2, h: h2 } = fixedShapeSize(poly);
14403
- return { w: w2, h: h2, ow: w2, oh: h2 };
14404
- }
14444
+ function insideDims(n, xsize, ysize) {
14405
14445
  const w = 72 * (n.info.width || xsize / 72);
14406
14446
  const h = 72 * (n.info.height || ysize / 72);
14407
14447
  return { w, h, ow: 72 * n.info.outline_width || w, oh: 72 * n.info.outline_height || h };
14408
14448
  }
14409
14449
  function insideScale(n, poly) {
14410
14450
  const flip = n.root.info.flip === true;
14451
+ if (poly.option.fixedshape) {
14452
+ const { w: w2, h: h2 } = fixedShapeSize(poly);
14453
+ const xsize2 = flip ? h2 : w2;
14454
+ const ysize2 = flip ? w2 : h2;
14455
+ return {
14456
+ scalex: xsize2 !== 0 ? w2 / xsize2 : w2,
14457
+ scaley: ysize2 !== 0 ? h2 / ysize2 : h2,
14458
+ boxURx: w2 / 2,
14459
+ boxURy: h2 / 2
14460
+ };
14461
+ }
14411
14462
  const lwrw = n.info.lw + n.info.rw;
14412
14463
  const xsize = flip ? n.info.ht : lwrw;
14413
14464
  const ysize = flip ? lwrw : n.info.ht;
14414
- const { w, h, ow, oh } = insideDims(n, poly, xsize, ysize);
14465
+ const { w, h, ow, oh } = insideDims(n, xsize, ysize);
14415
14466
  return {
14416
14467
  scalex: xsize !== 0 ? w / xsize : w,
14417
14468
  scaley: ysize !== 0 ? h / ysize : h,
@@ -16637,7 +16688,7 @@ function gdRankdir(n) {
16637
16688
  function gdFlip(n) {
16638
16689
  return (gdRankdir(n) & 1) !== 0;
16639
16690
  }
16640
- function cwrotatepf(p, cwrot) {
16691
+ function cwrotatepf2(p, cwrot) {
16641
16692
  switch (cwrot) {
16642
16693
  case 90:
16643
16694
  return { x: p.y, y: -p.x };
@@ -16784,7 +16835,7 @@ function setOrder(pp, q) {
16784
16835
  pp.order = MC_SCALE * a / (2 * Math.PI) | 0;
16785
16836
  }
16786
16837
  function applyDir(pp, bp, dir, rd, definedFinal) {
16787
- const q = cwrotatepf(dir.p, 90 * rd);
16838
+ const q = cwrotatepf2(dir.p, 90 * rd);
16788
16839
  pp.p = q;
16789
16840
  pp.bp = bp;
16790
16841
  pp.side = dir.dyna ? dir.side : invflipSide(dir.side, rd);
@@ -16800,7 +16851,7 @@ function nodeInsideFn(n) {
16800
16851
  }
16801
16852
  function compassPoint(n, insideFn, yArg, xArg, rd) {
16802
16853
  let p = { x: xArg, y: yArg };
16803
- if (rd) p = cwrotatepf(p, 90 * rd);
16854
+ if (rd) p = cwrotatepf2(p, 90 * rd);
16804
16855
  const curve = [{ x: 0, y: 0 }, { x: 0, y: 0 }, { x: p.x, y: p.y }, { x: p.x, y: p.y }];
16805
16856
  const ctx = { nodeCoord: n.info.coord, rw: n.info.rw, bp: null, node: n };
16806
16857
  bezierClip(ctx, insideFn, curve, true);
@@ -17168,7 +17219,9 @@ function pointSizeResult(sz0, peripheries, penwidth) {
17168
17219
  outlineW: szOutline,
17169
17220
  outlineH: szOutline,
17170
17221
  baseW: sz0,
17171
- baseH: sz0
17222
+ baseH: sz0,
17223
+ fixedshape: false
17224
+ // C point_init never sets option.fixedshape
17172
17225
  };
17173
17226
  }
17174
17227
  function initPointSize(n, g, shape) {
@@ -17203,14 +17256,17 @@ function initNodeFromLabel(n, g, measurer) {
17203
17256
  label.space = sz.space;
17204
17257
  label.valign = sz.valign.charCodeAt(0);
17205
17258
  storeNodeSize(n, sz, flip);
17206
- assignShapeInfo(n, effectivePolygon(poly, params));
17259
+ assignShapeInfo(n, effectivePolygon(poly, params, sz.fixedshape));
17207
17260
  return true;
17208
17261
  }
17209
- function effectivePolygon(poly, p) {
17262
+ function effectivePolygon(poly, p, fixedshape) {
17210
17263
  let sides = p.sides;
17211
17264
  if (sides <= 2 && (p.distortion !== 0 || p.skew !== 0)) sides = 120;
17212
17265
  return {
17213
17266
  ...poly,
17267
+ // C: poly->option.fixedshape = true inside the fixedsize="shape" branch;
17268
+ // poly-inside and computeVertices key the shape-box/width split on it.
17269
+ option: { ...poly.option, fixedshape },
17214
17270
  regular: p.regular,
17215
17271
  peripheries: p.peripheries,
17216
17272
  sides,
@@ -25327,6 +25383,21 @@ function nodeBoxOf(n, g) {
25327
25383
  const rb = recordClipBox(n);
25328
25384
  if (rb) return { center: n.info.coord, ...rb, isEllipse: false, penwidth };
25329
25385
  }
25386
+ const si = n.info.shape_info;
25387
+ if (si?.option?.fixedshape === true && si.vertices) {
25388
+ const ext = fixedShapeSize(si);
25389
+ const flip = g.root.info.flip === true;
25390
+ const w = flip ? ext.h : ext.w;
25391
+ const h = flip ? ext.w : ext.h;
25392
+ return {
25393
+ center: n.info.coord,
25394
+ lw: w / 2,
25395
+ rw: w / 2,
25396
+ ht: h,
25397
+ isEllipse: ELLIPSE_SHAPES.has(shapeName),
25398
+ penwidth: 0
25399
+ };
25400
+ }
25330
25401
  return {
25331
25402
  center: n.info.coord,
25332
25403
  lw: n.info.lw > 0 ? n.info.lw : 27,