@2112-lab/central-plant 0.1.90 → 0.1.92

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.
@@ -28570,91 +28570,148 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
28570
28570
  * Attach IO device models to a smart component from cached models.
28571
28571
  * Each device referenced in componentData.attachedDevices is looked up
28572
28572
  * in the model preloader cache, cloned, positioned, and added as a child.
28573
+ * If a device model is not in cache, it will be preloaded first.
28573
28574
  *
28574
28575
  * @param {THREE.Object3D} componentModel - The parent component model
28575
28576
  * @param {Object} componentData - Component dictionary entry (has attachedDevices)
28576
28577
  * @param {Object} modelPreloader - ModelPreloader instance with cache and componentDictionary
28577
28578
  * @param {string} parentComponentId - The parent component's UUID
28578
- * @returns {void}
28579
+ * @returns {Promise<void>}
28579
28580
  */
28580
- function attachIODevicesToComponent(componentModel, componentData, modelPreloader, parentComponentId) {
28581
- var attachedDevices = componentData.attachedDevices;
28582
- if (!attachedDevices || Object.keys(attachedDevices).length === 0) {
28583
- return;
28584
- }
28585
- console.log("\uD83D\uDD0C attachIODevicesToComponent(): Attaching ".concat(Object.keys(attachedDevices).length, " IO devices to smart component"));
28586
- for (var _i = 0, _Object$entries = Object.entries(attachedDevices); _i < _Object$entries.length; _i++) {
28587
- var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
28588
- attachmentId = _Object$entries$_i[0],
28589
- attachment = _Object$entries$_i[1];
28590
- try {
28591
- var _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen;
28592
- var deviceData = (_modelPreloader$compo = modelPreloader.componentDictionary) === null || _modelPreloader$compo === void 0 ? void 0 : _modelPreloader$compo[attachment.deviceId];
28593
- if (!deviceData || !deviceData.modelKey) {
28594
- console.warn("\u26A0\uFE0F IO device ".concat(attachment.deviceId, " not found in dictionary, skipping"));
28595
- continue;
28596
- }
28597
- var cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId);
28598
- if (!cachedDevice) {
28599
- console.warn("\u26A0\uFE0F IO device model not in cache: ".concat(deviceData.modelKey, ", skipping"));
28600
- continue;
28601
- }
28602
-
28603
- // Clone so each component instance owns its own io-device subtree and materials.
28604
- // Without this, all placed copies of the same smart component share the cached
28605
- // object, causing material mutations (from behaviors) to bleed across instances.
28606
- var deviceModel = cachedDevice.clone();
28607
- deviceModel.traverse(function (child) {
28608
- if (child.isMesh && child.material) {
28609
- child.material = Array.isArray(child.material) ? child.material.map(function (m) {
28610
- return m.clone();
28611
- }) : child.material.clone();
28612
- }
28613
- });
28581
+ function attachIODevicesToComponent(_x, _x2, _x3, _x4) {
28582
+ return _attachIODevicesToComponent.apply(this, arguments);
28583
+ }
28584
+ function _attachIODevicesToComponent() {
28585
+ _attachIODevicesToComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(componentModel, componentData, modelPreloader, parentComponentId) {
28586
+ var attachedDevices, _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, _t, _t2;
28587
+ return _regenerator().w(function (_context) {
28588
+ while (1) switch (_context.n) {
28589
+ case 0:
28590
+ attachedDevices = componentData.attachedDevices;
28591
+ if (!(!attachedDevices || Object.keys(attachedDevices).length === 0)) {
28592
+ _context.n = 1;
28593
+ break;
28594
+ }
28595
+ return _context.a(2);
28596
+ case 1:
28597
+ console.log("\uD83D\uDD0C attachIODevicesToComponent(): Attaching ".concat(Object.keys(attachedDevices).length, " IO devices to smart component"));
28598
+ _i = 0, _Object$entries = Object.entries(attachedDevices);
28599
+ case 2:
28600
+ if (!(_i < _Object$entries.length)) {
28601
+ _context.n = 14;
28602
+ break;
28603
+ }
28604
+ _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), attachmentId = _Object$entries$_i[0], attachment = _Object$entries$_i[1];
28605
+ _context.p = 3;
28606
+ deviceData = (_modelPreloader$compo = modelPreloader.componentDictionary) === null || _modelPreloader$compo === void 0 ? void 0 : _modelPreloader$compo[attachment.deviceId];
28607
+ if (!(!deviceData || !deviceData.modelKey)) {
28608
+ _context.n = 4;
28609
+ break;
28610
+ }
28611
+ console.warn("\u26A0\uFE0F IO device ".concat(attachment.deviceId, " not found in dictionary, skipping"));
28612
+ return _context.a(3, 13);
28613
+ case 4:
28614
+ // Try to get from cache first
28615
+ cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId); // If not in cache, try to preload it
28616
+ if (cachedDevice) {
28617
+ _context.n = 10;
28618
+ break;
28619
+ }
28620
+ console.log("\uD83D\uDD04 IO device model not in cache, preloading: ".concat(deviceData.modelKey));
28621
+ _context.p = 5;
28622
+ if (!((_modelPreloader$loadi = modelPreloader.loadingPromises) !== null && _modelPreloader$loadi !== void 0 && _modelPreloader$loadi.has(deviceData.modelKey))) {
28623
+ _context.n = 7;
28624
+ break;
28625
+ }
28626
+ _context.n = 6;
28627
+ return modelPreloader.loadingPromises.get(deviceData.modelKey);
28628
+ case 6:
28629
+ _context.n = 8;
28630
+ break;
28631
+ case 7:
28632
+ _context.n = 8;
28633
+ return modelPreloader.preloadSingleModel(deviceData.modelKey);
28634
+ case 8:
28635
+ cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId);
28636
+ _context.n = 10;
28637
+ break;
28638
+ case 9:
28639
+ _context.p = 9;
28640
+ _t = _context.v;
28641
+ console.warn("\u26A0\uFE0F Failed to preload IO device model ".concat(deviceData.modelKey, ":"), _t);
28642
+ case 10:
28643
+ if (cachedDevice) {
28644
+ _context.n = 11;
28645
+ break;
28646
+ }
28647
+ console.warn("\u26A0\uFE0F IO device model could not be loaded: ".concat(deviceData.modelKey, ", skipping"));
28648
+ return _context.a(3, 13);
28649
+ case 11:
28650
+ // Clone so each component instance owns its own io-device subtree and materials.
28651
+ // Without this, all placed copies of the same smart component share the cached
28652
+ // object, causing material mutations (from behaviors) to bleed across instances.
28653
+ deviceModel = cachedDevice.clone();
28654
+ deviceModel.traverse(function (child) {
28655
+ if (child.isMesh && child.material) {
28656
+ child.material = Array.isArray(child.material) ? child.material.map(function (m) {
28657
+ return m.clone();
28658
+ }) : child.material.clone();
28659
+ }
28660
+ });
28614
28661
 
28615
- // Name the device model
28616
- deviceModel.name = "".concat(attachment.attachmentLabel || 'IO Device', " (").concat(attachmentId, ")");
28617
-
28618
- // Set user data for identification — include ioConfig data points so the
28619
- // component tooltip can render state displays without an extra lookup.
28620
- deviceModel.userData = {
28621
- objectType: 'io-device',
28622
- deviceId: attachment.deviceId,
28623
- attachmentId: attachmentId,
28624
- attachmentLabel: attachment.attachmentLabel,
28625
- parentComponentId: parentComponentId,
28626
- deviceName: deviceData.name || '',
28627
- // Snapshot of the device's data point definitions (stateType, stateConfig, direction, etc.)
28628
- // ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
28629
- dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
28630
- // Device-level I/O direction: 'input' means the user can write state via the tooltip
28631
- ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output',
28632
- // Signal wiring sourced from this attachment (for state propagation reference)
28633
- signalOutputs: attachment.signalOutputs || []
28634
- };
28662
+ // Name the device model
28663
+ deviceModel.name = "".concat(attachment.attachmentLabel || 'IO Device', " (").concat(attachmentId, ")");
28635
28664
 
28636
- // Position at the attachment point
28637
- if ((_attachment$attachmen = attachment.attachmentPoint) !== null && _attachment$attachmen !== void 0 && _attachment$attachmen.position) {
28638
- var pos = attachment.attachmentPoint.position;
28639
- deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
28640
- }
28665
+ // Set user data for identification — include ioConfig data points so the
28666
+ // component tooltip can render state displays without an extra lookup.
28667
+ deviceModel.userData = {
28668
+ objectType: 'io-device',
28669
+ deviceId: attachment.deviceId,
28670
+ attachmentId: attachmentId,
28671
+ attachmentLabel: attachment.attachmentLabel,
28672
+ parentComponentId: parentComponentId,
28673
+ deviceName: deviceData.name || '',
28674
+ // Snapshot of the device's data point definitions (stateType, stateConfig, direction, etc.)
28675
+ // ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
28676
+ dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
28677
+ // Device-level I/O direction: 'input' means the user can write state via the tooltip
28678
+ ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output'
28679
+ };
28641
28680
 
28642
- // IO device models are authored at the same real-world unit scale
28643
- // as the host component, so keep them at their natural (1:1) size.
28644
- // Note: attachmentPoint.scale is the connector marker sphere size,
28645
- // NOT a desired device model scale.
28646
- deviceModel.scale.setScalar(1);
28681
+ // Position at the attachment point
28682
+ if ((_attachment$attachmen = attachment.attachmentPoint) !== null && _attachment$attachmen !== void 0 && _attachment$attachmen.position) {
28683
+ pos = attachment.attachmentPoint.position;
28684
+ deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
28685
+ }
28647
28686
 
28648
- // Add as child of the component
28649
- componentModel.add(deviceModel);
28650
- console.log("\u2705 Attached IO device: ".concat(attachment.attachmentLabel || attachment.deviceId, " at"), {
28651
- position: deviceModel.position,
28652
- scale: deviceModel.scale
28653
- });
28654
- } catch (err) {
28655
- console.error("\u274C Error attaching IO device ".concat(attachment.deviceId, ":"), err);
28656
- }
28657
- }
28687
+ // IO device models are authored at the same real-world unit scale
28688
+ // as the host component, so keep them at their natural (1:1) size.
28689
+ // Note: attachmentPoint.scale is the connector marker sphere size,
28690
+ // NOT a desired device model scale.
28691
+ deviceModel.scale.setScalar(1);
28692
+
28693
+ // Add as child of the component
28694
+ componentModel.add(deviceModel);
28695
+ console.log("\u2705 Attached IO device: ".concat(attachment.attachmentLabel || attachment.deviceId, " at"), {
28696
+ position: deviceModel.position,
28697
+ scale: deviceModel.scale
28698
+ });
28699
+ _context.n = 13;
28700
+ break;
28701
+ case 12:
28702
+ _context.p = 12;
28703
+ _t2 = _context.v;
28704
+ console.error("\u274C Error attaching IO device ".concat(attachment.deviceId, ":"), _t2);
28705
+ case 13:
28706
+ _i++;
28707
+ _context.n = 2;
28708
+ break;
28709
+ case 14:
28710
+ return _context.a(2);
28711
+ }
28712
+ }, _callee, null, [[5, 9], [3, 12]]);
28713
+ }));
28714
+ return _attachIODevicesToComponent.apply(this, arguments);
28658
28715
  }
