azure-maps-control 2.1.14 → 2.1.17

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.
@@ -72,6 +72,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
72
72
  apiVersionQueryParameter: "api-version",
73
73
  authorizationHeaderName: "Authorization",
74
74
  authorizationTokenPrefix: "Bearer ",
75
+ jwtSasPrefix: "jwt-sas ",
75
76
  domainPlaceHolder: "{{azMapsDomain}}",
76
77
  legacyDomainPlaceHolder: "{azMapsDomain}",
77
78
  viewPlaceHolder: "{{azMapsView}}",
@@ -342,7 +343,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
342
343
  return Url;
343
344
  }());
344
345
 
345
- var version = "2.1.14";
346
+ var version = "2.1.17";
346
347
 
347
348
  /**
348
349
  * A helper class that provides methods for getting various forms of the map controls current version.
@@ -700,7 +701,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
700
701
  delete this._container;
701
702
  }
702
703
  if (this._map) {
703
- this._map.events.remove("styledata", this._onStyleChange);
704
+ this._map.events.remove("stylechanged", this._onStyleChange);
704
705
  delete this._map;
705
706
  }
706
707
  if (this._observer) {
@@ -724,7 +725,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
724
725
  if (style.toLowerCase() === exports.ControlStyle.auto) {
725
726
  this._map.styles.definitions().then(function (definitions) {
726
727
  if (_this._map) {
727
- _this._map.events.add("styledata", _this._onStyleChange);
728
+ _this._map.events.add("stylechanged", _this._onStyleChange);
728
729
  }
729
730
  });
730
731
  }
@@ -837,6 +838,15 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
837
838
  }
838
839
  }
839
840
  });
841
+ // Keep the focus on this control when esc key is pressed on the grid
842
+ grid.addEventListener("keydown", function (event) {
843
+ if (event.key === "Escape" || event.key === "Esc") {
844
+ event.stopPropagation();
845
+ rotationButton.focus();
846
+ container.classList.remove("in-use");
847
+ grid.classList.add("hidden-accessible-element");
848
+ }
849
+ });
840
850
  // If the control's position will require inverting the element order
841
851
  // add them in the opposite order to preserve tabindex.
842
852
  if (options && CompassControl.InvertOrderPositions.includes(options.position)) {
@@ -984,6 +994,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
984
994
  var _this = _super.call(this) || this;
985
995
  _this.container = null;
986
996
  _this.map = null;
997
+ _this.pitchButton = null;
987
998
  _this.pitchIncrementButton = null;
988
999
  _this.pitchDecrementButton = null;
989
1000
  _this.hasMouse = false;
@@ -992,6 +1003,10 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
992
1003
  _this.updatePitchButtonsState = function () {
993
1004
  var minPitchReached = _this.map.getCamera().pitch <= 0;
994
1005
  var maxPitchReached = _this.map.getCamera().pitch >= 60;
1006
+ // Keep the focus on this control when max/min pitch is reached
1007
+ if (_this.hasFocus && _this.pitchButton && (minPitchReached || maxPitchReached)) {
1008
+ _this.pitchButton.focus();
1009
+ }
995
1010
  if (_this.options.inverted) {
996
1011
  if (_this.pitchIncrementButton && _this.pitchIncrementButton.disabled != minPitchReached) {
997
1012
  _this.pitchIncrementButton.disabled = minPitchReached;
@@ -1054,6 +1069,15 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
1054
1069
  }
1055
1070
  }
1056
1071
  });
1072
+ // Keep the focus on this control when esc key is pressed on the grid
1073
+ grid.addEventListener("keydown", function (event) {
1074
+ if (event.key === "Escape" || event.key === "Esc") {
1075
+ event.stopPropagation();
1076
+ pitchButton.focus();
1077
+ container.classList.remove("in-use");
1078
+ grid.classList.add("hidden-accessible-element");
1079
+ }
1080
+ });
1057
1081
  // If the control's position will require inverting the element order
1058
1082
  // add them in the opposite order to preserve tabindex.
1059
1083
  if (options && PitchControl.INVERT_ORDER_POSITIONS.includes(options.position)) {
@@ -1070,6 +1094,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
1070
1094
  }
1071
1095
  this.map = map;
1072
1096
  this.container = container;
1097
+ this.pitchButton = pitchButton;
1073
1098
  map.events.add('pitch', this.pitchChanged);
1074
1099
  this.updatePitchButtonsState();
1075
1100
  return container;
@@ -1078,6 +1103,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
1078
1103
  if (this.container) {
1079
1104
  this.container.remove();
1080
1105
  this.container = null;
1106
+ this.pitchButton = null;
1081
1107
  this.pitchIncrementButton = null;
1082
1108
  this.pitchDecrementButton = null;
1083
1109
  }
@@ -4450,7 +4476,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4450
4476
  _super.prototype.onRemove.call(this);
4451
4477
  this.styleOpsGrid = null;
4452
4478
  this.styleButtons.clear();
4453
- this.map.events.remove("styledata", this.onStyleChange);
4479
+ this.map.events.remove("stylechanged", this.onStyleChange);
4454
4480
  this.map.events.remove("stylesetchanged", this.onStylesetChange);
4455
4481
  };
4456
4482
  /**
@@ -4505,7 +4531,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4505
4531
  var _this = this;
4506
4532
  var styleOptionButton = document.createElement("button");
4507
4533
  var friendlyName = this.mapToFriendlyStyleName(name, styleset);
4508
- styleOptionButton.setAttribute("alt", friendlyName);
4534
+ styleOptionButton.setAttribute("aria-label", friendlyName);
4509
4535
  styleOptionButton.setAttribute("type", "button");
4510
4536
  var styleIconImage = new Image();
4511
4537
  fetchIconPromise
@@ -4525,9 +4551,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4525
4551
  }
4526
4552
  _this.styleIcons.set(name, iconUrl);
4527
4553
  });
4528
- if (this.options.layout === "icons") {
4529
- styleIconImage.alt = friendlyName;
4530
- }
4554
+ styleIconImage.setAttribute("aria-hidden", "true");
4531
4555
  styleOptionButton.appendChild(styleIconImage);
4532
4556
  if (this.options.layout === "icons") {
4533
4557
  styleOptionButton.classList.add(StyleControl.Css.button);
@@ -4567,7 +4591,6 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4567
4591
  }
4568
4592
  selectCurrButton.classList.add(StyleControl.Css.currentStyle);
4569
4593
  selectCurrButton.setAttribute("aria-label", "Select Style");
4570
- selectCurrButton.setAttribute("alt", "Select Style");
4571
4594
  selectCurrButton.setAttribute("tabindex", "-1");
4572
4595
  this.currStyleImage = new Image();
4573
4596
  selectCurrButton.appendChild(this.currStyleImage);
@@ -4593,7 +4616,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4593
4616
  this.map.styles.definitions().then(function (definitions) { return __awaiter(_this, void 0, void 0, function () {
4594
4617
  return __generator(this, function (_a) {
4595
4618
  this.onStylesetChange(definitions);
4596
- this.map.events.add("styledata", this.onStyleChange);
4619
+ this.map.events.add("stylechanged", this.onStyleChange);
4597
4620
  return [2 /*return*/];
