@itwin/ecschema-rpcinterface-tests 5.13.0-dev.16 → 5.13.0-dev.18

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.
@@ -91445,6 +91445,8 @@ const COPYRIGHT_NOTICE = `Copyright © 2017-${new Date().getFullYear()} <a href=
91445
91445
 
91446
91446
 
91447
91447
 
91448
+ /** CSS class name applied to the notice element of a logo card created by [[IModelApp.makeLogoCard]]. */
91449
+ const logoCardNoticeClassName = "logo-cards";
91448
91450
  /**
91449
91451
  * Global singleton that connects the user interface with the iTwin.js services. There can be only one IModelApp active in a session. All
91450
91452
  * members of IModelApp are static, and it serves as a singleton object for gaining access to session information.
@@ -91957,10 +91959,21 @@ class IModelApp {
91957
91959
  }
91958
91960
  if (undefined !== opts.notice) {
91959
91961
  if (typeof opts.notice === "string")
91960
- IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: "logo-cards" });
91962
+ IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: logoCardNoticeClassName });
91961
91963
  else
91962
91964
  noticeCell.appendChild(opts.notice);
91963
91965
  }
91966
+ else if (undefined !== opts.noticeLines) {
91967
+ // A <p> cannot legally contain flow content, so use a <div> when a line is an element.
91968
+ const containerTag = opts.noticeLines.some((line) => typeof line !== "string") ? "div" : "p";
91969
+ const notice = IModelApp.makeHTMLElement(containerTag, { parent: noticeCell, className: logoCardNoticeClassName });
91970
+ opts.noticeLines.forEach((line, index) => {
91971
+ if (index > 0)
91972
+ notice.appendChild(IModelApp.makeHTMLElement("br"));
91973
+ // Strings are appended as text nodes so they are never parsed as HTML.
91974
+ notice.append(line);
91975
+ });
91976
+ }
91964
91977
  return card;
91965
91978
  }
91966
91979
  /** Make the logo card for the library itself. This card gets placed at the top of the stack.
@@ -93527,7 +93540,9 @@ let iModelJsCss = `
93527
93540
 
93528
93541
  .logo-cards {
93529
93542
  position:relative;
93530
- width:100%
93543
+ width:100%;
93544
+ margin-block-start:1em;
93545
+ margin-block-end:1em
93531
93546
  }
93532
93547
 
