@itwin/map-layers 3.0.0-dev.78 → 3.0.0-dev.82

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.
Files changed (198) hide show
  1. package/lib/{map-layers.d.ts → cjs/map-layers.d.ts} +0 -0
  2. package/lib/cjs/map-layers.d.ts.map +1 -0
  3. package/lib/{map-layers.js → cjs/map-layers.js} +0 -0
  4. package/lib/cjs/map-layers.js.map +1 -0
  5. package/lib/{mapLayers.d.ts → cjs/mapLayers.d.ts} +0 -0
  6. package/lib/cjs/mapLayers.d.ts.map +1 -0
  7. package/lib/{mapLayers.js → cjs/mapLayers.js} +0 -0
  8. package/lib/cjs/mapLayers.js.map +1 -0
  9. package/lib/{public → cjs/public}/locales/en/mapLayers.json +0 -0
  10. package/lib/{ui → cjs/ui}/Interfaces.d.ts +0 -0
  11. package/lib/cjs/ui/Interfaces.d.ts.map +1 -0
  12. package/lib/{ui → cjs/ui}/Interfaces.js +0 -0
  13. package/lib/cjs/ui/Interfaces.js.map +1 -0
  14. package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.d.ts +0 -0
  15. package/lib/cjs/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
  16. package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.js +0 -0
  17. package/lib/cjs/ui/MapLayersUiItemsProvider.js.map +1 -0
  18. package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.d.ts +0 -0
  19. package/lib/cjs/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
  20. package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.js +0 -0
  21. package/lib/cjs/ui/widget/AttachLayerPopupButton.js.map +1 -0
  22. package/lib/{ui → cjs/ui}/widget/BasemapPanel.d.ts +0 -0
  23. package/lib/cjs/ui/widget/BasemapPanel.d.ts.map +1 -0
  24. package/lib/{ui → cjs/ui}/widget/BasemapPanel.js +0 -0
  25. package/lib/cjs/ui/widget/BasemapPanel.js.map +1 -0
  26. package/lib/{ui → cjs/ui}/widget/BasemapPanel.scss +1 -1
  27. package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.d.ts +0 -0
  28. package/lib/cjs/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
  29. package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.js +0 -0
  30. package/lib/cjs/ui/widget/ConfirmMessageDialog.js.map +1 -0
  31. package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.d.ts +0 -0
  32. package/lib/cjs/ui/widget/MapLayerDroppable.d.ts.map +1 -0
  33. package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.js +0 -0
  34. package/lib/cjs/ui/widget/MapLayerDroppable.js.map +1 -0
  35. package/lib/{ui → cjs/ui}/widget/MapLayerManager.d.ts +0 -0
  36. package/lib/cjs/ui/widget/MapLayerManager.d.ts.map +1 -0
  37. package/lib/{ui → cjs/ui}/widget/MapLayerManager.js +0 -0
  38. package/lib/cjs/ui/widget/MapLayerManager.js.map +1 -0
  39. package/lib/{ui → cjs/ui}/widget/MapLayerManager.scss +1 -1
  40. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.d.ts +0 -0
  41. package/lib/cjs/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
  42. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.js +0 -0
  43. package/lib/cjs/ui/widget/MapLayerSettingsMenu.js.map +1 -0
  44. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.d.ts +0 -0
  45. package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
  46. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.js +0 -0
  47. package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
  48. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.scss +1 -1
  49. package/lib/{ui → cjs/ui}/widget/MapLayersWidget.d.ts +0 -0
  50. package/lib/cjs/ui/widget/MapLayersWidget.d.ts.map +1 -0
  51. package/lib/{ui → cjs/ui}/widget/MapLayersWidget.js +0 -0
  52. package/lib/cjs/ui/widget/MapLayersWidget.js.map +1 -0
  53. package/lib/{ui → cjs/ui}/widget/MapManagerSettings.d.ts +0 -0
  54. package/lib/cjs/ui/widget/MapManagerSettings.d.ts.map +1 -0
  55. package/lib/{ui → cjs/ui}/widget/MapManagerSettings.js +0 -0
  56. package/lib/cjs/ui/widget/MapManagerSettings.js.map +1 -0
  57. package/lib/{ui → cjs/ui}/widget/MapManagerSettings.scss +1 -1
  58. package/lib/{ui → cjs/ui}/widget/MapUrlDialog.d.ts +0 -0
  59. package/lib/cjs/ui/widget/MapUrlDialog.d.ts.map +1 -0
  60. package/lib/{ui → cjs/ui}/widget/MapUrlDialog.js +0 -0
  61. package/lib/cjs/ui/widget/MapUrlDialog.js.map +1 -0
  62. package/lib/{ui → cjs/ui}/widget/MapUrlDialog.scss +1 -1
  63. package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.d.ts +0 -0
  64. package/lib/cjs/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
  65. package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.js +0 -0
  66. package/lib/cjs/ui/widget/SubLayersDataProvider.js.map +1 -0
  67. package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.d.ts +0 -0
  68. package/lib/cjs/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
  69. package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.js +0 -0
  70. package/lib/cjs/ui/widget/SubLayersPopupButton.js.map +1 -0
  71. package/lib/{ui → cjs/ui}/widget/SubLayersTree.d.ts +0 -0
  72. package/lib/cjs/ui/widget/SubLayersTree.d.ts.map +1 -0
  73. package/lib/{ui → cjs/ui}/widget/SubLayersTree.js +0 -0
  74. package/lib/cjs/ui/widget/SubLayersTree.js.map +1 -0
  75. package/lib/{ui → cjs/ui}/widget/SubLayersTree.scss +1 -1
  76. package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.d.ts +0 -0
  77. package/lib/cjs/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
  78. package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.js +0 -0
  79. package/lib/cjs/ui/widget/TransparencyPopupButton.js.map +1 -0
  80. package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.scss +1 -1
  81. package/lib/esm/map-layers.d.ts +5 -0
  82. package/lib/esm/map-layers.d.ts.map +1 -0
  83. package/lib/esm/map-layers.js +9 -0
  84. package/lib/esm/map-layers.js.map +1 -0
  85. package/lib/esm/mapLayers.d.ts +29 -0
  86. package/lib/esm/mapLayers.d.ts.map +1 -0
  87. package/lib/esm/mapLayers.js +50 -0
  88. package/lib/esm/mapLayers.js.map +1 -0
  89. package/lib/esm/public/locales/en/mapLayers.json +113 -0
  90. package/lib/esm/ui/Interfaces.d.ts +32 -0
  91. package/lib/esm/ui/Interfaces.d.ts.map +1 -0
  92. package/lib/esm/ui/Interfaces.js +2 -0
  93. package/lib/esm/ui/Interfaces.js.map +1 -0
  94. package/lib/esm/ui/MapLayersUiItemsProvider.d.ts +23 -0
  95. package/lib/esm/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
  96. package/lib/esm/ui/MapLayersUiItemsProvider.js +50 -0
  97. package/lib/esm/ui/MapLayersUiItemsProvider.js.map +1 -0
  98. package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts +14 -0
  99. package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
  100. package/lib/esm/ui/widget/AttachLayerPopupButton.js +308 -0
  101. package/lib/esm/ui/widget/AttachLayerPopupButton.js.map +1 -0
  102. package/lib/esm/ui/widget/BasemapPanel.d.ts +5 -0
  103. package/lib/esm/ui/widget/BasemapPanel.d.ts.map +1 -0
  104. package/lib/esm/ui/widget/BasemapPanel.js +141 -0
  105. package/lib/esm/ui/widget/BasemapPanel.js.map +1 -0
  106. package/lib/esm/ui/widget/BasemapPanel.scss +98 -0
  107. package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts +22 -0
  108. package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
  109. package/lib/esm/ui/widget/ConfirmMessageDialog.js +22 -0
  110. package/lib/esm/ui/widget/ConfirmMessageDialog.js.map +1 -0
  111. package/lib/esm/ui/widget/MapLayerDroppable.d.ts +19 -0
  112. package/lib/esm/ui/widget/MapLayerDroppable.d.ts.map +1 -0
  113. package/lib/esm/ui/widget/MapLayerDroppable.js +80 -0
  114. package/lib/esm/ui/widget/MapLayerDroppable.js.map +1 -0
  115. package/lib/esm/ui/widget/MapLayerManager.d.ts +27 -0
  116. package/lib/esm/ui/widget/MapLayerManager.d.ts.map +1 -0
  117. package/lib/esm/ui/widget/MapLayerManager.js +347 -0
  118. package/lib/esm/ui/widget/MapLayerManager.js.map +1 -0
  119. package/lib/esm/ui/widget/MapLayerManager.scss +525 -0
  120. package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts +10 -0
  121. package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
  122. package/lib/esm/ui/widget/MapLayerSettingsMenu.js +79 -0
  123. package/lib/esm/ui/widget/MapLayerSettingsMenu.js.map +1 -0
  124. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts +5 -0
  125. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
  126. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js +31 -0
  127. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
  128. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.scss +31 -0
  129. package/lib/esm/ui/widget/MapLayersWidget.d.ts +12 -0
  130. package/lib/esm/ui/widget/MapLayersWidget.d.ts.map +1 -0
  131. package/lib/esm/ui/widget/MapLayersWidget.js +23 -0
  132. package/lib/esm/ui/widget/MapLayersWidget.js.map +1 -0
  133. package/lib/esm/ui/widget/MapManagerSettings.d.ts +4 -0
  134. package/lib/esm/ui/widget/MapManagerSettings.d.ts.map +1 -0
  135. package/lib/esm/ui/widget/MapManagerSettings.js +168 -0
  136. package/lib/esm/ui/widget/MapManagerSettings.js.map +1 -0
  137. package/lib/esm/ui/widget/MapManagerSettings.scss +23 -0
  138. package/lib/esm/ui/widget/MapUrlDialog.d.ts +23 -0
  139. package/lib/esm/ui/widget/MapUrlDialog.d.ts.map +1 -0
  140. package/lib/esm/ui/widget/MapUrlDialog.js +346 -0
  141. package/lib/esm/ui/widget/MapUrlDialog.js.map +1 -0
  142. package/lib/esm/ui/widget/MapUrlDialog.scss +85 -0
  143. package/lib/esm/ui/widget/SubLayersDataProvider.d.ts +21 -0
  144. package/lib/esm/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
  145. package/lib/esm/ui/widget/SubLayersDataProvider.js +73 -0
  146. package/lib/esm/ui/widget/SubLayersDataProvider.js.map +1 -0
  147. package/lib/esm/ui/widget/SubLayersPopupButton.d.ts +11 -0
  148. package/lib/esm/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
  149. package/lib/esm/ui/widget/SubLayersPopupButton.js +36 -0
  150. package/lib/esm/ui/widget/SubLayersPopupButton.js.map +1 -0
  151. package/lib/esm/ui/widget/SubLayersTree.d.ts +16 -0
  152. package/lib/esm/ui/widget/SubLayersTree.d.ts.map +1 -0
  153. package/lib/esm/ui/widget/SubLayersTree.js +374 -0
  154. package/lib/esm/ui/widget/SubLayersTree.js.map +1 -0
  155. package/lib/esm/ui/widget/SubLayersTree.scss +64 -0
  156. package/lib/esm/ui/widget/TransparencyPopupButton.d.ts +14 -0
  157. package/lib/esm/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
  158. package/lib/esm/ui/widget/TransparencyPopupButton.js +44 -0
  159. package/lib/esm/ui/widget/TransparencyPopupButton.js.map +1 -0
  160. package/lib/esm/ui/widget/TransparencyPopupButton.scss +53 -0
  161. package/lib/public/en/mapLayers.json +113 -0
  162. package/package.json +45 -39
  163. package/lib/map-layers.d.ts.map +0 -1
  164. package/lib/map-layers.js.map +0 -1
  165. package/lib/mapLayers.d.ts.map +0 -1
  166. package/lib/mapLayers.js.map +0 -1
  167. package/lib/ui/Interfaces.d.ts.map +0 -1
  168. package/lib/ui/Interfaces.js.map +0 -1
  169. package/lib/ui/MapLayersUiItemsProvider.d.ts.map +0 -1
  170. package/lib/ui/MapLayersUiItemsProvider.js.map +0 -1
  171. package/lib/ui/widget/AttachLayerPopupButton.d.ts.map +0 -1
  172. package/lib/ui/widget/AttachLayerPopupButton.js.map +0 -1
  173. package/lib/ui/widget/BasemapPanel.d.ts.map +0 -1
  174. package/lib/ui/widget/BasemapPanel.js.map +0 -1
  175. package/lib/ui/widget/ConfirmMessageDialog.d.ts.map +0 -1
  176. package/lib/ui/widget/ConfirmMessageDialog.js.map +0 -1
  177. package/lib/ui/widget/MapLayerDroppable.d.ts.map +0 -1
  178. package/lib/ui/widget/MapLayerDroppable.js.map +0 -1
  179. package/lib/ui/widget/MapLayerManager.d.ts.map +0 -1
  180. package/lib/ui/widget/MapLayerManager.js.map +0 -1
  181. package/lib/ui/widget/MapLayerSettingsMenu.d.ts.map +0 -1
  182. package/lib/ui/widget/MapLayerSettingsMenu.js.map +0 -1
  183. package/lib/ui/widget/MapLayerSettingsPopupButton.d.ts.map +0 -1
  184. package/lib/ui/widget/MapLayerSettingsPopupButton.js.map +0 -1
  185. package/lib/ui/widget/MapLayersWidget.d.ts.map +0 -1
  186. package/lib/ui/widget/MapLayersWidget.js.map +0 -1
  187. package/lib/ui/widget/MapManagerSettings.d.ts.map +0 -1
  188. package/lib/ui/widget/MapManagerSettings.js.map +0 -1
  189. package/lib/ui/widget/MapUrlDialog.d.ts.map +0 -1
  190. package/lib/ui/widget/MapUrlDialog.js.map +0 -1
  191. package/lib/ui/widget/SubLayersDataProvider.d.ts.map +0 -1
  192. package/lib/ui/widget/SubLayersDataProvider.js.map +0 -1
  193. package/lib/ui/widget/SubLayersPopupButton.d.ts.map +0 -1
  194. package/lib/ui/widget/SubLayersPopupButton.js.map +0 -1
  195. package/lib/ui/widget/SubLayersTree.d.ts.map +0 -1
  196. package/lib/ui/widget/SubLayersTree.js.map +0 -1
  197. package/lib/ui/widget/TransparencyPopupButton.d.ts.map +0 -1
  198. package/lib/ui/widget/TransparencyPopupButton.js.map +0 -1