28659
28716
 
28660
28717
  var ModelManager = /*#__PURE__*/function () {
@@ -28741,21 +28798,24 @@ var ModelManager = /*#__PURE__*/function () {
28741
28798
  });
28742
28799
 
28743
28800
  // Attach IO devices for smart components (import flow)
28744
- if (componentData.isSmart && componentData.attachedDevices) {
28745
- attachIODevicesToComponent(libraryModel, componentData, modelPreloader, originalProps.uuid);
28801
+ if (!(componentData.isSmart && componentData.attachedDevices)) {
28802
+ _context.n = 4;
28803
+ break;
28746
28804
  }
28747
-
28805
+ _context.n = 4;
28806
+ return attachIODevicesToComponent(libraryModel, componentData, modelPreloader, originalProps.uuid);
28807
+ case 4:
28748
28808
  // Replace mesh in scene
28749
28809
  this._replaceMeshInScene(targetMesh, libraryModel, originalProps.parent, component);
28750
28810
  console.log("\uD83C\uDF89 ".concat((_jsonEntry$userData3 = jsonEntry.userData) === null || _jsonEntry$userData3 === void 0 ? void 0 : _jsonEntry$userData3.libraryId, " GLB model successfully rendered in scene"));
28751
28811
  return _context.a(2, libraryModel);
28752
- case 4:
28753
- _context.p = 4;
28812
+ case 5:
28813
+ _context.p = 5;
28754
28814
  _t = _context.v;
28755
28815
  console.error("\u274C Error loading ".concat((_jsonEntry$userData4 = jsonEntry.userData) === null || _jsonEntry$userData4 === void 0 ? void 0 : _jsonEntry$userData4.libraryId, " GLB model:"), _t);
28756
28816
  return _context.a(2, targetMesh);
28757
28817
  }
28758
- }, _callee, this, [[1, 4]]);
28818
+ }, _callee, this, [[1, 5]]);
28759
28819
  }));
28760
28820
  function loadLibraryModel(_x, _x2, _x3) {
28761
28821
  return _loadLibraryModel.apply(this, arguments);
@@ -32251,8 +32311,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
32251
32311
  // ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
32252
32312
  dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
32253
32313
  // Device-level I/O direction: 'input' means the user can write state via the tooltip
32254
- ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output',
32255
- signalOutputs: attachment.signalOutputs || []
32314
+ ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output'
32256
32315
  };