93533
93548
  .imodeljs-modal-overlay {
@@ -93571,7 +93586,7 @@ let iModelJsCss = `
93571
93586
  max-width: calc(100% - (2 * var(--width-border))) !important;
93572
93587
  width: unset !important;
93573
93588
  }
93574
- .imodeljs-about .logo-card-message p {
93589
+ .imodeljs-about .logo-card-message p, .imodeljs-about .logo-card-message .logo-cards {
93575
93590
  margin-block-end: 1em;
93576
93591
  }
93577
93592
  .imodeljs-about .logo-cards {
@@ -96217,9 +96232,12 @@ class Google3dTilesProvider {
96217
96232
  // Order by most occurances to least
96218
96233
  // See https://developers.google.com/maps/documentation/tile/create-renderer#display-attributions
96219
96234
  const sortedCopyrights = [...copyrightMap.entries()].sort((a, b) => b[1] - a[1]);
96220
- let copyrightMsg = "Data provided by:<br><ul>";
96221
- copyrightMsg += sortedCopyrights.map(([key]) => `<li>${key}</li>`).join("");
96222
- copyrightMsg += "</ul>";
96235
+ const list = document.createElement("ul");
96236
+ for (const [key] of sortedCopyrights) {
96237
+ const item = document.createElement("li");
96238
+ item.textContent = key;
96239
+ list.appendChild(item);
96240
+ }
96223
96241
  const iconSrc = document.createElement("img");
96224
96242
  iconSrc.src = `${_IModelApp__WEBPACK_IMPORTED_MODULE_8__.IModelApp.publicPath}images/GoogleMaps_Logo_Gray.svg`;
96225
96243
  iconSrc.style.padding = "10px 10px 5px 10px";
@@ -96227,7 +96245,7 @@ class Google3dTilesProvider {
96227
96245
  iconSrc,
96228
96246
  iconWidth: 98,
96229
96247
  heading: "Google Photorealistic 3D Tiles",
96230
- notice: copyrightMsg
96248
+ noticeLines: ["Data provided by:", list],
96231
96249
  }));
96232
96250
  }
96233
96251
  }
@@ -116617,7 +116635,7 @@ class GoogleMapsDecorator {
116617
116635
  const copyrightText = sortedCopyrights.map(([key]) => ` • ${key}`).join("");
116618
116636
  // Create and add element, offset to leave space for i.js and Google logos
116619
116637
  const elem = document.createElement("div");
116620
- elem.innerHTML = copyrightText;
116638
+ elem.textContent = copyrightText;
116621
116639
  elem.style.color = "white";
116622
116640
  elem.style.fontSize = "11px";
116623
116641
  elem.style.textWrap = "wrap";
@@ -153464,6 +153482,7 @@ __webpack_require__.r(__webpack_exports__);
153464
153482
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
153465
153483
  /* harmony export */ OrbitGtTileTree: () => (/* binding */ OrbitGtTileTree),
153466
153484
  /* harmony export */ OrbitGtTreeReference: () => (/* binding */ OrbitGtTreeReference),
153485
+ /* harmony export */ computeOrthometricVerticalShift: () => (/* binding */ computeOrthometricVerticalShift),
153467
153486
  /* harmony export */ createOrbitGtTileTreeReference: () => (/* binding */ createOrbitGtTileTreeReference)
153468
153487
  /* harmony export */ });
153469
153488
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
@@ -153471,11 +153490,12 @@ __webpack_require__.r(__webpack_exports__);
153471
153490
  /* harmony import */ var _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @itwin/core-geometry */ "../../core/geometry/lib/esm/core-geometry.js");
153472
153491
  /* harmony import */ var _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @itwin/core-orbitgt */ "../../core/orbitgt/lib/esm/core-orbitgt.js");
153473
153492
  /* harmony import */ var _BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../BackgroundMapGeometry */ "../../core/frontend/lib/esm/BackgroundMapGeometry.js");
153474
- /* harmony import */ var _DisplayStyleState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../DisplayStyleState */ "../../core/frontend/lib/esm/DisplayStyleState.js");
153475
- /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
153476
- /* harmony import */ var _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../RealityDataSource */ "../../core/frontend/lib/esm/RealityDataSource.js");
153477
- /* harmony import */ var _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../common/internal/render/MeshPrimitives */ "../../core/frontend/lib/esm/common/internal/render/MeshPrimitives.js");
153478
- /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
153493
+ /* harmony import */ var _common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../common/FrontendLoggerCategory */ "../../core/frontend/lib/esm/common/FrontendLoggerCategory.js");
153494
+ /* harmony import */ var _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../DisplayStyleState */ "../../core/frontend/lib/esm/DisplayStyleState.js");
153495
+ /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
153496
+ /* harmony import */ var _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../RealityDataSource */ "../../core/frontend/lib/esm/RealityDataSource.js");
153497
+ /* harmony import */ var _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../common/internal/render/MeshPrimitives */ "../../core/frontend/lib/esm/common/internal/render/MeshPrimitives.js");
153498
+ /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
153479
153499
  /*---------------------------------------------------------------------------------------------
153480
153500
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
153481
153501
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -153493,6 +153513,7 @@ __webpack_require__.r(__webpack_exports__);
153493
153513
 
153494
153514
 
153495
153515
 
153516
+
153496
153517
  const scratchRange = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.create();
153497
153518
  const scratchWorldFrustum = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Frustum();
153498
153519
  function compareSourceKeys(lhs, rhs) {
@@ -153556,7 +153577,7 @@ class OrbitGtTileTreeParams {
153556
153577
  id;
153557
153578
  modelId;
153558
153579
  iModel;
153559
- get priority() { return _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileLoadPriority.Context; }
153580
+ get priority() { return _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileLoadPriority.Context; }
153560
153581
  constructor(rdSourceKey, iModel, modelId, location) {
153561
153582
  this.location = location;
153562
153583
  const key = rdSourceKey;
@@ -153565,10 +153586,10 @@ class OrbitGtTileTreeParams {
153565
153586
  this.iModel = iModel;
153566
153587
  }
153567
153588
  }
153568
- class OrbitGtRootTile extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.Tile {
153589
+ class OrbitGtRootTile extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.Tile {
153569
153590
  _loadChildren(_resolve, _reject) { }
153570
153591
  async requestContent(_isCanceled) { return undefined; }
153571
- get channel() { return _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.channels.getForHttp("itwinjs-orbitgit"); }
153592
+ get channel() { return _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.channels.getForHttp("itwinjs-orbitgit"); }
153572
153593
  async readContent(_data, _system, _isCanceled) { return {}; }
153573
153594
  freeMemory() { }
153574
153595
  constructor(params, tree) { super(params, tree); }
@@ -153638,7 +153659,7 @@ class TileSortProjector {
153638
153659
  coordinate.z = point.z;
153639
153660
  }
153640
153661
  }
153641
- class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileUsageMarker {
153662
+ class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileUsageMarker {
153642
153663
  graphic;
153643
153664
  constructor(graphic, viewport, time) {
153644
153665
  super();
@@ -153649,7 +153670,7 @@ class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.Til
153649
153670
  this.graphic[Symbol.dispose]();
153650
153671
  }
153651
153672
  }
153652
- class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTree {
153673
+ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileTree {
153653
153674
  _dataManager;
153654
153675
  _centerOffset;
153655
153676
  _ecefTransform;
@@ -153665,7 +153686,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153665
153686
  this._dataManager = _dataManager;
153666
153687
  this._centerOffset = _centerOffset;
153667
153688
  this._ecefTransform = _ecefTransform;
153668
- this._layerHandler = new _tile_internal__WEBPACK_IMPORTED_MODULE_9__.LayerTileTreeHandler(this);
153689
+ this._layerHandler = new _tile_internal__WEBPACK_IMPORTED_MODULE_10__.LayerTileTreeHandler(this);
153669
153690
  this._tileParams = { contentId: "0", range: cloudRange, maximumSize: 256 };
153670
153691
  this.rootTile = new OrbitGtRootTile(this._tileParams, this);
153671
153692
  }
@@ -153714,7 +153735,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153714
153735
  let totalPointCount = 0;
153715
153736
  const tileCount = frameData.tilesToRender.size();
153716
153737
  // Inform TileAdmin about tiles we are handling ourselves...
153717
- _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.addExternalTilesForUser(args.context.viewport, { requested: frameData.tilesToLoad.size() + (frameData.hasMissingData() ? 1 : 0), selected: tileCount, ready: tileCount });
153738
+ _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.addExternalTilesForUser(args.context.viewport, { requested: frameData.tilesToLoad.size() + (frameData.hasMissingData() ? 1 : 0), selected: tileCount, ready: tileCount });
153718
153739
  if (debugBuilder)
153719
153740
  debugBuilder.setSymbology(_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, 1);
153720
153741
  let minLevel = 100, maxLevel = -100;
@@ -153735,8 +153756,8 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153735
153756
  range.high.addInPlace(this._centerOffset);
153736
153757
  const qParams = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QParams3d.fromRange(range, undefined, (tile.points8 != null) ? _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Quantization.rangeScale8 : _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Quantization.rangeScale16);
153737
153758
  const featureTable = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureTable(1, this.modelId, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.BatchType.Primary);
153738
- const features = new _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_8__.Mesh.Features(featureTable);
153739
- const system = _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.renderSystem;
153759
+ const features = new _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_9__.Mesh.Features(featureTable);
153760
+ const system = _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.renderSystem;
153740
153761
  const voxelSize = (range.high.x - range.low.x) / 64;
153741
153762
  features.add(new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Feature(this.modelId), 1);
153742
153763
  const tilePoints = (tile.points8 != null) ? tile.points8.toNativeBuffer() : tile.points16.toNativeBuffer();
@@ -153763,8 +153784,34 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153763
153784
  }
153764
153785
  args.drawGraphics();
153765
153786
  if (frameData.hasMissingData()) {
153766
- this._dataManager.loadData(frameData).then(() => _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.onTileLoad.raiseEvent(this.rootTile)).catch((_err) => undefined);
153787
+ this._dataManager.loadData(frameData).then(() => _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.onTileLoad.raiseEvent(this.rootTile)).catch((_err) => undefined);
153788
+ }
153789
+ }
153790
+ }
153791
+ /** Computes the vertical shift, in meters along geodetic up, to correctly place a point cloud whose CRS does not
153792
+ * define a vertical datum, assuming its heights are orthometric (relative to the geoid).
153793
+ *
153794
+ * The shift is the difference between converting the point cloud's origin with its height treated as orthometric
153795
+ * versus ellipsoidal (`heightAsEllipsoidalDbZ`, already computed by the caller). Returns zero if the shift cannot
153796
+ * be computed or the iModel's converter makes no distinction between the two.
153797
+ * Exported strictly for tests.
153798
+ * @internal
153799
+ */
153800
+ async function computeOrthometricVerticalShift(geoOrigin, heightAsEllipsoidalDbZ, iModel) {
153801
+ const geoidConverter = iModel.noGcsDefined ? undefined : iModel.geoServices.getConverter({ horizontalCRS: { epsg: 4326 }, verticalCRS: { id: "GEOID" } });
153802
+ if (undefined === geoidConverter)
153803
+ return 0;
153804
+ try {
153805
+ const response = await geoidConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
153806
+ if (response.iModelCoords[0].s !== _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
153807
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__.FrontendLoggerCategory.RealityData, `Failed to compute orthometric height correction for point cloud (status ${response.iModelCoords[0].s}); heights will be treated as ellipsoidal`);
153808
+ return 0;
153767
153809
  }
153810
+ return _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p).z - heightAsEllipsoidalDbZ;
153811
+ }
153812
+ catch (err) {
153813
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__.FrontendLoggerCategory.RealityData, err);
153814
+ return 0;
153768
153815
  }
153769
153816
  }
153770
153817
  (function (OrbitGtTileTree) {
@@ -153790,7 +153837,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153790
153837
  return isValidSASToken(props.sasToken);
153791
153838
  }
153792
153839
  async function createOrbitGtTileTree(rdSourceKey, iModel, modelId) {
153793
- const rdSource = await _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.fromKey(rdSourceKey, iModel.iTwinId);
153840
+ const rdSource = await _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.fromKey(rdSourceKey, iModel.iTwinId);
153794
153841
  const isContextShare = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.ContextShare;
153795
153842
  const isTilestUrl = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.TilesetUrl;
153796
153843
  let blobStringUrl;
@@ -153801,7 +153848,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153801
153848
  const docRootName = realityData.rootDocument;
153802
153849
  if (!docRootName)
153803
153850
  return undefined;
153804
- const token = await _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.getAccessToken();
153851
+ const token = await _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.getAccessToken();
153805
153852
  const blobUrl = await realityData.getBlobUrl(token, docRootName);
153806
153853
  blobStringUrl = blobUrl.toString();
153807
153854
  }
@@ -153809,7 +153856,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153809
153856
  blobStringUrl = rdSourceKey.id;
153810
153857
  }
153811
153858
  else {
153812
- const orbitGtBlobProps = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createOrbitGtBlobPropsFromKey(rdSourceKey);
153859
+ const orbitGtBlobProps = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createOrbitGtBlobPropsFromKey(rdSourceKey);
153813
153860
  if (orbitGtBlobProps === undefined)
153814
153861
  return undefined;
153815
153862
  if (!isValidOrbitGtBlobProps(orbitGtBlobProps))
@@ -153844,7 +153891,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153844
153891
  const wgs84CRS = "4978";
153845
153892
  await _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.prepareForArea(wgs84CRS, new _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.OrbitGtBounds());
153846
153893
  const pointCloudToEcef = transformFromOrbitGt(_itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.createTransform(pointCloudCRS, new _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.OrbitGtCoordinate(pointCloudCenter.x, pointCloudCenter.y, pointCloudCenter.z), wgs84CRS));
153847
- const pointCloudCenterToEcef = pointCloudToEcef.multiplyTransformTransform(addCloudCenter);
153894
+ let pointCloudCenterToEcef = pointCloudToEcef.multiplyTransformTransform(addCloudCenter);
153848
153895
  ecefTransform.setFrom(pointCloudCenterToEcef);
153849
153896
  let ecefToDb = iModel.getMapEcefToDb(0);
153850
153897
  // In initial publishing version the iModel ecef Transform was used to locate the reality model.
@@ -153864,7 +153911,21 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153864
153911
  const geoOrigin = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(cartographicOrigin.longitudeDegrees, cartographicOrigin.latitudeDegrees, cartographicOrigin.height);
153865
153912
  const response = await geoConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
153866
153913
  if (response.iModelCoords[0].s === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
153867
- const ecefToDbOrigin = await (0,_BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__.calculateEcefToDbTransformAtLocation)(_itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p), iModel);
153914
+ const dbOriginFromGcs = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p);
153915
+ // A projected CRS defines no vertical datum, so the point cloud's heights are conventionally orthometric -
153916
+ // but pointCloudToEcef above treated them as ellipsoidal. Correct the placement by the difference.
153917
+ // (A compound CRS also takes this path; that stays correct unless orbitgt gains a geoid model.)
153918
+ if (_itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.isProjectedCRS(pointCloudCRS)) {
153919
+ const verticalShift = await computeOrthometricVerticalShift(geoOrigin, dbOriginFromGcs.z, iModel);
153920
+ if (0 !== verticalShift) {
153921
+ const upVector = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Vector3d.createStartEnd(cartographicOrigin.toEcef(), _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Cartographic.fromRadians({ longitude: cartographicOrigin.longitude, latitude: cartographicOrigin.latitude, height: cartographicOrigin.height + 1 }).toEcef()).normalize();
153922
+ if (undefined !== upVector) {
153923
+ pointCloudCenterToEcef = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Transform.createTranslation(upVector.scale(verticalShift)).multiplyTransformTransform(pointCloudCenterToEcef);
153924
+ ecefTransform.setFrom(pointCloudCenterToEcef);
153925
+ }
153926
+ }
153927
+ }
153928
+ const ecefToDbOrigin = await (0,_BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__.calculateEcefToDbTransformAtLocation)(dbOriginFromGcs, iModel);
153868
153929
  if (ecefToDbOrigin)
153869
153930
  ecefToDb = ecefToDbOrigin;
153870
153931
  }
@@ -153884,7 +153945,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153884
153945
  /** Supplies a reality data [[TileTree]] from a URL. May be associated with a persistent [[GeometricModelState]], or attached at run-time via a [[ContextOrbitGtState]].
153885
153946
  * Exported strictly for tests.
153886
153947
  */
153887
- class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.RealityModelTileTree.Reference {
153948
+ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.RealityModelTileTree.Reference {
153888
153949
  treeOwner;
153889
153950
  _rdSourceKey;
153890
153951
  _modelId;
@@ -153897,15 +153958,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
153897
153958
  this._rdSourceKey = props.rdSourceKey;
153898
153959
  }
153899
153960
  else if (props.orbitGtBlob) {
153900
- this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createKeyFromOrbitGtBlobProps(props.orbitGtBlob);
153961
+ this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createKeyFromOrbitGtBlobProps(props.orbitGtBlob);
153901
153962
  }
153902
153963
  else {
153903
153964
  // TODO: Maybe we should throw an exception
153904
- this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createKeyFromBlobUrl("", _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.OrbitGtBlob, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataFormat.OPC);
153965
+ this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createKeyFromBlobUrl("", _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.OrbitGtBlob, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataFormat.OPC);
153905
153966
  }
153906
153967
  // ###TODO find compatible model Id
153907
153968
  let modelId = props.modelId;
153908
- if (undefined === modelId && this._source instanceof _DisplayStyleState__WEBPACK_IMPORTED_MODULE_5__.DisplayStyleState)
153969
+ if (undefined === modelId && this._source instanceof _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__.DisplayStyleState)
153909
153970
  modelId = orbitGtTreeSupplier.findCompatibleContextRealityModelId(this._rdSourceKey, this._source);
153910
153971
  this._modelId = modelId ?? props.iModel.transientIds.getNext();
153911
153972
  const ogtTreeId = { rdSourceKey: this._rdSourceKey, modelId: this.modelId };
@@ -153920,11 +153981,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
153920
153981
  if (undefined === tree || hit.iModel !== tree.iModel)
153921
153982
  return undefined;
153922
153983
  const strings = [];
153923
- strings.push(_IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.localization.getLocalizedString("iModelJs:RealityModelTypes.OrbitGTPointCloud"));
153984
+ strings.push(_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:RealityModelTypes.OrbitGTPointCloud"));
153924
153985
  if (this._name)
153925
- strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.localization.getLocalizedString("iModelJs:TooltipInfo.Name")} ${this._name}`);
153986
+ strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:TooltipInfo.Name")} ${this._name}`);
153926
153987
  const div = document.createElement("div");