4598
4621
  });
4599
4622
  }); });
@@ -4782,6 +4805,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4782
4805
  return this.container;
4783
4806
  };
4784
4807
  TrafficControl.prototype.onRemove = function () {
4808
+ _super.prototype.onRemove.call(this);
4785
4809
  this.map = null;
4786
4810
  };
4787
4811
  /**
@@ -4842,6 +4866,8 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4842
4866
  _this.table = ["Fast",
4843
4867
  ["green", "yellow", "red", "dark-red"],
4844
4868
  "Slow"];
4869
+ _this.map = null;
4870
+ _this.syncHiddenState = null;
4845
4871
  return _this;
4846
4872
  }
4847
4873
  /**
@@ -4851,11 +4877,21 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4851
4877
  * @return An HTMLElement to be placed on the map for the control.
4852
4878
  */
4853
4879
  TrafficLegendControl.prototype.onAdd = function (map) {
4880
+ this.map = map;
4854
4881
  var container = this.buildContainer(map, exports.ControlStyle.auto, "Traffic Legend");
4855
4882
  var TrafficLegendDiv = this.buildTrafficLegendDiv(map);
4883
+ container.setAttribute("role", "definition");
4856
4884
  container.appendChild(TrafficLegendDiv);
4857
4885
  return container;
4858
4886
  };
4887
+ TrafficLegendControl.prototype.onRemove = function () {
4888
+ _super.prototype.onRemove.call(this);
4889
+ if (this.syncHiddenState) {
4890
+ this.map.events.remove('styledata', this.syncHiddenState);
4891
+ this.syncHiddenState = null;
4892
+ }
4893
+ this.map = null;
4894
+ };
4859
4895
  TrafficLegendControl.prototype.buildTrafficLegendDiv = function (map) {
4860
4896
  var e_1, _a, e_2, _b;
4861
4897
  var trafficLegend = document.createElement("div");
@@ -4920,8 +4956,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4920
4956
  }
4921
4957
  trafficLegendTable.appendChild(tr2);
4922
4958
  trafficLegend.appendChild(trafficLegendTable);
4923
- // display legend when the traffic flow is shown, hide it otherwise
4924
- map.events.add("styledata", function (eventData) {
4959
+ this.syncHiddenState = function (eventData) {
4925
4960
  if (eventData.dataType === "style") {
4926
4961
  var trafficOptions = map.getTraffic();
4927
4962
  if (trafficOptions.flow && trafficOptions.flow !== "none") {
@@ -4931,7 +4966,10 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
4931
4966
  trafficLegend.classList.add("hidden");
4932
4967
  }
4933
4968
  }
4934
- });
4969
+ };
4970
+ // display legend when the traffic flow is shown, hide it otherwise
4971
+ this.syncHiddenState({ dataType: 'style' });
4972
+ map.events.add("styledata", this.syncHiddenState);
4935
4973
  return trafficLegend;
4936
4974
  };
4937
4975
  return TrafficLegendControl;
@@ -12762,6 +12800,12 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
12762
12800
  // They must use setOptions(...).
12763
12801
  return cloneDeepWith_1(this.options, PopupOptions._cloneCustomizer);
12764
12802
  };
12803
+ /**
12804
+ * Returns popup container element.
12805
+ */
12806
+ Popup.prototype.getPopupContainer = function () {
12807
+ return this.containerDiv;
12808
+ };
12765
12809
  /**
12766
12810
  * Drags the popup to the specified pixel.
12767
12811
  * Accounts for the pixel offset when dragging started.
@@ -13791,6 +13835,11 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
13791
13835
  * Literal value `"anonymous"`
13792
13836
  */
13793
13837
  AuthenticationType["anonymous"] = "anonymous";
13838
+ /**
13839
+ * The shared access signature authentication mechanism. Allows a callback responsible for acquiring a token to be provided on requests.
13840
+ * Literal value `"sas"`.
13841
+ */
13842
+ AuthenticationType["sas"] = "sas";
13794
13843
  })(exports.AuthenticationType || (exports.AuthenticationType = {}));