32257
32316
  if ((_attachment$attachmen = attachment.attachmentPoint) !== null && _attachment$attachmen !== void 0 && _attachment$attachmen.position) {
32258
32317
  pos = attachment.attachmentPoint.position;
@@ -36814,7 +36873,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
36814
36873
  * Initialize the CentralPlant manager
36815
36874
  *
36816
36875
  * @constructor
36817
- * @version 0.1.90
36876
+ * @version 0.1.92
36818
36877
  * @updated 2025-10-22
36819
36878
  *
36820
36879
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -37890,6 +37949,337 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
37890
37949
  return results;
37891
37950
  }
37892
37951
 
37952
+ // ===== I/O DEVICE ASSET API =====
37953
+
37954
+ /**
37955
+ * Set the asset service for I/O device attachment operations.
37956
+ * The service handles S3 storage and Vuex state updates so that
37957
+ * the central-plant package stays free of sandbox-specific dependencies.
37958
+ * @param {Object} service - Object with createSmartComponent, addComponentAttachment, removeComponentAttachment methods
37959
+ * @example
37960
+ * import { createAssetService } from '~/services/AssetService'
37961
+ * centralPlant.setAssetService(createAssetService(store))
37962
+ */
37963
+ }, {
37964
+ key: "setAssetService",
37965
+ value: function setAssetService(service) {
37966
+ if (!service || _typeof(service) !== 'object') {
37967
+ console.warn('⚠️ setAssetService(): service must be an object');
37968
+ return;
37969
+ }
37970
+ this.assetService = service;
37971
+ console.log('✅ Asset service set');
37972
+ }
37973
+
37974
+ /**
37975
+ * List all available I/O Device assets from the component dictionary.
37976
+ * @param {Object} [options={}]
37977
+ * @param {'all'|'bundled'|'user'} [options.source='all'] - Filter by asset origin
37978
+ * @returns {Array<{uuid: string, name: string, assetType: string, ioConfig: Object}>}
37979
+ * @example
37980
+ * const devices = centralPlant.getIoDevices({ source: 'all' })
37981
+ * const bundledOnly = centralPlant.getIoDevices({ source: 'bundled' })
37982
+ */
37983
+ }, {
37984
+ key: "getIoDevices",
37985
+ value: function getIoDevices() {
37986
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
37987
+ _ref$source = _ref.source,
37988
+ source = _ref$source === void 0 ? 'all' : _ref$source;
37989
+ var mp = this.getUtility('modelPreloader');
37990
+ var dict = mp === null || mp === void 0 ? void 0 : mp.componentDictionary;
37991
+ if (!dict) {
37992
+ console.warn('⚠️ getIoDevices(): component dictionary not loaded');
37993
+ return [];
37994
+ }
37995
+ return Object.values(dict).filter(function (entry) {
37996
+ return entry.assetType === 'I/O Device';
37997
+ }).filter(function (entry) {
37998
+ if (source === 'bundled') return !entry.isS3Component;
37999
+ if (source === 'user') return entry.isS3Component === true;
38000
+ return true; // 'all'
38001
+ }).map(function (entry) {
38002
+ return {
38003
+ uuid: entry.uuid || entry.id,
38004
+ name: entry.name,
38005
+ assetType: entry.assetType,
38006
+ ioConfig: entry.ioConfig || {}
38007
+ };
38008
+ });
38009
+ }
38010
+
38011
+ /**
38012
+ * Return a list of smart components that reference a given I/O Device.
38013
+ * Useful for enforcing deletion guards.
38014
+ * @param {Object} options
38015
+ * @param {string} options.deviceUuid - UUID of the I/O Device asset to check
38016
+ * @returns {Array<{componentId: string, componentName: string}>}
38017
+ * @example
38018
+ * const usage = centralPlant.getIoDeviceUsage({ deviceUuid: 'io-def-push-button' })
38019
+ * // [{ componentId: 'comp-smart-pump-01', componentName: 'Smart Pump' }]
38020
+ */
38021
+ }, {
38022
+ key: "getIoDeviceUsage",
38023
+ value: function getIoDeviceUsage() {
38024
+ var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
38025
+ deviceUuid = _ref2.deviceUuid;
38026
+ if (!deviceUuid) {
38027
+ console.warn('⚠️ getIoDeviceUsage(): deviceUuid is required');
38028
+ return [];
38029
+ }
38030
+ var mp = this.getUtility('modelPreloader');
38031
+ var dict = mp === null || mp === void 0 ? void 0 : mp.componentDictionary;
38032
+ if (!dict) {
38033
+ console.warn('⚠️ getIoDeviceUsage(): component dictionary not loaded');
38034
+ return [];
38035
+ }
38036
+ var results = [];
38037
+ Object.values(dict).forEach(function (entry) {
38038
+ if (!entry.isSmart || !entry.attachedDevices) return;
38039
+ var uses = Object.values(entry.attachedDevices).some(function (att) {
38040
+ return att.deviceId === deviceUuid;
38041
+ });
38042
+ if (uses) {
38043
+ results.push({
38044
+ componentId: entry.uuid || entry.id,
38045
+ componentName: entry.name || ''
38046
+ });
38047
+ }
38048
+ });
38049
+ return results;
38050
+ }
38051
+
38052
+ /**
38053
+ * Create a new smart component asset by attaching I/O devices to an existing component.
38054
+ * Requires setAssetService() to have been called first.
38055
+ * @param {Object} options
38056
+ * @param {string} options.componentUuid - UUID of the base component to promote
38057
+ * @param {string} [options.name] - Display name for the new smart component (auto-deduped)
38058
+ * @param {Array} options.attachments - Attachment descriptors (attachmentId, deviceId, attachmentLabel, attachmentPoint)
38059
+ * @param {Blob} [options.thumbnailBlob] - Optional thumbnail image blob
38060
+ * @returns {Promise<Object>} The new smart component asset object
38061
+ * @example
38062
+ * const newAsset = await centralPlant.createSmartComponent({
38063
+ * componentUuid: 'comp-base-pump-01',
38064
+ * name: 'Smart Pump A',
38065
+ * attachments: [{
38066
+ * attachmentId: 'attch-button-01',
38067
+ * deviceId: 'io-def-push-button',
38068
+ * attachmentLabel: 'Power Button',
38069
+ * attachmentPoint: { position: { x: -0.1, y: 0.3, z: 0.0 }, direction: { x: 0.0, y: 1.0, z: 0.0 } }
38070
+ * }]
38071
+ * })
38072
+ */
38073
+ }, {
38074
+ key: "createSmartComponent",
38075
+ value: (function () {
38076
+ var _createSmartComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
38077
+ var _ref3,
38078
+ componentUuid,
38079
+ name,
38080
+ attachments,
38081
+ thumbnailBlob,
38082
+ newAsset,
38083
+ mp,
38084
+ _args3 = arguments;
38085
+ return _regenerator().w(function (_context3) {
38086
+ while (1) switch (_context3.n) {
38087
+ case 0:
38088
+ _ref3 = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {}, componentUuid = _ref3.componentUuid, name = _ref3.name, attachments = _ref3.attachments, thumbnailBlob = _ref3.thumbnailBlob;
38089
+ if (this.assetService) {
38090
+ _context3.n = 1;
38091
+ break;
38092
+ }
38093
+ throw new Error('createSmartComponent(): no asset service set — call setAssetService() first');
38094
+ case 1:
38095
+ if (componentUuid) {
38096
+ _context3.n = 2;
38097
+ break;
38098
+ }
38099
+ throw new Error('createSmartComponent(): componentUuid is required');
38100
+ case 2:
38101
+ if (!(!Array.isArray(attachments) || attachments.length === 0)) {
38102
+ _context3.n = 3;
38103
+ break;
38104
+ }
38105
+ throw new Error('createSmartComponent(): at least one attachment is required');
38106
+ case 3:
38107
+ _context3.n = 4;
38108
+ return this.assetService.createSmartComponent({
38109
+ componentUuid: componentUuid,
38110
+ name: name,
38111
+ attachments: attachments,
38112
+ thumbnailBlob: thumbnailBlob
38113
+ });
38114
+ case 4:
38115
+ newAsset = _context3.v;
38116
+ // Register in model preloader dictionary so addComponent() can use it immediately
38117
+ mp = this.getUtility('modelPreloader');
38118
+ if (mp !== null && mp !== void 0 && mp.componentDictionary && newAsset !== null && newAsset !== void 0 && newAsset.uuid) {
38119
+ mp.componentDictionary[newAsset.uuid] = _objectSpread2(_objectSpread2({}, newAsset), {}, {
38120
+ id: newAsset.uuid
38121
+ });
38122
+ console.log("\u2705 createSmartComponent(): registered \"".concat(newAsset.name, "\" in component dictionary"));
38123
+ }
38124
+ return _context3.a(2, newAsset);
38125
+ }
38126
+ }, _callee3, this);
38127
+ }));
38128
+ function createSmartComponent() {
38129
+ return _createSmartComponent.apply(this, arguments);
38130
+ }
38131
+ return createSmartComponent;
38132
+ }()
38133
+ /**
38134
+ * Add or update a single I/O device attachment on an existing smart component.
38135
+ * Requires setAssetService() to have been called first.
38136
+ * Updates S3 data and Vuex store only — does NOT update live scene objects.
38137
+ * @param {Object} options
38138
+ * @param {string} options.componentUuid - UUID of the smart component to update
38139
+ * @param {Object} options.attachment - Attachment descriptor
38140
+ * @param {string} options.attachment.attachmentId - Globally unique attachment key
38141
+ * @param {string} options.attachment.deviceId - UUID of the I/O Device asset
38142
+ * @param {string} options.attachment.attachmentLabel - Human-readable label
38143
+ * @param {Object} [options.attachment.attachmentPoint] - Position/direction on the model
38144
+ * @returns {Promise<Object>} The updated smart component asset object
38145
+ * @example
38146
+ * await centralPlant.addComponentAttachment({
38147
+ * componentUuid: 'comp-smart-pump-01',
38148
+ * attachment: {
38149
+ * attachmentId: 'attch-led-01',
38150
+ * deviceId: 'io-def-signal-light',
38151
+ * attachmentLabel: 'Status LED',
38152
+ * attachmentPoint: { position: { x: 0.1, y: 0.3, z: 0.0 }, direction: { x: 0.0, y: 1.0, z: 0.0 } }
38153
+ * }
38154
+ * })
38155
+ */
38156
+ )
38157
+ }, {
38158
+ key: "addComponentAttachment",
38159
+ value: (function () {
38160
+ var _addComponentAttachment = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
38161
+ var _ref4,
38162
+ componentUuid,
38163
+ attachment,
38164
+ updatedAsset,
38165
+ mp,
38166
+ _args4 = arguments;
38167
+ return _regenerator().w(function (_context4) {
38168
+ while (1) switch (_context4.n) {
38169
+ case 0:
38170
+ _ref4 = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {}, componentUuid = _ref4.componentUuid, attachment = _ref4.attachment;
38171
+ if (this.assetService) {
38172
+ _context4.n = 1;
38173
+ break;
38174
+ }
38175
+ throw new Error('addComponentAttachment(): no asset service set — call setAssetService() first');
38176
+ case 1:
38177
+ if (componentUuid) {
38178
+ _context4.n = 2;
38179
+ break;
38180
+ }
38181
+ throw new Error('addComponentAttachment(): componentUuid is required');
38182
+ case 2:
38183
+ if (!(!(attachment !== null && attachment !== void 0 && attachment.attachmentId) || !(attachment !== null && attachment !== void 0 && attachment.deviceId))) {
38184
+ _context4.n = 3;
38185
+ break;
38186
+ }
38187
+ throw new Error('addComponentAttachment(): attachment must have attachmentId and deviceId');
38188
+ case 3:
38189
+ _context4.n = 4;
38190
+ return this.assetService.addComponentAttachment({
38191
+ componentUuid: componentUuid,
38192
+ attachment: attachment
38193
+ });
38194
+ case 4:
38195
+ updatedAsset = _context4.v;
38196
+ // Sync component dictionary
38197
+ mp = this.getUtility('modelPreloader');
38198
+ if (mp !== null && mp !== void 0 && mp.componentDictionary && updatedAsset !== null && updatedAsset !== void 0 && updatedAsset.uuid) {
38199
+ mp.componentDictionary[updatedAsset.uuid] = _objectSpread2(_objectSpread2(_objectSpread2({}, mp.componentDictionary[updatedAsset.uuid] || {}), updatedAsset), {}, {
38200
+ id: updatedAsset.uuid
38201
+ });
38202
+ }
38203
+ return _context4.a(2, updatedAsset);
38204
+ }
38205
+ }, _callee4, this);
38206
+ }));
38207
+ function addComponentAttachment() {
38208
+ return _addComponentAttachment.apply(this, arguments);
38209
+ }
38210
+ return addComponentAttachment;
38211
+ }()
38212
+ /**
38213
+ * Remove a single I/O device attachment from a smart component.
38214
+ * Requires setAssetService() to have been called first.
38215
+ * If this is the last attachment the component is demoted to a plain component.
38216
+ * Updates S3 data and Vuex store only — does NOT update live scene objects.
38217
+ * @param {Object} options
38218
+ * @param {string} options.componentUuid - UUID of the smart component to update
38219
+ * @param {string} options.attachmentId - The attachmentId key to remove
38220
+ * @returns {Promise<Object>} The updated component asset object
38221
+ * @example
38222
+ * await centralPlant.removeComponentAttachment({
38223
+ * componentUuid: 'comp-smart-pump-01',
38224
+ * attachmentId: 'attch-led-01'
38225
+ * })
38226
+ */
38227
+ )
38228
+ }, {
38229
+ key: "removeComponentAttachment",
38230
+ value: (function () {
38231
+ var _removeComponentAttachment = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
38232
+ var _ref5,
38233
+ componentUuid,
38234
+ attachmentId,
38235
+ updatedAsset,
38236
+ mp,
38237
+ _args5 = arguments;
38238
+ return _regenerator().w(function (_context5) {
38239
+ while (1) switch (_context5.n) {
38240
+ case 0:
38241
+ _ref5 = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : {}, componentUuid = _ref5.componentUuid, attachmentId = _ref5.attachmentId;
38242
+ if (this.assetService) {
38243
+ _context5.n = 1;
38244
+ break;
38245
+ }
38246
+ throw new Error('removeComponentAttachment(): no asset service set — call setAssetService() first');
38247
+ case 1:
38248
+ if (componentUuid) {
38249
+ _context5.n = 2;
38250
+ break;
38251
+ }
38252
+ throw new Error('removeComponentAttachment(): componentUuid is required');
38253
+ case 2:
38254
+ if (attachmentId) {
38255
+ _context5.n = 3;
38256
+ break;
38257
+ }
38258
+ throw new Error('removeComponentAttachment(): attachmentId is required');
38259
+ case 3:
38260
+ _context5.n = 4;
38261
+ return this.assetService.removeComponentAttachment({
38262
+ componentUuid: componentUuid,
38263
+ attachmentId: attachmentId
38264
+ });
38265
+ case 4:
38266
+ updatedAsset = _context5.v;
38267
+ // Sync component dictionary
38268
+ mp = this.getUtility('modelPreloader');
38269
+ if (mp !== null && mp !== void 0 && mp.componentDictionary && updatedAsset !== null && updatedAsset !== void 0 && updatedAsset.uuid) {
38270
+ mp.componentDictionary[updatedAsset.uuid] = _objectSpread2(_objectSpread2(_objectSpread2({}, mp.componentDictionary[updatedAsset.uuid] || {}), updatedAsset), {}, {
38271
+ id: updatedAsset.uuid
38272
+ });
38273
+ }
38274
+ return _context5.a(2, updatedAsset);
38275
+ }
38276
+ }, _callee5, this);
38277
+ }));
38278
+ function removeComponentAttachment() {
38279
+ return _removeComponentAttachment.apply(this, arguments);
38280
+ }
38281
+ return removeComponentAttachment;
38282
+ }()
37893
38283
  /**
37894
38284
  * Get all component IDs from the scene
37895
38285
  * @returns {Array<string>} Array of component UUID strings, or empty array if none exist
@@ -37907,6 +38297,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
37907
38297
  * // Check if specific component exists
37908
38298
  * const hasChiller = componentIds.some(id => id.includes('chiller'));
37909
38299
  */