153927
- div.innerHTML = strings.join("<br>");
153988
+ strings.forEach((str, index) => {
153989
+ if (index > 0)
153990
+ div.appendChild(document.createElement("br"));
153991
+ div.appendChild(document.createTextNode(str));
153992
+ });
153928
153993
  return div;
153929
153994
  }
153930
153995
  }
@@ -155688,7 +155753,11 @@ class RealityTreeReference extends RealityModelTileTree.Reference {
155688
155753
  if (-1 === key.indexOf("#")) // Avoid internal cesium
155689
155754
  strings.push(`${key}: ${JSON.stringify(batch[key])}`);
155690
155755
  const div = document.createElement("div");
155691
- div.innerHTML = strings.join("<br>");
155756
+ strings.forEach((str, index) => {
155757
+ if (index > 0)
155758
+ div.appendChild(document.createElement("br"));
155759
+ div.appendChild(document.createTextNode(str));
155760
+ });
155692
155761
  return div;
155693
155762
  }
155694
155763
  /** @deprecated in 5.0 - might be removed in next major version. Use [addAttributions] instead. */
@@ -156876,7 +156945,21 @@ class ArcGisUtilities {
156876
156945
  */
156877
156946
  static async validateSource(args) {
156878
156947
  const { source, ignoreCache, capabilitiesFilter } = args;
156879
- const metadata = await this.getServiceJson({ url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache });
156948
+ let metadata;
156949
+ try {
156950
+ metadata = await this.getServiceJson({ url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache });
156951
+ }
156952
+ catch (err) {
156953
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError) {
156954
+ let blockedOrigin;
156955
+ try {
156956
+ blockedOrigin = new URL(err.url).origin;
156957
+ }
156958
+ catch { /* non-hierarchical URL */ }
156959
+ return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
156960
+ }
156961
+ throw err;
156962
+ }
156880
156963
  const json = metadata?.content;
156881
156964
  if (json === undefined) {
156882
156965
  return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.InvalidUrl };
@@ -156939,6 +157022,9 @@ class ArcGisUtilities {
156939
157022
  * @param password Password to use for legacy token based security
156940
157023
  * @param ignoreCache Flag to skip cache lookup (i.e. force a new server request)
156941
157024
  * @param requireToken Flag to indicate if a token is required
157025
+ * @throws [[MapLayerUntrustedOriginError]] if an NTLM/Negotiate challenge could not be answered because
157026
+ * the URL's origin is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]);
157027
+ * all other errors are caught and reported by returning `undefined`.
156942
157028
  */
156943
157029
  static async getServiceJson(args) {
156944
157030
  const { url, formatId, userName, password, queryParams, ignoreCache, requireToken } = args;
@@ -156974,8 +157060,17 @@ class ArcGisUtilities {
156974
157060
  }
156975
157061
  let response = await fetch(tmpUrl, { method: "GET" });
156976
157062
  if (response.status === 401 && !requireToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
156977
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
156978
- response = await fetch(tmpUrl, { method: "GET", credentials: "include" });
157063
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
157064
+ const challengedUrl = response.url || tmpUrl.toString();
157065
+ if (!_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
157066
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError(challengedUrl);
157067
+ _IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
157068
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
157069
+ response = await fetch(challengedUrl, {
157070
+ method: "GET",
157071
+ credentials: "include",
157072
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
157073
+ });
156979
157074
  }
156980
157075
  // Append security token when corresponding error code is returned by ArcGIS service
156981
157076
  let errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);
@@ -156997,8 +157092,10 @@ class ArcGisUtilities {
156997
157092
  ArcGisUtilities._serviceCache.set(url, (errorCode === undefined ? info : undefined));
156998
157093
  return info; // Always return json, even though it contains an error code.
156999
157094
  }
157000
- catch {
157095
+ catch (err) {
157001
157096
  ArcGisUtilities._serviceCache.set(url, undefined);
157097
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError)
157098
+ throw err; // propagate so callers can report the blocked origin
157002
157099
  return undefined;
157003
157100
  }
157004
157101
  }
@@ -157160,7 +157257,9 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
157160
157257
  try {
157161
157258
  metadata = await _tile_internal__WEBPACK_IMPORTED_MODULE_0__.ArcGisUtilities.getServiceJson({ url: this._settings.url, formatId: this._settings.formatId, userName: this._settings.userName, password: this._settings.password, queryParams: this._settings.collectQueryParams() });
157162
157259
  }
157163
- catch {
157260
+ catch (err) {
157261
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError)
157262
+ this.reportBlockedOrigin(err.url);
157164
157263
  }
157165
157264
  if (metadata && metadata.accessTokenRequired) {
157166
157265
  const accessClient = _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.getAccessClient(this._settings.formatId);
@@ -157208,12 +157307,32 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
157208
157307
  await this._firstRequestPromise;
157209
157308
  let response;
157210
157309
  try {
157211
- response = await fetch(urlObj, { ...options, credentials: this._includeUserCredentials ? "include" : undefined });
157310
+ const requestUrl = urlObj.toString();
157311
+ const includeCredentials = this.includeUserCredentials(requestUrl);
157312
+ response = await fetch(urlObj, {
157313
+ ...options,
157314
+ credentials: includeCredentials ? "include" : undefined,
157315
+ redirect: includeCredentials ? this.credentialedRedirect : options?.redirect,
157316
+ });
157317
+ if (includeCredentials)
157318
+ this.checkCredentialedRedirect(requestUrl, response);
157212
157319
  if (response.status === 401 && !this._lastAccessToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
157213
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
157214
- response = await fetch(urlObj, { ...options, credentials: "include" });
157215
- if (response.status === 200) {
157216
- this._includeUserCredentials = true; // avoid going through 401 challenges over and over
157320
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
157321
+ const challengedUrl = response.url || requestUrl;
157322
+ if (this.isSsoAllowed(challengedUrl)) {
157323
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
157324
+ this.logUntrustedOriginUse(challengedUrl);
157325
+ response = await fetch(challengedUrl, {
157326
+ ...options,
157327
+ credentials: "include",
157328
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
157329
+ });
157330
+ if (response.status === 200) {
157331
+ this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
157332
+ }
157333
+ }
157334
+ else {
157335
+ this.reportBlockedOrigin(challengedUrl);
157217
157336
  }
157218
157337
  }
157219
157338
  if ((this._lastAccessToken && response.status === 400)
@@ -157426,8 +157545,12 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
157426
157545
  }
157427
157546
  async initialize() {
157428
157547
  const metadata = await this.getServiceJson();
157429
- if (metadata?.content === undefined)
157548
+ if (metadata?.content === undefined) {
157549
+ // By returning (i.e., not throwing), we ensure the tile tree gets created and the current provider is preserved to report status.
157550
+ if (this.status === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.UntrustedOrigin)
157551
+ return;
157430
157552
  throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_0__.ServerError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_5__.IModelStatus.ValidationFailed, "");
157553
+ }
157431
157554
  const json = metadata.content;
157432
157555
  if (json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.TokenRequired
157433
157556
  || json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.InvalidToken
@@ -157512,7 +157635,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
157512
157635
  addLogoCards(cards) {
157513
157636
  if (!cards.dataset.arcGisLogoCard) {
157514
157637
  cards.dataset.arcGisLogoCard = "true";
157515
- cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS", notice: this._copyrightText }));
157638
+ cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS", noticeLines: [this._copyrightText] }));
157516
157639
  }
157517
157640
  }
157518
157641
  async addAttributions(cards, _vp) {
@@ -157553,7 +157676,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
157553
157676
  if (json && Array.isArray(json.results)) {
157554
157677
  for (const result of json.results) {
157555
157678
  if (result.attributes !== undefined && result.attributes[result.displayFieldName] !== undefined) {
157556
- const thisString = `${result.displayFieldName}: ${result.attributes[result.displayFieldName]}`;
157679
+ const thisString = `${(0,_tile_internal__WEBPACK_IMPORTED_MODULE_2__.escapeHtml)(String(result.displayFieldName))}: ${(0,_tile_internal__WEBPACK_IMPORTED_MODULE_2__.escapeHtml)(String(result.attributes[result.displayFieldName]))}`;
157557
157680
  if (!stringSet.has(thisString)) {
157558
157681
  strings.push(thisString);
157559
157682
  stringSet.add(thisString);
@@ -157869,13 +157992,7 @@ class BingMapsImageryLayerProvider extends _tile_internal__WEBPACK_IMPORTED_MODU
157869
157992
  const copyrights = [];
157870
157993
  for (const match of matchingAttributions)
157871
157994
  copyrights.push(match.copyrightMessage);
157872
- let copyrightMsg = "";
157873
- for (let i = 0; i < copyrights.length; ++i) {
157874
- if (i > 0)
157875
- copyrightMsg += "<br>";
157876
- copyrightMsg += copyrights[i];
157877
- }
157878
- cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.makeLogoCard({ iconSrc: `${_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.publicPath}images/bing.svg`, heading: "Microsoft Bing", notice: copyrightMsg }));
157995
+ cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.makeLogoCard({ iconSrc: `${_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.publicPath}images/bing.svg`, heading: "Microsoft Bing", noticeLines: copyrights }));
157879
157996
  }
157880
157997
  async addAttributions(cards, vp) {
157881
157998
  // eslint-disable-next-line @typescript-eslint/no-deprecated
@@ -158484,7 +158601,10 @@ class WmsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE
158484
158601
  // Don't throw error if unauthorized status:
158485
158602
  // We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
158486
158603
  // When credentials will be provided, a new provider will be created, and initialization should be fine.
158487
- if (error?.status === 401) {
158604
+ if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError) {
158605
+ this.reportBlockedOrigin(error.url);
158606
+ }
158607
+ else if (error?.status === 401) {
158488
158608
  this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerImageryProviderStatus.RequireAuth);
158489
158609
  }
158490
158610
  else {
@@ -158646,7 +158766,8 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
158646
158766
  }
158647
158767
  async initialize() {
158648
158768
  try {
158649
- this._capabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_2__.WmtsCapabilities.create(this._baseUrl);
158769
+ const credentials = (this._settings.userName && this._settings.password ? { user: this._settings.userName, password: this._settings.password } : undefined);
158770
+ this._capabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_2__.WmtsCapabilities.create(this._baseUrl, credentials);
158650
158771
  this.initPreferredTileMatrixSet();
158651
158772
  this.initPreferredStyle();
158652
158773
  this.initDisplayedLayer();
@@ -158659,7 +158780,10 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
158659
158780
  // Don't throw error if unauthorized status:
158660
158781
  // We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
158661
158782
  // When credentials will be provided, a new provider will be created, and initialization should be fine.
158662
- if (error?.status === 401) {
158783
+ if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerUntrustedOriginError) {
158784
+ this.reportBlockedOrigin(error.url);
158785
+ }
158786
+ else if (error?.status === 401) {
158663
158787
  this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.RequireAuth);
158664
158788
  }
158665
158789
  else {
@@ -159470,14 +159594,18 @@ __webpack_require__.r(__webpack_exports__);
159470
159594
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
159471
159595
  /* harmony export */ WmsUtilities: () => (/* binding */ WmsUtilities)
159472
159596
  /* harmony export */ });
159473
- /* harmony import */ var _request_Request__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../request/Request */ "../../core/frontend/lib/esm/request/Request.js");
159474
- /* harmony import */ var _request_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../request/utils */ "../../core/frontend/lib/esm/request/utils.js");
159597
+ /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
159598
+ /* harmony import */ var _request_Request__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../request/Request */ "../../core/frontend/lib/esm/request/Request.js");
159599
+ /* harmony import */ var _request_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../request/utils */ "../../core/frontend/lib/esm/request/utils.js");
159600
+ /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
159475
159601
  /*---------------------------------------------------------------------------------------------
159476
159602
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
159477
159603
  * See LICENSE.md in the project root for license terms and full copyright notice.
159478
159604
  *--------------------------------------------------------------------------------------------*/
159479
159605
 
159480
159606
 
159607
+
159608
+
159481
159609
  /** @packageDocumentation
159482
159610
  * @module Tiles
159483
159611
  */
@@ -159494,16 +159622,35 @@ class WmsUtilities {
159494
159622
  static async fetchXml(url, credentials) {
159495
159623
  let headers;
159496
159624
  if (credentials && credentials.user && credentials.password) {
159497
- headers = new Headers();
159498
- (0,_request_utils__WEBPACK_IMPORTED_MODULE_1__.setBasicAuthorization)(headers, credentials);
159625
+ // Basic credentials are considered settings-derived credentials for this source. When the registry is
159626
+ // enforcing trusted origins, the source URL itself is the only implicitly trusted origin for basic auth;
159627
+ // opaque/custom-protocol URLs have no network origin and must therefore be treated as untrusted.
159628
+ const allowBasicAuth = !_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins
159629
+ || _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, url);
159630
+ if (allowBasicAuth) {
159631
+ headers = new Headers();
159632
+ (0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.setBasicAuthorization)(headers, credentials);
159633
+ }
159499
159634
  }
159500
159635
  let response = await fetch(url, { method: "GET", headers });
159501
- if (!credentials && response.status === 401 && (0,_request_utils__WEBPACK_IMPORTED_MODULE_1__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
159502
- // We got a http 401 challenge, lets try SSO (i.e. Windows Authentication)
159503
- response = await fetch(url, { method: "GET", credentials: "include" });
159636
+ if (!headers && credentials && credentials.user && credentials.password && (response.status === 401 || response.status === 403)) {
159637
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(url);
159638
+ }
159639
+ if (!credentials && response.status === 401 && (0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
159640
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
159641
+ const challengedUrl = response.url || url;
159642
+ if (!_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
159643
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(challengedUrl);
159644
+ _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
159645
+ // We got a http 401 challenge, lets try SSO (i.e. Windows Authentication).
159646
+ response = await fetch(challengedUrl, {
159647
+ method: "GET",
159648
+ credentials: "include",
159649
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
159650
+ });
159504
159651
  }
159505
159652
  if (response.status !== 200)
159506
- throw new _request_Request__WEBPACK_IMPORTED_MODULE_0__.HttpResponseError(response.status, await response.text());
159653
+ throw new _request_Request__WEBPACK_IMPORTED_MODULE_1__.HttpResponseError(response.status, await response.text());
159507
159654
  return response.text();
159508
159655
  }
159509
159656
  }
@@ -171917,6 +172064,7 @@ __webpack_require__.r(__webpack_exports__);
171917
172064
  /* harmony export */ MapLayerSourceStatus: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSourceStatus),
171918
172065
  /* harmony export */ MapLayerSources: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSources),
171919
172066
  /* harmony export */ MapLayerTileTreeReference: () => (/* reexport safe */ _map_MapLayerTileTreeReference__WEBPACK_IMPORTED_MODULE_64__.MapLayerTileTreeReference),
172067
+ /* harmony export */ MapLayerUntrustedOriginError: () => (/* reexport safe */ _map_MapLayerFormatRegistry__WEBPACK_IMPORTED_MODULE_42__.MapLayerUntrustedOriginError),
171920
172068
  /* harmony export */ MapTile: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTile),
171921
172069
  /* harmony export */ MapTileLoader: () => (/* reexport safe */ _internal_tile_map_MapTileLoader__WEBPACK_IMPORTED_MODULE_72__.MapTileLoader),
171922
172070
  /* harmony export */ MapTileProjection: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTileProjection),
@@ -171996,6 +172144,7 @@ __webpack_require__.r(__webpack_exports__);
171996
172144
  /* harmony export */ collectMaskRefs: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.collectMaskRefs),
171997
172145
  /* harmony export */ compareMapLayer: () => (/* reexport safe */ _internal_render_webgl_MapLayerParams__WEBPACK_IMPORTED_MODULE_94__.compareMapLayer),
171998
172146
  /* harmony export */ computeCesiumTokenTimeoutInterval: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.computeCesiumTokenTimeoutInterval),
172147
+ /* harmony export */ computeOrthometricVerticalShift: () => (/* reexport safe */ _internal_tile_OrbitGtTileTree__WEBPACK_IMPORTED_MODULE_84__.computeOrthometricVerticalShift),
171999
172148
  /* harmony export */ createClassifierTileTreeReference: () => (/* reexport safe */ _internal_tile_ClassifierTileTree__WEBPACK_IMPORTED_MODULE_83__.createClassifierTileTreeReference),
172000
172149
  /* harmony export */ createDefaultViewFlagOverrides: () => (/* reexport safe */ _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__.createDefaultViewFlagOverrides),
172001
172150
  /* harmony export */ createGraphicFromDescription: () => (/* reexport safe */ _internal_tile_ImdlGraphicsCreator__WEBPACK_IMPORTED_MODULE_37__.createGraphicFromDescription),
@@ -172012,6 +172161,7 @@ __webpack_require__.r(__webpack_exports__);
172012
172161
  /* harmony export */ decodeMeshoptBuffer: () => (/* reexport safe */ _internal_tile_MeshoptCompression__WEBPACK_IMPORTED_MODULE_93__.decodeMeshoptBuffer),
172013
172162
  /* harmony export */ deflateCoordinates: () => (/* reexport safe */ _internal_tile_map_ImageryProviders_CoordinatesUtils__WEBPACK_IMPORTED_MODULE_47__.deflateCoordinates),
172014
172163
  /* harmony export */ disposeTileTreesForGeometricModels: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.disposeTileTreesForGeometricModels),
