@crystaldesign/web-planner-logic 26.11.0-beta.2 → 26.11.0-beta.21

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.
Files changed (108) hide show
  1. package/build/cjs/{DivaBoxPlanner-68cc1bd1.js → DivaBoxPlanner-051e3b01.js} +134 -47
  2. package/build/cjs/{DivaStandardPlanner-d44ae0e7.js → DivaStandardPlanner-40846a4f.js} +340 -190
  3. package/build/cjs/{DoorPlanner-1719cbe1.js → DoorPlanner-51477bb2.js} +3 -1
  4. package/build/cjs/{Host3DSignalR-a456221e.js → Host3DSignalR-72511b72.js} +41 -24
  5. package/build/cjs/{LiviqueWWSHandler-f2afb4eb.js → LiviqueWWSHandler-fbfeeb05.js} +3 -1
  6. package/build/cjs/{PfisterWWSHandler-8f522ab6.js → PfisterWWSHandler-a7ac983b.js} +3 -1
  7. package/build/cjs/PlannerHandler2D-e2c83aec.js +544 -0
  8. package/build/cjs/{SeriousBasketHandler-b39f0556.js → SeriousBasketHandler-60853c54.js} +3 -1
  9. package/build/cjs/{ShelfPlanner-1dde2d7c.js → ShelfPlanner-a901f6da.js} +262 -148
  10. package/build/cjs/{StandardWWSHandler-62ec343d.js → StandardWWSHandler-3a8a3685.js} +3 -1
  11. package/build/cjs/{index-d63749e4.js → index-7d87a838.js} +15132 -13899
  12. package/build/cjs/index.js +13 -2
  13. package/build/esm/{DivaBoxPlanner-a347ef5d.js → DivaBoxPlanner-a76550ee.js} +134 -47
  14. package/build/esm/{DivaStandardPlanner-a8f0d722.js → DivaStandardPlanner-56c260dc.js} +339 -190
  15. package/build/esm/{DoorPlanner-60c065e5.js → DoorPlanner-a40a4342.js} +3 -1
  16. package/build/esm/{Host3DSignalR-0c7e84a7.js → Host3DSignalR-6f824d99.js} +41 -24
  17. package/build/esm/{LiviqueWWSHandler-3df03404.js → LiviqueWWSHandler-2f1189d0.js} +3 -1
  18. package/build/esm/{PfisterWWSHandler-28b609ef.js → PfisterWWSHandler-81238c20.js} +3 -1
  19. package/build/esm/PlannerHandler2D-d93ae013.js +526 -0
  20. package/build/esm/{SeriousBasketHandler-276a8035.js → SeriousBasketHandler-bca9210d.js} +3 -1
  21. package/build/esm/{ShelfPlanner-7380b831.js → ShelfPlanner-539f1b08.js} +262 -148
  22. package/build/esm/{StandardWWSHandler-1d13f6a3.js → StandardWWSHandler-cdc4c837.js} +3 -1
  23. package/build/esm/{index-358c0a3c.js → index-b755400a.js} +15128 -13899
  24. package/build/esm/index.js +3 -1
  25. package/build/types/web-planner-logic/src/index.d.ts +8 -3
  26. package/build/types/web-planner-logic/src/index.d.ts.map +1 -1
  27. package/build/types/web-planner-logic/src/interface/Articles/ArticleDataType.d.ts +13 -0
  28. package/build/types/web-planner-logic/src/interface/Articles/ArticleDataType.d.ts.map +1 -1
  29. package/build/types/web-planner-logic/src/interface/Articles/ArticleInfoType.d.ts +13 -0
  30. package/build/types/web-planner-logic/src/interface/Articles/ArticleInfoType.d.ts.map +1 -1
  31. package/build/types/web-planner-logic/src/interface/Articles/CatalogArticleDataType.d.ts +3 -0
  32. package/build/types/web-planner-logic/src/interface/Articles/CatalogArticleDataType.d.ts.map +1 -1
  33. package/build/types/web-planner-logic/src/interface/DivaCatalogDataType.d.ts +5 -0
  34. package/build/types/web-planner-logic/src/interface/DivaCatalogDataType.d.ts.map +1 -1
  35. package/build/types/web-planner-logic/src/interface/IDM/ArticleApi.d.ts +19 -18
  36. package/build/types/web-planner-logic/src/interface/IDM/ArticleApi.d.ts.map +1 -1
  37. package/build/types/web-planner-logic/src/interface/Planner/ISaveSetPlanner.d.ts +37 -0
  38. package/build/types/web-planner-logic/src/interface/Planner/ISaveSetPlanner.d.ts.map +1 -1
  39. package/build/types/web-planner-logic/src/interface/ShelfPlanner/ShelfAccessoiresView.d.ts +5 -0
  40. package/build/types/web-planner-logic/src/interface/ShelfPlanner/ShelfAccessoiresView.d.ts.map +1 -1
  41. package/build/types/web-planner-logic/src/interface/webPlannerParams/WebPlannerParamsType.d.ts +46 -2
  42. package/build/types/web-planner-logic/src/interface/webPlannerParams/WebPlannerParamsType.d.ts.map +1 -1
  43. package/build/types/web-planner-logic/src/logic/Article/DivaArticle.d.ts.map +1 -1
  44. package/build/types/web-planner-logic/src/logic/Article/Engine/ArticleEngine.d.ts +4 -0
  45. package/build/types/web-planner-logic/src/logic/Article/Engine/ArticleEngine.d.ts.map +1 -1
  46. package/build/types/web-planner-logic/src/logic/Article/Engine/IDMArticleEngine.d.ts +12 -2
  47. package/build/types/web-planner-logic/src/logic/Article/Engine/IDMArticleEngine.d.ts.map +1 -1
  48. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlanner.d.ts +20 -0
  49. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlanner.d.ts.map +1 -1
  50. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlannerGrid.d.ts +31 -1
  51. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlannerGrid.d.ts.map +1 -1
  52. package/build/types/web-planner-logic/src/logic/DivaApiHandler.d.ts +25 -0
  53. package/build/types/web-planner-logic/src/logic/DivaApiHandler.d.ts.map +1 -1
  54. package/build/types/web-planner-logic/src/logic/DivaCatalogHandler.d.ts +1 -0
  55. package/build/types/web-planner-logic/src/logic/DivaCatalogHandler.d.ts.map +1 -1
  56. package/build/types/web-planner-logic/src/logic/DivaWebPlanner.d.ts +149 -95
  57. package/build/types/web-planner-logic/src/logic/DivaWebPlanner.d.ts.map +1 -1
  58. package/build/types/web-planner-logic/src/logic/Planner/BoxPlanner/ConstructionRulesHandler.d.ts +19 -0
  59. package/build/types/web-planner-logic/src/logic/Planner/BoxPlanner/ConstructionRulesHandler.d.ts.map +1 -1
  60. package/build/types/web-planner-logic/src/logic/Planner/BoxPlanner/DivaBoxPlanner.d.ts +15 -1
  61. package/build/types/web-planner-logic/src/logic/Planner/BoxPlanner/DivaBoxPlanner.d.ts.map +1 -1
  62. package/build/types/web-planner-logic/src/logic/Planner/DivaPlannerHandler.d.ts +11 -1
  63. package/build/types/web-planner-logic/src/logic/Planner/DivaPlannerHandler.d.ts.map +1 -1
  64. package/build/types/web-planner-logic/src/logic/Planner/DivaStandardPlanner.d.ts +28 -1
  65. package/build/types/web-planner-logic/src/logic/Planner/DivaStandardPlanner.d.ts.map +1 -1
  66. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/DockingPointHandler.d.ts +9 -114
  67. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/DockingPointHandler.d.ts.map +1 -1
  68. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/PlannerHandler2D.d.ts +5 -7
  69. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/PlannerHandler2D.d.ts.map +1 -1
  70. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/SVGUtils.d.ts +5 -6
  71. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/SVGUtils.d.ts.map +1 -1
  72. package/build/types/web-planner-logic/src/logic/Planner/Rendering/Host3DSignalR.d.ts.map +1 -1
  73. package/build/types/web-planner-logic/src/logic/Planner/Rendering/PlannerHandler3D.d.ts +17 -1
  74. package/build/types/web-planner-logic/src/logic/Planner/Rendering/PlannerHandler3D.d.ts.map +1 -1
  75. package/build/types/web-planner-logic/src/logic/Set/DivaSet.d.ts +2 -2
  76. package/build/types/web-planner-logic/src/logic/Set/DivaSet.d.ts.map +1 -1
  77. package/build/types/web-planner-logic/src/logic/Set/DivaSetHandler.d.ts +31 -3
  78. package/build/types/web-planner-logic/src/logic/Set/DivaSetHandler.d.ts.map +1 -1
  79. package/build/types/web-planner-logic/src/logic/Set/catalogXml/articleGeo.d.ts +9 -0
  80. package/build/types/web-planner-logic/src/logic/Set/catalogXml/articleGeo.d.ts.map +1 -0
  81. package/build/types/web-planner-logic/src/logic/Set/catalogXml/parseCatalogXml.d.ts +12 -0
  82. package/build/types/web-planner-logic/src/logic/Set/catalogXml/parseCatalogXml.d.ts.map +1 -0
  83. package/build/types/web-planner-logic/src/logic/Set/catalogXml/types.d.ts +66 -0
  84. package/build/types/web-planner-logic/src/logic/Set/catalogXml/types.d.ts.map +1 -0
  85. package/build/types/web-planner-logic/src/logic/bootMark.d.ts +71 -0
  86. package/build/types/web-planner-logic/src/logic/bootMark.d.ts.map +1 -0
  87. package/build/types/web-planner-logic/src/model/Articles/Article/CatalogArticleData.d.ts +1 -0
  88. package/build/types/web-planner-logic/src/model/Articles/Article/CatalogArticleData.d.ts.map +1 -1
  89. package/build/types/web-planner-logic/src/model/Articles/Article/IDMCatalogArticle.d.ts +11 -0
  90. package/build/types/web-planner-logic/src/model/Articles/Article/IDMCatalogArticle.d.ts.map +1 -1
  91. package/build/types/web-planner-logic/src/model/Catalog/CatalogData.d.ts +13 -0
  92. package/build/types/web-planner-logic/src/model/Catalog/CatalogData.d.ts.map +1 -1
  93. package/build/types/web-planner-logic/src/model/Catalog/IDMCatalogData.d.ts.map +1 -1
  94. package/build/types/web-planner-logic/src/model/Planner/DockingPoint.d.ts +1 -44
  95. package/build/types/web-planner-logic/src/model/Planner/DockingPoint.d.ts.map +1 -1
  96. package/build/types/web-planner-logic/src/model/Planner/PlannerElementData.d.ts +6 -1
  97. package/build/types/web-planner-logic/src/model/Planner/PlannerElementData.d.ts.map +1 -1
  98. package/build/types/web-planner-logic/src/test/engineFeatureDefaults.test.d.ts +2 -0
  99. package/build/types/web-planner-logic/src/test/engineFeatureDefaults.test.d.ts.map +1 -0
  100. package/build/types/web-planner-logic/src/test/idmPlannerPaletteView.test.d.ts +2 -0
  101. package/build/types/web-planner-logic/src/test/idmPlannerPaletteView.test.d.ts.map +1 -0
  102. package/build/types/web-planner-logic/src/test/parseSvgOltGeometry.test.d.ts +2 -0
  103. package/build/types/web-planner-logic/src/test/parseSvgOltGeometry.test.d.ts.map +1 -0
  104. package/build/types/web-planner-logic/src/test/stretchGoldenMaster.test.d.ts +2 -0
  105. package/build/types/web-planner-logic/src/test/stretchGoldenMaster.test.d.ts.map +1 -0
  106. package/package.json +5 -5
  107. package/build/cjs/PlannerHandler2D-dbe1d858.js +0 -2470
  108. package/build/esm/PlannerHandler2D-f8657005.js +0 -2455