13795
13844
  /**
13796
13845
  * Options for specifying how the map control should authenticate with the Azure Maps services.
@@ -13830,11 +13879,15 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
13830
13879
  */
13831
13880
  _this.aadInstance = undefined;
13832
13881
  /**
13833
- * A callback to use with the anonymous authentication mechanism.
13882
+ * A callback to use with the anonymous/sas authentication mechanism.
13834
13883
  * This callback will be responsible for resolving to a authentication token.
13835
13884
  * E.g. fetching a CORS protected token from an endpoint.
13836
13885
  */
13837
13886
  _this.getToken = undefined;
13887
+ /**
13888
+ * Optionally provide an initial token for sas authentication.
13889
+ */
13890
+ _this.sasToken = undefined;
13838
13891
  /**
13839
13892
  * Optionally provide an existing `AuthenticationContext` from the ADAL.js library.
13840
13893
  * This authentication context will be used to acquire the AAD token.
@@ -13877,6 +13930,14 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
13877
13930
  this.authType = exports.AuthenticationType.anonymous;
13878
13931
  this.getToken = getTokenCallback;
13879
13932
  };
13933
+ /**
13934
+ * Sets the required options to configure the sas authentication method.
13935
+ * @param getTokenCallback Callback function responsible for resolving to an authentication token.
13936
+ */
13937
+ AuthenticationOptions.prototype.setSasCallbackFunction = function (getTokenCallback) {
13938
+ this.authType = exports.AuthenticationType.sas;
13939
+ this.getToken = getTokenCallback;
13940
+ };
13880
13941
  /**
13881
13942
  * Override the standard merge behavior to handle mutually exclusive options.
13882
13943
  * @internal
@@ -13896,6 +13957,9 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
13896
13957
  else if (merged.authType === exports.AuthenticationType.anonymous) {
13897
13958
  merged.subscriptionKey = merged.authContext = merged.aadAppId = undefined;
13898
13959
  }
13960
+ else if (merged.authType === exports.AuthenticationType.sas) {
13961
+ merged.authContext = merged.subscriptionKey = merged.aadAppId = undefined;
13962
+ }
13899
13963
  return merged;
13900
13964
  };
13901
13965
  return AuthenticationOptions;
@@ -14622,7 +14686,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
14622
14686
  path: "search/address/reverse/json",
14623
14687
  queryParams: __assign({ "api-version": "1.0", "language": options.style.language, "limit": 1, "query": normalizeLatitude(options.position[1]) + "," + normalizeLongitude(options.position[0]) }, (options.style.view && { view: options.style.view }))
14624
14688
  };
14625
- return new Url((_a = this.map.authentication) === null || _a === void 0 ? void 0 : _a.signRequest(urlOptions)).get();
14689
+ return new Url(((_a = this.map.authentication) === null || _a === void 0 ? void 0 : _a.signRequest(urlOptions)) || urlOptions).get();
14626
14690
  };
14627
14691
  return NearbyGeographySearchService;
14628
14692
  }());
@@ -15826,8 +15890,10 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
15826
15890
  _this.createMapKeyBindingInfo();
15827
15891
  _this.map.getMapContainer().setAttribute("role", "application");
15828
15892
  _this.map.getMapContainer().setAttribute("aria-label", "Map Application");
15893
+ _this.map.getCanvasContainer().setAttribute("aria-live", "polite");
15894
+ _this.map.getCanvasContainer().setAttribute("aria-describedby", "atlas-map-state atlas-map-style");
15829
15895
  _this.map.getCanvas().setAttribute("aria-label", "Interactive Map");
15830
- _this.map.getCanvas().setAttribute("aria-describedby", "atlas-map-state atlas-map-style atlas-map-shortcuts");
15896
+ _this.map.getCanvas().setAttribute("aria-describedby", "atlas-map-shortcuts");
15831
15897
  _this.map.getCanvas().setAttribute("alt", "Interactive Map");
15832
15898
  };
15833
15899
  this.removeFromMap = function () {
@@ -15849,10 +15915,12 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
15849
15915
  delete _this.atlasMapStyleInfo;
15850
15916
  _this.map.getMapContainer().removeAttribute("role");
15851
15917
  _this.map.getMapContainer().removeAttribute("aria-label");
15918
+ _this.map.getCanvasContainer().removeAttribute("aria-live");
15919
+ _this.map.getCanvasContainer().removeAttribute("aria-describedby");
15852
15920
  _this.map.getCanvas().removeAttribute("aria-label");
15853
15921
  _this.map.getCanvas().removeAttribute("aria-describedby");
15854
15922
  _this.map.getCanvas().removeAttribute("alt");
15855
- _this.map.events.remove("styledata", _this.updateMapStyle);
15923
+ _this.map.events.remove("stylechanged", _this.updateMapStyle);
15856
15924
  };
15857
15925
  this.createMapKeyBindingInfo = function () {
15858
15926
  _this.atlasMapKeyBindings = document.createElement("div");
@@ -15877,7 +15945,6 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
15877
15945
  "Jump focus to the map: Escape."
15878
15946
  ].join("\n");
15879
15947
  _this.map.getCanvasContainer().appendChild(_this.atlasMapKeyBindings);
15880
- _this.atlasMapKeyBindings.setAttribute("aria-live", "polite");
15881
15948
  var baseShortcutKeyCodes = [
15882
15949
  // - (zoom out)
15883
15950
  189,
@@ -15909,7 +15976,6 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
15909
15976
  _this.atlasMapLiveStateInfo.id = "atlas-map-state";
15910
15977
  _this.atlasMapLiveStateInfo.classList.add("hidden-accessible-element");
15911
15978
  _this.map.getCanvasContainer().appendChild(_this.atlasMapLiveStateInfo);
15912
- _this.atlasMapLiveStateInfo.setAttribute("aria-live", "assertive");
15913
15979
  }
15914
15980
  };
15915
15981
  this.initializeMapStyleInfo = function () {
@@ -15918,10 +15984,8 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
15918
15984
  _this.atlasMapStyleInfo.setAttribute("aria-hidden", "true");
15919
15985
  _this.atlasMapStyleInfo.id = "atlas-map-style";
15920
15986
  _this.atlasMapStyleInfo.classList.add("hidden-accessible-element");
15921
- _this.updateMapStyle();
15922
- _this.map.events.add("styledata", _this.updateMapStyle);
15987
+ _this.map.events.add("stylechanged", _this.updateMapStyle);
15923
15988
  _this.map.getCanvasContainer().appendChild(_this.atlasMapStyleInfo);
15924
- _this.atlasMapStyleInfo.setAttribute("aria-live", "polite");
15925
15989
  };
15926
15990
  this.updateMapStyle = function () {
15927
15991
  _this.atlasMapStyleInfo.innerHTML = "<p>Map style: " + _this.map.getStyle().style + ".</p>";
@@ -16219,15 +16283,106 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
16219
16283
  _this.map.layers.add(_this.incidentLayer, "labels");
16220
16284
  }
16221
16285
  //Create a popup but leave it closed so we can update it and display it later.
16222
- _this.popup = new Popup({
16286
+ _this.clickPopup = new Popup({
16223
16287
  position: [0, 0],
16224
16288
  pixelOffset: [0, -18]
16225
16289
  });
16226
16290
  _this.map.addEventListener("mouseover", _this.incidentLayerName, _this.cursorToPointer);
16227
16291
  _this.map.addEventListener("mouseleave", _this.incidentLayerName, _this.cursorToDefault);
16228
16292
  _this.map.addEventListener("click", _this.incidentLayerName, _this.openIncidentPopup);
16293
+ _this.map.events.addOnce('idle', _this.setAccessiblePopups);
16294
+ _this.map.events.add('moveend', _this.setAccessiblePopups);
16229
16295
  };
16296
+ this.accessiblePopups = [];
16297
+ this.setAccessiblePopups = function () { return __awaiter(_this, void 0, void 0, function () {
16298
+ var features, localizedStrings, createPopup, insertHiddenBefore, insertHiddenInFront, addHidden;
16299
+ var _this = this;
16300
+ return __generator(this, function (_a) {
16301
+ switch (_a.label) {
16302
+ case 0:
16303
+ this.accessiblePopups.forEach(function (popup) { return popup.remove(); });
16304
+ this.accessiblePopups = [];
16305
+ features = this.map.layers.getRenderedShapes(this.map.getCamera().bounds, this.incidentLayer);
16306
+ return [4 /*yield*/, this.map._getLocalizedStrings()];
16307
+ case 1:
16308
+ localizedStrings = _a.sent();
16309
+ createPopup = function (features, idx) {
16310
+ var incidentFeature = features[idx];
16311
+ var incidentPosition = incidentFeature.geometry.coordinates;
16312
+ var point = new Point(new Position(incidentPosition[0], incidentPosition[1]));
16313
+ var incident = new Incident(incidentFeature.properties, point, localizedStrings);
16314
+ var popup = IncidentPopupFactory.build(incident, _this.incidentLanguage);
16315
+ var element = popup.getPopupContainer();
16316
+ element.addEventListener('focusin', function (event) {
16317
+ // side effects: clear other managed popups
16318
+ _this.clickPopup.remove();
16319
+ _this.accessiblePopups.filter(function (p) { return p !== popup; }).forEach(function (popup) { return popup.remove(); });
16320
+ // insert previous and next popups
16321
+ if (idx - 1 >= 0) {
16322
+ insertHiddenBefore(popup, createPopup(features, idx - 1));
16323
+ }
16324
+ if (idx + 1 < features.length) {
16325
+ addHidden(createPopup(features, idx + 1));
16326
+ }
16327
+ // if we are on boundaries: add the first / last popup
16328
+ // to maintain popups on full page navigation cycle
16329
+ if (idx >= 2 && idx == features.length - 1) {
16330
+ insertHiddenInFront(createPopup(features, 0));
16331
+ }
16332
+ if (idx == 0 && features.length >= 2) {
16333
+ addHidden(createPopup(features, features.length - 1));
16334
+ }
16335
+ });
16336
+ if (idx == features.length - 1) {
16337
+ element.addEventListener('focusout', function (event) {
16338
+ // close the popup if we detect the focus moving away from the page (relatedTarget === null)
16339
+ // (will remain open otherwise)
16340
+ if (event.relatedTarget === null) {
16341
+ popup.close();
16342
+ }
16343
+ });
16344
+ }
16345
+ _this.accessiblePopups.push(popup);
16346
+ return popup;
16347
+ };
16348
+ insertHiddenBefore = function (base, toInsert) {
16349
+ toInsert.open(_this.map);
16350
+ toInsert.close();
16351
+ var containerToSwapIn = toInsert.getPopupContainer();
16352
+ var baseContainer = base.getPopupContainer();
16353
+ baseContainer.parentElement.insertBefore(containerToSwapIn, baseContainer);
16354
+ };
16355
+ insertHiddenInFront = function (toInsert) {
16356
+ toInsert.open(_this.map);
16357
+ toInsert.close();
16358
+ var containerToSwapIn = toInsert.getPopupContainer();
16359
+ var parent = containerToSwapIn.parentElement;
16360
+ parent.insertBefore(containerToSwapIn, parent.firstElementChild);
16361
+ };
16362
+ addHidden = function (popup) {
16363
+ popup.open(_this.map);
16364
+ popup.close();
16365
+ };
16366
+ if (features.length > 0) {
16367
+ addHidden(createPopup(features, 0));
16368
+ }
16369
+ if (features.length > 1) {
16370
+ addHidden(createPopup(features, features.length - 1));
16371
+ }
16372
+ return [2 /*return*/];
16373
+ }
16374
+ });
16375
+ }); };
16230
16376
  this.removeFromMap = function () {
16377
+ var _a;
16378
+ _this.map.removeEventListener("mouseover", _this.incidentLayerName, _this.cursorToPointer);
16379
+ _this.map.removeEventListener("mouseleave", _this.incidentLayerName, _this.cursorToDefault);
16380
+ _this.map.removeEventListener("click", _this.incidentLayerName, _this.openIncidentPopup);
16381
+ _this.map.events.remove('idle', _this.setAccessiblePopups);
16382
+ _this.map.events.remove('moveend', _this.setAccessiblePopups);
16383
+ _this.accessiblePopups.forEach(function (popup) { return popup.remove(); });
16384
+ _this.accessiblePopups = [];
16385
+ (_a = _this.clickPopup) === null || _a === void 0 ? void 0 : _a.remove();
16231
16386
  if (_this.map.layers.getLayerById(_this.incidentLayerName) != null) {
16232
16387
  _this.map.layers.remove(_this.incidentLayerName);
16233
16388
  }
@@ -16242,14 +16397,22 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
16242
16397
  _this.map.getCanvas().style.cursor = "";
16243
16398
  };