172164
+ /* harmony export */ escapeHtml: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.escapeHtml),
172015
172165
  /* harmony export */ getCesiumAccessClient: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessClient),
172016
172166
  /* harmony export */ getCesiumAccessTokenAndEndpointUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessTokenAndEndpointUrl),
172017
172167
  /* harmony export */ getCesiumAssetUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAssetUrl),
@@ -172031,7 +172181,8 @@ __webpack_require__.r(__webpack_exports__);
172031
172181
  /* harmony export */ readImdlContent: () => (/* reexport safe */ _ImdlReader__WEBPACK_IMPORTED_MODULE_35__.readImdlContent),
172032
172182
  /* harmony export */ readPntsColors: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPntsColors),
172033
172183
  /* harmony export */ readPointCloudTileContent: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPointCloudTileContent),
172034
- /* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic)
172184
+ /* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic),
172185
+ /* harmony export */ tryGetOrigin: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.tryGetOrigin)
172035
172186
  /* harmony export */ });
172036
172187
  /* harmony import */ var _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal/tile/ViewFlagOverrides */ "../../core/frontend/lib/esm/internal/tile/ViewFlagOverrides.js");
172037
172188
  /* harmony import */ var _map_MapCartoRectangle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map/MapCartoRectangle */ "../../core/frontend/lib/esm/tile/map/MapCartoRectangle.js");