@@ -0,0 +1,23 @@
1
+ import { AbstractWidgetProps, StagePanelLocation, StagePanelSection, UiItemsProvider } from "@itwin/appui-abstract";
2
+ import { Localization } from "@itwin/core-common";
3
+ import { ConfigurableCreateInfo, WidgetControl } from "@itwin/appui-react";
4
+ import { MapLayerOptions } from "./Interfaces";
5
+ export declare class MapLayersUiItemsProvider implements UiItemsProvider {
6
+ readonly id = "MapLayersUiItemsProvider";
7
+ static localization: Localization;
8
+ constructor(localization: Localization);
9
+ provideWidgets(_stageId: string, stageUsage: string, location: StagePanelLocation, section: StagePanelSection | undefined): ReadonlyArray<AbstractWidgetProps>;
10
+ }
11
+ /** MapLayersWidgetControl provides a widget to attach and remove maps layers from the active view's display style.
12
+ * ``` tsx
13
+ * <Widget id={MapLayersWidgetControl.id} label={MapLayersWidgetControl.label} control={MapLayersWidgetControl}
14
+ * iconSpec={MapLayersWidgetControl.iconSpec} />,
15
+ * ```
16
+ */
17
+ export declare class MapLayersWidgetControl extends WidgetControl {
18
+ static id: string;
19
+ static iconSpec: string;
20
+ static get label(): string;
21
+ constructor(info: ConfigurableCreateInfo, mapLayerOptions: MapLayerOptions | undefined);
22
+ }
23
+ //# sourceMappingURL=MapLayersUiItemsProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapLayersUiItemsProvider.d.ts","sourceRoot":"","sources":["../../../src/ui/MapLayersUiItemsProvider.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAc,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAChI,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,qBAAa,wBAAyB,YAAW,eAAe;IAC9D,SAAgB,EAAE,8BAA8B;IAChD,OAAc,YAAY,EAAE,YAAY,CAAC;gBAEtB,YAAY,EAAE,YAAY;IAItC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,aAAa,CAAC,mBAAmB,CAAC;CAmBtK;AAED;;;;;GAKG;AACH,qBAAa,sBAAuB,SAAQ,aAAa;IACvD,OAAc,EAAE,SAAqB;IACrC,OAAc,QAAQ,SAAc;IAEpC,WAAkB,KAAK,IAAI,MAAM,CAEhC;gBAEW,IAAI,EAAE,sBAAsB,EAAE,eAAe,EAAE,eAAe,GAAG,SAAS;CAKvF"}
@@ -0,0 +1,50 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as React from "react";
6
+ import { StagePanelLocation, StagePanelSection, StageUsage } from "@itwin/appui-abstract";
7
+ import { MapLayersWidget } from "./widget/MapLayersWidget";
8
+ import { WidgetControl } from "@itwin/appui-react";
9
+ import { IModelApp } from "@itwin/core-frontend";
10
+ export class MapLayersUiItemsProvider {
11
+ constructor(localization) {
12
+ this.id = "MapLayersUiItemsProvider";
13
+ MapLayersUiItemsProvider.localization = localization;
14
+ }
15
+ provideWidgets(_stageId, stageUsage, location, section) {
16
+ const widgets = [];
17
+ const mapLayerOptions = {
18
+ hideExternalMapLayers: false,
19
+ mapTypeOptions: { supportTileUrl: false, supportWmsAuthentication: true },
20
+ fetchPublicMapLayerSources: false,
21
+ };
22
+ if (stageUsage === StageUsage.General && location === StagePanelLocation.Right && section === StagePanelSection.Start) {
23
+ widgets.push({
24
+ id: "map-layers:mapLayersWidget",
25
+ label: MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:Widget.Label"),
26
+ icon: "icon-map",
27
+ getWidgetContent: () => React.createElement(MapLayersWidget, { mapLayerOptions: mapLayerOptions }), // eslint-disable-line react/display-name
28
+ });
29
+ }
30
+ return widgets;
31
+ }
32
+ }
33
+ /** MapLayersWidgetControl provides a widget to attach and remove maps layers from the active view's display style.
34
+ * ``` tsx
35
+ * <Widget id={MapLayersWidgetControl.id} label={MapLayersWidgetControl.label} control={MapLayersWidgetControl}
36
+ * iconSpec={MapLayersWidgetControl.iconSpec} />,
37
+ * ```
38
+ */
39
+ export class MapLayersWidgetControl extends WidgetControl {
40
+ constructor(info, mapLayerOptions) {
41
+ super(info, mapLayerOptions);
42
+ this.reactNode = React.createElement(MapLayersWidget, { mapLayerOptions: mapLayerOptions });
43
+ }
44
+ static get label() {
45
+ return IModelApp.localization.getLocalizedString("mapLayers:Widget.Label");
46
+ }
47
+ }
48
+ MapLayersWidgetControl.id = "MapLayersWidget";
49
+ MapLayersWidgetControl.iconSpec = "icon-map";
50
+ //# sourceMappingURL=MapLayersUiItemsProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapLayersUiItemsProvider.js","sourceRoot":"","sources":["../../../src/ui/MapLayersUiItemsProvider.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAE/F,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAuB,kBAAkB,EAAE,iBAAiB,EAAE,UAAU,EAAmB,MAAM,uBAAuB,CAAC;AAEhI,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAA0B,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,MAAM,OAAO,wBAAwB;IAInC,YAAmB,YAA0B;QAH7B,OAAE,GAAG,0BAA0B,CAAC;QAI9C,wBAAwB,CAAC,YAAY,GAAG,YAAY,CAAC;IACvD,CAAC;IAEM,cAAc,CAAC,QAAgB,EAAE,UAAkB,EAAE,QAA4B,EAAE,OAAsC;QAC9H,MAAM,OAAO,GAA0B,EAAE,CAAC;QAC1C,MAAM,eAAe,GAAoB;YACvC,qBAAqB,EAAE,KAAK;YAC5B,cAAc,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,wBAAwB,EAAE,IAAI,EAAE;YACzE,0BAA0B,EAAE,KAAK;SAClC,CAAC;QAEF,IAAI,UAAU,KAAK,UAAU,CAAC,OAAO,IAAI,QAAQ,KAAK,kBAAkB,CAAC,KAAK,IAAI,OAAO,KAAK,iBAAiB,CAAC,KAAK,EAAE;YACrH,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,4BAA4B;gBAChC,KAAK,EAAE,wBAAwB,CAAC,YAAY,CAAC,kBAAkB,CAAC,wBAAwB,CAAC;gBACzF,IAAI,EAAE,UAAU;gBAChB,gBAAgB,EAAE,GAAG,EAAE,CAAC,oBAAC,eAAe,IAAC,eAAe,EAAE,eAAe,GAAI,EAAE,yCAAyC;aACzH,CAAC,CAAC;SACJ;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,sBAAuB,SAAQ,aAAa;IAQvD,YAAY,IAA4B,EAAE,eAA4C;QACpF,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAE7B,IAAI,CAAC,SAAS,GAAG,oBAAC,eAAe,IAAC,eAAe,EAAE,eAAe,GAAI,CAAC;IACzE,CAAC;IARM,MAAM,KAAK,KAAK;QACrB,OAAO,SAAS,CAAC,YAAY,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,CAAC;IAC7E,CAAC;;AALa,yBAAE,GAAG,iBAAiB,CAAC;AACvB,+BAAQ,GAAG,UAAU,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as React from \"react\";\r\nimport { AbstractWidgetProps, StagePanelLocation, StagePanelSection, StageUsage, UiItemsProvider } from \"@itwin/appui-abstract\";\r\nimport { Localization } from \"@itwin/core-common\";\r\nimport { MapLayersWidget } from \"./widget/MapLayersWidget\";\r\nimport { ConfigurableCreateInfo, WidgetControl } from \"@itwin/appui-react\";\r\nimport { IModelApp } from \"@itwin/core-frontend\";\r\nimport { MapLayerOptions } from \"./Interfaces\";\r\n\r\nexport class MapLayersUiItemsProvider implements UiItemsProvider {\r\n public readonly id = \"MapLayersUiItemsProvider\";\r\n public static localization: Localization;\r\n\r\n public constructor(localization: Localization) {\r\n MapLayersUiItemsProvider.localization = localization;\r\n }\r\n\r\n public provideWidgets(_stageId: string, stageUsage: string, location: StagePanelLocation, section: StagePanelSection | undefined): ReadonlyArray<AbstractWidgetProps> {\r\n const widgets: AbstractWidgetProps[] = [];\r\n const mapLayerOptions: MapLayerOptions = {\r\n hideExternalMapLayers: false,\r\n mapTypeOptions: { supportTileUrl: false, supportWmsAuthentication: true },\r\n fetchPublicMapLayerSources: false,\r\n };\r\n\r\n if (stageUsage === StageUsage.General && location === StagePanelLocation.Right && section === StagePanelSection.Start) {\r\n widgets.push({\r\n id: \"map-layers:mapLayersWidget\",\r\n label: MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:Widget.Label\"),\r\n icon: \"icon-map\",\r\n getWidgetContent: () => <MapLayersWidget mapLayerOptions={mapLayerOptions} />, // eslint-disable-line react/display-name\r\n });\r\n }\r\n\r\n return widgets;\r\n }\r\n}\r\n\r\n/** MapLayersWidgetControl provides a widget to attach and remove maps layers from the active view's display style.\r\n * ``` tsx\r\n * <Widget id={MapLayersWidgetControl.id} label={MapLayersWidgetControl.label} control={MapLayersWidgetControl}\r\n * iconSpec={MapLayersWidgetControl.iconSpec} />,\r\n * ```\r\n */\r\nexport class MapLayersWidgetControl extends WidgetControl {\r\n public static id = \"MapLayersWidget\";\r\n public static iconSpec = \"icon-map\";\r\n\r\n public static get label(): string {\r\n return IModelApp.localization.getLocalizedString(\"mapLayers:Widget.Label\");\r\n }\r\n\r\n constructor(info: ConfigurableCreateInfo, mapLayerOptions: MapLayerOptions | undefined) {\r\n super(info, mapLayerOptions);\r\n\r\n this.reactNode = <MapLayersWidget mapLayerOptions={mapLayerOptions} />;\r\n }\r\n}\r\n"]}
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ /** @internal */
3
+ export declare enum AttachLayerButtonType {
4
+ Primary = 0,
5
+ Blue = 1,
6
+ Icon = 2
7
+ }
8
+ export interface AttachLayerPopupButtonProps {
9
+ isOverlay: boolean;
10
+ buttonType?: AttachLayerButtonType;
11
+ }
12
+ /** @internal */
13
+ export declare function AttachLayerPopupButton(props: AttachLayerPopupButtonProps): JSX.Element;
14
+ //# sourceMappingURL=AttachLayerPopupButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AttachLayerPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":";AAwTA,gBAAgB;AAChB,oBAAY,qBAAqB;IAC/B,OAAO,IAAA;IACP,IAAI,IAAA;IACJ,IAAI,IAAA;CACL;AACD,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED,gBAAgB;AAEhB,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,eAqHxE"}
@@ -0,0 +1,308 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as React from "react";
6
+ import { IModelApp, MapLayerSettingsService, MapLayerSourceStatus, NotifyMessageDetails, OutputMessagePriority } from "@itwin/core-frontend";
7
+ import { RelativePosition } from "@itwin/appui-abstract";
8
+ import * as UiCore from "@itwin/core-react";
9
+ import { ModalDialogManager } from "@itwin/appui-react";
10
+ import { useSourceMapContext } from "./MapLayerManager";
11
+ import { MapUrlDialog } from "./MapUrlDialog";
12
+ import { MapLayersUiItemsProvider } from "../MapLayersUiItemsProvider";
13
+ import { ConfirmMessageDialog } from "./ConfirmMessageDialog";
14
+ import { Button, Input } from "@itwin/itwinui-react";
15
+ // eslint-disable-next-line @typescript-eslint/naming-convention
16
+ function AttachLayerPanel({ isOverlay, onLayerAttached }) {
17
+ var _a, _b;
18
+ const [layerNameToAdd, setLayerNameToAdd] = React.useState();
19
+ const [sourceFilterString, setSourceFilterString] = React.useState();
20
+ const [placeholderLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.SearchPlaceholder"));
21
+ const [addCustomLayerLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.Custom"));
22
+ const [addCustomLayerToolTip] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.AttachCustomLayer"));
23
+ const [loadingMapSources] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.LoadingMapSources"));
24
+ const [removeLayerDefButtonTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.RemoveLayerDefButtonTitle"));
25
+ const [editLayerDefButtonTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.EditLayerDefButtonTitle"));
26
+ const [removeLayerDefDialogTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.RemoveLayerDefDialogTitle"));
27
+ const [loading, setLoading] = React.useState(false);
28
+ const [layerNameUnderCursor, setLayerNameUnderCursor] = React.useState();
29
+ // 'isMounted' is used to prevent any async operation once the hook has been
30
+ // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.
31
+ const isMounted = React.useRef(false);
32
+ React.useEffect(() => {
33
+ isMounted.current = true;
34
+ return () => {
35
+ isMounted.current = false;
36
+ // We close any open dialogs that we might have opened
37
+ // This was added because the modal dialog remained remained displayed after the session expired.
38
+ ModalDialogManager.closeDialog();
39
+ };
40
+ }, []);
41
+ const handleFilterTextChanged = React.useCallback((event) => {
42
+ setSourceFilterString(event.target.value);
43
+ }, []);
44
+ const { loadingSources, sources, activeViewport, backgroundLayers, overlayLayers, mapTypesOptions } = useSourceMapContext();
45
+ const iTwinId = (_a = activeViewport === null || activeViewport === void 0 ? void 0 : activeViewport.iModel) === null || _a === void 0 ? void 0 : _a.iTwinId;
46
+ const iModelId = (_b = activeViewport === null || activeViewport === void 0 ? void 0 : activeViewport.iModel) === null || _b === void 0 ? void 0 : _b.iModelId;
47
+ const styleContainsLayer = React.useCallback((name) => {
48
+ if (backgroundLayers) {
49
+ if (-1 !== backgroundLayers.findIndex((layer) => layer.name === name))
50
+ return true;
51
+ }
52
+ if (overlayLayers) {
53
+ if (-1 !== overlayLayers.findIndex((layer) => layer.name === name))
54
+ return true;
55
+ }
56
+ return false;
57
+ }, [backgroundLayers, overlayLayers]);
58
+ const handleModalUrlDialogOk = React.useCallback(() => {
59
+ // close popup and refresh UI
60
+ onLayerAttached();
61
+ }, [onLayerAttached]);
62
+ const handleModalUrlDialogCancel = React.useCallback(() => {
63
+ // close popup and refresh UI
64
+ setLoading(false);
65
+ ModalDialogManager.closeDialog();
66
+ }, []);
67
+ React.useEffect(() => {
68
+ async function attemptToAddLayer(layerName) {
69
+ if (layerName && activeViewport) {
70
+ // if the layer is not in the style add it now.
71
+ if (undefined === (backgroundLayers === null || backgroundLayers === void 0 ? void 0 : backgroundLayers.find((layer) => layerName === layer.name)) && undefined === (overlayLayers === null || overlayLayers === void 0 ? void 0 : overlayLayers.find((layer) => layerName === layer.name))) {
72
+ const mapLayerSettings = sources === null || sources === void 0 ? void 0 : sources.find((source) => source.name === layerName);
73
+ if (mapLayerSettings === undefined) {
74
+ return;
75
+ }
76
+ try {
77
+ if (isMounted.current) {
78
+ setLoading(true);
79
+ }
80
+ const { status, subLayers } = await mapLayerSettings.validateSource();
81
+ if (status === MapLayerSourceStatus.Valid || status === MapLayerSourceStatus.RequireAuth) {
82
+ if (status === MapLayerSourceStatus.Valid) {
83
+ const layerSettings = mapLayerSettings.toLayerSettings(subLayers);
84
+ if (layerSettings) {
85
+ activeViewport.displayStyle.attachMapLayerSettings(layerSettings, isOverlay);
86
+ activeViewport.invalidateRenderPlan();
87
+ const msg = IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerAttached", { sourceName: layerSettings.name, sourceUrl: layerSettings.url });
88
+ IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));
89
+ }
90
+ if (isMounted.current) {
91
+ setLoading(false);
92
+ }
93
+ if (onLayerAttached) {
94
+ onLayerAttached();
95
+ }
96
+ }
97
+ else if (status === MapLayerSourceStatus.RequireAuth && isMounted.current) {
98
+ ModalDialogManager.openDialog(React.createElement(MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, layerRequiringCredentials: mapLayerSettings.toJSON(), onOkResult: handleModalUrlDialogOk, onCancelResult: handleModalUrlDialogCancel, mapTypesOptions: mapTypesOptions }));
99
+ }
100
+ }
101
+ else {
102
+ const msg = IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerValidationFailed", { sourceUrl: mapLayerSettings.url });
103
+ IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));
104
+ if (isMounted.current) {
105
+ setLoading(false);
106
+ }
107
+ }
108
+ }
109
+ catch (err) {
110
+ if (isMounted.current) {
111
+ setLoading(false);
112
+ }
113
+ const msg = IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerAttachError", { error: err, sourceUrl: mapLayerSettings.url });
114
+ IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));
115
+ }
116
+ }
117
+ }
118
+ return;
119
+ }
120
+ if (layerNameToAdd) {
121
+ attemptToAddLayer(layerNameToAdd); // eslint-disable-line @typescript-eslint/no-floating-promises
122
+ if (isMounted.current) {
123
+ setLayerNameToAdd(undefined);
124
+ }
125
+ }
126
+ }, [setLayerNameToAdd, layerNameToAdd, activeViewport, sources, backgroundLayers, isOverlay, overlayLayers, onLayerAttached, handleModalUrlDialogOk, mapTypesOptions, handleModalUrlDialogCancel]);
127
+ const options = React.useMemo(() => sources === null || sources === void 0 ? void 0 : sources.filter((source) => !styleContainsLayer(source.name)), [sources, styleContainsLayer]);
128
+ const filteredOptions = React.useMemo(() => {
129
+ if (undefined === sourceFilterString || 0 === sourceFilterString.length) {
130
+ return options;
131
+ }
132
+ else {
133
+ return options === null || options === void 0 ? void 0 : options.filter((option) => option.name.toLowerCase().includes(sourceFilterString === null || sourceFilterString === void 0 ? void 0 : sourceFilterString.toLowerCase()));
134
+ }
135
+ }, [options, sourceFilterString]);
136
+ const handleAddNewMapSource = React.useCallback(() => {
137
+ ModalDialogManager.openDialog(React.createElement(MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, onOkResult: handleModalUrlDialogOk, mapTypesOptions: mapTypesOptions }));
138
+ return;
139
+ }, [activeViewport, handleModalUrlDialogOk, isOverlay, mapTypesOptions]);
140
+ const handleAttach = React.useCallback((mapName) => {
141
+ setLayerNameToAdd(mapName);
142
+ }, []);
143
+ const handleKeypressOnSourceList = React.useCallback((event) => {
144
+ var _a, _b;
145
+ const key = event.key;
146
+ if (key === "Enter") {
147
+ event.preventDefault();
148
+ const mapName = (_b = (_a = event.currentTarget) === null || _a === void 0 ? void 0 : _a.dataset) === null || _b === void 0 ? void 0 : _b.value;
149
+ if (mapName && mapName.length) {
150
+ handleAttach(mapName);
151
+ }
152
+ }
153
+ }, [handleAttach]);
154
+ const onListboxValueChange = React.useCallback((mapName) => {
155
+ setLayerNameToAdd(mapName);
156
+ }, []);
157
+ const handleNoConfirmation = React.useCallback((_layerName) => {
158
+ ModalDialogManager.closeDialog();
159
+ }, []);
160
+ const handleYesConfirmation = React.useCallback(async (source) => {
161
+ const layerName = source.name;
162
+ if (!!iTwinId && !!iModelId) {
163
+ if (await MapLayerSettingsService.deleteSharedSettings(source, iTwinId, iModelId)) {
164
+ const msg = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.RemoveLayerDefSuccess", { layerName });
165
+ IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));
166
+ }
167
+ else {
168
+ const msg = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.RemoveLayerDefError", { layerName });
169
+ IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));
170
+ }
171
+ }
172
+ ModalDialogManager.closeDialog();
173
+ }, [iTwinId, iModelId]);
174
+ /*
175
+ Handle Remove layer button clicked
176
+ */
177
+ const onItemRemoveButtonClicked = React.useCallback((source, event) => {
178
+ event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.
179
+ const layerName = source.name;
180
+ const msg = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.RemoveLayerDefDialogMessage", { layerName });
181
+ ModalDialogManager.openDialog(React.createElement(ConfirmMessageDialog, { className: "map-sources-delete-confirmation", title: removeLayerDefDialogTitle, message: msg, maxWidth: 400, onClose: () => handleNoConfirmation(layerName), onEscape: () => handleNoConfirmation(layerName), onYesResult: async () => handleYesConfirmation(source), onNoResult: () => handleNoConfirmation(layerName) }));
182
+ }, [handleNoConfirmation, handleYesConfirmation, removeLayerDefDialogTitle]);
183
+ /*
184
+ Handle Edit layer button clicked
185
+ */
186
+ const onItemEditButtonClicked = React.useCallback((event) => {
187
+ var _a, _b, _c;
188
+ event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.
189
+ const targetLayerName = (_c = (_b = (_a = event === null || event === void 0 ? void 0 : event.currentTarget) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.dataset) === null || _c === void 0 ? void 0 : _c.value;
190
+ const matchingSource = sources.find((layerSource) => layerSource.name === targetLayerName);
191
+ // we expect a single layer source matching this name
192
+ if (matchingSource === undefined) {
193
+ return;
194
+ }
195
+ ModalDialogManager.openDialog(React.createElement(MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, mapLayerSourceToEdit: matchingSource, onOkResult: handleModalUrlDialogOk, mapTypesOptions: mapTypesOptions }));
196
+ }, [activeViewport, handleModalUrlDialogOk, isOverlay, mapTypesOptions, sources]);
197
+ return (React.createElement("div", { className: "map-manager-header" },
198
+ (loading || loadingSources) && React.createElement(UiCore.LoadingSpinner, { message: loadingMapSources }),
199
+ React.createElement("div", { className: "map-manager-source-listbox-header" },
200
+ React.createElement(Input, { type: "text", className: "map-manager-source-list-filter", placeholder: placeholderLabel, value: sourceFilterString, onChange: handleFilterTextChanged }),
201
+ React.createElement(Button, { className: "map-manager-add-source-button", title: addCustomLayerToolTip, onClick: handleAddNewMapSource }, addCustomLayerLabel)),
202
+ React.createElement("div", { className: "map-manager-sources" },
203
+ React.createElement(UiCore.Listbox, { id: "map-sources", selectedValue: layerNameToAdd, className: "map-manager-source-list", onKeyPress: handleKeypressOnSourceList, onListboxValueChange: onListboxValueChange }, filteredOptions === null || filteredOptions === void 0 ? void 0 : filteredOptions.map((source) => React.createElement(UiCore.ListboxItem, { key: source.name, className: "map-source-list-entry", value: source.name, onMouseEnter: () => setLayerNameUnderCursor(source.name), onMouseLeave: () => setLayerNameUnderCursor(undefined) },
204
+ React.createElement("span", { className: "map-source-list-entry-name", title: source.name }, source.name),
205
+ // otherwise list feels cluttered.
206
+ (!!iTwinId && !!iModelId && layerNameUnderCursor && layerNameUnderCursor === source.name) &&
207
+ React.createElement(React.Fragment, null,
208
+ React.createElement(Button, { className: "map-source-list-entry-button", title: editLayerDefButtonTitle, onClick: onItemEditButtonClicked },
209
+ React.createElement(UiCore.Icon, { iconSpec: "icon-edit" })),
210
+ React.createElement(Button, { className: "map-source-list-entry-button", title: removeLayerDefButtonTitle, onClick: (event) => { onItemRemoveButtonClicked(source, event); } },
211
+ React.createElement(UiCore.Icon, { iconSpec: "icon-delete" })))))))));
212
+ }
213
+ /** @internal */
214
+ export var AttachLayerButtonType;
215
+ (function (AttachLayerButtonType) {
216
+ AttachLayerButtonType[AttachLayerButtonType["Primary"] = 0] = "Primary";
217
+ AttachLayerButtonType[AttachLayerButtonType["Blue"] = 1] = "Blue";
218
+ AttachLayerButtonType[AttachLayerButtonType["Icon"] = 2] = "Icon";
219
+ })(AttachLayerButtonType || (AttachLayerButtonType = {}));
220
+ /** @internal */
221
+ // eslint-disable-next-line @typescript-eslint/naming-convention
222
+ export function AttachLayerPopupButton(props) {
223
+ const [showAttachLayerLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:AttachLayerPopup.Attach"));
224
+ const [hideAttachLayerLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:AttachLayerPopup.Close"));
225
+ const [addCustomLayerButtonLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.AddCustomLayerButtonLabel"));
226
+ const [popupOpen, setPopupOpen] = React.useState(false);
227
+ const buttonRef = React.useRef(null);
228
+ const panelRef = React.useRef(null);
229
+ // 'isMounted' is used to prevent any async operation once the hook has been
230
+ // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.
231
+ const isMounted = React.useRef(false);
232
+ React.useEffect(() => {
233
+ isMounted.current = true;
234
+ return () => {
235
+ isMounted.current = false;
236
+ };
237
+ }, []);
238
+ const togglePopup = React.useCallback(() => {
239
+ setPopupOpen(!popupOpen);
240
+ }, [popupOpen]);
241
+ const handleClosePopup = React.useCallback(() => {
242
+ setPopupOpen(false);
243
+ }, []);
244
+ const isInsideCoreDialog = React.useCallback((element) => {
245
+ if (element.nodeName === "DIV") {
246
+ if (element.classList && element.classList.contains("core-dialog"))
247
+ return true;
248
+ if (element.parentElement && isInsideCoreDialog(element.parentElement))
249
+ return true;
250
+ }
251
+ else {
252
+ // istanbul ignore else
253
+ if (element.parentElement && isInsideCoreDialog(element.parentElement))
254
+ return true;
255
+ }
256
+ return false;
257
+ }, []);
258
+ const handleOutsideClick = React.useCallback((event) => {
259
+ if (isInsideCoreDialog(event.target)) {
260
+ return;
261
+ }
262
+ // If clicking on button that open panel - don't trigger outside click processing
263
+ if ((buttonRef === null || buttonRef === void 0 ? void 0 : buttonRef.current) && (buttonRef === null || buttonRef === void 0 ? void 0 : buttonRef.current.contains(event.target))) {
264
+ return;
265
+ }
266
+ // If clicking the panel, this is not an outside clicked
267
+ if (panelRef.current && (panelRef === null || panelRef === void 0 ? void 0 : panelRef.current.contains(event.target))) {
268
+ return;
269
+ }
270
+ // If we reach this point, we got an outside clicked, no close the popup
271
+ setPopupOpen(false);
272
+ }, [isInsideCoreDialog]);
273
+ const { refreshFromStyle } = useSourceMapContext();
274
+ const handleLayerAttached = React.useCallback(() => {
275
+ if (!isMounted.current) {
276
+ return;
277
+ }
278
+ setPopupOpen(false);
279
+ refreshFromStyle();
280
+ }, [refreshFromStyle]);
281
+ function renderButton() {
282
+ let button;
283
+ if (props.buttonType === undefined || props.buttonType === AttachLayerButtonType.Icon) {
284
+ button = (React.createElement("button", { ref: buttonRef, className: "map-manager-attach-layer-button", title: popupOpen ? hideAttachLayerLabel : showAttachLayerLabel, onClick: togglePopup },
285
+ React.createElement(UiCore.WebFontIcon, { iconName: "icon-add" })));
286
+ }
287
+ else {
288
+ const determineStyleType = () => {
289
+ switch (props.buttonType) {
290
+ case AttachLayerButtonType.Blue:
291
+ return "high-visibility";
292
+ case AttachLayerButtonType.Primary:
293
+ default:
294
+ return "cta";
295
+ }
296
+ };
297
+ const styleType = determineStyleType();
298
+ button = (React.createElement(Button, { ref: buttonRef, styleType: styleType, title: popupOpen ? hideAttachLayerLabel : showAttachLayerLabel, onClick: togglePopup }, addCustomLayerButtonLabel));
299
+ }
300
+ return button;
301
+ }
302
+ return (React.createElement(React.Fragment, null,
303
+ renderButton(),
304
+ React.createElement(UiCore.Popup, { isOpen: popupOpen, position: RelativePosition.BottomRight, onClose: handleClosePopup, onOutsideClick: handleOutsideClick, target: buttonRef.current, closeOnEnter: false },
305
+ React.createElement("div", { ref: panelRef, className: "map-sources-popup-panel" },
306
+ React.createElement(AttachLayerPanel, { isOverlay: props.isOverlay, onLayerAttached: handleLayerAttached })))));
307
+ }
308
+ //# sourceMappingURL=AttachLayerPopupButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AttachLayerPopupButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport * as React from \"react\";\r\nimport { IModelApp, MapLayerSettingsService, MapLayerSource, MapLayerSourceStatus, NotifyMessageDetails, OutputMessagePriority } from \"@itwin/core-frontend\";\r\nimport { RelativePosition } from \"@itwin/appui-abstract\";\r\nimport * as UiCore from \"@itwin/core-react\";\r\nimport { ModalDialogManager } from \"@itwin/appui-react\";\r\nimport { useSourceMapContext } from \"./MapLayerManager\";\r\nimport { MapUrlDialog } from \"./MapUrlDialog\";\r\nimport { MapLayersUiItemsProvider } from \"../MapLayersUiItemsProvider\";\r\nimport { ConfirmMessageDialog } from \"./ConfirmMessageDialog\";\r\nimport { Button, Input } from \"@itwin/itwinui-react\";\r\n\r\n// cSpell:ignore droppable Sublayer\r\n\r\ninterface AttachLayerPanelProps {\r\n isOverlay: boolean;\r\n onLayerAttached: () => void;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nfunction AttachLayerPanel({ isOverlay, onLayerAttached }: AttachLayerPanelProps) {\r\n const [layerNameToAdd, setLayerNameToAdd] = React.useState<string | undefined>();\r\n const [sourceFilterString, setSourceFilterString] = React.useState<string | undefined>();\r\n const [placeholderLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.SearchPlaceholder\"));\r\n const [addCustomLayerLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.Custom\"));\r\n const [addCustomLayerToolTip] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.AttachCustomLayer\"));\r\n const [loadingMapSources] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.LoadingMapSources\"));\r\n const [removeLayerDefButtonTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefButtonTitle\"));\r\n const [editLayerDefButtonTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.EditLayerDefButtonTitle\"));\r\n const [removeLayerDefDialogTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefDialogTitle\"));\r\n const [loading, setLoading] = React.useState(false);\r\n const [layerNameUnderCursor, setLayerNameUnderCursor] = React.useState<string | undefined>();\r\n\r\n // 'isMounted' is used to prevent any async operation once the hook has been\r\n // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.\r\n const isMounted = React.useRef(false);\r\n React.useEffect(() => {\r\n isMounted.current = true;\r\n return () => {\r\n isMounted.current = false;\r\n\r\n // We close any open dialogs that we might have opened\r\n // This was added because the modal dialog remained remained displayed after the session expired.\r\n ModalDialogManager.closeDialog();\r\n };\r\n }, []);\r\n\r\n const handleFilterTextChanged = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\r\n setSourceFilterString(event.target.value);\r\n }, []);\r\n\r\n const { loadingSources, sources, activeViewport, backgroundLayers, overlayLayers, mapTypesOptions } = useSourceMapContext();\r\n const iTwinId = activeViewport?.iModel?.iTwinId;\r\n const iModelId = activeViewport?.iModel?.iModelId;\r\n\r\n const styleContainsLayer = React.useCallback((name: string) => {\r\n if (backgroundLayers) {\r\n if (-1 !== backgroundLayers.findIndex((layer) => layer.name === name))\r\n return true;\r\n }\r\n if (overlayLayers) {\r\n if (-1 !== overlayLayers.findIndex((layer) => layer.name === name))\r\n return true;\r\n }\r\n return false;\r\n }, [backgroundLayers, overlayLayers]);\r\n\r\n const handleModalUrlDialogOk = React.useCallback(() => {\r\n // close popup and refresh UI\r\n onLayerAttached();\r\n }, [onLayerAttached]);\r\n\r\n const handleModalUrlDialogCancel = React.useCallback(() => {\r\n // close popup and refresh UI\r\n setLoading(false);\r\n ModalDialogManager.closeDialog();\r\n }, []);\r\n\r\n React.useEffect(() => {\r\n async function attemptToAddLayer(layerName: string) {\r\n if (layerName && activeViewport) {\r\n // if the layer is not in the style add it now.\r\n if (undefined === backgroundLayers?.find((layer) => layerName === layer.name) && undefined === overlayLayers?.find((layer) => layerName === layer.name)) {\r\n const mapLayerSettings = sources?.find((source) => source.name === layerName);\r\n if (mapLayerSettings === undefined) {\r\n return;\r\n }\r\n\r\n try {\r\n if (isMounted.current) {\r\n setLoading(true);\r\n }\r\n\r\n const { status, subLayers } = await mapLayerSettings.validateSource();\r\n if (status === MapLayerSourceStatus.Valid || status === MapLayerSourceStatus.RequireAuth) {\r\n\r\n if (status === MapLayerSourceStatus.Valid) {\r\n const layerSettings = mapLayerSettings.toLayerSettings(subLayers);\r\n\r\n if (layerSettings) {\r\n activeViewport.displayStyle.attachMapLayerSettings(layerSettings, isOverlay);\r\n\r\n activeViewport.invalidateRenderPlan();\r\n\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerAttached\", { sourceName: layerSettings.name, sourceUrl: layerSettings.url });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\r\n }\r\n\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n if (onLayerAttached) {\r\n onLayerAttached();\r\n }\r\n\r\n } else if (status === MapLayerSourceStatus.RequireAuth && isMounted.current) {\r\n ModalDialogManager.openDialog(\r\n <MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n layerRequiringCredentials={mapLayerSettings.toJSON()}\r\n onOkResult={handleModalUrlDialogOk}\r\n onCancelResult={handleModalUrlDialogCancel}\r\n mapTypesOptions={mapTypesOptions} />\r\n );\r\n }\r\n\r\n } else {\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerValidationFailed\", { sourceUrl: mapLayerSettings.url });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n }\r\n } catch (err) {\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerAttachError\", { error: err, sourceUrl: mapLayerSettings.url });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n }\r\n }\r\n\r\n }\r\n return;\r\n }\r\n\r\n if (layerNameToAdd) {\r\n attemptToAddLayer(layerNameToAdd); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n\r\n if (isMounted.current) {\r\n setLayerNameToAdd(undefined);\r\n }\r\n }\r\n }, [setLayerNameToAdd, layerNameToAdd, activeViewport, sources, backgroundLayers, isOverlay, overlayLayers, onLayerAttached, handleModalUrlDialogOk, mapTypesOptions, handleModalUrlDialogCancel]);\r\n\r\n const options = React.useMemo(() => sources?.filter((source) => !styleContainsLayer(source.name)), [sources, styleContainsLayer]);\r\n const filteredOptions = React.useMemo(() => {\r\n if (undefined === sourceFilterString || 0 === sourceFilterString.length) {\r\n return options;\r\n } else {\r\n return options?.filter((option) => option.name.toLowerCase().includes(sourceFilterString?.toLowerCase()));\r\n }\r\n }, [options, sourceFilterString]);\r\n\r\n const handleAddNewMapSource = React.useCallback(() => {\r\n ModalDialogManager.openDialog(<MapUrlDialog activeViewport={activeViewport} isOverlay={isOverlay} onOkResult={handleModalUrlDialogOk} mapTypesOptions={mapTypesOptions} />);\r\n return;\r\n }, [activeViewport, handleModalUrlDialogOk, isOverlay, mapTypesOptions]);\r\n\r\n const handleAttach = React.useCallback((mapName: string) => {\r\n setLayerNameToAdd(mapName);\r\n }, []);\r\n\r\n const handleKeypressOnSourceList = React.useCallback((event: React.KeyboardEvent<HTMLUListElement>) => {\r\n const key = event.key;\r\n if (key === \"Enter\") {\r\n event.preventDefault();\r\n const mapName = event.currentTarget?.dataset?.value;\r\n if (mapName && mapName.length) {\r\n handleAttach(mapName);\r\n }\r\n }\r\n }, [handleAttach]);\r\n\r\n const onListboxValueChange = React.useCallback((mapName: string) => {\r\n setLayerNameToAdd(mapName);\r\n }, []);\r\n\r\n const handleNoConfirmation = React.useCallback((_layerName: string) => {\r\n ModalDialogManager.closeDialog();\r\n }, []);\r\n\r\n const handleYesConfirmation = React.useCallback(async (source: MapLayerSource) => {\r\n\r\n const layerName = source.name;\r\n if (!!iTwinId && !!iModelId) {\r\n if (await MapLayerSettingsService.deleteSharedSettings(source, iTwinId, iModelId)) {\r\n const msg = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefSuccess\", { layerName });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\r\n } else {\r\n const msg = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefError\", { layerName });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n }\r\n }\r\n\r\n ModalDialogManager.closeDialog();\r\n }, [iTwinId, iModelId]);\r\n\r\n /*\r\n Handle Remove layer button clicked\r\n */\r\n const onItemRemoveButtonClicked = React.useCallback((source, event) => {\r\n event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.\r\n\r\n const layerName = source.name;\r\n\r\n const msg = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefDialogMessage\", { layerName });\r\n ModalDialogManager.openDialog(\r\n <ConfirmMessageDialog\r\n className=\"map-sources-delete-confirmation\"\r\n title={removeLayerDefDialogTitle}\r\n message={msg}\r\n maxWidth={400}\r\n onClose={() => handleNoConfirmation(layerName)}\r\n onEscape={() => handleNoConfirmation(layerName)}\r\n onYesResult={async () => handleYesConfirmation(source)}\r\n onNoResult={() => handleNoConfirmation(layerName)}\r\n />\r\n );\r\n }, [handleNoConfirmation, handleYesConfirmation, removeLayerDefDialogTitle]);\r\n\r\n /*\r\n Handle Edit layer button clicked\r\n */\r\n const onItemEditButtonClicked = React.useCallback((event) => {\r\n event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.\r\n\r\n const targetLayerName = event?.currentTarget?.parentNode?.dataset?.value;\r\n const matchingSource = sources.find((layerSource) => layerSource.name === targetLayerName);\r\n\r\n // we expect a single layer source matching this name\r\n if (matchingSource === undefined) {\r\n return;\r\n }\r\n ModalDialogManager.openDialog(<MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n mapLayerSourceToEdit={matchingSource}\r\n onOkResult={handleModalUrlDialogOk}\r\n mapTypesOptions={mapTypesOptions} />);\r\n }, [activeViewport, handleModalUrlDialogOk, isOverlay, mapTypesOptions, sources]);\r\n\r\n return (\r\n <div className=\"map-manager-header\">\r\n {(loading || loadingSources) && <UiCore.LoadingSpinner message={loadingMapSources} />}\r\n <div className=\"map-manager-source-listbox-header\">\r\n <Input type=\"text\" className=\"map-manager-source-list-filter\"\r\n placeholder={placeholderLabel}\r\n value={sourceFilterString}\r\n onChange={handleFilterTextChanged} />\r\n <Button className=\"map-manager-add-source-button\" title={addCustomLayerToolTip} onClick={handleAddNewMapSource}>\r\n {addCustomLayerLabel}</Button>\r\n </div>\r\n <div className=\"map-manager-sources\">\r\n <UiCore.Listbox\r\n id=\"map-sources\"\r\n selectedValue={layerNameToAdd}\r\n className=\"map-manager-source-list\"\r\n onKeyPress={handleKeypressOnSourceList}\r\n onListboxValueChange={onListboxValueChange} >\r\n {\r\n filteredOptions?.map((source) =>\r\n <UiCore.ListboxItem\r\n key={source.name}\r\n className=\"map-source-list-entry\"\r\n value={source.name}\r\n onMouseEnter={() => setLayerNameUnderCursor(source.name)}\r\n onMouseLeave={() => setLayerNameUnderCursor(undefined)}>\r\n <span className=\"map-source-list-entry-name\" title={source.name}>{source.name}</span>\r\n\r\n { // Display the delete icon only when the mouse over a specific item\r\n // otherwise list feels cluttered.\r\n (!!iTwinId && !!iModelId && layerNameUnderCursor && layerNameUnderCursor === source.name) &&\r\n <>\r\n <Button\r\n className=\"map-source-list-entry-button\"\r\n title={editLayerDefButtonTitle}\r\n onClick={onItemEditButtonClicked}>\r\n <UiCore.Icon iconSpec=\"icon-edit\" />\r\n </Button>\r\n <Button\r\n className=\"map-source-list-entry-button\"\r\n title={removeLayerDefButtonTitle}\r\n onClick={(event: React.MouseEvent) => { onItemRemoveButtonClicked(source, event); }}>\r\n <UiCore.Icon iconSpec=\"icon-delete\" />\r\n </Button>\r\n </>}\r\n\r\n </UiCore.ListboxItem>\r\n )\r\n }\r\n </UiCore.Listbox>\r\n </div>\r\n </div>\r\n\r\n );\r\n}\r\n\r\n/** @internal */\r\nexport enum AttachLayerButtonType {\r\n Primary,\r\n Blue,\r\n Icon\r\n}\r\nexport interface AttachLayerPopupButtonProps {\r\n isOverlay: boolean;\r\n buttonType?: AttachLayerButtonType;\r\n}\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function AttachLayerPopupButton(props: AttachLayerPopupButtonProps) {\r\n const [showAttachLayerLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:AttachLayerPopup.Attach\"));\r\n const [hideAttachLayerLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:AttachLayerPopup.Close\"));\r\n const [addCustomLayerButtonLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.AddCustomLayerButtonLabel\"));\r\n const [popupOpen, setPopupOpen] = React.useState(false);\r\n const buttonRef = React.useRef<HTMLButtonElement>(null);\r\n const panelRef = React.useRef<HTMLDivElement>(null);\r\n\r\n // 'isMounted' is used to prevent any async operation once the hook has been\r\n // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.\r\n const isMounted = React.useRef(false);\r\n React.useEffect(() => {\r\n isMounted.current = true;\r\n return () => {\r\n isMounted.current = false;\r\n };\r\n }, []);\r\n\r\n const togglePopup = React.useCallback(() => {\r\n setPopupOpen(!popupOpen);\r\n }, [popupOpen]);\r\n\r\n const handleClosePopup = React.useCallback(() => {\r\n setPopupOpen(false);\r\n }, []);\r\n\r\n const isInsideCoreDialog = React.useCallback((element: HTMLElement) => {\r\n if (element.nodeName === \"DIV\") {\r\n if (element.classList && element.classList.contains(\"core-dialog\"))\r\n return true;\r\n if (element.parentElement && isInsideCoreDialog(element.parentElement))\r\n return true;\r\n } else {\r\n // istanbul ignore else\r\n if (element.parentElement && isInsideCoreDialog(element.parentElement))\r\n return true;\r\n }\r\n return false;\r\n }, []);\r\n\r\n const handleOutsideClick = React.useCallback((event: MouseEvent) => {\r\n if (isInsideCoreDialog(event.target as HTMLElement)) {\r\n return;\r\n }\r\n\r\n // If clicking on button that open panel - don't trigger outside click processing\r\n if (buttonRef?.current && buttonRef?.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n\r\n // If clicking the panel, this is not an outside clicked\r\n if (panelRef.current && panelRef?.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n\r\n // If we reach this point, we got an outside clicked, no close the popup\r\n setPopupOpen(false);\r\n\r\n }, [isInsideCoreDialog]);\r\n\r\n const { refreshFromStyle } = useSourceMapContext();\r\n\r\n const handleLayerAttached = React.useCallback(() => {\r\n if (!isMounted.current) {\r\n return;\r\n }\r\n setPopupOpen(false);\r\n refreshFromStyle();\r\n }, [refreshFromStyle]);\r\n\r\n function renderButton(): React.ReactNode {\r\n let button: React.ReactNode;\r\n\r\n if (props.buttonType === undefined || props.buttonType === AttachLayerButtonType.Icon) {\r\n button = (\r\n <button ref={buttonRef} className=\"map-manager-attach-layer-button\" title={popupOpen ? hideAttachLayerLabel : showAttachLayerLabel}\r\n onClick={togglePopup}>\r\n <UiCore.WebFontIcon iconName=\"icon-add\" />\r\n </button>\r\n );\r\n } else {\r\n const determineStyleType = () => {\r\n switch (props.buttonType) {\r\n case AttachLayerButtonType.Blue:\r\n return \"high-visibility\";\r\n case AttachLayerButtonType.Primary:\r\n default:\r\n return \"cta\";\r\n }\r\n };\r\n const styleType = determineStyleType();\r\n button = (\r\n <Button ref={buttonRef} styleType={styleType} title={popupOpen ? hideAttachLayerLabel : showAttachLayerLabel}\r\n onClick={togglePopup}>{addCustomLayerButtonLabel}</Button>\r\n );\r\n }\r\n\r\n return button;\r\n }\r\n\r\n return (\r\n <>\r\n {renderButton()}\r\n <UiCore.Popup\r\n isOpen={popupOpen}\r\n position={RelativePosition.BottomRight}\r\n onClose={handleClosePopup}\r\n onOutsideClick={handleOutsideClick}\r\n target={buttonRef.current}\r\n closeOnEnter={false}\r\n >\r\n <div ref={panelRef} className=\"map-sources-popup-panel\" >\r\n <AttachLayerPanel isOverlay={props.isOverlay} onLayerAttached={handleLayerAttached} />\r\n </div>\r\n </UiCore.Popup >\r\n </>\r\n );\r\n}\r\n"]}
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import "./BasemapPanel.scss";
3
+ /** @internal */
4
+ export declare function BasemapPanel(): JSX.Element;
5
+ //# sourceMappingURL=BasemapPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasemapPanel.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/BasemapPanel.tsx"],"names":[],"mappings":";AAgBA,OAAO,qBAAqB,CAAC;AAiB7B,gBAAgB;AAEhB,wBAAgB,YAAY,gBAwI3B"}