@@ -1,26 +1,47 @@
1
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
1
2
  import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
2
3
  import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
3
4
  import _createClass from '@babel/runtime/helpers/createClass';
4
5
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
5
6
  import _regeneratorRuntime from '@babel/runtime/regenerator';
6
- import { V as Vector3, c as Vector2, P as PlannerElementData, B as BoundingBox } from './index-358c0a3c.js';
7
+ import { V as Vector3, P as PlannerElementData, B as BoundingBox } from './index-b755400a.js';
7
8
  import DivaUtils, { DivaError, md5 } from '@crystaldesign/diva-utils';
8
- import { d as dockingPointHandlerInst, h as handler2D } from './PlannerHandler2D-f8657005.js';
9
+ import { computeDockedTransform } from '@crystaldesign/planner-2d-core';
10
+ import { d as dockingPointHandlerInst, h as handler2D } from './PlannerHandler2D-d93ae013.js';
9
11
  import '@babel/runtime/helpers/slicedToArray';
10
12
  import '@babel/runtime/helpers/objectWithoutProperties';
11
- import '@babel/runtime/helpers/toConsumableArray';
12
13
  import 'axios';
13
14
  import '@crystaldesign/basket-model';
14
15
  import '@babel/runtime/helpers/typeof';
16
+ import 'fast-xml-parser';
15
17
  import '@babel/runtime/helpers/possibleConstructorReturn';
16
18
  import '@babel/runtime/helpers/getPrototypeOf';
17
19
  import '@babel/runtime/helpers/inherits';
18
20
  import '@babel/runtime/helpers/wrapNativeSuper';
19
21
  import '@crystaldesign/basket-handler';
20
22
  import 'socket.io-client';
21
- import 'fabric';
22
- import 'w3c-xmlserializer';
23
+ import '@babel/runtime/helpers/get';
23
24
 
25
+ /** Configurator 2.0 set planner payload (`SetPlanData` after base64 decode). */
26
+
27
+ /** Legacy planner 1.x payload (no `v: 2` wrapper). */
28
+
29
+ function parseSetPlanData(setPlanData) {
30
+ var planDataString = DivaUtils.decodeBase64(setPlanData);
31
+ return JSON.parse(planDataString);
32
+ }
33
+ function isSavePlannerV2(planData) {
34
+ return planData.v === 2;
35
+ }
36
+
37
+ /** Article codex from a V2 or legacy element record. */
38
+ function saveElementArticleCodex(element) {
39
+ return element.articleCodex || element.Codex;
40
+ }
41
+
42
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
43
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
44
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
24
45
  var LOG = DivaUtils.initLog('Planner', 'WEB-PLANNER-LOGIC');
25
46
  var ACC_DOCK_TYPES = ['AVO', 'AVU', 'AVC', 'AVS', 'AVN'];