38300
+ )
37910
38301
  }, {
37911
38302
  key: "getComponentIds",
37912
38303
  value: function getComponentIds() {
@@ -38075,41 +38466,41 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38075
38466
  }, {
38076
38467
  key: "getComponents",
38077
38468
  value: (function () {
38078
- var _getComponents = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
38469
+ var _getComponents = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
38079
38470
  var options,
38080
38471
  validation,
38081
38472
  enhancedOptions,
38082
- _args3 = arguments,
38473
+ _args6 = arguments,
38083
38474
  _t;
38084
- return _regenerator().w(function (_context3) {
38085
- while (1) switch (_context3.n) {
38475
+ return _regenerator().w(function (_context6) {
38476
+ while (1) switch (_context6.n) {
38086
38477
  case 0:
38087
- options = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {};
38478
+ options = _args6.length > 0 && _args6[0] !== undefined ? _args6[0] : {};
38088
38479
  // Validate filter options using centralized validator
38089
38480
  validation = this.internals.validator.validateComponentFilter(options);
38090
38481
  if (validation.isValid) {
38091
- _context3.n = 1;
38482
+ _context6.n = 1;
38092
38483
  break;
38093
38484
  }
38094
38485
  console.warn('⚠️ getComponents(): Invalid filter options provided:', validation.message);
38095
- return _context3.a(2, []);
38486
+ return _context6.a(2, []);
38096
38487
  case 1:
38097
- _context3.p = 1;
38488
+ _context6.p = 1;
38098
38489
  // Always include metadata
38099
38490
  enhancedOptions = _objectSpread2(_objectSpread2({}, options), {}, {
38100
38491
  includeMetadata: true
38101
38492
  });
38102
- _context3.n = 2;
38493
+ _context6.n = 2;
38103
38494
  return this.managers.componentDataManager.getDictionaryComponents(enhancedOptions);
38104
38495
  case 2:
38105
- return _context3.a(2, _context3.v);
38496
+ return _context6.a(2, _context6.v);
38106
38497
  case 3:
38107
- _context3.p = 3;
38108
- _t = _context3.v;
38498
+ _context6.p = 3;
38499
+ _t = _context6.v;
38109
38500
  console.error('❌ getDictionaryComponents(): Error retrieving available components:', _t);
38110
- return _context3.a(2, []);
38501
+ return _context6.a(2, []);
38111
38502
  }
38112
- }, _callee3, this, [[1, 3]]);
38503
+ }, _callee6, this, [[1, 3]]);
38113
38504
  }));
38114
38505
  function getComponents() {
38115
38506
  return _getComponents.apply(this, arguments);
@@ -38212,23 +38603,23 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38212
38603
  }, {
38213
38604
  key: "extendComponentDictionary",
38214
38605
  value: (function () {
38215
- var _extendComponentDictionary = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(additionalComponents) {
38216
- return _regenerator().w(function (_context4) {
38217
- while (1) switch (_context4.n) {
38606
+ var _extendComponentDictionary = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(additionalComponents) {
38607
+ return _regenerator().w(function (_context7) {
38608
+ while (1) switch (_context7.n) {
38218
38609
  case 0:
38219
38610
  if (this.managers.componentDataManager) {
38220
- _context4.n = 1;
38611
+ _context7.n = 1;
38221
38612
  break;
38222
38613
  }
38223
38614
  console.warn('⚠️ extendComponentDictionary(): Component data manager not available');
38224
- return _context4.a(2, false);
38615
+ return _context7.a(2, false);
38225
38616
  case 1:
38226
- _context4.n = 2;
38617
+ _context7.n = 2;
38227
38618
  return this.managers.componentDataManager.extendComponentDictionary(additionalComponents);
38228
38619
  case 2:
38229
- return _context4.a(2, _context4.v);
38620
+ return _context7.a(2, _context7.v);
38230
38621
  }
38231
- }, _callee4, this);
38622
+ }, _callee7, this);
38232
38623
  }));
38233
38624
  function extendComponentDictionary(_x3) {
38234
38625
  return _extendComponentDictionary.apply(this, arguments);
@@ -38251,23 +38642,23 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38251
38642
  }, {
38252
38643
  key: "removeS3Components",
38253
38644
  value: (function () {
38254
- var _removeS3Components = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
38255
- return _regenerator().w(function (_context5) {
38256
- while (1) switch (_context5.n) {
38645
+ var _removeS3Components = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
38646
+ return _regenerator().w(function (_context8) {
38647
+ while (1) switch (_context8.n) {
38257
38648
  case 0:
38258
38649
  if (this.managers.componentDataManager) {
38259
- _context5.n = 1;
38650
+ _context8.n = 1;
38260
38651
  break;
38261
38652
  }
38262
38653
  console.warn('⚠️ removeS3Components(): Component data manager not available');
38263
- return _context5.a(2, false);
38654
+ return _context8.a(2, false);
38264
38655
  case 1:
38265
- _context5.n = 2;
38656
+ _context8.n = 2;
38266
38657
  return this.managers.componentDataManager.removeS3Components();
38267
38658
  case 2:
38268
- return _context5.a(2, _context5.v);
38659
+ return _context8.a(2, _context8.v);
38269
38660
  }
38270
- }, _callee5, this);
38661
+ }, _callee8, this);
38271
38662
  }));
38272
38663
  function removeS3Components() {
38273
38664
  return _removeS3Components.apply(this, arguments);
@@ -38291,23 +38682,23 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38291
38682
  }, {
38292
38683
  key: "removeComponentFromDictionary",
38293
38684
  value: (function () {
38294
- var _removeComponentFromDictionary = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(componentKey) {
38295
- return _regenerator().w(function (_context6) {
38296
- while (1) switch (_context6.n) {
38685
+ var _removeComponentFromDictionary = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9(componentKey) {
38686
+ return _regenerator().w(function (_context9) {
38687
+ while (1) switch (_context9.n) {
38297
38688
  case 0:
38298
38689
  if (this.managers.componentDataManager) {
38299
- _context6.n = 1;
38690
+ _context9.n = 1;
38300
38691
  break;
38301
38692
  }
38302
38693
  console.warn('⚠️ removeComponentFromDictionary(): Component data manager not available');
38303
- return _context6.a(2, false);
38694
+ return _context9.a(2, false);
38304
38695
  case 1:
38305
- _context6.n = 2;
38696
+ _context9.n = 2;
38306
38697
  return this.managers.componentDataManager.removeComponentFromDictionary(componentKey);
38307
38698
  case 2:
38308
- return _context6.a(2, _context6.v);
38699
+ return _context9.a(2, _context9.v);
38309
38700
  }
38310
- }, _callee6, this);
38701
+ }, _callee9, this);
38311
38702
  }));
38312
38703
  function removeComponentFromDictionary(_x4) {
38313
38704
  return _removeComponentFromDictionary.apply(this, arguments);
@@ -38554,49 +38945,49 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38554
38945
  }, {
38555
38946
  key: "initialize2DViewport",
38556
38947
  value: function () {
38557
- var _initialize2DViewport = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(container) {
38948
+ var _initialize2DViewport = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0(container) {
38558
38949
  var viewType,
38559
38950
  instanceKey,
38560
38951
  success,
38561
- _args7 = arguments,
38952
+ _args0 = arguments,
38562
38953
  _t2;
38563
- return _regenerator().w(function (_context7) {
38564
- while (1) switch (_context7.n) {
38954
+ return _regenerator().w(function (_context0) {
38955
+ while (1) switch (_context0.n) {
38565
38956
  case 0:
38566
- viewType = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : 'top';
38567
- instanceKey = _args7.length > 2 && _args7[2] !== undefined ? _args7[2] : null;
38957
+ viewType = _args0.length > 1 && _args0[1] !== undefined ? _args0[1] : 'top';
38958
+ instanceKey = _args0.length > 2 && _args0[2] !== undefined ? _args0[2] : null;
38568
38959
  if (container) {
38569
- _context7.n = 1;
38960
+ _context0.n = 1;
38570
38961
  break;
38571
38962
  }
38572
38963
  console.warn('⚠️ initialize2DViewport(): No container provided');
38573
- return _context7.a(2, false);
38964
+ return _context0.a(2, false);
38574
38965
  case 1:
38575
38966
  if (this.managers.viewport2DManager) {
38576
- _context7.n = 2;
38967
+ _context0.n = 2;
38577
38968
  break;
38578
38969
  }
38579
38970
  console.warn('⚠️ initialize2DViewport(): Viewport2D manager not available');
38580
- return _context7.a(2, false);
38971
+ return _context0.a(2, false);
38581
38972
  case 2:
38582
- _context7.p = 2;
38583
- _context7.n = 3;
38973
+ _context0.p = 2;
38974
+ _context0.n = 3;
38584
38975
  return this.managers.viewport2DManager.initialize(container, viewType, instanceKey);
38585
38976
  case 3:
38586
- success = _context7.v;
38977
+ success = _context0.v;
38587
38978
  if (success) {
38588
38979
  console.log("\u2705 2D viewport initialized successfully (".concat(viewType, " view, key: ").concat(instanceKey || viewType, ")"));
38589
38980
  } else {
38590
38981
  console.warn("\u26A0\uFE0F Failed to initialize 2D viewport (".concat(viewType, " view)"));
38591
38982
  }
38592
- return _context7.a(2, success);
38983
+ return _context0.a(2, success);
38593
38984
  case 4:
38594
- _context7.p = 4;
38595
- _t2 = _context7.v;
38985
+ _context0.p = 4;
38986
+ _t2 = _context0.v;
38596
38987
  console.error('❌ initialize2DViewport(): Error initializing 2D viewport:', _t2);
38597
- return _context7.a(2, false);
38988
+ return _context0.a(2, false);
38598
38989
  }
38599
- }, _callee7, this, [[2, 4]]);
38990
+ }, _callee0, this, [[2, 4]]);
38600
38991
  }));
38601
38992
  function initialize2DViewport(_x5) {
38602
38993
  return _initialize2DViewport.apply(this, arguments);
@@ -38744,7 +39135,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38744
39135
  }, {
38745
39136
  key: "initializeModelPreloading",
38746
39137
  value: (function () {
38747
- var _initializeModelPreloading = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
39138
+ var _initializeModelPreloading = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee1() {
38748
39139
  var basePath,
38749
39140
  normalizedBasePath,
38750
39141
  dictionaryPath,
@@ -38753,13 +39144,13 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38753
39144
  componentDictionary,
38754
39145
  _modelPreloader2,
38755
39146
  progress,
38756
- _args8 = arguments,
39147
+ _args1 = arguments,
38757
39148
  _t3;
38758
- return _regenerator().w(function (_context8) {
38759
- while (1) switch (_context8.n) {
39149
+ return _regenerator().w(function (_context1) {
39150
+ while (1) switch (_context1.n) {
38760
39151
  case 0:
38761
- basePath = _args8.length > 0 && _args8[0] !== undefined ? _args8[0] : '/library/';
38762
- _context8.p = 1;
39152
+ basePath = _args1.length > 0 && _args1[0] !== undefined ? _args1[0] : '/library/';
39153
+ _context1.p = 1;
38763
39154
  // Ensure basePath ends with a slash
38764
39155
  normalizedBasePath = basePath.endsWith('/') ? basePath : "".concat(basePath, "/");
38765
39156
  dictionaryPath = "".concat(normalizedBasePath, "component-dictionary.json");
@@ -38770,39 +39161,39 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38770
39161
  console.log("\uFFFD Models path: ".concat(modelsBasePath));
38771
39162
 
38772
39163
  // Load the component dictionary
38773
- _context8.n = 2;
39164
+ _context1.n = 2;
38774
39165
  return fetch(dictionaryPath);
38775
39166
  case 2:
38776
- response = _context8.v;
39167
+ response = _context1.v;
38777
39168
  if (response.ok) {
38778
- _context8.n = 3;
39169
+ _context1.n = 3;
38779
39170
  break;
38780
39171
  }
38781
39172
  throw new Error("Failed to load component dictionary: ".concat(response.status));
38782
39173
  case 3:
38783
- _context8.n = 4;
39174
+ _context1.n = 4;
38784
39175
  return response.json();
38785
39176
  case 4:
38786
- componentDictionary = _context8.v;
39177
+ componentDictionary = _context1.v;
38787
39178
  console.log('📚 Component dictionary loaded:', Object.keys(componentDictionary));
38788
39179
 
38789
39180
  // Start preloading all models with the specified base path
38790
39181
  _modelPreloader2 = this.getUtility('modelPreloader');
38791
- _context8.n = 5;
39182
+ _context1.n = 5;
38792
39183
  return _modelPreloader2.preloadAllModels(componentDictionary, modelsBasePath);
38793
39184
  case 5:
38794
- progress = _context8.v;
39185
+ progress = _context1.v;
38795
39186
  console.log('🎉 Model preloading completed:', progress);
38796
- return _context8.a(2, progress);
39187
+ return _context1.a(2, progress);
38797
39188
  case 6:
38798
- _context8.p = 6;
38799
- _t3 = _context8.v;
39189
+ _context1.p = 6;
39190
+ _t3 = _context1.v;
38800
39191
  console.error('❌ Failed to initialize model preloading:', _t3);
38801
39192
  throw _t3;
38802
39193
  case 7:
38803
- return _context8.a(2);
39194
+ return _context1.a(2);
38804
39195
  }
38805
- }, _callee8, this, [[1, 6]]);
39196
+ }, _callee1, this, [[1, 6]]);
38806
39197
  }));
38807
39198
  function initializeModelPreloading() {
38808
39199
  return _initializeModelPreloading.apply(this, arguments);
@@ -38819,55 +39210,55 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38819
39210
  }, {
38820
39211
  key: "importScene",
38821
39212
  value: (function () {
38822
- var _importScene = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9(jsonData) {
39213
+ var _importScene = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee10(jsonData) {
38823
39214
  var validation, _t4;
38824
- return _regenerator().w(function (_context9) {
38825
- while (1) switch (_context9.n) {
39215
+ return _regenerator().w(function (_context10) {
39216
+ while (1) switch (_context10.n) {
38826
39217
  case 0:
38827
39218
  if (jsonData) {
38828
- _context9.n = 1;
39219
+ _context10.n = 1;
38829
39220
  break;
38830
39221
  }
38831
39222
  console.error('❌ No JSON data provided for import');
38832
- return _context9.a(2, false);
39223
+ return _context10.a(2, false);
38833
39224
  case 1:
38834
- _context9.p = 1;
39225
+ _context10.p = 1;
38835
39226
  // Validate scene data structure
38836
39227
  validation = this.internals.validateAndAnalyzeSceneData(jsonData);
38837
39228
  if (validation.isValid) {
38838
- _context9.n = 2;
39229
+ _context10.n = 2;
38839
39230
  break;
38840
39231
  }
38841
39232
  console.error('❌ Invalid scene data format:', validation.message);
38842
- return _context9.a(2, false);
39233
+ return _context10.a(2, false);
38843
39234
  case 2:
38844
- _context9.n = 3;
39235
+ _context10.n = 3;
38845
39236
  return this.setImportedSceneData(jsonData);
38846
39237
  case 3:
38847
39238
  if (!(this.sceneViewer && this.sceneViewer.sceneOperationsManager)) {
38848
- _context9.n = 5;
39239
+ _context10.n = 5;
38849
39240
  break;
38850
39241
  }
38851
- _context9.n = 4;
39242
+ _context10.n = 4;
38852
39243
  return this.sceneViewer.sceneOperationsManager.loadSceneFromData(jsonData);
38853
39244
  case 4:
38854
39245
  console.log('✅ Scene imported successfully');
38855
- return _context9.a(2, true);
39246
+ return _context10.a(2, true);
38856
39247
  case 5:
38857
39248
  console.error('❌ SceneViewer not available for scene loading');
38858
- return _context9.a(2, false);
39249
+ return _context10.a(2, false);
38859
39250
  case 6:
38860
- _context9.n = 8;
39251
+ _context10.n = 8;
38861
39252
  break;
38862
39253
  case 7:
38863
- _context9.p = 7;
38864
- _t4 = _context9.v;
39254
+ _context10.p = 7;
39255
+ _t4 = _context10.v;
38865
39256
  console.error('❌ Error importing scene:', _t4);
38866
- return _context9.a(2, false);
39257
+ return _context10.a(2, false);
38867
39258
  case 8:
38868
- return _context9.a(2);
39259
+ return _context10.a(2);
38869
39260
  }
38870
- }, _callee9, this, [[1, 7]]);
39261
+ }, _callee10, this, [[1, 7]]);
38871
39262
  }));
38872
39263
  function importScene(_x6) {
38873
39264
  return _importScene.apply(this, arguments);
@@ -38891,33 +39282,33 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38891
39282
  }, {
38892
39283
  key: "exportSceneJSON",
38893
39284
  value: (function () {
38894
- var _exportSceneJSON = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee0() {
39285
+ var _exportSceneJSON = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee11() {
38895
39286
  var filename,
38896
- _args0 = arguments,
39287
+ _args11 = arguments,
38897
39288
  _t5;
38898
- return _regenerator().w(function (_context0) {
38899
- while (1) switch (_context0.n) {
39289
+ return _regenerator().w(function (_context11) {
39290
+ while (1) switch (_context11.n) {
38900
39291
  case 0:
38901
- filename = _args0.length > 0 && _args0[0] !== undefined ? _args0[0] : null;
39292
+ filename = _args11.length > 0 && _args11[0] !== undefined ? _args11[0] : null;
38902
39293
  if (this.managers.sceneExportManager) {
38903
- _context0.n = 1;
39294
+ _context11.n = 1;
38904
39295
  break;
38905
39296
  }
38906
39297
  console.error('❌ Scene export manager not available');
38907
- return _context0.a(2, false);
39298
+ return _context11.a(2, false);
38908
39299
  case 1:
38909
- _context0.p = 1;
38910
- _context0.n = 2;
39300
+ _context11.p = 1;
39301
+ _context11.n = 2;
38911
39302
  return this.managers.sceneExportManager.downloadSceneJSON(filename);
38912
39303
  case 2:
38913
- return _context0.a(2, _context0.v);
39304
+ return _context11.a(2, _context11.v);
38914
39305
  case 3:
38915
- _context0.p = 3;
38916
- _t5 = _context0.v;
39306
+ _context11.p = 3;
39307
+ _t5 = _context11.v;
38917
39308
  console.error('❌ Error exporting scene as JSON:', _t5);
38918
- return _context0.a(2, false);
39309
+ return _context11.a(2, false);
38919
39310
  }
38920
- }, _callee0, this, [[1, 3]]);
39311
+ }, _callee11, this, [[1, 3]]);
38921
39312
  }));
38922
39313
  function exportSceneJSON() {
38923
39314
  return _exportSceneJSON.apply(this, arguments);
@@ -38942,33 +39333,33 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38942
39333
  }, {
38943
39334
  key: "exportSceneGLTF",
38944
39335
  value: (function () {
38945
- var _exportSceneGLTF = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee1() {
39336
+ var _exportSceneGLTF = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee12() {
38946
39337
  var filename,
38947
- _args1 = arguments,
39338
+ _args12 = arguments,
38948
39339
  _t6;
38949
- return _regenerator().w(function (_context1) {
38950
- while (1) switch (_context1.n) {
39340
+ return _regenerator().w(function (_context12) {
39341
+ while (1) switch (_context12.n) {
38951
39342
  case 0:
38952
- filename = _args1.length > 0 && _args1[0] !== undefined ? _args1[0] : null;
39343
+ filename = _args12.length > 0 && _args12[0] !== undefined ? _args12[0] : null;
38953
39344
  if (this.managers.sceneExportManager) {
38954
- _context1.n = 1;
39345
+ _context12.n = 1;
38955
39346
  break;
38956
39347
  }
38957
39348
  console.error('❌ Scene export manager not available');
38958
- return _context1.a(2, false);
39349
+ return _context12.a(2, false);
38959
39350
  case 1:
38960
- _context1.p = 1;
38961
- _context1.n = 2;
39351
+ _context12.p = 1;
39352
+ _context12.n = 2;
38962
39353
  return this.managers.sceneExportManager.exportSceneAsGLTF(filename, false);
38963
39354
  case 2:
38964
- return _context1.a(2, _context1.v);
39355
+ return _context12.a(2, _context12.v);
38965
39356
  case 3:
38966
- _context1.p = 3;
38967
- _t6 = _context1.v;
39357
+ _context12.p = 3;
39358
+ _t6 = _context12.v;
38968
39359
  console.error('❌ Error exporting scene as GLTF:', _t6);
38969
- return _context1.a(2, false);
39360
+ return _context12.a(2, false);
38970
39361
  }
38971
- }, _callee1, this, [[1, 3]]);
39362
+ }, _callee12, this, [[1, 3]]);
38972
39363
  }));
38973
39364
  function exportSceneGLTF() {
38974
39365
  return _exportSceneGLTF.apply(this, arguments);
@@ -38994,33 +39385,33 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
38994
39385
  }, {
38995
39386
  key: "exportSceneGLB",
38996
39387
  value: (function () {
38997
- var _exportSceneGLB = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee10() {
39388
+ var _exportSceneGLB = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee13() {
38998
39389
  var filename,
38999
- _args10 = arguments,
39390
+ _args13 = arguments,
39000
39391
  _t7;
39001
- return _regenerator().w(function (_context10) {
39002
- while (1) switch (_context10.n) {
39392
+ return _regenerator().w(function (_context13) {
39393
+ while (1) switch (_context13.n) {
39003
39394
  case 0:
39004
- filename = _args10.length > 0 && _args10[0] !== undefined ? _args10[0] : null;
39395
+ filename = _args13.length > 0 && _args13[0] !== undefined ? _args13[0] : null;
39005
39396
  if (this.managers.sceneExportManager) {
39006
- _context10.n = 1;
39397
+ _context13.n = 1;
39007
39398
  break;
39008
39399
  }
39009
39400
  console.error('❌ Scene export manager not available');
39010
- return _context10.a(2, false);
39401
+ return _context13.a(2, false);
39011
39402
  case 1:
39012
- _context10.p = 1;
39013
- _context10.n = 2;
39403
+ _context13.p = 1;
39404
+ _context13.n = 2;
39014
39405
  return this.managers.sceneExportManager.exportSceneAsGLB(filename);
39015
39406
  case 2:
39016
- return _context10.a(2, _context10.v);
39407
+ return _context13.a(2, _context13.v);
39017
39408
  case 3:
39018
- _context10.p = 3;
39019
- _t7 = _context10.v;
39409
+ _context13.p = 3;
39410
+ _t7 = _context13.v;
39020
39411
  console.error('❌ Error exporting scene as GLB:', _t7);
39021
- return _context10.a(2, false);
39412
+ return _context13.a(2, false);
39022
39413
  }
39023
- }, _callee10, this, [[1, 3]]);
39414
+ }, _callee13, this, [[1, 3]]);
39024
39415
  }));
39025
39416
  function exportSceneGLB() {
39026
39417
  return _exportSceneGLB.apply(this, arguments);
@@ -39059,16 +39450,16 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
39059
39450
  }, {
39060
39451
  key: "loadSceneFromData",
39061
39452
  value: (function () {
39062
- var _loadSceneFromData = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee11(sceneData) {
39063
- return _regenerator().w(function (_context11) {
39064
- while (1) switch (_context11.n) {
39453
+ var _loadSceneFromData = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee14(sceneData) {
39454
+ return _regenerator().w(function (_context14) {
39455
+ while (1) switch (_context14.n) {
39065
39456
  case 0:
39066
- _context11.n = 1;
39457
+ _context14.n = 1;
39067
39458
  return this.setImportedSceneData(sceneData);
39068
39459
  case 1:
39069
- return _context11.a(2, true);
39460
+ return _context14.a(2, true);
39070
39461
  }
39071
- }, _callee11, this);
39462
+ }, _callee14, this);
39072
39463
  }));
39073
39464
  function loadSceneFromData(_x7) {
39074
39465
  return _loadSceneFromData.apply(this, arguments);