@itwin/ecschema-rpcinterface-tests 5.13.0-dev.9 → 5.14.0-dev.1

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.
@@ -18201,31 +18201,6 @@ module.exports = {
18201
18201
  }));
18202
18202
 
18203
18203
 
18204
- /***/ },
18205
-
18206
- /***/ "../../common/temp/node_modules/.pnpm/wms-capabilities@0.4.0/node_modules/wms-capabilities/dist/wms-capabilities.min.js"
18207
- /*!******************************************************************************************************************************!*\
18208
- !*** ../../common/temp/node_modules/.pnpm/wms-capabilities@0.4.0/node_modules/wms-capabilities/dist/wms-capabilities.min.js ***!
18209
- \******************************************************************************************************************************/
18210
- (module) {
18211
-
18212
- "use strict";
18213
- (function(f,m){ true?module.exports=m():0})(this,function(){function f(a){return void 0!==a}function m(a,c,b){if(a.nodeType===u.CDATA_SECTION||a.nodeType===u.TEXT)c?b.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else for(a=a.firstChild;a;a=a.nextSibling)m(a,c,b);return b}function F(a){for(a=a.nextElementSibling||a.nextSibling;a&&
18214
- a.nodeType!==u.ELEMENT;)a=a.nextSibling;return a}function h(a,c,b){b=f(b)?b:{};var d;var n=0;for(d=a.length;n<d;++n)b[a[n]]=c;return b}function A(a,c){return function(b,d){b=a.call(f(c)?c:this,b,d);f(b)&&d[d.length-1].push(b)}}function l(a,c,b,d,e){d.push(a);for(a=b.firstElementChild||b.firstChild;a&&a.nodeType!==u.ELEMENT;)a=a.nextSibling;for(;a;a=F(a))b=c[a.namespaceURI||null],f(b)&&(b=b[a.localName],f(b)&&b.call(e,a,d));return d.pop()}function b(a,c,b){return function(d,e){var n=a.call(f(b)?b:
18215
- this,d,e);f(n)&&(e=e[e.length-1],d=f(c)?c:d.localName,e[d]=n)}}function k(a,c,b){return function(d,e){var n=a.call(f(b)?b:this,d,e);if(f(n)){e=e[e.length-1];d=f(c)?c:d.localName;var g=[];(d in e?e[d]:e[d]=g).push(n)}}}function r(a){if(a=/^\s*(true|1)|(false|0)\s*$/.exec(a))return f(a[1])||!1}function t(a){return p(m(a,!1,[]).join(""))}function p(a){if(a=/^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*$/i.exec(a))return parseFloat(a[1])}function w(a){return v(m(a,!1,[]).join(""))}function v(a){if(a=/^\s*(\d+)\s*$/.exec(a))return parseInt(a[1],
18216
- 10)}function e(a){return m(a,!1,[]).join("").replace(G,"")}function x(a){return a.getAttributeNS("http://www.w3.org/1999/xlink","href")}function B(a){return[p(a.getAttribute("minx")),p(a.getAttribute("miny")),p(a.getAttribute("maxx")),p(a.getAttribute("maxy"))]}function q(a,c){return l({},H,a,c)}function y(a,c){return l({},I,a,c)}function C(a,c){c=q(a,c);if(f(c))return a=[v(a.getAttribute("width")),v(a.getAttribute("height"))],c.size=a,c}function D(a,c){return l([],J,a,c)}var u={ELEMENT:1,ATTRIBUTE:2,
18217
- TEXT:3,CDATA_SECTION:4,ENTITY_REFERENCE:5,ENTITY:6,PROCESSING_INSTRUCTION:7,COMMENT:8,DOCUMENT:9,DOCUMENT_TYPE:10,DOCUMENT_FRAGMENT:11,NOTATION:12},z=function(a){this._parser=new a};z.prototype.toDocument=function(a){return this._parser.parseFromString(a,"application/xml")};z.prototype.getAllTextContent=function(a,c){return m(a,c,[]).join("").join("")};var G=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,g=[null,"http://www.opengis.net/wms"],M=h(g,{Service:b(function(a,c){return l({},K,a,c)}),Capability:b(function(a,
18218
- c){return l({},L,a,c)})}),L=h(g,{Request:b(function(a,c){return l({},N,a,c)}),Exception:b(function(a,c){return l([],O,a,c)}),Layer:b(function(a,c){var b=r(a.getAttribute("queryable"));return l({queryable:f(b)?b:!1},E,a,c)})}),K=h(g,{Name:b(e),Title:b(e),Abstract:b(e),KeywordList:b(D),OnlineResource:b(x),ContactInformation:b(function(a,c){return l({},P,a,c)}),Fees:b(e),AccessConstraints:b(e),LayerLimit:b(w),MaxWidth:b(w),MaxHeight:b(w)}),P=h(g,{ContactPersonPrimary:b(function(a,c){return l({},Q,a,
18219
- c)}),ContactPosition:b(e),ContactAddress:b(function(a,c){return l({},R,a,c)}),ContactVoiceTelephone:b(e),ContactFacsimileTelephone:b(e),ContactElectronicMailAddress:b(e)}),Q=h(g,{ContactPerson:b(e),ContactOrganization:b(e)}),R=h(g,{AddressType:b(e),Address:b(e),City:b(e),StateOrProvince:b(e),PostCode:b(e),Country:b(e)}),O=h(g,{Format:A(e)}),E=h(g,{Name:b(e),Title:b(e),Abstract:b(e),KeywordList:b(D),CRS:k(e),SRS:k(e),EX_GeographicBoundingBox:b(function(a,c){var b=l({},S,a,c);if(f(b)){a=b.westBoundLongitude;
18220
- c=b.southBoundLatitude;var d=b.eastBoundLongitude;b=b.northBoundLatitude;if(f(a)&&f(c)&&f(d)&&f(b))return[a,c,d,b]}}),LatLonBoundingBox:b(function(a,b){a=B(a);if(f(a[0])&&f(a[1])&&f(a[2])&&f(a[3]))return a}),BoundingBox:k(function(a,b){b=B(a);var c=[p(a.getAttribute("resx")),p(a.getAttribute("resy"))];return{crs:a.getAttribute("CRS")||a.getAttribute("SRS"),extent:b,res:c}}),Dimension:k(function(a,b){return{name:a.getAttribute("name"),units:a.getAttribute("units"),unitSymbol:a.getAttribute("unitSymbol"),
18221
- "default":a.getAttribute("default"),multipleValues:r(a.getAttribute("multipleValues")),nearestValue:r(a.getAttribute("nearestValue")),current:r(a.getAttribute("current")),values:e(a)}}),Attribution:b(function(a,b){return l({},T,a,b)}),AuthorityURL:k(function(a,b){b=q(a,b);if(f(b))return b.name=a.getAttribute("name"),b}),Identifier:k(e),MetadataURL:k(function(a,b){b=q(a,b);if(f(b))return b.type=a.getAttribute("type"),b}),DataURL:k(q),FeatureListURL:k(q),Style:k(function(a,b){return l({},U,a,b)}),MinScaleDenominator:b(t),
18222
- MaxScaleDenominator:b(t),ScaleHint:b(function(a,b){b=parseFloat(a.getAttribute("min"));a=parseFloat(a.getAttribute("max"));return{min:b,max:a}}),Layer:k(function(a,b){var c=b[b.length-1];b=l({},E,a,b);if(f(b)){var d=r(a.getAttribute("queryable"));f(d)||(d=c.queryable);b.queryable=f(d)?d:!1;d=v(a.getAttribute("cascaded"));f(d)||(d=c.cascaded);b.cascaded=d;d=r(a.getAttribute("opaque"));f(d)||(d=c.opaque);b.opaque=f(d)?d:!1;d=r(a.getAttribute("noSubsets"));f(d)||(d=c.noSubsets);b.noSubsets=f(d)?d:!1;
18223
- d=p(a.getAttribute("fixedWidth"));f(d)||(d=c.fixedWidth);b.fixedWidth=d;a=p(a.getAttribute("fixedHeight"));f(a)||(a=c.fixedHeight);b.fixedHeight=a;a=["Style","CRS","AuthorityURL"];d=0;for(var e=a.length;d<e;d++){var g=a[d],h=c[g];if(f(h)){var k=[];k=g in b?b[g]:b[g]=k;k=k.concat(h);b[g]=k}}a="EX_GeographicBoundingBox BoundingBox Dimension Attribution MinScaleDenominator MaxScaleDenominator".split(" ");d=0;for(e=a.length;d<e;d++)g=a[d],f(b[g])||(b[g]=c[g]);return b}})}),T=h(g,{Title:b(e),OnlineResource:b(x),
18224
- LogoURL:b(C)}),S=h(g,{westBoundLongitude:b(t),eastBoundLongitude:b(t),southBoundLatitude:b(t),northBoundLatitude:b(t)}),N=h(g,{GetCapabilities:b(y),GetMap:b(y),GetFeatureInfo:b(y)}),I=h(g,{Format:k(e),DCPType:k(function(a,b){return l({},V,a,b)})}),V=h(g,{HTTP:b(function(a,b){return l({},W,a,b)})}),W=h(g,{Get:b(q),Post:b(q)}),U=h(g,{Name:b(e),Title:b(e),Abstract:b(e),LegendURL:k(C),StyleSheetURL:b(q),StyleURL:b(q)}),H=h(g,{Format:b(e),OnlineResource:b(x)}),J=h(g,{Keyword:A(e)});g=function(a,b){b||
18225
- "undefined"===typeof window||(b=window.DOMParser);this.version=void 0;this._parser=new z(b);this._data=a};g.prototype.data=function(a){this._data=a;return this};g.prototype.toJSON=function(a){a=a||this._data;return this.parse(a)};g.prototype.parse=function(a){return this._readFromDocument(this._parser.toDocument(a))};g.prototype._readFromDocument=function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType==u.ELEMENT)return this.readFromNode(a);return null};g.prototype.readFromNode=function(a){this.version=
18226
- a.getAttribute("version");return l({version:this.version},M,a,[])||null};return g});
18227
-
18228
-
18229
18204
  /***/ },
18230
18205
 
18231
18206
  /***/ "../../core/bentley/lib/esm/AccessToken.js"
@@ -26290,6 +26265,12 @@ var BriefcaseIdValue;
26290
26265
  BriefcaseIdValue[BriefcaseIdValue["FirstValid"] = 2] = "FirstValid";
26291
26266
  /** All valid iModelHub issued BriefcaseIds will be equal or lower than this */
26292
26267
  BriefcaseIdValue[BriefcaseIdValue["LastValid"] = 16777205] = "LastValid";
26268
+ /**
26269
+ * Briefcase Id reserved for `Element` Ids allocated by SchemaSync reservations.
26270
+ * Never assigned to a real briefcase by iModelHub.
26271
+ * @internal
26272
+ */
26273
+ BriefcaseIdValue[BriefcaseIdValue["SchemaSyncElementReserved"] = 16777206] = "SchemaSyncElementReserved";
26293
26274
  /**
26294
26275
  * The briefcase has not been assigned a unique Id by iModelHub. Only briefcases that have been assigned a unique BriefcaseId may create changesets,
26295
26276
  * because BriefcaseId is used to create unique ElementIds for new elements.
@@ -26902,7 +26883,7 @@ class Code {
26902
26883
  equals(other) { return Code.equalCodes(this, other); }
26903
26884
  /** @internal */
26904
26885
  static equalCodes(c1, c2) {
26905
- return c1.spec === c2.spec && c1.scope === c2.scope && c1.value === c2.value;
26886
+ return c1.spec === c2.spec && c1.scope === c2.scope && (c1.value ?? "").toLowerCase() === (c2.value ?? "").toLowerCase();
26906
26887
  }
26907
26888
  /** Determine whether this Code is valid. */
26908
26889
  static isValid(c) { return _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.isValidId64(c.spec); }
@@ -28324,15 +28305,28 @@ class QueryBinder {
28324
28305
  * @param indexOrName Specify parameter index or its name used in ECSQL statement.
28325
28306
  * @param val @type OrderedId64Iterable value to bind to ECSQL statement.
28326
28307
  * @returns @type QueryBinder to allow fluent interface.
28308
+ * @throws an [[ITwinError]] with scope `"itwin-QueryBinder"` and key `"invalid-arguments"` if any entry is not a valid [Id64String]($bentley).
28327
28309
  */
28328
28310
  bindIdSet(indexOrName, val) {
28329
28311
  this.verify(indexOrName);
28330
28312
  const name = String(indexOrName);
28331
- _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.OrderedId64Iterable.uniqueIterator(val);
28313
+ const ids = [];
28314
+ // `string` is an Iterable<string>. In that case assume caller passed a single Id64String, matching CompressedId64Set.sortAndCompress.
28315
+ const iterable = typeof val === "string" ? [val] : val;
28316
+ for (const id of iterable) {
28317
+ if (!_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.isValidId64(id)) {
28318
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.ITwinError.throwError({
28319
+ message: `QueryBinder.bindIdSet: entry ${JSON.stringify(id)} for parameter "${name}" is not a valid Id64String`,
28320
+ iTwinErrorId: { scope: "itwin-QueryBinder", key: "invalid-arguments" },
28321
+ });
28322
+ }
28323
+ ids.push(id);
28324
+ }
28325
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.OrderedId64Iterable.sortArray(ids);
28332
28326
  Object.defineProperty(this._args, name, {
28333
28327
  enumerable: true, value: {
28334
28328
  type: QueryParamType.IdSet,
28335
- value: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.CompressedId64Set.sortAndCompress(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.OrderedId64Iterable.uniqueIterator(val)),
28329
+ value: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.CompressedId64Set.compressArray(ids),
28336
28330
  },
28337
28331
  });
28338
28332
  return this;
@@ -31399,7 +31393,7 @@ var ExternalSourceAttachmentRole;
31399
31393
  /** The attached [ExternalSource]($backend) models a part of the whole. */
31400
31394
  ExternalSourceAttachmentRole[ExternalSourceAttachmentRole["SpecifyPart"] = 1] = "SpecifyPart";
31401
31395
  })(ExternalSourceAttachmentRole || (ExternalSourceAttachmentRole = {}));
31402
- /** The *rank* for a Category
31396
+ /** The *rank* for a [Category]($backend), [SubCategory]($backend), or [DefinitionSet]($backend).
31403
31397
  * @public @preview
31404
31398
  * @extensions
31405
31399
  */
@@ -35397,6 +35391,7 @@ __webpack_require__.r(__webpack_exports__);
35397
35391
  /* harmony export */ CloudSqliteError: () => (/* binding */ CloudSqliteError),
35398
35392
  /* harmony export */ EditTxnError: () => (/* binding */ EditTxnError),
35399
35393
  /* harmony export */ ElementError: () => (/* binding */ ElementError),
35394
+ /* harmony export */ ElementReservationError: () => (/* binding */ ElementReservationError),
35400
35395
  /* harmony export */ ITwinSettingsError: () => (/* binding */ ITwinSettingsError),
35401
35396
  /* harmony export */ ServerBasedLocksError: () => (/* binding */ ServerBasedLocksError),
35402
35397
  /* harmony export */ SqliteError: () => (/* binding */ SqliteError),
@@ -35558,6 +35553,22 @@ var ElementError;
35558
35553
  }
35559
35554
  ElementError.isError = isError;
35560
35555
  })(ElementError || (ElementError = {}));
35556
+ /** @beta */
35557
+ var ElementReservationError;
35558
+ (function (ElementReservationError) {
35559
+ /** the ITwinError scope for `ElementReservationError`s. */
35560
+ ElementReservationError.scope = "itwin-ElementReservation";
35561
+ /** Instantiate and throw an ElementReservationError */
35562
+ function throwError(key, e) {
35563
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.ITwinError.throwError({ ...e, iTwinErrorId: { scope: ElementReservationError.scope, key } });
35564
+ }
35565
+ ElementReservationError.throwError = throwError;
35566
+ /** Determine whether an error object is an ElementReservationError */
35567
+ function isError(error, key) {
35568
+ return _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.ITwinError.isError(error, ElementReservationError.scope, key);
35569
+ }
35570
+ ElementReservationError.isError = isError;
35571
+ })(ElementReservationError || (ElementReservationError = {}));
35561
35572
 
35562
35573
 
35563
35574
  /***/ },
@@ -44856,6 +44867,7 @@ __webpack_require__.r(__webpack_exports__);
44856
44867
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
44857
44868
  /* harmony export */ ListMarkerEnumerator: () => (/* binding */ ListMarkerEnumerator),
44858
44869
  /* harmony export */ TextStyleSettings: () => (/* binding */ TextStyleSettings),
44870
+ /* harmony export */ targetPointShapes: () => (/* binding */ targetPointShapes),
44859
44871
  /* harmony export */ terminatorShapes: () => (/* binding */ terminatorShapes),
44860
44872
  /* harmony export */ textAnnotationFrameShapes: () => (/* binding */ textAnnotationFrameShapes)
44861
44873
  /* harmony export */ });