@@ -173730,7 +173881,8 @@ __webpack_require__.r(__webpack_exports__);
173730
173881
  __webpack_require__.r(__webpack_exports__);
173731
173882
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
173732
173883
  /* harmony export */ MapLayerFormat: () => (/* binding */ MapLayerFormat),
173733
- /* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry)
173884
+ /* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry),
173885
+ /* harmony export */ MapLayerUntrustedOriginError: () => (/* binding */ MapLayerUntrustedOriginError)
173734
173886
  /* harmony export */ });
173735
173887
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
173736
173888
  /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
@@ -173745,7 +173897,7 @@ __webpack_require__.r(__webpack_exports__);
173745
173897
 
173746
173898
 
173747
173899
 
173748
- const loggerCategory = "ArcGISFeatureProvider";
173900
+ const loggerCategory = "MapLayerFormatRegistry";
173749
173901
  /**
173750
173902
  * Class representing a map-layer format.
173751
173903
  * Each format has it's unique 'formatId' string, used to uniquely identify a format in the [[MapLayerFormatRegistry]].
@@ -173794,16 +173946,127 @@ class MapLayerFormat {
173794
173946
  return undefined;
173795
173947
  }
173796
173948
  }
173949
+ /** Error thrown when an NTLM or Negotiate http 401 challenge could not be answered because the request
173950
+ * URL's origin is not listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]]
173951
+ * (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
173952
+ * Thrown by the static map-layer utilities (e.g. capabilities / service-metadata fetches) that have no
173953
+ * provider instance on which to report the blocked origin; callers convert it to
173954
+ * [[MapLayerImageryProviderStatus.UntrustedOrigin]] (provider initialization) or
173955
+ * [[MapLayerSourceStatus.UntrustedOrigin]] (source validation).
173956
+ * @internal
173957
+ */
173958
+ class MapLayerUntrustedOriginError extends Error {
173959
+ /** The URL of the request whose authentication challenge was left unanswered. */
173960
+ url;
173961
+ constructor(url) {
173962
+ super(`Authentication blocked: origin of '${url}' is not listed in MapLayerFormatRegistry.trustedCredentialsOrigins`);
173963
+ this.url = url;
173964
+ }
173965
+ }
173797
173966
  /**
173798
173967
  * A registry of MapLayerFormats identified by their unique format IDs. The registry can be accessed via [[IModelApp.mapLayerFormatRegistry]].
173799
173968
  * @public
173800
173969
  */