16244
16399
  this.openIncidentPopup = function (data) {
16245
- _this.popup.remove();
16400
+ _this.clickPopup.remove();
16401
+ _this.accessiblePopups.forEach(function (popup) { return popup.close(); });
16246
16402
  var incidentPosition = data.position;
16247
16403
  var incidentFeature = data.features[0];
16248
16404
  _this.map._getLocalizedStrings().then(function (localizedStrings) {
16249
16405
  var point = new Point(new Position(incidentPosition[0], incidentPosition[1]));
16250
16406
  var incident = new Incident(incidentFeature.properties, point, localizedStrings);
16251
- _this.popup = IncidentPopupFactory.build(incident, _this.incidentLanguage);
16252
- _this.popup.open(_this.map);
16407
+ _this.clickPopup = IncidentPopupFactory.build(incident, _this.incidentLanguage);
16408
+ _this.clickPopup.open(_this.map);
16409
+ var element = _this.clickPopup.getPopupContainer();
16410
+ // ensures popup is closed on tabbing when the focus is moved away from the window
16411
+ element.addEventListener('focusout', function (event) {
16412
+ if (event.relatedTarget === null) {
16413
+ _this.clickPopup.close();
16414
+ }
16415
+ });
16253
16416
  });
16254
16417
  };
16255
16418
  this.map = map;
