@2112-lab/central-plant 0.3.35 → 0.3.37

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.
@@ -61,7 +61,6 @@ function _attachIODevicesToComponent() {
61
61
  _context.n = 10;
62
62
  break;
63
63
  }
64
- console.log("\uD83D\uDD04 IO device model not in cache, preloading: ".concat(deviceData.modelKey));
65
64
  _context.p = 5;
66
65
  if (!((_modelPreloader$loadi = modelPreloader.loadingPromises) !== null && _modelPreloader$loadi !== void 0 && _modelPreloader$loadi.has(deviceData.modelKey))) {
67
66
  _context.n = 7;
@@ -143,10 +142,6 @@ function _attachIODevicesToComponent() {
143
142
 
144
143
  // Add as child of the component
145
144
  componentModel.add(deviceModel);
146
- console.log("\u2705 Attached IO device: ".concat(attachment.attachmentLabel || attachment.deviceId, " at"), {
147
- position: deviceModel.position,
148
- scale: deviceModel.scale
149
- });
150
145
  _context.n = 13;
151
146
  break;
152
147
  case 12:
@@ -31,7 +31,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
31
31
  * Initialize the CentralPlant manager
32
32
  *
33
33
  * @constructor
34
- * @version 0.3.35
34
+ * @version 0.3.37
35
35
  * @updated 2025-10-22
36
36
  *
37
37
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -220,12 +220,13 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
220
220
  behaviors: ((_this$importedSceneDa3 = this.importedSceneData.behaviors) === null || _this$importedSceneDa3 === void 0 ? void 0 : _this$importedSceneDa3.length) || 0,
221
221
  timestamp: new Date().toISOString()
222
222
  });
223
- console.log('[Behavior] Scene behaviors detail:', this.importedSceneData.behaviors);
223
+
224
+ // Scene behaviors loaded
224
225
 
225
226
  // Register behaviors with IoBehaviorManager
226
227
  ioBehavMgr = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.ioBehaviorManager;
227
228
  if (ioBehavMgr) {
228
- console.log('[Behavior] Calling setCrossComponentBehaviors with:', this.importedSceneData.behaviors || []);
229
+ // Setting cross-component behaviors
229
230
  ioBehavMgr.setCrossComponentBehaviors(this.importedSceneData.behaviors || []);
230
231
  } else {
231
232
  console.warn('[Behavior] ioBehaviorManager not available!');
@@ -724,7 +725,6 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
724
725
 
725
726
  // Enable drag functionality for the specific element
726
727
  this.sceneViewer.managers.componentDragManager.enableElementDrag(element, componentId);
727
- console.log("\u2705 enableDragDrop(): Enabled drag and drop for ".concat(componentId));
728
728
  return true;
729
729
  } catch (error) {
730
730
  console.error('❌ enableDragDrop(): Error enabling drag and drop:', error);
@@ -760,7 +760,6 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
760
760
  }
761
761
  try {
762
762
  this.sceneViewer.managers.componentDragManager.disableElementDrag(element);
763
- console.log('✅ disableDragDrop(): Disabled drag and drop for element');
764
763
  return true;
765
764
  } catch (error) {
766
765
  console.error('❌ disableDragDrop(): Error disabling drag and drop:', error);
@@ -794,7 +793,6 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
794
793
  if (this.sceneViewer.managers.componentDragManager) {
795
794
  this.sceneViewer.managers.componentDragManager.setEnabled(enabled);
796
795
  }
797
- console.log("\u2705 setDragDropEnabled(): Drag and drop ".concat(enabled ? 'enabled' : 'disabled'));
798
796
  return true;
799
797
  } catch (error) {
800
798
  console.error('❌ setDragDropEnabled(): Error setting drag and drop state:', error);
@@ -212,12 +212,10 @@ var CentralPlantInternals = /*#__PURE__*/function () {
212
212
  if (this.centralPlant.sceneViewer.$refs.container && this.centralPlant.sceneViewer.camera && this.centralPlant.sceneViewer.scene) {
213
213
  this.centralPlant.managers.tooltipsManager = new SceneTooltipsManager(this.centralPlant.sceneViewer.$refs.container, this.centralPlant.sceneViewer.camera, this.centralPlant.sceneViewer.scene);
214
214
  this.centralPlant.sceneViewer.tooltipsManager = this.centralPlant.managers.tooltipsManager;
215
- console.log('🔍 Tooltip manager initialized:', this.centralPlant.managers.tooltipsManager);
216
215
 
217
216
  // Initialize the component tooltip manager (screen-space tooltip on selection)
218
217
  this.centralPlant.managers.componentTooltipManager = new ComponentTooltipManager(this.centralPlant.sceneViewer);
219
218
  this.centralPlant.sceneViewer.componentTooltipManager = this.centralPlant.managers.componentTooltipManager;
220
- console.log('🔍 Component tooltip manager initialized');
221
219
  }
222
220
  }
223
221
 
@@ -1153,7 +1151,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1153
1151
 
1154
1152
  // Register component-level behaviors (intra-component io-device linking)
1155
1153
  if (componentData.behaviors && componentData.behaviors.length > 0) {
1156
- console.log("[DragDrop] Registering ".concat(componentData.behaviors.length, " component-level behavior(s) for ").concat(componentId));
1154
+ // Registering ${componentData.behaviors.length} component-level behavior(s)
1157
1155
  ioBehavMgr.registerComponentBehaviors(componentId, componentData.behaviors);
1158
1156
  }
1159
1157
  }