173801
173970
  class MapLayerFormatRegistry {
173802
173971
  _configOptions;
173972
+ _trustedCredentialsOrigins = [];
173973
+ /** Opt-in enforcement of origin restrictions on map-layer credentials.
173974
+ * When enabled, map layer providers:
173975
+ * - attach the basic-auth credentials stored in the layer settings only to requests targeting the origin
173976
+ * of the layer's settings URL or an origin listed in [[trustedCredentialsOrigins]];
173977
+ * - retry a request with browser credentials included (i.e. SSO / Windows Authentication) after an NTLM
173978
+ * or Negotiate http 401 challenge only for origins explicitly listed in [[trustedCredentialsOrigins]]
173979
+ * (the settings-URL origin is NOT implicitly trusted for SSO, since map-layer URLs may originate from
173980
+ * untrusted user input while SSO shares the user's ambient identity).
173981
+ * Default is false, preserving the legacy behavior of sending credentials to any request URL.
173982
+ * @beta
173983
+ */
173984
+ restrictCredentialsToTrustedOrigins = false;
173803
173985
  constructor(opts) {
173804
173986
  this._configOptions = opts ?? {};
173805
173987
  _internal__WEBPACK_IMPORTED_MODULE_2__.internalMapLayerImageryFormats.forEach((format) => this.register(format));
173806
173988
  }
173989
+ /** Origins (e.g. "https://tiles.example.com") to which map layer providers may send credentials —
173990
+ * both the basic-auth credentials stored in the layer settings and browser credentials for
173991
+ * SSO (i.e. Windows Authentication) retries after an NTLM or Negotiate http 401 challenge.
173992
+ * Only enforced when [[restrictCredentialsToTrustedOrigins]] is enabled.
173993
+ * For basic-auth, the origin of each map layer's settings URL is always implicitly trusted; for SSO,
173994
+ * origins must be explicitly listed here.
173995
+ * Entries are normalized to their origin (scheme + host + port); only `http:` and `https:` URLs are accepted,
173996
+ * and any other entry is ignored and logged. Opaque schemes such as `file:`, `data:`, `about:` and custom
173997
+ * Electron protocols are rejected because they all share the same serialized origin, so trusting one would
173998
+ * trust every other.
173999
+ * @beta
174000
+ */
174001
+ get trustedCredentialsOrigins() {
174002
+ return this._trustedCredentialsOrigins;
174003
+ }
174004
+ set trustedCredentialsOrigins(origins) {
174005
+ const normalized = [];
174006
+ for (const entry of origins) {
174007
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(entry);
174008
+ if (origin !== undefined)
174009
+ normalized.push(origin);
174010
+ else
174011
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `trustedCredentialsOrigins: ignoring '${entry}'; entries must be http or https URLs.`);
174012
+ }
174013
+ this._trustedCredentialsOrigins = normalized;
174014
+ }
174015
+ /** Returns true if a request to the given URL may be retried with browser credentials included
174016
+ * (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
174017
+ * Always true unless [[restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
174018
+ * When enabled, the URL's origin must be explicitly listed in [[trustedCredentialsOrigins]];
174019
+ * unlike basic-auth, the settings-URL origin is NOT implicitly trusted because SSO shares the user's
174020
+ * ambient identity, and map-layer URLs may originate from untrusted user input.
174021
+ * @internal
174022
+ */
174023
+ isSsoAllowed(url) {
174024
+ if (!this.restrictCredentialsToTrustedOrigins)
174025
+ return true;
174026
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
174027
+ // Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
174028
+ return origin !== undefined && this._trustedCredentialsOrigins.includes(origin);
174029
+ }
174030
+ /** Returns true if the basic-auth credentials belonging to a map-layer source or settings URL may be
174031
+ * attached to a request to the given URL. Always true unless [[restrictCredentialsToTrustedOrigins]]
174032
+ * is enabled (opt-in). When enabled, the origin of `settingsUrl` is implicitly trusted (the credentials
174033
+ * belong to that server); any other origin must be listed in [[trustedCredentialsOrigins]].
174034
+ * @internal
174035
+ */
174036
+ isCredentialsSharingAllowed(url, settingsUrl) {
174037
+ if (!this.restrictCredentialsToTrustedOrigins)
174038
+ return true;
174039
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
174040
+ if (origin === undefined)
174041
+ return false;
174042
+ if (origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
174043
+ return true;
174044
+ // Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
174045
+ return this._trustedCredentialsOrigins.includes(origin);
174046
+ }
174047
+ /** Origins for which a "credentials sent to untrusted origin" warning was already logged;
174048
+ * used to log the discovery warning only once per origin.
174049
+ */
174050
+ _untrustedUseLogged = new Set();
174051
+ /** Logs a warning (once per origin) when credentials are sent to an origin that would be blocked
174052
+ * if [[restrictCredentialsToTrustedOrigins]] were enabled.
174053
+ * Helps applications discover the origins they need to whitelist before opting in to the restriction.
174054
+ * If `settingsUrl` is supplied, requests sharing its origin are not logged, since that origin is
174055
+ * implicitly trusted for basic-auth.
174056
+ * @internal
174057
+ */
174058
+ logUntrustedOriginUse(url, settingsUrl) {
174059
+ if (this.restrictCredentialsToTrustedOrigins)
174060
+ return; // restriction active; nothing to preview
174061
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url) ?? url;
174062
+ if (settingsUrl !== undefined && origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
174063
+ return; // implicitly trusted for basic-auth
174064
+ if (this._untrustedUseLogged.has(origin) || this._trustedCredentialsOrigins.includes(origin))
174065
+ return;
174066
+ this._untrustedUseLogged.add(origin);
174067
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `Credentials sent to origin '${origin}' which is not in MapLayerFormatRegistry.trustedCredentialsOrigins; `
174068
+ + "this request would be blocked if restrictCredentialsToTrustedOrigins were enabled.");
174069
+ }
173807
174070
  _formats = new Map();
173808
174071
  isRegistered(formatId) { return this._formats.get(formatId) !== undefined; }
173809
174072
  register(formatClass) {
@@ -173969,6 +174232,14 @@ class WmsMapLayerFormat extends ImageryMapLayerFormat {
173969
174232
  return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
173970
174233
  }
173971
174234
  catch (err) {
174235
+ if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
174236
+ let blockedOrigin;
174237
+ try {
174238
+ blockedOrigin = new URL(err.url).origin;
174239
+ }
174240
+ catch { /* non-hierarchical URL */ }
174241
+ return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
174242
+ }
173972
174243
  let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
173973
174244
  if (err?.status === 401) {
173974
174245
  status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
@@ -174034,6 +174305,14 @@ class WmtsMapLayerFormat extends ImageryMapLayerFormat {
174034
174305
  return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
174035
174306
  }
174036
174307
  catch (err) {
174308
+ if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
174309
+ let blockedOrigin;
174310
+ try {
174311
+ blockedOrigin = new URL(err.url).origin;
174312
+ }
174313
+ catch { /* non-hierarchical URL */ }
174314
+ return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
174315
+ }
174037
174316
  let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
174038
174317
  if (err?.status === 401) {
174039
174318
  status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
@@ -174098,7 +174377,9 @@ const internalMapLayerImageryFormats = [WmsMapLayerFormat, WmtsMapLayerFormat, A
174098
174377
  __webpack_require__.r(__webpack_exports__);
174099
174378
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
174100
174379
  /* harmony export */ MapLayerImageryProvider: () => (/* binding */ MapLayerImageryProvider),
174101
- /* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus)
174380
+ /* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus),
174381
+ /* harmony export */ escapeHtml: () => (/* binding */ escapeHtml),
174382
+ /* harmony export */ tryGetOrigin: () => (/* binding */ tryGetOrigin)
174102
174383
  /* harmony export */ });
174103
174384
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
174104
174385
  /* harmony import */ var _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @itwin/core-common */ "../../core/common/lib/esm/core-common.js");
@@ -174125,6 +174406,34 @@ __webpack_require__.r(__webpack_exports__);
174125
174406
  const tileImageSize = 256, untiledImageSize = 256;
174126
174407
  const earthRadius = 6378137;
174127
174408
  const doDebugToolTips = false;
174409
+ /** Escapes HTML metacharacters so the text renders literally when assigned to `innerHTML`.
174410
+ * Use for any server- or user-supplied string that ends up in the map tooltip, which is rendered
174411
+ * as HTML by [[MapLayerTileTreeReference.getToolTip]].
174412
+ * @internal
174413
+ */
174414
+ function escapeHtml(text) {
174415
+ return text.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
174416
+ }
174417
+ /** Returns the origin (scheme + host + port) of the given URL, or undefined if it cannot be parsed or does
174418
+ * not denote a distinct network origin.
174419
+ *
174420
+ * Only `http:` and `https:` URLs yield an origin. Every other scheme is rejected because opaque URLs
174421
+ * — `file:`, `data:`, `about:`, `blob:null`, and the custom protocols Electron hosts commonly register —
174422
+ * all serialize to the literal string `"null"`. Comparing those would make unrelated URLs look same-origin,
174423
+ * so a single trusted entry could unlock all of them. Callers use this for credential-trust decisions, and
174424
+ * returning `undefined` keeps those decisions fail-closed.
174425
+ * @internal
174426
+ */
174427
+ function tryGetOrigin(url) {
174428
+ let parsed;
174429
+ try {
174430
+ parsed = new URL(url);
174431
+ }
174432
+ catch {
174433
+ return undefined;
174434
+ }
174435
+ return (parsed.protocol === "http:" || parsed.protocol === "https:") ? parsed.origin : undefined;
174436
+ }
174128
174437
  /** The status of the map layer imagery provider that lets you know if authentication is needed to request tiles.
174129
174438
  * @public
174130
174439
  */
@@ -174132,6 +174441,12 @@ var MapLayerImageryProviderStatus;
174132
174441
  (function (MapLayerImageryProviderStatus) {
174133
174442
  MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["Valid"] = 0] = "Valid";
174134
174443
  MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["RequireAuth"] = 1] = "RequireAuth";
174444
+ /** A request received an authentication challenge, but credentials were withheld because the request origin
174445
+ * is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
174446
+ * The blocked origins are available via [[MapLayerImageryProvider.blockedOrigins]].
174447
+ * @beta
174448
+ */
174449
+ MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["UntrustedOrigin"] = 2] = "UntrustedOrigin";
174135
174450
  })(MapLayerImageryProviderStatus || (MapLayerImageryProviderStatus = {}));
174136
174451
  /** Abstract class for map layer imagery providers.
174137
174452
  * Map layer imagery providers request and provide tile images and other data. Each map layer from a separate source needs its own imagery provider object.
@@ -174149,7 +174464,41 @@ class MapLayerImageryProvider {
174149
174464
  /** @internal */
174150
174465
  _status = MapLayerImageryProviderStatus.Valid;
174151
174466
  /** @internal */