@@ -21957,17 +22120,19 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
21957
22120
  * Triggers the user provided function to fetch the token and stores it.
21958
22121
  * @internal
21959
22122
  */
21960
- this._triggerTokenFetch = function () {
22123
+ this._triggerTokenFetch = function (isAnonymousAuth) {
22124
+ if (isAnonymousAuth === void 0) { isAnonymousAuth = false; }
21961
22125
  return new Promise(function (resolve, reject) {
22126
+ if (typeof _this.options.getToken !== "function") {
22127
+ reject(new Error("Token cannot be " + (isAnonymousAuth ? 'fetched' : 'renewed') + " because getToken was not set or is not a function."));
22128
+ return;
22129
+ }
21962
22130
  _this.options.getToken(function (token) {
21963
22131
  try {
21964
22132
  // Try to get the timeout first as this will guarantee the token is correctly formatted.
21965
22133
  var timeout = _this._getTokenExpiry(token) - AuthenticationManager.constants.tokenRefreshClockSkew;
21966
- _this._storeAccessToken(token);
21967
- clearTimeout(_this.tokenTimeOutHandle); // Clear the previous refresh timeout in case it hadn't triggered yet.
21968
- // @ts-ignore
21969
- // tslint:disable-next-line: no-string-based-set-timeout
21970
- _this.tokenTimeOutHandle = setTimeout(_this._triggerTokenFetch, timeout * 1000);
22134
+ _this._storeToken(token);
22135
+ _this._setTimeoutTokenFetch(timeout);
21971
22136
  resolve();
21972
22137
  }
21973
22138
  catch (_a) {
@@ -21978,6 +22143,18 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
21978
22143
  }, _this.map);
21979
22144
  });
21980
22145
  };
22146
+ /**
22147
+ * Create a timer to trigger the user provided function to fetch the token.
22148
+ * @param seconds delay in seconds
22149
+ * @internal
22150
+ */
22151
+ this._setTimeoutTokenFetch = function (seconds) {
22152
+ clearTimeout(_this.tokenTimeOutHandle); // Clear the previous refresh timeout in case it hadn't triggered yet.
22153
+ // @ts-ignore
22154
+ // tslint:disable-next-line: no-string-based-set-timeout
22155
+ _this.tokenTimeOutHandle = setTimeout(_this._triggerTokenFetch, Math.min(seconds * 1000, 0x7fffffff) // setTimeout will fire immediately if the delay is greater than 2^31-1.
22156
+ );
22157
+ };
21981
22158
  var serviceOptions = map.getServiceOptions();
21982
22159
  this.options = serviceOptions.authOptions;
21983
22160
  this.sessionId = serviceOptions.sessionId;
@@ -22019,6 +22196,28 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
22019
22196
  }
22020
22197
  else if (_this.options.authType === exports.AuthenticationType.anonymous) {
22021
22198
  // Anonymous authentication, just call the users provided callback.
22199
+ resolve(_this._triggerTokenFetch(true));
22200
+ }
22201
+ else if (_this.options.authType === exports.AuthenticationType.sas) {
22202
+ if (_this.options.sasToken) {
22203
+ var expiresIn = -1;
22204
+ try {
22205
+ expiresIn = _this._getTokenExpiry(_this.options.sasToken);
22206
+ }
22207
+ catch (_a) {
22208
+ reject(new Error("An invalid sasToken was provided."));
22209
+ return;
22210
+ }
22211
+ if (expiresIn > AuthenticationManager.constants.tokenRefreshClockSkew) {
22212
+ // Save the initial token
22213
+ _this._storeToken(_this.options.sasToken);
22214
+ // Create a timer to refresh the token
22215
+ _this._setTimeoutTokenFetch(expiresIn - AuthenticationManager.constants.tokenRefreshClockSkew);
22216
+ resolve();
22217
+ return;
22218
+ }
22219
+ }
22220
+ // Call the users provided callback to fetch the token.
22022
22221
  resolve(_this._triggerTokenFetch());
22023
22222
  }
22024
22223
  else {
@@ -22144,8 +22343,9 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
22144
22343
  }
22145
22344
  return token_1;
22146
22345
  }
