@itwin/core-frontend 5.15.0-dev.3 → 5.15.0-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -1
- package/lib/cjs/IModelApp.d.ts +19 -1
- package/lib/cjs/IModelApp.d.ts.map +1 -1
- package/lib/cjs/IModelApp.js +15 -0
- package/lib/cjs/IModelApp.js.map +1 -1
- package/lib/cjs/RealityDataSourceCesiumIonAssetImpl.d.ts.map +1 -1
- package/lib/cjs/RealityDataSourceCesiumIonAssetImpl.js +7 -14
- package/lib/cjs/RealityDataSourceCesiumIonAssetImpl.js.map +1 -1
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.d.ts +53 -0
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.d.ts.map +1 -0
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.js +145 -0
- package/lib/cjs/quantity-formatting/FormatsProviderReloadCoordinator.js.map +1 -0
- package/lib/cjs/quantity-formatting/QuantityFormatter.d.ts +23 -34
- package/lib/cjs/quantity-formatting/QuantityFormatter.d.ts.map +1 -1
- package/lib/cjs/quantity-formatting/QuantityFormatter.js +99 -90
- package/lib/cjs/quantity-formatting/QuantityFormatter.js.map +1 -1
- package/lib/cjs/tile/map/CesiumTerrainProvider.d.ts +27 -6
- package/lib/cjs/tile/map/CesiumTerrainProvider.d.ts.map +1 -1
- package/lib/cjs/tile/map/CesiumTerrainProvider.js +51 -21
- package/lib/cjs/tile/map/CesiumTerrainProvider.js.map +1 -1
- package/lib/esm/IModelApp.d.ts +19 -1
- package/lib/esm/IModelApp.d.ts.map +1 -1
- package/lib/esm/IModelApp.js +15 -0
- package/lib/esm/IModelApp.js.map +1 -1
- package/lib/esm/RealityDataSourceCesiumIonAssetImpl.d.ts.map +1 -1
- package/lib/esm/RealityDataSourceCesiumIonAssetImpl.js +7 -14
- package/lib/esm/RealityDataSourceCesiumIonAssetImpl.js.map +1 -1
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.d.ts +53 -0
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.d.ts.map +1 -0
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.js +140 -0
- package/lib/esm/quantity-formatting/FormatsProviderReloadCoordinator.js.map +1 -0
- package/lib/esm/quantity-formatting/QuantityFormatter.d.ts +23 -34
- package/lib/esm/quantity-formatting/QuantityFormatter.d.ts.map +1 -1
- package/lib/esm/quantity-formatting/QuantityFormatter.js +99 -90
- package/lib/esm/quantity-formatting/QuantityFormatter.js.map +1 -1
- package/lib/esm/tile/map/CesiumTerrainProvider.d.ts +27 -6
- package/lib/esm/tile/map/CesiumTerrainProvider.d.ts.map +1 -1
- package/lib/esm/tile/map/CesiumTerrainProvider.js +50 -22
- package/lib/esm/tile/map/CesiumTerrainProvider.js.map +1 -1
- package/lib/public/locales/en/iModelJs.json +3 -1
- package/lib/public/scripts/parse-imdl-worker.js +2 -2
- package/lib/test-public/scripts/parse-imdl-worker.js +2 -2
- package/lib/test-public/test-worker.js +1 -1
- package/package.json +21 -21
|
@@ -15,6 +15,7 @@ const core_quantity_1 = require("@itwin/core-quantity");
|
|
|
15
15
|
const FrontendLoggerCategory_1 = require("../common/FrontendLoggerCategory");
|
|
16
16
|
const IModelApp_1 = require("../IModelApp");
|
|
17
17
|
const AlternateUnitLabels_1 = require("./AlternateUnitLabels");
|
|
18
|
+
const FormatsProviderReloadCoordinator_1 = require("./FormatsProviderReloadCoordinator");
|
|
18
19
|
// cSpell:ignore FORMATPROPS FORMATKEY ussurvey uscustomary USCUSTOM
|
|
19
20
|
/**
|
|
20
21
|
* Defines standard format types for tools that need to display measurements to user.
|
|
@@ -201,12 +202,24 @@ class FormatsProviderManager {
|
|
|
201
202
|
}
|
|
202
203
|
get formatsProvider() { return this; }
|
|
203
204
|
set formatsProvider(formatsProvider) {
|
|
205
|
+
this.setFormatsProvider(formatsProvider);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Replaces the underlying formats provider and raises an event indicating that all formats changed.
|
|
209
|
+
* @param formatsProvider The formats provider to use for subsequent format lookups.
|
|
210
|
+
* @param impliedUnitSystem The unit system implied by the replacement provider, if any. Not stored here; [[QuantityFormatter]] applies it as the active unit system when handling `onFormatsChanged`.
|
|
211
|
+
* @internal
|
|
212
|
+
*/
|
|
213
|
+
setFormatsProvider(formatsProvider, impliedUnitSystem) {
|
|
204
214
|
this._removeProviderListener?.();
|
|
205
215
|
this._formatsProvider = formatsProvider;
|
|
206
216
|
this._removeProviderListener = this._formatsProvider.onFormatsChanged.addListener((args) => {
|
|
207
217
|
this.onFormatsChanged.raiseEvent(args);
|
|
208
218
|
});
|
|
209
|
-
|
|
219
|
+
const args = { formatsChanged: "all" };
|
|
220
|
+
if (impliedUnitSystem !== undefined)
|
|
221
|
+
args.impliedUnitSystem = impliedUnitSystem;
|
|
222
|
+
this.onFormatsChanged.raiseEvent(args);
|
|
210
223
|
}
|
|
211
224
|
}
|
|
212
225
|
exports.FormatsProviderManager = FormatsProviderManager;
|
|
@@ -288,10 +301,13 @@ class QuantityFormatter {
|
|
|
288
301
|
_hasEverBeenReady = false;
|
|
289
302
|
_initializedPromise;
|
|
290
303
|
_resolveInitialized;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
304
|
+
_emitSystemChangedOnReady = false;
|
|
305
|
+
_isDisposed = false;
|
|
306
|
+
_disposedError = new Error("QuantityFormatter was disposed before the reload completed.");
|
|
307
|
+
_reloadCoordinator;
|
|
294
308
|
_removeFormatsProviderListener;
|
|
309
|
+
_activeFormatSpecsTarget;
|
|
310
|
+
_activeParserSpecsTarget;
|
|
295
311
|
/**
|
|
296
312
|
* constructor
|
|
297
313
|
* @param showMetricOrUnitSystem - Pass in `true` to show Metric formatted quantity values. Defaults to Imperial. To explicitly
|
|
@@ -301,6 +317,12 @@ class QuantityFormatter {
|
|
|
301
317
|
this._initializedPromise = new Promise((resolve) => {
|
|
302
318
|
this._resolveInitialized = resolve;
|
|
303
319
|
});
|
|
320
|
+
this._reloadCoordinator = new FormatsProviderReloadCoordinator_1.FormatsProviderReloadCoordinator({
|
|
321
|
+
startReload: () => { this._isReady = false; },
|
|
322
|
+
executeReload: async (intent) => this._executeReload(intent),
|
|
323
|
+
finalizeReload: async () => this.finalizeReload(),
|
|
324
|
+
handleReloadFailure: (error) => this._handleReloadFailure(error),
|
|
325
|
+
}, this._disposedError);
|
|
304
326
|
if (undefined !== showMetricOrUnitSystem) {
|
|
305
327
|
if (typeof showMetricOrUnitSystem === "boolean")
|
|
306
328
|
this._activeUnitSystem = showMetricOrUnitSystem ? "metric" : "imperial";
|
|
@@ -309,70 +331,44 @@ class QuantityFormatter {
|
|
|
309
331
|
}
|
|
310
332
|
}
|
|
311
333
|
[Symbol.dispose]() {
|
|
334
|
+
if (this._isDisposed)
|
|
335
|
+
return;
|
|
336
|
+
this._isDisposed = true;
|
|
337
|
+
this._isReady = false;
|
|
338
|
+
this._emitSystemChangedOnReady = false;
|
|
339
|
+
this._reloadCoordinator.dispose();
|
|
312
340
|
if (this._removeFormatsProviderListener) {
|
|
313
341
|
this._removeFormatsProviderListener();
|
|
314
342
|
this._removeFormatsProviderListener = undefined;
|
|
315
343
|
}
|
|
316
344
|
}
|
|
345
|
+
/** Runs an action that schedules a reload and waits for the reload queue to drain.
|
|
346
|
+
* The most recent call wins. If another call is made before this reload queue drains, this call is rejected.
|
|
347
|
+
* @internal
|
|
348
|
+
*/
|
|
349
|
+
async runAndWaitForReload(action) {
|
|
350
|
+
return this._reloadCoordinator.runAndWaitForReload(action);
|
|
351
|
+
}
|
|
317
352
|
/** Schedule an async reload. If no reload is in flight, runs immediately. If a reload is
|
|
318
|
-
* already in flight, stores the intent as pending
|
|
319
|
-
*
|
|
353
|
+
* already in flight, stores the intent as pending. Pending format changes are merged and run before
|
|
354
|
+
* the latest other pending intent. `finalizeReload()` fires only when the queue is fully drained.
|
|
320
355
|
*
|
|
321
356
|
* **Await semantics:** When a reload is already in flight, the returned promise resolves
|
|
322
357
|
* immediately *without* the requested reload having run. Callers that need to know when
|
|
323
|
-
*
|
|
358
|
+
* an explicitly triggered reload has actually completed should use [[runAndWaitForReload]].
|
|
324
359
|
*
|
|
325
|
-
* Reload intents:
|
|
326
|
-
* - `"full"` — rebuild entire registry + re-register provider listener (onInitialized, setUnitsProvider)
|
|
327
|
-
* - `"formatsChanged"` — patch registry from provider + load maps (formatsChanged listener)
|
|
328
|
-
* - `"activeSystem"` — reload format/parsing maps for current unit system (setActiveUnitSystem, reinitializeFormatAndParsingsMaps)
|
|
329
360
|
* @internal
|
|
330
361
|
*/
|
|
331
362
|
async scheduleReload(intent) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
this.
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
try {
|
|
341
|
-
await this._executeReload(intent);
|
|
363
|
+
return this._reloadCoordinator.scheduleReload(intent);
|
|
364
|
+
}
|
|
365
|
+
_handleReloadFailure(error) {
|
|
366
|
+
if (!this._isDisposed)
|
|
367
|
+
core_bentley_1.Logger.logError(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, core_bentley_1.BentleyError.getErrorMessage(error));
|
|
368
|
+
if (this._hasEverBeenReady && !this._isDisposed) {
|
|
369
|
+
core_bentley_1.Logger.logWarning(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, "Reload failed — restoring previous ready state. Cached specs may be stale.");
|
|
370
|
+
this._isReady = true;
|
|
342
371
|
}
|
|
343
|
-
catch (err) {
|
|
344
|
-
core_bentley_1.Logger.logError(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, core_bentley_1.BentleyError.getErrorMessage(err));
|
|
345
|
-
this._reloadInFlight = false;
|
|
346
|
-
// If there's a pending reload, still try to run it
|
|
347
|
-
if (this._pendingReload) {
|
|
348
|
-
const next = this._pendingReload;
|
|
349
|
-
this._pendingReload = undefined;
|
|
350
|
-
return this.scheduleReload(next);
|
|
351
|
-
}
|
|
352
|
-
// Restore prior ready state so stale-but-usable specs remain accessible
|
|
353
|
-
if (this._hasEverBeenReady) {
|
|
354
|
-
core_bentley_1.Logger.logWarning(`${FrontendLoggerCategory_1.FrontendLoggerCategory.Package}.QuantityFormatter`, "Reload failed — restoring previous ready state. Cached specs may be stale.");
|
|
355
|
-
this._isReady = true;
|
|
356
|
-
}
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
// Current reload succeeded — check if another was queued
|
|
360
|
-
if (this._pendingReload) {
|
|
361
|
-
const next = this._pendingReload;
|
|
362
|
-
this._pendingReload = undefined;
|
|
363
|
-
this._reloadInFlight = false;
|
|
364
|
-
return this.scheduleReload(next);
|
|
365
|
-
}
|
|
366
|
-
// Queue is drained — finalize
|
|
367
|
-
await this.finalizeReload();
|
|
368
|
-
// A new reload may have been queued during the async finalizeReload window
|
|
369
|
-
if (this._pendingReload) {
|
|
370
|
-
const next = this._pendingReload;
|
|
371
|
-
this._pendingReload = undefined;
|
|
372
|
-
this._reloadInFlight = false;
|
|
373
|
-
return this.scheduleReload(next);
|
|
374
|
-
}
|
|
375
|
-
this._reloadInFlight = false;
|
|
376
372
|
}
|
|
377
373
|
/** Execute the reload work for a given intent. All reload logic is centralized here.
|
|
378
374
|
* @internal
|
|
@@ -381,47 +377,51 @@ class QuantityFormatter {
|
|
|
381
377
|
switch (intent.scope) {
|
|
382
378
|
case "full":
|
|
383
379
|
await this._reloadCore();
|
|
380
|
+
return;
|
|
381
|
+
case "formatsChanged":
|
|
382
|
+
await this._rebuildRegistryFromProvider(intent.args);
|
|
384
383
|
break;
|
|
385
|
-
case "formatsChanged": {
|
|
386
|
-
const { args } = intent;
|
|
387
|
-
await this._rebuildRegistryFromProvider(args);
|
|
388
|
-
if (args.impliedUnitSystem && args.impliedUnitSystem !== this._activeUnitSystem) {
|
|
389
|
-
this._activeUnitSystem = args.impliedUnitSystem;
|
|
390
|
-
}
|
|
391
|
-
await this.loadFormatAndParsingMapsForSystem(this._activeUnitSystem);
|
|
392
|
-
if (args.impliedUnitSystem) {
|
|
393
|
-
this._deferredSystemChangedEmit = { system: this._activeUnitSystem };
|
|
394
|
-
}
|
|
395
|
-
break;
|
|
396
|
-
}
|
|
397
|
-
case "activeSystem":
|
|
398
|
-
await this.loadFormatAndParsingMapsForSystem(this._activeUnitSystem);
|
|
399
|
-
if (intent.emitSystemChanged) {
|
|
400
|
-
this._deferredSystemChangedEmit = { system: this._activeUnitSystem };
|
|
401
|
-
}
|
|
402
|
-
break;
|
|
403
384
|
}
|
|
385
|
+
// Build the active specs in temporary maps so readers keep using complete specs until the new ones are ready.
|
|
386
|
+
const nextFormatSpecs = new Map();
|
|
387
|
+
const nextParserSpecs = new Map();
|
|
388
|
+
this._activeFormatSpecsTarget = nextFormatSpecs;
|
|
389
|
+
this._activeParserSpecsTarget = nextParserSpecs;
|
|
390
|
+
try {
|
|
391
|
+
await this.loadFormatAndParsingMapsForSystem(this._activeUnitSystem);
|
|
392
|
+
}
|
|
393
|
+
finally {
|
|
394
|
+
this._activeFormatSpecsTarget = undefined;
|
|
395
|
+
this._activeParserSpecsTarget = undefined;
|
|
396
|
+
}
|
|
397
|
+
this._activeFormatSpecsByType = nextFormatSpecs;
|
|
398
|
+
this._activeParserSpecsByType = nextParserSpecs;
|
|
404
399
|
}
|
|
405
400
|
/** Called when the reload queue is fully drained after a successful reload.
|
|
406
401
|
* Sets `isReady` to true, resolves `whenInitialized` (one-shot), and emits ready events.
|
|
407
402
|
* @internal
|
|
408
403
|
*/
|
|
409
404
|
async finalizeReload() {
|
|
405
|
+
if (this._isDisposed)
|
|
406
|
+
return;
|
|
410
407
|
// Phase 1: Let providers register async work
|
|
411
408
|
const collector = new core_quantity_1.FormattingReadyCollector();
|
|
412
409
|
this.onBeforeFormattingReady.raiseEvent(collector);
|
|
413
410
|
await collector.awaitAll();
|
|
411
|
+
if (this._isDisposed)
|
|
412
|
+
return;
|
|
414
413
|
// Phase 2: Signal ready to consumers
|
|
415
414
|
this._isReady = true;
|
|
416
415
|
this._hasEverBeenReady = true;
|
|
417
416
|
this._resolveInitialized();
|
|
418
417
|
this.onFormattingReady.emit();
|
|
419
|
-
|
|
418
|
+
if (this._isDisposed)
|
|
419
|
+
return;
|
|
420
|
+
// Phase 3: Emit unit-system-changed if the unit system was changed since the last ready state, reporting the system that is now active.
|
|
420
421
|
// This fires after isReady === true so listeners can safely use the formatter.
|
|
421
|
-
if (this.
|
|
422
|
-
|
|
423
|
-
this.
|
|
424
|
-
this.onActiveFormattingUnitSystemChanged.emit(args);
|
|
422
|
+
if (this._emitSystemChangedOnReady) {
|
|
423
|
+
this._emitSystemChangedOnReady = false;
|
|
424
|
+
this.onActiveFormattingUnitSystemChanged.emit({ system: this._activeUnitSystem });
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
getOverrideFormatPropsByQuantityType(quantityTypeKey, unitSystem) {
|
|
@@ -492,8 +492,8 @@ class QuantityFormatter {
|
|
|
492
492
|
async loadFormatAndParserSpec(quantityTypeDefinition, formatProps) {
|
|
493
493
|
const formatterSpec = await quantityTypeDefinition.generateFormatterSpec(formatProps, this.unitsProvider);
|
|
494
494
|
const parserSpec = await quantityTypeDefinition.generateParserSpec(formatProps, this.unitsProvider, this.alternateUnitLabelsProvider);
|
|
495
|
-
this._activeFormatSpecsByType.set(quantityTypeDefinition.key, formatterSpec);
|
|
496
|
-
this._activeParserSpecsByType.set(quantityTypeDefinition.key, parserSpec);
|
|
495
|
+
(this._activeFormatSpecsTarget ?? this._activeFormatSpecsByType).set(quantityTypeDefinition.key, formatterSpec);
|
|
496
|
+
(this._activeParserSpecsTarget ?? this._activeParserSpecsByType).set(quantityTypeDefinition.key, parserSpec);
|
|
497
497
|
}
|
|
498
498
|
// repopulate formatSpec and parserSpec entries using only default format
|
|
499
499
|
async loadDefaultFormatAndParserSpecForQuantity(typeKey) {
|
|
@@ -550,17 +550,20 @@ class QuantityFormatter {
|
|
|
550
550
|
* @internal
|
|
551
551
|
*/
|
|
552
552
|
async onInitialized() {
|
|
553
|
+
// Register once, before the first reload, so provider changes made while a units-provider reload is running are not missed.
|
|
554
|
+
this._removeFormatsProviderListener ??= IModelApp_1.IModelApp.formatsProvider.onFormatsChanged.addListener((args) => {
|
|
555
|
+
if (args.impliedUnitSystem && args.impliedUnitSystem !== this._activeUnitSystem) {
|
|
556
|
+
this._activeUnitSystem = args.impliedUnitSystem;
|
|
557
|
+
this._emitSystemChangedOnReady = true;
|
|
558
|
+
}
|
|
559
|
+
void this.scheduleReload({ scope: "formatsChanged", args });
|
|
560
|
+
});
|
|
553
561
|
await this.scheduleReload({ scope: "full" });
|
|
554
562
|
}
|
|
555
563
|
/** Core reload logic — does all async I/O and cache rebuilding without events or state management.
|
|
556
564
|
* @internal
|
|
557
565
|
*/
|
|
558
566
|
async _reloadCore() {
|
|
559
|
-
// Remove any existing listener before re-registering to avoid duplicates when called via setUnitsProvider.
|
|
560
|
-
if (this._removeFormatsProviderListener) {
|
|
561
|
-
this._removeFormatsProviderListener();
|
|
562
|
-
this._removeFormatsProviderListener = undefined;
|
|
563
|
-
}
|
|
564
567
|
await this.initializeQuantityTypesRegistry();
|
|
565
568
|
const initialKoQs = [["DefaultToolsUnits.LENGTH", "Units.M"], ["DefaultToolsUnits.ANGLE", "Units.RAD"], ["DefaultToolsUnits.AREA", "Units.SQ_M"], ["DefaultToolsUnits.VOLUME", "Units.CUB_M"], ["DefaultToolsUnits.LENGTH_COORDINATE", "Units.M"], ["CivilUnits.STATION", "Units.M"], ["CivilUnits.LENGTH", "Units.M"], ["AecUnits.LENGTH", "Units.M"]];
|
|
566
569
|
for (const entry of initialKoQs) {
|
|
@@ -573,10 +576,6 @@ class QuantityFormatter {
|
|
|
573
576
|
}
|
|
574
577
|
}
|
|
575
578
|
}
|
|
576
|
-
// Register formatsProvider listener that triggers a queued reload when formats change
|
|
577
|
-
this._removeFormatsProviderListener = IModelApp_1.IModelApp.formatsProvider.onFormatsChanged.addListener((args) => {
|
|
578
|
-
void this.scheduleReload({ scope: "formatsChanged", args });
|
|
579
|
-
});
|
|
580
579
|
// initialize default format and parsing specs
|
|
581
580
|
await this.loadFormatAndParsingMapsForSystem();
|
|
582
581
|
}
|
|
@@ -670,6 +669,9 @@ class QuantityFormatter {
|
|
|
670
669
|
await IModelApp_1.IModelApp.quantityFormatter.resetToUseInternalUnitsProvider();
|
|
671
670
|
return;
|
|
672
671
|
}
|
|
672
|
+
// Disposal can occur while the reload is awaited, so do not notify afterward.
|
|
673
|
+
if (this._isDisposed)
|
|
674
|
+
return;
|
|
673
675
|
this.onUnitsProviderChanged.emit();
|
|
674
676
|
}
|
|
675
677
|
/**
|
|
@@ -709,7 +711,11 @@ class QuantityFormatter {
|
|
|
709
711
|
this._overrideFormatPropsByUnitSystem = overrideFormatPropsByUnitSystem;
|
|
710
712
|
}
|
|
711
713
|
unitSystemKey && (this._activeUnitSystem = unitSystemKey);
|
|
712
|
-
|
|
714
|
+
if (fireUnitSystemChanged)
|
|
715
|
+
this._emitSystemChangedOnReady = true;
|
|
716
|
+
await this.scheduleReload({ scope: "activeSystem" });
|
|
717
|
+
if (this._isDisposed)
|
|
718
|
+
return;
|
|
713
719
|
IModelApp_1.IModelApp.toolAdmin && startDefaultTool && await IModelApp_1.IModelApp.toolAdmin.startDefaultTool();
|
|
714
720
|
}
|
|
715
721
|
/** Set the Active unit system to one of the supported types. This will asynchronously load the formatter and parser specs for the activated system. */
|
|
@@ -722,7 +728,10 @@ class QuantityFormatter {
|
|
|
722
728
|
if (this._activeUnitSystem === systemType)
|
|
723
729
|
return;
|
|
724
730
|
this._activeUnitSystem = systemType;
|
|
725
|
-
|
|
731
|
+
this._emitSystemChangedOnReady = true;
|
|
732
|
+
await this.scheduleReload({ scope: "activeSystem" });
|
|
733
|
+
if (this._isDisposed)
|
|
734
|
+
return;
|
|
726
735
|
// allow settings provider to store the change
|
|
727
736
|
await this._unitFormattingSettingsProvider?.storeUnitSystemSetting({ system: systemType });
|
|
728
737
|
if (IModelApp_1.IModelApp.toolAdmin && restartActiveTool)
|