microboard-temp 0.10.1 → 0.11.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.
package/dist/esm/node.js CHANGED
@@ -1827,6 +1827,24 @@ class Matrix {
1827
1827
  const { translateX, translateY, scaleX, scaleY, shearX, shearY } = matrix;
1828
1828
  return this.translateX === translateX && this.translateY === translateY && this.scaleX === scaleX && this.scaleY === scaleY && this.shearX === shearX && this.shearY === shearY;
1829
1829
  }
1830
+ composeWith(parent) {
1831
+ const result = parent.copy();
1832
+ result.multiplyByMatrix(this);
1833
+ return result;
1834
+ }
1835
+ toLocalOf(parent) {
1836
+ const result = parent.getInverse();
1837
+ result.multiplyByMatrix(this);
1838
+ return result;
1839
+ }
1840
+ applyInverseLinear(dx, dy) {
1841
+ const { scaleX, scaleY, shearX, shearY } = this;
1842
+ const denom = scaleX * scaleY - shearX * shearY;
1843
+ return {
1844
+ x: (scaleY * dx - shearX * dy) / denom,
1845
+ y: (-shearY * dx + scaleX * dy) / denom
1846
+ };
1847
+ }
1830
1848
  }
1831
1849
 
1832
1850
  // src/Subject.ts