174152
- _includeUserCredentials = false;
174467
+ _blockedOrigins = new Set();
174468
+ /** Origins of requests for which credentials were withheld because they are not trusted
174469
+ * (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
174470
+ * Populated when [[status]] transitions to [[MapLayerImageryProviderStatus.UntrustedOrigin]];
174471
+ * [[onStatusChanged]] is raised again each time a new origin is added. Cleared by [[resetStatus]].
174472
+ * @beta
174473
+ */
174474
+ get blockedOrigins() { return [...this._blockedOrigins]; }
174475
+ /** Origins for which a previous SSO handshake (i.e. Windows Authentication) succeeded.
174476
+ * Browser credentials are only included for subsequent requests targeting these origins,
174477
+ * so that a successful handshake with one host does not leak credentials to other hosts
174478
+ * this provider may contact.
174479
+ * @internal
174480
+ */
174481
+ _ssoSucceededOrigins = new Set();
174482
+ /** Returns true if browser credentials should be included for the given URL because a previous
174483
+ * SSO handshake succeeded for its origin AND the origin is still allowed by the current policy
174484
+ * (see [[MapLayerFormatRegistry.isSsoAllowed]]). Re-checking the policy ensures a handshake recorded
174485
+ * while enforcement was disabled — or before an origin was removed from
174486
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]] — does not keep latching credentials on.
174487
+ * @internal
174488
+ */
174489
+ includeUserCredentials(url) {
174490
+ const origin = tryGetOrigin(url);
174491
+ return origin !== undefined && this._ssoSucceededOrigins.has(origin) && this.isSsoAllowed(url);
174492
+ }
174493
+ /** Records that an SSO handshake succeeded for the given URL's origin, so subsequent requests
174494
+ * to that origin include browser credentials without going through another 401 challenge.
174495
+ * @internal
174496
+ */
174497
+ recordSsoSucceeded(url) {
174498
+ const origin = tryGetOrigin(url);
174499
+ if (origin !== undefined)
174500
+ this._ssoSucceededOrigins.add(origin);
174501
+ }
174153
174502
  /** @internal */
174154
174503
  onFirstRequestCompleted = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
174155
174504
  /** @internal */
@@ -174165,7 +174514,17 @@ class MapLayerImageryProvider {
174165
174514
  * @public
174166
174515
  */
174167
174516
  get supportsMapFeatureInfo() { return false; }
174168
- resetStatus() { this.setStatus(MapLayerImageryProviderStatus.Valid); }
174517
+ /** Reset the provider's status to [[MapLayerImageryProviderStatus.Valid]] and clear the list of
174518
+ * [[blockedOrigins]] accumulated while in the [[MapLayerImageryProviderStatus.UntrustedOrigin]] state.
174519
+ * Raises [[onStatusChanged]] if the status actually changes.
174520
+ * Typically called after the user has provided credentials or the application has updated
174521
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]], so that subsequent requests are re-attempted.
174522
+ * @beta
174523
+ */
174524
+ resetStatus() {
174525
+ this._blockedOrigins.clear();
174526
+ this.setStatus(MapLayerImageryProviderStatus.Valid);
174527
+ }
174169
174528
  /** @internal */
174170
174529
  get tileSize() { return this._usesCachedTiles ? tileImageSize : untiledImageSize; }
174171
174530
  /** @internal */
@@ -174339,6 +174698,32 @@ class MapLayerImageryProvider {
174339
174698
  (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setBasicAuthorization)(headers, this._settings.userName, this._settings.password);
174340
174699
  }
174341
174700
  }
174701
+ /** Returns true if the given URL has the same origin as this layer's settings URL.
174702
+ * Used to avoid leaking credentials to third-party hosts.
174703
+ * @internal
174704
+ */
174705
+ matchesSettingsUrlOrigin(url) {
174706
+ const origin = tryGetOrigin(url);
174707
+ return origin !== undefined && origin === tryGetOrigin(this._settings.url);
174708
+ }
174709
+ /** Returns true if the basic-auth credentials from the layer settings may be attached to a request to the given URL.
174710
+ * Always true unless [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
174711
+ * When enabled, the origin of this layer's settings URL is implicitly trusted (the credentials belong to that
174712
+ * server); other origins must be listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]].
174713
+ * See [[MapLayerFormatRegistry.isCredentialsSharingAllowed]].
174714
+ * @internal
174715
+ */
174716
+ isCredentialsSharingAllowed(url) {
174717
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, this._settings.url);
174718
+ }
174719
+ /** Returns true if a request to the given URL may be retried with browser credentials included
174720
+ * (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
174721
+ * See [[MapLayerFormatRegistry.isSsoAllowed]].
174722
+ * @internal
174723
+ */
174724
+ isSsoAllowed(url) {
174725
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(url);
174726
+ }
174342
174727
  /** @internal */