@@ -44894,6 +44906,11 @@ const textAnnotationFrameShapes = ["none", "line", "rectangle", "circle", "equil
44894
44906
  * @beta
44895
44907
  */
44896
44908
  const terminatorShapes = ["openArrow", "closedArrow", "closedArrowFilled", "circle", "circleFilled", "slash", "none"];
44909
+ /**
44910
+ * Predefined shapes that can be used to indicate the target point of a leader in a [[TextAnnotation]].
44911
+ * @beta
44912
+ */
44913
+ const targetPointShapes = ["cross", "plus", "circle", "square", "rectangle"];
44897
44914
  ;
44898
44915
  ;
44899
44916
  function deepFreeze(obj) {
@@ -45013,6 +45030,11 @@ class TextStyleSettings {
45013
45030
  terminatorShape: terminatorShapes[0],
45014
45031
  terminatorHeightFactor: 1.0,
45015
45032
  terminatorWidthFactor: 1.0,
45033
+ showLeaders: true,
45034
+ showTerminators: true,
45035
+ showTargetPoint: false,
45036
+ targetPointShape: targetPointShapes[0],
45037
+ targetPointOffsetFactor: 0,
45016
45038
  },
45017
45039
  tabInterval: 4,
45018
45040
  indentation: 0,
@@ -45063,6 +45085,11 @@ class TextStyleSettings {
45063
45085
  terminatorShape: props.leader?.terminatorShape ?? defaults.leader.terminatorShape,
45064
45086
  terminatorHeightFactor: props.leader?.terminatorHeightFactor ?? defaults.leader.terminatorHeightFactor,
45065
45087
  terminatorWidthFactor: props.leader?.terminatorWidthFactor ?? defaults.leader.terminatorWidthFactor,
45088
+ showLeaders: props.leader?.showLeaders ?? defaults.leader.showLeaders,
45089
+ showTerminators: props.leader?.showTerminators ?? defaults.leader.showTerminators,
45090
+ showTargetPoint: props.leader?.showTargetPoint ?? defaults.leader.showTargetPoint,
45091
+ targetPointShape: props.leader?.targetPointShape ?? defaults.leader.targetPointShape,
45092
+ targetPointOffsetFactor: props.leader?.targetPointOffsetFactor ?? defaults.leader.targetPointOffsetFactor,
45066
45093
  };
45067
45094
  this.leader = Object.freeze(leader);
45068
45095
  this.tabInterval = props.tabInterval ?? defaults.tabInterval;
@@ -45100,9 +45127,17 @@ class TextStyleSettings {
45100
45127
  * @returns true if the two leader styles are equal, false otherwise.
45101
45128
  */
45102
45129
  leaderEquals(other) {
45103
- return this.leader.color === other.color && this.leader.wantElbow === other.wantElbow
45104
- && this.leader.elbowLength === other.elbowLength && this.leader.terminatorShape === other.terminatorShape && this.leader.terminatorHeightFactor === other.terminatorHeightFactor
45105
- && this.leader.terminatorWidthFactor === other.terminatorWidthFactor;
45130
+ return this.leader.color === other.color
45131
+ && this.leader.wantElbow === other.wantElbow
45132
+ && this.leader.elbowLength === other.elbowLength
45133
+ && this.leader.terminatorShape === other.terminatorShape
45134
+ && this.leader.terminatorHeightFactor === other.terminatorHeightFactor
45135
+ && this.leader.terminatorWidthFactor === other.terminatorWidthFactor
45136
+ && this.leader.showLeaders === other.showLeaders
45137
+ && this.leader.showTerminators === other.showTerminators
45138
+ && this.leader.showTargetPoint === other.showTargetPoint
45139
+ && this.leader.targetPointShape === other.targetPointShape
45140
+ && this.leader.targetPointOffsetFactor === other.targetPointOffsetFactor;
45106
45141
  }
45107
45142
  frameEquals(other) {
45108
45143
  return this.frame?.shape === other.shape
@@ -45256,6 +45291,7 @@ __webpack_require__.r(__webpack_exports__);
45256
45291
  /* harmony export */ ElementGeometry: () => (/* reexport safe */ _geometry_ElementGeometry__WEBPACK_IMPORTED_MODULE_49__.ElementGeometry),
45257
45292
  /* harmony export */ ElementGeometryChange: () => (/* reexport safe */ _ModelGeometryChanges__WEBPACK_IMPORTED_MODULE_96__.ElementGeometryChange),
45258
45293
  /* harmony export */ ElementGeometryOpcode: () => (/* reexport safe */ _geometry_ElementGeometry__WEBPACK_IMPORTED_MODULE_49__.ElementGeometryOpcode),
45294
+ /* harmony export */ ElementReservationError: () => (/* reexport safe */ _ITwinCoreErrors__WEBPACK_IMPORTED_MODULE_73__.ElementReservationError),
45259
45295
  /* harmony export */ EmptyLocalization: () => (/* reexport safe */ _Localization__WEBPACK_IMPORTED_MODULE_83__.EmptyLocalization),
45260
45296
  /* harmony export */ EntityMetaData: () => (/* reexport safe */ _EntityProps__WEBPACK_IMPORTED_MODULE_34__.EntityMetaData),
45261
45297
  /* harmony export */ EntityReferenceSet: () => (/* reexport safe */ _EntityReference__WEBPACK_IMPORTED_MODULE_35__.EntityReferenceSet),
@@ -45576,6 +45612,7 @@ __webpack_require__.r(__webpack_exports__);
45576
45612
  /* harmony export */ resolveNavPropId: () => (/* reexport safe */ _ViewProps__WEBPACK_IMPORTED_MODULE_127__.resolveNavPropId),
45577
45613
  /* harmony export */ rpcOverIpcStrings: () => (/* reexport safe */ _ipc_IpcSession__WEBPACK_IMPORTED_MODULE_79__.rpcOverIpcStrings),
45578
45614
  /* harmony export */ serializeIpcError: () => (/* reexport safe */ _ipc_IpcErrors__WEBPACK_IMPORTED_MODULE_75__.serializeIpcError),
45615
+ /* harmony export */ targetPointShapes: () => (/* reexport safe */ _annotation_TextStyle__WEBPACK_IMPORTED_MODULE_7__.targetPointShapes),
45579
45616
  /* harmony export */ terminatorShapes: () => (/* reexport safe */ _annotation_TextStyle__WEBPACK_IMPORTED_MODULE_7__.terminatorShapes),
45580
45617
  /* harmony export */ textAnnotationFrameShapes: () => (/* reexport safe */ _annotation_TextStyle__WEBPACK_IMPORTED_MODULE_7__.textAnnotationFrameShapes),
45581
45618
  /* harmony export */ tileFormatFromNumber: () => (/* reexport safe */ _tile_TileIO__WEBPACK_IMPORTED_MODULE_162__.tileFormatFromNumber),
@@ -79303,7 +79340,7 @@ class ECSchemaRpcLocater {
79303
79340
  * @param _matchType How to match key against candidate schemas
79304
79341
  * @param _context The SchemaContext that will control the lifetime of the schema and holds the schema's references, if they exist.
79305
79342
  * @throws Error Always throws an error indicating this method is not supported.
79306
- * @deprecated in 5.0 - will not be removed until after 2026-08-08. Use the asynchronous `getSchema` method for schema retrieval.
79343
+ * @deprecated in 5.0 - might be removed in next major version. Use the asynchronous `getSchema` method for schema retrieval.
79307
79344
  */
79308
79345
  getSchemaSync(_schemaKey, _matchType, _context) {
79309
79346
  throw new Error("getSchemaSync is not supported. Use the asynchronous getSchema method instead.");
@@ -85414,10 +85451,19 @@ class BriefcaseTxns extends BriefcaseNotificationHandler {
85414
85451
  return _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ipcAppChannels.txns;
85415
85452
  }
85416
85453
  /** Event raised after Txn validation or changeset application to indicate the set of changed elements.
85454
+ * Each [[TxnEntityChange]] exposes its class through `metadata.classFullName`. Use [[TxnEntityChanges.filter]] with `metadata.is` to match a class or one of its subclasses.
85455
+ * @example
85456
+ * ```ts
85457
+ * iModel.txns.onElementsChanged.addListener((changes) => {
85458
+ * for (const change of changes.filter({ includeMetadata: (metadata) => metadata.is("BisCore:GeometricElement") }))
85459
+ * updateElement(change.id);
85460
+ * });
85461
+ * ```
85417
85462
  * @note If there are many changed elements in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
85418
85463
  */
85419
85464
  onElementsChanged = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
85420
85465
  /** Event raised after Txn validation or changeset application to indicate the set of changed models.
85466
+ * Each [[TxnEntityChange]] exposes its class through `metadata.classFullName`. Use [[TxnEntityChanges.filter]] with `metadata.is` to match a class or one of its subclasses.
85421
85467
  * @note If there are many changed models in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
85422
85468
  */
85423
85469
  onModelsChanged = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
@@ -88437,11 +88483,11 @@ class EmphasizeElements {
88437
88483
  * @see [[Viewport.addFeatureOverrideProvider]]
88438
88484
  */
88439
88485
  addFeatureOverrides(overrides, vp) {
88486
+ // Apply regardless of whether there are any emphasized/overridden elements for independent de-emphasis...
88487
+ if (undefined !== this._defaultAppearance)
88488
+ overrides.setDefaultOverrides(this._defaultAppearance);
88440
88489
  const emphasizedElements = this.getEmphasizedElements(vp);
88441
88490
  if (undefined !== emphasizedElements) {
88442
- if (this._defaultAppearance !== undefined) {
88443
- overrides.setDefaultOverrides(this._defaultAppearance);
88444
- }
88445
88491
  const appearance = this.wantEmphasis ? this._emphasizedAppearance : _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureAppearance.defaults;
88446
88492
  // Avoid creating a new object per-element inside the loop
88447
88493
  const args = { elementId: "", appearance };
@@ -88457,8 +88503,6 @@ class EmphasizeElements {
88457
88503
  }
88458
88504
  const overriddenElements = this.getOverriddenElements();
88459
88505
  if (undefined !== overriddenElements) {
88460
- if (undefined !== this._defaultAppearance)
88461
- overrides.setDefaultOverrides(this._defaultAppearance);
88462
88506
  // Avoid creating a new object per-element inside the loop
88463
88507
  const args = { elementId: "", appearance: _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureAppearance.defaults };
88464
88508
  for (const [key, ids] of overriddenElements) {
@@ -88525,7 +88569,10 @@ class EmphasizeElements {
88525
88569
  return { overrideType, color };
88526
88570
  }
88527
88571
  /** Establish a default appearance to apply to elements without overrides. If changing the default appearance
88528
- * without also calling overrideElements, an explicit refresh must be requested for the change to take effect.
88572
+ * without also calling emphasizeElements/overrideElements, an explicit refresh must be requested for the change to take effect.
88573
+ * @note Setting this to `undefined` to undo [[emphasizeElements]] or [[isolateElements]] leaves the always-drawn/isolated
88574
+ * element IDs in place but invisible to [[getEmphasizedElements]], [[getEmphasizedIsolatedElements]], and [[clearEmphasizedElements]].
88575
+ * Prefer [[clearEmphasizedElements]] or [[clearEmphasizedIsolatedElements]] to undo emphasis, which clear both together.
88529
88576
  * @see [[Viewport.setFeatureOverrideProviderChanged]]
88530
88577
  */
88531
88578
  get defaultAppearance() { return this._defaultAppearance; }
@@ -88884,7 +88931,9 @@ class EmphasizeElements {
88884
88931
  return true;
88885
88932
  }
88886
88933
  /** @return true if provider is currently overriding the display of any elements. */
88887
- isActive(vp) { return (undefined !== this.getNeverDrawnElements(vp) || undefined !== this.getAlwaysDrawnElements(vp) || undefined !== this.getOverriddenElements()); }
88934
+ isActive(vp) {
88935
+ return undefined !== this._defaultAppearance || undefined !== this.getNeverDrawnElements(vp) || undefined !== this.getAlwaysDrawnElements(vp) || undefined !== this.getOverriddenElements();
88936
+ }
88888
88937
  /** Serialize to JSON representation.
88889
88938
  * @see [[EmphasizeElements.fromJSON]]
88890
88939
  */
@@ -88930,8 +88979,12 @@ class EmphasizeElements {
88930
88979
  changed = true;
88931
88980
  if (undefined !== props.alwaysDrawnExclusiveEmphasized)
88932
88981
  this._emphasizeIsolated = new Set(props.alwaysDrawnExclusiveEmphasized); // changed status determined by setAlwaysDrawnElements...
88933
- if (undefined !== props.defaultAppearance)
88934
- this.defaultAppearance = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureAppearance.fromJSON(props.defaultAppearance); // changed status determined by setAlwaysDrawnElements or overrideElements...
88982
+ if (undefined !== props.defaultAppearance) {
88983
+ const defaultAppearance = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureAppearance.fromJSON(props.defaultAppearance);
88984
+ if (undefined === this._defaultAppearance || !this._defaultAppearance.equals(defaultAppearance))
88985
+ changed = true;
88986
+ this.defaultAppearance = defaultAppearance;
88987
+ }
88935
88988
  if (props.unanimatedAppearance)
88936
88989
  this.unanimatedAppearance = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureAppearance.fromJSON(props.unanimatedAppearance);
88937
88990
  if (undefined !== props.appearanceOverride) {
@@ -91407,6 +91460,8 @@ const COPYRIGHT_NOTICE = `Copyright © 2017-${new Date().getFullYear()} <a href=
91407
91460
 
91408
91461
 
91409
91462
 
91463
+ /** CSS class name applied to the notice element of a logo card created by [[IModelApp.makeLogoCard]]. */
91464
+ const logoCardNoticeClassName = "logo-cards";
91410
91465
  /**
91411
91466
  * Global singleton that connects the user interface with the iTwin.js services. There can be only one IModelApp active in a session. All
91412
91467
  * members of IModelApp are static, and it serves as a singleton object for gaining access to session information.
@@ -91919,10 +91974,21 @@ class IModelApp {
91919
91974
  }
91920
91975
  if (undefined !== opts.notice) {
91921
91976
  if (typeof opts.notice === "string")
91922
- IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: "logo-cards" });
91977
+ IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: logoCardNoticeClassName });
91923
91978
  else
91924
91979
  noticeCell.appendChild(opts.notice);
91925
91980
  }
91981
+ else if (undefined !== opts.noticeLines) {
91982
+ // A <p> cannot legally contain flow content, so use a <div> when a line is an element.
91983
+ const containerTag = opts.noticeLines.some((line) => typeof line !== "string") ? "div" : "p";
91984
+ const notice = IModelApp.makeHTMLElement(containerTag, { parent: noticeCell, className: logoCardNoticeClassName });
91985
+ opts.noticeLines.forEach((line, index) => {
91986
+ if (index > 0)
91987
+ notice.appendChild(IModelApp.makeHTMLElement("br"));
91988
+ // Strings are appended as text nodes so they are never parsed as HTML.
91989
+ notice.append(line);
91990
+ });
91991
+ }
91926
91992
  return card;
91927
91993
  }
91928
91994
  /** Make the logo card for the library itself. This card gets placed at the top of the stack.
@@ -93489,7 +93555,9 @@ let iModelJsCss = `
93489
93555
 
93490
93556
  .logo-cards {
93491
93557
  position:relative;
93492
- width:100%
93558
+ width:100%;
93559
+ margin-block-start:1em;
93560
+ margin-block-end:1em
93493
93561
  }
93494
93562
 
93495
93563
  .imodeljs-modal-overlay {
@@ -93533,7 +93601,7 @@ let iModelJsCss = `
93533
93601
  max-width: calc(100% - (2 * var(--width-border))) !important;
93534
93602
  width: unset !important;
93535
93603
  }
93536
- .imodeljs-about .logo-card-message p {
93604
+ .imodeljs-about .logo-card-message p, .imodeljs-about .logo-card-message .logo-cards {
93537
93605
  margin-block-end: 1em;
93538
93606
  }
93539
93607
  .imodeljs-about .logo-cards {
@@ -96179,9 +96247,12 @@ class Google3dTilesProvider {
96179
96247
  // Order by most occurances to least
96180
96248
  // See https://developers.google.com/maps/documentation/tile/create-renderer#display-attributions
96181
96249
  const sortedCopyrights = [...copyrightMap.entries()].sort((a, b) => b[1] - a[1]);
96182
- let copyrightMsg = "Data provided by:<br><ul>";
96183
- copyrightMsg += sortedCopyrights.map(([key]) => `<li>${key}</li>`).join("");
96184
- copyrightMsg += "</ul>";
96250
+ const list = document.createElement("ul");
96251
+ for (const [key] of sortedCopyrights) {
96252
+ const item = document.createElement("li");
96253
+ item.textContent = key;
96254
+ list.appendChild(item);
96255
+ }
96185
96256
  const iconSrc = document.createElement("img");
96186
96257
  iconSrc.src = `${_IModelApp__WEBPACK_IMPORTED_MODULE_8__.IModelApp.publicPath}images/GoogleMaps_Logo_Gray.svg`;
96187
96258
  iconSrc.style.padding = "10px 10px 5px 10px";
@@ -96189,7 +96260,7 @@ class Google3dTilesProvider {
96189
96260
  iconSrc,
96190
96261
  iconWidth: 98,
96191
96262
  heading: "Google Photorealistic 3D Tiles",
96192
- notice: copyrightMsg
96263
+ noticeLines: ["Data provided by:", list],
96193
96264
  }));
96194
96265
  }
96195
96266
  }
@@ -100475,6 +100546,7 @@ class ViewManager {
100475
100546
  cursor = "default";
100476
100547
  _viewports = [];
100477
100548
  decorators = [];
100549
+ _selectedViewportChange = Promise.resolve();
100478
100550
  _selectedView;
100479
100551
  _invalidateScenes = false;
100480
100552
  _skipSceneCreation = false;
@@ -100602,9 +100674,16 @@ class ViewManager {
100602
100674
  }
100603
100675
  /** @internal */
100604
100676
  notifySelectedViewportChanged(previous, current) {
100605
- _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.toolAdmin.onSelectedViewportChanged(previous, current); // eslint-disable-line @typescript-eslint/no-floating-promises
100677
+ const selectedViewportChange = _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.toolAdmin.onSelectedViewportChanged(previous, current)
100678
+ .catch(() => undefined);
100679
+ this._selectedViewportChange = this._selectedViewportChange.then(async () => selectedViewportChange, async () => selectedViewportChange)
100680
+ .then(() => undefined, () => undefined);
100606
100681
  this.onSelectedViewportChanged.emit({ previous, current });
100607
100682
  }
100683
+ /** @internal */
100684
+ async waitForSelectedViewportChange() {
100685
+ await this._selectedViewportChange;
100686
+ }
100608
100687
  /** The "selected view" is the default for certain operations. */
100609
100688
  get selectedView() { return this._selectedView; }
100610
100689
  /** Get the first opened view. */
@@ -104125,11 +104204,13 @@ class Viewport {
104125
104204
  dropModelAppearanceOverride(id) {
104126
104205
  this.view.displayStyle.settings.dropModelAppearanceOverride(id);
104127
104206
  }
104128
- /** Some changes may or may not require us to invalidate the scene.
104207
+ /** Some changes do not alter the set of graphics being displayed (the "scene") but may alter the visibility of objects within those graphics.
104208
+ * Under certain circumstances, we may want to recreate the scene after such changes.
104129
104209
  * Specifically, when shadows are enabled or we are displaying view attachments, the following changes may affect the visibility or transparency of elements or features:
104130
104210
  * - Viewed categories and subcategories;
104131
104211
  * - Always/never drawn elements
104132
104212
  * - Symbology overrides.
104213
+ * Cached decorations will also be invalidated in case they depend on object visibility.
104133
104214
  */
104134
104215
  maybeInvalidateScene() {
104135
104216
  // When shadows are being displayed and the set of displayed categories changes, we must invalidate the scene so that shadows will be regenerated.
@@ -104138,7 +104219,10 @@ class Viewport {
104138
104219
  return;
104139
104220
  if (this.view.displayStyle.wantShadows || this.view.isSheetView())
104140
104221
  this.invalidateScene();
104222
+ this.onSceneVisibilityChanged();
104141
104223
  }
104224
+ /** @internal Invoked by [[maybeInvalidateScene]] when the visibility of objects in the scene may have changed, but the scene itself has not changed. */
104225
+ onSceneVisibilityChanged() { }
104142
104226
  /** Enable or disable display of elements belonging to a set of categories specified by Id.
104143
104227
  * Visibility of individual subcategories belonging to a category can be controlled separately through the use of [[SubCategoryOverride]]s.
104144
104228
  * By default, enabling display of a category does not affect display of subcategories thereof which have been overridden to be invisible.
@@ -106177,6 +106261,13 @@ class ScreenViewport extends Viewport {
106177
106261
  // When the scene is invalidated, so are all cached decorations - they will be regenerated.
106178
106262
  this._decorationCache.clear();
106179
106263
  }
106264
+ /** @internal */
106265
+ onSceneVisibilityChanged() {
106266
+ super.onSceneVisibilityChanged();
106267
+ // Cached decorations may be associated with objects in the scene whose visibility has changed. Give them the opportunity to react.
106268
+ this._decorationCache.clear();
106269
+ this.invalidateDecorations();
106270
+ }
106180
106271
  /** Forces removal of a specific decorator's cached decorations from this viewport, if they exist.
106181
106272
  * This will force those decorations to be regenerated.
106182
106273
  * @see [[ViewportDecorator.useCachedDecorations]].
@@ -116559,7 +116650,7 @@ class GoogleMapsDecorator {
116559
116650
  const copyrightText = sortedCopyrights.map(([key]) => ` • ${key}`).join("");
116560
116651
  // Create and add element, offset to leave space for i.js and Google logos
116561
116652
  const elem = document.createElement("div");
116562
- elem.innerHTML = copyrightText;
116653
+ elem.textContent = copyrightText;
116563
116654
  elem.style.color = "white";
116564
116655
  elem.style.fontSize = "11px";
116565
116656
  elem.style.textWrap = "wrap";
@@ -153406,6 +153497,7 @@ __webpack_require__.r(__webpack_exports__);
153406
153497
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
153407
153498
  /* harmony export */ OrbitGtTileTree: () => (/* binding */ OrbitGtTileTree),
153408
153499
  /* harmony export */ OrbitGtTreeReference: () => (/* binding */ OrbitGtTreeReference),
153500
+ /* harmony export */ computeOrthometricVerticalShift: () => (/* binding */ computeOrthometricVerticalShift),
153409
153501
  /* harmony export */ createOrbitGtTileTreeReference: () => (/* binding */ createOrbitGtTileTreeReference)
153410
153502
  /* harmony export */ });
153411
153503
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
@@ -153413,11 +153505,12 @@ __webpack_require__.r(__webpack_exports__);
153413
153505
  /* harmony import */ var _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @itwin/core-geometry */ "../../core/geometry/lib/esm/core-geometry.js");
153414
153506
  /* harmony import */ var _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @itwin/core-orbitgt */ "../../core/orbitgt/lib/esm/core-orbitgt.js");
153415
153507
  /* harmony import */ var _BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../BackgroundMapGeometry */ "../../core/frontend/lib/esm/BackgroundMapGeometry.js");
153416
- /* harmony import */ var _DisplayStyleState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../DisplayStyleState */ "../../core/frontend/lib/esm/DisplayStyleState.js");
153417
- /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
153418
- /* harmony import */ var _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../RealityDataSource */ "../../core/frontend/lib/esm/RealityDataSource.js");
153419
- /* 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");
153420
- /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
153508
+ /* harmony import */ var _common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../common/FrontendLoggerCategory */ "../../core/frontend/lib/esm/common/FrontendLoggerCategory.js");
153509
+ /* harmony import */ var _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../DisplayStyleState */ "../../core/frontend/lib/esm/DisplayStyleState.js");
153510
+ /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
153511
+ /* harmony import */ var _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../RealityDataSource */ "../../core/frontend/lib/esm/RealityDataSource.js");
153512
+ /* 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");
153513
+ /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
153421
153514
  /*---------------------------------------------------------------------------------------------
153422
153515
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
153423
153516
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -153435,6 +153528,7 @@ __webpack_require__.r(__webpack_exports__);
153435
153528
 
153436
153529
 
153437
153530
 
153531
+
153438
153532
  const scratchRange = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.create();
153439
153533
  const scratchWorldFrustum = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Frustum();
153440
153534
  function compareSourceKeys(lhs, rhs) {
@@ -153498,7 +153592,7 @@ class OrbitGtTileTreeParams {
153498
153592
  id;
153499
153593
  modelId;
153500
153594
  iModel;
153501
- get priority() { return _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileLoadPriority.Context; }
153595
+ get priority() { return _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileLoadPriority.Context; }
153502
153596
  constructor(rdSourceKey, iModel, modelId, location) {
153503
153597
  this.location = location;
153504
153598
  const key = rdSourceKey;
@@ -153507,10 +153601,10 @@ class OrbitGtTileTreeParams {
153507
153601
  this.iModel = iModel;
153508
153602
  }
153509
153603
  }
153510
- class OrbitGtRootTile extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.Tile {
153604
+ class OrbitGtRootTile extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.Tile {
153511
153605
  _loadChildren(_resolve, _reject) { }
153512
153606
  async requestContent(_isCanceled) { return undefined; }
153513
- get channel() { return _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.channels.getForHttp("itwinjs-orbitgit"); }
153607
+ get channel() { return _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.channels.getForHttp("itwinjs-orbitgit"); }
153514
153608
  async readContent(_data, _system, _isCanceled) { return {}; }
153515
153609
  freeMemory() { }
153516
153610
  constructor(params, tree) { super(params, tree); }
@@ -153580,7 +153674,7 @@ class TileSortProjector {
153580
153674
  coordinate.z = point.z;
153581
153675
  }
153582
153676
  }
153583
- class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileUsageMarker {
153677
+ class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileUsageMarker {
153584
153678
  graphic;
153585
153679
  constructor(graphic, viewport, time) {
153586
153680
  super();
@@ -153591,7 +153685,7 @@ class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.Til
153591
153685
  this.graphic[Symbol.dispose]();
153592
153686
  }
153593
153687
  }
153594
- class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTree {
153688
+ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileTree {
153595
153689
  _dataManager;
153596
153690
  _centerOffset;
153597
153691
  _ecefTransform;
@@ -153607,7 +153701,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153607
153701
  this._dataManager = _dataManager;
153608
153702
  this._centerOffset = _centerOffset;
153609
153703
  this._ecefTransform = _ecefTransform;
153610
- this._layerHandler = new _tile_internal__WEBPACK_IMPORTED_MODULE_9__.LayerTileTreeHandler(this);
153704
+ this._layerHandler = new _tile_internal__WEBPACK_IMPORTED_MODULE_10__.LayerTileTreeHandler(this);
153611
153705
  this._tileParams = { contentId: "0", range: cloudRange, maximumSize: 256 };
153612
153706
  this.rootTile = new OrbitGtRootTile(this._tileParams, this);
153613
153707
  }
@@ -153656,7 +153750,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153656
153750
  let totalPointCount = 0;
153657
153751
  const tileCount = frameData.tilesToRender.size();
153658
153752
  // Inform TileAdmin about tiles we are handling ourselves...
153659
- _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.addExternalTilesForUser(args.context.viewport, { requested: frameData.tilesToLoad.size() + (frameData.hasMissingData() ? 1 : 0), selected: tileCount, ready: tileCount });
153753
+ _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.addExternalTilesForUser(args.context.viewport, { requested: frameData.tilesToLoad.size() + (frameData.hasMissingData() ? 1 : 0), selected: tileCount, ready: tileCount });
153660
153754
  if (debugBuilder)
153661
153755
  debugBuilder.setSymbology(_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, 1);
153662
153756
  let minLevel = 100, maxLevel = -100;
@@ -153677,8 +153771,8 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153677
153771
  range.high.addInPlace(this._centerOffset);
153678
153772
  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);
153679
153773
  const featureTable = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureTable(1, this.modelId, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.BatchType.Primary);
153680
- const features = new _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_8__.Mesh.Features(featureTable);
153681
- const system = _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.renderSystem;
153774
+ const features = new _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_9__.Mesh.Features(featureTable);
153775
+ const system = _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.renderSystem;
153682
153776
  const voxelSize = (range.high.x - range.low.x) / 64;
153683
153777
  features.add(new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Feature(this.modelId), 1);
153684
153778
  const tilePoints = (tile.points8 != null) ? tile.points8.toNativeBuffer() : tile.points16.toNativeBuffer();
@@ -153705,8 +153799,34 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153705
153799
  }
153706
153800
  args.drawGraphics();
153707
153801
  if (frameData.hasMissingData()) {
153708
- this._dataManager.loadData(frameData).then(() => _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.onTileLoad.raiseEvent(this.rootTile)).catch((_err) => undefined);
153802
+ this._dataManager.loadData(frameData).then(() => _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.onTileLoad.raiseEvent(this.rootTile)).catch((_err) => undefined);
153803
+ }
153804
+ }
153805
+ }
153806
+ /** Computes the vertical shift, in meters along geodetic up, to correctly place a point cloud whose CRS does not
153807
+ * define a vertical datum, assuming its heights are orthometric (relative to the geoid).
153808
+ *
153809
+ * The shift is the difference between converting the point cloud's origin with its height treated as orthometric
153810
+ * versus ellipsoidal (`heightAsEllipsoidalDbZ`, already computed by the caller). Returns zero if the shift cannot
153811
+ * be computed or the iModel's converter makes no distinction between the two.
153812
+ * Exported strictly for tests.
153813
+ * @internal
153814
+ */
153815
+ async function computeOrthometricVerticalShift(geoOrigin, heightAsEllipsoidalDbZ, iModel) {
153816
+ const geoidConverter = iModel.noGcsDefined ? undefined : iModel.geoServices.getConverter({ horizontalCRS: { epsg: 4326 }, verticalCRS: { id: "GEOID" } });
153817
+ if (undefined === geoidConverter)
153818
+ return 0;
153819
+ try {
153820
+ const response = await geoidConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
153821
+ if (response.iModelCoords[0].s !== _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
153822
+ _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`);
153823
+ return 0;
153709
153824
  }
153825
+ return _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p).z - heightAsEllipsoidalDbZ;
153826
+ }
153827
+ catch (err) {
153828
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__.FrontendLoggerCategory.RealityData, err);
153829
+ return 0;
153710
153830
  }
153711
153831
  }
153712
153832
  (function (OrbitGtTileTree) {
@@ -153732,7 +153852,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153732
153852
  return isValidSASToken(props.sasToken);
153733
153853
  }
153734
153854
  async function createOrbitGtTileTree(rdSourceKey, iModel, modelId) {
153735
- const rdSource = await _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.fromKey(rdSourceKey, iModel.iTwinId);
153855
+ const rdSource = await _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.fromKey(rdSourceKey, iModel.iTwinId);
153736
153856
  const isContextShare = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.ContextShare;
153737
153857
  const isTilestUrl = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.TilesetUrl;
153738
153858
  let blobStringUrl;
@@ -153743,7 +153863,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153743
153863
  const docRootName = realityData.rootDocument;
153744
153864
  if (!docRootName)
153745
153865
  return undefined;
153746
- const token = await _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.getAccessToken();
153866
+ const token = await _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.getAccessToken();
153747
153867
  const blobUrl = await realityData.getBlobUrl(token, docRootName);
153748
153868
  blobStringUrl = blobUrl.toString();
153749
153869
  }
@@ -153751,7 +153871,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153751
153871
  blobStringUrl = rdSourceKey.id;
153752
153872
  }
153753
153873
  else {
153754
- const orbitGtBlobProps = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createOrbitGtBlobPropsFromKey(rdSourceKey);
153874
+ const orbitGtBlobProps = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createOrbitGtBlobPropsFromKey(rdSourceKey);
153755
153875
  if (orbitGtBlobProps === undefined)
153756
153876
  return undefined;
153757
153877
  if (!isValidOrbitGtBlobProps(orbitGtBlobProps))
@@ -153786,7 +153906,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153786
153906
  const wgs84CRS = "4978";
153787
153907
  await _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.prepareForArea(wgs84CRS, new _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.OrbitGtBounds());
153788
153908
  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));
153789
- const pointCloudCenterToEcef = pointCloudToEcef.multiplyTransformTransform(addCloudCenter);
153909
+ let pointCloudCenterToEcef = pointCloudToEcef.multiplyTransformTransform(addCloudCenter);
153790
153910
  ecefTransform.setFrom(pointCloudCenterToEcef);
153791
153911
  let ecefToDb = iModel.getMapEcefToDb(0);
153792
153912
  // In initial publishing version the iModel ecef Transform was used to locate the reality model.
@@ -153806,7 +153926,21 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153806
153926
  const geoOrigin = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(cartographicOrigin.longitudeDegrees, cartographicOrigin.latitudeDegrees, cartographicOrigin.height);
153807
153927
  const response = await geoConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
153808
153928
  if (response.iModelCoords[0].s === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
153809
- const ecefToDbOrigin = await (0,_BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__.calculateEcefToDbTransformAtLocation)(_itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p), iModel);
153929
+ const dbOriginFromGcs = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p);
153930
+ // A projected CRS defines no vertical datum, so the point cloud's heights are conventionally orthometric -
153931
+ // but pointCloudToEcef above treated them as ellipsoidal. Correct the placement by the difference.
153932
+ // (A compound CRS also takes this path; that stays correct unless orbitgt gains a geoid model.)
153933
+ if (_itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.isProjectedCRS(pointCloudCRS)) {
153934
+ const verticalShift = await computeOrthometricVerticalShift(geoOrigin, dbOriginFromGcs.z, iModel);
153935
+ if (0 !== verticalShift) {
153936
+ 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();
153937
+ if (undefined !== upVector) {
153938
+ pointCloudCenterToEcef = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Transform.createTranslation(upVector.scale(verticalShift)).multiplyTransformTransform(pointCloudCenterToEcef);
153939
+ ecefTransform.setFrom(pointCloudCenterToEcef);
153940
+ }
153941
+ }
153942
+ }
153943
+ const ecefToDbOrigin = await (0,_BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__.calculateEcefToDbTransformAtLocation)(dbOriginFromGcs, iModel);
153810
153944
  if (ecefToDbOrigin)
153811
153945
  ecefToDb = ecefToDbOrigin;
153812
153946
  }
@@ -153826,7 +153960,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
153826
153960
  /** Supplies a reality data [[TileTree]] from a URL. May be associated with a persistent [[GeometricModelState]], or attached at run-time via a [[ContextOrbitGtState]].
153827
153961
  * Exported strictly for tests.
153828
153962
  */
153829
- class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.RealityModelTileTree.Reference {
153963
+ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.RealityModelTileTree.Reference {
153830
153964
  treeOwner;
153831
153965
  _rdSourceKey;
153832
153966
  _modelId;
@@ -153839,15 +153973,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
153839
153973
  this._rdSourceKey = props.rdSourceKey;
153840
153974
  }
153841
153975
  else if (props.orbitGtBlob) {
153842
- this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createKeyFromOrbitGtBlobProps(props.orbitGtBlob);
153976
+ this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createKeyFromOrbitGtBlobProps(props.orbitGtBlob);
153843
153977
  }
153844
153978
  else {
153845
153979
  // TODO: Maybe we should throw an exception
153846
- 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);
153980
+ 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);
153847
153981
  }
153848
153982
  // ###TODO find compatible model Id
153849
153983
  let modelId = props.modelId;
153850
- if (undefined === modelId && this._source instanceof _DisplayStyleState__WEBPACK_IMPORTED_MODULE_5__.DisplayStyleState)
153984
+ if (undefined === modelId && this._source instanceof _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__.DisplayStyleState)
153851
153985
  modelId = orbitGtTreeSupplier.findCompatibleContextRealityModelId(this._rdSourceKey, this._source);
153852
153986
  this._modelId = modelId ?? props.iModel.transientIds.getNext();
153853
153987
  const ogtTreeId = { rdSourceKey: this._rdSourceKey, modelId: this.modelId };
@@ -153862,11 +153996,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
153862
153996
  if (undefined === tree || hit.iModel !== tree.iModel)
153863
153997
  return undefined;
153864
153998
  const strings = [];
153865
- strings.push(_IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.localization.getLocalizedString("iModelJs:RealityModelTypes.OrbitGTPointCloud"));
153999
+ strings.push(_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:RealityModelTypes.OrbitGTPointCloud"));
153866
154000
  if (this._name)
153867
- strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.localization.getLocalizedString("iModelJs:TooltipInfo.Name")} ${this._name}`);
154001
+ strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:TooltipInfo.Name")} ${this._name}`);
153868
154002
  const div = document.createElement("div");
153869
- div.innerHTML = strings.join("<br>");
154003
+ strings.forEach((str, index) => {
154004
+ if (index > 0)
154005
+ div.appendChild(document.createElement("br"));
154006
+ div.appendChild(document.createTextNode(str));
154007
+ });
153870
154008
  return div;
153871
154009
  }
153872
154010
  }
@@ -155630,7 +155768,11 @@ class RealityTreeReference extends RealityModelTileTree.Reference {
155630
155768
  if (-1 === key.indexOf("#")) // Avoid internal cesium
155631
155769
  strings.push(`${key}: ${JSON.stringify(batch[key])}`);
155632
155770
  const div = document.createElement("div");
155633
- div.innerHTML = strings.join("<br>");
155771
+ strings.forEach((str, index) => {
155772
+ if (index > 0)
155773
+ div.appendChild(document.createElement("br"));
155774
+ div.appendChild(document.createTextNode(str));
155775
+ });
155634
155776
  return div;
155635
155777
  }
155636
155778
  /** @deprecated in 5.0 - might be removed in next major version. Use [addAttributions] instead. */
@@ -156818,7 +156960,21 @@ class ArcGisUtilities {
156818
156960
  */
156819
156961
  static async validateSource(args) {
156820
156962
  const { source, ignoreCache, capabilitiesFilter } = args;
156821
- const metadata = await this.getServiceJson({ url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache });
156963
+ let metadata;
156964
+ try {
156965
+ metadata = await this.getServiceJson({ url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache });
156966
+ }
156967
+ catch (err) {
156968
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError) {
156969
+ let blockedOrigin;
156970
+ try {
156971
+ blockedOrigin = new URL(err.url).origin;
156972
+ }
156973
+ catch { /* non-hierarchical URL */ }
156974
+ return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
156975
+ }
156976
+ throw err;
156977
+ }
156822
156978
  const json = metadata?.content;
156823
156979
  if (json === undefined) {
156824
156980
  return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.InvalidUrl };
@@ -156881,6 +157037,9 @@ class ArcGisUtilities {
156881
157037
  * @param password Password to use for legacy token based security
156882
157038
  * @param ignoreCache Flag to skip cache lookup (i.e. force a new server request)
156883
157039
  * @param requireToken Flag to indicate if a token is required
157040
+ * @throws [[MapLayerUntrustedOriginError]] if an NTLM/Negotiate challenge could not be answered because
157041
+ * the URL's origin is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]);
157042
+ * all other errors are caught and reported by returning `undefined`.
156884
157043
  */
156885
157044
  static async getServiceJson(args) {
156886
157045
  const { url, formatId, userName, password, queryParams, ignoreCache, requireToken } = args;
@@ -156916,8 +157075,17 @@ class ArcGisUtilities {
156916
157075
  }
156917
157076
  let response = await fetch(tmpUrl, { method: "GET" });
156918
157077
  if (response.status === 401 && !requireToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
156919
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
156920
- response = await fetch(tmpUrl, { method: "GET", credentials: "include" });
157078
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
157079
+ const challengedUrl = response.url || tmpUrl.toString();
157080
+ if (!_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
157081
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError(challengedUrl);
157082
+ _IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
157083
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
157084
+ response = await fetch(challengedUrl, {
157085
+ method: "GET",
157086
+ credentials: "include",
157087
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
157088
+ });
156921
157089
  }
156922
157090
  // Append security token when corresponding error code is returned by ArcGIS service
156923
157091
  let errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);
@@ -156939,8 +157107,10 @@ class ArcGisUtilities {
156939
157107
  ArcGisUtilities._serviceCache.set(url, (errorCode === undefined ? info : undefined));
156940
157108
  return info; // Always return json, even though it contains an error code.
156941
157109
  }
156942
- catch {
157110
+ catch (err) {
156943
157111
  ArcGisUtilities._serviceCache.set(url, undefined);
157112
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError)
157113
+ throw err; // propagate so callers can report the blocked origin
156944
157114
  return undefined;
156945
157115
  }
156946
157116
  }
@@ -157102,7 +157272,9 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
157102
157272
  try {
157103
157273
  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() });
157104
157274
  }
157105
- catch {
157275
+ catch (err) {
157276
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError)
157277
+ this.reportBlockedOrigin(err.url);
157106
157278
  }
157107
157279
  if (metadata && metadata.accessTokenRequired) {
157108
157280
  const accessClient = _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.getAccessClient(this._settings.formatId);
@@ -157150,12 +157322,32 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
157150
157322
  await this._firstRequestPromise;
157151
157323
  let response;
157152
157324
  try {
157153
- response = await fetch(urlObj, { ...options, credentials: this._includeUserCredentials ? "include" : undefined });
157325
+ const requestUrl = urlObj.toString();
157326
+ const includeCredentials = this.includeUserCredentials(requestUrl);
157327
+ response = await fetch(urlObj, {
157328
+ ...options,
157329
+ credentials: includeCredentials ? "include" : undefined,
157330
+ redirect: includeCredentials ? this.credentialedRedirect : options?.redirect,
157331
+ });
157332
+ if (includeCredentials)
157333
+ this.checkCredentialedRedirect(requestUrl, response);
157154
157334
  if (response.status === 401 && !this._lastAccessToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
157155
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
157156
- response = await fetch(urlObj, { ...options, credentials: "include" });
157157
- if (response.status === 200) {
157158
- this._includeUserCredentials = true; // avoid going through 401 challenges over and over
157335
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
157336
+ const challengedUrl = response.url || requestUrl;
157337
+ if (this.isSsoAllowed(challengedUrl)) {
157338
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
157339
+ this.logUntrustedOriginUse(challengedUrl);
157340
+ response = await fetch(challengedUrl, {
157341
+ ...options,
157342
+ credentials: "include",
157343
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
157344
+ });
157345
+ if (response.status === 200) {
157346
+ this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
157347
+ }
157348
+ }
157349
+ else {
157350
+ this.reportBlockedOrigin(challengedUrl);
157159
157351
  }
157160
157352
  }
157161
157353
  if ((this._lastAccessToken && response.status === 400)
@@ -157368,8 +157560,12 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
157368
157560
  }
157369
157561
  async initialize() {
157370
157562
  const metadata = await this.getServiceJson();
157371
- if (metadata?.content === undefined)
157563
+ if (metadata?.content === undefined) {
157564
+ // By returning (i.e., not throwing), we ensure the tile tree gets created and the current provider is preserved to report status.
157565
+ if (this.status === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.UntrustedOrigin)
157566
+ return;
157372
157567
  throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_0__.ServerError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_5__.IModelStatus.ValidationFailed, "");
157568
+ }
157373
157569
  const json = metadata.content;
157374
157570
  if (json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.TokenRequired
157375
157571
  || json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.InvalidToken
@@ -157454,7 +157650,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
157454
157650
  addLogoCards(cards) {
157455
157651
  if (!cards.dataset.arcGisLogoCard) {
157456
157652
  cards.dataset.arcGisLogoCard = "true";
157457
- cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS", notice: this._copyrightText }));
157653
+ cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS", noticeLines: [this._copyrightText] }));
157458
157654
  }
157459
157655
  }
157460
157656
  async addAttributions(cards, _vp) {
@@ -157495,7 +157691,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
157495
157691
  if (json && Array.isArray(json.results)) {
157496
157692
  for (const result of json.results) {
157497
157693
  if (result.attributes !== undefined && result.attributes[result.displayFieldName] !== undefined) {
157498
- const thisString = `${result.displayFieldName}: ${result.attributes[result.displayFieldName]}`;
157694
+ 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]))}`;
157499
157695
  if (!stringSet.has(thisString)) {
157500
157696
  strings.push(thisString);
157501
157697
  stringSet.add(thisString);
@@ -157811,13 +158007,7 @@ class BingMapsImageryLayerProvider extends _tile_internal__WEBPACK_IMPORTED_MODU
157811
158007
  const copyrights = [];
157812
158008
  for (const match of matchingAttributions)
157813
158009
  copyrights.push(match.copyrightMessage);
157814
- let copyrightMsg = "";
157815
- for (let i = 0; i < copyrights.length; ++i) {
157816
- if (i > 0)
157817
- copyrightMsg += "<br>";
157818
- copyrightMsg += copyrights[i];
157819
- }
157820
- 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 }));
158010
+ 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 }));
157821
158011
  }
157822
158012
  async addAttributions(cards, vp) {
157823
158013
  // eslint-disable-next-line @typescript-eslint/no-deprecated
@@ -158426,7 +158616,10 @@ class WmsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE
158426
158616
  // Don't throw error if unauthorized status:
158427
158617
  // We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
158428
158618
  // When credentials will be provided, a new provider will be created, and initialization should be fine.
158429
- if (error?.status === 401) {
158619
+ if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError) {
158620
+ this.reportBlockedOrigin(error.url);
158621
+ }
158622
+ else if (error?.status === 401) {
158430
158623
  this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerImageryProviderStatus.RequireAuth);
158431
158624
  }
158432
158625
  else {
@@ -158588,7 +158781,8 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
158588
158781
  }
158589
158782
  async initialize() {
158590
158783
  try {
158591
- this._capabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_2__.WmtsCapabilities.create(this._baseUrl);
158784
+ const credentials = (this._settings.userName && this._settings.password ? { user: this._settings.userName, password: this._settings.password } : undefined);
158785
+ this._capabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_2__.WmtsCapabilities.create(this._baseUrl, credentials);
158592
158786
  this.initPreferredTileMatrixSet();
158593
158787
  this.initPreferredStyle();
158594
158788
  this.initDisplayedLayer();
@@ -158601,7 +158795,10 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
158601
158795
  // Don't throw error if unauthorized status:
158602
158796
  // We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
158603
158797
  // When credentials will be provided, a new provider will be created, and initialization should be fine.
158604
- if (error?.status === 401) {
158798
+ if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerUntrustedOriginError) {
158799
+ this.reportBlockedOrigin(error.url);
158800
+ }
158801
+ else if (error?.status === 401) {
158605
158802
  this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.RequireAuth);
158606
158803
  }
158607
158804
  else {
@@ -159176,8 +159373,7 @@ __webpack_require__.r(__webpack_exports__);
159176
159373
  /* harmony export */ WmsCapabilities: () => (/* binding */ WmsCapabilities),
159177
159374
  /* harmony export */ WmsCapability: () => (/* binding */ WmsCapability)
159178
159375
  /* harmony export */ });
159179
- /* harmony import */ var wms_capabilities__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! wms-capabilities */ "../../common/temp/node_modules/.pnpm/wms-capabilities@0.4.0/node_modules/wms-capabilities/dist/wms-capabilities.min.js");
159180
- /* harmony import */ var wms_capabilities__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(wms_capabilities__WEBPACK_IMPORTED_MODULE_0__);
159376
+ /* harmony import */ var wms_capabilities__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! wms-capabilities */ "../../common/temp/node_modules/.pnpm/wms-capabilities@0.6.0/node_modules/wms-capabilities/dist/wms-capabilities.mjs");
159181
159377
  /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
159182
159378
  /*---------------------------------------------------------------------------------------------
159183
159379
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
@@ -159329,7 +159525,7 @@ var WmsCapability;
159329
159525
  this.title = _json.Title;
159330
159526
  this.queryable = _json.queryable ? true : false;
159331
159527
  this.cartoRange = rangeFromJSON(_json);
159332
- this.ownCrs = capabilities.isVersion13 ? _json.CRS : _json.SRS;
159528
+ this.ownCrs = initArray(capabilities.isVersion13 ? _json.CRS : _json.SRS) ?? [];
159333
159529
  const crs = new Set(this.ownCrs);
159334
159530
  if (parent) {
159335
159531
  getParentCrs(parent, crs);
@@ -159359,12 +159555,32 @@ class WmsCapabilities {
159359
159555
  get featureInfoFormats() { return Array.isArray(this._json.Capability?.Request?.GetFeatureInfo?.Format) ? this._json.Capability?.Request?.GetFeatureInfo?.Format : undefined; }
159360
159556
  constructor(_json) {
159361
159557
  this._json = _json;
159362
- this.version = _json.version;
159363
- this.isVersion13 = _json.version !== undefined && 0 === _json.version.indexOf("1.3");
159364
- this.service = new WmsCapability.Service(_json.Service);
159365
- if (_json.Capability)
159558
+ if (!_json || typeof _json !== "object" || (_json.Service === undefined && _json.Capability === undefined))
159559
+ throw new Error("Invalid WMS GetCapabilities response");
159560
+ this.version = typeof _json.version === "string" ? _json.version : undefined;
159561
+ this.isVersion13 = this.version !== undefined && this.version.startsWith("1.3");
159562
+ this.service = new WmsCapability.Service(_json.Service ?? {});
159563
+ if (_json.Capability?.Layer)
159366
159564
  this.layer = new WmsCapability.Layer(_json.Capability.Layer, this);
159367
159565
  }
159566
+ /** Parse a GetCapabilities XML response, returning undefined if it is not a valid WMS capabilities document. */
159567
+ static tryParse(xmlCapabilities) {
159568
+ // Validate the document is actually rooted at a WMS capabilities element before parsing:
159569
+ // wms-capabilities happily parses any root and recognizes direct Service/Capability children.
159570
+ // WMS 1.3.0 uses WMS_Capabilities; WMS 1.0.0-1.1.1 uses WMT_MS_Capabilities.
159571
+ const doc = new DOMParser().parseFromString(xmlCapabilities, "text/xml");
159572
+ const rootName = doc.documentElement?.localName;
159573
+ if (rootName !== "WMS_Capabilities" && rootName !== "WMT_MS_Capabilities")
159574
+ return undefined; // Not a WMS GetCapabilities document
159575
+ if (doc.getElementsByTagName("parsererror").length > 0)
159576
+ return undefined; // XML parse error (browsers embed a parsererror element)
159577
+ try {
159578
+ return new WmsCapabilities(new wms_capabilities__WEBPACK_IMPORTED_MODULE_0__["default"](undefined, DOMParser).parse(xmlCapabilities));
159579
+ }
159580
+ catch {
159581
+ return undefined; // Degenerate capabilities document
159582
+ }
159583
+ }
159368
159584
  static async create(url, credentials, ignoreCache, queryParams) {
159369
159585
  if (!ignoreCache) {
159370
159586
  const cached = WmsCapabilities._capabilitiesCache.get(url);
@@ -159383,7 +159599,9 @@ class WmsCapabilities {
159383
159599
  const xmlCapabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_1__.WmsUtilities.fetchXml(tmpUrl.toString(), credentials);
159384
159600
  if (!xmlCapabilities)
159385
159601
  return undefined;
159386
- const capabilities = new WmsCapabilities(new (wms_capabilities__WEBPACK_IMPORTED_MODULE_0___default())().parse(xmlCapabilities));
159602
+ const capabilities = WmsCapabilities.tryParse(xmlCapabilities);
159603
+ if (capabilities === undefined)
159604
+ return undefined;
159387
159605
  if (!credentials) {
159388
159606
  // Avoid caching protected data
159389
159607
  WmsCapabilities._capabilitiesCache.set(url, capabilities);
@@ -159412,14 +159630,18 @@ __webpack_require__.r(__webpack_exports__);
159412
159630
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
159413
159631
  /* harmony export */ WmsUtilities: () => (/* binding */ WmsUtilities)
159414
159632
  /* harmony export */ });
159415
- /* harmony import */ var _request_Request__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../request/Request */ "../../core/frontend/lib/esm/request/Request.js");
159416
- /* harmony import */ var _request_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../request/utils */ "../../core/frontend/lib/esm/request/utils.js");
159633
+ /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
159634
+ /* harmony import */ var _request_Request__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../request/Request */ "../../core/frontend/lib/esm/request/Request.js");
159635
+ /* harmony import */ var _request_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../request/utils */ "../../core/frontend/lib/esm/request/utils.js");
159636
+ /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
159417
159637
  /*---------------------------------------------------------------------------------------------
159418
159638
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
159419
159639
  * See LICENSE.md in the project root for license terms and full copyright notice.
159420
159640
  *--------------------------------------------------------------------------------------------*/
159421
159641
 
159422
159642
 
159643
+
159644
+
159423
159645
  /** @packageDocumentation
159424
159646
  * @module Tiles
159425
159647
  */
@@ -159436,16 +159658,35 @@ class WmsUtilities {
159436
159658
  static async fetchXml(url, credentials) {
159437
159659
  let headers;
159438
159660
  if (credentials && credentials.user && credentials.password) {
159439
- headers = new Headers();
159440
- (0,_request_utils__WEBPACK_IMPORTED_MODULE_1__.setBasicAuthorization)(headers, credentials);
159661
+ // Basic credentials are considered settings-derived credentials for this source. When the registry is
159662
+ // enforcing trusted origins, the source URL itself is the only implicitly trusted origin for basic auth;
159663
+ // opaque/custom-protocol URLs have no network origin and must therefore be treated as untrusted.
159664
+ const allowBasicAuth = !_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins
159665
+ || _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, url);
159666
+ if (allowBasicAuth) {
159667
+ headers = new Headers();
159668
+ (0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.setBasicAuthorization)(headers, credentials);
159669
+ }
159441
159670
  }
159442
159671
  let response = await fetch(url, { method: "GET", headers });
159443
- if (!credentials && response.status === 401 && (0,_request_utils__WEBPACK_IMPORTED_MODULE_1__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
159444
- // We got a http 401 challenge, lets try SSO (i.e. Windows Authentication)
159445
- response = await fetch(url, { method: "GET", credentials: "include" });
159672
+ if (!headers && credentials && credentials.user && credentials.password && (response.status === 401 || response.status === 403)) {
159673
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(url);
159674
+ }
159675
+ if (!credentials && response.status === 401 && (0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
159676
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
159677
+ const challengedUrl = response.url || url;
159678
+ if (!_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
159679
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(challengedUrl);
159680
+ _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
159681
+ // We got a http 401 challenge, lets try SSO (i.e. Windows Authentication).
159682
+ response = await fetch(challengedUrl, {
159683
+ method: "GET",
159684
+ credentials: "include",
159685
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
159686
+ });
159446
159687
  }
159447
159688
  if (response.status !== 200)
159448
- throw new _request_Request__WEBPACK_IMPORTED_MODULE_0__.HttpResponseError(response.status, await response.text());
159689
+ throw new _request_Request__WEBPACK_IMPORTED_MODULE_1__.HttpResponseError(response.status, await response.text());
159449
159690
  return response.text();
159450
159691
  }
159451
159692
  }
@@ -161121,13 +161362,17 @@ class QuantityFormatter {
161121
161362
  }
161122
161363
  /** Rebuild all system entries for a single KoQ name in the registry. */
161123
161364
  async _rebuildRegistryForName(name, unitMap) {
161124
- let anySystemHadFormat = false;
161125
161365
  for (const system of QuantityFormatter._allUnitSystems) {
161126
161366
  const formatProps = await _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.formatsProvider.getFormat(name, system);
161127
161367
  if (formatProps) {
161128
- anySystemHadFormat = true;
161129
- for (const [persistenceUnitName] of unitMap.entries()) {
161130
- await this.addFormattingSpecsToRegistry({ name, persistenceUnitName, formatProps, system });
161368
+ for (const [persistenceUnitName, systemMap] of unitMap.entries()) {
161369
+ try {
161370
+ await this.addFormattingSpecsToRegistry({ name, persistenceUnitName, formatProps, system });
161371
+ }
161372
+ catch (err) {
161373
+ systemMap.delete(system);
161374
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(`${_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_2__.FrontendLoggerCategory.Package}.QuantityFormatter`, `Unable to rebuild format ${name} for persistence unit ${persistenceUnitName} and system ${system}: ${_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BentleyError.getErrorMessage(err)}`);
161375
+ }
161131
161376
  }
161132
161377
  }
161133
161378
  else {
@@ -161137,9 +161382,13 @@ class QuantityFormatter {
161137
161382
  }
161138
161383
  }
161139
161384
  }
161140
- if (!anySystemHadFormat) {
161141
- this._formatSpecsRegistry.delete(name);
161385
+ // Remove persistence units that no longer have a valid entry in any system.
161386
+ for (const [persistenceUnitName, systemMap] of unitMap.entries()) {
161387
+ if (systemMap.size === 0)
161388
+ unitMap.delete(persistenceUnitName);
161142
161389
  }
161390
+ if (unitMap.size === 0)
161391
+ this._formatSpecsRegistry.delete(name);
161143
161392
  }
161144
161393
  /** Return a map that serves as a registry of all standard and custom quantity types. */
161145
161394
  get quantityTypesRegistry() {
@@ -171851,6 +172100,7 @@ __webpack_require__.r(__webpack_exports__);
171851
172100
  /* harmony export */ MapLayerSourceStatus: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSourceStatus),
171852
172101
  /* harmony export */ MapLayerSources: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSources),
171853
172102
  /* harmony export */ MapLayerTileTreeReference: () => (/* reexport safe */ _map_MapLayerTileTreeReference__WEBPACK_IMPORTED_MODULE_64__.MapLayerTileTreeReference),
172103
+ /* harmony export */ MapLayerUntrustedOriginError: () => (/* reexport safe */ _map_MapLayerFormatRegistry__WEBPACK_IMPORTED_MODULE_42__.MapLayerUntrustedOriginError),
171854
172104
  /* harmony export */ MapTile: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTile),
171855
172105
  /* harmony export */ MapTileLoader: () => (/* reexport safe */ _internal_tile_map_MapTileLoader__WEBPACK_IMPORTED_MODULE_72__.MapTileLoader),
171856
172106
  /* harmony export */ MapTileProjection: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTileProjection),
@@ -171930,6 +172180,7 @@ __webpack_require__.r(__webpack_exports__);
171930
172180
  /* harmony export */ collectMaskRefs: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.collectMaskRefs),
171931
172181
  /* harmony export */ compareMapLayer: () => (/* reexport safe */ _internal_render_webgl_MapLayerParams__WEBPACK_IMPORTED_MODULE_94__.compareMapLayer),
171932
172182
  /* harmony export */ computeCesiumTokenTimeoutInterval: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.computeCesiumTokenTimeoutInterval),
172183
+ /* harmony export */ computeOrthometricVerticalShift: () => (/* reexport safe */ _internal_tile_OrbitGtTileTree__WEBPACK_IMPORTED_MODULE_84__.computeOrthometricVerticalShift),
171933
172184
  /* harmony export */ createClassifierTileTreeReference: () => (/* reexport safe */ _internal_tile_ClassifierTileTree__WEBPACK_IMPORTED_MODULE_83__.createClassifierTileTreeReference),
171934
172185
  /* harmony export */ createDefaultViewFlagOverrides: () => (/* reexport safe */ _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__.createDefaultViewFlagOverrides),
171935
172186
  /* harmony export */ createGraphicFromDescription: () => (/* reexport safe */ _internal_tile_ImdlGraphicsCreator__WEBPACK_IMPORTED_MODULE_37__.createGraphicFromDescription),
@@ -171946,6 +172197,7 @@ __webpack_require__.r(__webpack_exports__);
171946
172197
  /* harmony export */ decodeMeshoptBuffer: () => (/* reexport safe */ _internal_tile_MeshoptCompression__WEBPACK_IMPORTED_MODULE_93__.decodeMeshoptBuffer),
171947
172198
  /* harmony export */ deflateCoordinates: () => (/* reexport safe */ _internal_tile_map_ImageryProviders_CoordinatesUtils__WEBPACK_IMPORTED_MODULE_47__.deflateCoordinates),
171948
172199
  /* harmony export */ disposeTileTreesForGeometricModels: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.disposeTileTreesForGeometricModels),
172200
+ /* harmony export */ escapeHtml: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.escapeHtml),
171949
172201
  /* harmony export */ getCesiumAccessClient: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessClient),
171950
172202
  /* harmony export */ getCesiumAccessTokenAndEndpointUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessTokenAndEndpointUrl),
171951
172203
  /* harmony export */ getCesiumAssetUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAssetUrl),
@@ -171965,7 +172217,8 @@ __webpack_require__.r(__webpack_exports__);
171965
172217
  /* harmony export */ readImdlContent: () => (/* reexport safe */ _ImdlReader__WEBPACK_IMPORTED_MODULE_35__.readImdlContent),
171966
172218
  /* harmony export */ readPntsColors: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPntsColors),
171967
172219
  /* harmony export */ readPointCloudTileContent: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPointCloudTileContent),
171968
- /* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic)
172220
+ /* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic),
172221
+ /* harmony export */ tryGetOrigin: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.tryGetOrigin)
171969
172222
  /* harmony export */ });
171970
172223
  /* harmony import */ var _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal/tile/ViewFlagOverrides */ "../../core/frontend/lib/esm/internal/tile/ViewFlagOverrides.js");
171971
172224
  /* harmony import */ var _map_MapCartoRectangle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map/MapCartoRectangle */ "../../core/frontend/lib/esm/tile/map/MapCartoRectangle.js");
@@ -173664,7 +173917,8 @@ __webpack_require__.r(__webpack_exports__);
173664
173917
  __webpack_require__.r(__webpack_exports__);
173665
173918
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
173666
173919
  /* harmony export */ MapLayerFormat: () => (/* binding */ MapLayerFormat),
173667
- /* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry)
173920
+ /* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry),
173921
+ /* harmony export */ MapLayerUntrustedOriginError: () => (/* binding */ MapLayerUntrustedOriginError)
173668
173922
  /* harmony export */ });
173669
173923
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
173670
173924
  /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
@@ -173679,7 +173933,7 @@ __webpack_require__.r(__webpack_exports__);
173679
173933
 
173680
173934
 
173681
173935
 
173682
- const loggerCategory = "ArcGISFeatureProvider";
173936
+ const loggerCategory = "MapLayerFormatRegistry";
173683
173937
  /**
173684
173938
  * Class representing a map-layer format.
173685
173939
  * Each format has it's unique 'formatId' string, used to uniquely identify a format in the [[MapLayerFormatRegistry]].
@@ -173728,16 +173982,127 @@ class MapLayerFormat {
173728
173982
  return undefined;
173729
173983
  }
173730
173984
  }
173985
+ /** Error thrown when an NTLM or Negotiate http 401 challenge could not be answered because the request
173986
+ * URL's origin is not listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]]
173987
+ * (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
173988
+ * Thrown by the static map-layer utilities (e.g. capabilities / service-metadata fetches) that have no
173989
+ * provider instance on which to report the blocked origin; callers convert it to
173990
+ * [[MapLayerImageryProviderStatus.UntrustedOrigin]] (provider initialization) or
173991
+ * [[MapLayerSourceStatus.UntrustedOrigin]] (source validation).
173992
+ * @internal
173993
+ */
173994
+ class MapLayerUntrustedOriginError extends Error {
173995
+ /** The URL of the request whose authentication challenge was left unanswered. */
173996
+ url;
173997
+ constructor(url) {
173998
+ super(`Authentication blocked: origin of '${url}' is not listed in MapLayerFormatRegistry.trustedCredentialsOrigins`);
173999
+ this.url = url;
174000
+ }
174001
+ }
173731
174002
  /**
173732
174003
  * A registry of MapLayerFormats identified by their unique format IDs. The registry can be accessed via [[IModelApp.mapLayerFormatRegistry]].
173733
174004
  * @public
173734
174005
  */
173735
174006
  class MapLayerFormatRegistry {
173736
174007
  _configOptions;
174008
+ _trustedCredentialsOrigins = [];
174009
+ /** Opt-in enforcement of origin restrictions on map-layer credentials.
174010
+ * When enabled, map layer providers:
174011
+ * - attach the basic-auth credentials stored in the layer settings only to requests targeting the origin
174012
+ * of the layer's settings URL or an origin listed in [[trustedCredentialsOrigins]];
174013
+ * - retry a request with browser credentials included (i.e. SSO / Windows Authentication) after an NTLM
174014
+ * or Negotiate http 401 challenge only for origins explicitly listed in [[trustedCredentialsOrigins]]
174015
+ * (the settings-URL origin is NOT implicitly trusted for SSO, since map-layer URLs may originate from
174016
+ * untrusted user input while SSO shares the user's ambient identity).
174017
+ * Default is false, preserving the legacy behavior of sending credentials to any request URL.
174018
+ * @beta
174019
+ */
174020
+ restrictCredentialsToTrustedOrigins = false;
173737
174021
  constructor(opts) {
173738
174022
  this._configOptions = opts ?? {};
173739
174023
  _internal__WEBPACK_IMPORTED_MODULE_2__.internalMapLayerImageryFormats.forEach((format) => this.register(format));
173740
174024
  }
174025
+ /** Origins (e.g. "https://tiles.example.com") to which map layer providers may send credentials —
174026
+ * both the basic-auth credentials stored in the layer settings and browser credentials for
174027
+ * SSO (i.e. Windows Authentication) retries after an NTLM or Negotiate http 401 challenge.
174028
+ * Only enforced when [[restrictCredentialsToTrustedOrigins]] is enabled.
174029
+ * For basic-auth, the origin of each map layer's settings URL is always implicitly trusted; for SSO,
174030
+ * origins must be explicitly listed here.
174031
+ * Entries are normalized to their origin (scheme + host + port); only `http:` and `https:` URLs are accepted,
174032
+ * and any other entry is ignored and logged. Opaque schemes such as `file:`, `data:`, `about:` and custom
174033
+ * Electron protocols are rejected because they all share the same serialized origin, so trusting one would
174034
+ * trust every other.
174035
+ * @beta
174036
+ */
174037
+ get trustedCredentialsOrigins() {
174038
+ return this._trustedCredentialsOrigins;
174039
+ }
174040
+ set trustedCredentialsOrigins(origins) {
174041
+ const normalized = [];
174042
+ for (const entry of origins) {
174043
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(entry);
174044
+ if (origin !== undefined)
174045
+ normalized.push(origin);
174046
+ else
174047
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `trustedCredentialsOrigins: ignoring '${entry}'; entries must be http or https URLs.`);
174048
+ }
174049
+ this._trustedCredentialsOrigins = normalized;
174050
+ }
174051
+ /** Returns true if a request to the given URL may be retried with browser credentials included
174052
+ * (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
174053
+ * Always true unless [[restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
174054
+ * When enabled, the URL's origin must be explicitly listed in [[trustedCredentialsOrigins]];
174055
+ * unlike basic-auth, the settings-URL origin is NOT implicitly trusted because SSO shares the user's
174056
+ * ambient identity, and map-layer URLs may originate from untrusted user input.
174057
+ * @internal
174058
+ */
174059
+ isSsoAllowed(url) {
174060
+ if (!this.restrictCredentialsToTrustedOrigins)
174061
+ return true;
174062
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
174063
+ // Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
174064
+ return origin !== undefined && this._trustedCredentialsOrigins.includes(origin);
174065
+ }
174066
+ /** Returns true if the basic-auth credentials belonging to a map-layer source or settings URL may be
174067
+ * attached to a request to the given URL. Always true unless [[restrictCredentialsToTrustedOrigins]]
174068
+ * is enabled (opt-in). When enabled, the origin of `settingsUrl` is implicitly trusted (the credentials
174069
+ * belong to that server); any other origin must be listed in [[trustedCredentialsOrigins]].
174070
+ * @internal
174071
+ */
174072
+ isCredentialsSharingAllowed(url, settingsUrl) {
174073
+ if (!this.restrictCredentialsToTrustedOrigins)
174074
+ return true;
174075
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
174076
+ if (origin === undefined)
174077
+ return false;
174078
+ if (origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
174079
+ return true;
174080
+ // Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
174081
+ return this._trustedCredentialsOrigins.includes(origin);
174082
+ }
174083
+ /** Origins for which a "credentials sent to untrusted origin" warning was already logged;
174084
+ * used to log the discovery warning only once per origin.
174085
+ */
174086
+ _untrustedUseLogged = new Set();
174087
+ /** Logs a warning (once per origin) when credentials are sent to an origin that would be blocked
174088
+ * if [[restrictCredentialsToTrustedOrigins]] were enabled.
174089
+ * Helps applications discover the origins they need to whitelist before opting in to the restriction.
174090
+ * If `settingsUrl` is supplied, requests sharing its origin are not logged, since that origin is
174091
+ * implicitly trusted for basic-auth.
174092
+ * @internal
174093
+ */
174094
+ logUntrustedOriginUse(url, settingsUrl) {
174095
+ if (this.restrictCredentialsToTrustedOrigins)
174096
+ return; // restriction active; nothing to preview
174097
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url) ?? url;
174098
+ if (settingsUrl !== undefined && origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
174099
+ return; // implicitly trusted for basic-auth
174100
+ if (this._untrustedUseLogged.has(origin) || this._trustedCredentialsOrigins.includes(origin))
174101
+ return;
174102
+ this._untrustedUseLogged.add(origin);
174103
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `Credentials sent to origin '${origin}' which is not in MapLayerFormatRegistry.trustedCredentialsOrigins; `
174104
+ + "this request would be blocked if restrictCredentialsToTrustedOrigins were enabled.");
174105
+ }
173741
174106
  _formats = new Map();
173742
174107
  isRegistered(formatId) { return this._formats.get(formatId) !== undefined; }
173743
174108
  register(formatClass) {
@@ -173903,6 +174268,14 @@ class WmsMapLayerFormat extends ImageryMapLayerFormat {
173903
174268
  return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
173904
174269
  }
173905
174270
  catch (err) {
174271
+ if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
174272
+ let blockedOrigin;
174273
+ try {
174274
+ blockedOrigin = new URL(err.url).origin;
174275
+ }
174276
+ catch { /* non-hierarchical URL */ }
174277
+ return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
174278
+ }
173906
174279
  let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
173907
174280
  if (err?.status === 401) {
173908
174281
  status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
@@ -173968,6 +174341,14 @@ class WmtsMapLayerFormat extends ImageryMapLayerFormat {
173968
174341
  return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
173969
174342
  }
173970
174343
  catch (err) {
174344
+ if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
174345
+ let blockedOrigin;
174346
+ try {
174347
+ blockedOrigin = new URL(err.url).origin;
174348
+ }
174349
+ catch { /* non-hierarchical URL */ }
174350
+ return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
174351
+ }
173971
174352
  let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
173972
174353
  if (err?.status === 401) {
173973
174354
  status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
@@ -174032,7 +174413,9 @@ const internalMapLayerImageryFormats = [WmsMapLayerFormat, WmtsMapLayerFormat, A
174032
174413
  __webpack_require__.r(__webpack_exports__);
174033
174414
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
174034
174415
  /* harmony export */ MapLayerImageryProvider: () => (/* binding */ MapLayerImageryProvider),
174035
- /* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus)
174416
+ /* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus),
174417
+ /* harmony export */ escapeHtml: () => (/* binding */ escapeHtml),
174418
+ /* harmony export */ tryGetOrigin: () => (/* binding */ tryGetOrigin)
174036
174419
  /* harmony export */ });
174037
174420
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
174038
174421
  /* harmony import */ var _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @itwin/core-common */ "../../core/common/lib/esm/core-common.js");
@@ -174059,6 +174442,34 @@ __webpack_require__.r(__webpack_exports__);
174059
174442
  const tileImageSize = 256, untiledImageSize = 256;
174060
174443
  const earthRadius = 6378137;
174061
174444
  const doDebugToolTips = false;
174445
+ /** Escapes HTML metacharacters so the text renders literally when assigned to `innerHTML`.
174446
+ * Use for any server- or user-supplied string that ends up in the map tooltip, which is rendered
174447
+ * as HTML by [[MapLayerTileTreeReference.getToolTip]].
174448
+ * @internal
174449
+ */
174450
+ function escapeHtml(text) {
174451
+ return text.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
174452
+ }
174453
+ /** Returns the origin (scheme + host + port) of the given URL, or undefined if it cannot be parsed or does
174454
+ * not denote a distinct network origin.
174455
+ *
174456
+ * Only `http:` and `https:` URLs yield an origin. Every other scheme is rejected because opaque URLs
174457
+ * — `file:`, `data:`, `about:`, `blob:null`, and the custom protocols Electron hosts commonly register —
174458
+ * all serialize to the literal string `"null"`. Comparing those would make unrelated URLs look same-origin,
174459
+ * so a single trusted entry could unlock all of them. Callers use this for credential-trust decisions, and
174460
+ * returning `undefined` keeps those decisions fail-closed.
174461
+ * @internal
174462
+ */
174463
+ function tryGetOrigin(url) {
174464
+ let parsed;
174465
+ try {
174466
+ parsed = new URL(url);
174467
+ }
174468
+ catch {
174469
+ return undefined;
174470
+ }
174471
+ return (parsed.protocol === "http:" || parsed.protocol === "https:") ? parsed.origin : undefined;
174472
+ }
174062
174473
  /** The status of the map layer imagery provider that lets you know if authentication is needed to request tiles.
174063
174474
  * @public
174064
174475
  */
@@ -174066,6 +174477,12 @@ var MapLayerImageryProviderStatus;
174066
174477
  (function (MapLayerImageryProviderStatus) {
174067
174478
  MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["Valid"] = 0] = "Valid";
174068
174479
  MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["RequireAuth"] = 1] = "RequireAuth";
174480
+ /** A request received an authentication challenge, but credentials were withheld because the request origin
174481
+ * is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
174482
+ * The blocked origins are available via [[MapLayerImageryProvider.blockedOrigins]].
174483
+ * @beta
174484
+ */
174485
+ MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["UntrustedOrigin"] = 2] = "UntrustedOrigin";
174069
174486
  })(MapLayerImageryProviderStatus || (MapLayerImageryProviderStatus = {}));
174070
174487
  /** Abstract class for map layer imagery providers.
174071
174488
  * 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.
@@ -174083,7 +174500,41 @@ class MapLayerImageryProvider {
174083
174500
  /** @internal */
174084
174501
  _status = MapLayerImageryProviderStatus.Valid;
174085
174502
  /** @internal */
174086
- _includeUserCredentials = false;
174503
+ _blockedOrigins = new Set();
174504
+ /** Origins of requests for which credentials were withheld because they are not trusted
174505
+ * (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
174506
+ * Populated when [[status]] transitions to [[MapLayerImageryProviderStatus.UntrustedOrigin]];
174507
+ * [[onStatusChanged]] is raised again each time a new origin is added. Cleared by [[resetStatus]].
174508
+ * @beta
174509
+ */
174510
+ get blockedOrigins() { return [...this._blockedOrigins]; }
174511
+ /** Origins for which a previous SSO handshake (i.e. Windows Authentication) succeeded.
174512
+ * Browser credentials are only included for subsequent requests targeting these origins,
174513
+ * so that a successful handshake with one host does not leak credentials to other hosts
174514
+ * this provider may contact.
174515
+ * @internal
174516
+ */
174517
+ _ssoSucceededOrigins = new Set();
174518
+ /** Returns true if browser credentials should be included for the given URL because a previous
174519
+ * SSO handshake succeeded for its origin AND the origin is still allowed by the current policy
174520
+ * (see [[MapLayerFormatRegistry.isSsoAllowed]]). Re-checking the policy ensures a handshake recorded
174521
+ * while enforcement was disabled — or before an origin was removed from
174522
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]] — does not keep latching credentials on.
174523
+ * @internal
174524
+ */
174525
+ includeUserCredentials(url) {
174526
+ const origin = tryGetOrigin(url);
174527
+ return origin !== undefined && this._ssoSucceededOrigins.has(origin) && this.isSsoAllowed(url);
174528
+ }
174529
+ /** Records that an SSO handshake succeeded for the given URL's origin, so subsequent requests
174530
+ * to that origin include browser credentials without going through another 401 challenge.
174531
+ * @internal
174532
+ */
174533
+ recordSsoSucceeded(url) {
174534
+ const origin = tryGetOrigin(url);
174535
+ if (origin !== undefined)
174536
+ this._ssoSucceededOrigins.add(origin);
174537
+ }
174087
174538
  /** @internal */
174088
174539
  onFirstRequestCompleted = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
174089
174540
  /** @internal */
@@ -174099,7 +174550,17 @@ class MapLayerImageryProvider {
174099
174550
  * @public
174100
174551
  */
174101
174552
  get supportsMapFeatureInfo() { return false; }
174102
- resetStatus() { this.setStatus(MapLayerImageryProviderStatus.Valid); }
174553
+ /** Reset the provider's status to [[MapLayerImageryProviderStatus.Valid]] and clear the list of
174554
+ * [[blockedOrigins]] accumulated while in the [[MapLayerImageryProviderStatus.UntrustedOrigin]] state.
174555
+ * Raises [[onStatusChanged]] if the status actually changes.
174556
+ * Typically called after the user has provided credentials or the application has updated
174557
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]], so that subsequent requests are re-attempted.
174558
+ * @beta
174559
+ */
174560
+ resetStatus() {
174561
+ this._blockedOrigins.clear();
174562
+ this.setStatus(MapLayerImageryProviderStatus.Valid);
174563
+ }
174103
174564
  /** @internal */
174104
174565
  get tileSize() { return this._usesCachedTiles ? tileImageSize : untiledImageSize; }
174105
174566
  /** @internal */
@@ -174273,6 +174734,32 @@ class MapLayerImageryProvider {
174273
174734
  (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setBasicAuthorization)(headers, this._settings.userName, this._settings.password);
174274
174735
  }
174275
174736
  }
174737
+ /** Returns true if the given URL has the same origin as this layer's settings URL.
174738
+ * Used to avoid leaking credentials to third-party hosts.
174739
+ * @internal
174740
+ */
174741
+ matchesSettingsUrlOrigin(url) {
174742
+ const origin = tryGetOrigin(url);
174743
+ return origin !== undefined && origin === tryGetOrigin(this._settings.url);
174744
+ }
174745
+ /** Returns true if the basic-auth credentials from the layer settings may be attached to a request to the given URL.
174746
+ * Always true unless [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
174747
+ * When enabled, the origin of this layer's settings URL is implicitly trusted (the credentials belong to that
174748
+ * server); other origins must be listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]].
174749
+ * See [[MapLayerFormatRegistry.isCredentialsSharingAllowed]].
174750
+ * @internal
174751
+ */
174752
+ isCredentialsSharingAllowed(url) {
174753
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, this._settings.url);
174754
+ }
174755
+ /** Returns true if a request to the given URL may be retried with browser credentials included
174756
+ * (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
174757
+ * See [[MapLayerFormatRegistry.isSsoAllowed]].
174758
+ * @internal
174759
+ */
174760
+ isSsoAllowed(url) {
174761
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(url);
174762
+ }
174276
174763
  /** @internal */
174277
174764
  async makeTileRequest(url, timeoutMs, authorization) {
174278
174765
  // We want to complete the first request before letting other requests go;
@@ -174292,40 +174779,132 @@ class MapLayerImageryProvider {
174292
174779
  throw new Error("fetch call failed");
174293
174780
  return response;
174294
174781
  }
174782
+ /** Records the given URL's origin and transitions the status to [[MapLayerImageryProviderStatus.UntrustedOrigin]].
174783
+ * Called when a request received an authentication challenge that could not be answered because the origin
174784
+ * is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
174785
+ * Raises [[onStatusChanged]] on the status transition, and again whenever a new origin is added.
174786
+ * @internal
174787
+ */
174788
+ reportBlockedOrigin(url) {
174789
+ const origin = tryGetOrigin(url) ?? url;
174790
+ const isNewOrigin = !this._blockedOrigins.has(origin);
174791
+ this._blockedOrigins.add(origin);
174792
+ if (this._status !== MapLayerImageryProviderStatus.UntrustedOrigin)
174793
+ this.setStatus(MapLayerImageryProviderStatus.UntrustedOrigin);
174794
+ else if (isNewOrigin)
174795
+ this.onStatusChanged.raiseEvent(this); // status unchanged, but a new origin was blocked
174796
+ }
174797
+ /** Logs a warning (once per origin, app-wide) when credentials are sent to an origin that would be blocked
174798
+ * if [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] were enabled.
174799
+ * Helps applications discover the origins they need to whitelist before opting in to the restriction.
174800
+ * See [[MapLayerFormatRegistry.logUntrustedOriginUse]].
174801
+ * @internal
174802
+ */
174803
+ logUntrustedOriginUse(url) {
174804
+ _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(url);
174805
+ }
174806
+ /** The redirect policy to apply to a request that carries browser credentials (see [[includeUserCredentials]]).
174807
+ *
174808
+ * When [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled, redirects are refused
174809
+ * outright (`"error"`). `fetch` cannot be asked to follow only same-origin redirects, and by the time a
174810
+ * followed redirect can be inspected the credentials have already been delivered to the destination — so
174811
+ * refusing is the only way to honour the guarantee that credentials reach none but the origins listed in
174812
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]]. Legitimate same-origin redirects fail as a result;
174813
+ * that is the cost of the opt-in restriction.
174814
+ *
174815
+ * When the restriction is disabled (the default), redirects are followed as before and
174816
+ * [[checkCredentialedRedirect]] reports the destination after the fact.
174817
+ * @internal
174818
+ */
174819
+ get credentialedRedirect() {
174820
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
174821
+ }
174822
+ /** Detects that a request carrying browser credentials (see [[includeUserCredentials]]) was transparently
174823
+ * redirected to a different origin, and reports or logs that origin.
174824
+ *
174825
+ * This is a **best-effort, after-the-fact** signal used only while
174826
+ * [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is disabled, where credentialed requests
174827
+ * still follow redirects (see [[credentialedRedirect]]). It cannot prevent the exposure — the credentials
174828
+ * have already been sent — and it does not fire at all when the destination denies CORS, because `fetch`
174829
+ * then rejects instead of returning a `Response`. The destination origin is never latched as SSO-succeeded,
174830
+ * so credentials do not keep flowing to it.
174831
+ * @internal
174832
+ */
174833
+ checkCredentialedRedirect(requestedUrl, response) {
174834
+ const finalOrigin = tryGetOrigin(response.url);
174835
+ if (!response.url || finalOrigin === undefined || finalOrigin === tryGetOrigin(requestedUrl))
174836
+ return;
174837
+ if (!this.isSsoAllowed(response.url))
174838
+ this.reportBlockedOrigin(response.url);
174839
+ else
174840
+ this.logUntrustedOriginUse(response.url); // no-op when the restriction is enabled
174841
+ }
174295
174842
  /** @internal */
174296
174843
  async makeRequest(url, timeoutMs, authorization) {
174297
174844
  let response;
174298
174845
  let headers;
174299
174846
  let hasCreds = false;
174847
+ // Whether this request had basic-auth credentials of its own to offer. Requests carrying a caller-supplied
174848
+ // `authorization` are excluded: those bypass the origin policy entirely.
174849
+ const hasSettingsCreds = !authorization && !!this._settings.userName && !!this._settings.password;
174300
174850
  if (authorization) {
174301
174851
  headers = new Headers();
174302
174852
  headers.set("Authorization", authorization);
174303
174853
  }
174304
- else if (this._settings.userName && this._settings.password) {
174305
- hasCreds = true;
174306
- headers = new Headers();
174307
- this.setRequestAuthorization(headers);
174854
+ else if (hasSettingsCreds) {
174855
+ if (this.isCredentialsSharingAllowed(url)) {
174856
+ hasCreds = true;
174857
+ headers = new Headers();
174858
+ this.setRequestAuthorization(headers);
174859
+ if (!this.matchesSettingsUrlOrigin(url))
174860
+ this.logUntrustedOriginUse(url);
174861
+ }
174308
174862
  }
174863
+ const includeCredentials = this.includeUserCredentials(url);
174309
174864
  const opts = {
174310
174865
  method: "GET",
174311
174866
  headers,
174312
- credentials: this._includeUserCredentials ? "include" : undefined,
174867
+ credentials: includeCredentials ? "include" : undefined,
174868
+ redirect: includeCredentials ? this.credentialedRedirect : undefined,
174313
174869
  };
174314
174870
  if (timeoutMs !== undefined)
174315
174871
  (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setRequestTimeout)(opts, timeoutMs);
174316
174872
  response = await fetch(url, opts);
174873
+ if (includeCredentials)
174874
+ this.checkCredentialedRedirect(url, response);
174875
+ // fetch follows redirects transparently, so all trust decisions below target the final
174876
+ // (post-redirect) URL reported by the response, not the URL we asked for.
174877
+ const challengedUrl = response.url || url;
174317
174878
  if (response.status === 401
174318
174879
  && (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])
174319
- && !this._includeUserCredentials
174880
+ && !includeCredentials
174320
174881
  && !hasCreds) {
174321
- // Removed the previous headers and make sure "include" credentials is set
174322
- opts.headers = undefined;
174323
- opts.credentials = "include";
174324
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
174325
- response = await fetch(url, opts);
174326
- if (response.status === 200) {
174327
- this._includeUserCredentials = true; // avoid going through 401 challenges over and over
174882
+ if (this.isSsoAllowed(challengedUrl)) {
174883
+ // Removed the previous headers and make sure "include" credentials is set
174884
+ opts.headers = undefined;
174885
+ opts.credentials = "include";
174886
+ // A Negotiate/NTLM handshake is normally a same-URL 401 round-trip, but in legacy mode we preserve
174887
+ // the previous behavior and allow the browser to follow redirects after the authenticated retry.
174888
+ opts.redirect = _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
174889
+ this.logUntrustedOriginUse(challengedUrl);
174890
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
174891
+ response = await fetch(challengedUrl, opts);
174892
+ if (response.status === 200) {
174893
+ this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
174894
+ }
174328
174895
  }
174896
+ else {
174897
+ this.reportBlockedOrigin(challengedUrl);
174898
+ }
174899
+ }
174900
+ else if ((response.status === 401 || response.status === 403) && hasSettingsCreds && !this.isCredentialsSharingAllowed(challengedUrl)) {
174901
+ // Some servers answer an unauthenticated request with 403 (Forbidden) rather than a 401 challenge;
174902
+ // since this request could not present its credentials to the challenging origin, either status most
174903
+ // likely results from that. The permission is recomputed for the challenged URL rather than reusing the
174904
+ // decision made for the requested one: `fetch` strips the Authorization header when it follows a
174905
+ // cross-origin redirect, so a trusted request can still arrive unauthenticated at an untrusted origin,
174906
+ // and conversely a request that started out untrusted may end up at an origin that is trusted.
174907
+ this.reportBlockedOrigin(challengedUrl);
174329
174908
  }
174330
174909
  return response;
174331
174910
  }
@@ -174357,16 +174936,28 @@ class MapLayerImageryProvider {
174357
174936
  }
174358
174937
  /** @internal */
174359
174938
  async toolTipFromUrl(strings, url) {
174360
- const headers = new Headers();
174361
- this.setRequestAuthorization(headers);
174939
+ let headers;
174940
+ if (this.isCredentialsSharingAllowed(url)) {
174941
+ headers = new Headers();
174942
+ this.setRequestAuthorization(headers);
174943
+ }
174362
174944
  try {
174945
+ const includeCredentials = this.includeUserCredentials(url);
174363
174946
  const response = await fetch(url, {
174364
174947
  method: "GET",
174365
174948
  headers,
174366
- credentials: this._includeUserCredentials ? "include" : undefined,
174949
+ credentials: includeCredentials ? "include" : undefined,
174950
+ redirect: includeCredentials ? this.credentialedRedirect : undefined,
174367
174951
  });
174368
- const text = await response.text();
174369
- if (undefined !== text) {
174952
+ if (includeCredentials)
174953
+ this.checkCredentialedRedirect(url, response);
174954
+ let text = await response.text();
174955
+ if (text) {
174956
+ // Tooltip content (e.g. WMS GetFeatureInfo responses) is rendered as HTML downstream and may
174957
+ // deliberately contain markup; text from origins not trusted for credentials is escaped.
174958
+ // fetch follows redirects transparently, so the text may come from a different origin than requested.
174959
+ if (!this.isCredentialsSharingAllowed(response.url || url))
174960
+ text = escapeHtml(text);
174370
174961
  strings.push(text);
174371
174962
  }
174372
174963
  }
@@ -174546,6 +175137,12 @@ var MapLayerSourceStatus;
174546
175137
  /** Format is not compatible with the URL provided.
174547
175138
  */
174548
175139
  MapLayerSourceStatus[MapLayerSourceStatus["IncompatibleFormat"] = 7] = "IncompatibleFormat";
175140
+ /** Authentication could not be attempted because the source's origin is not trusted
175141
+ * (see [MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]($frontend)). Add the origin to
175142
+ * [MapLayerFormatRegistry.trustedCredentialsOrigins]($frontend) rather than prompting for credentials.
175143
+ * @beta
175144
+ */
175145
+ MapLayerSourceStatus[MapLayerSourceStatus["UntrustedOrigin"] = 8] = "UntrustedOrigin";
174549
175146
  })(MapLayerSourceStatus || (MapLayerSourceStatus = {}));
174550
175147
  /** A source for map layers. These may be catalogued for convenient use by users or applications.
174551
175148
  * @public
@@ -174833,10 +175430,8 @@ class MapLayerTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_3__.T
174833
175430
  const tree = this.treeOwner.tileTree;
174834
175431
  if (undefined === tree || hit.iModel !== tree.iModel || tree.modelId !== hit.sourceId)
174835
175432
  return undefined;
174836
- const strings = [];
174837
- strings.push(`Map Layer: ${this._layerSettings.name}`);
174838
175433
  const div = document.createElement("div");
174839
- div.innerHTML = strings.join("<br>");
175434
+ div.textContent = `Map Layer: ${this._layerSettings.name}`;
174840
175435
  return div;
174841
175436
  }
174842
175437
  decorate(_context) {
@@ -176545,7 +177140,9 @@ class MapTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_7__.TileTr
176545
177140
  let carto;
176546
177141
  const strings = [];
176547
177142
  const getTooltipFunc = async (imageryTreeRef, quadId, cartoGraphic, imageryTree) => {
176548
- strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_4__.IModelApp.localization.getLocalizedString("iModelJs:MapLayers.ImageryLayer")}: ${imageryTreeRef.layerSettings.name}`);
177143
+ // innerHTML is used below because imageryLoader.getToolTip may deliberately supply markup.
177144
+ const layerName = (0,_internal__WEBPACK_IMPORTED_MODULE_7__.escapeHtml)(imageryTreeRef.layerSettings.name);
177145
+ strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_4__.IModelApp.localization.getLocalizedString("iModelJs:MapLayers.ImageryLayer")}: ${layerName}`);
176549
177146
  carto = cartoGraphic;
176550
177147
  await imageryTree.imageryLoader.getToolTip(strings, quadId, cartoGraphic, imageryTree);
176551
177148
  };
@@ -186419,7 +187016,11 @@ class InteractiveTool extends Tool {
186419
187016
  async onPostInstall() { }
186420
187017
  /** Override Call to reset tool to initial state */
186421
187018
  async onReinitialize() { }
186422
- /** Invoked when the tool becomes no longer active, to perform additional cleanup logic */
187019
+ /** Invoked when the tool becomes no longer active, to perform additional cleanup logic.
187020
+ * Cleanup must not assume that the EditCommand associated with the tool is still active: an immediate tool may have finished or
187021
+ * replaced it while this tool remained active. Tools must not start an EditCommand from onCleanup; ToolAdmin owns finishing the active EditCommand during tool cleanup.
187022
+ * @note A ViewTool should never start an EditCommand. An InputCollector may start an EditCommand only if suspending a tool that supports EditManipulators (ex. SelectionTool).
187023
+ */
186423
187024
  async onCleanup() { }
186424
187025
  /** Notification of a ViewTool or InputCollector starting and this tool is being suspended.
186425
187026
  * @note Applies only to PrimitiveTool and InputCollector, a ViewTool can't be suspended.
@@ -188593,23 +189194,54 @@ class ToolAdmin {
188593
189194
  }
188594
189195
  /** @internal */
188595
189196
  async setPrimitiveTool(newTool) {
188596
- if (undefined !== this._primitiveTool) {
188597
- await this._primitiveTool.onCleanup();
188598
- if (undefined !== this._editCommandHandler)
188599
- await this._editCommandHandler.finishCommand();
188600
- this._primitiveTool = undefined;
189197
+ return this.setPrimitiveToolInternal(newTool);
189198
+ }
189199
+ async setPrimitiveToolInternal(newTool, pendingFinishCommand) {
189200
+ const oldTool = this._primitiveTool;
189201
+ let ownsOldTool = undefined === oldTool;
189202
+ if (undefined !== oldTool) {
189203
+ let mainError;
189204
+ try {
189205
+ await oldTool.onCleanup();
189206
+ }
189207
+ catch (err) {
189208
+ mainError = (err instanceof Error) ? err : new Error(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BentleyError.getErrorMessage(err));
189209
+ }
189210
+ try {
189211
+ if (undefined !== pendingFinishCommand)
189212
+ await pendingFinishCommand;
189213
+ else if (undefined !== this._editCommandHandler)
189214
+ await this._editCommandHandler.finishCommand();
189215
+ }
189216
+ catch (err) {
189217
+ // throw finishCommand error if onCleanup succeeded, otherwise log finishCommand failure...
189218
+ if (undefined === mainError)
189219
+ mainError = (err instanceof Error) ? err : new Error(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BentleyError.getErrorMessage(err));
189220
+ else
189221
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(`${_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_4__.FrontendLoggerCategory.Package}.toolAdmin`, err);
189222
+ }
189223
+ finally {
189224
+ // Force-clear stale tool state if either onCleanup or finishCommand failed...
189225
+ ownsOldTool = this._primitiveTool === oldTool;
189226
+ if (ownsOldTool)
189227
+ this._primitiveTool = undefined;
189228
+ }
189229
+ if (undefined !== mainError)
189230
+ throw mainError;
188601
189231
  }
188602
- this._primitiveTool = newTool;
189232
+ // Do not let a delayed transition overwrite a tool installed by a newer transition.
189233
+ if (ownsOldTool)
189234
+ this._primitiveTool = newTool;
188603
189235
  }
188604
- // serialize concurrent starts to avoid two tools installing simultaneously.
188605
- _primitiveToolStarting;
189236
+ // Serialize primitive starts and last-viewport cleanup to avoid overlapping transitions.
189237
+ _primitiveToolTransition;
188606
189238
  /** @internal */
188607
189239
  async startPrimitiveTool(newTool) {
188608
189240
  // If another start is in progress wait for it to finish before proceeding.
188609
- while (undefined !== this._primitiveToolStarting)
188610
- await this._primitiveToolStarting;
188611
- let resolveStarting;
188612
- this._primitiveToolStarting = new Promise((r) => { resolveStarting = r; });
189241
+ while (undefined !== this._primitiveToolTransition)
189242
+ await this._primitiveToolTransition;
189243
+ let resolveTransition;
189244
+ const transition = this._primitiveToolTransition = new Promise((resolve) => { resolveTransition = resolve; });
188613
189245
  try {
188614
189246
  _IModelApp__WEBPACK_IMPORTED_MODULE_5__.IModelApp.notifications.outputPrompt("");
188615
189247
  await this.exitViewTool();
@@ -188637,9 +189269,9 @@ class ToolAdmin {
188637
189269
  this.onActiveToolChanged(activeTool, StartOrResume.Start);
188638
189270
  }
188639
189271
  finally {
188640
- if (resolveStarting)
188641
- resolveStarting();
188642
- this._primitiveToolStarting = undefined;
189272
+ resolveTransition?.();
189273
+ if (this._primitiveToolTransition === transition)
189274
+ this._primitiveToolTransition = undefined;
188643
189275
  }
188644
189276
  }
188645
189277
  /** Method used by interactive tools to send updated values to UI components, typically showing tool settings.
@@ -188886,10 +189518,41 @@ class ToolAdmin {
188886
189518
  set coordinateLockOverrides(coordLockOvr) { this.toolState.coordLockOvr = coordLockOvr; }
188887
189519
  /** @internal */
188888
189520
  async callOnCleanup() {
188889
- await this.exitViewTool();
188890
- await this.exitInputCollector();
188891
- if (undefined !== this._primitiveTool)
188892
- await this._primitiveTool.onCleanup();
189521
+ let pendingFinishCommand;
189522
+ const previousTransition = this._primitiveToolTransition;
189523
+ let resolveTransition;
189524
+ const transition = this._primitiveToolTransition = new Promise((resolve) => { resolveTransition = resolve; });
189525
+ try {
189526
+ // Start the edit-command cleanup before the first await. ViewManager can invoke this method
189527
+ // without awaiting it when the last viewport is dropped.
189528
+ if (undefined !== this._editCommandHandler) {
189529
+ const finishCommand = this._editCommandHandler.finishCommand();
189530
+ // Attach a rejection handler immediately: another cleanup operation may fail before this promise is awaited.
189531
+ pendingFinishCommand = finishCommand.catch((err) => {
189532
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(`${_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_4__.FrontendLoggerCategory.Package}.toolAdmin`, err);
189533
+ return "";
189534
+ });
189535
+ }
189536
+ if (undefined !== previousTransition)
189537
+ await previousTransition;
189538
+ if (undefined !== this._viewTool)
189539
+ await this.exitViewTool();
189540
+ if (undefined !== this._inputCollector)
189541
+ await this.exitInputCollector();
189542
+ // Keep cleanup path consistent with other primitive-tool transitions.
189543
+ if (undefined !== this._primitiveTool)
189544
+ await this.setPrimitiveToolInternal(undefined, pendingFinishCommand); // NOTE: ViewManager.setSelectedView will call startDefaultTool if a new view is opened...
189545
+ else if (undefined !== pendingFinishCommand)
189546
+ await pendingFinishCommand;
189547
+ }
189548
+ catch (err) {
189549
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(`${_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_4__.FrontendLoggerCategory.Package}.toolAdmin`, err);
189550
+ }
189551
+ finally {
189552
+ resolveTransition?.();
189553
+ if (this._primitiveToolTransition === transition)
189554
+ this._primitiveToolTransition = undefined;
189555
+ }
188893
189556
  }
188894
189557
  }
188895
189558
  /**
@@ -269880,18 +270543,19 @@ class PolyfaceQuery {
269880
270543
  */
269881
270544
  static dihedralAngleSummary(source, ignoreBoundaries = false) {
269882
270545
  // more info can be found at geometry/internaldocs/Polyface.md
270546
+ // visit all facets and collect normals and edges
269883
270547
  const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_29__.IndexedEdgeMatcher();
269884
270548
  const vertices = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_34__.Polyface ? source.data.point : undefined;
269885
270549
  const visitor = source instanceof _Polyface__WEBPACK_IMPORTED_MODULE_34__.Polyface ? source.createVisitor(1) : source;
269886
270550
  visitor.setNumWrap(1);
269887
- const centroidNormal = [];
270551
+ const facetNormals = [];
269888
270552
  let normalCounter = 0;
269889
270553
  for (visitor.reset(); visitor.moveToNextFacet();) {
269890
270554
  const numEdges = visitor.pointCount - 1;
269891
270555
  const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_14__.PolygonOps.centroidAreaNormal(visitor.point);
269892
270556
  if (normal === undefined)
269893
270557
  return -2;
269894
- centroidNormal.push(normal);
270558
+ facetNormals.push(normal);
269895
270559
  for (let i = 0; i < numEdges; i++) {
269896
270560
  const edge = edges.addEdge(visitor.clientPointIndex(i), visitor.clientPointIndex(i + 1), normalCounter);
269897
270561
  if (!vertices) // decorate if we don't have vertices to query later
@@ -269907,21 +270571,24 @@ class PolyfaceQuery {
269907
270571
  edges.sortAndCollectClusters(manifoldClusters, ignoreBoundaries ? undefined : badClusters, undefined, badClusters);
269908
270572
  if (badClusters.length > 0)
269909
270573
  return -2;
269910
- // find angle between facet centroid normals (dihedral angles)
270574
+ // find angle between facet normals (dihedral angles)
269911
270575
  let numPositive = 0;
269912
270576
  let numPlanar = 0;
269913
270577
  let numNegative = 0;
269914
270578
  const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_12__.Vector3d.create();
269915
270579
  for (const cluster of manifoldClusters) {
269916
270580
  if (Array.isArray(cluster) && cluster.length === 2) {
269917
- const sideA = cluster[0];
269918
- const sideB = cluster[1];
269919
- if (vertices)
269920
- vertices.vectorIndexIndex(sideA.startVertex, sideA.endVertex, edgeVector);
269921
- else
270581
+ const sideA = cluster[0]; // edge on facetA
270582
+ const sideB = cluster[1]; // edge on facetB
270583
+ if (vertices) {
270584
+ if (!vertices.vectorIndexIndex(sideA.startVertex, sideA.endVertex, edgeVector))
270585
+ return -2;
270586
+ }
270587
+ else {
269922
270588
  edgeVector.setFrom(sideA.edgeVector);
269923
- const facetNormalA = centroidNormal[sideA.facetIndex].direction;
269924
- const facetNormalB = centroidNormal[sideB.facetIndex].direction;
270589
+ }
270590
+ const facetNormalA = facetNormals[sideA.facetIndex].direction;
270591
+ const facetNormalB = facetNormals[sideB.facetIndex].direction;
269925
270592
  const dihedralAngle = facetNormalA.signedAngleTo(facetNormalB, edgeVector);
269926
270593
  if (dihedralAngle.isAlmostZero)
269927
270594
  numPlanar++;
@@ -334348,6 +335015,1170 @@ var loadLanguages = instance.loadLanguages;
334348
335015
 
334349
335016
 
334350
335017
 
335018
+ /***/ },
335019
+
335020
+ /***/ "../../common/temp/node_modules/.pnpm/wms-capabilities@0.6.0/node_modules/wms-capabilities/dist/wms-capabilities.mjs"
335021
+ /*!***************************************************************************************************************************!*\
335022
+ !*** ../../common/temp/node_modules/.pnpm/wms-capabilities@0.6.0/node_modules/wms-capabilities/dist/wms-capabilities.mjs ***!
335023
+ \***************************************************************************************************************************/
335024
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
335025
+
335026
+ "use strict";
335027
+ __webpack_require__.r(__webpack_exports__);
335028
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
335029
+ /* harmony export */ "default": () => (/* binding */ WMS)
335030
+ /* harmony export */ });
335031
+
335032
+ /**
335033
+ * wms-capabilities @0.6.0
335034
+ * @description WMS service Capabilities > JSON, based on openlayers
335035
+ * @license BSD-2-Clause
335036
+ * @preserve
335037
+ */
335038
+
335039
+ /**
335040
+ * Returns true if the specified value is not undefined.
335041
+ *
335042
+ * @param {?} val Variable to test.
335043
+ * @return {Boolean} Whether variable is defined.
335044
+ */
335045
+ var isDef = (val) => val !== void 0;
335046
+
335047
+ /**
335048
+ * Adds a key-value pair to the object/map/hash if it doesn't exist yet.
335049
+ *
335050
+ * @param {Object.<K,V>} obj The object to which to add the key-value pair.
335051
+ * @param {String} key The key to add.
335052
+ * @param {V} value The value to add if the key wasn't present.
335053
+ * @return {V} The value of the entry at the end of the function.
335054
+ * @template K,V
335055
+ */
335056
+ var setIfUndefined = (obj, key, value) => key in obj ? obj[key] : (obj[key] = value);
335057
+
335058
+ /**
335059
+ * @enum {Number}
335060
+ */
335061
+ const NODE_TYPES = {
335062
+ ELEMENT: 1,
335063
+ ATTRIBUTE: 2,
335064
+ TEXT: 3,
335065
+ CDATA_SECTION: 4,
335066
+ ENTITY_REFERENCE: 5,
335067
+ ENTITY: 6,
335068
+ PROCESSING_INSTRUCTION: 7,
335069
+ COMMENT: 8,
335070
+ DOCUMENT: 9,
335071
+ DOCUMENT_TYPE: 10,
335072
+ DOCUMENT_FRAGMENT: 11,
335073
+ NOTATION: 12
335074
+ };
335075
+
335076
+ class XMLParser {
335077
+ /**
335078
+ * XML DOM parser
335079
+ * @constructor
335080
+ * @param {DOMParser} DOMParser
335081
+ */
335082
+ constructor (DOMParser) {
335083
+ /**
335084
+ * @type {DOMParser}
335085
+ */
335086
+ this._parser = new DOMParser();
335087
+ };
335088
+
335089
+ /**
335090
+ * @param {String} xmlstring
335091
+ * @return {Document}
335092
+ */
335093
+ toDocument (xmlstring) {
335094
+ return this._parser.parseFromString(xmlstring, 'application/xml');
335095
+ }
335096
+
335097
+ /**
335098
+ * Recursively grab all text content of child nodes into a single string.
335099
+ * @param {Node} node Node.
335100
+ * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line
335101
+ * breaks.
335102
+ * @return {string} All text content.
335103
+ * @api
335104
+ */
335105
+ getAllTextContent (node, normalizeWhitespace) {
335106
+ return getAllTextContent(node, normalizeWhitespace).join('');
335107
+ }
335108
+ }
335109
+
335110
+
335111
+ /**
335112
+ * Recursively grab all text content of child nodes into a single string.
335113
+ * @param {Node} node Node.
335114
+ * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line
335115
+ * breaks.
335116
+ * @return {string} All text content.
335117
+ * @api
335118
+ */
335119
+ function getAllTextContent (node, normalizeWhitespace) {
335120
+ return getAllTextContentInternal(node, normalizeWhitespace, []).join('');
335121
+ }
335122
+
335123
+
335124
+ /**
335125
+ * @param {Node} node Node.
335126
+ * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line
335127
+ * breaks.
335128
+ * @param {Array.<String|string>} accumulator Accumulator.
335129
+ * @private
335130
+ * @return {Array.<String|string>} Accumulator.
335131
+ */
335132
+ function getAllTextContentInternal (node, normalizeWhitespace, accumulator) {
335133
+ if (node.nodeType === NODE_TYPES.CDATA_SECTION ||
335134
+ node.nodeType === NODE_TYPES.TEXT) {
335135
+ if (normalizeWhitespace) {
335136
+ // FIXME understand why goog.dom.getTextContent_ uses String here
335137
+ accumulator.push(String(node.nodeValue).replace(/(\r\n|\r|\n)/g, ''));
335138
+ } else {
335139
+ accumulator.push(node.nodeValue);
335140
+ }
335141
+ } else {
335142
+ var n;
335143
+ for (n = node.firstChild; n; n = n.nextSibling) {
335144
+ getAllTextContentInternal(n, normalizeWhitespace, accumulator);
335145
+ }
335146
+ }
335147
+ return accumulator;
335148
+ }
335149
+
335150
+ /**
335151
+ * @param {Object.<string, Object.<string, XMLParser.Parser>>} parsersNS
335152
+ * Parsers by namespace.
335153
+ * @param {Node} node Node.
335154
+ * @param {Array.<*>} objectStack Object stack.
335155
+ * @param {*=} bind The object to use as `this`.
335156
+ */
335157
+ function parseNode (parsersNS, node, objectStack, bind) {
335158
+ for (var n = firstElementChild(node); n; n = nextElementSibling(n)) {
335159
+ var namespaceURI = n.namespaceURI || null;
335160
+ var parsers = parsersNS[namespaceURI];
335161
+ if (isDef(parsers)) {
335162
+ var parser = parsers[n.localName];
335163
+ if (isDef(parser)) {
335164
+ parser.call(bind, n, objectStack);
335165
+ }
335166
+ }
335167
+ }
335168
+ }
335169
+
335170
+ /**
335171
+ * Mostly for node.js
335172
+ * @param {Node} node
335173
+ * @return {Node}
335174
+ */
335175
+ function firstElementChild (node) {
335176
+ let firstElementChild = node.firstElementChild || node.firstChild;
335177
+ while (firstElementChild && firstElementChild.nodeType !== NODE_TYPES.ELEMENT) {
335178
+ firstElementChild = firstElementChild.nextSibling;
335179
+ }
335180
+ return firstElementChild;
335181
+ }
335182
+
335183
+ /**
335184
+ * Mostly for node.js
335185
+ * @param {Node} node
335186
+ * @return {Node}
335187
+ */
335188
+ function nextElementSibling (node) {
335189
+ let nextSibling = node.nextElementSibling || node.nextSibling;
335190
+ while (nextSibling && nextSibling.nodeType !== NODE_TYPES.ELEMENT) {
335191
+ nextSibling = nextSibling.nextSibling;
335192
+ }
335193
+ return nextSibling;
335194
+ }
335195
+
335196
+ /**
335197
+ * @param {Array.<string>} namespaceURIs Namespace URIs.
335198
+ * @param {Object.<string, XMLParser.Parser>} parsers Parsers.
335199
+ * @param {Object.<string, Object.<string, XMLParser.Parser>>=} opt_parsersNS
335200
+ * ParsersNS.
335201
+ * @return {Object.<string, Object.<string, XMLParser.Parser>>} Parsers NS.
335202
+ */
335203
+ function makeParsersNS (namespaceURIs, parsers, opt_parsersNS) {
335204
+ return /** @type {Object.<string, Object.<string, XMLParser.Parser>>} */ (
335205
+ makeStructureNS(namespaceURIs, parsers, opt_parsersNS));
335206
+ }
335207
+
335208
+ /**
335209
+ * Creates a namespaced structure, using the same values for each namespace.
335210
+ * This can be used as a starting point for versioned parsers, when only a few
335211
+ * values are version specific.
335212
+ * @param {Array.<string>} namespaceURIs Namespace URIs.
335213
+ * @param {T} structure Structure.
335214
+ * @param {Object.<string, T>=} opt_structureNS Namespaced structure to add to.
335215
+ * @return {Object.<string, T>} Namespaced structure.
335216
+ * @template T
335217
+ */
335218
+ function makeStructureNS (namespaceURIs, structure, opt_structureNS) {
335219
+ /**
335220
+ * @type {Object.<string, *>}
335221
+ */
335222
+ var structureNS = isDef(opt_structureNS) ? opt_structureNS : {};
335223
+ var i, ii;
335224
+ for (i = 0, ii = namespaceURIs.length; i < ii; ++i) {
335225
+ structureNS[namespaceURIs[i]] = structure;
335226
+ }
335227
+ return structureNS;
335228
+ }
335229
+
335230
+
335231
+ /**
335232
+ * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
335233
+ * @param {T=} opt_this The object to use as `this` in `valueReader`.
335234
+ * @return {Function} Parser.
335235
+ * @template T
335236
+ */
335237
+ function makeArrayPusher (valueReader, opt_this) {
335238
+ return (
335239
+ /**
335240
+ * @param {Node} node Node.
335241
+ * @param {Array.<*>} objectStack Object stack.
335242
+ */
335243
+ function(node, objectStack) {
335244
+ var value = valueReader.call(isDef(opt_this) ? opt_this : this,
335245
+ node, objectStack);
335246
+ if (isDef(value)) {
335247
+ var array = objectStack[objectStack.length - 1];
335248
+ array.push(value);
335249
+ }
335250
+ });
335251
+ }
335252
+
335253
+ /**
335254
+ * @param {Object} object Object.
335255
+ * @param {Object.<String, Object.<String, Function>>} parsersNS Parsers by namespace.
335256
+ * @param {Node} node Node.
335257
+ * @param {Array.<*>} objectStack Object stack.
335258
+ * @param {*=} bind The object to use as `this`.
335259
+ * @return {Object|undefined} Object.
335260
+ */
335261
+ function pushParseAndPop (object, parsersNS, node, objectStack, bind) {
335262
+ objectStack.push(object);
335263
+ parseNode(parsersNS, node, objectStack, bind);
335264
+ return objectStack.pop();
335265
+ }
335266
+
335267
+
335268
+ /**
335269
+ * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
335270
+ * @param {string=} opt_property Property.
335271
+ * @param {T=} opt_this The object to use as `this` in `valueReader`.
335272
+ * @return {XMLParser.Parser} Parser.
335273
+ * @template T
335274
+ */
335275
+ function makeObjectPropertySetter (valueReader, opt_property, opt_this) {
335276
+ return (
335277
+ /**
335278
+ * @param {Node} node Node.
335279
+ * @param {Array.<*>} objectStack Object stack.
335280
+ */
335281
+ function(node, objectStack) {
335282
+ let value = valueReader.call(isDef(opt_this) ? opt_this : this,
335283
+ node, objectStack);
335284
+ if (isDef(value)) {
335285
+ var object = /** @type {Object} */ (objectStack[objectStack.length - 1]);
335286
+ var property = isDef(opt_property) ? opt_property : node.localName;
335287
+ object[property] = value;
335288
+ }
335289
+ });
335290
+ }
335291
+
335292
+
335293
+ /**
335294
+ * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.
335295
+ * @param {string=} opt_property Property.
335296
+ * @param {T=} opt_this The object to use as `this` in `valueReader`.
335297
+ * @return {Function} Parser.
335298
+ * @template T
335299
+ */
335300
+ function makeObjectPropertyPusher (valueReader, opt_property, opt_this) {
335301
+ return (
335302
+ /**
335303
+ * @param {Node} node Node.
335304
+ * @param {Array.<*>} objectStack Object stack.
335305
+ */
335306
+ function(node, objectStack) {
335307
+ var value = valueReader.call(isDef(opt_this) ? opt_this : this,
335308
+ node, objectStack);
335309
+
335310
+ if (isDef(value)) {
335311
+ var object = /** @type {Object} */ (objectStack[objectStack.length - 1]);
335312
+ var property = isDef(opt_property) ? opt_property : node.localName;
335313
+ var array = setIfUndefined(object, property, []);
335314
+ array.push(value);
335315
+ }
335316
+ });
335317
+ }
335318
+
335319
+ /**
335320
+ * Make sure we trim BOM and NBSP
335321
+ * @type {RegExp}
335322
+ */
335323
+ const TRIM_RE = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
335324
+
335325
+ /**
335326
+ * @param {String} str
335327
+ * @return {String}
335328
+ */
335329
+ function trim (str) {
335330
+ return str.replace(TRIM_RE, '');
335331
+ }
335332
+
335333
+ /**
335334
+ * @param {string} string String.
335335
+ * @return {boolean|undefined} Boolean.
335336
+ */
335337
+ function readBooleanString (string) {
335338
+ const m = /^\s*(true|1)|(false|0)\s*$/.exec(string);
335339
+ if (m) {
335340
+ return isDef(m[1]) || false;
335341
+ } else {
335342
+ return undefined;
335343
+ }
335344
+ }
335345
+
335346
+
335347
+ /**
335348
+ * @param {Node} node Node.
335349
+ * @return {number|undefined} Decimal.
335350
+ */
335351
+ function readDecimal (node) {
335352
+ return readDecimalString(getAllTextContent(node, false));
335353
+ }
335354
+
335355
+
335356
+ /**
335357
+ * @param {string} string String.
335358
+ * @return {number|undefined} Decimal.
335359
+ */
335360
+ function readDecimalString (string) {
335361
+ // FIXME check spec
335362
+ const m = /^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*$/i.exec(string);
335363
+ if (m) {
335364
+ return parseFloat(m[1]);
335365
+ } else {
335366
+ return undefined;
335367
+ }
335368
+ }
335369
+
335370
+
335371
+ /**
335372
+ * @param {Node} node Node.
335373
+ * @return {number|undefined} Non negative integer.
335374
+ */
335375
+ function readNonNegativeInteger (node) {
335376
+ return readNonNegativeIntegerString(getAllTextContent(node, false));
335377
+ }
335378
+
335379
+
335380
+ /**
335381
+ * @param {string} string String.
335382
+ * @return {number|undefined} Non negative integer.
335383
+ */
335384
+ function readNonNegativeIntegerString (string) {
335385
+ const m = /^\s*(\d+)\s*$/.exec(string);
335386
+ if (m) {
335387
+ return parseInt(m[1], 10);
335388
+ } else {
335389
+ return undefined;
335390
+ }
335391
+ }
335392
+
335393
+
335394
+ /**
335395
+ * @param {Node} node Node.
335396
+ * @return {string|undefined} String.
335397
+ */
335398
+ function readString (node) {
335399
+ return trim(getAllTextContent(node, false));
335400
+ }
335401
+
335402
+ /**
335403
+ * @const
335404
+ * @type {string}
335405
+ */
335406
+ const NAMESPACE_URI = 'http://www.w3.org/1999/xlink';
335407
+
335408
+ /**
335409
+ * @param {Node} node Node.
335410
+ * @return {Boolean|undefined} Boolean.
335411
+ */
335412
+ function readHref (node) {
335413
+ return node.getAttributeNS(NAMESPACE_URI, 'href');
335414
+ }
335415
+
335416
+ /**
335417
+ * @param {Node} node Node.
335418
+ * @param {Array.<*>} objectStack Object stack.
335419
+ * @return {Object|undefined} Attribution object.
335420
+ */
335421
+ function readAttribution(node, objectStack) {
335422
+ return pushParseAndPop({}, ATTRIBUTION_PARSERS, node, objectStack);
335423
+ }
335424
+
335425
+
335426
+ /**
335427
+ * @private
335428
+ * @param {Node} node Node.
335429
+ * @return {ol.Extent} Bounding box object.
335430
+ */
335431
+ function readBoundingBoxExtent (node) {
335432
+ return [
335433
+ readDecimalString(node.getAttribute('minx')),
335434
+ readDecimalString(node.getAttribute('miny')),
335435
+ readDecimalString(node.getAttribute('maxx')),
335436
+ readDecimalString(node.getAttribute('maxy'))
335437
+ ];
335438
+ }
335439
+
335440
+ /**
335441
+ * @private
335442
+ * @param {Node} node Node.
335443
+ * @param {Array.<*>} objectStack Object stack.
335444
+ * @return {Object} Bounding box object.
335445
+ */
335446
+ function readBoundingBox (node, objectStack) {
335447
+ const extent = readBoundingBoxExtent(node);
335448
+ const resolutions = [
335449
+ readDecimalString(node.getAttribute('resx')),
335450
+ readDecimalString(node.getAttribute('resy'))
335451
+ ];
335452
+
335453
+ return {
335454
+ 'crs': node.getAttribute('CRS') || node.getAttribute('SRS'),
335455
+ extent, res: resolutions
335456
+ };
335457
+ }
335458
+
335459
+ /**
335460
+ * @private
335461
+ * @param {Node} node Node.
335462
+ * @param {Array.<*>} objectStack Object stack.
335463
+ * @return {ol.Extent|undefined} Bounding box object.
335464
+ */
335465
+ function readLatLonBoundingBox (node, objectStack) {
335466
+ const extent = readBoundingBoxExtent(node);
335467
+
335468
+ if (!isDef(extent[0]) || !isDef(extent[1]) ||
335469
+ !isDef(extent[2]) || !isDef(extent[3])) {
335470
+ return undefined;
335471
+ }
335472
+
335473
+ return extent;
335474
+ }
335475
+
335476
+
335477
+ /**
335478
+ * @privat
335479
+ * @param {Node} node Node
335480
+ * @param {Arra.<Object>} objectStack Object stack
335481
+ * @return {Object}
335482
+ */
335483
+ function readScaleHint (node, objectStack) {
335484
+ const min = parseFloat(node.getAttribute('min'));
335485
+ const max = parseFloat(node.getAttribute('max'));
335486
+
335487
+ return { min, max };
335488
+ }
335489
+
335490
+
335491
+ /**
335492
+ * @private
335493
+ * @param {Node} node Node.
335494
+ * @param {Array.<*>} objectStack Object stack.
335495
+ * @return {ol.Extent|undefined} Bounding box object.
335496
+ */
335497
+ function readEXGeographicBoundingBox (node, objectStack) {
335498
+ const geographicBoundingBox = pushParseAndPop({},
335499
+ EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS,
335500
+ node, objectStack);
335501
+ if (!isDef(geographicBoundingBox)) return undefined;
335502
+
335503
+ const westBoundLongitude = /** @type {number|undefined} */
335504
+ (geographicBoundingBox['westBoundLongitude']);
335505
+ const southBoundLatitude = /** @type {number|undefined} */
335506
+ (geographicBoundingBox['southBoundLatitude']);
335507
+ const eastBoundLongitude = /** @type {number|undefined} */
335508
+ (geographicBoundingBox['eastBoundLongitude']);
335509
+ const northBoundLatitude = /** @type {number|undefined} */
335510
+ (geographicBoundingBox['northBoundLatitude']);
335511
+
335512
+ if (!isDef(westBoundLongitude) || !isDef(southBoundLatitude) ||
335513
+ !isDef(eastBoundLongitude) || !isDef(northBoundLatitude)) {
335514
+ return undefined;
335515
+ }
335516
+
335517
+ return [
335518
+ westBoundLongitude, southBoundLatitude,
335519
+ eastBoundLongitude, northBoundLatitude
335520
+ ];
335521
+ }
335522
+
335523
+
335524
+ /**
335525
+ * @param {Node} node Node.
335526
+ * @param {Array.<*>} objectStack Object stack.
335527
+ * @private
335528
+ * @return {Object|undefined} Capability object.
335529
+ */
335530
+ function readCapability (node, objectStack) {
335531
+ return pushParseAndPop({}, CAPABILITY_PARSERS, node, objectStack);
335532
+ }
335533
+
335534
+
335535
+ /**
335536
+ * @param {Node} node Node.
335537
+ * @param {Array.<*>} objectStack Object stack.
335538
+ * @private
335539
+ * @return {Object|undefined} Service object.
335540
+ */
335541
+ function readService (node, objectStack) {
335542
+ return pushParseAndPop({}, SERVICE_PARSERS, node, objectStack);
335543
+ }
335544
+
335545
+
335546
+ /**
335547
+ * @param {Node} node Node.
335548
+ * @param {Array.<*>} objectStack Object stack.
335549
+ * @private
335550
+ * @return {Object|undefined} Contact information object.
335551
+ */
335552
+ function readContactInformation (node, objectStack) {
335553
+ return pushParseAndPop({}, CONTACT_INFORMATION_PARSERS,
335554
+ node, objectStack);
335555
+ }
335556
+
335557
+
335558
+ /**
335559
+ * @param {Node} node Node.
335560
+ * @param {Array.<*>} objectStack Object stack.
335561
+ * @private
335562
+ * @return {Object|undefined} Contact person object.
335563
+ */
335564
+ function readContactPersonPrimary (node, objectStack) {
335565
+ return pushParseAndPop({}, CONTACT_PERSON_PARSERS,
335566
+ node, objectStack);
335567
+ }
335568
+
335569
+
335570
+ /**
335571
+ * @param {Node} node Node.
335572
+ * @param {Array.<*>} objectStack Object stack.
335573
+ * @private
335574
+ * @return {Object|undefined} Contact address object.
335575
+ */
335576
+ function readContactAddress (node, objectStack) {
335577
+ return pushParseAndPop({}, CONTACT_ADDRESS_PARSERS,
335578
+ node, objectStack);
335579
+ }
335580
+
335581
+
335582
+ /**
335583
+ * @param {Node} node Node.
335584
+ * @param {Array.<*>} objectStack Object stack.
335585
+ * @private
335586
+ * @return {Array.<string>|undefined} Format array.
335587
+ */
335588
+ function readException (node, objectStack) {
335589
+ return pushParseAndPop(
335590
+ [], EXCEPTION_PARSERS, node, objectStack);
335591
+ }
335592
+
335593
+
335594
+ /**
335595
+ * @param {Node} node Node.
335596
+ * @param {Array.<*>} objectStack Object stack.
335597
+ * @private
335598
+ * @return {Object|undefined} Layer object.
335599
+ */
335600
+ function readCapabilityLayer (node, objectStack) {
335601
+ const queryable = readBooleanString(node.getAttribute('queryable'));
335602
+ return pushParseAndPop({
335603
+ queryable: isDef(queryable) ? queryable : false },
335604
+ LAYER_PARSERS, node, objectStack);
335605
+ }
335606
+
335607
+
335608
+ /**
335609
+ * @private
335610
+ * @param {Node} node Node.
335611
+ * @param {Array.<*>} objectStack Object stack.
335612
+ * @return {Object|undefined} Layer object.
335613
+ */
335614
+ function readLayer (node, objectStack) {
335615
+ var parentLayerObject = /** @type {Object.<string,*>} */
335616
+ (objectStack[objectStack.length - 1]);
335617
+
335618
+ const layerObject = /** @type {Object.<string,*>} */
335619
+ (pushParseAndPop({}, LAYER_PARSERS,
335620
+ node, objectStack));
335621
+
335622
+ if (!isDef(layerObject)) return undefined;
335623
+
335624
+ let queryable = readBooleanString(node.getAttribute('queryable'));
335625
+ if (!isDef(queryable)) {
335626
+ queryable = parentLayerObject['queryable'];
335627
+ }
335628
+ layerObject['queryable'] = isDef(queryable) ? queryable : false;
335629
+
335630
+ let cascaded = readNonNegativeIntegerString(node.getAttribute('cascaded'));
335631
+ if (!isDef(cascaded)) {
335632
+ cascaded = parentLayerObject['cascaded'];
335633
+ }
335634
+ layerObject['cascaded'] = cascaded;
335635
+
335636
+ let opaque = readBooleanString(node.getAttribute('opaque'));
335637
+ if (!isDef(opaque)) {
335638
+ opaque = parentLayerObject['opaque'];
335639
+ }
335640
+ layerObject['opaque'] = isDef(opaque) ? opaque : false;
335641
+
335642
+ let noSubsets = readBooleanString(node.getAttribute('noSubsets'));
335643
+ if (!isDef(noSubsets)) {
335644
+ noSubsets = parentLayerObject['noSubsets'];
335645
+ }
335646
+ layerObject['noSubsets'] = isDef(noSubsets) ? noSubsets : false;
335647
+
335648
+ let fixedWidth = readDecimalString(node.getAttribute('fixedWidth'));
335649
+ if (!isDef(fixedWidth)) {
335650
+ fixedWidth = parentLayerObject['fixedWidth'];
335651
+ }
335652
+ layerObject['fixedWidth'] = fixedWidth;
335653
+
335654
+ let fixedHeight = readDecimalString(node.getAttribute('fixedHeight'));
335655
+ if (!isDef(fixedHeight)) {
335656
+ fixedHeight = parentLayerObject['fixedHeight'];
335657
+ }
335658
+ layerObject['fixedHeight'] = fixedHeight;
335659
+
335660
+ // See 7.2.4.8
335661
+ const addKeys = ['Style', 'CRS', 'AuthorityURL'];
335662
+ for (let i = 0, len = addKeys.length; i < len; i++) {
335663
+ const key = addKeys[i];
335664
+ const parentValue = parentLayerObject[key];
335665
+ if (isDef(parentValue)) {
335666
+ let childValue = setIfUndefined(layerObject, key, []);
335667
+ childValue = childValue.concat(parentValue);
335668
+ layerObject[key] = childValue;
335669
+ }
335670
+ }
335671
+
335672
+ const replaceKeys = ['EX_GeographicBoundingBox', 'BoundingBox', 'Dimension',
335673
+ 'Attribution', 'MinScaleDenominator', 'MaxScaleDenominator'
335674
+ ];
335675
+ for (let i = 0, len = replaceKeys.length; i < len; i++) {
335676
+ const key = replaceKeys[i];
335677
+ const childValue = layerObject[key];
335678
+ if (!isDef(childValue)) {
335679
+ const parentValue = parentLayerObject[key];
335680
+ layerObject[key] = parentValue;
335681
+ }
335682
+ }
335683
+
335684
+ return layerObject;
335685
+ }
335686
+
335687
+
335688
+ /**
335689
+ * @private
335690
+ * @param {Node} node Node.
335691
+ * @param {Array.<*>} objectStack Object stack.
335692
+ * @return {Object} Dimension object.
335693
+ */
335694
+ function readDimension (node, objectStack) {
335695
+ return {
335696
+ 'name': node.getAttribute('name'),
335697
+ 'units': node.getAttribute('units'),
335698
+ 'unitSymbol': node.getAttribute('unitSymbol'),
335699
+ 'default': node.getAttribute('default'),
335700
+ 'multipleValues': readBooleanString(node.getAttribute('multipleValues')),
335701
+ 'nearestValue': readBooleanString(node.getAttribute('nearestValue')),
335702
+ 'current': readBooleanString(node.getAttribute('current')),
335703
+ 'values': readString(node)
335704
+ };
335705
+ }
335706
+
335707
+
335708
+ /**
335709
+ * @private
335710
+ * @param {Node} node Node.
335711
+ * @param {Array.<*>} objectStack Object stack.
335712
+ * @return {Object|undefined} Online resource object.
335713
+ */
335714
+ function readFormatOnlineresource (node, objectStack) {
335715
+ return pushParseAndPop({}, FORMAT_ONLINERESOURCE_PARSERS,
335716
+ node, objectStack);
335717
+ }
335718
+
335719
+
335720
+ /**
335721
+ * @private
335722
+ * @param {Node} node Node.
335723
+ * @param {Array.<*>} objectStack Object stack.
335724
+ * @return {Object|undefined} Request object.
335725
+ */
335726
+ function readRequest (node, objectStack) {
335727
+ return pushParseAndPop({}, REQUEST_PARSERS, node, objectStack);
335728
+ }
335729
+
335730
+
335731
+ /**
335732
+ * @private
335733
+ * @param {Node} node Node.
335734
+ * @param {Array.<*>} objectStack Object stack.
335735
+ * @return {Object|undefined} DCP type object.
335736
+ */
335737
+ function readDCPType (node, objectStack) {
335738
+ return pushParseAndPop({}, DCPTYPE_PARSERS, node, objectStack);
335739
+ }
335740
+
335741
+
335742
+ /**
335743
+ * @private
335744
+ * @param {Node} node Node.
335745
+ * @param {Array.<*>} objectStack Object stack.
335746
+ * @return {Object|undefined} HTTP object.
335747
+ */
335748
+ function readHTTP (node, objectStack) {
335749
+ return pushParseAndPop({}, HTTP_PARSERS, node, objectStack);
335750
+ }
335751
+
335752
+
335753
+ /**
335754
+ * @private
335755
+ * @param {Node} node Node.
335756
+ * @param {Array.<*>} objectStack Object stack.
335757
+ * @return {Object|undefined} Operation type object.
335758
+ */
335759
+ function readOperationType (node, objectStack) {
335760
+ return pushParseAndPop({}, OPERATIONTYPE_PARSERS, node, objectStack);
335761
+ }
335762
+
335763
+
335764
+ /**
335765
+ * @private
335766
+ * @param {Node} node Node.
335767
+ * @param {Array.<*>} objectStack Object stack.
335768
+ * @return {Object|undefined} Online resource object.
335769
+ */
335770
+ function readSizedFormatOnlineresource (node, objectStack) {
335771
+ var formatOnlineresource = readFormatOnlineresource(node, objectStack);
335772
+ if (isDef(formatOnlineresource)) {
335773
+ const size = [
335774
+ readNonNegativeIntegerString(node.getAttribute('width')),
335775
+ readNonNegativeIntegerString(node.getAttribute('height'))
335776
+ ];
335777
+ formatOnlineresource['size'] = size;
335778
+ return formatOnlineresource;
335779
+ }
335780
+ return undefined;
335781
+ }
335782
+
335783
+
335784
+ /**
335785
+ * @private
335786
+ * @param {Node} node Node.
335787
+ * @param {Array.<*>} objectStack Object stack.
335788
+ * @return {Object|undefined} Authority URL object.
335789
+ */
335790
+ function readAuthorityURL (node, objectStack) {
335791
+ var authorityObject = readFormatOnlineresource(node, objectStack);
335792
+ if (isDef(authorityObject)) {
335793
+ authorityObject['name'] = node.getAttribute('name');
335794
+ return authorityObject;
335795
+ }
335796
+ return undefined;
335797
+ }
335798
+
335799
+
335800
+ /**
335801
+ * @private
335802
+ * @param {Node} node Node.
335803
+ * @param {Array.<*>} objectStack Object stack.
335804
+ * @return {Object|undefined} Metadata URL object.
335805
+ */
335806
+ function readMetadataURL (node, objectStack) {
335807
+ var metadataObject = readFormatOnlineresource(node, objectStack);
335808
+ if (isDef(metadataObject)) {
335809
+ metadataObject['type'] = node.getAttribute('type');
335810
+ return metadataObject;
335811
+ }
335812
+ return undefined;
335813
+ }
335814
+
335815
+
335816
+ /**
335817
+ * @private
335818
+ * @param {Node} node Node.
335819
+ * @param {Array.<*>} objectStack Object stack.
335820
+ * @return {Object|undefined} Style object.
335821
+ */
335822
+ function readStyle (node, objectStack) {
335823
+ return pushParseAndPop({}, STYLE_PARSERS, node, objectStack);
335824
+ }
335825
+
335826
+
335827
+ /**
335828
+ * @private
335829
+ * @param {Node} node Node.
335830
+ * @param {Array.<*>} objectStack Object stack.
335831
+ * @return {Array.<string>|undefined} Keyword list.
335832
+ */
335833
+ function readKeywordList (node, objectStack) {
335834
+ return pushParseAndPop(
335835
+ [], KEYWORDLIST_PARSERS, node, objectStack);
335836
+ }
335837
+
335838
+
335839
+ /**
335840
+ * @const
335841
+ * @type {Array.<string>}
335842
+ */
335843
+ const NAMESPACE_URIS = [
335844
+ null,
335845
+ 'http://www.opengis.net/wms'
335846
+ ];
335847
+
335848
+ /**
335849
+ * @const
335850
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335851
+ * @private
335852
+ */
335853
+ const PARSERS = makeParsersNS(
335854
+ NAMESPACE_URIS, {
335855
+ 'Service': makeObjectPropertySetter(readService),
335856
+ 'Capability': makeObjectPropertySetter(readCapability)
335857
+ });
335858
+
335859
+ /**
335860
+ * @const
335861
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335862
+ * @private
335863
+ */
335864
+ const CAPABILITY_PARSERS = makeParsersNS(
335865
+ NAMESPACE_URIS, {
335866
+ 'Request': makeObjectPropertySetter(readRequest),
335867
+ 'Exception': makeObjectPropertySetter(readException),
335868
+ 'Layer': makeObjectPropertySetter(readCapabilityLayer)
335869
+ });
335870
+
335871
+ /**
335872
+ * @const
335873
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335874
+ * @private
335875
+ */
335876
+ const SERVICE_PARSERS = makeParsersNS(
335877
+ NAMESPACE_URIS, {
335878
+ 'Name': makeObjectPropertySetter(readString),
335879
+ 'Title': makeObjectPropertySetter(readString),
335880
+ 'Abstract': makeObjectPropertySetter(readString),
335881
+ 'KeywordList': makeObjectPropertySetter(readKeywordList),
335882
+ 'OnlineResource': makeObjectPropertySetter(readHref),
335883
+ 'ContactInformation': makeObjectPropertySetter(readContactInformation),
335884
+ 'Fees': makeObjectPropertySetter(readString),
335885
+ 'AccessConstraints': makeObjectPropertySetter(readString),
335886
+ 'LayerLimit': makeObjectPropertySetter(readNonNegativeInteger),
335887
+ 'MaxWidth': makeObjectPropertySetter(readNonNegativeInteger),
335888
+ 'MaxHeight': makeObjectPropertySetter(readNonNegativeInteger)
335889
+ });
335890
+
335891
+ /**
335892
+ * @const
335893
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335894
+ * @private
335895
+ */
335896
+ const CONTACT_INFORMATION_PARSERS = makeParsersNS(
335897
+ NAMESPACE_URIS, {
335898
+ 'ContactPersonPrimary': makeObjectPropertySetter(readContactPersonPrimary),
335899
+ 'ContactPosition': makeObjectPropertySetter(readString),
335900
+ 'ContactAddress': makeObjectPropertySetter(readContactAddress),
335901
+ 'ContactVoiceTelephone': makeObjectPropertySetter(readString),
335902
+ 'ContactFacsimileTelephone': makeObjectPropertySetter(readString),
335903
+ 'ContactElectronicMailAddress': makeObjectPropertySetter(readString)
335904
+ });
335905
+
335906
+ /**
335907
+ * @const
335908
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335909
+ * @private
335910
+ */
335911
+ const CONTACT_PERSON_PARSERS = makeParsersNS(
335912
+ NAMESPACE_URIS, {
335913
+ 'ContactPerson': makeObjectPropertySetter(readString),
335914
+ 'ContactOrganization': makeObjectPropertySetter(readString)
335915
+ });
335916
+
335917
+
335918
+ /**
335919
+ * @const
335920
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335921
+ * @private
335922
+ */
335923
+ const CONTACT_ADDRESS_PARSERS = makeParsersNS(
335924
+ NAMESPACE_URIS, {
335925
+ 'AddressType': makeObjectPropertySetter(readString),
335926
+ 'Address': makeObjectPropertySetter(readString),
335927
+ 'City': makeObjectPropertySetter(readString),
335928
+ 'StateOrProvince': makeObjectPropertySetter(readString),
335929
+ 'PostCode': makeObjectPropertySetter(readString),
335930
+ 'Country': makeObjectPropertySetter(readString)
335931
+ });
335932
+
335933
+
335934
+ /**
335935
+ * @const
335936
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335937
+ * @private
335938
+ */
335939
+ const EXCEPTION_PARSERS = makeParsersNS(
335940
+ NAMESPACE_URIS, {
335941
+ 'Format': makeArrayPusher(readString)
335942
+ });
335943
+
335944
+
335945
+ /**
335946
+ * @const
335947
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335948
+ * @private
335949
+ */
335950
+ const LAYER_PARSERS = makeParsersNS(
335951
+ NAMESPACE_URIS, {
335952
+ 'Name': makeObjectPropertySetter(readString),
335953
+ 'Title': makeObjectPropertySetter(readString),
335954
+ 'Abstract': makeObjectPropertySetter(readString),
335955
+ 'KeywordList': makeObjectPropertySetter(readKeywordList),
335956
+ 'CRS': makeObjectPropertyPusher(readString),
335957
+ 'SRS': makeObjectPropertyPusher(readString),
335958
+ 'EX_GeographicBoundingBox': makeObjectPropertySetter(readEXGeographicBoundingBox),
335959
+ 'LatLonBoundingBox': makeObjectPropertySetter(readLatLonBoundingBox),
335960
+ 'BoundingBox': makeObjectPropertyPusher(readBoundingBox),
335961
+ 'Dimension': makeObjectPropertyPusher(readDimension),
335962
+ 'Attribution': makeObjectPropertySetter(readAttribution),
335963
+ 'AuthorityURL': makeObjectPropertyPusher(readAuthorityURL),
335964
+ 'Identifier': makeObjectPropertyPusher(readString),
335965
+ 'MetadataURL': makeObjectPropertyPusher(readMetadataURL),
335966
+ 'DataURL': makeObjectPropertyPusher(readFormatOnlineresource),
335967
+ 'FeatureListURL': makeObjectPropertyPusher(readFormatOnlineresource),
335968
+ 'Style': makeObjectPropertyPusher(readStyle),
335969
+ 'MinScaleDenominator': makeObjectPropertySetter(readDecimal),
335970
+ 'MaxScaleDenominator': makeObjectPropertySetter(readDecimal),
335971
+ 'ScaleHint': makeObjectPropertySetter(readScaleHint),
335972
+ 'Layer': makeObjectPropertyPusher(readLayer)
335973
+ });
335974
+
335975
+
335976
+ /**
335977
+ * @const
335978
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335979
+ * @private
335980
+ */
335981
+ const ATTRIBUTION_PARSERS = makeParsersNS(
335982
+ NAMESPACE_URIS, {
335983
+ 'Title': makeObjectPropertySetter(readString),
335984
+ 'OnlineResource': makeObjectPropertySetter(readHref),
335985
+ 'LogoURL': makeObjectPropertySetter(readSizedFormatOnlineresource)
335986
+ });
335987
+
335988
+
335989
+ /**
335990
+ * @const
335991
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
335992
+ * @private
335993
+ */
335994
+ const EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS =
335995
+ makeParsersNS(NAMESPACE_URIS, {
335996
+ 'westBoundLongitude': makeObjectPropertySetter(readDecimal),
335997
+ 'eastBoundLongitude': makeObjectPropertySetter(readDecimal),
335998
+ 'southBoundLatitude': makeObjectPropertySetter(readDecimal),
335999
+ 'northBoundLatitude': makeObjectPropertySetter(readDecimal)
336000
+ });
336001
+
336002
+
336003
+ /**
336004
+ * @const
336005
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
336006
+ * @private
336007
+ */
336008
+ const REQUEST_PARSERS = makeParsersNS(
336009
+ NAMESPACE_URIS, {
336010
+ 'GetCapabilities': makeObjectPropertySetter(
336011
+ readOperationType),
336012
+ 'GetMap': makeObjectPropertySetter(
336013
+ readOperationType),
336014
+ 'GetFeatureInfo': makeObjectPropertySetter(
336015
+ readOperationType)
336016
+ });
336017
+
336018
+
336019
+ /**
336020
+ * @const
336021
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
336022
+ * @private
336023
+ */
336024
+ const OPERATIONTYPE_PARSERS = makeParsersNS(
336025
+ NAMESPACE_URIS, {
336026
+ 'Format': makeObjectPropertyPusher(readString),
336027
+ 'DCPType': makeObjectPropertyPusher(
336028
+ readDCPType)
336029
+ });
336030
+
336031
+
336032
+ /**
336033
+ * @const
336034
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
336035
+ * @private
336036
+ */
336037
+ const DCPTYPE_PARSERS = makeParsersNS(
336038
+ NAMESPACE_URIS, {
336039
+ 'HTTP': makeObjectPropertySetter(
336040
+ readHTTP)
336041
+ });
336042
+
336043
+
336044
+ /**
336045
+ * @const
336046
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
336047
+ * @private
336048
+ */
336049
+ const HTTP_PARSERS = makeParsersNS(
336050
+ NAMESPACE_URIS, {
336051
+ 'Get': makeObjectPropertySetter(
336052
+ readFormatOnlineresource),
336053
+ 'Post': makeObjectPropertySetter(
336054
+ readFormatOnlineresource)
336055
+ });
336056
+
336057
+
336058
+ /**
336059
+ * @const
336060
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
336061
+ * @private
336062
+ */
336063
+ const STYLE_PARSERS = makeParsersNS(
336064
+ NAMESPACE_URIS, {
336065
+ 'Name': makeObjectPropertySetter(readString),
336066
+ 'Title': makeObjectPropertySetter(readString),
336067
+ 'Abstract': makeObjectPropertySetter(readString),
336068
+ 'LegendURL': makeObjectPropertyPusher(readSizedFormatOnlineresource),
336069
+ 'StyleSheetURL': makeObjectPropertySetter(readFormatOnlineresource),
336070
+ 'StyleURL': makeObjectPropertySetter(readFormatOnlineresource)
336071
+ });
336072
+
336073
+
336074
+ /**
336075
+ * @const
336076
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
336077
+ * @private
336078
+ */
336079
+ const FORMAT_ONLINERESOURCE_PARSERS = makeParsersNS(
336080
+ NAMESPACE_URIS, {
336081
+ 'Format': makeObjectPropertySetter(readString),
336082
+ 'OnlineResource': makeObjectPropertySetter(readHref)
336083
+ });
336084
+
336085
+
336086
+ /**
336087
+ * @const
336088
+ * @type {Object.<string, Object.<string, XMLParser.Parser>>}
336089
+ * @private
336090
+ */
336091
+ const KEYWORDLIST_PARSERS = makeParsersNS(
336092
+ NAMESPACE_URIS, {
336093
+ 'Keyword': makeArrayPusher(readString)
336094
+ });
336095
+
336096
+ class WMS {
336097
+ /**
336098
+ * WMS Capabilities parser
336099
+ *
336100
+ * @param {String=} xmlString
336101
+ * @constructor
336102
+ */
336103
+ constructor(xmlString, DOMParser) {
336104
+ if (!DOMParser && typeof window !== 'undefined') {
336105
+ DOMParser = window.DOMParser;
336106
+ }
336107
+
336108
+ /**
336109
+ * @type {String}
336110
+ */
336111
+ this.version = undefined;
336112
+
336113
+ /**
336114
+ * @type {XMLParser}
336115
+ */
336116
+ this._parser = new XMLParser(DOMParser);
336117
+
336118
+ /**
336119
+ * @type {String=}
336120
+ */
336121
+ this._data = xmlString;
336122
+ }
336123
+
336124
+
336125
+ /**
336126
+ * @param {String} xmlString
336127
+ * @return {WMS}
336128
+ */
336129
+ data (xmlString) {
336130
+ this._data = xmlString;
336131
+ return this;
336132
+ }
336133
+
336134
+ /**
336135
+ * @param {String=} xmlString
336136
+ * @return {Object|null}
336137
+ */
336138
+ toJSON (xmlString) {
336139
+ xmlString = xmlString || this._data;
336140
+ return this.parse(xmlString);
336141
+ }
336142
+
336143
+ /**
336144
+ * @return {String} xml
336145
+ * @return {Object|null}
336146
+ */
336147
+ parse (xmlString) {
336148
+ return this.readFromDocument(this._parser.toDocument(xmlString));
336149
+ }
336150
+
336151
+ /**
336152
+ * @param {Document} doc
336153
+ * @return {Object|null}
336154
+ */
336155
+ readFromDocument (doc) {
336156
+ for (let node = doc.firstChild; node; node = node.nextSibling) {
336157
+ if (node.nodeType == NODE_TYPES.ELEMENT) {
336158
+ return this.readFromNode(node);
336159
+ }
336160
+ }
336161
+ return null;
336162
+ }
336163
+
336164
+ /**
336165
+ * @param {DOMNode} node
336166
+ * @return {Object}
336167
+ */
336168
+ readFromNode (node) {
336169
+ this.version = node.getAttribute('version');
336170
+ const wmsCapabilityObject = pushParseAndPop({
336171
+ 'version': this.version
336172
+ }, PARSERS, node, []);
336173
+
336174
+ return wmsCapabilityObject || null;
336175
+ }
336176
+ }
336177
+
336178
+
336179
+ //# sourceMappingURL=wms-capabilities.mjs.map
336180
+
336181
+
334351
336182
  /***/ },
334352
336183
 
334353
336184
  /***/ "../../core/frontend/package.json"
@@ -334357,7 +336188,7 @@ var loadLanguages = instance.loadLanguages;
334357
336188
  (module) {
334358
336189
 
334359
336190
  "use strict";
334360
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.13.0-dev.9","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/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@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-multiple-assets":"^1.3.1","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"}}');
336191
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.14.0-dev.1","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.6.0"}}');
334361
336192
 
334362
336193
  /***/ }
334363
336194