26
47
  var DivaStandardPlanner = /*#__PURE__*/function () {
@@ -50,7 +71,13 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
50
71
  _defineProperty(this, "nextElementId", 1);
51
72
  _defineProperty(this, "collisionHandler", void 0);
52
73
  _defineProperty(this, "dockToAVUorAVOororAVNorAVSorAVC", function (plannerElement, targetElements) {
53
- if (plannerElement.HasAVU) {
74
+ // Capability comes from the SVG-parsed docking points, not the catalog metadata counts
75
+ // (countAV*): the parsed SVG is the same source the targeted dock (tryDockElementToDP) uses, so
76
+ // auto-dock stays consistent with it even when the catalog's SVG detail info misses the counts.
77
+ var hasFreeDP = function hasFreeDP(type) {
78
+ return plannerElement.getFreeDockingPointsByType(type).length > 0;
79
+ };
80
+ if (hasFreeDP('AVU')) {
54
81
  //Try to dock Element to free AVR
55
82
  var successDP = dockingPointHandlerInst.tryDockElement(plannerElement, 'AVU', targetElements);
56
83
  if (successDP) {
@@ -66,28 +93,28 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
66
93
  if (_successDP) return true;
67
94
  }
68
95
  }
69
- if (plannerElement.HasAVO) {
96
+ if (hasFreeDP('AVO')) {
70
97
  var _successDP2 = dockingPointHandlerInst.tryDockElement(plannerElement, 'AVO', targetElements);
71
98
  if (_successDP2) {
72
99
  _this.updateWorldPos(plannerElement, _successDP2);
73
100
  return true;
74
101
  }
75
102
  }
76
- if (plannerElement.HasAVN) {
103
+ if (hasFreeDP('AVN')) {
77
104
  var _successDP3 = dockingPointHandlerInst.tryDockElement(plannerElement, 'AVN', targetElements);
78
105
  if (_successDP3) {
79
106
  _this.updateWorldPos(plannerElement, _successDP3);
80
107
  return true;
81
108
  }
82
109
  }
83
- if (plannerElement.HasAVS) {
110
+ if (hasFreeDP('AVS')) {
84
111
  var _successDP4 = dockingPointHandlerInst.tryDockElement(plannerElement, 'AVS', targetElements);
85
112
  if (_successDP4) {
86
113
  _this.updateWorldPos(plannerElement, _successDP4);
87
114
  return true;
88
115
  }
89
116
  }
90
- if (plannerElement.HasAVC) {
117
+ if (hasFreeDP('AVC')) {
91
118
  var _successDP5 = dockingPointHandlerInst.tryDockElement(plannerElement, 'AVC', targetElements);
92
119
  if (_successDP5) {
93
120
  _this.updateWorldPos(plannerElement, _successDP5);
@@ -220,30 +247,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
220
247
  var refElement = this.plannerElements.get(dockingPoint.OnElementId);
221
248
  var refDockingPoint = refElement.getDockingPointById(dockingPoint.OnDP.DpId);
222
249
  if (refDockingPoint == undefined) return updateConfig;
223
- var worldPosNewElement = new Vector3(0, 0, 0);
224
- var worldPosNewElementIgnoreOLF = new Vector3(0, 0, 0);
225
-
226
- // DP LocalWorldPos is OLF-corner-relative when HasOLFPolygon (from SVG). Convert to OLT-corner-relative for WorldPosCornerIgnoreOLF.
227
- var refDPLocalOlt = refElement.HasOLFPolygon ? new Vector2(refDockingPoint.LocalWorldPos.x - refElement.getOltLeft(), refDockingPoint.LocalWorldPos.z - refElement.getOltTop()) : new Vector2(refDockingPoint.LocalWorldPos.x, refDockingPoint.LocalWorldPos.z);
228
- var newDPLocalOlt = plannerElement.HasOLFPolygon ? new Vector2(dockingPoint.LocalWorldPos.x - plannerElement.getOltLeft(), dockingPoint.LocalWorldPos.z - plannerElement.getOltTop()) : new Vector2(dockingPoint.LocalWorldPos.x, dockingPoint.LocalWorldPos.z);
229
- var rotatedLocalRefDP = new Vector2(refDockingPoint.LocalWorldPos.x, refDockingPoint.LocalWorldPos.z);
230
- rotatedLocalRefDP = Vector2.rotateOrigin(rotatedLocalRefDP, refElement.RotDeg);
231
- var angleToRot = refElement.RotDeg + refDockingPoint.RotDeg - dockingPoint.RotDeg;
232
- plannerElement.RotDeg = angleToRot;
233
- var refWorldPosCor = refElement.WorldPosCorner;
234
- // For ref without OLF: use same corner for both alignments (no OLF/OLT split; WorldPosCornerIgnoreOLF getter also does this).
235
- var refWorldPosCorIgnoreOLF = refElement.HasOLFPolygon ? refElement.WorldPosCornerIgnoreOLF : refWorldPosCor;
236
- var rotatedLocalDP2D = Vector2.rotateOrigin(new Vector2(dockingPoint.LocalWorldPos.x, dockingPoint.LocalWorldPos.z), angleToRot);
237
- worldPosNewElement.x = refWorldPosCor.x + rotatedLocalRefDP.x - rotatedLocalDP2D.x;
238
- worldPosNewElement.y = refWorldPosCor.y + refDockingPoint.LocalWorldPos.y - dockingPoint.LocalWorldPos.y;
239
- worldPosNewElement.z = refWorldPosCor.z + rotatedLocalRefDP.y - rotatedLocalDP2D.y;
240
- var rotatedRefDPOlt = Vector2.rotateOrigin(refDPLocalOlt, refElement.RotDeg);
241
- var rotatedNewDPOlt = Vector2.rotateOrigin(newDPLocalOlt, angleToRot);
242
- worldPosNewElementIgnoreOLF.x = refWorldPosCorIgnoreOLF.x + rotatedRefDPOlt.x - rotatedNewDPOlt.x;
243
- worldPosNewElementIgnoreOLF.z = refWorldPosCorIgnoreOLF.z + rotatedRefDPOlt.y - rotatedNewDPOlt.y;
244
- worldPosNewElementIgnoreOLF.y = refWorldPosCorIgnoreOLF.y + refDockingPoint.LocalWorldPos.y - dockingPoint.LocalWorldPos.y;
245
- plannerElement.WorldPosCorner = worldPosNewElement;
246
- plannerElement.WorldPosCornerIgnoreOLF = worldPosNewElementIgnoreOLF;
250
+ this.applyDockTransform(plannerElement, refElement, dockingPoint, refDockingPoint);
247
251
  updateConfig = this.set.onDockingChanged(plannerElement.ElementId, refElement.ElementId, 'DOCK', dockingPoint.Type);
248
252
  var data = this.set.getPlannerData(plannerElement.ElementId);
249
253
  plannerElement.updatePlannerData(data);
@@ -252,15 +256,81 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
252
256
  return updateConfig;
253
257
  }
254
258
 
259
+ /**
260
+ * Positions `plannerElement` so its `dockingPoint` aligns to `refElement`'s `refDockingPoint`
261
+ * (rotation + OLF/OLT-aware translation). Mutates only the element's world position and rotation —
262
+ * NOT the docking relations — so it is reusable for a non-committing snap preview
263
+ * ({@link getDockSnapPreview}) as well as the real dock ({@link updateWorldPos}).
264
+ */
265
+ }, {
266
+ key: "applyDockTransform",
267
+ value: function applyDockTransform(plannerElement, refElement, dockingPoint, refDockingPoint) {
268
+ var dockedTransform = computeDockedTransform(refElement, refDockingPoint, plannerElement, dockingPoint);
269
+ plannerElement.RotDeg = dockedTransform.rotDeg;
270
+ plannerElement.WorldPosCorner = new Vector3(dockedTransform.worldPosCorner.x, dockedTransform.worldPosCorner.y, dockedTransform.worldPosCorner.z);
271
+ plannerElement.WorldPosCornerIgnoreOLF = new Vector3(dockedTransform.worldPosCornerIgnoreOLF.x, dockedTransform.worldPosCornerIgnoreOLF.y, dockedTransform.worldPosCornerIgnoreOLF.z);
272
+ }
273
+
274
+ /**
275
+ * Non-committing preview of where `elementId` would auto-snap if released now: runs the same
276
+ * dockable-pair search as END, and for the closest pair computes the docked transform via
277
+ * {@link applyDockTransform} (apply → read → restore, no docking relations touched). Returns the
278
+ * delta from the element's current transform (cm / deg), or null if nothing is in snapping range.
279
+ * `excludeElementIds` skips the element's own move-group so it doesn't "snap" to siblings that
280
+ * are translating with it.
281
+ */
282
+ }, {
283
+ key: "getDockSnapPreview",
284
+ value: function getDockSnapPreview(elementId, autoDockingDistance) {
285
+ var excludeElementIds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
286
+ var element = this.plannerElements.get(elementId);
287
+ if (!element) return null;
288
+ var targets = this.getAllPlannerElements().filter(function (e) {
289
+ return e.getElementId() !== elementId && !excludeElementIds.includes(e.getElementId());
290
+ });
291
+ var pairs = dockingPointHandlerInst.searchDockableElementsInArea(element, targets, autoDockingDistance);
292
+ if (!pairs || pairs.size === 0) return null;
293
+ var best;
294
+ pairs.forEach(function (p) {
295
+ if (best == undefined || p.distance < best.distance) best = p;
296
+ });
297
+ if (best == undefined) return null;
298
+ var targetElement = this.plannerElements.get(best.targetDP.ElementId);
299
+ if (!targetElement) return null;
300
+ var savedRot = element.RotDeg;
301
+ var savedCenter = element.WorldPosCenter;
302
+ var savedX = savedCenter.x,
303
+ savedY = savedCenter.y,
304
+ savedZ = savedCenter.z;
305
+ this.applyDockTransform(element, targetElement, best.sourceDP, best.targetDP);
306
+ var snapped = element.WorldPosCenter;
307
+ var result = {
308
+ dx: snapped.x - savedX,
309
+ dz: snapped.z - savedZ,
310
+ dRotDeg: element.RotDeg - savedRot
311
+ };
312
+ // Restore — the preview must leave the planner state untouched.
313
+ element.RotDeg = savedRot;
314
+ element.WorldPosCenter = new Vector3(savedX, savedY, savedZ);
315
+ return result;
316
+ }
317
+
255
318
  /**
256
319
  * This function updates the position information of all elements. It is called after updating the SVG of 1 element.
257
320
  * The position is updated based on the posNr.
258
321
  * At the end - the collision is calculated
322
+ * @param changedElementIds elements whose SVG was reloaded this cycle (their docking geometry may
323
+ * have moved, e.g. an AVC shifted by stretch areas). Elements docked - directly or transitively -
324
+ * to one of them are re-anchored to the moved partner after the PosNr walk, which on its own only
325
+ * propagates forward in PosNr order and prefers AVL over AVC anchors.
259
326
  */
260
327
  }, {
261
328
  key: "updateAllElementsWorldPos",
262
- value: function updateAllElementsWorldPos(checkCollisionSingleElementId) {
329
+ value: function updateAllElementsWorldPos(checkCollisionSingleElementId, changedElementIds) {
263
330
  if (this.doDisablePlanner2D) return false;
331
+ var getDockedDPsInPriorityOrder = function getDockedDPsInPriorityOrder(element) {
332
+ return element.getDockingDockingPointsByType('AVL').concat(element.getDockingDockingPointsByType('AVR')).concat(element.getDockingDockingPointsByType('AVU')).concat(element.getDockingDockingPointsByType('AVO')).concat(element.getDockingDockingPointsByType('AVN')).concat(element.getDockingDockingPointsByType('AVS')).concat(element.getDockingDockingPointsByType('AVC'));
333
+ };
264
334
  var updateConfig = false;
265
335
  var sortedPlannerElementsbyPosNr = [];
266
336
  var accElems = [];
@@ -281,7 +351,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
281
351
  var element = sortedPlannerElementsbyPosNr[i];
282
352
  alreadyCorrectedId.push(element.ElementId);
283
353
  if (i > firstI) {
284
- var dockingPoints = element.getDockingDockingPointsByType('AVL').concat(element.getDockingDockingPointsByType('AVR')).concat(element.getDockingDockingPointsByType('AVU')).concat(element.getDockingDockingPointsByType('AVO')).concat(element.getDockingDockingPointsByType('AVN')).concat(element.getDockingDockingPointsByType('AVS')).concat(element.getDockingDockingPointsByType('AVC'));
354
+ var dockingPoints = getDockedDPsInPriorityOrder(element);
285
355
  for (var j = 0; j < dockingPoints.length; j++) {
286
356
  //Nur wenn er auf ein element schaut das schon gedockt ist korrigieren
287
357
  if (alreadyCorrectedId.indexOf(dockingPoints[j].OnElementId) >= 0) {
@@ -292,6 +362,38 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
292
362
  }
293
363
  }
294
364
  }
365
+
366
+ // The walk above anchors each element to its FIRST docked partner in AVL-first priority and
367
+ // only propagates forward in PosNr order - both hide a geometry change in a reloaded partner
368
+ // (e.g. an AVC line shifted by stretch areas). Sweep outward from the reloaded elements:
369
+ // re-anchor every element docked - directly or transitively - to a moved partner, until stable.
370
+ if (changedElementIds && changedElementIds.length > 0) {
371
+ var moved = new Set(changedElementIds);
372
+ var progressed = true;
373
+ while (progressed) {
374
+ progressed = false;
375
+ var _iterator = _createForOfIteratorHelper(sortedPlannerElementsbyPosNr),
376
+ _step;
377
+ try {
378
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
379
+ var _element = _step.value;
380
+ if (!_element || moved.has(_element.ElementId)) continue;
381
+ var dpToMovedPartner = getDockedDPsInPriorityOrder(_element).find(function (dp) {
382
+ return moved.has(dp.OnElementId);
383
+ });
384
+ if (dpToMovedPartner) {
385
+ updateConfig = this.updateWorldPos(_element, dpToMovedPartner) || updateConfig;
386
+ moved.add(_element.ElementId);
387
+ progressed = true;
388
+ }
389
+ }
390
+ } catch (err) {
391
+ _iterator.e(err);
392
+ } finally {
393
+ _iterator.f();
394
+ }
395
+ }
396
+ }
295
397
  this.checkCollision(false, checkCollisionSingleElementId);
296
398
  return updateConfig;
297
399
  }
@@ -778,7 +880,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
778
880
  elementsToDelete.push(elementsLostDockingRelation[i].ElementId);
779
881
  }
780
882
  }
781
- this.updateAllElementsWorldPos();
883
+ this.updateAllElementsWorldPos(undefined, elemtsWhereSomethingChanged);
782
884
  this.updatePlannerPosNr();
783
885
  this.updatePlannerBoundingBox();
784
886
  }
@@ -808,14 +910,13 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
808
910
  key: "extendPlanner",
809
911
  value: (function () {
810
912
  var _extendPlanner = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(setPlanData, globalBoundingBox) {
811
- var planDataString, planData, jsonElements, elementsSortedbyPosNr, accElements, oldElementidMapping, i, _jsonElement$Accessoi, jsonElement, catalogArticle, plannerElement, data, curElement, DPsInfo, j, dpInfo, sourceDP, targetElement, targetDP;
913
+ var planData, jsonElements, elementsSortedbyPosNr, accElements, oldElementidMapping, i, _saveElementArticleCo, _jsonElement$Accessoi, jsonElement, catalogArticle, plannerElement, data, elementsForDockingExtend, row, curElement, DPsInfo, j, dpInfo, sourceDP, targetElement, targetDP;
812
914
  return _regeneratorRuntime.wrap(function _callee4$(_context4) {
813
915
  while (1) switch (_context4.prev = _context4.next) {
814
916
  case 0:
815
- planDataString = DivaUtils.decodeBase64(setPlanData);
816
- planData = JSON.parse(planDataString);
817
- if (!(planData.v != null && planData.v == 2)) {
818
- _context4.next = 40;
917
+ planData = parseSetPlanData(setPlanData);
918
+ if (!isSavePlannerV2(planData)) {
919
+ _context4.next = 39;
819
920
  break;
820
921
  }
821
922
  jsonElements = planData.set.elements;
@@ -823,70 +924,70 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
823
924
  accElements = [];
824
925
  oldElementidMapping = new Map(); //First reset planner element values in jsonElement so that every set is planned to be set to origin
825
926
  i = 0;
826
- case 8:
927
+ case 7:
827
928
  if (!(i < jsonElements.length)) {
828
- _context4.next = 36;
929
+ _context4.next = 35;
829
930
  break;
830
931
  }
831
- _context4.prev = 9;
932
+ _context4.prev = 8;
832
933
  jsonElement = jsonElements[i];
833
- catalogArticle = this.set.CatalogData.getCatalogArticleByArticleCodex(jsonElement.articleCodex || jsonElement.Codex);
934
+ catalogArticle = this.set.CatalogData.getCatalogArticleByArticleCodex((_saveElementArticleCo = saveElementArticleCodex(jsonElement)) !== null && _saveElementArticleCo !== void 0 ? _saveElementArticleCo : '');
834
935
  if (!(!catalogArticle && (_jsonElement$Accessoi = jsonElement.AccessoireInitParams) !== null && _jsonElement$Accessoi !== void 0 && _jsonElement$Accessoi.RelatedToBasketID && !this.set.getSetState.onlyRunLogic)) {
835
- _context4.next = 15;
936
+ _context4.next = 14;
836
937
  break;
837
938
  }
838
939
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
839
940
  code: 'WC_0012'
840
941
  }));
841
- return _context4.abrupt("continue", 33);
842
- case 15:
942
+ return _context4.abrupt("continue", 32);
943
+ case 14:
843
944
  plannerElement = new PlannerElementData(this.set.getSetId(), jsonElement.basketID, this.nextElementId, DivaStandardPlanner.plannerType);
844
- oldElementidMapping.set(parseInt(jsonElement.elementID), plannerElement);
945
+ oldElementidMapping.set(jsonElement.elementID, plannerElement);
845
946
  this.nextElementId = plannerElement.getElementId() + 1;
846
947
  this.plannerElements.set(plannerElement.ElementId, plannerElement);
847
948
  this.set.setElementId(jsonElement.basketID, plannerElement.ElementId);
848
949
  data = this.set.getPlannerData(plannerElement.ElementId);
849
950
  plannerElement.updatePlannerData(data);
850
951
  if (this.doDisablePlanner2D) {
851
- _context4.next = 25;
952
+ _context4.next = 24;
852
953
  break;
853
954
  }
854
- _context4.next = 25;
955
+ _context4.next = 24;
855
956
  return handler2D.loadSVG(plannerElement, this.set);
856
- case 25:
957
+ case 24:
857
958
  plannerElement.WorldPosCenter = new Vector3(globalBoundingBox.WorldPos.x + globalBoundingBox.Size.x + jsonElement.x + 100, globalBoundingBox.WorldPos.y + jsonElement.y, globalBoundingBox.WorldPos.z + jsonElement.z);
858
959
  plannerElement.RotDeg = jsonElement.rot;
859
960
  if (plannerElement.IsDockedAccessoire) {
860
961
  accElements.push(jsonElement);
861
962
  plannerElement.PosNr = jsonElement.posNr;
862
- plannerElement.AccessoirePosNr = jsonElement.accNr;
963
+ if (jsonElement.accNr != null) plannerElement.AccessoirePosNr = jsonElement.accNr;
863
964
  } else {
864
965
  elementsSortedbyPosNr[jsonElement.posNr - 1] = jsonElement;
865
966
  plannerElement.PosNr = jsonElement.posNr;
866
967
  }
867
- _context4.next = 33;
968
+ _context4.next = 32;
868
969
  break;
869
- case 30:
870
- _context4.prev = 30;
871
- _context4.t0 = _context4["catch"](9);
970
+ case 29:
971
+ _context4.prev = 29;
972
+ _context4.t0 = _context4["catch"](8);
872
973
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
873
974
  cause: _context4.t0,
874
975
  code: 'WC_0012'
875
976
  }));
876
- case 33:
977
+ case 32:
877
978
  i++;
878
- _context4.next = 8;
979
+ _context4.next = 7;
879
980
  break;
880
- case 36:
881
- elementsSortedbyPosNr = elementsSortedbyPosNr.concat(accElements);
882
- for (i = 0; i < elementsSortedbyPosNr.length; i++) {
883
- curElement = oldElementidMapping.get(elementsSortedbyPosNr[i].elementID);
884
- if (elementsSortedbyPosNr.length > 1) {
885
- //This is the case when a complex product is loaded
886
- //First element is already positioned correctly not docket
981
+ case 35:
982
+ elementsForDockingExtend = [].concat(_toConsumableArray(elementsSortedbyPosNr.filter(function (e) {
983
+ return e != null;
984
+ })), accElements);
985
+ for (i = 0; i < elementsForDockingExtend.length; i++) {
986
+ row = elementsForDockingExtend[i];
987
+ curElement = oldElementidMapping.get(row.elementID);
988
+ if (elementsForDockingExtend.length > 1) {
887
989
  if (i > 0) {
888
- //The other elements are docked to the First element.
889
- DPsInfo = elementsSortedbyPosNr[i].DP;
990
+ DPsInfo = row.DP;
890
991
  for (j = 0; j < DPsInfo.length; j++) {
891
992
  dpInfo = DPsInfo[j];
892
993
  sourceDP = curElement === null || curElement === void 0 ? void 0 : curElement.getDockingPointById(dpInfo.id);
@@ -899,17 +1000,17 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
899
1000
  }
900
1001
  }
901
1002
  }
902
- _context4.next = 41;
1003
+ _context4.next = 40;
903
1004
  break;
904
- case 40:
1005
+ case 39:
905
1006
  LOG.error(new DivaError('The function extend Planner works only with products that are saved in the configurator 2.0', {
906
1007
  code: 'WC_0012'
907
1008
  }));
908
- case 41:
1009
+ case 40:
909
1010
  case "end":
910
1011
  return _context4.stop();
911
1012
  }
912
- }, _callee4, this, [[9, 30]]);
1013
+ }, _callee4, this, [[8, 29]]);
913
1014
  }));
914
1015
  function extendPlanner(_x7, _x8) {
915
1016
  return _extendPlanner.apply(this, arguments);
@@ -920,46 +1021,44 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
920
1021
  key: "initPlanner",
921
1022
  value: function () {
922
1023
  var _initPlanner = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(setPlanData) {
923
- var planDataString, planData, jsonElements, elementsSortedbyPosNr, accElements, i, _jsonElement$Accessoi2, jsonElement, catalogArticle, elementID, plannerElement, data, onlyOneBaseElement, _jsonElement, hasSavedPos, element, DPsInfo, j, dpInfo, sourceElement, sourceDP, targetElement, targetDP, _jsonElements, _elementsSortedbyPosNr, _accElements, _jsonElement2$Accesso, _jsonElement2, _catalogArticle, basketID, elementId, _plannerElement, _data, centerWorldPos, parentPosNr, accPosNr, _DPsInfo, _dpInfo, _this$plannerElements, targetElementId, dpType, curElement, _targetElement;
1024
+ var planData, _planData$set, jsonElements, elementsSortedbyPosNr, accElements, i, _saveElementArticleCo2, _jsonElement$Accessoi2, jsonElement, catalogArticle, elementID, plannerElement, data, onlyOneBaseElement, elementsForDocking, row, _jsonElement, hasSavedPos, element, DPsInfo, j, dpInfo, sourceElement, sourceDP, targetElement, targetDP, alreadyDocked, docked, _elementsForDocking$i, elementId, _planData$Sets, _legacySet$Elements, legacySet, _jsonElements, _elementsSortedbyPosNr, _accElements, _saveElementArticleCo3, _jsonElement2$Accesso, _jsonElement2, _catalogArticle, basketID, _elementId, _plannerElement, _data, centerWorldPos, parentPosNr, accPosNr, elementsForDockingV1, _row, _DPsInfo, _dpInfo, _this$plannerElements, targetElementId, dpType, curElement, _targetElement, anchorElement;
924
1025
  return _regeneratorRuntime.wrap(function _callee5$(_context5) {
925
1026
  while (1) switch (_context5.prev = _context5.next) {
926
1027
  case 0:
927
- planDataString = DivaUtils.decodeBase64(setPlanData);
928
- planData = JSON.parse(planDataString);
929
- if (!(planData.v != null && planData.v == 2)) {
930
- _context5.next = 62;
1028
+ planData = parseSetPlanData(setPlanData);
1029
+ if (!isSavePlannerV2(planData)) {
1030
+ _context5.next = 63;
931
1031
  break;
932
1032
  }
933
1033
  LOG.debug('Initialize set Plan Data - V2\n' + planData, 'DivaStandardPlanner initPlanner');
934
- if (!(!planData.set || !planData.set.elements || planData.set.elements.length == 0)) {
935
- _context5.next = 6;
1034
+ if ((_planData$set = planData.set) !== null && _planData$set !== void 0 && (_planData$set = _planData$set.elements) !== null && _planData$set !== void 0 && _planData$set.length) {
1035
+ _context5.next = 5;
936
1036
  break;
937
1037
  }
938
1038
  return _context5.abrupt("return");
939
- case 6:
940
- //Init new saved Plannings
1039
+ case 5:
941
1040
  jsonElements = planData.set.elements;
942
1041
  elementsSortedbyPosNr = [];
943
1042
  accElements = [];
944
1043
  i = 0;
945
- case 10:
1044
+ case 9:
946
1045
  if (!(i < jsonElements.length)) {
947
- _context5.next = 38;
1046
+ _context5.next = 37;
948
1047
  break;
949
1048
  }
950
- _context5.prev = 11;
1049
+ _context5.prev = 10;
951
1050
  jsonElement = jsonElements[i];
952
- catalogArticle = this.set.CatalogData.getCatalogArticleByArticleCodex(jsonElement.articleCodex || jsonElement.Codex);
1051
+ catalogArticle = this.set.CatalogData.getCatalogArticleByArticleCodex((_saveElementArticleCo2 = saveElementArticleCodex(jsonElement)) !== null && _saveElementArticleCo2 !== void 0 ? _saveElementArticleCo2 : '');
953
1052
  if (!(!catalogArticle && (_jsonElement$Accessoi2 = jsonElement.AccessoireInitParams) !== null && _jsonElement$Accessoi2 !== void 0 && _jsonElement$Accessoi2.RelatedToBasketID && !this.set.getSetState.onlyRunLogic)) {
954
- _context5.next = 17;
1053
+ _context5.next = 16;
955
1054
  break;
956
1055
  }
957
1056
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
958
1057
  code: 'WC_0012'
959
1058
  }));
960
- return _context5.abrupt("continue", 35);
961
- case 17:
962
- elementID = parseInt(jsonElement.elementID);
1059
+ return _context5.abrupt("continue", 34);
1060
+ case 16:
1061
+ elementID = jsonElement.elementID;
963
1062
  plannerElement = new PlannerElementData(this.set.getSetId(), jsonElement.basketID, elementID, DivaStandardPlanner.plannerType);
964
1063
  this.nextElementId = elementID + 1;
965
1064
  this.plannerElements.set(plannerElement.ElementId, plannerElement);
@@ -967,12 +1066,12 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
967
1066
  data = this.set.getPlannerData(plannerElement.ElementId);
968
1067
  plannerElement.updatePlannerData(data);
969
1068
  if (this.doDisablePlanner2D) {
970
- _context5.next = 27;
1069
+ _context5.next = 26;
971
1070
  break;
972
1071
  }
973
- _context5.next = 27;
1072
+ _context5.next = 26;
974
1073
  return handler2D.loadSVG(plannerElement, this.set);
975
- case 27:
1074
+ case 26:
976
1075
  //Im neuen speichern ist die Position hinten link - nicht mehr im Centrum wie im alten Planer
977
1076
  //plannerElement.WorldPosCenter = new Vector3(jsonElement.x, jsonElement.y, jsonElement.z);
978
1077
  plannerElement.WorldPosCenter = new Vector3(this.plannerBoundingBox.WorldPos.x + jsonElement.x, this.plannerBoundingBox.WorldPos.y + jsonElement.y, this.plannerBoundingBox.WorldPos.z + jsonElement.z);
@@ -980,141 +1079,151 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
980
1079
  if (plannerElement.IsDockedAccessoire) {
981
1080
  accElements.push(jsonElement);
982
1081
  plannerElement.PosNr = jsonElement.posNr;
983
- plannerElement.AccessoirePosNr = jsonElement.accNr;
1082
+ if (jsonElement.accNr != null) plannerElement.AccessoirePosNr = jsonElement.accNr;
984
1083
  } else {
985
1084
  elementsSortedbyPosNr[jsonElement.posNr - 1] = jsonElement;
986
1085
  plannerElement.PosNr = jsonElement.posNr;
987
1086
  }
988
- _context5.next = 35;
1087
+ _context5.next = 34;
989
1088
  break;
990
- case 32:
991
- _context5.prev = 32;
992
- _context5.t0 = _context5["catch"](11);
1089
+ case 31:
1090
+ _context5.prev = 31;
1091
+ _context5.t0 = _context5["catch"](10);
993
1092
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
994
1093
  cause: _context5.t0,
995
1094
  code: 'WC_0012'
996
1095
  }));
997
- case 35:
1096
+ case 34:
998
1097
  i++;
999
- _context5.next = 10;
1098
+ _context5.next = 9;
1000
1099
  break;
1001
- case 38:
1002
- onlyOneBaseElement = elementsSortedbyPosNr.length == 1; //Saves if only one base element is in the planning. All the others are only accessoires
1003
- elementsSortedbyPosNr = elementsSortedbyPosNr.concat(accElements);
1100
+ case 37:
1101
+ onlyOneBaseElement = elementsSortedbyPosNr.filter(Boolean).length == 1; //Saves if only one base element is in the planning. All the others are only accessoires
1102
+ elementsForDocking = [].concat(_toConsumableArray(elementsSortedbyPosNr.filter(function (e) {
1103
+ return e != null;
1104
+ })), accElements);
1004
1105
  i = 0;
1005
- case 41:
1006
- if (!(i < elementsSortedbyPosNr.length)) {
1007
- _context5.next = 60;
1106
+ case 40:
1107
+ if (!(i < elementsForDocking.length)) {
1108
+ _context5.next = 61;
1008
1109
  break;
1009
1110
  }
1010
- _context5.prev = 42;
1111
+ _context5.prev = 41;
1112
+ row = elementsForDocking[i];
1011
1113
  if (!(i == 0 && onlyOneBaseElement && this.plannerHasStaticBackground)) {
1012
1114
  _context5.next = 48;
1013
1115
  break;
1014
1116
  }
1015
1117
  //if the planner has a static background room and there is only one base element (ignore docked ACCs) then it should be forced positioned in the center of the room.
1016
1118
  //Only do this for fresh plannings - if the saved planData already contains a position, keep it.
1119
+ //if the planner has a static background room and there is only one base element (ignore docked ACCs) then it should be forced positioned in the center of the room
1017
1120
  _jsonElement = elementsSortedbyPosNr[i];
1018
- hasSavedPos = _jsonElement.x != null || _jsonElement.y != null || _jsonElement.z != null;
1121
+ hasSavedPos = (_jsonElement === null || _jsonElement === void 0 ? void 0 : _jsonElement.x) != null || (_jsonElement === null || _jsonElement === void 0 ? void 0 : _jsonElement.y) != null || (_jsonElement === null || _jsonElement === void 0 ? void 0 : _jsonElement.z) != null;
1019
1122
  if (!hasSavedPos) {
1020
- element = this.plannerElements.get(_jsonElement.elementID);
1123
+ element = this.plannerElements.get(row.elementID);
1021
1124
  if (element) element.WorldPosCenter = new Vector3(0, element.Height / 2, element.Depth / 2);
1022
1125
  }
1023
- return _context5.abrupt("continue", 57);
1126
+ return _context5.abrupt("continue", 58);
1024
1127
  case 48:
1025
- if (!(elementsSortedbyPosNr[i].DP == null || elementsSortedbyPosNr[i].DP.length == 0)) {
1128
+ if (!(row.DP == null || row.DP.length == 0)) {
1026
1129
  _context5.next = 50;
1027
1130
  break;
1028
1131
  }
1029
- return _context5.abrupt("continue", 57);
1132
+ return _context5.abrupt("continue", 58);
1030
1133
  case 50:
1031
- DPsInfo = elementsSortedbyPosNr[i].DP;
1134
+ DPsInfo = row.DP;
1032
1135
  for (j = 0; j < DPsInfo.length; j++) {
1033
1136
  dpInfo = DPsInfo[j];
1034
- if (dpInfo.id && dpInfo.id != '' && dpInfo.onID && dpInfo.onID != '' && dpInfo.onDPID && dpInfo.onDPID != '') {
1035
- sourceElement = this.plannerElements.get(elementsSortedbyPosNr[i].elementID);
1137
+ if (dpInfo.id && dpInfo.onID != null && dpInfo.onDPID) {
1138
+ sourceElement = this.plannerElements.get(row.elementID);
1036
1139
  sourceDP = sourceElement === null || sourceElement === void 0 ? void 0 : sourceElement.getDockingPointById(dpInfo.id);
1037
1140
  targetElement = this.plannerElements.get(dpInfo.onID);
1038
1141
  targetDP = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getDockingPointById(dpInfo.onDPID);
1039
1142
  if (sourceDP && targetDP) {
1040
- dockingPointHandlerInst.tryDockElementDPToDP(sourceElement, targetElement, sourceDP, targetDP);
1143
+ // Saved plans store each relation on both sides - skip the mirror entry of an already established pair.
1144
+ alreadyDocked = sourceDP.IsDocking && sourceDP.OnDP == targetDP;
1145
+ docked = alreadyDocked || dockingPointHandlerInst.tryDockElementDPToDP(sourceElement, targetElement, sourceDP, targetDP);
1146
+ if (!docked && !this.doDisablePlanner2D) LOG.error(new DivaError('Saved docking relation rejected on init: ' + dpInfo.id + ' (elem ' + (sourceElement === null || sourceElement === void 0 ? void 0 : sourceElement.ElementId) + ') -> ' + dpInfo.onDPID + ' (elem ' + (targetElement === null || targetElement === void 0 ? void 0 : targetElement.ElementId) + ')', {
1147
+ code: 'WC_0012'
1148
+ }));
1041
1149
  } else {
1042
1150
  if (!this.doDisablePlanner2D) LOG.error(new DivaError('Error initializing docking point between source element with id: ' + (sourceElement === null || sourceElement === void 0 ? void 0 : sourceElement.ElementId) + ' and target Element with id: ' + (targetElement === null || targetElement === void 0 ? void 0 : targetElement.ElementId) + '. SourceDPID: ' + dpInfo.id + '; targetDPID: ' + dpInfo.onDPID));
1043
1151
  }
1044
1152
  }
1045
1153
  }
1046
- _context5.next = 57;
1154
+ _context5.next = 58;
1047
1155
  break;
1048
1156
  case 54:
1049
1157
  _context5.prev = 54;
1050
- _context5.t1 = _context5["catch"](42);
1051
- LOG.error(new DivaError('Error initializing dockingPoints of element with elementID ' + elementsSortedbyPosNr[i].elementID, {
1158
+ _context5.t1 = _context5["catch"](41);
1159
+ elementId = (_elementsForDocking$i = elementsForDocking[i]) === null || _elementsForDocking$i === void 0 ? void 0 : _elementsForDocking$i.elementID;
1160
+ LOG.error(new DivaError('Error initializing dockingPoints of element with elementID ' + elementId, {
1052
1161
  cause: _context5.t1,
1053
1162
  code: 'WC_0012'
1054
1163
  }));
1055
- case 57:
1164
+ case 58:
1056
1165
  i++;
1057
- _context5.next = 41;
1166
+ _context5.next = 40;
1058
1167
  break;
1059
- case 60:
1060
- _context5.next = 113;
1168
+ case 61:
1169
+ _context5.next = 116;
1061
1170
  break;
1062
- case 62:
1171
+ case 63:
1063
1172
  LOG.debug('Initialize set Plan Data - old V1\n' + planData, 'DivaStandardPlanner initPlanner');
1064
- if (!(!planData.Sets || planData.Sets.length == 0 || !planData.Sets[0].Elements || planData.Sets[0].Elements.length == 0)) {
1065
- _context5.next = 65;
1173
+ legacySet = (_planData$Sets = planData.Sets) === null || _planData$Sets === void 0 ? void 0 : _planData$Sets[0];
1174
+ if (legacySet !== null && legacySet !== void 0 && (_legacySet$Elements = legacySet.Elements) !== null && _legacySet$Elements !== void 0 && _legacySet$Elements.length) {
1175
+ _context5.next = 67;
1066
1176
  break;
1067
1177
  }
1068
1178
  return _context5.abrupt("return");
1069
- case 65:
1070
- //Init old Plannings - saved with the old planner
1071
- _jsonElements = planData.Sets[0].Elements;
1179
+ case 67:
1180
+ _jsonElements = legacySet.Elements;
1072
1181
  _elementsSortedbyPosNr = [];
1073
1182
  _accElements = []; //Zuerst initialisiere alle Elemente
1074
1183
  //Dann positioniere sie richtig
1075
1184
  i = 0;
1076
- case 69:
1185
+ case 71:
1077
1186
  if (!(i < _jsonElements.length)) {
1078
- _context5.next = 103;
1187
+ _context5.next = 105;
1079
1188
  break;
1080
1189
  }
1081
- _context5.prev = 70;
1190
+ _context5.prev = 72;
1082
1191
  _jsonElement2 = _jsonElements[i];
1083
- _catalogArticle = this.set.CatalogData.getCatalogArticleByArticleCodex(_jsonElement2.articleCodex || _jsonElement2.Codex);
1192
+ _catalogArticle = this.set.CatalogData.getCatalogArticleByArticleCodex((_saveElementArticleCo3 = saveElementArticleCodex(_jsonElement2)) !== null && _saveElementArticleCo3 !== void 0 ? _saveElementArticleCo3 : '');
1084
1193
  if (!(!_catalogArticle && (_jsonElement2$Accesso = _jsonElement2.AccessoireInitParams) !== null && _jsonElement2$Accesso !== void 0 && _jsonElement2$Accesso.RelatedToBasketID && !this.set.getSetState.onlyRunLogic)) {
1085
- _context5.next = 76;
1194
+ _context5.next = 78;
1086
1195
  break;
1087
1196
  }
1088
- LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
1197
+ LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V1', {
1089
1198
  code: 'WC_0012'
1090
1199
  }));
1091
- return _context5.abrupt("continue", 100);
1092
- case 76:
1200
+ return _context5.abrupt("continue", 102);
1201
+ case 78:
1093
1202
  basketID = _jsonElement2.BasketID;
1094
1203
  if (this.set.getElementId(basketID) == -1) this.set.setElementId(basketID, Number(_jsonElement2.ID));
1095
- elementId = this.set.getElementId(basketID);
1096
- _jsonElement2.elementId = elementId;
1097
- if (!(elementId == -1)) {
1098
- _context5.next = 83;
1204
+ _elementId = this.set.getElementId(basketID);
1205
+ _jsonElement2.elementId = _elementId;
1206
+ if (!(_elementId == -1)) {
1207
+ _context5.next = 85;
1099
1208
  break;
1100
1209
  }
1101
1210
  LOG.error(new DivaError('Error when initializing planner. The elementID Was not saved in the article. ', {
1102
1211
  code: 'WC_0012'
1103
1212
  }));
1104
- return _context5.abrupt("continue", 100);
1105
- case 83:
1106
- _plannerElement = new PlannerElementData(this.set.getSetId(), basketID, elementId, DivaStandardPlanner.plannerType);
1107
- this.nextElementId = elementId + 1;
1213
+ return _context5.abrupt("continue", 102);
1214
+ case 85:
1215
+ _plannerElement = new PlannerElementData(this.set.getSetId(), basketID, _elementId, DivaStandardPlanner.plannerType);
1216
+ this.nextElementId = _elementId + 1;
1108
1217
  this.plannerElements.set(_plannerElement.ElementId, _plannerElement);
1109
1218
  _data = this.set.getPlannerData(_plannerElement.ElementId);
1110
1219
  _plannerElement.updatePlannerData(_data);
1111
1220
  if (this.doDisablePlanner2D) {
1112
- _context5.next = 91;
1221
+ _context5.next = 93;
1113
1222
  break;
1114
1223
  }
1115
- _context5.next = 91;
1224
+ _context5.next = 93;
1116
1225
  return handler2D.loadSVG(_plannerElement, this.set);
1117
- case 91:
1226
+ case 93:
1118
1227
  //Achtung die Pos Infos im alten Planer waren Zentrumskoordinaten!!! Nicht hinten oben.
1119
1228
  centerWorldPos = new Vector3(_jsonElement2.PosX, _jsonElement2.PosZ, _jsonElement2.PosY);
1120
1229
  _plannerElement.WorldPosCenter = new Vector3(this.plannerBoundingBox.WorldPos.x + centerWorldPos.x, this.plannerBoundingBox.WorldPos.y + centerWorldPos.y, this.plannerBoundingBox.WorldPos.z + centerWorldPos.z);
@@ -1124,70 +1233,75 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1124
1233
  if (_jsonElement2.PosNum.toString().indexOf('.') > 0) {
1125
1234
  parentPosNr = _jsonElement2.PosNum.toString().split('.')[0];
1126
1235
  accPosNr = _jsonElement2.PosNum.toString().split('.')[1];
1127
- _plannerElement.PosNr = parentPosNr;
1128
- _plannerElement.AccessoirePosNr = accPosNr;
1236
+ _plannerElement.PosNr = Number(parentPosNr);
1237
+ _plannerElement.AccessoirePosNr = Number(accPosNr);
1129
1238
  }
1130
1239
  } else {
1131
1240
  _elementsSortedbyPosNr[_jsonElement2.PosNum - 1] = _jsonElement2;
1132
1241
  _plannerElement.PosNr = _jsonElement2.PosNum;
1133
1242
  }
1134
- _context5.next = 100;
1243
+ _context5.next = 102;
1135
1244
  break;
1136
- case 97:
1137
- _context5.prev = 97;
1138
- _context5.t2 = _context5["catch"](70);
1245
+ case 99:
1246
+ _context5.prev = 99;
1247
+ _context5.t2 = _context5["catch"](72);
1139
1248
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner - Plan Data old Planner', {
1140
1249
  cause: _context5.t2,
1141
1250
  code: 'WC_0012'
1142
1251
  }));
1143
- case 100:
1252
+ case 102:
1144
1253
  i++;
1145
- _context5.next = 69;
1254
+ _context5.next = 71;
1146
1255
  break;
1147
- case 103:
1148
- _elementsSortedbyPosNr = _elementsSortedbyPosNr.concat(_accElements);
1149
- //Dann werden die DockingPoints durchgegangen und die jeweils richtigen müssen gesucht werden.
1150
- i = 0;
1151
1256
  case 105:
1152
- if (!(i < _elementsSortedbyPosNr.length)) {
1153
- _context5.next = 113;
1257
+ elementsForDockingV1 = [].concat(_toConsumableArray(_elementsSortedbyPosNr.filter(function (e) {
1258
+ return e != null;
1259
+ })), _accElements);
1260
+ i = 0;
1261
+ case 107:
1262
+ if (!(i < elementsForDockingV1.length)) {
1263
+ _context5.next = 116;
1154
1264
  break;
1155
1265
  }
1156
- if (!(_elementsSortedbyPosNr[i].DP == null || _elementsSortedbyPosNr[i].DP.length == 0)) {
1157
- _context5.next = 108;
1266
+ _row = elementsForDockingV1[i];
1267
+ if (!(_row.DP == null || _row.DP.length == 0)) {
1268
+ _context5.next = 111;
1158
1269
  break;
1159
1270
  }
1160
- return _context5.abrupt("continue", 110);
1161
- case 108:
1162
- _DPsInfo = _elementsSortedbyPosNr[i].DP;
1271
+ return _context5.abrupt("continue", 113);
1272
+ case 111:
1273
+ _DPsInfo = _row.DP;
1163
1274
  for (j = 0; j < _DPsInfo.length; j++) {
1164
1275
  _dpInfo = _DPsInfo[j];
1165
1276
  if (_dpInfo.DP && _dpInfo.DP != '' && _dpInfo.onID && _dpInfo.onID != '') {
1166
- targetElementId = parseInt(_dpInfo.onID);
1277
+ targetElementId = parseInt(String(_dpInfo.onID));
1167
1278
  dpType = _dpInfo.DP;
1168
- curElement = this.plannerElements.get(_elementsSortedbyPosNr[i].elementId);
1279
+ curElement = _row.elementId != null ? this.plannerElements.get(_row.elementId) : undefined;
1169
1280
  _targetElement = (_this$plannerElements = this.plannerElements.get(targetElementId)) !== null && _this$plannerElements !== void 0 ? _this$plannerElements : this.getPlannerElementByIndex(targetElementId - 1);
1170
1281
  if (curElement && _targetElement) {
1171
1282
  dockingPointHandlerInst.initDockingPointRelationByArea(curElement, _targetElement, dpType);
1172
1283
  } else {
1173
- LOG.error(new DivaError('Error initializing dockingPoints of element with elementID ' + _elementsSortedbyPosNr[i].elementId, {
1284
+ LOG.error(new DivaError('Error initializing dockingPoints of element with elementID ' + _row.elementId, {
1174
1285
  code: 'WC_0012'
1175
1286
  }));
1176
1287
  }
1177
1288
  }
1178
1289
  }
1179
- case 110:
1290
+ case 113:
1180
1291
  i++;
1181
- _context5.next = 105;
1292
+ _context5.next = 107;
1182
1293
  break;
1183
- case 113:
1184
- this.updateAllElementsWorldPos();
1294
+ case 116:
1295
+ this.plannerElements.forEach(function (el) {
1296
+ if (!el.IsDockedAccessoire && (anchorElement == undefined || el.PosNr < anchorElement.PosNr)) anchorElement = el;
1297
+ });
1298
+ this.updateAllElementsWorldPos(undefined, anchorElement ? [anchorElement.ElementId] : undefined);
1185
1299
  this.updatePlannerPosNr();
1186
- case 115:
1300
+ case 119:
1187
1301
  case "end":
1188
1302
  return _context5.stop();
1189
1303
  }
1190
- }, _callee5, this, [[11, 32], [42, 54], [70, 97]]);
1304
+ }, _callee5, this, [[10, 31], [41, 54], [72, 99]]);
1191
1305
  }));
1192
1306
  function initPlanner(_x9) {
1193
1307
  return _initPlanner.apply(this, arguments);
@@ -1296,27 +1410,61 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1296
1410
  key: "copyPlannerElement",
1297
1411
  value: (function () {
1298
1412
  var _copyPlannerElement = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(articleCopyRelation, copyInfo) {
1299
- var articlesToLoad, i;
1413
+ var i, _copyInfo$copyIndex, rel, dirX, sourceElement, targetDP;
1300
1414
  return _regeneratorRuntime.wrap(function _callee7$(_context7) {
1301
1415
  while (1) switch (_context7.prev = _context7.next) {
1302
1416
  case 0:
1303
- articlesToLoad = [];
1304
- articleCopyRelation.forEach(function (rel) {
1305
- if (copyInfo == undefined) articlesToLoad.push(rel.value);
1306
- });
1307
1417
  i = 0;
1308
- case 3:
1309
- if (!(i < articlesToLoad.length)) {
1310
- _context7.next = 9;
1418
+ case 1:
1419
+ if (!(i < articleCopyRelation.length)) {
1420
+ _context7.next = 24;
1421
+ break;
1422
+ }
1423
+ rel = articleCopyRelation[i];
1424
+ if (!(copyInfo == undefined)) {
1425
+ _context7.next = 7;
1311
1426
  break;
1312
1427
  }
1313
1428
  _context7.next = 6;
1314
- return this.addPlannerElement(articlesToLoad[i], {});
1429
+ return this.addPlannerElement(rel.value, {});
1315
1430
  case 6:
1431
+ return _context7.abrupt("continue", 21);
1432
+ case 7:
1433
+ //Directional copy (copyIndex.x = -1 left / 1 right): dock the copy at the source element's free AVL/AVR
1434
+ dirX = (_copyInfo$copyIndex = copyInfo.copyIndex) === null || _copyInfo$copyIndex === void 0 ? void 0 : _copyInfo$copyIndex.x;
1435
+ if (!(dirX != -1 && dirX != 1)) {
1436
+ _context7.next = 12;
1437
+ break;
1438
+ }
1439
+ _context7.next = 11;
1440
+ return this.addPlannerElement(rel.value, {});
1441
+ case 11:
1442
+ return _context7.abrupt("continue", 21);
1443
+ case 12:
1444
+ sourceElement = this.plannerElements.get(rel.key);
1445
+ targetDP = sourceElement === null || sourceElement === void 0 ? void 0 : sourceElement.getFreeDockingPointsByType(dirX == -1 ? 'AVL' : 'AVR').find(function (dp) {
1446
+ return !dp.IsDisabled;
1447
+ });
1448
+ if (!(sourceElement && targetDP)) {
1449
+ _context7.next = 19;
1450
+ break;
1451
+ }
1452
+ _context7.next = 17;
1453
+ return this.addPlannerElement(rel.value, {
1454
+ targetElemIdToDock: sourceElement.ElementId,
1455
+ targetDockingPointId: targetDP.DpId
1456
+ });
1457
+ case 17:
1458
+ _context7.next = 21;
1459
+ break;
1460
+ case 19:
1461
+ _context7.next = 21;
1462
+ return this.addPlannerElement(rel.value, {});
1463
+ case 21:
1316
1464
  i++;
1317
- _context7.next = 3;
1465
+ _context7.next = 1;
1318
1466
  break;
1319
- case 9:
1467
+ case 24:
1320
1468
  case "end":
1321
1469
  return _context7.stop();
1322
1470
  }
@@ -1341,7 +1489,8 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1341
1489
  }, {
1342
1490
  key: "getPlannerElementsInfluencedByCopy",
1343
1491
  value: function getPlannerElementsInfluencedByCopy(elementId, copyInfo) {
1344
- if (!copyInfo || copyInfo.copyType != 'BoxPlanner_backside') throw new Error('copyType needs to be BoxPlanner_backside here');
1492
+ //STD = directional AVL/AVR copy of a single element; only the element itself is influenced
1493
+ if (!copyInfo || copyInfo.copyType != 'BoxPlanner_backside' && copyInfo.copyType != 'STD') throw new Error('copyType needs to be BoxPlanner_backside or STD here');
1345
1494
  if (this.plannerElements.has(elementId)) return [elementId];
1346
1495
  return [];
1347
1496
  }
@@ -1543,12 +1692,12 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1543
1692
  */
1544
1693
  }, {
1545
1694
  key: "updatePlannerTrans",
1546
- value: function updatePlannerTrans(elementId, deltaMove, deltaAngleDeg, rotCorrection, transState, autoDockingDistance) {
1695
+ value: function updatePlannerTrans(elementId, deltaMove, deltaAngleDeg, rotCorrection, transState, autoDockingDistance, turningPoint) {
1547
1696
  var _this3 = this;
1548
1697
  var updateConfig = false;
1549
1698
  if (this.plannerElements.has(elementId)) {
1550
1699
  var plannerElement = this.plannerElements.get(elementId);
1551
- plannerElement === null || plannerElement === void 0 || plannerElement.updateDeltaTrans(deltaMove, deltaAngleDeg, rotCorrection, transState == 'END');
1700
+ plannerElement === null || plannerElement === void 0 || plannerElement.updateDeltaTrans(deltaMove, deltaAngleDeg, rotCorrection, transState == 'END', turningPoint);
1552
1701
  if (transState == 'START') {
1553
1702
  if (plannerElement) {
1554
1703
  var dpsToUndock = ['AVR', 'AVL'];