@@ -97,6 +97,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
97
97
  entries.push({
98
98
  anim: anim,
99
99
  mesh: mesh,
100
+ deviceModelRoot: deviceModelRoot,
100
101
  origPos: mesh.position.clone(),
101
102
  origRot: mesh.rotation.clone(),
102
103
  origWorldPos: worldPos,
@@ -113,9 +114,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
113
114
  }
114
115
  if (entries.length) {
115
116
  this._entries.set(key, entries);
116
- console.log("[IoBehaviorManager] Loaded ".concat(entries.length, " animation(s) for attachment \"").concat(attachmentId, "\" (parent: ").concat(parentUuid, ") \u2014 stateVariables: ").concat(entries.map(function (e) {
117
- return e.anim.stateVariable;
118
- }).join(', ')));
117
+ // Loaded ${entries.length} animation(s) for attachment "${attachmentId}"
119
118
  } else {
120
119
  console.warn("[IoBehaviorManager] No mesh entries resolved for attachment \"".concat(attachmentId, "\" \u2014 behaviorConfig had ").concat(anims.length, " entries but none matched a mesh"));
121
120
  }
@@ -133,13 +132,8 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
133
132
  }, {
134
133
  key: "triggerState",
135
134
  value: function triggerState(attachmentId, dataPointId, value, parentUuid) {
136
- var _this$_crossComponent;
137
- console.log("[Behavior] triggerState called:", {
138
- attachmentId: attachmentId,
139
- dataPointId: dataPointId,
140
- value: value,
141
- parentUuid: parentUuid
142
- });
135
+ // triggerState: ${attachmentId}.${dataPointId} = ${value}
136
+
143
137
  if (parentUuid) {
144
138
  var key = this._key(parentUuid, attachmentId);
145
139
  var entries = this._entries.get(key);
@@ -194,12 +188,12 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
194
188
  // Evaluate component-level behaviors (intra-component io-device linking)
195
189
  if (parentUuid && this._componentBehaviors.has(parentUuid)) {
196
190
  var componentBehaviors = this._componentBehaviors.get(parentUuid);
197
- console.log("[Behavior] Checking component-level behaviors for ".concat(parentUuid, " (count: ").concat(componentBehaviors.length, ")"));
191
+ // Checking component-level behaviors (count: ${componentBehaviors.length})
198
192
  this.triggerCrossComponentBehaviors(componentBehaviors, parentUuid, attachmentId, dataPointId, value);
199
193
  }
200
194
 
201
195
  // Evaluate cross-component behaviors if any are registered
202
- console.log("[Behavior] Checking cross-component behaviors (count: ".concat(((_this$_crossComponent = this._crossComponentBehaviors) === null || _this$_crossComponent === void 0 ? void 0 : _this$_crossComponent.length) || 0, ")"));
196
+ // Checking cross-component behaviors (count: ${this._crossComponentBehaviors?.length || 0})
203
197
  if (this._crossComponentBehaviors && this._crossComponentBehaviors.length > 0) {
204
198
  this.triggerCrossComponentBehaviors(this._crossComponentBehaviors, parentUuid, attachmentId, dataPointId, value);
205
199
  }
@@ -218,7 +212,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
218
212
  this._crossComponentBehaviors = (behaviors || []).map(function (b) {
219
213
  return _this2._normalizeBehavior(b);
220
214
  });
221
- console.log("[Behavior] Loaded ".concat(this._crossComponentBehaviors.length, " cross-component behavior(s)"), this._crossComponentBehaviors);
215
+ // Loaded ${this._crossComponentBehaviors.length} cross-component behavior(s)
222
216
  }
223
217
 
224
218
  /**
@@ -237,7 +231,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
237
231
  return _this3._normalizeBehavior(b);
238
232
  });
239
233
  this._componentBehaviors.set(componentUuid, normalized);
240
- console.log("[Behavior] Registered ".concat(normalized.length, " component-level behavior(s) for component ").concat(componentUuid), normalized);
234
+ // Registered ${normalized.length} component-level behavior(s) for component ${componentUuid}
241
235
  }
242
236
 
243
237
  /**
@@ -348,7 +342,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
348
342
  key: "configure",
349
343
  value: function configure(stateAdapter) {
350
344
  this._stateAdapter = stateAdapter || null;
351
- console.log('[Behavior] State adapter configured:', !!this._stateAdapter);
345
+ // State adapter configured
352
346
  }
353
347
 
354
348
  /**
@@ -364,10 +358,10 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
364
358
  key: "triggerCrossComponentBehaviors",
365
359
  value: function triggerCrossComponentBehaviors(behaviors, triggerParentUuid, triggerAttachmentId, triggerStateId, value) {
366
360
  if (!behaviors || !Array.isArray(behaviors)) {
367
- console.log('[Behavior] No behaviors to evaluate');
368
361
  return;
369
362
  }
370
- console.log("[Behavior] Evaluating ".concat(behaviors.length, " behavior(s) for trigger: ").concat(triggerParentUuid, ".").concat(triggerAttachmentId, ".").concat(triggerStateId, " = ").concat(value));
363
+
364
+ // Evaluating ${behaviors.length} behavior(s)
371
365
  var _iterator5 = _createForOfIteratorHelper(behaviors),
372
366
  _step5;
373
367
  try {
@@ -402,7 +396,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
402
396
 
403
397
  // Verify that the input matches the triggering source
404
398
  if (inputComponent === triggerParentUuid && input.attachment === triggerAttachmentId && input.state === triggerStateId) {
405
- console.log("[Behavior] \u2713 Behavior \"".concat(behavior.id, "\" matched!"));
399
+ // Behavior "${behavior.id}" matched
406
400
 
407
401
  // Collect all outputs (single or multiple)
408
402
  var outputs = _outputs || (output ? [output] : []);
@@ -420,14 +414,13 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
420
414
 
421
415
  // Direct state mapping without conditions
422
416
  if (this._stateAdapter) {
423
- console.log("[Behavior] Dispatching state-to-state: ".concat(out.attachment, ".").concat(out.state, " = ").concat(value));
417
+ // Dispatching state-to-state: ${out.attachment}.${out.state} = ${value}
424
418
  this._stateAdapter.setState(out.attachment, out.state, value);
425
- console.log("[Behavior] \u2713 State-to-state triggered: ".concat(input.attachment, ".").concat(input.state, " (").concat(value, ") \u2192 ").concat(out.attachment, ".").concat(out.state));
426
419
 
427
420
  // Trigger animations on the output component
428
421
  // triggerState(attachmentId, dataPointId, value, parentUuid)
429
422
  if (outputComponent) {
430
- console.log("[Behavior] Triggering animations on output component: ".concat(outputComponent, ".").concat(out.attachment, ".").concat(out.state));
423
+ // Triggering animations on output component
431
424
  this.triggerState(out.attachment, out.state, value, outputComponent);
432
425
  } else {
433
426
  console.warn("[Behavior] Could not find component for attachment \"".concat(out.attachment, "\""));
@@ -438,7 +431,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
438
431
  }
439
432
  // LEGACY: Mesh-based pattern with conditions
440
433
  else if (conditions && out.child) {
441
- console.log('[Behavior] Using legacy mesh-based pattern with conditions');
434
+ // Using legacy mesh-based pattern with conditions
442
435
  // Evaluate conditions
443
436
  var _iterator7 = _createForOfIteratorHelper(conditions),
444
437
  _step7;
@@ -855,13 +848,9 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
855
848
  value: function _applyAnimation(entry, value) {
856
849
  var anim = entry.anim,
857
850
  mesh = entry.mesh,
858
- origPos = entry.origPos,
859
- origRot = entry.origRot,
860
- origWorldPos = entry.origWorldPos,
861
- origWorldQuat = entry.origWorldQuat,
862
- origWorldCenter = entry.origWorldCenter,
863
- deviceWorldQuat = entry.deviceWorldQuat,
864
- viewerMaxDim = entry.viewerMaxDim;
851
+ origPos = entry.origPos;
852
+ entry.origRot;
853
+ var viewerMaxDim = entry.viewerMaxDim;
865
854
  var mapping = this._resolveMapping(anim, value);
866
855
  if (!mapping) return;
867
856
  var types = anim.transformTypes || [];
@@ -873,7 +862,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
873
862
  if (type === 'translation') {
874
863
  this._applyTranslation(mesh, origPos, mapping.transform);
875
864
  } else if (type === 'rotation') {
876
- this._applyRotation(mesh, origPos, origRot, anim, mapping.rotationTransform, origWorldPos, origWorldQuat, origWorldCenter, deviceWorldQuat, viewerMaxDim);
865
+ this._applyRotation(entry, anim, mapping.rotationTransform, viewerMaxDim);
877
866
  } else if (type === 'color') {
878
867
  this._applyColor(mesh, mapping.colorTransform);
879
868
  }
@@ -1017,25 +1006,71 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
1017
1006
  mesh.position.set(origPos.x - ((_transform$x = transform.x) !== null && _transform$x !== void 0 ? _transform$x : 0), origPos.y - ((_transform$y = transform.y) !== null && _transform$y !== void 0 ? _transform$y : 0), origPos.z + ((_transform$z = transform.z) !== null && _transform$z !== void 0 ? _transform$z : 0));
1018
1007
  }
1019
1008
 
1009
+ /**
1010
+ * Recompute world-space rest-pose transforms for a behavior entry using the
1011
+ * current parent/device world matrix. origPos/origRot are local rest pose and
1012
+ * stay valid after parent moves; world anchors must be derived at apply time.
1013
+ *
1014
+ * @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
1015
+ * @returns {{ origWorldPos: THREE.Vector3, origWorldQuat: THREE.Quaternion, origWorldCenter: THREE.Vector3, deviceWorldQuat: THREE.Quaternion }|null}
1016
+ */
1017
+ }, {
1018
+ key: "_getRestWorldTransforms",
1019
+ value: function _getRestWorldTransforms(entry) {
1020
+ var mesh = entry.mesh,
1021
+ origPos = entry.origPos,
1022
+ origRot = entry.origRot,
1023
+ deviceModelRoot = entry.deviceModelRoot;
1024
+ if (!mesh || !origPos || !origRot) return null;
1025
+ var savedPos = mesh.position.clone();
1026
+ var savedQuat = mesh.quaternion.clone();
1027
+ mesh.position.copy(origPos);
1028
+ mesh.rotation.copy(origRot);
1029
+ mesh.updateMatrixWorld(true);
1030
+ var origWorldPos = new THREE.Vector3();
1031
+ mesh.getWorldPosition(origWorldPos);
1032
+ var origWorldQuat = new THREE.Quaternion();
1033
+ mesh.getWorldQuaternion(origWorldQuat);
1034
+ var box = new THREE.Box3().setFromObject(mesh);
1035
+ var origWorldCenter = new THREE.Vector3();
1036
+ if (!box.isEmpty()) box.getCenter(origWorldCenter);else origWorldCenter.copy(origWorldPos);
1037
+ var deviceWorldQuat = new THREE.Quaternion();
1038
+ if (deviceModelRoot) {
1039
+ deviceModelRoot.getWorldQuaternion(deviceWorldQuat);
1040
+ }
1041
+ mesh.position.copy(savedPos);
1042
+ mesh.quaternion.copy(savedQuat);
1043
+ return {
1044
+ origWorldPos: origWorldPos,
1045
+ origWorldQuat: origWorldQuat,
1046
+ origWorldCenter: origWorldCenter,
1047
+ deviceWorldQuat: deviceWorldQuat
1048
+ };
1049
+ }
1050
+
1020
1051
  /**
1021
1052
  * Apply a rotation around an arbitrary pivot point using world-space quaternion
1022
1053
  * math matching the ReconstructionViewer's setMeshPreviewRotationAxis approach.
1023
1054
  * This ensures the runtime axis/pivot matches what the user configured in the
1024
1055
  * animation dialog, regardless of the device's parent transform in the scene.
1025
1056
  *
1026
- * @param {THREE.Object3D} mesh
1027
- * @param {THREE.Vector3} origPos - local position at load time (unused, kept for signature compat)
1028
- * @param {THREE.Euler} origRot - local rotation at load time (unused)
1057
+ * @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
1029
1058
  * @param {Object} anim
1030
1059
  * @param {number} angleDeg - Degrees
1031
- * @param {THREE.Vector3} origWorldPos - world position at load time
1032
- * @param {THREE.Quaternion} origWorldQuat - world quaternion at load time
1033
- * @param {THREE.Vector3} origWorldCenter - world bounding-box center at load time
1060
+ * @param {number} viewerMaxDim
1034
1061
  */
1035
1062
  }, {
1036
1063
  key: "_applyRotation",
1037
- value: function _applyRotation(mesh, origPos, origRot, anim, angleDeg, origWorldPos, origWorldQuat, origWorldCenter, deviceWorldQuat, viewerMaxDim) {
1064
+ value: function _applyRotation(entry, anim, angleDeg, viewerMaxDim) {
1038
1065
  var _anim$rotAxis, _anim$rotAxisOffset;
1066
+ var mesh = entry.mesh,
1067
+ origPos = entry.origPos,
1068
+ origRot = entry.origRot;
1069
+ var restWorld = this._getRestWorldTransforms(entry);
1070
+ var origWorldPos = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldPos;
1071
+ var origWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldQuat;
1072
+ var origWorldCenter = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldCenter;
1073
+ var deviceWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.deviceWorldQuat;
1039
1074
  var angle = THREE.MathUtils.degToRad(typeof angleDeg === 'number' ? angleDeg : 0);
1040
1075
  var axis = ((_anim$rotAxis = anim.rotAxis) !== null && _anim$rotAxis !== void 0 ? _anim$rotAxis : 'x').toLowerCase();
1041
1076
  var off = (_anim$rotAxisOffset = anim.rotAxisOffset) !== null && _anim$rotAxisOffset !== void 0 ? _anim$rotAxisOffset : {
@@ -766,7 +766,6 @@ function _findInAllCachePartitions() {
766
766
  _context16.n = 7;
767
767
  break;
768
768
  }
769
- console.log("\u2705 [findInAllCachePartitions] Found in ".concat(cacheName, " (exact match): ").concat(cacheKey.substring(0, 80), "..."));
770
769
  return _context16.a(2, response);
771
770
  case 7:
772
771
  if (!(encodedCacheKey !== cacheKey)) {
@@ -781,7 +780,6 @@ function _findInAllCachePartitions() {
781
780
  _context16.n = 9;
782
781
  break;
783
782
  }
784
- console.log("\u2705 [findInAllCachePartitions] Found in ".concat(cacheName, " (encoded match): ").concat(encodedCacheKey.substring(0, 80), "..."));
785
783
  return _context16.a(2, response);
786
784
  case 9:
787
785
  _context16.n = 4;
@@ -816,8 +814,6 @@ function _getCachedS3Object() {
816
814
  cachedResponse,
817
815
  cachedTime,
818
816
  age,
819
- _allKeys,
820
- matchingKeys,
821
817
  _args19 = arguments;
822
818
  return _regenerator().w(function (_context19) {
823
819
  while (1) switch (_context19.n) {
@@ -825,50 +821,26 @@ function _getCachedS3Object() {
825
821
  storageOptions = _args19.length > 1 && _args19[1] !== undefined ? _args19[1] : {};
826
822
  expiryMs = _args19.length > 2 && _args19[2] !== undefined ? _args19[2] : null;
827
823
  cacheKey = "https://s3.cache/".concat(s3Key);
828
- expiry = expiryMs || cacheManager.getExpiryForPath(s3Key);
829
- console.log("\uD83D\uDD0D [S3Cache] Checking for cached S3 object:", {
830
- s3Key: s3Key,
831
- cacheKey: cacheKey
832
- });
833
-
834
- // First, check ALL app cache partitions for a hit (handles auth race condition)
824
+ expiry = expiryMs || cacheManager.getExpiryForPath(s3Key); // First, check ALL app cache partitions for a hit (handles auth race condition)
835
825
  _context19.n = 1;
836
826
  return findInAllCachePartitions(cacheKey);
837
827
  case 1:
838
828
  cachedResponse = _context19.v;
839
829
  if (!cachedResponse) {
840
- _context19.n = 4;
830
+ _context19.n = 3;
841
831
  break;
842
832
  }
843
833
  cachedTime = cachedResponse.headers.get('x-cached-time');
844
834
  age = Date.now() - parseInt(cachedTime || '0');
845
- console.log("\u2705 [S3Cache] Found in cache partition, age: ".concat(Math.round(age / 1000), "s, expiry: ").concat(Math.round(expiry / 1000), "s"));
846
835
  if (!(age < expiry)) {
847
836
  _context19.n = 3;
848
837
  break;
849
838
  }
850
- console.log("\u2705 [S3Cache] Returning cached blob for: ".concat(s3Key));
851
839
  _context19.n = 2;
852
840
  return cachedResponse.blob();
853
841
  case 2:
854
842
  return _context19.a(2, _context19.v);
855
843
  case 3:
856
- console.log("\u23F0 [S3Cache] Cache entry expired, will re-fetch");
857
- _context19.n = 6;
858
- break;
859
- case 4:
860
- console.log("\u274C [S3Cache] Not found in any cache partition");
861
- _context19.n = 5;
862
- return getAllCacheKeys();
863
- case 5:
864
- _allKeys = _context19.v;
865
- matchingKeys = _toConsumableArray(_allKeys).filter(function (k) {
866
- return k.includes('24dd6a7a') || k.includes('.glb');
867
- });
868
- if (matchingKeys.length > 0) {
869
- console.log("\uD83D\uDD0D [S3Cache] Available GLB cache keys:", matchingKeys.slice(0, 5));
870
- }
871
- case 6:
872
844
  return _context19.a(2, cacheManager.execute({
873
845
  cacheKey: cacheKey,
874
846
  sourceKey: s3Key,
@@ -1027,7 +999,6 @@ function _preloadS3Objects() {
1027
999
  };
1028
1000
  }()));
1029
1001
  case 1:
1030
- console.log("\u2705 Preload complete: ".concat(results.success, " success, ").concat(results.failed, " failed"));
1031
1002
  return _context22.a(2, results);
1032
1003
  }
1033
1004
  }, _callee22);
@@ -1205,7 +1176,6 @@ function _preloadLocalFiles() {
1205
1176
  return _regenerator().w(function (_context29) {
1206
1177
  while (1) switch (_context29.n) {
1207
1178
  case 0:
1208
- console.log("preloadLocalFiles started");
1209
1179
  results = {
1210
1180
  success: 0,
1211
1181
  failed: 0,
@@ -1244,7 +1214,6 @@ function _preloadLocalFiles() {
1244
1214
  };
1245
1215
  }()));
1246
1216
  case 1:
1247
- console.log("preloadLocalFiles finished");
1248
1217
  if (results.failed > 0) {
1249
1218
  console.warn("\u26A0\uFE0F preloadLocalFiles Cache priming finished with errors: ".concat(results.failed, " failed"), results.errors);
1250
1219
  }
@@ -469,7 +469,6 @@ var S3MetadataCacheService = /*#__PURE__*/function () {
469
469
  // Update memory cache
470
470
  this._memoryCache = metadata;
471
471
  this._memoryCacheTime = Date.now();
472
- console.log("\uD83D\uDCBE S3MetadataCacheService: Set ".concat(components.length, " components"));
473
472
  return _context9.a(2, true);
474
473
  case 4:
475
474
  _context9.p = 4;
@@ -320,7 +320,7 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
320
320
  value: (function () {
321
321
  var _extendComponentDictionary = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(additionalComponents) {
322
322
  var _this3 = this;
323
- var _this$sceneViewer, newComponents, skippedCount, addedCount, modelPreloader, _t;
323
+ var _this$sceneViewer, newComponents, modelPreloader, _t;
324
324
  return _regenerator().w(function (_context3) {
325
325
  while (1) switch (_context3.n) {
326
326
  case 0:
@@ -344,7 +344,6 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
344
344
  _context3.p = 3;
345
345
  // Filter out components that already exist in the dictionary (deduplication)
346
346
  newComponents = {};
347
- skippedCount = 0;
348
347
  Object.entries(additionalComponents).forEach(function (_ref3) {
349
348
  var _ref4 = _slicedToArray(_ref3, 2),
350
349
  key = _ref4[0],
@@ -352,13 +351,12 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
352
351
  if (!_this3.componentDictionary[key]) {
353
352
  newComponents[key] = component;
354
353
  } else {
355
- skippedCount++;
356
354
  console.log("\u26A0\uFE0F Skipping duplicate component: ".concat(key, " (").concat(component.name || 'unnamed', ")"));
357
355
  }
358
356
  });
359
357
 
360
358
  // Merge only new components into dictionary
361
- addedCount = Object.keys(newComponents).length;
359
+ Object.keys(newComponents).length;
362
360
  Object.assign(this.componentDictionary, newComponents);
363
361
 
364
362
  // Update ModelPreloader's dictionary reference
@@ -366,12 +364,10 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
366
364
  modelPreloader = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.centralPlant) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.utilities) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.modelPreloader;
367
365
  if (modelPreloader) {
368
366
  modelPreloader.componentDictionary = this.componentDictionary;
369
- console.log("\uD83D\uDD04 Updated ModelPreloader's dictionary reference (".concat(Object.keys(this.componentDictionary).length, " total components)"));
370
367
  }
371
368
 
372
369
  // Clear cache to force refresh
373
370
  this.clearCache();
374
- console.log("\u2705 extendComponentDictionary(): Added ".concat(addedCount, " new components (").concat(skippedCount, " duplicates skipped)"));
375
371
  return _context3.a(2, true);
376
372
  case 4:
377
373
  _context3.p = 4;
@@ -5,7 +5,7 @@ import { BaseDisposable } from '../../core/baseDisposable.js';
5
5
  // ---------------------------------------------------------------------------
6
6
  // Inline styles (injected once into the document head)
7
7
  // ---------------------------------------------------------------------------
8
- var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n}\n\n.cp-tooltip__card {\n background: rgba(28, 32, 40, 0.95);\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: 10px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);\n overflow: hidden;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__header {\n padding: 10px 14px;\n font-weight: 600;\n font-size: 14px;\n color: #e8ecf1;\n background: rgba(255, 255, 255, 0.04);\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n letter-spacing: 0.2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 I/O Devices section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__io-section {\n position: relative;\n}\n\n.cp-tooltip__io-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n color: #a4adba;\n cursor: pointer;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.cp-tooltip__io-trigger:hover {\n background: rgba(255, 255, 255, 0.06);\n color: #e8ecf1;\n}\n\n.cp-tooltip__io-trigger-label {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.6px;\n font-weight: 500;\n}\n\n.cp-tooltip__io-arrow {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__io-arrow {\n transform: rotate(90deg);\n}\n\n/* \u2500\u2500 Device list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__device-list {\n max-height: 0;\n overflow: hidden;\n transition: max-height 0.25s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__device-list {\n max-height: 300px;\n}\n\n.cp-tooltip__device-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px 6px 20px;\n color: #c1c8d1;\n font-size: 12px;\n border-top: 1px solid rgba(255, 255, 255, 0.04);\n transition: background 0.1s ease;\n}\n\n.cp-tooltip__device-item:hover {\n background: rgba(255, 255, 255, 0.04);\n}\n\n.cp-tooltip__device-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #4fc3f7;\n flex-shrink: 0;\n}\n\n.cp-tooltip__device-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Empty state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__no-devices {\n padding: 8px 14px;\n color: #6b7280;\n font-size: 12px;\n font-style: italic;\n}\n\n/* \u2500\u2500 Caret arrow pointing down \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__caret {\n width: 0;\n height: 0;\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-top: 7px solid rgba(28, 32, 40, 0.95);\n margin: 0 auto;\n position: relative;\n top: -1px;\n}\n\n/* \u2500\u2500 Data point rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__dp-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 4px 12px 4px 30px;\n font-size: 11.5px;\n border-top: 1px solid rgba(255, 255, 255, 0.025);\n min-height: 24px;\n}\n\n.cp-tooltip__dp-name {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #7c8d9e;\n}\n\n/* Read-only state badge */\n.cp-tooltip__dp-badge {\n font-size: 10.5px;\n font-weight: 600;\n padding: 1px 7px;\n border-radius: 8px;\n flex-shrink: 0;\n background: rgba(255, 255, 255, 0.07);\n color: #9aabb8;\n min-width: 30px;\n text-align: center;\n letter-spacing: 0.2px;\n}\n\n.cp-tooltip__dp-badge.active {\n background: rgba(76, 175, 80, 0.28);\n color: #a5d6a7;\n}\n\n/* Binary toggle button */\n.cp-tooltip__dp-toggle {\n font-size: 10.5px;\n font-weight: 600;\n padding: 2px 9px;\n border-radius: 8px;\n flex-shrink: 0;\n border: 1px solid rgba(255, 255, 255, 0.14);\n background: rgba(255, 255, 255, 0.06);\n color: #c1c8d1;\n cursor: pointer;\n min-width: 40px;\n text-align: center;\n transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;\n}\n\n.cp-tooltip__dp-toggle:hover {\n background: rgba(255, 255, 255, 0.12);\n border-color: rgba(255, 255, 255, 0.25);\n}\n\n.cp-tooltip__dp-toggle.on {\n background: rgba(76, 175, 80, 0.28);\n border-color: rgba(76, 175, 80, 0.55);\n color: #a5d6a7;\n}\n\n/* Number / float input */\n.cp-tooltip__dp-input {\n width: 62px;\n background: rgba(255, 255, 255, 0.06);\n border: 1px solid rgba(255, 255, 255, 0.14);\n border-radius: 4px;\n color: #e8ecf1;\n font-size: 11px;\n padding: 2px 5px;\n text-align: right;\n outline: none;\n flex-shrink: 0;\n}\n\n.cp-tooltip__dp-input:focus {\n border-color: rgba(79, 195, 247, 0.55);\n}\n\n/* Enum select */\n.cp-tooltip__dp-select {\n background: rgba(255, 255, 255, 0.06);\n border: 1px solid rgba(255, 255, 255, 0.14);\n border-radius: 4px;\n color: #e8ecf1;\n font-size: 11px;\n padding: 2px 4px;\n outline: none;\n flex-shrink: 0;\n max-width: 96px;\n cursor: pointer;\n}\n\n.cp-tooltip__dp-select:focus {\n border-color: rgba(79, 195, 247, 0.55);\n}\n\n/* Unit suffix */\n.cp-tooltip__dp-unit {\n font-size: 10px;\n color: #505c68;\n flex-shrink: 0;\n margin-left: -4px;\n}\n";
8
+ var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n color-scheme: light;\n}\n\n.cp-tooltip__card {\n background: rgba(255, 255, 255, 0.97);\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__header {\n padding: 10px 14px;\n font-weight: 600;\n font-size: 14px;\n color: #2c3e50;\n background: rgba(0, 0, 0, 0.02);\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n letter-spacing: 0.2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 I/O Devices section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__io-section {\n position: relative;\n}\n\n.cp-tooltip__io-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n color: #666666;\n cursor: pointer;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.cp-tooltip__io-trigger:hover {\n background: rgba(0, 0, 0, 0.04);\n color: #333333;\n}\n\n.cp-tooltip__io-trigger-label {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.6px;\n font-weight: 500;\n}\n\n.cp-tooltip__io-arrow {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__io-arrow {\n transform: rotate(90deg);\n}\n\n/* \u2500\u2500 Device list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__device-list {\n max-height: 0;\n overflow: hidden;\n transition: max-height 0.25s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__device-list {\n max-height: 300px;\n}\n\n.cp-tooltip__device-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px 6px 20px;\n color: #555555;\n font-size: 12px;\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n transition: background 0.1s ease;\n}\n\n.cp-tooltip__device-item:hover {\n background: rgba(0, 0, 0, 0.03);\n}\n\n.cp-tooltip__device-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #1976d2;\n flex-shrink: 0;\n}\n\n.cp-tooltip__device-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Empty state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__no-devices {\n padding: 8px 14px;\n color: #888888;\n font-size: 12px;\n font-style: italic;\n}\n\n/* \u2500\u2500 Caret arrow pointing down \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__caret {\n width: 0;\n height: 0;\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-top: 7px solid rgba(255, 255, 255, 0.97);\n margin: 0 auto;\n position: relative;\n top: -1px;\n filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.1));\n}\n\n/* \u2500\u2500 Data point rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__dp-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 4px 12px 4px 30px;\n font-size: 11.5px;\n border-top: 1px solid rgba(0, 0, 0, 0.05);\n min-height: 24px;\n}\n\n.cp-tooltip__dp-name {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #666666;\n}\n\n/* Read-only state badge */\n.cp-tooltip__dp-badge {\n font-size: 10.5px;\n font-weight: 600;\n padding: 1px 7px;\n border-radius: 8px;\n flex-shrink: 0;\n background: #f0f2f5;\n color: #666666;\n min-width: 30px;\n text-align: center;\n letter-spacing: 0.2px;\n}\n\n.cp-tooltip__dp-badge.active {\n background: rgba(76, 175, 80, 0.15);\n color: #2e7d32;\n}\n\n/* Binary toggle button */\n.cp-tooltip__dp-toggle {\n font-size: 10.5px;\n font-weight: 600;\n padding: 2px 9px;\n border-radius: 8px;\n flex-shrink: 0;\n border: 1px solid #dddddd;\n background: #f8f9fa;\n color: #555555;\n cursor: pointer;\n min-width: 40px;\n text-align: center;\n transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;\n}\n\n.cp-tooltip__dp-toggle:hover {\n background: #eeeeee;\n border-color: #cccccc;\n}\n\n.cp-tooltip__dp-toggle.on {\n background: rgba(76, 175, 80, 0.15);\n border-color: rgba(76, 175, 80, 0.45);\n color: #2e7d32;\n}\n\n/* Number / float input */\n.cp-tooltip__dp-input {\n width: 62px;\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 5px;\n text-align: right;\n outline: none;\n flex-shrink: 0;\n}\n\n.cp-tooltip__dp-input:focus {\n border-color: #1976d2;\n}\n\n/* Enum select */\n.cp-tooltip__dp-select {\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 4px;\n outline: none;\n flex-shrink: 0;\n max-width: 96px;\n cursor: pointer;\n}\n\n.cp-tooltip__dp-select:focus {\n border-color: #1976d2;\n}\n\n/* Unit suffix */\n.cp-tooltip__dp-unit {\n font-size: 10px;\n color: #888888;\n flex-shrink: 0;\n margin-left: -4px;\n}\n";
9
9
  var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
10
10
  /**
11
11
  * @param {Object} sceneViewer - The sceneViewer instance
@@ -55,7 +55,8 @@ var SceneExportManager = /*#__PURE__*/function () {
55
55
  }, {
56
56
  key: "exportSceneData",
57
57
  value: function exportSceneData() {
58
- var _this = this;
58
+ var _this = this,
59
+ _this$sceneViewer$cur2;
59
60
  console.log('📤 Starting scene export...');
60
61
  if (!this.sceneViewer.scene) {
61
62
  console.warn('⚠️ No scene available for export');
@@ -267,6 +268,12 @@ var SceneExportManager = /*#__PURE__*/function () {
267
268
  children: sceneChildren
268
269
  }
269
270
  };
271
+
272
+ // Preserve cross-component behaviors authored in the Behavior window
273
+ var sceneBehaviors = (_this$sceneViewer$cur2 = this.sceneViewer.currentSceneData) === null || _this$sceneViewer$cur2 === void 0 ? void 0 : _this$sceneViewer$cur2.behaviors;
274
+ if (sceneBehaviors && sceneBehaviors.length > 0) {
275
+ exportData.behaviors = sceneBehaviors;
276
+ }
270
277
  console.log('✅ Scene export completed:', exportData);
271
278
  console.log("\uD83D\uDCCA Exported ".concat(sceneChildren.length, " components and ").concat(exportData.connections.length, " connections"));
272
279
  return exportData;
@@ -332,7 +339,7 @@ var SceneExportManager = /*#__PURE__*/function () {
332
339
  }, {
333
340
  key: "getExportMetadata",
334
341
  value: function getExportMetadata() {
335
- var _this$sceneViewer$cur2;
342
+ var _this$sceneViewer$cur3;
336
343
  if (!this.sceneViewer.scene) {
337
344
  return null;
338
345
  }
@@ -343,7 +350,7 @@ var SceneExportManager = /*#__PURE__*/function () {
343
350
  return {
344
351
  totalObjects: objectCount,
345
352
  hasCurrentSceneData: !!this.sceneViewer.currentSceneData,
346
- connectionsCount: ((_this$sceneViewer$cur2 = this.sceneViewer.currentSceneData) === null || _this$sceneViewer$cur2 === void 0 || (_this$sceneViewer$cur2 = _this$sceneViewer$cur2.connections) === null || _this$sceneViewer$cur2 === void 0 ? void 0 : _this$sceneViewer$cur2.length) || 0,
353
+ connectionsCount: ((_this$sceneViewer$cur3 = this.sceneViewer.currentSceneData) === null || _this$sceneViewer$cur3 === void 0 || (_this$sceneViewer$cur3 = _this$sceneViewer$cur3.connections) === null || _this$sceneViewer$cur3 === void 0 ? void 0 : _this$sceneViewer$cur3.length) || 0,
347
354
  exportTimestamp: new Date().toISOString()
348
355
  };
349
356
  }
@@ -873,7 +873,6 @@ var SceneOperationsManager = /*#__PURE__*/function () {
873
873
 
874
874
  // Check if dictionary has connector children and component doesn't already have them
875
875
  if (dictEntry !== null && dictEntry !== void 0 && dictEntry.children && Array.isArray(dictEntry.children) && dictEntry.children.length > 0) {
876
- // Only inject if the component doesn't already have children
877
876
  if (!child.children || child.children.length === 0) {
878
877
  // Get component rotation (in degrees from JSON)
879
878
  var rotation = child.rotation || {
@@ -903,7 +902,6 @@ var SceneOperationsManager = /*#__PURE__*/function () {
903
902
  connectorsInjected++;
904
903
  return clonedConnector;
905
904
  });
906
- console.log("\uD83D\uDD0C Injected ".concat(child.children.length, " connectors for ").concat(child.uuid, " (").concat(libraryId, ") with rotation [").concat(rotation.x, "\xB0, ").concat(rotation.y, "\xB0, ").concat(rotation.z, "\xB0]"));
907
905
  componentsProcessed++;
908
906
  }
909
907
  }