@@ -20323,6 +20341,15 @@ class Transformation {
20323
20341
  getRotation() {
20324
20342
  return this.rotate;
20325
20343
  }
20344
+ setLocalMatrix(matrix) {
20345
+ this.previous = this._matrix.copy();
20346
+ this._matrix = matrix.copy();
20347
+ this.subject.publish(this, {
20348
+ class: "Transformation",
20349
+ method: "applyMatrix",
20350
+ items: [{ id: this.id, matrix: this.getMatrixData() }]
20351
+ });
20352
+ }
20326
20353
  setLocal(xOrData, y, scaleX, scaleY) {
20327
20354
  this.previous = this._matrix.copy();
20328
20355
  if (typeof xOrData === "object") {
@@ -23177,6 +23204,24 @@ class LayeredIndex {
23177
23204
  }
23178
23205
 
23179
23206
  // src/SpatialIndex/SpacialIndex.ts
23207
+ function worldBoundsToLocal(container, left, top, right, bottom) {
23208
+ const inv = container.getWorldMatrix().getInverse();
23209
+ const corners = [
23210
+ new Point(left, top),
23211
+ new Point(right, top),
23212
+ new Point(right, bottom),
23213
+ new Point(left, bottom)
23214
+ ];
23215
+ for (const c of corners)
23216
+ inv.apply(c);
23217
+ return {
23218
+ left: Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
23219
+ top: Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y),
23220
+ right: Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
23221
+ bottom: Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y)
23222
+ };
23223
+ }
23224
+
23180
23225
  class SpatialIndex {
23181
23226
  subject = new Subject;
23182
23227
  itemsArray = [];
@@ -23228,6 +23273,8 @@ class SpatialIndex {
23228
23273
  if (item.parent !== "Board") {
23229
23274
  const parentFrame = this.items.getById(item.parent);
23230
23275
  parentFrame?.removeChildItems(item);
23276
+ this.subject.publish(this.items);
23277
+ return;
23231
23278
  }
23232
23279
  this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
23233
23280
  this.itemsIndex.remove(item);
@@ -23242,10 +23289,20 @@ class SpatialIndex {
23242
23289
  this.subject.publish(this.items);
23243
23290
  }
23244
23291
  copy() {
23245
- return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => ({
23246
- ...item.serialize(true),
23247
- id: item.getId()
23248
- }));
23292
+ return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => {
23293
+ const serialized = { ...item.serialize(true), id: item.getId() };
23294
+ if (item.parent !== "Board" && item.getWorldMatrix) {
23295
+ const worldMatrix = item.getWorldMatrix();
23296
+ serialized.transformation = {
23297
+ ...serialized.transformation,
23298
+ translateX: worldMatrix.translateX,
23299
+ translateY: worldMatrix.translateY,
23300
+ scaleX: worldMatrix.scaleX,
23301
+ scaleY: worldMatrix.scaleY
23302
+ };
23303
+ }
23304
+ return serialized;
23305
+ });
23249
23306
  }
23250
23307
  getItemsWithIncludedChildren(items) {
23251
23308
  return items.flatMap((item) => {
@@ -23411,7 +23468,8 @@ class SpatialIndex {
23411
23468
  const children = [];
23412
23469
  const clearItems = items.filter((item) => {
23413
23470
  if ("index" in item && item.index) {
23414
- children.push(...item.index.getEnclosed(left, top, right, bottom));
23471
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
23472
+ children.push(...item.index.getEnclosed(local.left, local.top, local.right, local.bottom));
23415
23473
  if (!item.getMbr().isEnclosedBy(mbr)) {
23416
23474
  return false;
23417
23475
  }
@@ -23426,7 +23484,8 @@ class SpatialIndex {
23426
23484
  const children = [];
23427
23485
  const clearItems = items.filter((item) => {
23428
23486
  if ("index" in item && item.index) {
23429
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
23487
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
23488
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
23430
23489
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
23431
23490
  return false;
23432
23491
  }
@@ -23440,7 +23499,9 @@ class SpatialIndex {
23440
23499
  const children = [];
23441
23500
  const clearItems = items.filter((item) => {
23442
23501
  if ("index" in item && item.index) {
23443
- children.push(...item.index.getUnderPoint(point3, tolerance));
23502
+ const localPt = new Point(point3.x, point3.y);
23503
+ item.getWorldMatrix().getInverse().apply(localPt);
23504
+ children.push(...item.index.getUnderPoint(localPt, tolerance));
23444
23505
  if (!item.getMbr().isUnderPoint(point3)) {
23445
23506
  return false;
23446
23507
  }
@@ -23455,7 +23516,8 @@ class SpatialIndex {
23455
23516
  const children = [];
23456
23517
  const clearItems = items.filter((item) => {
23457
23518
  if ("index" in item && item.index) {
23458
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
23519
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
23520
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
23459
23521
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
23460
23522
  return false;
23461
23523
  }
@@ -23918,6 +23980,49 @@ class SimpleSpatialIndex {
23918
23980
  }
23919
23981
 
23920
23982
  // src/Items/BaseItem/BaseItem.ts
23983
+ function toLocalTransformOp(op, containerMatrix, itemId) {
23984
+ switch (op.method) {
23985
+ case "applyMatrix": {
23986
+ const converted = op.items.map((item) => {
23987
+ const local = containerMatrix.applyInverseLinear(item.matrix.translateX, item.matrix.translateY);
23988
+ return { ...item, matrix: { ...item.matrix, translateX: local.x, translateY: local.y } };
23989
+ });
23990
+ return { ...op, items: converted };
23991
+ }
23992
+ case "translateBy": {
23993
+ const local = containerMatrix.applyInverseLinear(op.x, op.y);
23994
+ return { ...op, x: local.x, y: local.y };
23995
+ }
23996
+ case "translateTo": {
23997
+ const pt = new Point(op.x, op.y);
23998
+ containerMatrix.getInverse().apply(pt);
23999
+ return { ...op, x: pt.x, y: pt.y };
24000
+ }
24001
+ case "scaleTo": {
24002
+ return { ...op, x: op.x / containerMatrix.scaleX, y: op.y / containerMatrix.scaleY };
24003
+ }
24004
+ case "scaleByTranslateBy": {
24005
+ const local = containerMatrix.applyInverseLinear(op.translate.x, op.translate.y);
24006
+ return { ...op, translate: { x: local.x, y: local.y } };
24007
+ }
24008
+ case "scaleByRelativeTo":
24009
+ case "scaleToRelativeTo": {
24010
+ const pt = new Point(op.point.x, op.point.y);
24011
+ containerMatrix.getInverse().apply(pt);
24012
+ return { ...op, point: pt };
24013
+ }
24014
+ case "transformMany": {
24015
+ if (!itemId || !op.items[itemId])
24016
+ return op;
24017
+ const subOp = op.items[itemId];
24018
+ const localSubOp = toLocalTransformOp(subOp, containerMatrix);
24019
+ return { ...op, items: { ...op.items, [itemId]: localSubOp } };
24020
+ }
24021
+ default:
24022
+ return op;
24023
+ }
24024
+ }
24025
+
23921
24026
  class BaseItem extends Mbr {
23922
24027
  defaultItemData;
23923
24028
  transformation;
@@ -23962,6 +24067,16 @@ class BaseItem extends Mbr {
23962
24067
  getId() {
23963
24068
  return this.id;
23964
24069
  }
24070
+ getWorldMatrix() {
24071
+ if (this.parent === "Board") {
24072
+ return this.transformation.toMatrix();
24073
+ }
24074
+ const container = this.board.items.getById(this.parent);
24075
+ if (!container) {
24076
+ return this.transformation.toMatrix();
24077
+ }
24078
+ return this.transformation.toMatrix().composeWith(container.getWorldMatrix());
24079
+ }
23965
24080
  setId(id) {
23966
24081
  this.id = id;
23967
24082
  this.transformation.setId(id);
@@ -24036,16 +24151,35 @@ class BaseItem extends Mbr {
24036
24151
  getMbr() {
24037
24152
  return new Mbr(this.left, this.top, this.right, this.bottom);
24038
24153
  }
24154
+ getWorldMbr() {
24155
+ if (this.parent === "Board" || !this.parent || !this.board?.items) {
24156
+ return this.getMbr();
24157
+ }
24158
+ const worldMatrix = this.getWorldMatrix();
24159
+ const local = this.getMbr();
24160
+ const corners = [
24161
+ new Point(local.left, local.top),
24162
+ new Point(local.right, local.top),
24163
+ new Point(local.right, local.bottom),
24164
+ new Point(local.left, local.bottom)
24165
+ ];
24166
+ for (const c of corners)
24167
+ worldMatrix.apply(c);
24168
+ return new Mbr(Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x), Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y), Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x), Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y));
24169
+ }
24039
24170
  applyAddChildren(childIds) {
24040
24171
  if (!this.index) {
24041
24172
  return;
24042
24173
  }
24174
+ const containerWorldMatrix = this.getWorldMatrix();
24043
24175
  childIds.forEach((childId) => {
24044
24176
  const foundItem = this.board.items.getById(childId);
24045
24177
  if (this.parent !== childId && this.getId() !== childId) {
24046
24178
  if (!this.index?.getById(childId) && foundItem) {
24179
+ const localMatrix = foundItem.transformation.toMatrix().toLocalOf(containerWorldMatrix);
24047
24180
  this.board.items.index.remove(foundItem);
24048
24181
  foundItem.parent = this.getId();
24182
+ foundItem.transformation.setLocalMatrix(localMatrix);
24049
24183
  this.index?.insert(foundItem);
24050
24184
  }
24051
24185
  }
@@ -24058,12 +24192,15 @@ class BaseItem extends Mbr {
24058
24192
  if (!this.index) {
24059
24193
  return;
24060
24194
  }
24195
+ const containerWorldMatrix = this.getWorldMatrix();
24061
24196
  childIds.forEach((childId) => {
24062
24197
  const foundItem = this.index?.getById(childId);
24063
24198
  if (this.parent !== childId && this.getId() !== childId) {
24064
24199
  if (foundItem) {
24200
+ const worldMatrix = foundItem.transformation.toMatrix().composeWith(containerWorldMatrix);
24065
24201
  this.index?.remove(foundItem);
24066
24202
  foundItem.parent = "Board";
24203
+ foundItem.transformation.setLocalMatrix(worldMatrix);
24067
24204
  this.board.items.index.insert(foundItem);
24068
24205
  }
24069
24206
  }
@@ -24175,9 +24312,17 @@ class BaseItem extends Mbr {
24175
24312
  apply(op) {
24176
24313
  op = op;
24177
24314
  switch (op.class) {
24178
- case "Transformation":
24179
- this.transformation.apply(op);
24315
+ case "Transformation": {
24316
+ let transformOp = op;
24317
+ if (this.parent !== "Board") {
24318
+ const container = this.board.items.getById(this.parent);
24319
+ if (container?.transformation) {
24320
+ transformOp = toLocalTransformOp(transformOp, container.getWorldMatrix(), this.id);
24321
+ }
24322
+ }
24323
+ this.transformation.apply(transformOp);
24180
24324
  break;
24325
+ }
24181
24326
  case "LinkTo":
24182
24327
  this.linkTo.apply(op);
24183
24328
  break;
@@ -38983,14 +39128,20 @@ function getControlPoint(data, findItem2) {
38983
39128
  }
38984
39129
  }
38985
39130
  }
39131
+ function getItemWorldMatrix(item) {
39132
+ if (item instanceof BaseItem && item.parent !== "Board") {
39133
+ return item.getWorldMatrix();
39134
+ }
39135
+ return item.transformation?.toMatrix() ?? new Matrix;
39136
+ }
38986
39137
  function toRelativePoint(point5, item) {
38987
- const inverse = item.transformation ? item.transformation.getInverse().toMatrix() : new Matrix;
39138
+ const inverse = getItemWorldMatrix(item).getInverse();
38988
39139
  point5 = point5.copy();
38989
39140
  point5.transform(inverse);
38990
39141
  return point5;
38991
39142
  }
38992
39143
  function fromRelativePoint(relativePoint, item, edge) {
38993
- const matrix = item.transformation?.toMatrix() ?? new Matrix;
39144
+ const matrix = getItemWorldMatrix(item);
38994
39145
  const point5 = relativePoint.copy();
38995
39146
  point5.transform(matrix);
38996
39147
  if (item instanceof RichText || item instanceof AINode) {
@@ -43465,7 +43616,13 @@ class Frame2 extends BaseItem {
43465
43616
  return;
43466
43617
  }
43467
43618
  this.renderPath(context);
43468
- super.render(context);
43619
+ const ctx = context.ctx;
43620
+ ctx.save();
43621
+ this.transformation.applyToContext(ctx);
43622
+ for (const child of this.index.list()) {
43623
+ child.render(context);
43624
+ }
43625
+ ctx.restore();
43469
43626
  this.renderBorders(context);
43470
43627
  this.renderName(context);
43471
43628
  }
@@ -45573,25 +45730,24 @@ function douglasPeucker(points, epsilon2) {
45573
45730
  // src/Items/Group/Group.ts
45574
45731
  class Group extends BaseItem {
45575
45732
  events;
45576
- children;
45577
45733
  linkTo;
45578
45734
  itemType = "Group";
45579
45735
  parent = "Board";
45580
45736
  transformation;
45581
45737
  subject = new Subject;
45582
- mbr = new Mbr;
45583
45738
  transformationRenderBlock = undefined;
45584
45739
  constructor(board, events, children = [], id = "") {
45585
- super(board, id);
45740
+ super(board, id, undefined, true);
45586
45741
  this.events = events;
45587
- this.children = children;
45588
45742
  this.linkTo = new LinkTo(this.id, this.events);
45589
45743
  this.transformation = new Transformation(this.id, this.events);
45590
- this.children = children;
45591
45744
  this.transformation.subject.subscribe(() => {
45592
45745
  this.updateMbr();
45593
45746
  this.subject.publish(this);
45594
45747
  });
45748
+ if (children.length > 0) {
45749
+ this.applyAddChildren(children);
45750
+ }
45595
45751
  }
45596
45752
  isClosed() {
45597
45753
  return false;
@@ -45599,45 +45755,17 @@ class Group extends BaseItem {
45599
45755
  getRichText() {
45600
45756
  return null;
45601
45757
  }
45602
- addChild(childId) {
45603
- this.emit({
45604
- class: "Group",
45605
- method: "addChild",
45606
- item: [this.getId()],
45607
- childId
45608
- });
45609
- }
45610
- applyAddChild(childId) {
45611
- if (!this.children.includes(childId)) {
45612
- this.children.push(childId);
45613
- this.updateMbr();
45614
- this.subject.publish(this);
45615
- }
45616
- }
45617
- applyRemoveChild(childId) {
45618
- this.children = this.children.filter((currChild) => currChild !== childId);
45619
- this.updateMbr();
45620
- this.subject.publish(this);
45621
- }
45622
- removeChild(childId) {
45623
- this.emit({
45624
- class: "Group",
45625
- method: "removeChild",
45626
- item: [this.getId()],
45627
- childId
45628
- });
45629
- }
45630
- emitRemoveChild(child) {
45631
- this.removeChild(child.getId());
45632
- child.parent = "Board";
45633
- }
45634
45758
  apply(op) {
45635
45759
  switch (op.class) {
45636
45760
  case "Group":
45637
45761
  if (op.method === "addChild") {
45638
- this.applyAddChild(op.childId);
45762
+ this.applyAddChildren([op.childId]);
45639
45763
  } else if (op.method === "removeChild") {
45640
- this.applyRemoveChild(op.childId);
45764
+ this.applyRemoveChildren([op.childId]);
45765
+ } else if (op.method === "addChildren") {
45766
+ this.applyAddChildren(op.newData.childIds);
45767
+ } else if (op.method === "removeChildren") {
45768
+ this.applyRemoveChildren(op.newData.childIds);
45641
45769
  }
45642
45770
  break;
45643
45771
  case "Transformation":
@@ -45662,24 +45790,69 @@ class Group extends BaseItem {
45662
45790
  this.transformation.setId(id);
45663
45791
  return this;
45664
45792
  }
45793
+ getMbr() {
45794
+ const children = this.index.list();
45795
+ if (children.length === 0) {
45796
+ return new Mbr(this.left, this.top, this.right, this.bottom);
45797
+ }
45798
+ const groupWorldMatrix = this.getWorldMatrix();
45799
+ let left = Number.MAX_SAFE_INTEGER;
45800
+ let top = Number.MAX_SAFE_INTEGER;
45801
+ let right = Number.MIN_SAFE_INTEGER;
45802
+ let bottom = Number.MIN_SAFE_INTEGER;
45803
+ for (const child of children) {
45804
+ const childLocalMbr = child.getMbr();
45805
+ const corners = [
45806
+ { x: childLocalMbr.left, y: childLocalMbr.top },
45807
+ { x: childLocalMbr.right, y: childLocalMbr.top },
45808
+ { x: childLocalMbr.right, y: childLocalMbr.bottom },
45809
+ { x: childLocalMbr.left, y: childLocalMbr.bottom }
45810
+ ];
45811
+ for (const corner of corners) {
45812
+ groupWorldMatrix.apply(corner);
45813
+ if (corner.x < left)
45814
+ left = corner.x;
45815
+ if (corner.y < top)
45816
+ top = corner.y;
45817
+ if (corner.x > right)
45818
+ right = corner.x;
45819
+ if (corner.y > bottom)
45820
+ bottom = corner.y;
45821
+ }
45822
+ }
45823
+ const mbr = new Mbr(left, top, right, bottom);
45824
+ this.left = left;
45825
+ this.top = top;
45826
+ this.right = right;
45827
+ this.bottom = bottom;
45828
+ return mbr;
45829
+ }
45830
+ updateMbr() {
45831
+ this.getMbr();
45832
+ }
45833
+ getChildrenIds() {
45834
+ return this.index.list().map((item) => item.getId());
45835
+ }
45836
+ getChildren() {
45837
+ return this.index.list();
45838
+ }
45839
+ getLinkTo() {
45840
+ return this.linkTo.link;
45841
+ }
45665
45842
  serialize() {
45666
45843
  return {
45667
45844
  itemType: "Group",
45668
- children: this.children,
45845
+ children: this.getChildrenIds(),
45669
45846
  transformation: this.transformation.serialize()
45670
45847
  };
45671
45848
  }
45672
45849
  deserialize(data) {
45673
- if (data.children) {
45674
- data.children.forEach((childId) => {
45675
- this.applyAddChild(childId);
45676
- const item = this.board.items.getById(childId);
45677
- if (item) {
45678
- item.parent = this.getId();
45679
- }
45680
- });
45850
+ if (data.transformation) {
45851
+ this.transformation.deserialize(data.transformation);
45852
+ }
45853
+ if (data.children && data.children.length > 0) {
45854
+ this.applyAddChildren(data.children);
45681
45855
  }
45682
- this.transformation.deserialize(data.transformation);
45683
45856
  this.subject.publish(this);
45684
45857
  return this;
45685
45858
  }
@@ -45689,99 +45862,25 @@ class Group extends BaseItem {
45689
45862
  getIntersectionPoints(segment) {
45690
45863
  const lines = this.getMbr().getLines();
45691
45864
  const initPoints = [];
45692
- const points = lines.reduce((acc, line) => {
45865
+ return lines.reduce((acc, line) => {
45693
45866
  const intersections = line.getIntersectionPoints(segment);
45694
45867
  if (intersections.length > 0) {
45695
45868
  acc.push(...intersections);
45696
45869
  }
45697
45870
  return acc;
45698
45871
  }, initPoints);
45699
- return points;
45700
- }
45701
- getMbr() {
45702
- const mbr = new Mbr;
45703
- let left = Number.MAX_SAFE_INTEGER;
45704
- let top = Number.MAX_SAFE_INTEGER;
45705
- let right = Number.MIN_SAFE_INTEGER;
45706
- let bottom = Number.MIN_SAFE_INTEGER;
45707
- const mbrs = this.children.flatMap((childId) => {
45708
- const item = this.board.items.getById(childId);
45709
- if (!item) {
45710
- return [];
45711
- }
45712
- const mbr2 = item.getMbr();
45713
- if (!mbr2) {
45714
- return [];
45715
- }
45716
- if (left > mbr2.left) {
45717
- left = mbr2.left;
45718
- }
45719
- if (top > mbr2.top) {
45720
- top = mbr2.top;
45721
- }
45722
- if (right < mbr2.right) {
45723
- right = mbr2.right;
45724
- }
45725
- if (bottom < mbr2.bottom) {
45726
- bottom = mbr2.bottom;
45727
- }
45728
- return [mbr2];
45729
- });
45730
- if (mbrs.length) {
45731
- mbr.combine(mbrs);
45732
- mbr.left = left !== Number.MAX_SAFE_INTEGER ? left : 0;
45733
- mbr.top = top !== Number.MAX_SAFE_INTEGER ? top : 0;
45734
- mbr.right = right !== Number.MIN_SAFE_INTEGER ? right : 0;
45735
- mbr.bottom = bottom !== Number.MIN_SAFE_INTEGER ? bottom : 0;
45736
- this.left = mbr.left;
45737
- this.bottom = mbr.bottom;
45738
- this.right = mbr.right;
45739
- this.top = mbr.top;
45740
- }
45741
- return mbr;
45742
- }
45743
- getChildrenIds() {
45744
- return this.children;
45745
- }
45746
- getChildren() {
45747
- return this.children.map((itemId) => this.board.items.getById(itemId)).filter((item) => item !== undefined);
45748
- }
45749
- updateMbr() {
45750
- const rect = this.getMbr();
45751
- this.mbr = rect;
45752
- this.mbr.borderColor = "transparent";
45753
- }
45754
- setBoard(board) {
45755
- this.board = board;
45756
- }
45757
- setChildren(items) {
45758
- items.forEach((itemId) => {
45759
- this.addChild(itemId);
45760
- const item = this.board.items.getById(itemId);
45761
- if (item) {
45762
- item.parent = this.getId();
45763
- }
45764
- });
45765
- this.updateMbr();
45766
- }
45767
- removeChildren() {
45768
- this.children.forEach((itemId) => {
45769
- this.removeChild(itemId);
45770
- const item = this.board.items.getById(itemId);
45771
- if (item) {
45772
- item.parent = this.parent;
45773
- }
45774
- });
45775
- this.updateMbr();
45776
- }
45777
- getLinkTo() {
45778
- return this.linkTo.link;
45779
45872
  }
45780
45873
  render(context) {
45781
45874
  if (this.transformationRenderBlock) {
45782
45875
  return;
45783
45876
  }
45784
- this.mbr.render(context);
45877
+ const ctx = context.ctx;
45878
+ ctx.save();
45879
+ this.transformation.applyToContext(ctx);
45880
+ for (const child of this.index.list()) {
45881
+ child.render(context);
45882
+ }
45883
+ ctx.restore();
45785
45884
  }
45786
45885
  renderHTML(documentFactory) {
45787
45886
  return documentFactory.createElement("div");
@@ -46213,7 +46312,7 @@ class ConnectorSnap {
46213
46312
  }
46214
46313
  }
46215
46314
  getNearest() {
46216
- const neighbors = this.board.items.getNearPointer(this.distance.neighbor / this.board.camera.getScale(), this.maxNeighbors);
46315
+ const neighbors = this.board.items.getNearPointer(this.distance.border / this.board.camera.getScale(), this.maxNeighbors);
46217
46316
  const pointer = this.board.pointer.point;
46218
46317
  let nearest = null;
46219
46318
  let nearestDistance = Number.MAX_VALUE;
@@ -48498,13 +48597,13 @@ class AlignmentHelper {
48498
48597
  return baseThickness / (zoom / 100);
48499
48598
  }
48500
48599
  combineMBRs(items) {
48600
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
48501
48601
  return items.reduce((acc, item, i) => {
48502
48602
  if (i === 0) {
48503
48603
  return acc;
48504
48604
  }
48505
- const itemMbr = item.getPathMbr();
48506
- return acc.combine(itemMbr);
48507
- }, items[0].getMbr());
48605
+ return acc.combine(worldMbr(item));
48606
+ }, worldMbr(items[0]));
48508
48607
  }
48509
48608
  checkAlignment(movingItem, excludeItems = []) {
48510
48609
  if (!Array.isArray(movingItem) && movingItem.itemType === "Comment") {
@@ -54198,8 +54297,9 @@ class SelectionItems {
54198
54297
  if (items.length === 0) {
54199
54298
  return;
54200
54299
  }
54201
- const mbr = items[0].getMbr();
54202
- items.slice(1).forEach((item) => mbr.combine(item.getMbr()));
54300
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
54301
+ const mbr = worldMbr(items[0]);
54302
+ items.slice(1).forEach((item) => mbr.combine(worldMbr(item)));
54203
54303
  return mbr;
54204
54304
  }
54205
54305
  }
@@ -54408,18 +54508,27 @@ function handleMultipleItemsResize({
54408
54508
  }) {
54409
54509
  const { matrix } = resize;
54410
54510
  const result = [];
54411
- const items = itemsToResize ? itemsToResize : board.selection.items.list();
54511
+ const rawItems = itemsToResize ? itemsToResize : board.selection.items.list();
54412
54512
  board.items.getComments().forEach((comment2) => {
54413
- if (items.some((item) => item.getId() === comment2.getItemToFollow())) {
54414
- items.push(comment2);
54513
+ if (rawItems.some((item) => item.getId() === comment2.getItemToFollow())) {
54514
+ rawItems.push(comment2);
54415
54515
  }
54416
54516
  });
54517
+ const selectedIds = new Set(rawItems.map((i) => i.getId()));
54518
+ const items = rawItems.filter((item) => item.parent === "Board" || !selectedIds.has(item.parent));
54417
54519
  for (const item of items) {
54418
- let itemX = item.getMbr().left;
54419
- let itemY = item.getMbr().top;
54520
+ const worldMbr = item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
54521
+ let itemX = worldMbr.left;
54522
+ let itemY = worldMbr.top;
54420
54523
  if (item.itemType === "Drawing") {
54421
- itemX = item.transformation.getMatrixData().translateX;
54422
- itemY = item.transformation.getMatrixData().translateY;
54524
+ if (item instanceof BaseItem && item.parent !== "Board") {
54525
+ const worldMatrix = item.getWorldMatrix();
54526
+ itemX = worldMatrix.translateX;
54527
+ itemY = worldMatrix.translateY;
54528
+ } else {
54529
+ itemX = item.transformation.getMatrixData().translateX;
54530
+ itemY = item.transformation.getMatrixData().translateY;
54531
+ }
54423
54532
  }
54424
54533
  const deltaX = itemX - initMbr.left;
54425
54534
  const translateX = deltaX * matrix.scaleX - deltaX + matrix.translateX;
@@ -55343,10 +55452,6 @@ class BoardSelection {
55343
55452
  if (!this.board.events) {
55344
55453
  return;
55345
55454
  }
55346
- if (operation.method === "transformMany") {
55347
- console.error("[DEBUG] transformMany emitted!", JSON.stringify(operation));
55348
- console.trace("[DEBUG] transformMany stack trace");
55349
- }
55350
55455
  const command = createCommand(this.board, operation);
55351
55456
  command.apply();
55352
55457
  this.board.events.emit(operation, command);
@@ -55889,17 +55994,12 @@ class BoardSelection {
55889
55994
  const addItem = (itemId) => {
55890
55995
  items.push({ id: itemId, matrix: { translateX: x, translateY: y, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 } });
55891
55996
  };
55892
- const tryToAddFrameChildren = (selectedItem) => {
55893
- if (!("index" in selectedItem) || !selectedItem.index) {
55997
+ const selectedIds = new Set(unselectedItem ? [unselectedItem.getId()] : this.board.selection.list().map((i) => i.getId()));
55998
+ const addWithComments = (item) => {
55999
+ if (item.parent !== "Board" && selectedIds.has(item.parent)) {
55894
56000
  return;
55895
56001
  }
55896
- for (const childId of selectedItem.getChildrenIds()) {
55897
- addItem(childId);
55898
- }
55899
- };
55900
- const addWithComments = (item) => {
55901
56002
  addItem(item.getId());
55902
- tryToAddFrameChildren(item);
55903
56003
  const followedComments = this.board.items.getComments().filter((comment2) => comment2.getItemToFollow() === item.getId());
55904
56004
  for (const comment2 of followedComments) {
55905
56005
  addItem(comment2.getId());
@@ -56731,6 +56831,28 @@ class Board {
56731
56831
  item: [item.getId()]
56732
56832
  });
56733
56833
  }
56834
+ group(items) {
56835
+ const id = this.getNewItemId();
56836
+ const groupData = {
56837
+ itemType: "Group",
56838
+ children: items.map((i) => i.getId()),
56839
+ transformation: { translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 }
56840
+ };
56841
+ this.emit({
56842
+ class: "Board",
56843
+ method: "addLockedGroup",
56844
+ item: id,
56845
+ data: groupData
56846
+ });
56847
+ return this.items.getById(id);
56848
+ }
56849
+ ungroup(group) {
56850
+ this.emit({
56851
+ class: "Board",
56852
+ method: "removeLockedGroup",
56853
+ item: [group.getId()]
56854
+ });
56855
+ }
56734
56856
  getByZIndex(index2) {
56735
56857
  return this.index.getByZIndex(index2);
56736
56858
  }