22147
- else if (this.options.authType === exports.AuthenticationType.anonymous) {
22148
- var token = this._getItem(AuthenticationManager.constants.storage.accessTokenKey);
22346
+ else if (this.options.authType === exports.AuthenticationType.anonymous
22347
+ || this.options.authType === exports.AuthenticationType.sas) {
22348
+ var token = this._getItem(AuthenticationManager.constants.storage.tokenKey);
22149
22349
  if (!token) {
22150
22350
  // Cached Token not present, invoke the user provided callback function to fetch function
22151
22351
  this._triggerTokenFetch();
@@ -22160,7 +22360,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
22160
22360
  }
22161
22361
  else if (expiresIn <= 0) {
22162
22362
  // token renew failed and dont have a token.
22163
- this._saveItem(AuthenticationManager.constants.storage.accessTokenKey, "");
22363
+ this._saveItem(AuthenticationManager.constants.storage.tokenKey, "");
22164
22364
  throw new Error(AuthenticationManager.constants.errors.tokenExpired);
22165
22365
  }
22166
22366
  }
@@ -22189,9 +22389,9 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
22189
22389
  * @param token token fetched from the user's server endpoint
22190
22390
  * @internal
22191
22391
  */
22192
- AuthenticationManager.prototype._storeAccessToken = function (token) {
22392
+ AuthenticationManager.prototype._storeToken = function (token) {
22193
22393
  // Store the value
22194
- this._saveItem(AuthenticationManager.constants.storage.accessTokenKey, token);
22394
+ this._saveItem(AuthenticationManager.constants.storage.tokenKey, token);
22195
22395
  var tokenEvent = {
22196
22396
  map: this.map,
22197
22397
  type: AuthenticationManager.constants.events.tokenAcquired
@@ -22280,7 +22480,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
22280
22480
  }
22281
22481
  };
22282
22482
  /**
22283
- * Return the number of milliseconds since 1970/01/01
22483
+ * Return the number of seconds since 1970/01/01
22284
22484
  * @ignore
22285
22485
  */
22286
22486
  AuthenticationManager.prototype._getCurrentTime = function () {
@@ -22299,6 +22499,9 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
22299
22499
  request.headers[constants.msClientIdHeaderName] = this.options.clientId;
22300
22500
  request.headers[constants.authorizationHeaderName] = constants.authorizationTokenPrefix + token;
22301
22501
  break;
22502
+ case exports.AuthenticationType.sas:
22503
+ request.headers[constants.authorizationHeaderName] = constants.jwtSasPrefix + token;
22504
+ break;
22302
22505
  case exports.AuthenticationType.subscriptionKey:
22303
22506
  request.headers["subscription-key"] = token;
22304
22507
  break;
@@ -22314,7 +22517,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
22314
22517
  // Enable localStorage for IE, as sessionStorage does not work for localhost.
22315
22518
  preferredCacheLocation: "localStorage",
22316
22519
  storage: {
22317
- accessTokenKey: "access.token.key",
22520
+ tokenKey: "access.token.key",
22318
22521
  testStorageKey: "testStorage"
22319
22522
  },
22320
22523
  events: {
@@ -24899,6 +25102,11 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
24899
25102
  * @default true
24900
25103
  */
24901
25104
  _this.showLogo = true;
25105
+ /**
25106
+ * Specifies if the map should display labels
25107
+ * @default true
25108
+ */
25109
+ _this.showLabels = true;
24902
25110
  /**
24903
25111
  * Additional custom attribution appended to map attribution.
24904
25112
  * Default `undefined`
@@ -25470,6 +25678,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25470
25678
  }
25471
25679
  StyleManager.prototype.updateIndoorState = function (theme, tilesetId) {
25472
25680
  var _this = this;
25681
+ var _a;
25473
25682
  var styleset = this.map.styles.getMapConfiguration();
25474
25683
  if (styleset) {
25475
25684
  this.preservedPreindoorStyleset = styleset;
@@ -25479,6 +25688,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25479
25688
  this.map.styles.setMapConfiguration("defaultIndoor_" + tilesetId, styleset === 'microsoft-maps:default' ? desiredIndoorStyle : undefined);
25480
25689
  }
25481
25690
  else {
25691
+ var didTilesetIdChange_1 = ((_a = this.indoorState) === null || _a === void 0 ? void 0 : _a.tilesetId) !== tilesetId;
25482
25692
  this.indoorState = {
25483
25693
  tilesetId: tilesetId,
25484
25694
  theme: theme
@@ -25492,7 +25702,8 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25492
25702
  var targetStylePrefix = currentStyle + "_indoor";
25493
25703
  var candidateStyle = definitions.styles.find(function (style) { return style.name.startsWith(targetStylePrefix); });
25494
25704
  if (candidateStyle) {
25495
- _this.map.setStyle({ style: candidateStyle.name });
25705
+ // force style reload if tileset id has changed to make sure the tiles will be re-requested with new tileset applied in indoor source placeholder
25706
+ _this.map.setStyle({ style: candidateStyle.name }, !didTilesetIdChange_1);
25496
25707
  }
25497
25708
  });
25498
25709
  }
@@ -25530,7 +25741,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25530
25741
  return baseName in styleNamesMap ? styleNamesMap[baseName] : baseName;
25531
25742
  };
25532
25743
  if (!this.serviceOptions.styleSet) {
25533
- newPromise = new HijackablePromise(this._request(this.serviceOptions.staticAssetsDomain, constants.stylePath + "/" + constants.styleResourcePath, "StyleDefinitions").then(function (definitions) { return ({
25744
+ newPromise = new HijackablePromise(this._request(this.serviceOptions.staticAssetsDomain, constants.stylePath + "/" + constants.styleResourcePath, "StyleDefinitions", { version: this.serviceOptions.styleDefinitionsVersion }).then(function (definitions) { return ({
25534
25745
  version: isNaN(definitions.version) ? 0 : parseFloat(definitions.version),
25535
25746
  defaultStyle: definitions.defaultStyle,
25536
25747
  styles: definitions.styles
@@ -25557,9 +25768,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25557
25768
  domain: _this.serviceOptions.staticAssetsDomain,
25558
25769
  path: constants.stylePath + "/" + constants.styleResourcePath + "/" + style.name,
25559
25770
  queryParams: {
25560
- //[constants.apiVersionQueryParameter]: this.serviceOptions.styleDefinitionsVersion,
25561
- // thus far we don't need to differentiate based on parameter here, as stylePatch will be called on cached styles as well
25562
- //language: styleOptions.language
25771
+ styleVersion: _this.serviceOptions.styleDefinitionsVersion,
25563
25772
  },
25564
25773
  protocol: "https"
25565
25774
  }).toString(),
@@ -25603,10 +25812,11 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25603
25812
  /**
25604
25813
  * @internal
25605
25814
  */
25606
- StyleManager.prototype.setStyle = function (styleOptions) {
25815
+ StyleManager.prototype.setStyle = function (styleOptions, diff) {
25816
+ if (diff === void 0) { diff = true; }
25607
25817
  try {
25608
25818
  this.map._getMap().setStyle(this.getStyle(styleOptions), {
25609
- diff: true,
25819
+ diff: diff,
25610
25820
  stylePatch: this._stylePatch.bind(this),
25611
25821
  validate: this.serviceOptions.validateStyle
25612
25822
  });
@@ -25717,7 +25927,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25717
25927
  currentLayerGroupLayers = [];
25718
25928
  };
25719
25929
  nextStyle.layers.forEach(function (nextLayer) {
25720
- var _a, _b, _c;
25930
+ var _a, _b, _c, _d, _e;
25721
25931
  var layerGroup = LayerGroupComparator.getLayerGroup(nextLayer);
25722
25932
  currentLayerGroupId = currentLayerGroupId ? currentLayerGroupId : layerGroup;
25723
25933
  // Set visiblity of fill-extrusion layers according to StyleOptions.showBuildingModels
@@ -25739,6 +25949,20 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25739
25949
  nextLayer.layout.visibility = "visible";
25740
25950
  }
25741
25951
  }
25952
+ // Set visibility of labels
25953
+ var isLabelLayerGroup = layerGroup === 'labels' || layerGroup === 'labels_places' || layerGroup === 'labels_indoor';
25954
+ if (isLabelLayerGroup && nextLayer.type === 'symbol') {
25955
+ if (styleOptions.showLabels) {
25956
+ updateLayoutProperty(nextLayer.id, "visibility", "visible");
25957
+ nextLayer.layout = (_d = nextLayer.layout) !== null && _d !== void 0 ? _d : {};
25958
+ nextLayer.layout.visibility = "visible";
25959
+ }
25960
+ else {
25961
+ updateLayoutProperty(nextLayer.id, "visibility", "none");
25962
+ nextLayer.layout = (_e = nextLayer.layout) !== null && _e !== void 0 ? _e : {};
25963
+ nextLayer.layout.visibility = "none";
25964
+ }
25965
+ }
25742
25966
  // Once this _stylePatch returns control to maplibre the next style will be applied immediately in the same context.
25743
25967
  // To avoid potential data races update LayerManager with new a new set of FundamentalMapLayers from here instead of
25744
25968
  // waiting for a styledata.load event to trigger a sync in a different context.
@@ -25801,7 +26025,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25801
26025
  // If there was a previous styledata change event attached, remove it.
25802
26026
  // When the sprite url changes between style changes then mapbox can't perform the diff
25803
26027
  // In such cases it recalculate the style again. Removing previous attached
25804
- // event listner makes sure that style changed event is not fired twice in these cases.
26028
+ // event listener makes sure that style changed event is not fired twice in these cases.
25805
26029
  this.map.events.remove("styledata", this._onStyleData);
25806
26030
  this.map.events.addOnce("styledata", this._onStyleData);
25807
26031
  };
@@ -25830,8 +26054,16 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
25830
26054
  if (url.includes(constants.styleResourcePlaceholder)) {
25831
26055
  params.url = params.url.replace(constants.styleResourcePlaceholder, constants.styleResourcePath);
25832
26056
  }
25833
- params.url = params.url + ("" + (url.includes('?') ? '&' : '?') + constants.apiVersionQueryParameter + "=" + this.serviceOptions.styleAPIVersion);
25834
- (_a = this.map.authentication) === null || _a === void 0 ? void 0 : _a.signRequest(params);
26057
+ if (params.url.toLocaleLowerCase().includes(this.serviceOptions.domain.toLocaleLowerCase()) ||
26058
+ params.url.toLocaleLowerCase().includes(this.serviceOptions.staticAssetsDomain.toLocaleLowerCase())) {
26059
+ // Only add API version param for Azure maps domain requests
26060
+ var targetUrl = new URL(params.url);
26061
+ if (!targetUrl.searchParams.get(constants.apiVersionQueryParameter)) {
26062
+ targetUrl.searchParams.set(constants.apiVersionQueryParameter, this.serviceOptions.styleAPIVersion);
26063
+ params.url = targetUrl.href;
26064
+ }
26065
+ (_a = this.map.authentication) === null || _a === void 0 ? void 0 : _a.signRequest(params);
26066
+ }
25835
26067
  };
25836
26068
  /**
25837
26069
  * Fetches a json resource at the specified domain and path.
@@ -26236,8 +26468,10 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
26236
26468
  /**
26237
26469
  * Set the map control's style options. Any options not specified will default to their current values.
26238
26470
  * @param options The options for setting the style of the map control.
26471
+ * @param diff [true] If false, forces a 'full' style update, removing the current style and building the given one instead of attempting a diff-based update. Defaults to true.
26239
26472
  */
26240
- Map.prototype.setStyle = function (options) {
26473
+ Map.prototype.setStyle = function (options, diff) {
26474
+ if (diff === void 0) { diff = true; }
26241
26475
  // This option may only be set when initializing the map.
26242
26476
  // The delete operation will handle non-exist property.
26243
26477
  delete options.preserveDrawingBuffer;
@@ -26275,7 +26509,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
26275
26509
  // if the language is changed, then either those delegates need changed
26276
26510
  // or the styledata event manually invoked.
26277
26511
  this.styleOptions = newOptions;
26278
- this._setStyleComponents(newOptions);
26512
+ this._setStyleComponents(newOptions, diff);
26279
26513
  };
26280
26514
  /**
26281
26515
  * Returns the map control's current style settings.
@@ -26937,10 +27171,11 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
26937
27171
  /**
26938
27172
  * @internal
26939
27173
  */
26940
- Map.prototype._rebuildStyle = function () {
27174
+ Map.prototype._rebuildStyle = function (diff) {
27175
+ if (diff === void 0) { diff = true; }
26941
27176
  return __awaiter(this, void 0, void 0, function () {
26942
27177
  return __generator(this, function (_a) {
26943
- this.styles.setStyle(this.styleOptions);
27178
+ this.styles.setStyle(this.styleOptions, diff);
26944
27179
  this.imageSprite._restoreImages();
26945
27180
  return [2 /*return*/];
26946
27181
  });
@@ -27021,7 +27256,10 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
27021
27256
  requestParams.url = requestParams.url.replace(constants.domainPlaceHolder, this.serviceOptions.domain);
27022
27257
  }
27023
27258
  }
27024
- (_a = this.authentication) === null || _a === void 0 ? void 0 : _a.signRequest(requestParams);
27259
+ if (requestParams.url.toLocaleLowerCase().includes(this.serviceOptions.domain.toLocaleLowerCase()) ||
27260
+ requestParams.url.toLocaleLowerCase().includes(this.serviceOptions.staticAssetsDomain.toLocaleLowerCase())) {
27261
+ (_a = this.authentication) === null || _a === void 0 ? void 0 : _a.signRequest(requestParams);
27262
+ }
27025
27263
  if (url.includes(constants.languagePlaceHolder)) {
27026
27264
  requestParams.url = requestParams.url.replace(constants.languagePlaceHolder, this.styleOptions.language);
27027
27265
  }
@@ -27048,8 +27286,9 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
27048
27286
  * Removes sources and layers that aren't used by the new style or any remaining layers.
27049
27287
  * @private
27050
27288
  */
27051
- Map.prototype._setStyleComponents = function (styleOptions) {
27289
+ Map.prototype._setStyleComponents = function (styleOptions, diff) {
27052
27290
  var _this = this;
27291
+ if (diff === void 0) { diff = true; }
27053
27292
  if (this.removed) {
27054
27293
  return;
27055
27294
  }
@@ -27059,7 +27298,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
27059
27298
  _this.styleOptions.style = styleSet.defaultStyle;
27060
27299
  }
27061
27300
  _this.styleOptions = styleOptions;
27062
- _this._rebuildStyle();
27301
+ _this._rebuildStyle(diff);
27063
27302
  });
27064
27303
  return;
27065
27304
  };
@@ -27105,7 +27344,7 @@ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous po
27105
27344
  var w = BoundingBox.getWest(bounds);
27106
27345
  var n = BoundingBox.getNorth(bounds);
27107
27346
  var e = BoundingBox.getEast(bounds);
27108
- if (isNaN(s) || isNaN(w) || isNaN(n) || isNaN(e)) {
27347
+ if (!isFinite(s) || !isFinite(w) || !isFinite(n) || !isFinite(e)) {
27109
27348
  throw new Error("The bounds specified are invalid: [" + bounds + "]");
27110
27349
  }
27111
27350
  while (w > e) {