174343
174728
  async makeTileRequest(url, timeoutMs, authorization) {
174344
174729
  // We want to complete the first request before letting other requests go;
@@ -174358,40 +174743,132 @@ class MapLayerImageryProvider {
174358
174743
  throw new Error("fetch call failed");
174359
174744
  return response;
174360
174745
  }
174746
+ /** Records the given URL's origin and transitions the status to [[MapLayerImageryProviderStatus.UntrustedOrigin]].
174747
+ * Called when a request received an authentication challenge that could not be answered because the origin
174748
+ * is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
174749
+ * Raises [[onStatusChanged]] on the status transition, and again whenever a new origin is added.
174750
+ * @internal
174751
+ */
174752
+ reportBlockedOrigin(url) {
174753
+ const origin = tryGetOrigin(url) ?? url;
174754
+ const isNewOrigin = !this._blockedOrigins.has(origin);
174755
+ this._blockedOrigins.add(origin);
174756
+ if (this._status !== MapLayerImageryProviderStatus.UntrustedOrigin)
174757
+ this.setStatus(MapLayerImageryProviderStatus.UntrustedOrigin);
174758
+ else if (isNewOrigin)
174759
+ this.onStatusChanged.raiseEvent(this); // status unchanged, but a new origin was blocked
174760
+ }
174761
+ /** Logs a warning (once per origin, app-wide) when credentials are sent to an origin that would be blocked
174762
+ * if [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] were enabled.
174763
+ * Helps applications discover the origins they need to whitelist before opting in to the restriction.
174764
+ * See [[MapLayerFormatRegistry.logUntrustedOriginUse]].
174765
+ * @internal
174766
+ */
174767
+ logUntrustedOriginUse(url) {
174768
+ _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(url);
174769
+ }
174770
+ /** The redirect policy to apply to a request that carries browser credentials (see [[includeUserCredentials]]).
174771
+ *
174772
+ * When [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled, redirects are refused
174773
+ * outright (`"error"`). `fetch` cannot be asked to follow only same-origin redirects, and by the time a
174774
+ * followed redirect can be inspected the credentials have already been delivered to the destination — so
174775
+ * refusing is the only way to honour the guarantee that credentials reach none but the origins listed in
174776
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]]. Legitimate same-origin redirects fail as a result;
174777
+ * that is the cost of the opt-in restriction.
174778
+ *
174779
+ * When the restriction is disabled (the default), redirects are followed as before and
174780
+ * [[checkCredentialedRedirect]] reports the destination after the fact.
174781
+ * @internal
174782
+ */
174783
+ get credentialedRedirect() {
174784
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
174785
+ }
174786
+ /** Detects that a request carrying browser credentials (see [[includeUserCredentials]]) was transparently
174787
+ * redirected to a different origin, and reports or logs that origin.
174788
+ *
174789
+ * This is a **best-effort, after-the-fact** signal used only while
174790
+ * [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is disabled, where credentialed requests
174791
+ * still follow redirects (see [[credentialedRedirect]]). It cannot prevent the exposure — the credentials
174792
+ * have already been sent — and it does not fire at all when the destination denies CORS, because `fetch`
174793
+ * then rejects instead of returning a `Response`. The destination origin is never latched as SSO-succeeded,
174794
+ * so credentials do not keep flowing to it.
174795
+ * @internal
174796
+ */
174797
+ checkCredentialedRedirect(requestedUrl, response) {
174798
+ const finalOrigin = tryGetOrigin(response.url);
174799
+ if (!response.url || finalOrigin === undefined || finalOrigin === tryGetOrigin(requestedUrl))
174800
+ return;
174801
+ if (!this.isSsoAllowed(response.url))
174802
+ this.reportBlockedOrigin(response.url);
174803
+ else
174804
+ this.logUntrustedOriginUse(response.url); // no-op when the restriction is enabled
174805
+ }
174361
174806
  /** @internal */
174362
174807
  async makeRequest(url, timeoutMs, authorization) {
174363
174808
  let response;
174364
174809
  let headers;
174365
174810
  let hasCreds = false;
174811
+ // Whether this request had basic-auth credentials of its own to offer. Requests carrying a caller-supplied
174812
+ // `authorization` are excluded: those bypass the origin policy entirely.
174813
+ const hasSettingsCreds = !authorization && !!this._settings.userName && !!this._settings.password;
174366
174814
  if (authorization) {
174367
174815
  headers = new Headers();
174368
174816
  headers.set("Authorization", authorization);
174369
174817
  }
174370
- else if (this._settings.userName && this._settings.password) {
174371
- hasCreds = true;
174372
- headers = new Headers();
174373
- this.setRequestAuthorization(headers);
174818
+ else if (hasSettingsCreds) {
174819
+ if (this.isCredentialsSharingAllowed(url)) {
174820
+ hasCreds = true;
174821
+ headers = new Headers();
174822
+ this.setRequestAuthorization(headers);
174823
+ if (!this.matchesSettingsUrlOrigin(url))
174824
+ this.logUntrustedOriginUse(url);
174825
+ }
174374
174826
  }
174827
+ const includeCredentials = this.includeUserCredentials(url);
174375
174828
  const opts = {
174376
174829
  method: "GET",
174377
174830
  headers,
174378
- credentials: this._includeUserCredentials ? "include" : undefined,
174831
+ credentials: includeCredentials ? "include" : undefined,
174832
+ redirect: includeCredentials ? this.credentialedRedirect : undefined,
174379
174833
  };
174380
174834
  if (timeoutMs !== undefined)
174381
174835
  (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setRequestTimeout)(opts, timeoutMs);
174382
174836
  response = await fetch(url, opts);
174837
+ if (includeCredentials)
174838
+ this.checkCredentialedRedirect(url, response);
174839
+ // fetch follows redirects transparently, so all trust decisions below target the final
174840
+ // (post-redirect) URL reported by the response, not the URL we asked for.
174841
+ const challengedUrl = response.url || url;
174383
174842
  if (response.status === 401
174384
174843
  && (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])
174385
- && !this._includeUserCredentials
174844
+ && !includeCredentials
174386
174845
  && !hasCreds) {
174387
- // Removed the previous headers and make sure "include" credentials is set
174388
- opts.headers = undefined;
174389
- opts.credentials = "include";
174390
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
174391
- response = await fetch(url, opts);
174392
- if (response.status === 200) {
174393
- this._includeUserCredentials = true; // avoid going through 401 challenges over and over
174846
+ if (this.isSsoAllowed(challengedUrl)) {
174847
+ // Removed the previous headers and make sure "include" credentials is set
174848
+ opts.headers = undefined;
174849
+ opts.credentials = "include";
174850
+ // A Negotiate/NTLM handshake is normally a same-URL 401 round-trip, but in legacy mode we preserve
174851
+ // the previous behavior and allow the browser to follow redirects after the authenticated retry.
174852
+ opts.redirect = _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
174853
+ this.logUntrustedOriginUse(challengedUrl);
174854
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
174855
+ response = await fetch(challengedUrl, opts);
174856
+ if (response.status === 200) {
174857
+ this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
174858
+ }
174394
174859
  }
174860
+ else {
174861
+ this.reportBlockedOrigin(challengedUrl);
174862
+ }
174863
+ }
174864
+ else if ((response.status === 401 || response.status === 403) && hasSettingsCreds && !this.isCredentialsSharingAllowed(challengedUrl)) {
174865
+ // Some servers answer an unauthenticated request with 403 (Forbidden) rather than a 401 challenge;
174866
+ // since this request could not present its credentials to the challenging origin, either status most
174867
+ // likely results from that. The permission is recomputed for the challenged URL rather than reusing the
174868
+ // decision made for the requested one: `fetch` strips the Authorization header when it follows a
174869
+ // cross-origin redirect, so a trusted request can still arrive unauthenticated at an untrusted origin,
174870
+ // and conversely a request that started out untrusted may end up at an origin that is trusted.
174871
+ this.reportBlockedOrigin(challengedUrl);
174395
174872
  }
174396
174873
  return response;
174397
174874
  }
@@ -174423,16 +174900,28 @@ class MapLayerImageryProvider {
174423
174900
  }
174424
174901
  /** @internal */
174425
174902
  async toolTipFromUrl(strings, url) {
174426
- const headers = new Headers();
174427
- this.setRequestAuthorization(headers);
174903
+ let headers;
174904
+ if (this.isCredentialsSharingAllowed(url)) {
174905
+ headers = new Headers();
174906
+ this.setRequestAuthorization(headers);
174907
+ }
174428
174908
  try {
174909
+ const includeCredentials = this.includeUserCredentials(url);
174429
174910
  const response = await fetch(url, {
174430
174911
  method: "GET",
174431
174912
  headers,
174432
- credentials: this._includeUserCredentials ? "include" : undefined,
174913
+ credentials: includeCredentials ? "include" : undefined,
174914
+ redirect: includeCredentials ? this.credentialedRedirect : undefined,
174433
174915
  });
174434
- const text = await response.text();
174435
- if (undefined !== text) {
174916
+ if (includeCredentials)
174917
+ this.checkCredentialedRedirect(url, response);
174918
+ let text = await response.text();
174919
+ if (text) {
174920
+ // Tooltip content (e.g. WMS GetFeatureInfo responses) is rendered as HTML downstream and may
174921
+ // deliberately contain markup; text from origins not trusted for credentials is escaped.
174922
+ // fetch follows redirects transparently, so the text may come from a different origin than requested.
174923
+ if (!this.isCredentialsSharingAllowed(response.url || url))
174924
+ text = escapeHtml(text);
174436
174925
  strings.push(text);
174437
174926
  }
174438
174927
  }
@@ -174612,6 +175101,12 @@ var MapLayerSourceStatus;
174612
175101
  /** Format is not compatible with the URL provided.
174613
175102
  */
174614
175103
  MapLayerSourceStatus[MapLayerSourceStatus["IncompatibleFormat"] = 7] = "IncompatibleFormat";
175104
+ /** Authentication could not be attempted because the source's origin is not trusted
175105
+ * (see [MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]($frontend)). Add the origin to
175106
+ * [MapLayerFormatRegistry.trustedCredentialsOrigins]($frontend) rather than prompting for credentials.
175107
+ * @beta
175108
+ */
175109
+ MapLayerSourceStatus[MapLayerSourceStatus["UntrustedOrigin"] = 8] = "UntrustedOrigin";
174615
175110
  })(MapLayerSourceStatus || (MapLayerSourceStatus = {}));
174616
175111
  /** A source for map layers. These may be catalogued for convenient use by users or applications.
174617
175112
  * @public
@@ -174899,10 +175394,8 @@ class MapLayerTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_3__.T
174899
175394
  const tree = this.treeOwner.tileTree;
174900
175395
  if (undefined === tree || hit.iModel !== tree.iModel || tree.modelId !== hit.sourceId)
174901
175396
  return undefined;
174902
- const strings = [];
174903
- strings.push(`Map Layer: ${this._layerSettings.name}`);
174904
175397
  const div = document.createElement("div");
174905
- div.innerHTML = strings.join("<br>");
175398
+ div.textContent = `Map Layer: ${this._layerSettings.name}`;
174906
175399
  return div;
174907
175400
  }
174908
175401
  decorate(_context) {
@@ -176611,7 +177104,9 @@ class MapTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_7__.TileTr
176611
177104
  let carto;
176612
177105
  const strings = [];
176613
177106
  const getTooltipFunc = async (imageryTreeRef, quadId, cartoGraphic, imageryTree) => {
176614
- strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_4__.IModelApp.localization.getLocalizedString("iModelJs:MapLayers.ImageryLayer")}: ${imageryTreeRef.layerSettings.name}`);
177107
+ // innerHTML is used below because imageryLoader.getToolTip may deliberately supply markup.
177108
+ const layerName = (0,_internal__WEBPACK_IMPORTED_MODULE_7__.escapeHtml)(imageryTreeRef.layerSettings.name);
177109
+ strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_4__.IModelApp.localization.getLocalizedString("iModelJs:MapLayers.ImageryLayer")}: ${layerName}`);
176615
177110
  carto = cartoGraphic;
176616
177111
  await imageryTree.imageryLoader.getToolTip(strings, quadId, cartoGraphic, imageryTree);
176617
177112
  };
@@ -334493,7 +334988,7 @@ var loadLanguages = instance.loadLanguages;
334493
334988
  (module) {
334494
334989
 
334495
334990
  "use strict";
334496
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.13.0-dev.16","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s build:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run build:test-worker && vitest --run","cover":"npm run build:test-worker && vitest --run","build:test-worker":"vite build --config ./src/test/worker/vite.config.mts 1>&2","build:workers":"rimraf lib/workers/webpack && vite build --config ./src/workers/ImdlParser/vite.config.mts 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.11","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/node":"~20.17.0","@types/sinon":"^17.0.2","@vitest/browser-playwright":"^4.1.10","@vitest/coverage-v8":"^4.1.10","cpx2":"^8.0.0","eslint":"^9.31.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","typescript":"~5.6.2","vite":"^6.4.3","vitest":"^4.1.10","vite-plugin-static-copy":"2.2.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"~4.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
334991
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.13.0-dev.18","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s build:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run build:test-worker && vitest --run","cover":"npm run build:test-worker && vitest --run","build:test-worker":"vite build --config ./src/test/worker/vite.config.mts 1>&2","build:workers":"rimraf lib/workers/webpack && vite build --config ./src/workers/ImdlParser/vite.config.mts 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.11","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/node":"~20.17.0","@types/sinon":"^17.0.2","@vitest/browser-playwright":"^4.1.10","@vitest/coverage-v8":"^4.1.10","cpx2":"^8.0.0","eslint":"^9.31.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","typescript":"~5.6.2","vite":"^6.4.3","vitest":"^4.1.10","vite-plugin-static-copy":"2.2.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"~4.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
334497
334992
 
334498
334993
  /***/ }
334499
334994