@evergis/react 4.0.132 → 4.0.133

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 (34) hide show
  1. package/dist/components/Dashboard/componentTypes.d.ts +1 -1
  2. package/dist/components/Dashboard/components/ContainerBackground/constants.d.ts +15 -0
  3. package/dist/components/Dashboard/components/ContainerBackground/index.d.ts +15 -0
  4. package/dist/components/Dashboard/components/ContainerBackground/styled.d.ts +42 -0
  5. package/dist/components/Dashboard/components/ContainerBackground/types.d.ts +2 -0
  6. package/dist/components/Dashboard/components/index.d.ts +1 -0
  7. package/dist/components/Dashboard/constants.d.ts +16 -0
  8. package/dist/components/Dashboard/containers/AttachmentContainer/styled.d.ts +2 -1
  9. package/dist/components/Dashboard/containers/IconContainer/styled.d.ts +2 -1
  10. package/dist/components/Dashboard/containers/ProgressContainer/styled.d.ts +2 -1
  11. package/dist/components/Dashboard/containers/RoundedBackgroundContainer/styled.d.ts +2 -1
  12. package/dist/components/Dashboard/containers/StructuredDataContainer/hooks/useStructuredData.d.ts +3 -1
  13. package/dist/components/Dashboard/containers/StructuredDataContainer/styled.d.ts +9 -7
  14. package/dist/components/Dashboard/containers/StructuredDataContainer/types.d.ts +7 -1
  15. package/dist/components/Dashboard/containers/TabsContainer/styled.d.ts +2 -1
  16. package/dist/components/Dashboard/grid/utils/gridTracks.d.ts +2 -2
  17. package/dist/components/Dashboard/grid/utils/gridTree.d.ts +2 -2
  18. package/dist/components/Dashboard/headers/FeatureCardSlideshowHeader/styled.d.ts +0 -1
  19. package/dist/components/Dashboard/hooks/index.d.ts +1 -0
  20. package/dist/components/Dashboard/hooks/useBgImageHost.d.ts +12 -0
  21. package/dist/components/Dashboard/hooks/useWrapperSize.d.ts +6 -1
  22. package/dist/components/Dashboard/styled/common.d.ts +7 -0
  23. package/dist/components/Dashboard/{styled.d.ts → styled/containers.d.ts} +3 -32
  24. package/dist/components/Dashboard/styled/dashboard.d.ts +11 -0
  25. package/dist/components/Dashboard/styled/index.d.ts +16 -0
  26. package/dist/components/Dashboard/styled/presentation.d.ts +15 -0
  27. package/dist/components/Dashboard/types.d.ts +28 -0
  28. package/dist/components/Dashboard/utils/hasContainerBgImage.d.ts +8 -0
  29. package/dist/components/Dashboard/utils/index.d.ts +1 -0
  30. package/dist/index.js +1456 -1247
  31. package/dist/index.js.map +1 -1
  32. package/dist/react.esm.js +1452 -1248
  33. package/dist/react.esm.js.map +1 -1
  34. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -3319,6 +3319,22 @@ const CONFIG_PAGE_ID = "page";
3319
3319
  * `grid-template-*`, иначе слот заголовка съест трек и раскладка съедет.
3320
3320
  */
3321
3321
  const TITLE_SLOT_IDS = ["title", "icon", "titleIcon"];
3322
+ /**
3323
+ * Универсальный slot-id фонового изображения контейнера.
3324
+ *
3325
+ * Допустим у любого контейнера, кроме `Divider`, и поэтому не перечисляется в наборах слотов —
3326
+ * ровно как слоты заголовка. Узел рисуется отдельным слоем `ContainerBackgroundLayer`
3327
+ * (см. `ContainerBackground`), а не через общий рендер детей.
3328
+ */
3329
+ const BG_IMAGE_SLOT_ID = "bgImage";
3330
+ /**
3331
+ * Slot-id, которые контейнер читает по `id` сам и не отдаёт ни в общий рендер тела
3332
+ * (`ContainerChildren`), ни в треки сетки (`gridTracks`/`gridTree`).
3333
+ *
3334
+ * Без `bgImage` в этом наборе фон группы отрисовался бы дважды: слоем и обычным ребёнком —
3335
+ * а в сетке ещё и съел бы трек.
3336
+ */
3337
+ const NON_TRACK_SLOT_IDS = [...TITLE_SLOT_IDS, BG_IMAGE_SLOT_ID];
3322
3338
  const DEFAULT_PAGES_CONFIG = {
3323
3339
  id: CONFIG_PAGES_ID,
3324
3340
  templateName: exports.ContainerTemplate.Pages,
@@ -4734,19 +4750,83 @@ const DashboardChip$1 = styled(uilibGl.Chip).withConfig({ displayName: "Dashboar
4734
4750
  ${({ $fontColor, $isDefault }) => !!$fontColor && !$isDefault && CustomChipColorMixin}
4735
4751
  `;
4736
4752
 
4737
- const LayersListWrapper = styled(uilibGl.Flex).withConfig({ displayName: "LayersListWrapper", componentId: "sc-10siqjn" }) `
4738
- flex-direction: column;
4739
- height: 100%;
4740
- width: 100%;
4741
- box-sizing: border-box;
4753
+ /**
4754
+ * Внутренний отступ корня контейнера при `options.innerPadding`.
4755
+ *
4756
+ * Значение фиксировано намеренно: опция булева, автор конфига включает «отступ от краёв фона»,
4757
+ * а не подбирает число — для произвольного отступа есть `options.padding`.
4758
+ */
4759
+ const CONTAINER_INNER_PADDING = "1rem";
4760
+ /**
4761
+ * Вылет слоя `bgImage` за края контейнера при `options.outflow` — по бокам и вверх.
4762
+ *
4763
+ * Ровно `padding` карточки контейнера (`ContainerWrapper` в `Dashboard/styled/containers.ts`): картинка
4764
+ * дотягивается до краёв колонки дашборда, а содержимое остаётся на месте. Вниз слой не
4765
+ * вытекает — там начинается следующий контейнер.
4766
+ */
4767
+ const BG_IMAGE_OUTFLOW = "1.5rem";
4768
+
4769
+ /**
4770
+ * Слой фонового изображения контейнера: единственный ребёнок, который рисуется ПОД содержимым.
4771
+ *
4772
+ * `z-index: -1` работает только внутри собственного stacking-контекста хоста (`isolation: isolate`
4773
+ * в `bgImageHostMixin`): там отрицательный слой ложится поверх фона хоста, но под его контентом.
4774
+ * Без изоляции он ушёл бы под фон ближайшего предка-контекста и пропал.
4775
+ *
4776
+ * `border-radius: inherit` повторяет скругление хоста, `pointer-events: none` оставляет клики
4777
+ * содержимому.
4778
+ *
4779
+ * `options.outflow` растягивает слой отрицательным `inset` — раскладка хоста при этом не
4780
+ * меняется: слой абсолютный, содержимое остаётся в своих границах, вытекает только картинка.
4781
+ * Вылет идёт по бокам и вверх, но НЕ вниз: снизу картинка обязана заканчиваться по краю
4782
+ * контейнера, иначе она наползала бы на следующий контейнер колонки.
4783
+ */
4784
+ const ContainerBackgroundLayer = styled.div.withConfig({ displayName: "ContainerBackgroundLayer", componentId: "sc-1ws6t58" }) `
4785
+ position: absolute;
4786
+ inset: ${({ $outflow }) => ($outflow ? `-${BG_IMAGE_OUTFLOW} -${BG_IMAGE_OUTFLOW} 0` : "0")};
4787
+ z-index: -1;
4788
+ overflow: hidden;
4789
+ border-radius: inherit;
4790
+ pointer-events: none;
4791
+
4792
+ img {
4793
+ width: 100%;
4794
+ height: 100%;
4795
+ object-position: center;
4796
+ object-fit: cover;
4797
+ }
4742
4798
  `;
4743
- const LayerListContainer = styled(uilibGl.Flex).withConfig({ displayName: "LayerListContainer", componentId: "sc-vfvx64" }) `
4744
- flex-grow: 1;
4745
- height: 100%;
4746
- box-sizing: border-box;
4747
- padding-top: 0.25rem;
4799
+ /**
4800
+ * Хост фонового слоя: корень контейнера, у которого в конфиге есть слот `bgImage`.
4801
+ *
4802
+ * Гейт по `$hasBgImage` принципиален — `position: relative` меняет containing block для
4803
+ * абсолютно позиционированных потомков (контролы слайдшоу, подписи прогресса), поэтому
4804
+ * включается только там, где автор конфига действительно попросил фон.
4805
+ *
4806
+ * `$innerPadding` (`options.innerPadding`) — отдельный гейт: отступ содержимого нужен и без
4807
+ * фона, поэтому он не привязан к `$hasBgImage`. `&&` поднимает специфичность до двух классов,
4808
+ * чтобы перебить `padding` из `$sizeCss` и собственных `defaults` контейнера; авторский inline
4809
+ * `style` по-прежнему сильнее — как и задумано.
4810
+ *
4811
+ * Модуль намеренно листовой: его импортирует `Dashboard/styled/containers.ts`, и обратная зависимость
4812
+ * замкнула бы цикл, уронив миксин в TDZ на инициализации.
4813
+ */
4814
+ const bgImageHostMixin = styled.css `
4815
+ ${({ $hasBgImage }) => !!$hasBgImage &&
4816
+ styled.css `
4817
+ position: relative;
4818
+ isolation: isolate;
4819
+ `};
4820
+
4821
+ ${({ $innerPadding }) => !!$innerPadding &&
4822
+ styled.css `
4823
+ && {
4824
+ padding: ${CONTAINER_INNER_PADDING};
4825
+ }
4826
+ `};
4748
4827
  `;
4749
4828
 
4829
+ /** Корень, тело и обёртка контейнера — и общие для них миксины размеров и отступов. */
4750
4830
  /**
4751
4831
  * Размеры контейнера из конфига.
4752
4832
  *
@@ -4785,7 +4865,7 @@ const noMarginMixin = styled.css `
4785
4865
  * `$sizeTransparent` поэтому работает только на контейнерах, которые ещё не переведены
4786
4866
  * на `useContainerRoot`.
4787
4867
  */
4788
- const ElementValueWrapper = styled.div.withConfig({ displayName: "ElementValueWrapper", componentId: "sc-dnq3zl" }) `
4868
+ const ElementValueWrapper = styled.div.withConfig({ displayName: "ElementValueWrapper", componentId: "sc-x3ra9l" }) `
4789
4869
  transition: background-color ${uilibGl.transition.toggle};
4790
4870
 
4791
4871
  ${({ noMargin }) => !!noMargin &&
@@ -4815,14 +4895,15 @@ const ElementValueWrapper = styled.div.withConfig({ displayName: "ElementValueWr
4815
4895
  * Всегда flex-колонка: заголовок и тело раньше были flex-элементами родительского `Container`,
4816
4896
  * и блочная обёртка вернула бы схлопывание вертикальных отступов между ними.
4817
4897
  */
4818
- const ContainerRoot = styled(uilibGl.Flex).withConfig({ displayName: "ContainerRoot", componentId: "sc-2j6lbd" }) `
4898
+ const ContainerRoot = styled(uilibGl.Flex).withConfig({ displayName: "ContainerRoot", componentId: "sc-1m2pft5" }) `
4819
4899
  flex-direction: column;
4820
4900
  min-width: 0;
4821
4901
 
4822
4902
  ${sizeCssMixin};
4823
4903
  ${noMarginMixin};
4904
+ ${bgImageHostMixin};
4824
4905
  `;
4825
- const Container = styled(uilibGl.Flex).withConfig({ displayName: "Container", componentId: "sc-1o8dsu2" }) `
4906
+ const Container = styled(uilibGl.Flex).withConfig({ displayName: "Container", componentId: "sc-px8dv0" }) `
4826
4907
  flex-direction: column;
4827
4908
  width: 100%;
4828
4909
 
@@ -4875,8 +4956,9 @@ const Container = styled(uilibGl.Flex).withConfig({ displayName: "Container", co
4875
4956
  `}
4876
4957
 
4877
4958
  ${sizeCssMixin};
4959
+ ${bgImageHostMixin};
4878
4960
  `;
4879
- const ContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "ContainerWrapper", componentId: "sc-16tb6s0" }) `
4961
+ const ContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "ContainerWrapper", componentId: "sc-1eb7t8v" }) `
4880
4962
  position: relative;
4881
4963
  box-sizing: border-box;
4882
4964
  width: 100%;
@@ -4897,7 +4979,9 @@ const ContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "Contain
4897
4979
  }
4898
4980
  `}
4899
4981
  `;
4900
- const DashboardChip = styled(uilibGl.Chip).withConfig({ displayName: "DashboardChip", componentId: "sc-19j7obx" }) `
4982
+
4983
+ /** Каркас дашборда: обёртка страницы, область контента, плейсхолдеры и чип значения. */
4984
+ const DashboardChip = styled(uilibGl.Chip).withConfig({ displayName: "DashboardChip", componentId: "sc-a3pqro" }) `
4901
4985
  margin: 0 0.25rem 0.25rem 0;
4902
4986
  background: ${({ $isDefault, $bgColor, theme: { palette } }) => $isDefault ? palette.element : $bgColor || palette.primary};
4903
4987
  border-radius: ${({ $radius, theme: { borderRadius } }) => $radius || borderRadius.medium};
@@ -4913,7 +4997,7 @@ const DashboardChip = styled(uilibGl.Chip).withConfig({ displayName: "DashboardC
4913
4997
  color: ${({ $isDefault, $fontColor, theme: { palette } }) => $isDefault ? palette.icon : $fontColor || "#fff"};
4914
4998
  }
4915
4999
  `;
4916
- const DashboardPlaceholderWrap = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholderWrap", componentId: "sc-anwihw" }) `
5000
+ const DashboardPlaceholderWrap = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholderWrap", componentId: "sc-qnoieo" }) `
4917
5001
  flex-grow: 1;
4918
5002
  flex-direction: column;
4919
5003
  justify-content: center;
@@ -4921,7 +5005,7 @@ const DashboardPlaceholderWrap = styled(uilibGl.Flex).withConfig({ displayName:
4921
5005
  width: 100%;
4922
5006
  margin-bottom: 2rem;
4923
5007
  `;
4924
- const DashboardPlaceholder = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholder", componentId: "sc-jry8vp" }) `
5008
+ const DashboardPlaceholder = styled(uilibGl.Flex).withConfig({ displayName: "DashboardPlaceholder", componentId: "sc-18za1l3" }) `
4925
5009
  flex-direction: column;
4926
5010
  justify-content: center;
4927
5011
  align-items: center;
@@ -4954,7 +5038,7 @@ const DashboardPlaceholder = styled(uilibGl.Flex).withConfig({ displayName: "Das
4954
5038
  }
4955
5039
  }
4956
5040
  `;
4957
- const DashboardWrapper = styled(uilibGl.Flex).withConfig({ displayName: "DashboardWrapper", componentId: "sc-100ipup" }) `
5041
+ const DashboardWrapper = styled(uilibGl.Flex).withConfig({ displayName: "DashboardWrapper", componentId: "sc-tnxl47" }) `
4958
5042
  flex-direction: column;
4959
5043
  flex-wrap: nowrap;
4960
5044
  flex-grow: 1;
@@ -4967,13 +5051,28 @@ const DashboardWrapper = styled(uilibGl.Flex).withConfig({ displayName: "Dashboa
4967
5051
  margin-top: -0.35rem;
4968
5052
  `}
4969
5053
  `;
4970
- const DashboardContent = styled(uilibGl.Flex).withConfig({ displayName: "DashboardContent", componentId: "sc-77il9k" }) `
5054
+ const DashboardContent = styled(uilibGl.Flex).withConfig({ displayName: "DashboardContent", componentId: "sc-cqvhte" }) `
4971
5055
  flex-grow: 1;
4972
5056
  width: 100%;
4973
5057
  padding: 1.5rem 1.5rem 2rem;
4974
5058
  overflow-y: auto;
4975
5059
  scrollbar-gutter: stable;
4976
5060
  `;
5061
+
5062
+ const LayersListWrapper = styled(uilibGl.Flex).withConfig({ displayName: "LayersListWrapper", componentId: "sc-10siqjn" }) `
5063
+ flex-direction: column;
5064
+ height: 100%;
5065
+ width: 100%;
5066
+ box-sizing: border-box;
5067
+ `;
5068
+ const LayerListContainer = styled(uilibGl.Flex).withConfig({ displayName: "LayerListContainer", componentId: "sc-vfvx64" }) `
5069
+ flex-grow: 1;
5070
+ height: 100%;
5071
+ box-sizing: border-box;
5072
+ padding-top: 0.25rem;
5073
+ `;
5074
+
5075
+ /** Презентационный режим: карточки-панели поверх дашборда и левая панель со списком слоёв. */
4977
5076
  const PresentationWrapperCss = styled.css `
4978
5077
  margin-bottom: 0.75rem;
4979
5078
  padding: 1.5rem;
@@ -4982,16 +5081,16 @@ const PresentationWrapperCss = styled.css `
4982
5081
  border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
4983
5082
  box-shadow: ${uilibGl.shadows.raised};
4984
5083
  `;
4985
- const PresentationWrapper = styled.div.withConfig({ displayName: "PresentationWrapper", componentId: "sc-891z9z" }) `
5084
+ const PresentationWrapper = styled.div.withConfig({ displayName: "PresentationWrapper", componentId: "sc-15hokqp" }) `
4986
5085
  ${PresentationWrapperCss};
4987
5086
  position: relative;
4988
5087
  z-index: 1;
4989
5088
  `;
4990
- const PresentationPanelWrapper = styled(PresentationWrapper).withConfig({ displayName: "PresentationPanelWrapper", componentId: "sc-1ptpbt9" }) `
5089
+ const PresentationPanelWrapper = styled(PresentationWrapper).withConfig({ displayName: "PresentationPanelWrapper", componentId: "sc-qy34j6" }) `
4991
5090
  margin-top: 0.75rem;
4992
5091
  transition: background-color ${uilibGl.transition.toggle};
4993
5092
  `;
4994
- const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHeader", componentId: "sc-182b7wg" }) `
5093
+ const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHeader", componentId: "sc-iysakx" }) `
4995
5094
  margin: -1.5rem -1.5rem 0 -1.5rem;
4996
5095
  padding: 1.5rem;
4997
5096
  // background: url(images.presentationHeader) 0 0 no-repeat;
@@ -5003,7 +5102,7 @@ const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHea
5003
5102
  padding-top: 7rem;
5004
5103
  `};
5005
5104
  `;
5006
- const PresentationHeaderTools = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderTools", componentId: "sc-dms7fm" }) `
5105
+ const PresentationHeaderTools = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderTools", componentId: "sc-16o9l28" }) `
5007
5106
  justify-content: space-between;
5008
5107
  align-items: center;
5009
5108
  margin-bottom: -0.5rem;
@@ -5021,7 +5120,7 @@ const PresentationHeaderTools = styled(uilibGl.Flex).withConfig({ displayName: "
5021
5120
  }
5022
5121
  }
5023
5122
  `;
5024
- const LayerGroupList = styled(uilibGl.Flex).withConfig({ displayName: "LayerGroupList", componentId: "sc-19uothl" }) `
5123
+ const LayerGroupList = styled(uilibGl.Flex).withConfig({ displayName: "LayerGroupList", componentId: "sc-1o4tem9" }) `
5025
5124
  flex-direction: column;
5026
5125
  height: 100%;
5027
5126
  flex-wrap: nowrap;
@@ -5034,8 +5133,8 @@ const LayerGroupList = styled(uilibGl.Flex).withConfig({ displayName: "LayerGrou
5034
5133
  flex-grow: 1;
5035
5134
  }
5036
5135
  `;
5037
- const PresentationHeaderButtons = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderButtons", componentId: "sc-c24t7n" }) ``;
5038
- const PresentationPanelContainer = styled.div.withConfig({ displayName: "PresentationPanelContainer", componentId: "sc-17q0jzw" }) `
5136
+ const PresentationHeaderButtons = styled(uilibGl.Flex).withConfig({ displayName: "PresentationHeaderButtons", componentId: "sc-h3z1ud" }) ``;
5137
+ const PresentationPanelContainer = styled.div.withConfig({ displayName: "PresentationPanelContainer", componentId: "sc-rngq9i" }) `
5039
5138
  position: absolute;
5040
5139
  top: 0;
5041
5140
  left: calc(${({ left }) => left || 0}px + 0.75rem);
@@ -5104,7 +5203,9 @@ const PresentationPanelContainer = styled.div.withConfig({ displayName: "Present
5104
5203
  }
5105
5204
  }
5106
5205
  `;
5107
- const DataSourceErrorContainer = styled(uilibGl.Flex).withConfig({ displayName: "DataSourceErrorContainer", componentId: "sc-nh93ry" }) `
5206
+
5207
+ /** Общее для нескольких разделов: ошибка источника данных, подпись атрибута, кнопки объекта. */
5208
+ const DataSourceErrorContainer = styled(uilibGl.Flex).withConfig({ displayName: "DataSourceErrorContainer", componentId: "sc-1drfyq0" }) `
5108
5209
  align-items: center;
5109
5210
  justify-content: center;
5110
5211
  flex-wrap: nowrap;
@@ -5123,12 +5224,12 @@ const DataSourceErrorContainer = styled(uilibGl.Flex).withConfig({ displayName:
5123
5224
  }
5124
5225
  }
5125
5226
  `;
5126
- const AttributeLabel = styled(uilibGl.Description).withConfig({ displayName: "AttributeLabel", componentId: "sc-9u3noy" }) `
5227
+ const AttributeLabel = styled(uilibGl.Description).withConfig({ displayName: "AttributeLabel", componentId: "sc-96skzy" }) `
5127
5228
  margin-top: 0 !important;
5128
5229
  margin-bottom: ${({ forCheckbox }) => forCheckbox ? "0.75rem" : "0.25rem"} !important;
5129
5230
  padding-left: ${({ isEdit }) => (isEdit ? "0.5rem" : "0")};
5130
5231
  `;
5131
- const FeatureControls = styled(uilibGl.Flex).withConfig({ displayName: "FeatureControls", componentId: "sc-1wenq0r" }) `
5232
+ const FeatureControls = styled(uilibGl.Flex).withConfig({ displayName: "FeatureControls", componentId: "sc-zlqfd7" }) `
5132
5233
  align-items: center;
5133
5234
  gap: 1rem;
5134
5235
  flex-wrap: nowrap;
@@ -5643,124 +5744,459 @@ const useWidgetContext = (type = exports.WidgetType.Dashboard) => {
5643
5744
  };
5644
5745
  };
5645
5746
 
5646
- const useRenderContainerItem = (type, renderElement) => {
5647
- const { config, layerInfo, selectedTabId, attributes } = useWidgetContext(type);
5648
- return React.useCallback((elementConfig, attribute) => {
5649
- const { id, options, style, children } = elementConfig || {};
5650
- const { hideEmpty, innerTemplateStyle } = options || {};
5651
- const hasUnits = children?.some(item => item.id === "units");
5652
- const iconIndex = children?.findIndex(item => item.id === "icon");
5653
- const icon = children?.[iconIndex];
5654
- const hasIcon = !!icon;
5655
- const elementChildren = elementConfig?.children?.map(child => ({
5656
- type: "attributeValue",
5657
- ...child,
5658
- attributeName: attribute,
5659
- options: { noUnits: hasUnits, ...child.options },
5660
- }));
5661
- const attr = getAttributeConfigurationByName(getAttributesConfiguration(layerInfo).attributes, attribute);
5662
- if (hasIcon) {
5663
- elementChildren[iconIndex] = {
5664
- ...elementChildren[iconIndex],
5665
- ...getAttributeIconElement(attr?.icon),
5666
- attributeName: null,
5667
- };
5668
- }
5669
- const render = attribute
5670
- ? getRenderElement({
5671
- config,
5672
- elementConfig: {
5673
- ...elementConfig,
5674
- children: elementChildren,
5675
- },
5676
- selectedTabId,
5677
- attributes,
5678
- layerInfo,
5679
- type,
5680
- })
5681
- : renderElement;
5682
- const value = render({ id: "value" });
5747
+ const parseAttachments = (raw) => {
5748
+ if (!raw)
5749
+ return [];
5750
+ if (Array.isArray(raw))
5751
+ return raw;
5752
+ if (typeof raw !== "string")
5753
+ return [];
5754
+ try {
5755
+ const parsed = JSON.parse(raw);
5756
+ return Array.isArray(parsed) ? parsed : [];
5757
+ }
5758
+ catch {
5759
+ return [];
5760
+ }
5761
+ };
5762
+ const attachmentsFromFeatures = (features, mapping = {}) => {
5763
+ if (!features?.length)
5764
+ return [];
5765
+ const { attributeLink = "link", attributeName = "name", attributeMime = "mimeType", attributeDate = "date", } = mapping;
5766
+ return features
5767
+ .map(feature => {
5768
+ const link = feature.properties?.[attributeLink];
5769
+ if (!link)
5770
+ return null;
5683
5771
  return {
5684
- id,
5685
- value,
5686
- hideEmpty,
5687
- style: innerTemplateStyle || style,
5688
- hasIcon,
5689
- hasUnits,
5690
- render,
5772
+ link,
5773
+ name: feature.properties?.[attributeName] ?? link,
5774
+ mimeType: feature.properties?.[attributeMime] ?? "",
5775
+ date: feature.properties?.[attributeDate],
5776
+ isExternal: /^https?:\/\//.test(link),
5691
5777
  };
5692
- }, [config, layerInfo, selectedTabId, attributes, type, renderElement]);
5778
+ })
5779
+ .filter(Boolean);
5693
5780
  };
5694
5781
 
5695
- const customModes = MapboxDraw.modes;
5696
- const StaticMode = {};
5697
- const InvisibleMode = {};
5698
- StaticMode.onSetup = function () {
5699
- this.setActionableState(undefined);
5700
- return {};
5701
- };
5702
- StaticMode.toDisplayFeatures = function (state, geojson, display) {
5703
- display(geojson);
5782
+ const useAttachmentItems = ({ type, elementConfig, valueOverride, }) => {
5783
+ const { attributes, dataSources } = useWidgetContext(type);
5784
+ const { children, options } = elementConfig || {};
5785
+ const { relatedDataSource, controls } = options || {};
5786
+ const valueElement = React.useMemo(() => children?.find(({ id }) => id === "value"), [children]);
5787
+ const attributeName = React.useMemo(() => {
5788
+ const candidate = valueElement?.attributeName ?? elementConfig?.attributeName;
5789
+ return Array.isArray(candidate) ? candidate[0] : candidate;
5790
+ }, [valueElement, elementConfig]);
5791
+ const rawValue = React.useMemo(() => {
5792
+ if (valueOverride !== undefined)
5793
+ return valueOverride;
5794
+ if (!attributeName)
5795
+ return undefined;
5796
+ return attributes?.find(item => item.attributeName === attributeName)?.value;
5797
+ }, [valueOverride, attributeName, attributes]);
5798
+ const items = React.useMemo(() => {
5799
+ if (relatedDataSource) {
5800
+ const dataSource = dataSources?.find(({ name }) => name === relatedDataSource);
5801
+ const mapping = controls?.[0];
5802
+ return attachmentsFromFeatures(dataSource?.features, mapping);
5803
+ }
5804
+ return parseAttachments(rawValue);
5805
+ }, [relatedDataSource, dataSources, controls, rawValue]);
5806
+ return {
5807
+ items,
5808
+ attributeName,
5809
+ rawValue,
5810
+ };
5704
5811
  };
5705
- InvisibleMode.onSetup = function () {
5706
- this.setActionableState(undefined);
5707
- return {};
5812
+
5813
+ const useGlobalContext = () => {
5814
+ const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, notification } = React.useContext(GlobalContext) || {};
5815
+ const translate = React.useCallback((value, options) => {
5816
+ if (t)
5817
+ return t(value, options);
5818
+ return options?.defaultValue ?? value;
5819
+ }, [t]);
5820
+ return React.useMemo(() => ({
5821
+ t: translate,
5822
+ language,
5823
+ themeName,
5824
+ api,
5825
+ ewktGeometry,
5826
+ ewktExtent,
5827
+ zoomLevel,
5828
+ notification,
5829
+ }), [language, translate, api, ewktGeometry, ewktExtent, zoomLevel, themeName, notification]);
5708
5830
  };
5709
- InvisibleMode.toDisplayFeatures = function () { };
5710
- customModes.static = StaticMode;
5711
- customModes.invisible = InvisibleMode;
5712
5831
 
5713
- const customStyles = [
5714
- {
5715
- id: "gl-draw-point",
5716
- type: "circle",
5717
- filter: ["all", ["==", "$type", "Point"]],
5718
- paint: {
5719
- "circle-radius": 5,
5720
- "circle-color": "#D20C0C",
5721
- "circle-stroke-color": "#FFFFFF",
5722
- "circle-stroke-width": 3,
5723
- "circle-stroke-opacity": 0.3,
5724
- },
5725
- },
5726
- {
5727
- id: "highlight-inactive-points",
5728
- type: "circle",
5729
- filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "false"]],
5730
- paint: {
5731
- "circle-radius": 5,
5732
- "circle-color": "#D20C0C",
5733
- "circle-stroke-color": "#FFFFFF",
5734
- "circle-stroke-width": 3,
5735
- "circle-stroke-opacity": 0.3,
5736
- },
5737
- },
5738
- {
5739
- id: "highlight-active-points",
5740
- type: "circle",
5741
- filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "true"]],
5742
- paint: {
5743
- "circle-radius": 3,
5744
- "circle-color": "#fbb03b",
5745
- "circle-stroke-color": "#FFFFFF",
5746
- "circle-stroke-width": 1,
5747
- "circle-stroke-opacity": 0.3,
5748
- },
5749
- },
5750
- {
5751
- id: "gl-draw-polygon-fill-static",
5752
- type: "fill",
5753
- filter: ["all", ["==", "$type", "Polygon"]],
5754
- paint: {
5755
- "fill-color": "#D20C0C",
5756
- "fill-outline-color": "#D20C0C",
5757
- "fill-opacity": 0.1,
5758
- },
5759
- },
5760
- {
5761
- id: "gl-draw-line",
5762
- type: "line",
5763
- filter: ["all", ["==", "$type", "LineString"]],
5832
+ const GRID_TILE_SIZE = "4.5rem";
5833
+ const LIST_ICON_SIZE = "1.5rem";
5834
+ const JPG_MIME_TYPE = "image/jpeg";
5835
+ const PNG_MIME_TYPE = "image/png";
5836
+ const IMAGE_MIME_TYPES = [
5837
+ "image/apng",
5838
+ "image/avif",
5839
+ "image/gif",
5840
+ "image/jpeg",
5841
+ "image/png",
5842
+ "image/svg+xml",
5843
+ "image/webp",
5844
+ ];
5845
+ const XLSX_MIME_TYPES = [
5846
+ "application/vnd.ms-excel",
5847
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
5848
+ ];
5849
+ const PDF_MIME_TYPE = "application/pdf";
5850
+ const DOCX_MIME_TYPES = [
5851
+ "application/msword",
5852
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
5853
+ ];
5854
+ const CSV_MIME_TYPE = "text/csv";
5855
+ const JSON_MIME_TYPE = "application/json";
5856
+ const TXT_MIME_TYPE = "text/plain";
5857
+ const PPTX_MIME_TYPES = [
5858
+ "application/vnd.ms-powerpoint",
5859
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
5860
+ ];
5861
+ const SHP_MIME_TYPE = "application/octet-stream";
5862
+ const KML_MIME_TYPE = "application/octet-stream";
5863
+ const ZIP_MIME_TYPE = "application/zip";
5864
+ const PYTHON_MIME_TYPES = ["application/x-python-code", "text/x-python"];
5865
+ var AddAttachmentSource;
5866
+ (function (AddAttachmentSource) {
5867
+ AddAttachmentSource["Pc"] = "pc";
5868
+ AddAttachmentSource["Catalog"] = "catalog";
5869
+ AddAttachmentSource["Link"] = "link";
5870
+ })(AddAttachmentSource || (AddAttachmentSource = {}));
5871
+
5872
+ var FileType;
5873
+ (function (FileType) {
5874
+ FileType[FileType["UNKNOWN"] = 0] = "UNKNOWN";
5875
+ FileType[FileType["XLSX"] = 1] = "XLSX";
5876
+ FileType[FileType["PDF"] = 2] = "PDF";
5877
+ FileType[FileType["CSV"] = 3] = "CSV";
5878
+ FileType[FileType["DOCX"] = 4] = "DOCX";
5879
+ FileType[FileType["IMAGE"] = 5] = "IMAGE";
5880
+ FileType[FileType["TXT"] = 6] = "TXT";
5881
+ FileType[FileType["JSON"] = 7] = "JSON";
5882
+ FileType[FileType["KML"] = 8] = "KML";
5883
+ FileType[FileType["PPTX"] = 9] = "PPTX";
5884
+ FileType[FileType["SHP"] = 10] = "SHP";
5885
+ FileType[FileType["ZIP"] = 11] = "ZIP";
5886
+ FileType[FileType["JPEG"] = 12] = "JPEG";
5887
+ FileType[FileType["JPG"] = 13] = "JPG";
5888
+ FileType[FileType["PNG"] = 14] = "PNG";
5889
+ FileType[FileType["PYTHON"] = 15] = "PYTHON";
5890
+ })(FileType || (FileType = {}));
5891
+ const IMAGE_FILE_TYPES = [
5892
+ FileType.IMAGE,
5893
+ FileType.JPEG,
5894
+ FileType.JPG,
5895
+ FileType.PNG,
5896
+ ];
5897
+
5898
+ const getFileType = (mimeType = "", name = "") => {
5899
+ if (mimeType === PNG_MIME_TYPE)
5900
+ return FileType.PNG;
5901
+ if (mimeType === JPG_MIME_TYPE)
5902
+ return FileType.JPG;
5903
+ if (IMAGE_MIME_TYPES.includes(mimeType))
5904
+ return FileType.IMAGE;
5905
+ if (XLSX_MIME_TYPES.includes(mimeType))
5906
+ return FileType.XLSX;
5907
+ if (DOCX_MIME_TYPES.includes(mimeType))
5908
+ return FileType.DOCX;
5909
+ if (mimeType === CSV_MIME_TYPE)
5910
+ return FileType.CSV;
5911
+ if (mimeType === PDF_MIME_TYPE)
5912
+ return FileType.PDF;
5913
+ if (mimeType === JSON_MIME_TYPE)
5914
+ return FileType.JSON;
5915
+ if (mimeType === KML_MIME_TYPE && (name.endsWith(".kml") || name.endsWith(".kmz"))) {
5916
+ return FileType.KML;
5917
+ }
5918
+ if (PYTHON_MIME_TYPES.includes(mimeType))
5919
+ return FileType.PYTHON;
5920
+ if (mimeType === TXT_MIME_TYPE && name.endsWith(".py"))
5921
+ return FileType.PYTHON;
5922
+ if (mimeType === TXT_MIME_TYPE)
5923
+ return FileType.TXT;
5924
+ if (PPTX_MIME_TYPES.includes(mimeType))
5925
+ return FileType.PPTX;
5926
+ if (mimeType === SHP_MIME_TYPE && name.endsWith(".shp"))
5927
+ return FileType.SHP;
5928
+ if (mimeType === ZIP_MIME_TYPE)
5929
+ return FileType.ZIP;
5930
+ return name.endsWith(".py") ? FileType.PYTHON : FileType.UNKNOWN;
5931
+ };
5932
+
5933
+ var img$j = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%2300AAFF'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cpath id='Vector_3' d='M9.84902 10.0353C9.69434 10.0353 9.55605 10.0112 9.43418 9.96318C9.3123 9.91396 9.20918 9.84658 9.1248 9.76104C9.0416 9.67549 8.97773 9.57705 8.9332 9.46572C8.88984 9.35439 8.86816 9.23662 8.86816 9.1124V9.04561C8.86816 8.90615 8.8875 8.77725 8.92617 8.65889C8.96484 8.53936 9.02227 8.43506 9.09844 8.346C9.17461 8.25693 9.27012 8.18779 9.38496 8.13857C9.4998 8.08818 9.6334 8.06299 9.78574 8.06299C9.92051 8.06299 10.0412 8.08467 10.1479 8.12803C10.2545 8.17139 10.3447 8.2335 10.4186 8.31436C10.4936 8.39521 10.5504 8.49307 10.5891 8.60791C10.6289 8.72275 10.6488 8.85166 10.6488 8.99463V9.23545H9.09492V8.86455H10.0705V8.81885C10.0717 8.75557 10.0605 8.70166 10.0371 8.65713C10.0148 8.6126 9.98203 8.57861 9.93867 8.55518C9.89531 8.53174 9.84258 8.52002 9.78047 8.52002C9.71602 8.52002 9.6627 8.53408 9.62051 8.56221C9.57949 8.59033 9.54727 8.629 9.52383 8.67822C9.50156 8.72627 9.48574 8.78193 9.47637 8.84521C9.46699 8.9085 9.46231 8.97529 9.46231 9.04561V9.1124C9.46231 9.18271 9.47168 9.24658 9.49043 9.304C9.51035 9.36143 9.53848 9.41064 9.5748 9.45166C9.6123 9.4915 9.65684 9.52256 9.7084 9.54482C9.76113 9.56709 9.8209 9.57822 9.8877 9.57822C9.96855 9.57822 10.0482 9.56299 10.1268 9.53252C10.2053 9.50205 10.2727 9.45166 10.3289 9.38135L10.5979 9.70127C10.5592 9.75635 10.5041 9.80967 10.4326 9.86123C10.3623 9.91279 10.2779 9.95498 10.1795 9.98779C10.0811 10.0194 9.9709 10.0353 9.84902 10.0353Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.4623 7.2998V9.9998H7.86816V7.2998H8.4623Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.17773 10.0001H5.58184V8.04893C5.58184 7.879 5.61699 7.73604 5.6873 7.62002C5.75879 7.50283 5.86133 7.41436 5.99492 7.35459C6.12852 7.29365 6.29023 7.26318 6.48008 7.26318C6.58789 7.26318 6.6916 7.27256 6.79121 7.29131C6.89082 7.31006 6.99395 7.33467 7.10059 7.36514L7.01797 7.83271C6.94883 7.81396 6.87617 7.79639 6.8 7.77998C6.725 7.76357 6.63066 7.75537 6.51699 7.75537C6.41035 7.75537 6.32715 7.78057 6.26738 7.83096C6.20762 7.88135 6.17773 7.954 6.17773 8.04893V10.0001ZM6.55039 8.09814V8.50947H5.30762V8.09814H6.55039ZM7.37129 8.09814V10.0001H6.77715V8.09814H7.37129Z' fill='white'/%3e%3c/g%3e%3c/svg%3e";
5934
+
5935
+ var img$i = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%2347C782'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='CSV'%3e%3cpath id='Vector_3' d='M10.3816 9.39736L10.9143 7.44092H11.6051L10.742 10.0003H10.2955L10.3816 9.39736ZM9.89824 7.44092L10.4309 9.39736L10.5205 10.0003H10.0687L9.21094 7.44092H9.89824Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.37852 9.32002C8.37852 9.28018 8.37266 9.24443 8.36094 9.21279C8.34922 9.17998 8.32754 9.14951 8.2959 9.12139C8.26426 9.09326 8.21855 9.06514 8.15879 9.03701C8.10019 9.00771 8.02285 8.97725 7.92676 8.94561C7.81426 8.90811 7.70586 8.86592 7.60156 8.81904C7.49727 8.771 7.4041 8.71533 7.32207 8.65205C7.24004 8.5876 7.175 8.5126 7.12695 8.42705C7.07891 8.34033 7.05488 8.23955 7.05488 8.12471C7.05488 8.01455 7.07949 7.91553 7.12871 7.82764C7.17793 7.73857 7.24648 7.66299 7.33437 7.60088C7.42344 7.5376 7.52773 7.48955 7.64727 7.45674C7.7668 7.42275 7.89746 7.40576 8.03926 7.40576C8.22676 7.40576 8.39199 7.43857 8.53496 7.5042C8.6791 7.56865 8.7916 7.66064 8.87246 7.78018C8.95449 7.89854 8.99551 8.03857 8.99551 8.20029H8.38203C8.38203 8.13584 8.36855 8.079 8.3416 8.02979C8.31582 7.98057 8.27656 7.94189 8.22383 7.91377C8.17109 7.88564 8.10488 7.87158 8.0252 7.87158C7.94785 7.87158 7.88281 7.8833 7.83008 7.90674C7.77734 7.93018 7.7375 7.96182 7.71055 8.00166C7.68359 8.04033 7.67012 8.08311 7.67012 8.12998C7.67012 8.16865 7.68066 8.20381 7.70176 8.23545C7.72402 8.26592 7.75508 8.29463 7.79492 8.32158C7.83594 8.34854 7.88516 8.37432 7.94258 8.39893C8.00117 8.42354 8.0668 8.44756 8.13945 8.471C8.27539 8.51436 8.39609 8.56299 8.50156 8.61689C8.6082 8.66963 8.69785 8.72998 8.77051 8.79795C8.84434 8.86475 8.9 8.94092 8.9375 9.02646C8.97617 9.11201 8.99551 9.20869 8.99551 9.3165C8.99551 9.43135 8.97324 9.5333 8.92871 9.62236C8.88418 9.71143 8.82031 9.78701 8.73711 9.84912C8.65391 9.91006 8.5543 9.95635 8.43828 9.98799C8.32227 10.0196 8.19277 10.0354 8.0498 10.0354C7.91855 10.0354 7.78906 10.019 7.66133 9.98623C7.53477 9.95225 7.41992 9.90068 7.3168 9.83154C7.21367 9.76123 7.13105 9.67158 7.06894 9.5626C7.00801 9.45244 6.97754 9.32178 6.97754 9.17061H7.59629C7.59629 9.24561 7.60625 9.30889 7.62617 9.36045C7.64609 9.41201 7.67539 9.45361 7.71406 9.48525C7.75273 9.51572 7.8002 9.53799 7.85645 9.55205C7.9127 9.56494 7.97715 9.57139 8.0498 9.57139C8.12832 9.57139 8.1916 9.56025 8.23965 9.53799C8.2877 9.51455 8.32285 9.48408 8.34512 9.44658C8.36738 9.40791 8.37852 9.36572 8.37852 9.32002Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.05293 9.1335H6.66816C6.65996 9.31162 6.61191 9.46865 6.52402 9.60459C6.43613 9.74053 6.31426 9.84658 6.1584 9.92275C6.00371 9.99775 5.8209 10.0353 5.60996 10.0353C5.43887 10.0353 5.28594 10.0065 5.15117 9.94912C5.01758 9.8917 4.90391 9.80908 4.81016 9.70127C4.71758 9.59346 4.64668 9.46279 4.59746 9.30928C4.54941 9.15576 4.52539 8.98291 4.52539 8.79072V8.65186C4.52539 8.45967 4.55059 8.28682 4.60098 8.1333C4.65254 7.97861 4.7252 7.84736 4.81895 7.73955C4.91387 7.63057 5.02754 7.54736 5.15996 7.48994C5.29238 7.43252 5.43945 7.40381 5.60117 7.40381C5.82383 7.40381 6.01191 7.44365 6.16543 7.52334C6.31895 7.60303 6.43789 7.7126 6.52227 7.85205C6.60664 7.99033 6.65645 8.14795 6.67168 8.3249H6.05645C6.0541 8.22881 6.0377 8.14854 6.00723 8.08408C5.97676 8.01846 5.92871 7.96924 5.86309 7.93643C5.79746 7.90361 5.71016 7.88721 5.60117 7.88721C5.525 7.88721 5.45879 7.90127 5.40254 7.92939C5.34629 7.95752 5.29941 8.00205 5.26191 8.06299C5.22441 8.12393 5.19629 8.20303 5.17754 8.30029C5.15996 8.39639 5.15117 8.5124 5.15117 8.64834V8.79072C5.15117 8.92666 5.15938 9.04268 5.17578 9.13877C5.19219 9.23486 5.21855 9.31338 5.25488 9.37432C5.29121 9.43525 5.33809 9.48037 5.39551 9.50967C5.4541 9.53779 5.52559 9.55186 5.60996 9.55186C5.70371 9.55186 5.78281 9.53721 5.84727 9.50791C5.91172 9.47744 5.96152 9.43174 5.99668 9.3708C6.03184 9.30869 6.05059 9.22959 6.05293 9.1335Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5936
+
5937
+ var img$h = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%232B7CD3'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='DOCX'%3e%3cpath id='Vector_3' d='M11.3209 7.44092L11.7393 8.2917L12.1576 7.44092H12.8607L12.1471 8.71006L12.8801 10.0003H12.1699L11.7393 9.13369L11.3086 10.0003H10.5967L11.3314 8.71006L10.616 7.44092H11.3209Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.77754 9.1335H10.3928C10.3846 9.31162 10.3365 9.46865 10.2486 9.60459C10.1607 9.74053 10.0389 9.84658 9.88301 9.92275C9.72832 9.99775 9.54551 10.0353 9.33457 10.0353C9.16348 10.0353 9.01055 10.0065 8.87578 9.94912C8.74219 9.8917 8.62852 9.80908 8.53477 9.70127C8.44219 9.59346 8.37129 9.46279 8.32207 9.30928C8.27402 9.15576 8.25 8.98291 8.25 8.79072V8.65186C8.25 8.45967 8.2752 8.28682 8.32559 8.1333C8.37715 7.97861 8.4498 7.84736 8.54355 7.73955C8.63848 7.63057 8.75215 7.54736 8.88457 7.48994C9.01699 7.43252 9.16406 7.40381 9.32578 7.40381C9.54844 7.40381 9.73652 7.44365 9.89004 7.52334C10.0436 7.60303 10.1625 7.7126 10.2469 7.85205C10.3313 7.99033 10.3811 8.14795 10.3963 8.3249H9.78105C9.77871 8.22881 9.7623 8.14854 9.73184 8.08408C9.70137 8.01846 9.65332 7.96924 9.5877 7.93643C9.52207 7.90361 9.43477 7.88721 9.32578 7.88721C9.24961 7.88721 9.1834 7.90127 9.12715 7.92939C9.0709 7.95752 9.02402 8.00205 8.98652 8.06299C8.94902 8.12393 8.9209 8.20303 8.90215 8.30029C8.88457 8.39639 8.87578 8.5124 8.87578 8.64834V8.79072C8.87578 8.92666 8.88398 9.04268 8.90039 9.13877C8.9168 9.23486 8.94316 9.31338 8.97949 9.37432C9.01582 9.43525 9.0627 9.48037 9.12012 9.50967C9.17871 9.53779 9.2502 9.55186 9.33457 9.55186C9.42832 9.55186 9.50742 9.53721 9.57188 9.50791C9.63633 9.47744 9.68613 9.43174 9.72129 9.3708C9.75645 9.30869 9.7752 9.22959 9.77754 9.1335Z' fill='white'/%3e%3cpath id='Vector_5' d='M7.90176 8.66963V8.77334C7.90176 8.96904 7.87422 9.14482 7.81914 9.30068C7.76523 9.45537 7.68848 9.58779 7.58887 9.69795C7.48926 9.80693 7.37148 9.89072 7.23555 9.94932C7.09961 10.0067 6.94961 10.0354 6.78555 10.0354C6.62031 10.0354 6.46914 10.0067 6.33203 9.94932C6.19609 9.89072 6.07773 9.80693 5.97695 9.69795C5.87734 9.58779 5.8 9.45537 5.74492 9.30068C5.69102 9.14482 5.66406 8.96904 5.66406 8.77334V8.66963C5.66406 8.47393 5.69102 8.29814 5.74492 8.14229C5.8 7.98643 5.87676 7.854 5.9752 7.74502C6.0748 7.63486 6.19258 7.55107 6.32852 7.49365C6.46563 7.43506 6.6168 7.40576 6.78203 7.40576C6.94609 7.40576 7.09609 7.43506 7.23203 7.49365C7.36914 7.55107 7.4875 7.63486 7.58711 7.74502C7.68672 7.854 7.76406 7.98643 7.81914 8.14229C7.87422 8.29814 7.90176 8.47393 7.90176 8.66963ZM7.27598 8.77334V8.66611C7.27598 8.53955 7.26484 8.42822 7.24258 8.33213C7.22148 8.23486 7.18984 8.15342 7.14766 8.08779C7.10547 8.02217 7.05332 7.97295 6.99121 7.94014C6.93027 7.90615 6.86055 7.88916 6.78203 7.88916C6.7 7.88916 6.62852 7.90615 6.56758 7.94014C6.50664 7.97295 6.45566 8.02217 6.41465 8.08779C6.37363 8.15342 6.34258 8.23486 6.32148 8.33213C6.30156 8.42822 6.2916 8.53955 6.2916 8.66611V8.77334C6.2916 8.89873 6.30156 9.01006 6.32148 9.10732C6.34258 9.20342 6.37363 9.28486 6.41465 9.35166C6.45684 9.41846 6.5084 9.46885 6.56934 9.50283C6.63145 9.53682 6.70352 9.55381 6.78555 9.55381C6.86406 9.55381 6.93379 9.53682 6.99473 9.50283C7.05566 9.46885 7.10664 9.41846 7.14766 9.35166C7.18984 9.28486 7.22148 9.20342 7.24258 9.10732C7.26484 9.01006 7.27598 8.89873 7.27598 8.77334Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.13711 10.0003H3.56934L3.57285 9.52568H4.13711C4.2543 9.52568 4.35332 9.49756 4.43418 9.44131C4.51621 9.38506 4.57832 9.30127 4.62051 9.18994C4.66387 9.07744 4.68555 8.93916 4.68555 8.7751V8.66436C4.68555 8.54131 4.67324 8.4335 4.64863 8.34092C4.6252 8.24717 4.59004 8.16924 4.54316 8.10713C4.49629 8.04385 4.4377 7.99639 4.36738 7.96475C4.29824 7.93311 4.21855 7.91729 4.12832 7.91729H3.55879V7.44092H4.12832C4.30176 7.44092 4.46055 7.4708 4.60469 7.53057C4.75 7.58916 4.87539 7.67354 4.98086 7.78369C5.0875 7.89268 5.16953 8.02217 5.22695 8.17217C5.28555 8.321 5.31484 8.48623 5.31484 8.66787V8.7751C5.31484 8.95557 5.28555 9.1208 5.22695 9.2708C5.16953 9.4208 5.08809 9.55029 4.98262 9.65928C4.87715 9.76826 4.75234 9.85264 4.6082 9.9124C4.46523 9.971 4.3082 10.0003 4.13711 10.0003ZM3.92266 7.44092V10.0003H3.30566V7.44092H3.92266Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5938
+
5939
+ var img$g = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23FF9C54'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='JPEG'%3e%3cpath id='Vector_3' d='M12.4043 8.63301V9.68418C12.3609 9.73223 12.2941 9.78379 12.2039 9.83887C12.1148 9.89277 12.0023 9.93906 11.8664 9.97773C11.7305 10.0164 11.5705 10.0357 11.3865 10.0357C11.2166 10.0357 11.0625 10.0088 10.9242 9.95488C10.7859 9.8998 10.667 9.81953 10.5674 9.71406C10.4689 9.60742 10.3928 9.47734 10.3389 9.32383C10.2861 9.16914 10.2598 8.99219 10.2598 8.79297V8.65059C10.2598 8.45137 10.2867 8.27441 10.3406 8.11973C10.3945 7.96504 10.4701 7.83496 10.5674 7.72949C10.6658 7.62285 10.7813 7.54199 10.9137 7.48691C11.0473 7.43184 11.1938 7.4043 11.3531 7.4043C11.5887 7.4043 11.7803 7.4418 11.9279 7.5168C12.0756 7.59063 12.1875 7.69316 12.2637 7.82441C12.3398 7.95449 12.3861 8.10508 12.4025 8.27617H11.8102C11.7984 8.1918 11.7762 8.12031 11.7434 8.06172C11.7117 8.00195 11.666 7.95684 11.6063 7.92637C11.5465 7.89473 11.4691 7.87891 11.3742 7.87891C11.3004 7.87891 11.233 7.89473 11.1721 7.92637C11.1123 7.95801 11.0613 8.00605 11.0191 8.07051C10.977 8.13379 10.9441 8.21348 10.9207 8.30957C10.8984 8.40566 10.8873 8.51816 10.8873 8.64707V8.79297C10.8873 8.9207 10.8979 9.03262 10.9189 9.12871C10.9412 9.2248 10.974 9.30508 11.0174 9.36953C11.0619 9.43281 11.1182 9.48086 11.1861 9.51367C11.2553 9.54531 11.3367 9.56113 11.4305 9.56113C11.4961 9.56113 11.5523 9.55586 11.5992 9.54531C11.6461 9.53359 11.6848 9.51953 11.7152 9.50312C11.7469 9.48555 11.7709 9.46914 11.7873 9.45391V9.05664H11.3584V8.63301H12.4043Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.95762 9.52617V10.0008H8.59355V9.52617H9.95762ZM8.81328 7.44141V10.0008H8.19629V7.44141H8.81328ZM9.78184 8.45742V8.91621H8.59355V8.45742H9.78184ZM9.96289 7.44141V7.91777H8.59355V7.44141H9.96289Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.77227 9.13242H6.13594V8.65605H6.77227C6.85898 8.65605 6.9293 8.64141 6.9832 8.61211C7.03711 8.58281 7.07637 8.54238 7.10098 8.49082C7.12676 8.43809 7.13965 8.37891 7.13965 8.31328C7.13965 8.24297 7.12676 8.17793 7.10098 8.11816C7.07637 8.0584 7.03711 8.01035 6.9832 7.97402C6.9293 7.93652 6.85898 7.91777 6.77227 7.91777H6.36797V10.0008H5.75098V7.44141H6.77227C6.97734 7.44141 7.15371 7.47891 7.30137 7.55391C7.4502 7.62891 7.56445 7.73203 7.64414 7.86328C7.72383 7.99336 7.76367 8.14219 7.76367 8.30977C7.76367 8.475 7.72383 8.61914 7.64414 8.74219C7.56445 8.86523 7.4502 8.96133 7.30137 9.03047C7.15371 9.09844 6.97734 9.13242 6.77227 9.13242Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.64395 9.19746V7.44141H5.25918V9.19746C5.25918 9.36855 5.21992 9.5168 5.14141 9.64219C5.06406 9.76758 4.95859 9.86484 4.825 9.93398C4.69258 10.002 4.54375 10.0359 4.37852 10.0359C4.20742 10.0359 4.05508 10.0072 3.92148 9.9498C3.78906 9.89238 3.68477 9.80391 3.60859 9.68437C3.53359 9.56484 3.49609 9.4125 3.49609 9.22734H4.11484C4.11484 9.31406 4.1248 9.38203 4.14473 9.43125C4.16465 9.4793 4.19395 9.51328 4.23262 9.5332C4.27246 9.55195 4.32109 9.56133 4.37852 9.56133C4.43477 9.56133 4.48223 9.54727 4.5209 9.51914C4.56074 9.48984 4.59121 9.44824 4.6123 9.39434C4.6334 9.33926 4.64395 9.27363 4.64395 9.19746Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5940
+
5941
+ var img$f = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23FF9C54'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='JPG'%3e%3cpath id='Vector_3' d='M11.3467 8.63301V9.68418C11.3033 9.73223 11.2365 9.78379 11.1463 9.83887C11.0572 9.89277 10.9447 9.93906 10.8088 9.97773C10.6729 10.0164 10.5129 10.0357 10.3289 10.0357C10.159 10.0357 10.0049 10.0088 9.8666 9.95488C9.72832 9.8998 9.60938 9.81953 9.50977 9.71406C9.41133 9.60742 9.33516 9.47734 9.28125 9.32383C9.22852 9.16914 9.20215 8.99219 9.20215 8.79297V8.65059C9.20215 8.45137 9.2291 8.27441 9.28301 8.11973C9.33691 7.96504 9.4125 7.83496 9.50977 7.72949C9.6082 7.62285 9.72363 7.54199 9.85605 7.48691C9.98965 7.43184 10.1361 7.4043 10.2955 7.4043C10.5311 7.4043 10.7227 7.4418 10.8703 7.5168C11.018 7.59063 11.1299 7.69316 11.2061 7.82441C11.2822 7.95449 11.3285 8.10508 11.3449 8.27617H10.7525C10.7408 8.1918 10.7186 8.12031 10.6857 8.06172C10.6541 8.00195 10.6084 7.95684 10.5486 7.92637C10.4889 7.89473 10.4115 7.87891 10.3166 7.87891C10.2428 7.87891 10.1754 7.89473 10.1145 7.92637C10.0547 7.95801 10.0037 8.00605 9.96152 8.07051C9.91934 8.13379 9.88652 8.21348 9.86309 8.30957C9.84082 8.40566 9.82969 8.51816 9.82969 8.64707V8.79297C9.82969 8.9207 9.84023 9.03262 9.86133 9.12871C9.88359 9.2248 9.91641 9.30508 9.95977 9.36953C10.0043 9.43281 10.0605 9.48086 10.1285 9.51367C10.1977 9.54531 10.2791 9.56113 10.3729 9.56113C10.4385 9.56113 10.4947 9.55586 10.5416 9.54531C10.5885 9.53359 10.6271 9.51953 10.6576 9.50312C10.6893 9.48555 10.7133 9.46914 10.7297 9.45391V9.05664H10.3008V8.63301H11.3467Z' fill='white'/%3e%3cpath id='Vector_4' d='M7.82891 9.13242H7.19258V8.65605H7.82891C7.91563 8.65605 7.98594 8.64141 8.03984 8.61211C8.09375 8.58281 8.13301 8.54238 8.15762 8.49082C8.1834 8.43809 8.19629 8.37891 8.19629 8.31328C8.19629 8.24297 8.1834 8.17793 8.15762 8.11816C8.13301 8.0584 8.09375 8.01035 8.03984 7.97402C7.98594 7.93652 7.91563 7.91777 7.82891 7.91777H7.42461V10.0008H6.80762V7.44141H7.82891C8.03398 7.44141 8.21035 7.47891 8.35801 7.55391C8.50684 7.62891 8.62109 7.73203 8.70078 7.86328C8.78047 7.99336 8.82031 8.14219 8.82031 8.30977C8.82031 8.475 8.78047 8.61914 8.70078 8.74219C8.62109 8.86523 8.50684 8.96133 8.35801 9.03047C8.21035 9.09844 8.03398 9.13242 7.82891 9.13242Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.70059 9.19746V7.44141H6.31582V9.19746C6.31582 9.36855 6.27656 9.5168 6.19805 9.64219C6.1207 9.76758 6.01523 9.86484 5.88164 9.93398C5.74922 10.002 5.60039 10.0359 5.43516 10.0359C5.26406 10.0359 5.11172 10.0072 4.97812 9.9498C4.8457 9.89238 4.74141 9.80391 4.66523 9.68437C4.59023 9.56484 4.55273 9.4125 4.55273 9.22734H5.17148C5.17148 9.31406 5.18145 9.38203 5.20137 9.43125C5.22129 9.4793 5.25059 9.51328 5.28926 9.5332C5.3291 9.55195 5.37773 9.56133 5.43516 9.56133C5.49141 9.56133 5.53887 9.54727 5.57754 9.51914C5.61738 9.48984 5.64785 9.44824 5.66895 9.39434C5.69004 9.33926 5.70059 9.27363 5.70059 9.19746Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5942
+
5943
+ var img$e = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23AE6BF1'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='JSON'%3e%3cpath id='Vector_3' d='M12.6014 7.44043V9.9998H11.9861L11.0809 8.40723V9.9998H10.4639V7.44043H11.0809L11.9861 9.03301V7.44043H12.6014Z' fill='white'/%3e%3cpath id='Vector_4' d='M10.0434 8.66914V8.77285C10.0434 8.96855 10.0158 9.14434 9.96074 9.3002C9.90684 9.45488 9.83008 9.5873 9.73047 9.69746C9.63086 9.80645 9.51309 9.89023 9.37715 9.94883C9.24121 10.0063 9.09121 10.035 8.92715 10.035C8.76191 10.035 8.61074 10.0063 8.47363 9.94883C8.3377 9.89023 8.21934 9.80645 8.11855 9.69746C8.01895 9.5873 7.9416 9.45488 7.88652 9.3002C7.83262 9.14434 7.80566 8.96855 7.80566 8.77285V8.66914C7.80566 8.47344 7.83262 8.29766 7.88652 8.1418C7.9416 7.98594 8.01836 7.85352 8.1168 7.74453C8.21641 7.63437 8.33418 7.55059 8.47012 7.49316C8.60723 7.43457 8.7584 7.40527 8.92363 7.40527C9.0877 7.40527 9.2377 7.43457 9.37363 7.49316C9.51074 7.55059 9.6291 7.63437 9.72871 7.74453C9.82832 7.85352 9.90566 7.98594 9.96074 8.1418C10.0158 8.29766 10.0434 8.47344 10.0434 8.66914ZM9.41758 8.77285V8.66562C9.41758 8.53906 9.40645 8.42773 9.38418 8.33164C9.36309 8.23438 9.33145 8.15293 9.28926 8.0873C9.24707 8.02168 9.19492 7.97246 9.13281 7.93965C9.07187 7.90566 9.00215 7.88867 8.92363 7.88867C8.8416 7.88867 8.77012 7.90566 8.70918 7.93965C8.64824 7.97246 8.59727 8.02168 8.55625 8.0873C8.51523 8.15293 8.48418 8.23438 8.46309 8.33164C8.44316 8.42773 8.4332 8.53906 8.4332 8.66562V8.77285C8.4332 8.89824 8.44316 9.00957 8.46309 9.10684C8.48418 9.20293 8.51523 9.28437 8.55625 9.35117C8.59844 9.41797 8.65 9.46836 8.71094 9.50234C8.77305 9.53633 8.84512 9.55332 8.92715 9.55332C9.00566 9.55332 9.07539 9.53633 9.13633 9.50234C9.19727 9.46836 9.24824 9.41797 9.28926 9.35117C9.33145 9.28437 9.36309 9.20293 9.38418 9.10684C9.40645 9.00957 9.41758 8.89824 9.41758 8.77285Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.84336 9.31953C6.84336 9.27969 6.8375 9.24395 6.82578 9.2123C6.81406 9.17949 6.79238 9.14902 6.76074 9.1209C6.7291 9.09277 6.6834 9.06465 6.62363 9.03652C6.56504 9.00723 6.4877 8.97676 6.3916 8.94512C6.2791 8.90762 6.1707 8.86543 6.06641 8.81855C5.96211 8.77051 5.86895 8.71484 5.78691 8.65156C5.70488 8.58711 5.63984 8.51211 5.5918 8.42656C5.54375 8.33984 5.51973 8.23906 5.51973 8.12422C5.51973 8.01406 5.54434 7.91504 5.59355 7.82715C5.64277 7.73809 5.71133 7.6625 5.79922 7.60039C5.88828 7.53711 5.99258 7.48906 6.11211 7.45625C6.23164 7.42227 6.3623 7.40527 6.5041 7.40527C6.6916 7.40527 6.85684 7.43809 6.9998 7.50371C7.14395 7.56816 7.25645 7.66016 7.3373 7.77969C7.41934 7.89805 7.46035 8.03809 7.46035 8.1998H6.84688C6.84688 8.13535 6.8334 8.07852 6.80645 8.0293C6.78066 7.98008 6.74141 7.94141 6.68867 7.91328C6.63594 7.88516 6.56973 7.87109 6.49004 7.87109C6.4127 7.87109 6.34766 7.88281 6.29492 7.90625C6.24219 7.92969 6.20234 7.96133 6.17539 8.00117C6.14844 8.03984 6.13496 8.08262 6.13496 8.12949C6.13496 8.16816 6.14551 8.20332 6.1666 8.23496C6.18887 8.26543 6.21992 8.29414 6.25977 8.32109C6.30078 8.34805 6.35 8.37383 6.40742 8.39844C6.46602 8.42305 6.53164 8.44707 6.6043 8.47051C6.74023 8.51387 6.86094 8.5625 6.96641 8.61641C7.07305 8.66914 7.1627 8.72949 7.23535 8.79746C7.30918 8.86426 7.36484 8.94043 7.40234 9.02598C7.44102 9.11152 7.46035 9.2082 7.46035 9.31602C7.46035 9.43086 7.43809 9.53281 7.39355 9.62187C7.34902 9.71094 7.28516 9.78652 7.20195 9.84863C7.11875 9.90957 7.01914 9.95586 6.90312 9.9875C6.78711 10.0191 6.65762 10.035 6.51465 10.035C6.3834 10.035 6.25391 10.0186 6.12617 9.98574C5.99961 9.95176 5.88477 9.9002 5.78164 9.83105C5.67852 9.76074 5.5959 9.67109 5.53379 9.56211C5.47285 9.45195 5.44238 9.32129 5.44238 9.17012H6.06113C6.06113 9.24512 6.07109 9.3084 6.09102 9.35996C6.11094 9.41152 6.14023 9.45312 6.17891 9.48477C6.21758 9.51523 6.26504 9.5375 6.32129 9.55156C6.37754 9.56445 6.44199 9.5709 6.51465 9.5709C6.59316 9.5709 6.65645 9.55977 6.70449 9.5375C6.75254 9.51406 6.7877 9.48359 6.80996 9.44609C6.83223 9.40742 6.84336 9.36523 6.84336 9.31953Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.41738 9.19648V7.44043H5.03262V9.19648C5.03262 9.36758 4.99336 9.51582 4.91484 9.64121C4.8375 9.7666 4.73203 9.86387 4.59844 9.93301C4.46602 10.001 4.31719 10.035 4.15195 10.035C3.98086 10.035 3.82852 10.0063 3.69492 9.94883C3.5625 9.89141 3.4582 9.80293 3.38203 9.6834C3.30703 9.56387 3.26953 9.41152 3.26953 9.22637H3.88828C3.88828 9.31309 3.89824 9.38105 3.91816 9.43027C3.93809 9.47832 3.96738 9.5123 4.00605 9.53223C4.0459 9.55098 4.09453 9.56035 4.15195 9.56035C4.2082 9.56035 4.25566 9.54629 4.29434 9.51816C4.33418 9.48887 4.36465 9.44727 4.38574 9.39336C4.40684 9.33828 4.41738 9.27266 4.41738 9.19648Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5944
+
5945
+ var img$d = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%236155E9'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='KML'%3e%3cpath id='Vector_3' d='M11.7408 9.5252V9.9998H10.4471V9.5252H11.7408ZM10.6668 7.44043V9.9998H10.0498V7.44043H10.6668Z' fill='white'/%3e%3cpath id='Vector_4' d='M7.09785 7.44043H7.60059L8.17188 9.22109L8.74316 7.44043H9.2459L8.37578 9.9998H7.96797L7.09785 7.44043ZM6.79199 7.44043H7.3123L7.40898 9.40215V9.9998H6.79199V7.44043ZM9.03145 7.44043H9.55352V9.9998H8.93477V9.40215L9.03145 7.44043Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.00664 7.44043V9.9998H4.38965V7.44043H5.00664ZM6.53418 7.44043L5.54277 8.7377L4.9627 9.37227L4.8502 8.80625L5.22109 8.24375L5.77305 7.44043H6.53418ZM5.80469 9.9998L5.14375 8.84668L5.62363 8.49336L6.53418 9.9998H5.80469Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5946
+
5947
+ var img$c = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23EC473F'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PDF'%3e%3cpath id='Vector_3' d='M10.2654 7.44043V9.9998H9.64844V7.44043H10.2654ZM11.2604 8.50566V8.98027H10.0896V8.50566H11.2604ZM11.3605 7.44043V7.9168H10.0896V7.44043H11.3605Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.04922 9.9998H7.48145L7.48496 9.5252H8.04922C8.16641 9.5252 8.26543 9.49707 8.34629 9.44082C8.42832 9.38457 8.49043 9.30078 8.53262 9.18945C8.57598 9.07695 8.59766 8.93867 8.59766 8.77461V8.66387C8.59766 8.54082 8.58535 8.43301 8.56074 8.34043C8.5373 8.24668 8.50215 8.16875 8.45527 8.10664C8.4084 8.04336 8.3498 7.9959 8.27949 7.96426C8.21035 7.93262 8.13066 7.9168 8.04043 7.9168H7.4709V7.44043H8.04043C8.21387 7.44043 8.37266 7.47031 8.5168 7.53008C8.66211 7.58867 8.7875 7.67305 8.89297 7.7832C8.99961 7.89219 9.08164 8.02168 9.13906 8.17168C9.19766 8.32051 9.22695 8.48574 9.22695 8.66738V8.77461C9.22695 8.95508 9.19766 9.12031 9.13906 9.27031C9.08164 9.42031 9.0002 9.5498 8.89473 9.65879C8.78926 9.76777 8.66445 9.85215 8.52031 9.91191C8.37734 9.97051 8.22031 9.9998 8.04922 9.9998ZM7.83477 7.44043V9.9998H7.21777V7.44043H7.83477Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.79375 9.13145H5.15742V8.65508H5.79375C5.88047 8.65508 5.95078 8.64043 6.00469 8.61113C6.05859 8.58184 6.09785 8.54141 6.12246 8.48984C6.14824 8.43711 6.16113 8.37793 6.16113 8.3123C6.16113 8.24199 6.14824 8.17695 6.12246 8.11719C6.09785 8.05742 6.05859 8.00937 6.00469 7.97305C5.95078 7.93555 5.88047 7.9168 5.79375 7.9168H5.38945V9.9998H4.77246V7.44043H5.79375C5.99883 7.44043 6.1752 7.47793 6.32285 7.55293C6.47168 7.62793 6.58594 7.73105 6.66562 7.8623C6.74531 7.99238 6.78516 8.14121 6.78516 8.30879C6.78516 8.47402 6.74531 8.61816 6.66562 8.74121C6.58594 8.86426 6.47168 8.96035 6.32285 9.02949C6.1752 9.09746 5.99883 9.13145 5.79375 9.13145Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5948
+
5949
+ var img$b = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%239381FF'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PNG'%3e%3cpath id='Vector_3' d='M11.5977 8.63301V9.68418C11.5543 9.73223 11.4875 9.78379 11.3973 9.83887C11.3082 9.89277 11.1957 9.93906 11.0598 9.97773C10.9238 10.0164 10.7639 10.0357 10.5799 10.0357C10.41 10.0357 10.2559 10.0088 10.1176 9.95488C9.9793 9.8998 9.86035 9.81953 9.76074 9.71406C9.6623 9.60742 9.58613 9.47734 9.53223 9.32383C9.47949 9.16914 9.45312 8.99219 9.45312 8.79297V8.65059C9.45312 8.45137 9.48008 8.27441 9.53398 8.11973C9.58789 7.96504 9.66348 7.83496 9.76074 7.72949C9.85918 7.62285 9.97461 7.54199 10.107 7.48691C10.2406 7.43184 10.3871 7.4043 10.5465 7.4043C10.782 7.4043 10.9736 7.4418 11.1213 7.5168C11.2689 7.59063 11.3809 7.69316 11.457 7.82441C11.5332 7.95449 11.5795 8.10508 11.5959 8.27617H11.0035C10.9918 8.1918 10.9695 8.12031 10.9367 8.06172C10.9051 8.00195 10.8594 7.95684 10.7996 7.92637C10.7398 7.89473 10.6625 7.87891 10.5676 7.87891C10.4937 7.87891 10.4264 7.89473 10.3654 7.92637C10.3057 7.95801 10.2547 8.00605 10.2125 8.07051C10.1703 8.13379 10.1375 8.21348 10.1141 8.30957C10.0918 8.40566 10.0807 8.51816 10.0807 8.64707V8.79297C10.0807 8.9207 10.0912 9.03262 10.1123 9.12871C10.1346 9.2248 10.1674 9.30508 10.2107 9.36953C10.2553 9.43281 10.3115 9.48086 10.3795 9.51367C10.4486 9.54531 10.5301 9.56113 10.6238 9.56113C10.6895 9.56113 10.7457 9.55586 10.7926 9.54531C10.8395 9.53359 10.8781 9.51953 10.9086 9.50312C10.9402 9.48555 10.9643 9.46914 10.9807 9.45391V9.05664H10.5518V8.63301H11.5977Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.01445 7.44141V10.0008H8.39922L7.49395 8.4082V10.0008H6.87695V7.44141H7.49395L8.39922 9.03398V7.44141H9.01445Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.45293 9.13242H4.8166V8.65605H5.45293C5.53965 8.65605 5.60996 8.64141 5.66387 8.61211C5.71777 8.58281 5.75703 8.54238 5.78164 8.49082C5.80742 8.43809 5.82031 8.37891 5.82031 8.31328C5.82031 8.24297 5.80742 8.17793 5.78164 8.11816C5.75703 8.0584 5.71777 8.01035 5.66387 7.97402C5.60996 7.93652 5.53965 7.91777 5.45293 7.91777H5.04863V10.0008H4.43164V7.44141H5.45293C5.65801 7.44141 5.83437 7.47891 5.98203 7.55391C6.13086 7.62891 6.24512 7.73203 6.3248 7.86328C6.40449 7.99336 6.44434 8.14219 6.44434 8.30977C6.44434 8.475 6.40449 8.61914 6.3248 8.74219C6.24512 8.86523 6.13086 8.96133 5.98203 9.03047C5.83437 9.09844 5.65801 9.13242 5.45293 9.13242Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5950
+
5951
+ var img$a = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23CA4424'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PPTX'%3e%3cpath id='Vector_3' d='M11.2125 7.44043L11.6309 8.29121L12.0492 7.44043H12.7523L12.0387 8.70957L12.7717 9.9998H12.0615L11.6309 9.1332L11.2002 9.9998H10.4883L11.223 8.70957L10.5076 7.44043H11.2125Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.54414 7.44043V9.9998H8.92715V7.44043H9.54414ZM10.3141 7.44043V7.9168H8.1748V7.44043H10.3141Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.88164 9.13145H6.24531V8.65508H6.88164C6.96836 8.65508 7.03867 8.64043 7.09258 8.61113C7.14648 8.58184 7.18574 8.54141 7.21035 8.48984C7.23613 8.43711 7.24902 8.37793 7.24902 8.3123C7.24902 8.24199 7.23613 8.17695 7.21035 8.11719C7.18574 8.05742 7.14648 8.00937 7.09258 7.97305C7.03867 7.93555 6.96836 7.9168 6.88164 7.9168H6.47734V9.9998H5.86035V7.44043H6.88164C7.08672 7.44043 7.26309 7.47793 7.41074 7.55293C7.55957 7.62793 7.67383 7.73105 7.75352 7.8623C7.8332 7.99238 7.87305 8.14121 7.87305 8.30879C7.87305 8.47402 7.8332 8.61816 7.75352 8.74121C7.67383 8.86426 7.55957 8.96035 7.41074 9.02949C7.26309 9.09746 7.08672 9.13145 6.88164 9.13145Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.43633 9.13145H3.8V8.65508H4.43633C4.52305 8.65508 4.59336 8.64043 4.64727 8.61113C4.70117 8.58184 4.74043 8.54141 4.76504 8.48984C4.79082 8.43711 4.80371 8.37793 4.80371 8.3123C4.80371 8.24199 4.79082 8.17695 4.76504 8.11719C4.74043 8.05742 4.70117 8.00937 4.64727 7.97305C4.59336 7.93555 4.52305 7.9168 4.43633 7.9168H4.03203V9.9998H3.41504V7.44043H4.43633C4.64141 7.44043 4.81777 7.47793 4.96543 7.55293C5.11426 7.62793 5.22852 7.73105 5.3082 7.8623C5.38789 7.99238 5.42773 8.14121 5.42773 8.30879C5.42773 8.47402 5.38789 8.61816 5.3082 8.74121C5.22852 8.86426 5.11426 8.96035 4.96543 9.02949C4.81777 9.09746 4.64141 9.13145 4.43633 9.13145Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5952
+
5953
+ var img$9 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%233674A5'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PY'%3e%3cpath id='Vector_3' d='M8.75215 7.44141L9.22324 8.55234L9.69609 7.44141H10.3605L9.53789 9.08145V10.0008H8.91035V9.08145L8.08594 7.44141H8.75215Z' fill='%23FED341'/%3e%3cpath id='Vector_4' d='M6.86406 9.13242H6.22773V8.65605H6.86406C6.95078 8.65605 7.02109 8.64141 7.075 8.61211C7.12891 8.58281 7.16816 8.54238 7.19277 8.49082C7.21855 8.43809 7.23145 8.37891 7.23145 8.31328C7.23145 8.24297 7.21855 8.17793 7.19277 8.11816C7.16816 8.0584 7.12891 8.01035 7.075 7.97402C7.02109 7.93652 6.95078 7.91777 6.86406 7.91777H6.45977V10.0008H5.84277V7.44141H6.86406C7.06914 7.44141 7.24551 7.47891 7.39316 7.55391C7.54199 7.62891 7.65625 7.73203 7.73594 7.86328C7.81563 7.99336 7.85547 8.14219 7.85547 8.30977C7.85547 8.475 7.81563 8.61914 7.73594 8.74219C7.65625 8.86523 7.54199 8.96133 7.39316 9.03047C7.24551 9.09844 7.06914 9.13242 6.86406 9.13242Z' fill='%23FED341'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5954
+
5955
+ var img$8 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23C0D155'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='SHP'%3e%3cpath id='Vector_3' d='M10.5359 9.13145H9.89961V8.65508H10.5359C10.6227 8.65508 10.693 8.64043 10.7469 8.61113C10.8008 8.58184 10.84 8.54141 10.8646 8.48984C10.8904 8.43711 10.9033 8.37793 10.9033 8.3123C10.9033 8.24199 10.8904 8.17695 10.8646 8.11719C10.84 8.05742 10.8008 8.00937 10.7469 7.97305C10.693 7.93555 10.6227 7.9168 10.5359 7.9168H10.1316V9.9998H9.51465V7.44043H10.5359C10.741 7.44043 10.9174 7.47793 11.065 7.55293C11.2139 7.62793 11.3281 7.73105 11.4078 7.8623C11.4875 7.99238 11.5273 8.14121 11.5273 8.30879C11.5273 8.47402 11.4875 8.61816 11.4078 8.74121C11.3281 8.86426 11.2139 8.96035 11.065 9.02949C10.9174 9.09746 10.741 9.13145 10.5359 9.13145Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.6082 8.45645V8.93105H7.29512V8.45645H8.6082ZM7.50078 7.44043V9.9998H6.88379V7.44043H7.50078ZM9.02305 7.44043V9.9998H8.40781V7.44043H9.02305Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.84824 9.31953C5.84824 9.27969 5.84238 9.24395 5.83066 9.2123C5.81895 9.17949 5.79727 9.14902 5.76562 9.1209C5.73398 9.09277 5.68828 9.06465 5.62852 9.03652C5.56992 9.00723 5.49258 8.97676 5.39648 8.94512C5.28398 8.90762 5.17559 8.86543 5.07129 8.81855C4.96699 8.77051 4.87383 8.71484 4.7918 8.65156C4.70977 8.58711 4.64473 8.51211 4.59668 8.42656C4.54863 8.33984 4.52461 8.23906 4.52461 8.12422C4.52461 8.01406 4.54922 7.91504 4.59844 7.82715C4.64766 7.73809 4.71621 7.6625 4.8041 7.60039C4.89316 7.53711 4.99746 7.48906 5.11699 7.45625C5.23652 7.42227 5.36719 7.40527 5.50898 7.40527C5.69648 7.40527 5.86172 7.43809 6.00469 7.50371C6.14883 7.56816 6.26133 7.66016 6.34219 7.77969C6.42422 7.89805 6.46523 8.03809 6.46523 8.1998H5.85176C5.85176 8.13535 5.83828 8.07852 5.81133 8.0293C5.78555 7.98008 5.74629 7.94141 5.69355 7.91328C5.64082 7.88516 5.57461 7.87109 5.49492 7.87109C5.41758 7.87109 5.35254 7.88281 5.2998 7.90625C5.24707 7.92969 5.20723 7.96133 5.18027 8.00117C5.15332 8.03984 5.13984 8.08262 5.13984 8.12949C5.13984 8.16816 5.15039 8.20332 5.17148 8.23496C5.19375 8.26543 5.2248 8.29414 5.26465 8.32109C5.30566 8.34805 5.35488 8.37383 5.4123 8.39844C5.4709 8.42305 5.53652 8.44707 5.60918 8.47051C5.74512 8.51387 5.86582 8.5625 5.97129 8.61641C6.07793 8.66914 6.16758 8.72949 6.24023 8.79746C6.31406 8.86426 6.36973 8.94043 6.40723 9.02598C6.4459 9.11152 6.46523 9.2082 6.46523 9.31602C6.46523 9.43086 6.44297 9.53281 6.39844 9.62187C6.35391 9.71094 6.29004 9.78652 6.20684 9.84863C6.12363 9.90957 6.02402 9.95586 5.90801 9.9875C5.79199 10.0191 5.6625 10.035 5.51953 10.035C5.38828 10.035 5.25879 10.0186 5.13105 9.98574C5.00449 9.95176 4.88965 9.9002 4.78652 9.83105C4.6834 9.76074 4.60078 9.67109 4.53867 9.56211C4.47773 9.45195 4.44727 9.32129 4.44727 9.17012H5.06602C5.06602 9.24512 5.07598 9.3084 5.0959 9.35996C5.11582 9.41152 5.14512 9.45312 5.18379 9.48477C5.22246 9.51523 5.26992 9.5375 5.32617 9.55156C5.38242 9.56445 5.44687 9.5709 5.51953 9.5709C5.59805 9.5709 5.66133 9.55977 5.70937 9.5375C5.75742 9.51406 5.79258 9.48359 5.81484 9.44609C5.83711 9.40742 5.84824 9.36523 5.84824 9.31953Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5956
+
5957
+ var img$7 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23DDE3EA'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='TXT'%3e%3cpath id='Vector_3' d='M10.6838 7.44043V9.9998H10.0668V7.44043H10.6838ZM11.4537 7.44043V7.9168H9.31445V7.44043H11.4537Z' fill='black'/%3e%3cpath id='Vector_4' d='M7.58164 7.44043L8 8.29121L8.41836 7.44043H9.12148L8.40781 8.70957L9.14082 9.9998H8.43066L8 9.1332L7.56934 9.9998H6.85742L7.59219 8.70957L6.87676 7.44043H7.58164Z' fill='black'/%3e%3cpath id='Vector_5' d='M5.91328 7.44043V9.9998H5.29629V7.44043H5.91328ZM6.6832 7.44043V7.9168H4.54395V7.44043H6.6832Z' fill='black'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5958
+
5959
+ var img$6 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%2341A246'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='XLSX'%3e%3cpath id='Vector_3' d='M10.983 7.44043L11.4014 8.29121L11.8197 7.44043H12.5229L11.8092 8.70957L12.5422 9.9998H11.832L11.4014 9.1332L10.9707 9.9998H10.2588L10.9936 8.70957L10.2781 7.44043H10.983Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.41172 9.31953C9.41172 9.27969 9.40586 9.24395 9.39414 9.2123C9.38242 9.17949 9.36074 9.14902 9.3291 9.1209C9.29746 9.09277 9.25176 9.06465 9.19199 9.03652C9.1334 9.00723 9.05605 8.97676 8.95996 8.94512C8.84746 8.90762 8.73906 8.86543 8.63477 8.81855C8.53047 8.77051 8.4373 8.71484 8.35527 8.65156C8.27324 8.58711 8.2082 8.51211 8.16016 8.42656C8.11211 8.33984 8.08809 8.23906 8.08809 8.12422C8.08809 8.01406 8.1127 7.91504 8.16191 7.82715C8.21113 7.73809 8.27969 7.6625 8.36758 7.60039C8.45664 7.53711 8.56094 7.48906 8.68047 7.45625C8.8 7.42227 8.93066 7.40527 9.07246 7.40527C9.25996 7.40527 9.4252 7.43809 9.56816 7.50371C9.7123 7.56816 9.8248 7.66016 9.90566 7.77969C9.9877 7.89805 10.0287 8.03809 10.0287 8.1998H9.41523C9.41523 8.13535 9.40176 8.07852 9.3748 8.0293C9.34902 7.98008 9.30977 7.94141 9.25703 7.91328C9.2043 7.88516 9.13809 7.87109 9.0584 7.87109C8.98105 7.87109 8.91602 7.88281 8.86328 7.90625C8.81055 7.92969 8.7707 7.96133 8.74375 8.00117C8.7168 8.03984 8.70332 8.08262 8.70332 8.12949C8.70332 8.16816 8.71387 8.20332 8.73496 8.23496C8.75723 8.26543 8.78828 8.29414 8.82812 8.32109C8.86914 8.34805 8.91836 8.37383 8.97578 8.39844C9.03437 8.42305 9.1 8.44707 9.17266 8.47051C9.30859 8.51387 9.4293 8.5625 9.53477 8.61641C9.64141 8.66914 9.73105 8.72949 9.80371 8.79746C9.87754 8.86426 9.9332 8.94043 9.9707 9.02598C10.0094 9.11152 10.0287 9.2082 10.0287 9.31602C10.0287 9.43086 10.0064 9.53281 9.96191 9.62187C9.91738 9.71094 9.85352 9.78652 9.77031 9.84863C9.68711 9.90957 9.5875 9.95586 9.47148 9.9875C9.35547 10.0191 9.22598 10.035 9.08301 10.035C8.95176 10.035 8.82227 10.0186 8.69453 9.98574C8.56797 9.95176 8.45312 9.9002 8.35 9.83105C8.24687 9.76074 8.16426 9.67109 8.10215 9.56211C8.04121 9.45195 8.01074 9.32129 8.01074 9.17012H8.62949C8.62949 9.24512 8.63945 9.3084 8.65937 9.35996C8.6793 9.41152 8.70859 9.45312 8.74727 9.48477C8.78594 9.51523 8.8334 9.5375 8.88965 9.55156C8.9459 9.56445 9.01035 9.5709 9.08301 9.5709C9.16152 9.5709 9.2248 9.55977 9.27285 9.5375C9.3209 9.51406 9.35605 9.48359 9.37832 9.44609C9.40059 9.40742 9.41172 9.36523 9.41172 9.31953Z' fill='white'/%3e%3cpath id='Vector_5' d='M7.73301 9.5252V9.9998H6.43926V9.5252H7.73301ZM6.65898 7.44043V9.9998H6.04199V7.44043H6.65898Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.1793 7.44043L4.59766 8.29121L5.01602 7.44043H5.71914L5.00547 8.70957L5.73848 9.9998H5.02832L4.59766 9.1332L4.16699 9.9998H3.45508L4.18984 8.70957L3.47441 7.44043H4.1793Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5960
+
5961
+ var img$5 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23F4BB0A'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='ZIP'%3e%3cpath id='Vector_3' d='M9.78789 9.13145H9.15156V8.65508H9.78789C9.87461 8.65508 9.94492 8.64043 9.99883 8.61113C10.0527 8.58184 10.092 8.54141 10.1166 8.48984C10.1424 8.43711 10.1553 8.37793 10.1553 8.3123C10.1553 8.24199 10.1424 8.17695 10.1166 8.11719C10.092 8.05742 10.0527 8.00937 9.99883 7.97305C9.94492 7.93555 9.87461 7.9168 9.78789 7.9168H9.38359V9.9998H8.7666V7.44043H9.78789C9.99297 7.44043 10.1693 7.47793 10.317 7.55293C10.4658 7.62793 10.5801 7.73105 10.6598 7.8623C10.7395 7.99238 10.7793 8.14121 10.7793 8.30879C10.7793 8.47402 10.7395 8.61816 10.6598 8.74121C10.5801 8.86426 10.4658 8.96035 10.317 9.02949C10.1693 9.09746 9.99297 9.13145 9.78789 9.13145Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.23242 7.44043V9.9998H7.61719V7.44043H8.23242Z' fill='white'/%3e%3cpath id='Vector_5' d='M7.19551 9.5252V9.9998H5.34277V9.5252H7.19551ZM7.1832 7.75684L5.64863 9.9998H5.20215V9.67461L6.7543 7.44043H7.1832V7.75684ZM6.98457 7.44043V7.9168H5.19336V7.44043H6.98457Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
5962
+
5963
+ const getFileTypeIcon = (fileType) => {
5964
+ switch (fileType) {
5965
+ case FileType.CSV:
5966
+ return img$i;
5967
+ case FileType.XLSX:
5968
+ return img$6;
5969
+ case FileType.DOCX:
5970
+ return img$h;
5971
+ case FileType.PDF:
5972
+ return img$c;
5973
+ case FileType.JSON:
5974
+ return img$e;
5975
+ case FileType.KML:
5976
+ return img$d;
5977
+ case FileType.PPTX:
5978
+ return img$a;
5979
+ case FileType.SHP:
5980
+ return img$8;
5981
+ case FileType.TXT:
5982
+ return img$7;
5983
+ case FileType.ZIP:
5984
+ return img$5;
5985
+ case FileType.IMAGE:
5986
+ case FileType.JPEG:
5987
+ return img$g;
5988
+ case FileType.JPG:
5989
+ return img$f;
5990
+ case FileType.PNG:
5991
+ return img$b;
5992
+ case FileType.PYTHON:
5993
+ return img$9;
5994
+ default:
5995
+ return img$j;
5996
+ }
5997
+ };
5998
+
5999
+ const useAttachmentPreviewImages = ({ items, active, }) => {
6000
+ const { api } = useGlobalContext();
6001
+ const [blobUrls, setBlobUrls] = React.useState({});
6002
+ const [failedLinks, setFailedLinks] = React.useState({});
6003
+ const inFlightRef = React.useRef(new Set());
6004
+ const blobUrlsRef = React.useRef(blobUrls);
6005
+ blobUrlsRef.current = blobUrls;
6006
+ React.useEffect(() => {
6007
+ if (!active || !api?.catalog?.getFile)
6008
+ return;
6009
+ items.forEach(item => {
6010
+ const fileType = getFileType(item.mimeType, item.name);
6011
+ const isImage = IMAGE_FILE_TYPES.includes(fileType);
6012
+ if (!isImage || item.isExternal)
6013
+ return;
6014
+ if (blobUrlsRef.current[item.link] || inFlightRef.current.has(item.link))
6015
+ return;
6016
+ inFlightRef.current.add(item.link);
6017
+ api.catalog
6018
+ .getFile(item.link)
6019
+ .then(blob => {
6020
+ const objectUrl = URL.createObjectURL(blob);
6021
+ setBlobUrls(prev => ({ ...prev, [item.link]: objectUrl }));
6022
+ })
6023
+ .catch(() => {
6024
+ setFailedLinks(prev => (prev[item.link] ? prev : { ...prev, [item.link]: true }));
6025
+ })
6026
+ .finally(() => {
6027
+ inFlightRef.current.delete(item.link);
6028
+ });
6029
+ });
6030
+ }, [active, api, items]);
6031
+ React.useEffect(() => () => {
6032
+ Object.values(blobUrlsRef.current).forEach(URL.revokeObjectURL);
6033
+ }, []);
6034
+ return React.useMemo(() => items.map(item => {
6035
+ const fileType = getFileType(item.mimeType, item.name);
6036
+ const isImage = IMAGE_FILE_TYPES.includes(fileType);
6037
+ const fileName = item.name;
6038
+ if (!isImage)
6039
+ return { src: getFileTypeIcon(fileType), fileName };
6040
+ if (item.isExternal)
6041
+ return { src: item.link, fileName };
6042
+ const hasError = !!failedLinks[item.link];
6043
+ const blobUrl = blobUrls[item.link];
6044
+ return {
6045
+ src: blobUrl ?? "",
6046
+ fileName,
6047
+ hasError,
6048
+ isLoading: !hasError && !blobUrl,
6049
+ };
6050
+ }), [items, blobUrls, failedLinks]);
6051
+ };
6052
+
6053
+ const useAutoCompleteControl = (items) => {
6054
+ const [value, setValue] = React.useState("");
6055
+ const [options, setOptions] = React.useState([]);
6056
+ const staticOptions = React.useMemo(() => (items ?? [])
6057
+ .filter(Boolean)
6058
+ .map(item => ({ text: String(item), value: String(item) })), [items]);
6059
+ const onChange = React.useCallback((newValue) => setValue(newValue), []);
6060
+ return {
6061
+ value,
6062
+ setValue,
6063
+ onChange,
6064
+ options: staticOptions.length ? staticOptions : options,
6065
+ setOptions,
6066
+ };
6067
+ };
6068
+
6069
+ /**
6070
+ * Пропсы хоста фонового слоя для корней, которые не берут пропсы из `useWrapperSize`
6071
+ * (ставят `id`/`style` руками — `Title`, `Icon`, `Tabs`, `AddFeature`, `ExportPdf`, …).
6072
+ *
6073
+ * Контейнеры на `useContainerRoot` этот хук напрямую не зовут: `useWrapperSize` вызывает его
6074
+ * сам и кладёт результат в `root` — так признаки хоста считаются в одном месте.
6075
+ */
6076
+ const useBgImageHost = (elementConfig) => {
6077
+ const hasBgImage = React.useMemo(() => hasContainerBgImage(elementConfig), [elementConfig]);
6078
+ const innerPadding = !!elementConfig?.options?.innerPadding;
6079
+ return React.useMemo(() => ({ $hasBgImage: hasBgImage, $innerPadding: innerPadding }), [hasBgImage, innerPadding]);
6080
+ };
6081
+
6082
+ const useRenderContainerItem = (type, renderElement) => {
6083
+ const { config, layerInfo, selectedTabId, attributes } = useWidgetContext(type);
6084
+ return React.useCallback((elementConfig, attribute) => {
6085
+ const { id, options, style, children } = elementConfig || {};
6086
+ const { hideEmpty, innerTemplateStyle } = options || {};
6087
+ const hasUnits = children?.some(item => item.id === "units");
6088
+ const iconIndex = children?.findIndex(item => item.id === "icon");
6089
+ const icon = children?.[iconIndex];
6090
+ const hasIcon = !!icon;
6091
+ const elementChildren = elementConfig?.children?.map(child => ({
6092
+ type: "attributeValue",
6093
+ ...child,
6094
+ attributeName: attribute,
6095
+ options: { noUnits: hasUnits, ...child.options },
6096
+ }));
6097
+ const attr = getAttributeConfigurationByName(getAttributesConfiguration(layerInfo).attributes, attribute);
6098
+ if (hasIcon) {
6099
+ elementChildren[iconIndex] = {
6100
+ ...elementChildren[iconIndex],
6101
+ ...getAttributeIconElement(attr?.icon),
6102
+ attributeName: null,
6103
+ };
6104
+ }
6105
+ const render = attribute
6106
+ ? getRenderElement({
6107
+ config,
6108
+ elementConfig: {
6109
+ ...elementConfig,
6110
+ children: elementChildren,
6111
+ },
6112
+ selectedTabId,
6113
+ attributes,
6114
+ layerInfo,
6115
+ type,
6116
+ })
6117
+ : renderElement;
6118
+ const value = render({ id: "value" });
6119
+ return {
6120
+ id,
6121
+ value,
6122
+ hideEmpty,
6123
+ style: innerTemplateStyle || style,
6124
+ hasIcon,
6125
+ hasUnits,
6126
+ render,
6127
+ };
6128
+ }, [config, layerInfo, selectedTabId, attributes, type, renderElement]);
6129
+ };
6130
+
6131
+ const customModes = MapboxDraw.modes;
6132
+ const StaticMode = {};
6133
+ const InvisibleMode = {};
6134
+ StaticMode.onSetup = function () {
6135
+ this.setActionableState(undefined);
6136
+ return {};
6137
+ };
6138
+ StaticMode.toDisplayFeatures = function (state, geojson, display) {
6139
+ display(geojson);
6140
+ };
6141
+ InvisibleMode.onSetup = function () {
6142
+ this.setActionableState(undefined);
6143
+ return {};
6144
+ };
6145
+ InvisibleMode.toDisplayFeatures = function () { };
6146
+ customModes.static = StaticMode;
6147
+ customModes.invisible = InvisibleMode;
6148
+
6149
+ const customStyles = [
6150
+ {
6151
+ id: "gl-draw-point",
6152
+ type: "circle",
6153
+ filter: ["all", ["==", "$type", "Point"]],
6154
+ paint: {
6155
+ "circle-radius": 5,
6156
+ "circle-color": "#D20C0C",
6157
+ "circle-stroke-color": "#FFFFFF",
6158
+ "circle-stroke-width": 3,
6159
+ "circle-stroke-opacity": 0.3,
6160
+ },
6161
+ },
6162
+ {
6163
+ id: "highlight-inactive-points",
6164
+ type: "circle",
6165
+ filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "false"]],
6166
+ paint: {
6167
+ "circle-radius": 5,
6168
+ "circle-color": "#D20C0C",
6169
+ "circle-stroke-color": "#FFFFFF",
6170
+ "circle-stroke-width": 3,
6171
+ "circle-stroke-opacity": 0.3,
6172
+ },
6173
+ },
6174
+ {
6175
+ id: "highlight-active-points",
6176
+ type: "circle",
6177
+ filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "true"]],
6178
+ paint: {
6179
+ "circle-radius": 3,
6180
+ "circle-color": "#fbb03b",
6181
+ "circle-stroke-color": "#FFFFFF",
6182
+ "circle-stroke-width": 1,
6183
+ "circle-stroke-opacity": 0.3,
6184
+ },
6185
+ },
6186
+ {
6187
+ id: "gl-draw-polygon-fill-static",
6188
+ type: "fill",
6189
+ filter: ["all", ["==", "$type", "Polygon"]],
6190
+ paint: {
6191
+ "fill-color": "#D20C0C",
6192
+ "fill-outline-color": "#D20C0C",
6193
+ "fill-opacity": 0.1,
6194
+ },
6195
+ },
6196
+ {
6197
+ id: "gl-draw-line",
6198
+ type: "line",
6199
+ filter: ["all", ["==", "$type", "LineString"]],
5764
6200
  layout: {
5765
6201
  "line-cap": "round",
5766
6202
  "line-join": "round",
@@ -6369,326 +6805,337 @@ const useLayerParams = (layer) => {
6369
6805
  return layerParams;
6370
6806
  };
6371
6807
 
6372
- const parseAttachments = (raw) => {
6373
- if (!raw)
6374
- return [];
6375
- if (Array.isArray(raw))
6376
- return raw;
6377
- if (typeof raw !== "string")
6378
- return [];
6379
- try {
6380
- const parsed = JSON.parse(raw);
6381
- return Array.isArray(parsed) ? parsed : [];
6382
- }
6383
- catch {
6384
- return [];
6385
- }
6386
- };
6387
- const attachmentsFromFeatures = (features, mapping = {}) => {
6388
- if (!features?.length)
6389
- return [];
6390
- const { attributeLink = "link", attributeName = "name", attributeMime = "mimeType", attributeDate = "date", } = mapping;
6391
- return features
6392
- .map(feature => {
6393
- const link = feature.properties?.[attributeLink];
6394
- if (!link)
6395
- return null;
6396
- return {
6397
- link,
6398
- name: feature.properties?.[attributeName] ?? link,
6399
- mimeType: feature.properties?.[attributeMime] ?? "",
6400
- date: feature.properties?.[attributeDate],
6401
- isExternal: /^https?:\/\//.test(link),
6402
- };
6403
- })
6404
- .filter(Boolean);
6405
- };
6406
-
6407
- const useAttachmentItems = ({ type, elementConfig, valueOverride, }) => {
6408
- const { attributes, dataSources } = useWidgetContext(type);
6409
- const { children, options } = elementConfig || {};
6410
- const { relatedDataSource, controls } = options || {};
6411
- const valueElement = React.useMemo(() => children?.find(({ id }) => id === "value"), [children]);
6412
- const attributeName = React.useMemo(() => {
6413
- const candidate = valueElement?.attributeName ?? elementConfig?.attributeName;
6414
- return Array.isArray(candidate) ? candidate[0] : candidate;
6415
- }, [valueElement, elementConfig]);
6416
- const rawValue = React.useMemo(() => {
6417
- if (valueOverride !== undefined)
6418
- return valueOverride;
6419
- if (!attributeName)
6420
- return undefined;
6421
- return attributes?.find(item => item.attributeName === attributeName)?.value;
6422
- }, [valueOverride, attributeName, attributes]);
6423
- const items = React.useMemo(() => {
6424
- if (relatedDataSource) {
6425
- const dataSource = dataSources?.find(({ name }) => name === relatedDataSource);
6426
- const mapping = controls?.[0];
6427
- return attachmentsFromFeatures(dataSource?.features, mapping);
6808
+ const useMaxZoomTo = () => {
6809
+ const { currentPage } = useWidgetPage();
6810
+ return React.useCallback((layerName) => {
6811
+ if (!layerName) {
6812
+ return [currentPage?.options?.maxZoomTo, undefined];
6428
6813
  }
6429
- return parseAttachments(rawValue);
6430
- }, [relatedDataSource, dataSources, controls, rawValue]);
6431
- return {
6432
- items,
6433
- attributeName,
6434
- rawValue,
6435
- };
6436
- };
6437
-
6438
- const useGlobalContext = () => {
6439
- const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, notification } = React.useContext(GlobalContext) || {};
6440
- const translate = React.useCallback((value, options) => {
6441
- if (t)
6442
- return t(value, options);
6443
- return options?.defaultValue ?? value;
6444
- }, [t]);
6445
- return React.useMemo(() => ({
6446
- t: translate,
6447
- language,
6448
- themeName,
6449
- api,
6450
- ewktGeometry,
6451
- ewktExtent,
6452
- zoomLevel,
6453
- notification,
6454
- }), [language, translate, api, ewktGeometry, ewktExtent, zoomLevel, themeName, notification]);
6455
- };
6456
-
6457
- const GRID_TILE_SIZE = "4.5rem";
6458
- const LIST_ICON_SIZE = "1.5rem";
6459
- const JPG_MIME_TYPE = "image/jpeg";
6460
- const PNG_MIME_TYPE = "image/png";
6461
- const IMAGE_MIME_TYPES = [
6462
- "image/apng",
6463
- "image/avif",
6464
- "image/gif",
6465
- "image/jpeg",
6466
- "image/png",
6467
- "image/svg+xml",
6468
- "image/webp",
6469
- ];
6470
- const XLSX_MIME_TYPES = [
6471
- "application/vnd.ms-excel",
6472
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
6473
- ];
6474
- const PDF_MIME_TYPE = "application/pdf";
6475
- const DOCX_MIME_TYPES = [
6476
- "application/msword",
6477
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
6478
- ];
6479
- const CSV_MIME_TYPE = "text/csv";
6480
- const JSON_MIME_TYPE = "application/json";
6481
- const TXT_MIME_TYPE = "text/plain";
6482
- const PPTX_MIME_TYPES = [
6483
- "application/vnd.ms-powerpoint",
6484
- "application/vnd.openxmlformats-officedocument.presentationml.presentation",
6485
- ];
6486
- const SHP_MIME_TYPE = "application/octet-stream";
6487
- const KML_MIME_TYPE = "application/octet-stream";
6488
- const ZIP_MIME_TYPE = "application/zip";
6489
- const PYTHON_MIME_TYPES = ["application/x-python-code", "text/x-python"];
6490
- var AddAttachmentSource;
6491
- (function (AddAttachmentSource) {
6492
- AddAttachmentSource["Pc"] = "pc";
6493
- AddAttachmentSource["Catalog"] = "catalog";
6494
- AddAttachmentSource["Link"] = "link";
6495
- })(AddAttachmentSource || (AddAttachmentSource = {}));
6496
-
6497
- var FileType;
6498
- (function (FileType) {
6499
- FileType[FileType["UNKNOWN"] = 0] = "UNKNOWN";
6500
- FileType[FileType["XLSX"] = 1] = "XLSX";
6501
- FileType[FileType["PDF"] = 2] = "PDF";
6502
- FileType[FileType["CSV"] = 3] = "CSV";
6503
- FileType[FileType["DOCX"] = 4] = "DOCX";
6504
- FileType[FileType["IMAGE"] = 5] = "IMAGE";
6505
- FileType[FileType["TXT"] = 6] = "TXT";
6506
- FileType[FileType["JSON"] = 7] = "JSON";
6507
- FileType[FileType["KML"] = 8] = "KML";
6508
- FileType[FileType["PPTX"] = 9] = "PPTX";
6509
- FileType[FileType["SHP"] = 10] = "SHP";
6510
- FileType[FileType["ZIP"] = 11] = "ZIP";
6511
- FileType[FileType["JPEG"] = 12] = "JPEG";
6512
- FileType[FileType["JPG"] = 13] = "JPG";
6513
- FileType[FileType["PNG"] = 14] = "PNG";
6514
- FileType[FileType["PYTHON"] = 15] = "PYTHON";
6515
- })(FileType || (FileType = {}));
6516
- const IMAGE_FILE_TYPES = [
6517
- FileType.IMAGE,
6518
- FileType.JPEG,
6519
- FileType.JPG,
6520
- FileType.PNG,
6521
- ];
6522
-
6523
- const getFileType = (mimeType = "", name = "") => {
6524
- if (mimeType === PNG_MIME_TYPE)
6525
- return FileType.PNG;
6526
- if (mimeType === JPG_MIME_TYPE)
6527
- return FileType.JPG;
6528
- if (IMAGE_MIME_TYPES.includes(mimeType))
6529
- return FileType.IMAGE;
6530
- if (XLSX_MIME_TYPES.includes(mimeType))
6531
- return FileType.XLSX;
6532
- if (DOCX_MIME_TYPES.includes(mimeType))
6533
- return FileType.DOCX;
6534
- if (mimeType === CSV_MIME_TYPE)
6535
- return FileType.CSV;
6536
- if (mimeType === PDF_MIME_TYPE)
6537
- return FileType.PDF;
6538
- if (mimeType === JSON_MIME_TYPE)
6539
- return FileType.JSON;
6540
- if (mimeType === KML_MIME_TYPE && (name.endsWith(".kml") || name.endsWith(".kmz"))) {
6541
- return FileType.KML;
6542
- }
6543
- if (PYTHON_MIME_TYPES.includes(mimeType))
6544
- return FileType.PYTHON;
6545
- if (mimeType === TXT_MIME_TYPE && name.endsWith(".py"))
6546
- return FileType.PYTHON;
6547
- if (mimeType === TXT_MIME_TYPE)
6548
- return FileType.TXT;
6549
- if (PPTX_MIME_TYPES.includes(mimeType))
6550
- return FileType.PPTX;
6551
- if (mimeType === SHP_MIME_TYPE && name.endsWith(".shp"))
6552
- return FileType.SHP;
6553
- if (mimeType === ZIP_MIME_TYPE)
6554
- return FileType.ZIP;
6555
- return name.endsWith(".py") ? FileType.PYTHON : FileType.UNKNOWN;
6814
+ return [currentPage?.options?.maxZoomTo, currentPage?.layers?.find(item => item.name === layerName)?.maxZoomTo];
6815
+ }, [currentPage?.layers, currentPage?.options?.maxZoomTo]);
6556
6816
  };
6557
6817
 
6558
- var img$j = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%2300AAFF'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cpath id='Vector_3' d='M9.84902 10.0353C9.69434 10.0353 9.55605 10.0112 9.43418 9.96318C9.3123 9.91396 9.20918 9.84658 9.1248 9.76104C9.0416 9.67549 8.97773 9.57705 8.9332 9.46572C8.88984 9.35439 8.86816 9.23662 8.86816 9.1124V9.04561C8.86816 8.90615 8.8875 8.77725 8.92617 8.65889C8.96484 8.53936 9.02227 8.43506 9.09844 8.346C9.17461 8.25693 9.27012 8.18779 9.38496 8.13857C9.4998 8.08818 9.6334 8.06299 9.78574 8.06299C9.92051 8.06299 10.0412 8.08467 10.1479 8.12803C10.2545 8.17139 10.3447 8.2335 10.4186 8.31436C10.4936 8.39521 10.5504 8.49307 10.5891 8.60791C10.6289 8.72275 10.6488 8.85166 10.6488 8.99463V9.23545H9.09492V8.86455H10.0705V8.81885C10.0717 8.75557 10.0605 8.70166 10.0371 8.65713C10.0148 8.6126 9.98203 8.57861 9.93867 8.55518C9.89531 8.53174 9.84258 8.52002 9.78047 8.52002C9.71602 8.52002 9.6627 8.53408 9.62051 8.56221C9.57949 8.59033 9.54727 8.629 9.52383 8.67822C9.50156 8.72627 9.48574 8.78193 9.47637 8.84521C9.46699 8.9085 9.46231 8.97529 9.46231 9.04561V9.1124C9.46231 9.18271 9.47168 9.24658 9.49043 9.304C9.51035 9.36143 9.53848 9.41064 9.5748 9.45166C9.6123 9.4915 9.65684 9.52256 9.7084 9.54482C9.76113 9.56709 9.8209 9.57822 9.8877 9.57822C9.96855 9.57822 10.0482 9.56299 10.1268 9.53252C10.2053 9.50205 10.2727 9.45166 10.3289 9.38135L10.5979 9.70127C10.5592 9.75635 10.5041 9.80967 10.4326 9.86123C10.3623 9.91279 10.2779 9.95498 10.1795 9.98779C10.0811 10.0194 9.9709 10.0353 9.84902 10.0353Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.4623 7.2998V9.9998H7.86816V7.2998H8.4623Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.17773 10.0001H5.58184V8.04893C5.58184 7.879 5.61699 7.73604 5.6873 7.62002C5.75879 7.50283 5.86133 7.41436 5.99492 7.35459C6.12852 7.29365 6.29023 7.26318 6.48008 7.26318C6.58789 7.26318 6.6916 7.27256 6.79121 7.29131C6.89082 7.31006 6.99395 7.33467 7.10059 7.36514L7.01797 7.83271C6.94883 7.81396 6.87617 7.79639 6.8 7.77998C6.725 7.76357 6.63066 7.75537 6.51699 7.75537C6.41035 7.75537 6.32715 7.78057 6.26738 7.83096C6.20762 7.88135 6.17773 7.954 6.17773 8.04893V10.0001ZM6.55039 8.09814V8.50947H5.30762V8.09814H6.55039ZM7.37129 8.09814V10.0001H6.77715V8.09814H7.37129Z' fill='white'/%3e%3c/g%3e%3c/svg%3e";
6559
-
6560
- var img$i = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%2347C782'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='CSV'%3e%3cpath id='Vector_3' d='M10.3816 9.39736L10.9143 7.44092H11.6051L10.742 10.0003H10.2955L10.3816 9.39736ZM9.89824 7.44092L10.4309 9.39736L10.5205 10.0003H10.0687L9.21094 7.44092H9.89824Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.37852 9.32002C8.37852 9.28018 8.37266 9.24443 8.36094 9.21279C8.34922 9.17998 8.32754 9.14951 8.2959 9.12139C8.26426 9.09326 8.21855 9.06514 8.15879 9.03701C8.10019 9.00771 8.02285 8.97725 7.92676 8.94561C7.81426 8.90811 7.70586 8.86592 7.60156 8.81904C7.49727 8.771 7.4041 8.71533 7.32207 8.65205C7.24004 8.5876 7.175 8.5126 7.12695 8.42705C7.07891 8.34033 7.05488 8.23955 7.05488 8.12471C7.05488 8.01455 7.07949 7.91553 7.12871 7.82764C7.17793 7.73857 7.24648 7.66299 7.33437 7.60088C7.42344 7.5376 7.52773 7.48955 7.64727 7.45674C7.7668 7.42275 7.89746 7.40576 8.03926 7.40576C8.22676 7.40576 8.39199 7.43857 8.53496 7.5042C8.6791 7.56865 8.7916 7.66064 8.87246 7.78018C8.95449 7.89854 8.99551 8.03857 8.99551 8.20029H8.38203C8.38203 8.13584 8.36855 8.079 8.3416 8.02979C8.31582 7.98057 8.27656 7.94189 8.22383 7.91377C8.17109 7.88564 8.10488 7.87158 8.0252 7.87158C7.94785 7.87158 7.88281 7.8833 7.83008 7.90674C7.77734 7.93018 7.7375 7.96182 7.71055 8.00166C7.68359 8.04033 7.67012 8.08311 7.67012 8.12998C7.67012 8.16865 7.68066 8.20381 7.70176 8.23545C7.72402 8.26592 7.75508 8.29463 7.79492 8.32158C7.83594 8.34854 7.88516 8.37432 7.94258 8.39893C8.00117 8.42354 8.0668 8.44756 8.13945 8.471C8.27539 8.51436 8.39609 8.56299 8.50156 8.61689C8.6082 8.66963 8.69785 8.72998 8.77051 8.79795C8.84434 8.86475 8.9 8.94092 8.9375 9.02646C8.97617 9.11201 8.99551 9.20869 8.99551 9.3165C8.99551 9.43135 8.97324 9.5333 8.92871 9.62236C8.88418 9.71143 8.82031 9.78701 8.73711 9.84912C8.65391 9.91006 8.5543 9.95635 8.43828 9.98799C8.32227 10.0196 8.19277 10.0354 8.0498 10.0354C7.91855 10.0354 7.78906 10.019 7.66133 9.98623C7.53477 9.95225 7.41992 9.90068 7.3168 9.83154C7.21367 9.76123 7.13105 9.67158 7.06894 9.5626C7.00801 9.45244 6.97754 9.32178 6.97754 9.17061H7.59629C7.59629 9.24561 7.60625 9.30889 7.62617 9.36045C7.64609 9.41201 7.67539 9.45361 7.71406 9.48525C7.75273 9.51572 7.8002 9.53799 7.85645 9.55205C7.9127 9.56494 7.97715 9.57139 8.0498 9.57139C8.12832 9.57139 8.1916 9.56025 8.23965 9.53799C8.2877 9.51455 8.32285 9.48408 8.34512 9.44658C8.36738 9.40791 8.37852 9.36572 8.37852 9.32002Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.05293 9.1335H6.66816C6.65996 9.31162 6.61191 9.46865 6.52402 9.60459C6.43613 9.74053 6.31426 9.84658 6.1584 9.92275C6.00371 9.99775 5.8209 10.0353 5.60996 10.0353C5.43887 10.0353 5.28594 10.0065 5.15117 9.94912C5.01758 9.8917 4.90391 9.80908 4.81016 9.70127C4.71758 9.59346 4.64668 9.46279 4.59746 9.30928C4.54941 9.15576 4.52539 8.98291 4.52539 8.79072V8.65186C4.52539 8.45967 4.55059 8.28682 4.60098 8.1333C4.65254 7.97861 4.7252 7.84736 4.81895 7.73955C4.91387 7.63057 5.02754 7.54736 5.15996 7.48994C5.29238 7.43252 5.43945 7.40381 5.60117 7.40381C5.82383 7.40381 6.01191 7.44365 6.16543 7.52334C6.31895 7.60303 6.43789 7.7126 6.52227 7.85205C6.60664 7.99033 6.65645 8.14795 6.67168 8.3249H6.05645C6.0541 8.22881 6.0377 8.14854 6.00723 8.08408C5.97676 8.01846 5.92871 7.96924 5.86309 7.93643C5.79746 7.90361 5.71016 7.88721 5.60117 7.88721C5.525 7.88721 5.45879 7.90127 5.40254 7.92939C5.34629 7.95752 5.29941 8.00205 5.26191 8.06299C5.22441 8.12393 5.19629 8.20303 5.17754 8.30029C5.15996 8.39639 5.15117 8.5124 5.15117 8.64834V8.79072C5.15117 8.92666 5.15938 9.04268 5.17578 9.13877C5.19219 9.23486 5.21855 9.31338 5.25488 9.37432C5.29121 9.43525 5.33809 9.48037 5.39551 9.50967C5.4541 9.53779 5.52559 9.55186 5.60996 9.55186C5.70371 9.55186 5.78281 9.53721 5.84727 9.50791C5.91172 9.47744 5.96152 9.43174 5.99668 9.3708C6.03184 9.30869 6.05059 9.22959 6.05293 9.1335Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6561
-
6562
- var img$h = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%232B7CD3'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='DOCX'%3e%3cpath id='Vector_3' d='M11.3209 7.44092L11.7393 8.2917L12.1576 7.44092H12.8607L12.1471 8.71006L12.8801 10.0003H12.1699L11.7393 9.13369L11.3086 10.0003H10.5967L11.3314 8.71006L10.616 7.44092H11.3209Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.77754 9.1335H10.3928C10.3846 9.31162 10.3365 9.46865 10.2486 9.60459C10.1607 9.74053 10.0389 9.84658 9.88301 9.92275C9.72832 9.99775 9.54551 10.0353 9.33457 10.0353C9.16348 10.0353 9.01055 10.0065 8.87578 9.94912C8.74219 9.8917 8.62852 9.80908 8.53477 9.70127C8.44219 9.59346 8.37129 9.46279 8.32207 9.30928C8.27402 9.15576 8.25 8.98291 8.25 8.79072V8.65186C8.25 8.45967 8.2752 8.28682 8.32559 8.1333C8.37715 7.97861 8.4498 7.84736 8.54355 7.73955C8.63848 7.63057 8.75215 7.54736 8.88457 7.48994C9.01699 7.43252 9.16406 7.40381 9.32578 7.40381C9.54844 7.40381 9.73652 7.44365 9.89004 7.52334C10.0436 7.60303 10.1625 7.7126 10.2469 7.85205C10.3313 7.99033 10.3811 8.14795 10.3963 8.3249H9.78105C9.77871 8.22881 9.7623 8.14854 9.73184 8.08408C9.70137 8.01846 9.65332 7.96924 9.5877 7.93643C9.52207 7.90361 9.43477 7.88721 9.32578 7.88721C9.24961 7.88721 9.1834 7.90127 9.12715 7.92939C9.0709 7.95752 9.02402 8.00205 8.98652 8.06299C8.94902 8.12393 8.9209 8.20303 8.90215 8.30029C8.88457 8.39639 8.87578 8.5124 8.87578 8.64834V8.79072C8.87578 8.92666 8.88398 9.04268 8.90039 9.13877C8.9168 9.23486 8.94316 9.31338 8.97949 9.37432C9.01582 9.43525 9.0627 9.48037 9.12012 9.50967C9.17871 9.53779 9.2502 9.55186 9.33457 9.55186C9.42832 9.55186 9.50742 9.53721 9.57188 9.50791C9.63633 9.47744 9.68613 9.43174 9.72129 9.3708C9.75645 9.30869 9.7752 9.22959 9.77754 9.1335Z' fill='white'/%3e%3cpath id='Vector_5' d='M7.90176 8.66963V8.77334C7.90176 8.96904 7.87422 9.14482 7.81914 9.30068C7.76523 9.45537 7.68848 9.58779 7.58887 9.69795C7.48926 9.80693 7.37148 9.89072 7.23555 9.94932C7.09961 10.0067 6.94961 10.0354 6.78555 10.0354C6.62031 10.0354 6.46914 10.0067 6.33203 9.94932C6.19609 9.89072 6.07773 9.80693 5.97695 9.69795C5.87734 9.58779 5.8 9.45537 5.74492 9.30068C5.69102 9.14482 5.66406 8.96904 5.66406 8.77334V8.66963C5.66406 8.47393 5.69102 8.29814 5.74492 8.14229C5.8 7.98643 5.87676 7.854 5.9752 7.74502C6.0748 7.63486 6.19258 7.55107 6.32852 7.49365C6.46563 7.43506 6.6168 7.40576 6.78203 7.40576C6.94609 7.40576 7.09609 7.43506 7.23203 7.49365C7.36914 7.55107 7.4875 7.63486 7.58711 7.74502C7.68672 7.854 7.76406 7.98643 7.81914 8.14229C7.87422 8.29814 7.90176 8.47393 7.90176 8.66963ZM7.27598 8.77334V8.66611C7.27598 8.53955 7.26484 8.42822 7.24258 8.33213C7.22148 8.23486 7.18984 8.15342 7.14766 8.08779C7.10547 8.02217 7.05332 7.97295 6.99121 7.94014C6.93027 7.90615 6.86055 7.88916 6.78203 7.88916C6.7 7.88916 6.62852 7.90615 6.56758 7.94014C6.50664 7.97295 6.45566 8.02217 6.41465 8.08779C6.37363 8.15342 6.34258 8.23486 6.32148 8.33213C6.30156 8.42822 6.2916 8.53955 6.2916 8.66611V8.77334C6.2916 8.89873 6.30156 9.01006 6.32148 9.10732C6.34258 9.20342 6.37363 9.28486 6.41465 9.35166C6.45684 9.41846 6.5084 9.46885 6.56934 9.50283C6.63145 9.53682 6.70352 9.55381 6.78555 9.55381C6.86406 9.55381 6.93379 9.53682 6.99473 9.50283C7.05566 9.46885 7.10664 9.41846 7.14766 9.35166C7.18984 9.28486 7.22148 9.20342 7.24258 9.10732C7.26484 9.01006 7.27598 8.89873 7.27598 8.77334Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.13711 10.0003H3.56934L3.57285 9.52568H4.13711C4.2543 9.52568 4.35332 9.49756 4.43418 9.44131C4.51621 9.38506 4.57832 9.30127 4.62051 9.18994C4.66387 9.07744 4.68555 8.93916 4.68555 8.7751V8.66436C4.68555 8.54131 4.67324 8.4335 4.64863 8.34092C4.6252 8.24717 4.59004 8.16924 4.54316 8.10713C4.49629 8.04385 4.4377 7.99639 4.36738 7.96475C4.29824 7.93311 4.21855 7.91729 4.12832 7.91729H3.55879V7.44092H4.12832C4.30176 7.44092 4.46055 7.4708 4.60469 7.53057C4.75 7.58916 4.87539 7.67354 4.98086 7.78369C5.0875 7.89268 5.16953 8.02217 5.22695 8.17217C5.28555 8.321 5.31484 8.48623 5.31484 8.66787V8.7751C5.31484 8.95557 5.28555 9.1208 5.22695 9.2708C5.16953 9.4208 5.08809 9.55029 4.98262 9.65928C4.87715 9.76826 4.75234 9.85264 4.6082 9.9124C4.46523 9.971 4.3082 10.0003 4.13711 10.0003ZM3.92266 7.44092V10.0003H3.30566V7.44092H3.92266Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6563
-
6564
- var img$g = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23FF9C54'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='JPEG'%3e%3cpath id='Vector_3' d='M12.4043 8.63301V9.68418C12.3609 9.73223 12.2941 9.78379 12.2039 9.83887C12.1148 9.89277 12.0023 9.93906 11.8664 9.97773C11.7305 10.0164 11.5705 10.0357 11.3865 10.0357C11.2166 10.0357 11.0625 10.0088 10.9242 9.95488C10.7859 9.8998 10.667 9.81953 10.5674 9.71406C10.4689 9.60742 10.3928 9.47734 10.3389 9.32383C10.2861 9.16914 10.2598 8.99219 10.2598 8.79297V8.65059C10.2598 8.45137 10.2867 8.27441 10.3406 8.11973C10.3945 7.96504 10.4701 7.83496 10.5674 7.72949C10.6658 7.62285 10.7813 7.54199 10.9137 7.48691C11.0473 7.43184 11.1938 7.4043 11.3531 7.4043C11.5887 7.4043 11.7803 7.4418 11.9279 7.5168C12.0756 7.59063 12.1875 7.69316 12.2637 7.82441C12.3398 7.95449 12.3861 8.10508 12.4025 8.27617H11.8102C11.7984 8.1918 11.7762 8.12031 11.7434 8.06172C11.7117 8.00195 11.666 7.95684 11.6063 7.92637C11.5465 7.89473 11.4691 7.87891 11.3742 7.87891C11.3004 7.87891 11.233 7.89473 11.1721 7.92637C11.1123 7.95801 11.0613 8.00605 11.0191 8.07051C10.977 8.13379 10.9441 8.21348 10.9207 8.30957C10.8984 8.40566 10.8873 8.51816 10.8873 8.64707V8.79297C10.8873 8.9207 10.8979 9.03262 10.9189 9.12871C10.9412 9.2248 10.974 9.30508 11.0174 9.36953C11.0619 9.43281 11.1182 9.48086 11.1861 9.51367C11.2553 9.54531 11.3367 9.56113 11.4305 9.56113C11.4961 9.56113 11.5523 9.55586 11.5992 9.54531C11.6461 9.53359 11.6848 9.51953 11.7152 9.50312C11.7469 9.48555 11.7709 9.46914 11.7873 9.45391V9.05664H11.3584V8.63301H12.4043Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.95762 9.52617V10.0008H8.59355V9.52617H9.95762ZM8.81328 7.44141V10.0008H8.19629V7.44141H8.81328ZM9.78184 8.45742V8.91621H8.59355V8.45742H9.78184ZM9.96289 7.44141V7.91777H8.59355V7.44141H9.96289Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.77227 9.13242H6.13594V8.65605H6.77227C6.85898 8.65605 6.9293 8.64141 6.9832 8.61211C7.03711 8.58281 7.07637 8.54238 7.10098 8.49082C7.12676 8.43809 7.13965 8.37891 7.13965 8.31328C7.13965 8.24297 7.12676 8.17793 7.10098 8.11816C7.07637 8.0584 7.03711 8.01035 6.9832 7.97402C6.9293 7.93652 6.85898 7.91777 6.77227 7.91777H6.36797V10.0008H5.75098V7.44141H6.77227C6.97734 7.44141 7.15371 7.47891 7.30137 7.55391C7.4502 7.62891 7.56445 7.73203 7.64414 7.86328C7.72383 7.99336 7.76367 8.14219 7.76367 8.30977C7.76367 8.475 7.72383 8.61914 7.64414 8.74219C7.56445 8.86523 7.4502 8.96133 7.30137 9.03047C7.15371 9.09844 6.97734 9.13242 6.77227 9.13242Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.64395 9.19746V7.44141H5.25918V9.19746C5.25918 9.36855 5.21992 9.5168 5.14141 9.64219C5.06406 9.76758 4.95859 9.86484 4.825 9.93398C4.69258 10.002 4.54375 10.0359 4.37852 10.0359C4.20742 10.0359 4.05508 10.0072 3.92148 9.9498C3.78906 9.89238 3.68477 9.80391 3.60859 9.68437C3.53359 9.56484 3.49609 9.4125 3.49609 9.22734H4.11484C4.11484 9.31406 4.1248 9.38203 4.14473 9.43125C4.16465 9.4793 4.19395 9.51328 4.23262 9.5332C4.27246 9.55195 4.32109 9.56133 4.37852 9.56133C4.43477 9.56133 4.48223 9.54727 4.5209 9.51914C4.56074 9.48984 4.59121 9.44824 4.6123 9.39434C4.6334 9.33926 4.64395 9.27363 4.64395 9.19746Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6818
+ const useCustomFeatureSelect = () => {
6819
+ const { currentPage } = useWidgetPage();
6820
+ return React.useCallback((layerName) => {
6821
+ if (!layerName) {
6822
+ return [currentPage?.options?.customFeatureSelect, undefined];
6823
+ }
6824
+ return [
6825
+ currentPage?.options?.customFeatureSelect,
6826
+ currentPage?.layers?.find(item => item.name === layerName)?.customFeatureSelect,
6827
+ ];
6828
+ }, [currentPage?.layers, currentPage?.options?.customFeatureSelect]);
6829
+ };
6565
6830
 
6566
- var img$f = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23FF9C54'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='JPG'%3e%3cpath id='Vector_3' d='M11.3467 8.63301V9.68418C11.3033 9.73223 11.2365 9.78379 11.1463 9.83887C11.0572 9.89277 10.9447 9.93906 10.8088 9.97773C10.6729 10.0164 10.5129 10.0357 10.3289 10.0357C10.159 10.0357 10.0049 10.0088 9.8666 9.95488C9.72832 9.8998 9.60938 9.81953 9.50977 9.71406C9.41133 9.60742 9.33516 9.47734 9.28125 9.32383C9.22852 9.16914 9.20215 8.99219 9.20215 8.79297V8.65059C9.20215 8.45137 9.2291 8.27441 9.28301 8.11973C9.33691 7.96504 9.4125 7.83496 9.50977 7.72949C9.6082 7.62285 9.72363 7.54199 9.85605 7.48691C9.98965 7.43184 10.1361 7.4043 10.2955 7.4043C10.5311 7.4043 10.7227 7.4418 10.8703 7.5168C11.018 7.59063 11.1299 7.69316 11.2061 7.82441C11.2822 7.95449 11.3285 8.10508 11.3449 8.27617H10.7525C10.7408 8.1918 10.7186 8.12031 10.6857 8.06172C10.6541 8.00195 10.6084 7.95684 10.5486 7.92637C10.4889 7.89473 10.4115 7.87891 10.3166 7.87891C10.2428 7.87891 10.1754 7.89473 10.1145 7.92637C10.0547 7.95801 10.0037 8.00605 9.96152 8.07051C9.91934 8.13379 9.88652 8.21348 9.86309 8.30957C9.84082 8.40566 9.82969 8.51816 9.82969 8.64707V8.79297C9.82969 8.9207 9.84023 9.03262 9.86133 9.12871C9.88359 9.2248 9.91641 9.30508 9.95977 9.36953C10.0043 9.43281 10.0605 9.48086 10.1285 9.51367C10.1977 9.54531 10.2791 9.56113 10.3729 9.56113C10.4385 9.56113 10.4947 9.55586 10.5416 9.54531C10.5885 9.53359 10.6271 9.51953 10.6576 9.50312C10.6893 9.48555 10.7133 9.46914 10.7297 9.45391V9.05664H10.3008V8.63301H11.3467Z' fill='white'/%3e%3cpath id='Vector_4' d='M7.82891 9.13242H7.19258V8.65605H7.82891C7.91563 8.65605 7.98594 8.64141 8.03984 8.61211C8.09375 8.58281 8.13301 8.54238 8.15762 8.49082C8.1834 8.43809 8.19629 8.37891 8.19629 8.31328C8.19629 8.24297 8.1834 8.17793 8.15762 8.11816C8.13301 8.0584 8.09375 8.01035 8.03984 7.97402C7.98594 7.93652 7.91563 7.91777 7.82891 7.91777H7.42461V10.0008H6.80762V7.44141H7.82891C8.03398 7.44141 8.21035 7.47891 8.35801 7.55391C8.50684 7.62891 8.62109 7.73203 8.70078 7.86328C8.78047 7.99336 8.82031 8.14219 8.82031 8.30977C8.82031 8.475 8.78047 8.61914 8.70078 8.74219C8.62109 8.86523 8.50684 8.96133 8.35801 9.03047C8.21035 9.09844 8.03398 9.13242 7.82891 9.13242Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.70059 9.19746V7.44141H6.31582V9.19746C6.31582 9.36855 6.27656 9.5168 6.19805 9.64219C6.1207 9.76758 6.01523 9.86484 5.88164 9.93398C5.74922 10.002 5.60039 10.0359 5.43516 10.0359C5.26406 10.0359 5.11172 10.0072 4.97812 9.9498C4.8457 9.89238 4.74141 9.80391 4.66523 9.68437C4.59023 9.56484 4.55273 9.4125 4.55273 9.22734H5.17148C5.17148 9.31406 5.18145 9.38203 5.20137 9.43125C5.22129 9.4793 5.25059 9.51328 5.28926 9.5332C5.3291 9.55195 5.37773 9.56133 5.43516 9.56133C5.49141 9.56133 5.53887 9.54727 5.57754 9.51914C5.61738 9.48984 5.64785 9.44824 5.66895 9.39434C5.69004 9.33926 5.70059 9.27363 5.70059 9.19746Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6831
+ const useCurrentPageLayers = () => {
6832
+ const { currentPage } = useWidgetPage();
6833
+ return React.useMemo(() => currentPage?.layers || [], [currentPage?.layers]);
6834
+ };
6567
6835
 
6568
- var img$e = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23AE6BF1'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='JSON'%3e%3cpath id='Vector_3' d='M12.6014 7.44043V9.9998H11.9861L11.0809 8.40723V9.9998H10.4639V7.44043H11.0809L11.9861 9.03301V7.44043H12.6014Z' fill='white'/%3e%3cpath id='Vector_4' d='M10.0434 8.66914V8.77285C10.0434 8.96855 10.0158 9.14434 9.96074 9.3002C9.90684 9.45488 9.83008 9.5873 9.73047 9.69746C9.63086 9.80645 9.51309 9.89023 9.37715 9.94883C9.24121 10.0063 9.09121 10.035 8.92715 10.035C8.76191 10.035 8.61074 10.0063 8.47363 9.94883C8.3377 9.89023 8.21934 9.80645 8.11855 9.69746C8.01895 9.5873 7.9416 9.45488 7.88652 9.3002C7.83262 9.14434 7.80566 8.96855 7.80566 8.77285V8.66914C7.80566 8.47344 7.83262 8.29766 7.88652 8.1418C7.9416 7.98594 8.01836 7.85352 8.1168 7.74453C8.21641 7.63437 8.33418 7.55059 8.47012 7.49316C8.60723 7.43457 8.7584 7.40527 8.92363 7.40527C9.0877 7.40527 9.2377 7.43457 9.37363 7.49316C9.51074 7.55059 9.6291 7.63437 9.72871 7.74453C9.82832 7.85352 9.90566 7.98594 9.96074 8.1418C10.0158 8.29766 10.0434 8.47344 10.0434 8.66914ZM9.41758 8.77285V8.66562C9.41758 8.53906 9.40645 8.42773 9.38418 8.33164C9.36309 8.23438 9.33145 8.15293 9.28926 8.0873C9.24707 8.02168 9.19492 7.97246 9.13281 7.93965C9.07187 7.90566 9.00215 7.88867 8.92363 7.88867C8.8416 7.88867 8.77012 7.90566 8.70918 7.93965C8.64824 7.97246 8.59727 8.02168 8.55625 8.0873C8.51523 8.15293 8.48418 8.23438 8.46309 8.33164C8.44316 8.42773 8.4332 8.53906 8.4332 8.66562V8.77285C8.4332 8.89824 8.44316 9.00957 8.46309 9.10684C8.48418 9.20293 8.51523 9.28437 8.55625 9.35117C8.59844 9.41797 8.65 9.46836 8.71094 9.50234C8.77305 9.53633 8.84512 9.55332 8.92715 9.55332C9.00566 9.55332 9.07539 9.53633 9.13633 9.50234C9.19727 9.46836 9.24824 9.41797 9.28926 9.35117C9.33145 9.28437 9.36309 9.20293 9.38418 9.10684C9.40645 9.00957 9.41758 8.89824 9.41758 8.77285Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.84336 9.31953C6.84336 9.27969 6.8375 9.24395 6.82578 9.2123C6.81406 9.17949 6.79238 9.14902 6.76074 9.1209C6.7291 9.09277 6.6834 9.06465 6.62363 9.03652C6.56504 9.00723 6.4877 8.97676 6.3916 8.94512C6.2791 8.90762 6.1707 8.86543 6.06641 8.81855C5.96211 8.77051 5.86895 8.71484 5.78691 8.65156C5.70488 8.58711 5.63984 8.51211 5.5918 8.42656C5.54375 8.33984 5.51973 8.23906 5.51973 8.12422C5.51973 8.01406 5.54434 7.91504 5.59355 7.82715C5.64277 7.73809 5.71133 7.6625 5.79922 7.60039C5.88828 7.53711 5.99258 7.48906 6.11211 7.45625C6.23164 7.42227 6.3623 7.40527 6.5041 7.40527C6.6916 7.40527 6.85684 7.43809 6.9998 7.50371C7.14395 7.56816 7.25645 7.66016 7.3373 7.77969C7.41934 7.89805 7.46035 8.03809 7.46035 8.1998H6.84688C6.84688 8.13535 6.8334 8.07852 6.80645 8.0293C6.78066 7.98008 6.74141 7.94141 6.68867 7.91328C6.63594 7.88516 6.56973 7.87109 6.49004 7.87109C6.4127 7.87109 6.34766 7.88281 6.29492 7.90625C6.24219 7.92969 6.20234 7.96133 6.17539 8.00117C6.14844 8.03984 6.13496 8.08262 6.13496 8.12949C6.13496 8.16816 6.14551 8.20332 6.1666 8.23496C6.18887 8.26543 6.21992 8.29414 6.25977 8.32109C6.30078 8.34805 6.35 8.37383 6.40742 8.39844C6.46602 8.42305 6.53164 8.44707 6.6043 8.47051C6.74023 8.51387 6.86094 8.5625 6.96641 8.61641C7.07305 8.66914 7.1627 8.72949 7.23535 8.79746C7.30918 8.86426 7.36484 8.94043 7.40234 9.02598C7.44102 9.11152 7.46035 9.2082 7.46035 9.31602C7.46035 9.43086 7.43809 9.53281 7.39355 9.62187C7.34902 9.71094 7.28516 9.78652 7.20195 9.84863C7.11875 9.90957 7.01914 9.95586 6.90312 9.9875C6.78711 10.0191 6.65762 10.035 6.51465 10.035C6.3834 10.035 6.25391 10.0186 6.12617 9.98574C5.99961 9.95176 5.88477 9.9002 5.78164 9.83105C5.67852 9.76074 5.5959 9.67109 5.53379 9.56211C5.47285 9.45195 5.44238 9.32129 5.44238 9.17012H6.06113C6.06113 9.24512 6.07109 9.3084 6.09102 9.35996C6.11094 9.41152 6.14023 9.45312 6.17891 9.48477C6.21758 9.51523 6.26504 9.5375 6.32129 9.55156C6.37754 9.56445 6.44199 9.5709 6.51465 9.5709C6.59316 9.5709 6.65645 9.55977 6.70449 9.5375C6.75254 9.51406 6.7877 9.48359 6.80996 9.44609C6.83223 9.40742 6.84336 9.36523 6.84336 9.31953Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.41738 9.19648V7.44043H5.03262V9.19648C5.03262 9.36758 4.99336 9.51582 4.91484 9.64121C4.8375 9.7666 4.73203 9.86387 4.59844 9.93301C4.46602 10.001 4.31719 10.035 4.15195 10.035C3.98086 10.035 3.82852 10.0063 3.69492 9.94883C3.5625 9.89141 3.4582 9.80293 3.38203 9.6834C3.30703 9.56387 3.26953 9.41152 3.26953 9.22637H3.88828C3.88828 9.31309 3.89824 9.38105 3.91816 9.43027C3.93809 9.47832 3.96738 9.5123 4.00605 9.53223C4.0459 9.55098 4.09453 9.56035 4.15195 9.56035C4.2082 9.56035 4.25566 9.54629 4.29434 9.51816C4.33418 9.48887 4.36465 9.44727 4.38574 9.39336C4.40684 9.33828 4.41738 9.27266 4.41738 9.19648Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6836
+ const useLayerHiddenAttributes = (layerName) => {
6837
+ const { currentPage, updateConfigPage } = useWidgetPage();
6838
+ const layerHiddenAttributes = React.useMemo(() => {
6839
+ return currentPage?.layers?.find(item => item.name === layerName)?.hiddenAttributes ?? [];
6840
+ }, [currentPage?.layers, layerName]);
6841
+ const updateLayerHiddenAttributes = React.useCallback((updatedHiddenAttributes) => {
6842
+ updateConfigPage({
6843
+ ...currentPage,
6844
+ layers: currentPage?.layers?.map(item => {
6845
+ return item.name === layerName
6846
+ ? {
6847
+ ...item,
6848
+ hiddenAttributes: updatedHiddenAttributes,
6849
+ }
6850
+ : item;
6851
+ }),
6852
+ });
6853
+ }, [currentPage, layerName, updateConfigPage]);
6854
+ return [layerHiddenAttributes, updateLayerHiddenAttributes];
6855
+ };
6569
6856
 
6570
- var img$d = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%236155E9'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='KML'%3e%3cpath id='Vector_3' d='M11.7408 9.5252V9.9998H10.4471V9.5252H11.7408ZM10.6668 7.44043V9.9998H10.0498V7.44043H10.6668Z' fill='white'/%3e%3cpath id='Vector_4' d='M7.09785 7.44043H7.60059L8.17188 9.22109L8.74316 7.44043H9.2459L8.37578 9.9998H7.96797L7.09785 7.44043ZM6.79199 7.44043H7.3123L7.40898 9.40215V9.9998H6.79199V7.44043ZM9.03145 7.44043H9.55352V9.9998H8.93477V9.40215L9.03145 7.44043Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.00664 7.44043V9.9998H4.38965V7.44043H5.00664ZM6.53418 7.44043L5.54277 8.7377L4.9627 9.37227L4.8502 8.80625L5.22109 8.24375L5.77305 7.44043H6.53418ZM5.80469 9.9998L5.14375 8.84668L5.62363 8.49336L6.53418 9.9998H5.80469Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6857
+ const useVisibleProjectItems = (applyMinMaxScale) => {
6858
+ const { map } = useMapContext();
6859
+ const projectItems = useCurrentPageLayers();
6860
+ const zoomChange = React.useMemo(() => (applyMinMaxScale && map.current?.getZoom() !== undefined ? Math.round(map.current?.getZoom()) : undefined), [applyMinMaxScale, map.current?.getZoom()]);
6861
+ return React.useMemo(() => {
6862
+ if (map.current?.getZoom() === undefined) {
6863
+ return [];
6864
+ }
6865
+ return (projectItems?.filter(item => item.isVisible &&
6866
+ (!applyMinMaxScale ||
6867
+ (Math.round(map.current.getZoom()) >= (item.minScale ?? 0) &&
6868
+ Math.round(map.current.getZoom()) <= (item.maxScale ?? 30)))) ?? []);
6869
+ }, [projectItems, zoomChange, applyMinMaxScale]);
6870
+ };
6571
6871
 
6572
- var img$c = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23EC473F'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PDF'%3e%3cpath id='Vector_3' d='M10.2654 7.44043V9.9998H9.64844V7.44043H10.2654ZM11.2604 8.50566V8.98027H10.0896V8.50566H11.2604ZM11.3605 7.44043V7.9168H10.0896V7.44043H11.3605Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.04922 9.9998H7.48145L7.48496 9.5252H8.04922C8.16641 9.5252 8.26543 9.49707 8.34629 9.44082C8.42832 9.38457 8.49043 9.30078 8.53262 9.18945C8.57598 9.07695 8.59766 8.93867 8.59766 8.77461V8.66387C8.59766 8.54082 8.58535 8.43301 8.56074 8.34043C8.5373 8.24668 8.50215 8.16875 8.45527 8.10664C8.4084 8.04336 8.3498 7.9959 8.27949 7.96426C8.21035 7.93262 8.13066 7.9168 8.04043 7.9168H7.4709V7.44043H8.04043C8.21387 7.44043 8.37266 7.47031 8.5168 7.53008C8.66211 7.58867 8.7875 7.67305 8.89297 7.7832C8.99961 7.89219 9.08164 8.02168 9.13906 8.17168C9.19766 8.32051 9.22695 8.48574 9.22695 8.66738V8.77461C9.22695 8.95508 9.19766 9.12031 9.13906 9.27031C9.08164 9.42031 9.0002 9.5498 8.89473 9.65879C8.78926 9.76777 8.66445 9.85215 8.52031 9.91191C8.37734 9.97051 8.22031 9.9998 8.04922 9.9998ZM7.83477 7.44043V9.9998H7.21777V7.44043H7.83477Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.79375 9.13145H5.15742V8.65508H5.79375C5.88047 8.65508 5.95078 8.64043 6.00469 8.61113C6.05859 8.58184 6.09785 8.54141 6.12246 8.48984C6.14824 8.43711 6.16113 8.37793 6.16113 8.3123C6.16113 8.24199 6.14824 8.17695 6.12246 8.11719C6.09785 8.05742 6.05859 8.00937 6.00469 7.97305C5.95078 7.93555 5.88047 7.9168 5.79375 7.9168H5.38945V9.9998H4.77246V7.44043H5.79375C5.99883 7.44043 6.1752 7.47793 6.32285 7.55293C6.47168 7.62793 6.58594 7.73105 6.66562 7.8623C6.74531 7.99238 6.78516 8.14121 6.78516 8.30879C6.78516 8.47402 6.74531 8.61816 6.66562 8.74121C6.58594 8.86426 6.47168 8.96035 6.32285 9.02949C6.1752 9.09746 5.99883 9.13145 5.79375 9.13145Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6872
+ const useServerNotificationsContext = () => {
6873
+ return React.useContext(ServerNotificationsContext);
6874
+ };
6573
6875
 
6574
- var img$b = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%239381FF'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PNG'%3e%3cpath id='Vector_3' d='M11.5977 8.63301V9.68418C11.5543 9.73223 11.4875 9.78379 11.3973 9.83887C11.3082 9.89277 11.1957 9.93906 11.0598 9.97773C10.9238 10.0164 10.7639 10.0357 10.5799 10.0357C10.41 10.0357 10.2559 10.0088 10.1176 9.95488C9.9793 9.8998 9.86035 9.81953 9.76074 9.71406C9.6623 9.60742 9.58613 9.47734 9.53223 9.32383C9.47949 9.16914 9.45312 8.99219 9.45312 8.79297V8.65059C9.45312 8.45137 9.48008 8.27441 9.53398 8.11973C9.58789 7.96504 9.66348 7.83496 9.76074 7.72949C9.85918 7.62285 9.97461 7.54199 10.107 7.48691C10.2406 7.43184 10.3871 7.4043 10.5465 7.4043C10.782 7.4043 10.9736 7.4418 11.1213 7.5168C11.2689 7.59063 11.3809 7.69316 11.457 7.82441C11.5332 7.95449 11.5795 8.10508 11.5959 8.27617H11.0035C10.9918 8.1918 10.9695 8.12031 10.9367 8.06172C10.9051 8.00195 10.8594 7.95684 10.7996 7.92637C10.7398 7.89473 10.6625 7.87891 10.5676 7.87891C10.4937 7.87891 10.4264 7.89473 10.3654 7.92637C10.3057 7.95801 10.2547 8.00605 10.2125 8.07051C10.1703 8.13379 10.1375 8.21348 10.1141 8.30957C10.0918 8.40566 10.0807 8.51816 10.0807 8.64707V8.79297C10.0807 8.9207 10.0912 9.03262 10.1123 9.12871C10.1346 9.2248 10.1674 9.30508 10.2107 9.36953C10.2553 9.43281 10.3115 9.48086 10.3795 9.51367C10.4486 9.54531 10.5301 9.56113 10.6238 9.56113C10.6895 9.56113 10.7457 9.55586 10.7926 9.54531C10.8395 9.53359 10.8781 9.51953 10.9086 9.50312C10.9402 9.48555 10.9643 9.46914 10.9807 9.45391V9.05664H10.5518V8.63301H11.5977Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.01445 7.44141V10.0008H8.39922L7.49395 8.4082V10.0008H6.87695V7.44141H7.49395L8.39922 9.03398V7.44141H9.01445Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.45293 9.13242H4.8166V8.65605H5.45293C5.53965 8.65605 5.60996 8.64141 5.66387 8.61211C5.71777 8.58281 5.75703 8.54238 5.78164 8.49082C5.80742 8.43809 5.82031 8.37891 5.82031 8.31328C5.82031 8.24297 5.80742 8.17793 5.78164 8.11816C5.75703 8.0584 5.71777 8.01035 5.66387 7.97402C5.60996 7.93652 5.53965 7.91777 5.45293 7.91777H5.04863V10.0008H4.43164V7.44141H5.45293C5.65801 7.44141 5.83437 7.47891 5.98203 7.55391C6.13086 7.62891 6.24512 7.73203 6.3248 7.86328C6.40449 7.99336 6.44434 8.14219 6.44434 8.30977C6.44434 8.475 6.40449 8.61914 6.3248 8.74219C6.24512 8.86523 6.13086 8.96133 5.98203 9.03047C5.83437 9.09844 5.65801 9.13242 5.45293 9.13242Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6876
+ const SERVER_NOTIFICATION_EVENT = {
6877
+ ReceiveFeaturesUpdate: "ReceiveFeaturesUpdateNotification",
6878
+ PythonProgressNotification: "ReceivePythonProgressNotification",
6879
+ PythonSandboxStats: "ReceivePythonSandboxStatsNotification",
6880
+ };
6881
+ const POLL_SUBTASK_INTERVAL_MS = 500;
6882
+ const POLL_SUBTASK_TIMEOUT_MS = 15_000;
6575
6883
 
6576
- var img$a = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23CA4424'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PPTX'%3e%3cpath id='Vector_3' d='M11.2125 7.44043L11.6309 8.29121L12.0492 7.44043H12.7523L12.0387 8.70957L12.7717 9.9998H12.0615L11.6309 9.1332L11.2002 9.9998H10.4883L11.223 8.70957L10.5076 7.44043H11.2125Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.54414 7.44043V9.9998H8.92715V7.44043H9.54414ZM10.3141 7.44043V7.9168H8.1748V7.44043H10.3141Z' fill='white'/%3e%3cpath id='Vector_5' d='M6.88164 9.13145H6.24531V8.65508H6.88164C6.96836 8.65508 7.03867 8.64043 7.09258 8.61113C7.14648 8.58184 7.18574 8.54141 7.21035 8.48984C7.23613 8.43711 7.24902 8.37793 7.24902 8.3123C7.24902 8.24199 7.23613 8.17695 7.21035 8.11719C7.18574 8.05742 7.14648 8.00937 7.09258 7.97305C7.03867 7.93555 6.96836 7.9168 6.88164 7.9168H6.47734V9.9998H5.86035V7.44043H6.88164C7.08672 7.44043 7.26309 7.47793 7.41074 7.55293C7.55957 7.62793 7.67383 7.73105 7.75352 7.8623C7.8332 7.99238 7.87305 8.14121 7.87305 8.30879C7.87305 8.47402 7.8332 8.61816 7.75352 8.74121C7.67383 8.86426 7.55957 8.96035 7.41074 9.02949C7.26309 9.09746 7.08672 9.13145 6.88164 9.13145Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.43633 9.13145H3.8V8.65508H4.43633C4.52305 8.65508 4.59336 8.64043 4.64727 8.61113C4.70117 8.58184 4.74043 8.54141 4.76504 8.48984C4.79082 8.43711 4.80371 8.37793 4.80371 8.3123C4.80371 8.24199 4.79082 8.17695 4.76504 8.11719C4.74043 8.05742 4.70117 8.00937 4.64727 7.97305C4.59336 7.93555 4.52305 7.9168 4.43633 7.9168H4.03203V9.9998H3.41504V7.44043H4.43633C4.64141 7.44043 4.81777 7.47793 4.96543 7.55293C5.11426 7.62793 5.22852 7.73105 5.3082 7.8623C5.38789 7.99238 5.42773 8.14121 5.42773 8.30879C5.42773 8.47402 5.38789 8.61816 5.3082 8.74121C5.22852 8.86426 5.11426 8.96035 4.96543 9.02949C4.81777 9.09746 4.64141 9.13145 4.43633 9.13145Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6884
+ const usePythonSandbox = () => {
6885
+ const { api } = useGlobalContext();
6886
+ const preparePythonSandbox = React.useCallback(({ resourceId, isNotebook = false }) => api.remoteTaskManager.post({
6887
+ workerType: "pythonService",
6888
+ methodType: "pythonrunner/prepare",
6889
+ data: { resourceId, isNotebook },
6890
+ }), [api.remoteTaskManager]);
6891
+ return { preparePythonSandbox };
6892
+ };
6577
6893
 
6578
- var img$9 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%233674A5'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='PY'%3e%3cpath id='Vector_3' d='M8.75215 7.44141L9.22324 8.55234L9.69609 7.44141H10.3605L9.53789 9.08145V10.0008H8.91035V9.08145L8.08594 7.44141H8.75215Z' fill='%23FED341'/%3e%3cpath id='Vector_4' d='M6.86406 9.13242H6.22773V8.65605H6.86406C6.95078 8.65605 7.02109 8.64141 7.075 8.61211C7.12891 8.58281 7.16816 8.54238 7.19277 8.49082C7.21855 8.43809 7.23145 8.37891 7.23145 8.31328C7.23145 8.24297 7.21855 8.17793 7.19277 8.11816C7.16816 8.0584 7.12891 8.01035 7.075 7.97402C7.02109 7.93652 6.95078 7.91777 6.86406 7.91777H6.45977V10.0008H5.84277V7.44141H6.86406C7.06914 7.44141 7.24551 7.47891 7.39316 7.55391C7.54199 7.62891 7.65625 7.73203 7.73594 7.86328C7.81563 7.99336 7.85547 8.14219 7.85547 8.30977C7.85547 8.475 7.81563 8.61914 7.73594 8.74219C7.65625 8.86523 7.54199 8.96133 7.39316 9.03047C7.24551 9.09844 7.06914 9.13242 6.86406 9.13242Z' fill='%23FED341'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6894
+ const FINAL_STATUSES = [
6895
+ api.RemoteTaskStatus.Completed,
6896
+ api.RemoteTaskStatus.Error,
6897
+ api.RemoteTaskStatus.Interrupted,
6898
+ api.RemoteTaskStatus.Timeout,
6899
+ ];
6900
+ const wait = (ms) => new Promise(resolve => window.setTimeout(resolve, ms));
6901
+ const pollSubtaskCompletion = async ({ taskId, api, intervalMs = POLL_SUBTASK_INTERVAL_MS, timeoutMs = POLL_SUBTASK_TIMEOUT_MS, }) => {
6902
+ const deadline = Date.now() + timeoutMs;
6903
+ let subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
6904
+ while (subTask && !FINAL_STATUSES.includes(subTask.status)) {
6905
+ if (Date.now() >= deadline)
6906
+ return null;
6907
+ await wait(intervalMs);
6908
+ subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
6909
+ }
6910
+ return subTask;
6911
+ };
6579
6912
 
6580
- var img$8 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23C0D155'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='SHP'%3e%3cpath id='Vector_3' d='M10.5359 9.13145H9.89961V8.65508H10.5359C10.6227 8.65508 10.693 8.64043 10.7469 8.61113C10.8008 8.58184 10.84 8.54141 10.8646 8.48984C10.8904 8.43711 10.9033 8.37793 10.9033 8.3123C10.9033 8.24199 10.8904 8.17695 10.8646 8.11719C10.84 8.05742 10.8008 8.00937 10.7469 7.97305C10.693 7.93555 10.6227 7.9168 10.5359 7.9168H10.1316V9.9998H9.51465V7.44043H10.5359C10.741 7.44043 10.9174 7.47793 11.065 7.55293C11.2139 7.62793 11.3281 7.73105 11.4078 7.8623C11.4875 7.99238 11.5273 8.14121 11.5273 8.30879C11.5273 8.47402 11.4875 8.61816 11.4078 8.74121C11.3281 8.86426 11.2139 8.96035 11.065 9.02949C10.9174 9.09746 10.741 9.13145 10.5359 9.13145Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.6082 8.45645V8.93105H7.29512V8.45645H8.6082ZM7.50078 7.44043V9.9998H6.88379V7.44043H7.50078ZM9.02305 7.44043V9.9998H8.40781V7.44043H9.02305Z' fill='white'/%3e%3cpath id='Vector_5' d='M5.84824 9.31953C5.84824 9.27969 5.84238 9.24395 5.83066 9.2123C5.81895 9.17949 5.79727 9.14902 5.76562 9.1209C5.73398 9.09277 5.68828 9.06465 5.62852 9.03652C5.56992 9.00723 5.49258 8.97676 5.39648 8.94512C5.28398 8.90762 5.17559 8.86543 5.07129 8.81855C4.96699 8.77051 4.87383 8.71484 4.7918 8.65156C4.70977 8.58711 4.64473 8.51211 4.59668 8.42656C4.54863 8.33984 4.52461 8.23906 4.52461 8.12422C4.52461 8.01406 4.54922 7.91504 4.59844 7.82715C4.64766 7.73809 4.71621 7.6625 4.8041 7.60039C4.89316 7.53711 4.99746 7.48906 5.11699 7.45625C5.23652 7.42227 5.36719 7.40527 5.50898 7.40527C5.69648 7.40527 5.86172 7.43809 6.00469 7.50371C6.14883 7.56816 6.26133 7.66016 6.34219 7.77969C6.42422 7.89805 6.46523 8.03809 6.46523 8.1998H5.85176C5.85176 8.13535 5.83828 8.07852 5.81133 8.0293C5.78555 7.98008 5.74629 7.94141 5.69355 7.91328C5.64082 7.88516 5.57461 7.87109 5.49492 7.87109C5.41758 7.87109 5.35254 7.88281 5.2998 7.90625C5.24707 7.92969 5.20723 7.96133 5.18027 8.00117C5.15332 8.03984 5.13984 8.08262 5.13984 8.12949C5.13984 8.16816 5.15039 8.20332 5.17148 8.23496C5.19375 8.26543 5.2248 8.29414 5.26465 8.32109C5.30566 8.34805 5.35488 8.37383 5.4123 8.39844C5.4709 8.42305 5.53652 8.44707 5.60918 8.47051C5.74512 8.51387 5.86582 8.5625 5.97129 8.61641C6.07793 8.66914 6.16758 8.72949 6.24023 8.79746C6.31406 8.86426 6.36973 8.94043 6.40723 9.02598C6.4459 9.11152 6.46523 9.2082 6.46523 9.31602C6.46523 9.43086 6.44297 9.53281 6.39844 9.62187C6.35391 9.71094 6.29004 9.78652 6.20684 9.84863C6.12363 9.90957 6.02402 9.95586 5.90801 9.9875C5.79199 10.0191 5.6625 10.035 5.51953 10.035C5.38828 10.035 5.25879 10.0186 5.13105 9.98574C5.00449 9.95176 4.88965 9.9002 4.78652 9.83105C4.6834 9.76074 4.60078 9.67109 4.53867 9.56211C4.47773 9.45195 4.44727 9.32129 4.44727 9.17012H5.06602C5.06602 9.24512 5.07598 9.3084 5.0959 9.35996C5.11582 9.41152 5.14512 9.45312 5.18379 9.48477C5.22246 9.51523 5.26992 9.5375 5.32617 9.55156C5.38242 9.56445 5.44687 9.5709 5.51953 9.5709C5.59805 9.5709 5.66133 9.55977 5.70937 9.5375C5.75742 9.51406 5.79258 9.48359 5.81484 9.44609C5.83711 9.40742 5.84824 9.36523 5.84824 9.31953Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
6913
+ const usePythonTask = () => {
6914
+ const { api: api$1, t } = useGlobalContext();
6915
+ const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
6916
+ const { preparePythonSandbox } = usePythonSandbox();
6917
+ const [status, setStatus] = React.useState(api.RemoteTaskStatus.Unknown);
6918
+ const [log, setLog] = React.useState(null);
6919
+ const [lastMessage, setLastMessage] = React.useState(null);
6920
+ const [error, setError] = React.useState(null);
6921
+ const [loading, setLoading] = React.useState(false);
6922
+ const [executionTime, setExecutionTime] = React.useState(null);
6923
+ const [taskId, setTaskId] = React.useState(null);
6924
+ const [subscriptionId, setSubscriptionId] = React.useState(null);
6925
+ const [isLogDialogOpen, setIsLogDialogOpen] = React.useState(false);
6926
+ const [result, setResult] = React.useState(null);
6927
+ const reset = React.useCallback(() => {
6928
+ setStatus(api.RemoteTaskStatus.Unknown);
6929
+ setError(null);
6930
+ setLoading(false);
6931
+ setExecutionTime(null);
6932
+ setTaskId(null);
6933
+ setSubscriptionId(null);
6934
+ setResult(null);
6935
+ }, []);
6936
+ const runTask = React.useCallback(async ({ resourceId, parameters, script, fileName, methodName, }) => {
6937
+ reset();
6938
+ setStatus(api.RemoteTaskStatus.Process);
6939
+ setLog(null);
6940
+ setLastMessage(null);
6941
+ setLoading(true);
6942
+ const start = Date.now();
6943
+ let prototypeId = await api$1.remoteTaskManager.createTaskPrototype({
6944
+ enabled: true,
6945
+ startIfPreviousError: true,
6946
+ startIfPreviousNotFinished: true,
6947
+ subTaskSettings: [
6948
+ {
6949
+ type: "pythonService",
6950
+ startParameters: {
6951
+ resourceId,
6952
+ parameters,
6953
+ script,
6954
+ fileName,
6955
+ methodName,
6956
+ method: "pythonrunner/run",
6957
+ },
6958
+ },
6959
+ ],
6960
+ });
6961
+ prototypeId = prototypeId.replace(/["']+/g, "");
6962
+ await preparePythonSandbox({ resourceId });
6963
+ const { id: newTaskId, success } = await api$1.remoteTaskManager.startTask1(prototypeId);
6964
+ if (!success) {
6965
+ setStatus(api.RemoteTaskStatus.Error);
6966
+ setLog(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
6967
+ setExecutionTime(Date.now() - start);
6968
+ setLoading(false);
6969
+ }
6970
+ const newSubscriptionId = await addSubscription({
6971
+ tag: "python_task_progress_event",
6972
+ resourceId,
6973
+ });
6974
+ setTaskId(newTaskId);
6975
+ setSubscriptionId(newSubscriptionId);
6976
+ const onNotification = async ({ data }) => {
6977
+ if (data?.taskId === newTaskId) {
6978
+ const isFinished = [api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status);
6979
+ setStatus(data.status);
6980
+ setLog(prev => [prev, data.log].filter(Boolean).join(""));
6981
+ if (data.log)
6982
+ setLastMessage(data.log);
6983
+ setExecutionTime(Date.now() - start);
6984
+ setLoading(false);
6985
+ setTaskId(isFinished ? null : newTaskId);
6986
+ setSubscriptionId(isFinished ? null : newSubscriptionId);
6987
+ if (isFinished) {
6988
+ unsubscribeById(newSubscriptionId);
6989
+ connection.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
6990
+ }
6991
+ if (data.status === api.RemoteTaskStatus.Completed) {
6992
+ try {
6993
+ const subTask = await pollSubtaskCompletion({ taskId: newTaskId, api: api$1 });
6994
+ if (subTask?.status === api.RemoteTaskStatus.Completed) {
6995
+ const response = subTask.results?.response;
6996
+ setResult(typeof response === "object" && response !== null
6997
+ ? response
6998
+ : null);
6999
+ }
7000
+ else {
7001
+ setError(new Error(t("taskResultUnavailable", {
7002
+ ns: "devMode",
7003
+ defaultValue: "Не удалось получить результат задачи",
7004
+ })));
7005
+ }
7006
+ }
7007
+ catch (e) {
7008
+ setError(e instanceof Error ? e : new Error(String(e)));
7009
+ }
7010
+ }
7011
+ }
7012
+ };
7013
+ connection.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7014
+ }, [reset, api$1, preparePythonSandbox, addSubscription, connection, t, unsubscribeById]);
7015
+ const stopTask = React.useCallback(async () => {
7016
+ await api$1.remoteTaskManager.stop(taskId);
7017
+ reset();
7018
+ unsubscribeById(subscriptionId);
7019
+ }, [api$1, reset, unsubscribeById, taskId, subscriptionId]);
7020
+ const openLog = React.useCallback(() => {
7021
+ setIsLogDialogOpen(true);
7022
+ }, []);
7023
+ const closeLog = React.useCallback(() => {
7024
+ setIsLogDialogOpen(false);
7025
+ }, []);
7026
+ return {
7027
+ taskId,
7028
+ runTask,
7029
+ stopTask,
7030
+ openLog,
7031
+ log,
7032
+ lastMessage,
7033
+ error,
7034
+ status,
7035
+ loading,
7036
+ executionTime,
7037
+ isLogDialogOpen,
7038
+ closeLog,
7039
+ result,
7040
+ };
7041
+ };
6581
7042
 
6582
- var img$7 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23DDE3EA'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='TXT'%3e%3cpath id='Vector_3' d='M10.6838 7.44043V9.9998H10.0668V7.44043H10.6838ZM11.4537 7.44043V7.9168H9.31445V7.44043H11.4537Z' fill='black'/%3e%3cpath id='Vector_4' d='M7.58164 7.44043L8 8.29121L8.41836 7.44043H9.12148L8.40781 8.70957L9.14082 9.9998H8.43066L8 9.1332L7.56934 9.9998H6.85742L7.59219 8.70957L6.87676 7.44043H7.58164Z' fill='black'/%3e%3cpath id='Vector_5' d='M5.91328 7.44043V9.9998H5.29629V7.44043H5.91328ZM6.6832 7.44043V7.9168H4.54395V7.44043H6.6832Z' fill='black'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
7043
+ const useRemoteTask = ({ onUpdate } = {}) => {
7044
+ const { api: api$1 } = useGlobalContext();
7045
+ const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
7046
+ const runTask = React.useCallback((prototype) => new Promise((resolve, reject) => {
7047
+ const start = async () => {
7048
+ const resourceId = prototype.subTaskSettings?.[0]?.startParameters?.resourceId;
7049
+ let prototypeId = await api$1.remoteTaskManager.createTaskPrototype(prototype);
7050
+ prototypeId = prototypeId.replace(/["']+/g, "");
7051
+ const { id: taskId, success } = await api$1.remoteTaskManager.startTask1(prototypeId);
7052
+ if (!success || !taskId) {
7053
+ reject(new Error("startTask returned no taskId"));
7054
+ return;
7055
+ }
7056
+ const subscriptionId = await addSubscription({
7057
+ tag: "python_task_progress_event",
7058
+ resourceId,
7059
+ });
7060
+ const onNotification = ({ data }) => {
7061
+ if (data?.taskId !== taskId) {
7062
+ return;
7063
+ }
7064
+ onUpdate?.({ status: data.status, log: data.log });
7065
+ const isCompleted = data.status === api.RemoteTaskStatus.Completed;
7066
+ const isError = data.status === api.RemoteTaskStatus.Error;
7067
+ if (isCompleted || isError) {
7068
+ connection?.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7069
+ if (subscriptionId) {
7070
+ unsubscribeById(subscriptionId);
7071
+ }
7072
+ resolve({
7073
+ taskId,
7074
+ status: isCompleted ? api.RemoteTaskStatus.Completed : api.RemoteTaskStatus.Error,
7075
+ log: data.log,
7076
+ });
7077
+ }
7078
+ };
7079
+ connection?.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7080
+ };
7081
+ start().catch(reject);
7082
+ }), [api$1, addSubscription, connection, unsubscribeById, onUpdate]);
7083
+ return { runTask };
7084
+ };
6583
7085
 
6584
- var img$6 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%2341A246'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='XLSX'%3e%3cpath id='Vector_3' d='M10.983 7.44043L11.4014 8.29121L11.8197 7.44043H12.5229L11.8092 8.70957L12.5422 9.9998H11.832L11.4014 9.1332L10.9707 9.9998H10.2588L10.9936 8.70957L10.2781 7.44043H10.983Z' fill='white'/%3e%3cpath id='Vector_4' d='M9.41172 9.31953C9.41172 9.27969 9.40586 9.24395 9.39414 9.2123C9.38242 9.17949 9.36074 9.14902 9.3291 9.1209C9.29746 9.09277 9.25176 9.06465 9.19199 9.03652C9.1334 9.00723 9.05605 8.97676 8.95996 8.94512C8.84746 8.90762 8.73906 8.86543 8.63477 8.81855C8.53047 8.77051 8.4373 8.71484 8.35527 8.65156C8.27324 8.58711 8.2082 8.51211 8.16016 8.42656C8.11211 8.33984 8.08809 8.23906 8.08809 8.12422C8.08809 8.01406 8.1127 7.91504 8.16191 7.82715C8.21113 7.73809 8.27969 7.6625 8.36758 7.60039C8.45664 7.53711 8.56094 7.48906 8.68047 7.45625C8.8 7.42227 8.93066 7.40527 9.07246 7.40527C9.25996 7.40527 9.4252 7.43809 9.56816 7.50371C9.7123 7.56816 9.8248 7.66016 9.90566 7.77969C9.9877 7.89805 10.0287 8.03809 10.0287 8.1998H9.41523C9.41523 8.13535 9.40176 8.07852 9.3748 8.0293C9.34902 7.98008 9.30977 7.94141 9.25703 7.91328C9.2043 7.88516 9.13809 7.87109 9.0584 7.87109C8.98105 7.87109 8.91602 7.88281 8.86328 7.90625C8.81055 7.92969 8.7707 7.96133 8.74375 8.00117C8.7168 8.03984 8.70332 8.08262 8.70332 8.12949C8.70332 8.16816 8.71387 8.20332 8.73496 8.23496C8.75723 8.26543 8.78828 8.29414 8.82812 8.32109C8.86914 8.34805 8.91836 8.37383 8.97578 8.39844C9.03437 8.42305 9.1 8.44707 9.17266 8.47051C9.30859 8.51387 9.4293 8.5625 9.53477 8.61641C9.64141 8.66914 9.73105 8.72949 9.80371 8.79746C9.87754 8.86426 9.9332 8.94043 9.9707 9.02598C10.0094 9.11152 10.0287 9.2082 10.0287 9.31602C10.0287 9.43086 10.0064 9.53281 9.96191 9.62187C9.91738 9.71094 9.85352 9.78652 9.77031 9.84863C9.68711 9.90957 9.5875 9.95586 9.47148 9.9875C9.35547 10.0191 9.22598 10.035 9.08301 10.035C8.95176 10.035 8.82227 10.0186 8.69453 9.98574C8.56797 9.95176 8.45312 9.9002 8.35 9.83105C8.24687 9.76074 8.16426 9.67109 8.10215 9.56211C8.04121 9.45195 8.01074 9.32129 8.01074 9.17012H8.62949C8.62949 9.24512 8.63945 9.3084 8.65937 9.35996C8.6793 9.41152 8.70859 9.45312 8.74727 9.48477C8.78594 9.51523 8.8334 9.5375 8.88965 9.55156C8.9459 9.56445 9.01035 9.5709 9.08301 9.5709C9.16152 9.5709 9.2248 9.55977 9.27285 9.5375C9.3209 9.51406 9.35605 9.48359 9.37832 9.44609C9.40059 9.40742 9.41172 9.36523 9.41172 9.31953Z' fill='white'/%3e%3cpath id='Vector_5' d='M7.73301 9.5252V9.9998H6.43926V9.5252H7.73301ZM6.65898 7.44043V9.9998H6.04199V7.44043H6.65898Z' fill='white'/%3e%3cpath id='Vector_6' d='M4.1793 7.44043L4.59766 8.29121L5.01602 7.44043H5.71914L5.00547 8.70957L5.73848 9.9998H5.02832L4.59766 9.1332L4.16699 9.9998H3.45508L4.18984 8.70957L3.47441 7.44043H4.1793Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
7086
+ const useAppHeight = () => {
7087
+ React.useEffect(() => {
7088
+ const setAppHeight = () => {
7089
+ document.documentElement.style.setProperty("--app-height", `${window.innerHeight}px`);
7090
+ };
7091
+ window.addEventListener("resize", setAppHeight);
7092
+ setAppHeight();
7093
+ return () => {
7094
+ window.removeEventListener("resize", setAppHeight);
7095
+ };
7096
+ }, []);
7097
+ };
6585
7098
 
6586
- var img$5 = "data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3e%3cg id='Frame'%3e%3cpath id='Vector' d='M13 16H3C2.4 16 2 15.6 2 15V1C2 0.4 2.4 0 3 0H10L14 4V15C14 15.6 13.6 16 13 16Z' fill='%23F4BB0A'/%3e%3cpath id='Vector_2' opacity='0.36' d='M14 4L10 0V3C10 3.6 10.4 4 11 4H14Z' fill='white'/%3e%3cg id='ZIP'%3e%3cpath id='Vector_3' d='M9.78789 9.13145H9.15156V8.65508H9.78789C9.87461 8.65508 9.94492 8.64043 9.99883 8.61113C10.0527 8.58184 10.092 8.54141 10.1166 8.48984C10.1424 8.43711 10.1553 8.37793 10.1553 8.3123C10.1553 8.24199 10.1424 8.17695 10.1166 8.11719C10.092 8.05742 10.0527 8.00937 9.99883 7.97305C9.94492 7.93555 9.87461 7.9168 9.78789 7.9168H9.38359V9.9998H8.7666V7.44043H9.78789C9.99297 7.44043 10.1693 7.47793 10.317 7.55293C10.4658 7.62793 10.5801 7.73105 10.6598 7.8623C10.7395 7.99238 10.7793 8.14121 10.7793 8.30879C10.7793 8.47402 10.7395 8.61816 10.6598 8.74121C10.5801 8.86426 10.4658 8.96035 10.317 9.02949C10.1693 9.09746 9.99297 9.13145 9.78789 9.13145Z' fill='white'/%3e%3cpath id='Vector_4' d='M8.23242 7.44043V9.9998H7.61719V7.44043H8.23242Z' fill='white'/%3e%3cpath id='Vector_5' d='M7.19551 9.5252V9.9998H5.34277V9.5252H7.19551ZM7.1832 7.75684L5.64863 9.9998H5.20215V9.67461L6.7543 7.44043H7.1832V7.75684ZM6.98457 7.44043V7.9168H5.19336V7.44043H6.98457Z' fill='white'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
7099
+ const useDebouncedCallback = (interval) => {
7100
+ return React.useMemo(() => debounce((cb) => {
7101
+ cb();
7102
+ }, interval), [interval]);
7103
+ };
6587
7104
 
6588
- const getFileTypeIcon = (fileType) => {
6589
- switch (fileType) {
6590
- case FileType.CSV:
6591
- return img$i;
6592
- case FileType.XLSX:
6593
- return img$6;
6594
- case FileType.DOCX:
6595
- return img$h;
6596
- case FileType.PDF:
6597
- return img$c;
6598
- case FileType.JSON:
6599
- return img$e;
6600
- case FileType.KML:
6601
- return img$d;
6602
- case FileType.PPTX:
6603
- return img$a;
6604
- case FileType.SHP:
6605
- return img$8;
6606
- case FileType.TXT:
6607
- return img$7;
6608
- case FileType.ZIP:
6609
- return img$5;
6610
- case FileType.IMAGE:
6611
- case FileType.JPEG:
6612
- return img$g;
6613
- case FileType.JPG:
6614
- return img$f;
6615
- case FileType.PNG:
6616
- return img$b;
6617
- case FileType.PYTHON:
6618
- return img$9;
6619
- default:
6620
- return img$j;
6621
- }
7105
+ const useToggle = (initial) => {
7106
+ const [state, setState] = React.useState(initial !== undefined ? initial : false);
7107
+ const toggle = React.useCallback(() => setState(!state), [state]);
7108
+ return [state, toggle, setState];
6622
7109
  };
6623
7110
 
6624
- const useAttachmentPreviewImages = ({ items, active, }) => {
6625
- const { api } = useGlobalContext();
6626
- const [blobUrls, setBlobUrls] = React.useState({});
6627
- const [failedLinks, setFailedLinks] = React.useState({});
6628
- const inFlightRef = React.useRef(new Set());
6629
- const blobUrlsRef = React.useRef(blobUrls);
6630
- blobUrlsRef.current = blobUrls;
7111
+ const DEBOUNCE_DELAY = 144;
7112
+ const useWindowResize = (callback, delay) => {
7113
+ const debounceCallback = React.useMemo(() => {
7114
+ return callback ? debounce(callback, delay || DEBOUNCE_DELAY) : undefined;
7115
+ }, [callback, delay]);
6631
7116
  React.useEffect(() => {
6632
- if (!active || !api?.catalog?.getFile)
6633
- return;
6634
- items.forEach(item => {
6635
- const fileType = getFileType(item.mimeType, item.name);
6636
- const isImage = IMAGE_FILE_TYPES.includes(fileType);
6637
- if (!isImage || item.isExternal)
6638
- return;
6639
- if (blobUrlsRef.current[item.link] || inFlightRef.current.has(item.link))
6640
- return;
6641
- inFlightRef.current.add(item.link);
6642
- api.catalog
6643
- .getFile(item.link)
6644
- .then(blob => {
6645
- const objectUrl = URL.createObjectURL(blob);
6646
- setBlobUrls(prev => ({ ...prev, [item.link]: objectUrl }));
6647
- })
6648
- .catch(() => {
6649
- setFailedLinks(prev => (prev[item.link] ? prev : { ...prev, [item.link]: true }));
6650
- })
6651
- .finally(() => {
6652
- inFlightRef.current.delete(item.link);
6653
- });
6654
- });
6655
- }, [active, api, items]);
6656
- React.useEffect(() => () => {
6657
- Object.values(blobUrlsRef.current).forEach(URL.revokeObjectURL);
6658
- }, []);
6659
- return React.useMemo(() => items.map(item => {
6660
- const fileType = getFileType(item.mimeType, item.name);
6661
- const isImage = IMAGE_FILE_TYPES.includes(fileType);
6662
- const fileName = item.name;
6663
- if (!isImage)
6664
- return { src: getFileTypeIcon(fileType), fileName };
6665
- if (item.isExternal)
6666
- return { src: item.link, fileName };
6667
- const hasError = !!failedLinks[item.link];
6668
- const blobUrl = blobUrls[item.link];
6669
- return {
6670
- src: blobUrl ?? "",
6671
- fileName,
6672
- hasError,
6673
- isLoading: !hasError && !blobUrl,
6674
- };
6675
- }), [items, blobUrls, failedLinks]);
7117
+ debounceCallback && window.addEventListener("resize", debounceCallback);
7118
+ return () => debounceCallback && window.removeEventListener("resize", debounceCallback);
7119
+ }, [debounceCallback]);
6676
7120
  };
6677
7121
 
6678
- const useAutoCompleteControl = (items) => {
6679
- const [value, setValue] = React.useState("");
6680
- const [options, setOptions] = React.useState([]);
6681
- const staticOptions = React.useMemo(() => (items ?? [])
6682
- .filter(Boolean)
6683
- .map(item => ({ text: String(item), value: String(item) })), [items]);
6684
- const onChange = React.useCallback((newValue) => setValue(newValue), []);
6685
- return {
6686
- value,
6687
- setValue,
6688
- onChange,
6689
- options: staticOptions.length ? staticOptions : options,
6690
- setOptions,
6691
- };
7122
+ const useContainerAttributes = ({ elementConfig, type, renderElement }) => {
7123
+ const getRenderContainerItem = useRenderContainerItem(type, renderElement);
7124
+ const { options } = elementConfig || {};
7125
+ const { attributes: optionAttributes, useProjectHiddenAttributes } = options || {};
7126
+ const { attributes: contextAttributes, layerInfo } = useWidgetContext(type);
7127
+ const [hiddenAttributes] = useLayerHiddenAttributes(layerInfo?.name ?? "");
7128
+ const attributesToRender = React.useMemo(() => {
7129
+ if (!optionAttributes)
7130
+ return null;
7131
+ const baseList = optionAttributes.length === 0
7132
+ ? contextAttributes?.map(({ attributeName }) => attributeName) ?? []
7133
+ : optionAttributes;
7134
+ if (!useProjectHiddenAttributes)
7135
+ return baseList;
7136
+ return baseList.filter(attribute => !hiddenAttributes.includes(attribute));
7137
+ }, [optionAttributes, contextAttributes, hiddenAttributes, useProjectHiddenAttributes]);
7138
+ return { getRenderContainerItem, attributesToRender };
6692
7139
  };
6693
7140
 
6694
7141
  /**
@@ -6701,10 +7148,15 @@ const useAutoCompleteControl = (items) => {
6701
7148
  * `data-id` и `$noMargin` раньше жили на внешней обёртке `ElementValueWrapper`; она вешала их
6702
7149
  * на второй узел поверх этого корня, дублируя стили, и для таких контейнеров больше не создаётся
6703
7150
  * (см. `ROOT_OWNING_TEMPLATES`).
7151
+ *
7152
+ * Пропсы хоста фонового слоя (`$hasBgImage`, `$innerPadding`) подмешиваются здесь, а не в каждом
7153
+ * контейнере: корень и так получает пропсы одним спредом, поэтому фон и внутренний отступ
7154
+ * включаются без единой дополнительной строки на месте вызова.
6704
7155
  */
6705
7156
  const useWrapperSize = ({ elementConfig, defaults }) => {
6706
7157
  const { id, style, templateName, options } = elementConfig || {};
6707
7158
  const { width, height, overflow, noMargin, autoHeight } = options || {};
7159
+ const bgHost = useBgImageHost(elementConfig);
6708
7160
  return React.useMemo(() => ({
6709
7161
  id,
6710
7162
  "data-id": id,
@@ -6720,7 +7172,8 @@ const useWrapperSize = ({ elementConfig, defaults }) => {
6720
7172
  heightAsMin: autoHeight,
6721
7173
  }),
6722
7174
  $noMargin: noMargin,
6723
- }), [id, templateName, style, width, height, overflow, noMargin, autoHeight, defaults]);
7175
+ ...bgHost,
7176
+ }), [id, templateName, style, width, height, overflow, noMargin, autoHeight, defaults, bgHost]);
6724
7177
  };
6725
7178
 
6726
7179
  /**
@@ -7537,110 +7990,55 @@ const useDiffPage = (type) => {
7537
7990
  * Натуральная ширина каждой плитки измеряется через временное inline `width: max-content`
7538
7991
  * (снимает применённое ограничение `--tile-width`, поэтому замер устойчив к динамике данных и не
7539
7992
  * зацикливает ResizeObserver — итоговый максимум совпадает с уже применённым). Возвращаемое число
7540
- * контейнер прокидывает в CSS-переменную `--tile-width`, которую читает каждая плитка.
7541
- *
7542
- * Результат ограничен шириной ячейки ряда: плитка задаёт свою ширину в пикселях и в grid не
7543
- * сжимается вместе с треком (`flex-shrink` там не действует, а `min-width: 0` базового
7544
- * контейнера позволяет треку ужаться), поэтому натуральная ширина шире ячейки означала бы
7545
- * наложение соседних плиток друг на друга.
7546
- *
7547
- * `enabled: false` полностью отключает измерение — ширина берётся из grid-ячейки.
7548
- */
7549
- const useEqualTileWidth = ({ enabled, itemsCount, columns, gap, }) => {
7550
- const ref = React.useRef(null);
7551
- const [width, setWidth] = React.useState();
7552
- const measure = React.useCallback(() => {
7553
- const node = ref.current;
7554
- if (!node)
7555
- return;
7556
- const tiles = Array.from(node.querySelectorAll("[data-tile]"));
7557
- if (!tiles.length)
7558
- return;
7559
- // Ширина ряда снимается до замера: временный `max-content` может распереть содержимое.
7560
- const available = columns > 0 ? (node.clientWidth - gap * (columns - 1)) / columns : 0;
7561
- tiles.forEach(tile => {
7562
- tile.style.width = "max-content";
7563
- });
7564
- let max = 0;
7565
- tiles.forEach(tile => {
7566
- max = Math.max(max, tile.getBoundingClientRect().width);
7567
- });
7568
- tiles.forEach(tile => {
7569
- tile.style.width = "";
7570
- });
7571
- // Ограниченную ширину округляем вниз — иначе округление вернуло бы ряд за границы контейнера.
7572
- const next = available > 0 && max > available ? Math.floor(available) : Math.ceil(max);
7573
- setWidth(previous => (max && previous !== next ? next : previous));
7574
- }, [columns, gap]);
7575
- React.useEffect(() => {
7576
- if (!enabled) {
7577
- setWidth(undefined);
7578
- return;
7579
- }
7580
- const node = ref.current;
7581
- if (!node)
7582
- return;
7583
- measure();
7584
- const observer = new ResizeObserver(() => measure());
7585
- observer.observe(node);
7586
- return () => observer.disconnect();
7587
- }, [enabled, itemsCount, measure]);
7588
- return [ref, enabled ? width : undefined];
7589
- };
7590
-
7591
- const SERVER_NOTIFICATION_EVENT = {
7592
- ReceiveFeaturesUpdate: "ReceiveFeaturesUpdateNotification",
7593
- PythonProgressNotification: "ReceivePythonProgressNotification",
7594
- PythonSandboxStats: "ReceivePythonSandboxStatsNotification",
7595
- };
7596
- const POLL_SUBTASK_INTERVAL_MS = 500;
7597
- const POLL_SUBTASK_TIMEOUT_MS = 15_000;
7598
-
7599
- const useServerNotificationsContext = () => {
7600
- return React.useContext(ServerNotificationsContext);
7601
- };
7602
-
7603
- const useRemoteTask = ({ onUpdate } = {}) => {
7604
- const { api: api$1 } = useGlobalContext();
7605
- const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
7606
- const runTask = React.useCallback((prototype) => new Promise((resolve, reject) => {
7607
- const start = async () => {
7608
- const resourceId = prototype.subTaskSettings?.[0]?.startParameters?.resourceId;
7609
- let prototypeId = await api$1.remoteTaskManager.createTaskPrototype(prototype);
7610
- prototypeId = prototypeId.replace(/["']+/g, "");
7611
- const { id: taskId, success } = await api$1.remoteTaskManager.startTask1(prototypeId);
7612
- if (!success || !taskId) {
7613
- reject(new Error("startTask returned no taskId"));
7614
- return;
7615
- }
7616
- const subscriptionId = await addSubscription({
7617
- tag: "python_task_progress_event",
7618
- resourceId,
7619
- });
7620
- const onNotification = ({ data }) => {
7621
- if (data?.taskId !== taskId) {
7622
- return;
7623
- }
7624
- onUpdate?.({ status: data.status, log: data.log });
7625
- const isCompleted = data.status === api.RemoteTaskStatus.Completed;
7626
- const isError = data.status === api.RemoteTaskStatus.Error;
7627
- if (isCompleted || isError) {
7628
- connection?.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7629
- if (subscriptionId) {
7630
- unsubscribeById(subscriptionId);
7631
- }
7632
- resolve({
7633
- taskId,
7634
- status: isCompleted ? api.RemoteTaskStatus.Completed : api.RemoteTaskStatus.Error,
7635
- log: data.log,
7636
- });
7637
- }
7638
- };
7639
- connection?.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7640
- };
7641
- start().catch(reject);
7642
- }), [api$1, addSubscription, connection, unsubscribeById, onUpdate]);
7643
- return { runTask };
7993
+ * контейнер прокидывает в CSS-переменную `--tile-width`, которую читает каждая плитка.
7994
+ *
7995
+ * Результат ограничен шириной ячейки ряда: плитка задаёт свою ширину в пикселях и в grid не
7996
+ * сжимается вместе с треком (`flex-shrink` там не действует, а `min-width: 0` базового
7997
+ * контейнера позволяет треку ужаться), поэтому натуральная ширина шире ячейки означала бы
7998
+ * наложение соседних плиток друг на друга.
7999
+ *
8000
+ * `enabled: false` полностью отключает измерение — ширина берётся из grid-ячейки.
8001
+ */
8002
+ const useEqualTileWidth = ({ enabled, itemsCount, columns, gap, }) => {
8003
+ const ref = React.useRef(null);
8004
+ const [width, setWidth] = React.useState();
8005
+ const measure = React.useCallback(() => {
8006
+ const node = ref.current;
8007
+ if (!node)
8008
+ return;
8009
+ const tiles = Array.from(node.querySelectorAll("[data-tile]"));
8010
+ if (!tiles.length)
8011
+ return;
8012
+ // Ширина ряда снимается до замера: временный `max-content` может распереть содержимое.
8013
+ const available = columns > 0 ? (node.clientWidth - gap * (columns - 1)) / columns : 0;
8014
+ tiles.forEach(tile => {
8015
+ tile.style.width = "max-content";
8016
+ });
8017
+ let max = 0;
8018
+ tiles.forEach(tile => {
8019
+ max = Math.max(max, tile.getBoundingClientRect().width);
8020
+ });
8021
+ tiles.forEach(tile => {
8022
+ tile.style.width = "";
8023
+ });
8024
+ // Ограниченную ширину округляем вниз — иначе округление вернуло бы ряд за границы контейнера.
8025
+ const next = available > 0 && max > available ? Math.floor(available) : Math.ceil(max);
8026
+ setWidth(previous => (max && previous !== next ? next : previous));
8027
+ }, [columns, gap]);
8028
+ React.useEffect(() => {
8029
+ if (!enabled) {
8030
+ setWidth(undefined);
8031
+ return;
8032
+ }
8033
+ const node = ref.current;
8034
+ if (!node)
8035
+ return;
8036
+ measure();
8037
+ const observer = new ResizeObserver(() => measure());
8038
+ observer.observe(node);
8039
+ return () => observer.disconnect();
8040
+ }, [enabled, itemsCount, measure]);
8041
+ return [ref, enabled ? width : undefined];
7644
8042
  };
7645
8043
 
7646
8044
  const SAVE_HOOK_RESULT_DURATION = 4000;
@@ -8020,417 +8418,139 @@ const useWidgetFilters = (type, filterName, items) => {
8020
8418
  }, { min: null, max: null }) || {};
8021
8419
  changeFilters({ [filterName]: { value, min, max } }, configFilter?.resetFilters);
8022
8420
  }, [filters, currentPage.filters, filterName, configFilter, items, changeFilters]);
8023
- return { filters, formatFilterColor, hasAnyFilter, isFiltered, onFilter };
8024
- };
8025
-
8026
- const useGetConfigLayer = () => {
8027
- const { currentPage } = useWidgetPage();
8028
- return React.useCallback((layerName) => currentPage?.layers?.find(({ name }) => name === layerName), [currentPage?.layers]);
8029
- };
8030
-
8031
- const useHideIfEmptyDataSource = (type = exports.WidgetType.Dashboard) => {
8032
- const { dataSources } = useWidgetContext(type);
8033
- return React.useCallback((dataSourceName) => {
8034
- if (!dataSourceName)
8035
- return false;
8036
- return !getDataSource(dataSourceName, dataSources)?.features?.length;
8037
- }, [dataSources]);
8038
- };
8039
-
8040
- const useProjectDashboardInit = () => {
8041
- const { projectInfo, updateProject } = useWidgetContext();
8042
- return React.useCallback(() => {
8043
- if (!projectInfo || !lodash.isEmpty(projectInfo.content?.dashboardConfiguration)) {
8044
- return;
8045
- }
8046
- const { alias, name } = projectInfo;
8047
- const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
8048
- newProjectInfo.content.dashboardConfiguration = getDefaultConfig({ title: alias || name });
8049
- updateProject(newProjectInfo);
8050
- }, [projectInfo, updateProject]);
8051
- };
8052
-
8053
- const useRelatedDataSourceAttributes = ({ type = exports.WidgetType.Dashboard, elementConfig, dataSources, feature, }) => {
8054
- const { layerInfos } = useWidgetContext(type);
8055
- const { currentPage } = useWidgetPage(type);
8056
- const { options } = elementConfig || {};
8057
- const { relatedDataSource } = options || {};
8058
- const dataSource = React.useMemo(() => getDataSource(relatedDataSource, dataSources), [dataSources, relatedDataSource]);
8059
- const configDataSource = React.useMemo(() => currentPage?.dataSources?.find(({ name }) => name === relatedDataSource), [currentPage?.dataSources, relatedDataSource]);
8060
- const layerInfo = React.useMemo(() => getDataSourceLayerInfo({ layerInfos, configDataSource, fetchedDataSource: dataSource }) ||
8061
- EMPTY_DATA_SOURCE_LAYER_INFO, [configDataSource, dataSource, layerInfos]);
8062
- const attributes = React.useMemo(() => getFeatureAttributes(feature, layerInfo, dataSource), [dataSource, feature, layerInfo]);
8063
- return { layerInfo, attributes, dataSource, configDataSource };
8064
- };
8065
-
8066
- const useRenderElement = (type = exports.WidgetType.Dashboard, elementConfig) => {
8067
- const { t } = useGlobalContext();
8068
- const { selectedTabId, setSelectedTabId, expandedContainers, layerInfo, attributes } = useWidgetContext(type);
8069
- const { config } = useWidgetConfig(type);
8070
- const { pageIndex } = useWidgetPage(type);
8071
- return React.useMemo(() => getRenderElement({
8072
- t,
8073
- type,
8074
- config,
8075
- elementConfig,
8076
- layerInfo,
8077
- attributes,
8078
- expandedContainers,
8079
- pageIndex,
8080
- selectedTabId,
8081
- setSelectedTabId,
8082
- }), [
8083
- attributes,
8084
- config,
8085
- elementConfig,
8086
- expandedContainers,
8087
- layerInfo,
8088
- pageIndex,
8089
- selectedTabId,
8090
- setSelectedTabId,
8091
- type,
8092
- ]);
8093
- };
8094
-
8095
- /** Пустой бокс на отключённом пути — стабильная ссылка, чтобы не плодить ре-рендеры. */
8096
- const EMPTY_BOX = {};
8097
- /**
8098
- * Измеряет фактические ширину и высоту DOM-элемента и обновляет их на любой ресайз (ResizeObserver).
8099
- *
8100
- * Возвращает `[ref, box]`, где `box` — `{ width, height }` в пикселях (content-box) либо пустой объект,
8101
- * пока элемент ещё не измерен. Используется для «резинового» графика: d3-графикам нужны конкретные
8102
- * пиксельные размеры, а не CSS `100%`, а для вписывания (fit) нужны обе оси.
8103
- *
8104
- * `enabled: false` полностью отключает наблюдение — обычные (не fill) графики не измеряются
8105
- * и не вызывают лишних ре-рендеров.
8106
- */
8107
- const useResizeBox = (enabled) => {
8108
- const ref = React.useRef(null);
8109
- const [box, setBox] = React.useState(EMPTY_BOX);
8110
- React.useEffect(() => {
8111
- const node = ref.current;
8112
- if (!enabled || !node)
8113
- return;
8114
- const observer = new ResizeObserver(([entry]) => {
8115
- const { width, height } = entry.contentRect;
8116
- setBox({ width, height });
8117
- });
8118
- observer.observe(node);
8119
- return () => observer.disconnect();
8120
- }, [enabled]);
8121
- return [ref, enabled ? box : EMPTY_BOX];
8122
- };
8123
-
8124
- const useShownOtherItems = (options) => {
8125
- const [showMore, onShowMore] = useToggle();
8126
- const { shownItems } = options || {};
8127
- return {
8128
- sliceItems: (items) => sliceShownOtherItems(items, options, showMore),
8129
- checkIsSliced: (items) => !!shownItems && items?.length > shownItems,
8130
- onShowMore,
8131
- showMore,
8132
- };
8133
- };
8134
-
8135
- const useUpdateDataSource = ({ dataSource, config, filters, attributes, layerParams, eqlParameters, }) => {
8136
- const { dataSources } = useWidgetContext();
8137
- const { getDataSourcePromises, getUpdatedDataSources } = useDataSources({
8138
- type: exports.WidgetType.Dashboard,
8139
- config,
8140
- filters,
8141
- attributes,
8142
- layerParams,
8143
- eqlParameters,
8144
- });
8145
- return React.useCallback(async (newFilters, offset = 0) => {
8146
- return getDataSourcePromises(dataSource, newFilters, offset).then((response) => {
8147
- const settled = { status: "fulfilled", value: response };
8148
- const responseDataSources = getUpdatedDataSources([settled], [dataSource], dataSources);
8149
- return {
8150
- items: responseDataSources.find(({ name }) => name === dataSource.name).features,
8151
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
8152
- totalCount: response.totalCount,
8153
- };
8154
- });
8155
- }, [dataSource, getDataSourcePromises, getUpdatedDataSources, dataSources]);
8156
- };
8157
-
8158
- const useMaxZoomTo = () => {
8159
- const { currentPage } = useWidgetPage();
8160
- return React.useCallback((layerName) => {
8161
- if (!layerName) {
8162
- return [currentPage?.options?.maxZoomTo, undefined];
8163
- }
8164
- return [currentPage?.options?.maxZoomTo, currentPage?.layers?.find(item => item.name === layerName)?.maxZoomTo];
8165
- }, [currentPage?.layers, currentPage?.options?.maxZoomTo]);
8166
- };
8167
-
8168
- const useCustomFeatureSelect = () => {
8169
- const { currentPage } = useWidgetPage();
8170
- return React.useCallback((layerName) => {
8171
- if (!layerName) {
8172
- return [currentPage?.options?.customFeatureSelect, undefined];
8173
- }
8174
- return [
8175
- currentPage?.options?.customFeatureSelect,
8176
- currentPage?.layers?.find(item => item.name === layerName)?.customFeatureSelect,
8177
- ];
8178
- }, [currentPage?.layers, currentPage?.options?.customFeatureSelect]);
8179
- };
8180
-
8181
- const useCurrentPageLayers = () => {
8182
- const { currentPage } = useWidgetPage();
8183
- return React.useMemo(() => currentPage?.layers || [], [currentPage?.layers]);
8184
- };
8185
-
8186
- const useLayerHiddenAttributes = (layerName) => {
8187
- const { currentPage, updateConfigPage } = useWidgetPage();
8188
- const layerHiddenAttributes = React.useMemo(() => {
8189
- return currentPage?.layers?.find(item => item.name === layerName)?.hiddenAttributes ?? [];
8190
- }, [currentPage?.layers, layerName]);
8191
- const updateLayerHiddenAttributes = React.useCallback((updatedHiddenAttributes) => {
8192
- updateConfigPage({
8193
- ...currentPage,
8194
- layers: currentPage?.layers?.map(item => {
8195
- return item.name === layerName
8196
- ? {
8197
- ...item,
8198
- hiddenAttributes: updatedHiddenAttributes,
8199
- }
8200
- : item;
8201
- }),
8202
- });
8203
- }, [currentPage, layerName, updateConfigPage]);
8204
- return [layerHiddenAttributes, updateLayerHiddenAttributes];
8205
- };
8206
-
8207
- const useVisibleProjectItems = (applyMinMaxScale) => {
8208
- const { map } = useMapContext();
8209
- const projectItems = useCurrentPageLayers();
8210
- const zoomChange = React.useMemo(() => (applyMinMaxScale && map.current?.getZoom() !== undefined ? Math.round(map.current?.getZoom()) : undefined), [applyMinMaxScale, map.current?.getZoom()]);
8211
- return React.useMemo(() => {
8212
- if (map.current?.getZoom() === undefined) {
8213
- return [];
8214
- }
8215
- return (projectItems?.filter(item => item.isVisible &&
8216
- (!applyMinMaxScale ||
8217
- (Math.round(map.current.getZoom()) >= (item.minScale ?? 0) &&
8218
- Math.round(map.current.getZoom()) <= (item.maxScale ?? 30)))) ?? []);
8219
- }, [projectItems, zoomChange, applyMinMaxScale]);
8220
- };
8221
-
8222
- const usePythonSandbox = () => {
8223
- const { api } = useGlobalContext();
8224
- const preparePythonSandbox = React.useCallback(({ resourceId, isNotebook = false }) => api.remoteTaskManager.post({
8225
- workerType: "pythonService",
8226
- methodType: "pythonrunner/prepare",
8227
- data: { resourceId, isNotebook },
8228
- }), [api.remoteTaskManager]);
8229
- return { preparePythonSandbox };
8421
+ return { filters, formatFilterColor, hasAnyFilter, isFiltered, onFilter };
8230
8422
  };
8231
8423
 
8232
- const FINAL_STATUSES = [
8233
- api.RemoteTaskStatus.Completed,
8234
- api.RemoteTaskStatus.Error,
8235
- api.RemoteTaskStatus.Interrupted,
8236
- api.RemoteTaskStatus.Timeout,
8237
- ];
8238
- const wait = (ms) => new Promise(resolve => window.setTimeout(resolve, ms));
8239
- const pollSubtaskCompletion = async ({ taskId, api, intervalMs = POLL_SUBTASK_INTERVAL_MS, timeoutMs = POLL_SUBTASK_TIMEOUT_MS, }) => {
8240
- const deadline = Date.now() + timeoutMs;
8241
- let subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
8242
- while (subTask && !FINAL_STATUSES.includes(subTask.status)) {
8243
- if (Date.now() >= deadline)
8244
- return null;
8245
- await wait(intervalMs);
8246
- subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
8247
- }
8248
- return subTask;
8424
+ const useGetConfigLayer = () => {
8425
+ const { currentPage } = useWidgetPage();
8426
+ return React.useCallback((layerName) => currentPage?.layers?.find(({ name }) => name === layerName), [currentPage?.layers]);
8249
8427
  };
8250
8428
 
8251
- const usePythonTask = () => {
8252
- const { api: api$1, t } = useGlobalContext();
8253
- const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
8254
- const { preparePythonSandbox } = usePythonSandbox();
8255
- const [status, setStatus] = React.useState(api.RemoteTaskStatus.Unknown);
8256
- const [log, setLog] = React.useState(null);
8257
- const [lastMessage, setLastMessage] = React.useState(null);
8258
- const [error, setError] = React.useState(null);
8259
- const [loading, setLoading] = React.useState(false);
8260
- const [executionTime, setExecutionTime] = React.useState(null);
8261
- const [taskId, setTaskId] = React.useState(null);
8262
- const [subscriptionId, setSubscriptionId] = React.useState(null);
8263
- const [isLogDialogOpen, setIsLogDialogOpen] = React.useState(false);
8264
- const [result, setResult] = React.useState(null);
8265
- const reset = React.useCallback(() => {
8266
- setStatus(api.RemoteTaskStatus.Unknown);
8267
- setError(null);
8268
- setLoading(false);
8269
- setExecutionTime(null);
8270
- setTaskId(null);
8271
- setSubscriptionId(null);
8272
- setResult(null);
8273
- }, []);
8274
- const runTask = React.useCallback(async ({ resourceId, parameters, script, fileName, methodName, }) => {
8275
- reset();
8276
- setStatus(api.RemoteTaskStatus.Process);
8277
- setLog(null);
8278
- setLastMessage(null);
8279
- setLoading(true);
8280
- const start = Date.now();
8281
- let prototypeId = await api$1.remoteTaskManager.createTaskPrototype({
8282
- enabled: true,
8283
- startIfPreviousError: true,
8284
- startIfPreviousNotFinished: true,
8285
- subTaskSettings: [
8286
- {
8287
- type: "pythonService",
8288
- startParameters: {
8289
- resourceId,
8290
- parameters,
8291
- script,
8292
- fileName,
8293
- methodName,
8294
- method: "pythonrunner/run",
8295
- },
8296
- },
8297
- ],
8298
- });
8299
- prototypeId = prototypeId.replace(/["']+/g, "");
8300
- await preparePythonSandbox({ resourceId });
8301
- const { id: newTaskId, success } = await api$1.remoteTaskManager.startTask1(prototypeId);
8302
- if (!success) {
8303
- setStatus(api.RemoteTaskStatus.Error);
8304
- setLog(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
8305
- setExecutionTime(Date.now() - start);
8306
- setLoading(false);
8307
- }
8308
- const newSubscriptionId = await addSubscription({
8309
- tag: "python_task_progress_event",
8310
- resourceId,
8311
- });
8312
- setTaskId(newTaskId);
8313
- setSubscriptionId(newSubscriptionId);
8314
- const onNotification = async ({ data }) => {
8315
- if (data?.taskId === newTaskId) {
8316
- const isFinished = [api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status);
8317
- setStatus(data.status);
8318
- setLog(prev => [prev, data.log].filter(Boolean).join(""));
8319
- if (data.log)
8320
- setLastMessage(data.log);
8321
- setExecutionTime(Date.now() - start);
8322
- setLoading(false);
8323
- setTaskId(isFinished ? null : newTaskId);
8324
- setSubscriptionId(isFinished ? null : newSubscriptionId);
8325
- if (isFinished) {
8326
- unsubscribeById(newSubscriptionId);
8327
- connection.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
8328
- }
8329
- if (data.status === api.RemoteTaskStatus.Completed) {
8330
- try {
8331
- const subTask = await pollSubtaskCompletion({ taskId: newTaskId, api: api$1 });
8332
- if (subTask?.status === api.RemoteTaskStatus.Completed) {
8333
- const response = subTask.results?.response;
8334
- setResult(typeof response === "object" && response !== null
8335
- ? response
8336
- : null);
8337
- }
8338
- else {
8339
- setError(new Error(t("taskResultUnavailable", {
8340
- ns: "devMode",
8341
- defaultValue: "Не удалось получить результат задачи",
8342
- })));
8343
- }
8344
- }
8345
- catch (e) {
8346
- setError(e instanceof Error ? e : new Error(String(e)));
8347
- }
8348
- }
8349
- }
8350
- };
8351
- connection.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
8352
- }, [reset, api$1, preparePythonSandbox, addSubscription, connection, t, unsubscribeById]);
8353
- const stopTask = React.useCallback(async () => {
8354
- await api$1.remoteTaskManager.stop(taskId);
8355
- reset();
8356
- unsubscribeById(subscriptionId);
8357
- }, [api$1, reset, unsubscribeById, taskId, subscriptionId]);
8358
- const openLog = React.useCallback(() => {
8359
- setIsLogDialogOpen(true);
8360
- }, []);
8361
- const closeLog = React.useCallback(() => {
8362
- setIsLogDialogOpen(false);
8363
- }, []);
8364
- return {
8365
- taskId,
8366
- runTask,
8367
- stopTask,
8368
- openLog,
8369
- log,
8370
- lastMessage,
8371
- error,
8372
- status,
8373
- loading,
8374
- executionTime,
8375
- isLogDialogOpen,
8376
- closeLog,
8377
- result,
8378
- };
8429
+ const useHideIfEmptyDataSource = (type = exports.WidgetType.Dashboard) => {
8430
+ const { dataSources } = useWidgetContext(type);
8431
+ return React.useCallback((dataSourceName) => {
8432
+ if (!dataSourceName)
8433
+ return false;
8434
+ return !getDataSource(dataSourceName, dataSources)?.features?.length;
8435
+ }, [dataSources]);
8379
8436
  };
8380
8437
 
8381
- const useAppHeight = () => {
8382
- React.useEffect(() => {
8383
- const setAppHeight = () => {
8384
- document.documentElement.style.setProperty("--app-height", `${window.innerHeight}px`);
8385
- };
8386
- window.addEventListener("resize", setAppHeight);
8387
- setAppHeight();
8388
- return () => {
8389
- window.removeEventListener("resize", setAppHeight);
8390
- };
8391
- }, []);
8438
+ const useProjectDashboardInit = () => {
8439
+ const { projectInfo, updateProject } = useWidgetContext();
8440
+ return React.useCallback(() => {
8441
+ if (!projectInfo || !lodash.isEmpty(projectInfo.content?.dashboardConfiguration)) {
8442
+ return;
8443
+ }
8444
+ const { alias, name } = projectInfo;
8445
+ const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
8446
+ newProjectInfo.content.dashboardConfiguration = getDefaultConfig({ title: alias || name });
8447
+ updateProject(newProjectInfo);
8448
+ }, [projectInfo, updateProject]);
8392
8449
  };
8393
8450
 
8394
- const useDebouncedCallback = (interval) => {
8395
- return React.useMemo(() => debounce((cb) => {
8396
- cb();
8397
- }, interval), [interval]);
8451
+ const useRelatedDataSourceAttributes = ({ type = exports.WidgetType.Dashboard, elementConfig, dataSources, feature, }) => {
8452
+ const { layerInfos } = useWidgetContext(type);
8453
+ const { currentPage } = useWidgetPage(type);
8454
+ const { options } = elementConfig || {};
8455
+ const { relatedDataSource } = options || {};
8456
+ const dataSource = React.useMemo(() => getDataSource(relatedDataSource, dataSources), [dataSources, relatedDataSource]);
8457
+ const configDataSource = React.useMemo(() => currentPage?.dataSources?.find(({ name }) => name === relatedDataSource), [currentPage?.dataSources, relatedDataSource]);
8458
+ const layerInfo = React.useMemo(() => getDataSourceLayerInfo({ layerInfos, configDataSource, fetchedDataSource: dataSource }) ||
8459
+ EMPTY_DATA_SOURCE_LAYER_INFO, [configDataSource, dataSource, layerInfos]);
8460
+ const attributes = React.useMemo(() => getFeatureAttributes(feature, layerInfo, dataSource), [dataSource, feature, layerInfo]);
8461
+ return { layerInfo, attributes, dataSource, configDataSource };
8398
8462
  };
8399
8463
 
8400
- const useToggle = (initial) => {
8401
- const [state, setState] = React.useState(initial !== undefined ? initial : false);
8402
- const toggle = React.useCallback(() => setState(!state), [state]);
8403
- return [state, toggle, setState];
8464
+ const useRenderElement = (type = exports.WidgetType.Dashboard, elementConfig) => {
8465
+ const { t } = useGlobalContext();
8466
+ const { selectedTabId, setSelectedTabId, expandedContainers, layerInfo, attributes } = useWidgetContext(type);
8467
+ const { config } = useWidgetConfig(type);
8468
+ const { pageIndex } = useWidgetPage(type);
8469
+ return React.useMemo(() => getRenderElement({
8470
+ t,
8471
+ type,
8472
+ config,
8473
+ elementConfig,
8474
+ layerInfo,
8475
+ attributes,
8476
+ expandedContainers,
8477
+ pageIndex,
8478
+ selectedTabId,
8479
+ setSelectedTabId,
8480
+ }), [
8481
+ attributes,
8482
+ config,
8483
+ elementConfig,
8484
+ expandedContainers,
8485
+ layerInfo,
8486
+ pageIndex,
8487
+ selectedTabId,
8488
+ setSelectedTabId,
8489
+ type,
8490
+ ]);
8404
8491
  };
8405
8492
 
8406
- const DEBOUNCE_DELAY = 144;
8407
- const useWindowResize = (callback, delay) => {
8408
- const debounceCallback = React.useMemo(() => {
8409
- return callback ? debounce(callback, delay || DEBOUNCE_DELAY) : undefined;
8410
- }, [callback, delay]);
8493
+ /** Пустой бокс на отключённом пути — стабильная ссылка, чтобы не плодить ре-рендеры. */
8494
+ const EMPTY_BOX = {};
8495
+ /**
8496
+ * Измеряет фактические ширину и высоту DOM-элемента и обновляет их на любой ресайз (ResizeObserver).
8497
+ *
8498
+ * Возвращает `[ref, box]`, где `box` — `{ width, height }` в пикселях (content-box) либо пустой объект,
8499
+ * пока элемент ещё не измерен. Используется для «резинового» графика: d3-графикам нужны конкретные
8500
+ * пиксельные размеры, а не CSS `100%`, а для вписывания (fit) нужны обе оси.
8501
+ *
8502
+ * `enabled: false` полностью отключает наблюдение — обычные (не fill) графики не измеряются
8503
+ * и не вызывают лишних ре-рендеров.
8504
+ */
8505
+ const useResizeBox = (enabled) => {
8506
+ const ref = React.useRef(null);
8507
+ const [box, setBox] = React.useState(EMPTY_BOX);
8411
8508
  React.useEffect(() => {
8412
- debounceCallback && window.addEventListener("resize", debounceCallback);
8413
- return () => debounceCallback && window.removeEventListener("resize", debounceCallback);
8414
- }, [debounceCallback]);
8509
+ const node = ref.current;
8510
+ if (!enabled || !node)
8511
+ return;
8512
+ const observer = new ResizeObserver(([entry]) => {
8513
+ const { width, height } = entry.contentRect;
8514
+ setBox({ width, height });
8515
+ });
8516
+ observer.observe(node);
8517
+ return () => observer.disconnect();
8518
+ }, [enabled]);
8519
+ return [ref, enabled ? box : EMPTY_BOX];
8415
8520
  };
8416
8521
 
8417
- const useContainerAttributes = ({ elementConfig, type, renderElement }) => {
8418
- const getRenderContainerItem = useRenderContainerItem(type, renderElement);
8419
- const { options } = elementConfig || {};
8420
- const { attributes: optionAttributes, useProjectHiddenAttributes } = options || {};
8421
- const { attributes: contextAttributes, layerInfo } = useWidgetContext(type);
8422
- const [hiddenAttributes] = useLayerHiddenAttributes(layerInfo?.name ?? "");
8423
- const attributesToRender = React.useMemo(() => {
8424
- if (!optionAttributes)
8425
- return null;
8426
- const baseList = optionAttributes.length === 0
8427
- ? contextAttributes?.map(({ attributeName }) => attributeName) ?? []
8428
- : optionAttributes;
8429
- if (!useProjectHiddenAttributes)
8430
- return baseList;
8431
- return baseList.filter(attribute => !hiddenAttributes.includes(attribute));
8432
- }, [optionAttributes, contextAttributes, hiddenAttributes, useProjectHiddenAttributes]);
8433
- return { getRenderContainerItem, attributesToRender };
8522
+ const useShownOtherItems = (options) => {
8523
+ const [showMore, onShowMore] = useToggle();
8524
+ const { shownItems } = options || {};
8525
+ return {
8526
+ sliceItems: (items) => sliceShownOtherItems(items, options, showMore),
8527
+ checkIsSliced: (items) => !!shownItems && items?.length > shownItems,
8528
+ onShowMore,
8529
+ showMore,
8530
+ };
8531
+ };
8532
+
8533
+ const useUpdateDataSource = ({ dataSource, config, filters, attributes, layerParams, eqlParameters, }) => {
8534
+ const { dataSources } = useWidgetContext();
8535
+ const { getDataSourcePromises, getUpdatedDataSources } = useDataSources({
8536
+ type: exports.WidgetType.Dashboard,
8537
+ config,
8538
+ filters,
8539
+ attributes,
8540
+ layerParams,
8541
+ eqlParameters,
8542
+ });
8543
+ return React.useCallback(async (newFilters, offset = 0) => {
8544
+ return getDataSourcePromises(dataSource, newFilters, offset).then((response) => {
8545
+ const settled = { status: "fulfilled", value: response };
8546
+ const responseDataSources = getUpdatedDataSources([settled], [dataSource], dataSources);
8547
+ return {
8548
+ items: responseDataSources.find(({ name }) => name === dataSource.name).features,
8549
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8550
+ totalCount: response.totalCount,
8551
+ };
8552
+ });
8553
+ }, [dataSource, getDataSourcePromises, getUpdatedDataSources, dataSources]);
8434
8554
  };
8435
8555
 
8436
8556
  const useRenderContainer = ({ elementConfig, type, renderElement, renderBody, }) => {
@@ -8470,6 +8590,7 @@ const useRenderContainer = ({ elementConfig, type, renderElement, renderBody, })
8470
8590
  const OneColumnContainer = React.memo(({ type, elementConfig, renderElement }) => {
8471
8591
  const { width, height, overflow } = elementConfig?.options || {};
8472
8592
  const templateName = elementConfig?.templateName;
8593
+ const bgHost = useBgImageHost(elementConfig);
8473
8594
  const renderBody = React.useCallback(({ id, value, style, hasUnits, render }) => (jsxRuntime.jsxs(Container, { id: id, isColumn: true, "data-templatename": templateName, style: style, "$sizeCss": getWrapperSizeStyle({
8474
8595
  style,
8475
8596
  width,
@@ -8477,7 +8598,7 @@ const OneColumnContainer = React.memo(({ type, elementConfig, renderElement }) =
8477
8598
  overflow,
8478
8599
  defaults: BASE_CONTAINER_STYLE,
8479
8600
  defaultWidth: FILL_SIZE,
8480
- }), children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxRuntime.jsxs(ContainerValue, { children: [value, hasUnits && (jsxRuntime.jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName]);
8601
+ }), ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: render }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxRuntime.jsxs(ContainerValue, { children: [value, hasUnits && (jsxRuntime.jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName, bgHost, elementConfig]);
8481
8602
  const { renderContainer, attributesToRender } = useRenderContainer({
8482
8603
  type,
8483
8604
  elementConfig,
@@ -8495,7 +8616,7 @@ const FlowGroup = React.memo(({ elementConfig, type, renderElement }) => {
8495
8616
  const isColumn = column === undefined || column;
8496
8617
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
8497
8618
  const { root, body } = useContainerRoot({ elementConfig, defaults: CONTAINERS_GROUP_DEFAULTS });
8498
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, isColumn: isColumn, "$alignItems": alignItems, children: jsxRuntime.jsx(ContainerChildren, { type: type, items: children, elementConfig: elementConfig, isColumn: isColumn, isMain: id?.startsWith(CONFIG_PAGE_ID), renderElement: renderElement }) }))] }));
8619
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, isColumn: isColumn, "$alignItems": alignItems, children: jsxRuntime.jsx(ContainerChildren, { type: type, items: children, elementConfig: elementConfig, isColumn: isColumn, isMain: id?.startsWith(CONFIG_PAGE_ID), renderElement: renderElement }) }))] }));
8499
8620
  });
8500
8621
 
8501
8622
  /**
@@ -8636,17 +8757,39 @@ const GridContextMenu = React.memo(({ position, onClose }) => {
8636
8757
  return (jsxRuntime.jsx(uilibGl.Popup, { isVisible: true, interactive: true, appendTo: appendToBody, placement: "bottom-start", onRequestClose: onClose, getReferenceClientRect: getReferenceClientRect, anchor: ref => jsxRuntime.jsx(MenuAnchor, { ref: ref }), children: jsxRuntime.jsx(uilibGl.Menu, { options: options, selectOption: handleSelect }) }));
8637
8758
  });
8638
8759
 
8639
- const AddFeatureContainer = React.memo(({ elementConfig }) => {
8760
+ /**
8761
+ * Фоновое изображение контейнера — универсальный слот `bgImage`.
8762
+ *
8763
+ * Ставится первым ребёнком корня контейнера; корень обязан быть хостом слоя
8764
+ * (`bgImageHostMixin` + проп `$hasBgImage`, у контейнеров на `useContainerRoot` он приходит
8765
+ * готовым в `root`).
8766
+ *
8767
+ * Слота нет в конфиге — в DOM не появляется ничего: ни обёртки, ни пустого слоя.
8768
+ *
8769
+ * `options.outflow` читает слой, а не хост: вылет за края — свойство картинки, а раскладка
8770
+ * контейнера от него не меняется.
8771
+ */
8772
+ const ContainerBackground = React.memo(({ elementConfig, renderElement }) => {
8773
+ const hasBgImage = React.useMemo(() => hasContainerBgImage(elementConfig), [elementConfig]);
8774
+ if (!hasBgImage || !renderElement)
8775
+ return null;
8776
+ return (jsxRuntime.jsx(ContainerBackgroundLayer, { "$outflow": elementConfig?.options?.outflow, children: renderElement({ id: BG_IMAGE_SLOT_ID, wrap: false }) }));
8777
+ });
8778
+
8779
+ const AddFeatureContainer = React.memo(({ elementConfig, renderElement }) => {
8640
8780
  const { id, children, style } = elementConfig || {};
8641
- return (jsxRuntime.jsx(Container, { id: id, style: style, children: children
8642
- .filter(({ type }) => type === "button")
8643
- .map(({ options }, index) => (jsxRuntime.jsx(AddFeatureButton, { icon: options?.icon, title: options?.title, layerName: options?.layerName, geometryType: options?.geometryType }, index))) }));
8781
+ const bgHost = useBgImageHost(elementConfig);
8782
+ return (jsxRuntime.jsxs(Container, { id: id, style: style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), children
8783
+ .filter(({ type }) => type === "button")
8784
+ .map(({ options }, index) => (jsxRuntime.jsx(AddFeatureButton, { icon: options?.icon, title: options?.title, layerName: options?.layerName, geometryType: options?.geometryType }, index)))] }));
8644
8785
  });
8645
8786
 
8646
8787
  const AttachmentsContainer = styled.div.withConfig({ displayName: "AttachmentsContainer", componentId: "sc-1y13q8d" }) `
8647
8788
  display: flex;
8648
8789
  flex-direction: column;
8649
8790
  width: 100%;
8791
+
8792
+ ${bgImageHostMixin};
8650
8793
  `;
8651
8794
  const AttachmentsHeaderRow = styled.div.withConfig({ displayName: "AttachmentsHeaderRow", componentId: "sc-l7u1q7" }) `
8652
8795
  &&& {
@@ -9009,7 +9152,7 @@ const AttachmentContainer = React.memo(({ type, elementConfig, renderElement })
9009
9152
  const handleClosePreview = React.useCallback(() => setPreviewIndex(null), []);
9010
9153
  const handleShowMore = React.useCallback(() => setShowMore(true), [setShowMore]);
9011
9154
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9012
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, children: jsxRuntime.jsxs(uilibGl.Flex, { column: true, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
9155
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, children: jsxRuntime.jsxs(uilibGl.Flex, { column: true, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
9013
9156
  ns: "common",
9014
9157
  defaultValue: "Ресурс недоступен",
9015
9158
  }) }, previewIndex))] }) }))] }));
@@ -9021,7 +9164,7 @@ const CameraContainer = React.memo(({ elementConfig, type, renderElement }) => {
9021
9164
  const { expandable, expanded } = options || {};
9022
9165
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9023
9166
  const { root, body } = useContainerRoot({ elementConfig });
9024
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value", wrap: false }) })] }))] }));
9167
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value", wrap: false }) })] }))] }));
9025
9168
  });
9026
9169
 
9027
9170
  /**
@@ -9052,7 +9195,7 @@ const ChartContainer = React.memo(({ elementConfig, isVisible, type, renderEleme
9052
9195
  const hasItems = !!data[0]?.items?.length;
9053
9196
  if (!loading && !hasItems && hideEmpty)
9054
9197
  return null;
9055
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [aliasElement && jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { column: !twoColumns, alignItems: twoColumns && fill ? "stretch" : "center", "$fill": !!fill, children: hasItems ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ContainerChart, { "$fill": !!fill, children: jsxRuntime.jsx(FillContext.Provider, { value: fillContextValue, children: renderElement({ id: "chart" }) }) }), jsxRuntime.jsx(ContainerLegend, { justifyContent: legendElement?.options?.center ? "center" : "flex-start", children: renderElement({ id: "legend" }) })] })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u2014" })) })] }))] }));
9198
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [aliasElement && jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { column: !twoColumns, alignItems: twoColumns && fill ? "stretch" : "center", "$fill": !!fill, children: hasItems ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ContainerChart, { "$fill": !!fill, children: jsxRuntime.jsx(FillContext.Provider, { value: fillContextValue, children: renderElement({ id: "chart" }) }) }), jsxRuntime.jsx(ContainerLegend, { justifyContent: legendElement?.options?.center ? "center" : "flex-start", children: renderElement({ id: "legend" }) })] })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u2014" })) })] }))] }));
9056
9199
  });
9057
9200
 
9058
9201
  const InnerContainerWrapper = styled.div.withConfig({ displayName: "InnerContainerWrapper", componentId: "sc-1a1fl7q" }) `
@@ -9081,6 +9224,16 @@ const DataSourceInnerContainer = React.memo(({ config, elementConfig, feature, m
9081
9224
  });
9082
9225
  const { options, children } = elementConfig || {};
9083
9226
  const { relatedDataSource, filterName, column } = options || {};
9227
+ /**
9228
+ * Конфиг записи — тот же узел хоста, но без слота фона.
9229
+ *
9230
+ * У `DataSource`/`DataSourceProgress` дети — слоты ВНУТРЕННЕГО шаблона, поэтому `bgImage`
9231
+ * достался бы и хосту, и каждой записи: одна картинка нарисовалась бы дважды. Фон остаётся
9232
+ * за хостом (он и есть контейнер), а записи получают конфиг без слота.
9233
+ */
9234
+ const innerConfig = React.useMemo(() => elementConfig && children?.some(({ id }) => id === BG_IMAGE_SLOT_ID)
9235
+ ? { ...elementConfig, children: children.filter(({ id }) => id !== BG_IMAGE_SLOT_ID) }
9236
+ : elementConfig, [elementConfig, children]);
9084
9237
  const aliasElement = React.useMemo(() => children?.find(({ id }) => id === "alias"), [children]);
9085
9238
  const valueElement = React.useMemo(() => children?.find(({ id }) => id === "value"), [children]);
9086
9239
  const aliasAttribute = React.useMemo(() => (aliasElement ? attributes?.find(({ attributeName }) => attributeName === aliasElement.attributeName) : null), [aliasElement, attributes]);
@@ -9123,7 +9276,7 @@ const DataSourceInnerContainer = React.memo(({ config, elementConfig, feature, m
9123
9276
  if (!InnerContainer) {
9124
9277
  return null;
9125
9278
  }
9126
- return (jsxRuntime.jsx(InnerContainerWrapper, { hasAnyFilter: hasAnyFilter, isFiltered: isFiltered(value), column: column === undefined || column, onClick: filterName ? () => onFilter(value) : undefined, children: jsxRuntime.jsx(InnerContainer, { config: config, elementConfig: elementConfig, feature: feature, maxValue: maxValue, type: type, index: index, renderElement: render }) }));
9279
+ return (jsxRuntime.jsx(InnerContainerWrapper, { hasAnyFilter: hasAnyFilter, isFiltered: isFiltered(value), column: column === undefined || column, onClick: filterName ? () => onFilter(value) : undefined, children: jsxRuntime.jsx(InnerContainer, { config: config, elementConfig: innerConfig, feature: feature, maxValue: maxValue, type: type, index: index, renderElement: render }) }));
9127
9280
  });
9128
9281
 
9129
9282
  const DataSourceProgressContainerWrapper = styled.div.withConfig({ displayName: "DataSourceProgressContainerWrapper", componentId: "sc-d525nv" }) `
@@ -9211,7 +9364,7 @@ const DataSourceContainer = React.memo(({ config, elementConfig, type, innerComp
9211
9364
  if (dataSource && !dataSource.features) {
9212
9365
  return jsxRuntime.jsx(DataSourceError, { name: elementConfig.templateName });
9213
9366
  }
9214
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(DataSourceContainerWrapper, { ...body, ref: tilesRef, isColumn: column, "$isRow": !column, "$columns": columns, "$gap": gap, "$align": align, "$stretch": stretch, "$tileWidth": tileWidth, children: sliceItems(dataSource.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { index: index, type: type, config: config, feature: feature, elementConfig: elementConfig, innerComponent: innerComponent }, index))) }), checkIsSliced(dataSource.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore
9367
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(DataSourceContainerWrapper, { ...body, ref: tilesRef, isColumn: column, "$isRow": !column, "$columns": columns, "$gap": gap, "$align": align, "$stretch": stretch, "$tileWidth": tileWidth, children: sliceItems(dataSource.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { index: index, type: type, config: config, feature: feature, elementConfig: elementConfig, innerComponent: innerComponent }, index))) }), checkIsSliced(dataSource.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore
9215
9368
  ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" })
9216
9369
  : t("showAll", { ns: "dashboard", defaultValue: "Показать все" }) }))] })) : (jsxRuntime.jsx(ContainerLoading, {}))] }));
9217
9370
  });
@@ -9220,6 +9373,8 @@ const ProgressContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName:
9220
9373
  align-items: center;
9221
9374
  width: 100%;
9222
9375
  margin-bottom: 1rem;
9376
+
9377
+ ${bgImageHostMixin};
9223
9378
  `;
9224
9379
  const ProgressIcon = styled.div.withConfig({ displayName: "ProgressIcon", componentId: "sc-1e9hoh1" }) `
9225
9380
  margin-right: 0.5rem;
@@ -9355,15 +9510,28 @@ const DataSourceProgressContainer = React.memo(({ config, elementConfig, type, i
9355
9510
  return jsxRuntime.jsx(DataSourceError, { name: elementConfig.templateName });
9356
9511
  }
9357
9512
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9358
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(DataSourceProgressContainerWrapper, { ...body, children: [sliceItems(dataSource?.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { type: type, index: index, feature: feature, config: config, elementConfig: elementConfig, maxValue: currentMaxValue, innerComponent: innerComponent }, index))), checkIsSliced(dataSource?.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" }) : t("showAll", {
9513
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxRuntime.jsxs(DataSourceProgressContainerWrapper, { ...body, children: [sliceItems(dataSource?.features)?.map((feature, index) => (jsxRuntime.jsx(DataSourceInnerContainer, { type: type, index: index, feature: feature, config: config, elementConfig: elementConfig, maxValue: currentMaxValue, innerComponent: innerComponent }, index))), checkIsSliced(dataSource?.features) && (jsxRuntime.jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" }) : t("showAll", {
9359
9514
  ns: "dashboard",
9360
9515
  defaultValue: "Показать все",
9361
9516
  }) })), showTotal && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.Divider, {}), jsxRuntime.jsxs(ProgressTotal, { children: [jsxRuntime.jsx(ProgressTotalTitle, { children: t("total", { ns: "dashboard", defaultValue: "Итого" }) }), jsxRuntime.jsxs(ProgressValue, { children: [totalValue, jsxRuntime.jsx(ProgressUnits, { children: totalUnits })] })] })] }))] })) : (jsxRuntime.jsx(ContainerLoading, {})), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type })] }));
9362
9517
  });
9363
9518
 
9364
- const DefaultAttributesContainer = React.memo(({ type, renderElement }) => {
9519
+ const DefaultAttributesContainer = React.memo(({ type, elementConfig, renderElement }) => {
9365
9520
  const { attributes } = useWidgetContext(type);
9366
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: attributes?.map(({ attributeName }) => (jsxRuntime.jsx(Container, { isColumn: true, children: renderElement({ id: attributeName }) }, attributeName))) }));
9521
+ const bgHost = useBgImageHost(elementConfig);
9522
+ const needsHost = !!bgHost.$hasBgImage || !!bgHost.$innerPadding;
9523
+ /*
9524
+ `isColumn` обязателен: без него срабатывает row-ветка Container, а правило
9525
+ `> * { width: 100% }` есть только в column-ветке. Тогда строка атрибута схлопывается
9526
+ по своему контенту, и подписи со значениями перестают выстраиваться в две колонки.
9527
+ */
9528
+ const rows = React.useMemo(() => attributes?.map(({ attributeName }) => (jsxRuntime.jsx(Container, { isColumn: true, children: renderElement({ id: attributeName }) }, attributeName))), [attributes, renderElement]);
9529
+ // Без фона контейнер намеренно отдаёт НЕСКОЛЬКО корней: каждая строка атрибута — отдельная
9530
+ // ячейка родительской колонки. Общая обёртка появляется только под фон или `innerPadding`,
9531
+ // которым иначе не от чего отсчитывать бокс, — и только если автор конфига их попросил.
9532
+ if (!needsHost)
9533
+ return jsxRuntime.jsx(jsxRuntime.Fragment, { children: rows });
9534
+ return (jsxRuntime.jsxs(Container, { isColumn: true, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), rows] }));
9367
9535
  });
9368
9536
 
9369
9537
  const ContainerDivider = styled(uilibGl.Divider).withConfig({ displayName: "ContainerDivider", componentId: "sc-9zqdb0" }) `
@@ -9601,7 +9769,7 @@ const FiltersContainer = React.memo(({ elementConfig, config, type, renderElemen
9601
9769
  }, [config, type]);
9602
9770
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9603
9771
  const selectedItems = React.useMemo(() => getFilterSelectedItems(filterItems, filters, configFilters), [configFilters, filters, filterItems]);
9604
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(uilibGl.Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsxRuntime.jsx(ContainerLoading, {}), !isLoading && isVisible && (jsxRuntime.jsx(FiltersContainerWrapper, { ...body, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0]?.options?.filterName })] }));
9772
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(uilibGl.Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsxRuntime.jsx(ContainerLoading, {}), !isLoading && isVisible && (jsxRuntime.jsx(FiltersContainerWrapper, { ...body, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsxRuntime.jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0]?.options?.filterName })] }));
9605
9773
  });
9606
9774
 
9607
9775
  /** Размер, при котором контейнер занимает всю ячейку родителя. */
@@ -9857,10 +10025,10 @@ const readTrackPixels = (grid, axis) => {
9857
10025
  /**
9858
10026
  * Дети, которые реально становятся треками.
9859
10027
  *
9860
- * `ContainerChildren` не рендерит слоты заголовка, поэтому и в `grid-template-*` их быть не
9861
- * должно — иначе треков окажется больше, чем ячеек, и раскладка съедет.
10028
+ * `ContainerChildren` не рендерит слоты заголовка и фон, поэтому и в `grid-template-*` их быть
10029
+ * не должно — иначе треков окажется больше, чем ячеек, и раскладка съедет.
9862
10030
  */
9863
- const getLayoutChildren = (node) => (node?.children ?? []).filter(({ id }) => !TITLE_SLOT_IDS.includes(id));
10031
+ const getLayoutChildren = (node) => (node?.children ?? []).filter(({ id }) => !NON_TRACK_SLOT_IDS.includes(id));
9864
10032
  /** Опция, в которой лежит доля трека: у строки это высота, у ячейки — ширина. */
9865
10033
  const getTrackSizeKey = (axis) => (axis === "row" ? "height" : "width");
9866
10034
  /**
@@ -10226,14 +10394,14 @@ const GridTrackContent = styled.div.withConfig({ displayName: "GridTrackContent"
10226
10394
  /** Узел-сетка: `ContainersGroup`, у которого включена опция `grid`. */
10227
10395
  const isGridNode = (node) => !!node?.options?.grid;
10228
10396
  /**
10229
- * Подменяет «раскладочных» детей узла, сохраняя слоты заголовка.
10397
+ * Подменяет «раскладочных» детей узла, сохраняя слоты заголовка и фона.
10230
10398
  *
10231
10399
  * Слоты кладутся первыми: их порядок относительно тела ни на что не влияет — тело их отфильтровывает,
10232
- * а `ExpandableTitle` ищет по `id`.
10400
+ * а `ExpandableTitle` и `ContainerBackground` ищут по `id`.
10233
10401
  */
10234
10402
  const setLayoutChildren = (node, children) => ({
10235
10403
  ...node,
10236
- children: [...(node.children ?? []).filter(({ id }) => TITLE_SLOT_IDS.includes(id)), ...children],
10404
+ children: [...(node.children ?? []).filter(({ id }) => NON_TRACK_SLOT_IDS.includes(id)), ...children],
10237
10405
  });
10238
10406
  /**
10239
10407
  * Иммутабельно применяет `mapper` к узлу с заданным `id` где угодно в поддереве.
@@ -10451,7 +10619,7 @@ const GridRowContainer = React.memo(({ elementConfig, renderElement }) => {
10451
10619
  elementConfig,
10452
10620
  defaults: autoHeight ? GRID_AUTO_FILL_DEFAULTS : GRID_FILL_DEFAULTS,
10453
10621
  });
10454
- return (jsxRuntime.jsx(ContainerRoot, { ...root, children: jsxRuntime.jsx(GridTracks, { node: elementConfig, axis: "column", body: body, gap: gap, renderElement: renderElement }) }));
10622
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(GridTracks, { node: elementConfig, axis: "column", body: body, gap: gap, renderElement: renderElement })] }));
10455
10623
  });
10456
10624
 
10457
10625
  const IconContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "IconContainerWrapper", componentId: "sc-1eg4h9n" }) `
@@ -10462,6 +10630,8 @@ const IconContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "Ico
10462
10630
  background-color: ${({ theme: { palette } }) => palette.element};
10463
10631
  border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
10464
10632
  overflow: hidden;
10633
+
10634
+ ${bgImageHostMixin};
10465
10635
  `;
10466
10636
  const IconContainerHeaderWrapper = styled(uilibGl.Flex).withConfig({ displayName: "IconContainerHeaderWrapper", componentId: "sc-1johipv" }) `
10467
10637
  justify-content: space-between;
@@ -10504,10 +10674,11 @@ const IconContainerText = styled.div.withConfig({ displayName: "IconContainerTex
10504
10674
 
10505
10675
  const IconContainer = React.memo(({ elementConfig, renderElement }) => {
10506
10676
  const { id, style } = elementConfig || {};
10507
- return (jsxRuntime.jsxs(IconContainerWrapper, { id: id, style: style, children: [jsxRuntime.jsxs(IconContainerHeaderWrapper, { children: [jsxRuntime.jsxs(IconContainerHeader, { children: [renderElement({ id: "icon" }), jsxRuntime.jsx(IconContainerTitle, { children: renderElement({ id: "alias" }) })] }), renderElement({ id: "link" })] }), jsxRuntime.jsx(IconContainerText, { children: renderElement({ id: "text" }) })] }));
10677
+ const bgHost = useBgImageHost(elementConfig);
10678
+ return (jsxRuntime.jsxs(IconContainerWrapper, { id: id, style: style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(IconContainerHeaderWrapper, { children: [jsxRuntime.jsxs(IconContainerHeader, { children: [renderElement({ id: "icon" }), jsxRuntime.jsx(IconContainerTitle, { children: renderElement({ id: "alias" }) })] }), renderElement({ id: "link" })] }), jsxRuntime.jsx(IconContainerText, { children: renderElement({ id: "text" }) })] }));
10508
10679
  });
10509
10680
 
10510
- const ImageContainerBg$1 = styled.div.withConfig({ displayName: "ImageContainerBg", componentId: "sc-cezopj" }) `
10681
+ const ImageContainerBg = styled.div.withConfig({ displayName: "ImageContainerBg", componentId: "sc-cezopj" }) `
10511
10682
  position: absolute;
10512
10683
  top: 0;
10513
10684
  bottom: 0;
@@ -10568,11 +10739,12 @@ const ImageContainerWrapper = styled(uilibGl.Flex).withConfig({ displayName: "Im
10568
10739
 
10569
10740
  ${sizeCssMixin};
10570
10741
  ${noMarginMixin};
10742
+ ${bgImageHostMixin};
10571
10743
  `;
10572
10744
 
10573
10745
  const ImageContainer = React.memo(({ elementConfig, renderElement }) => {
10574
10746
  const root = useWrapperSize({ elementConfig });
10575
- return (jsxRuntime.jsxs(ImageContainerWrapper, { ...root, children: [jsxRuntime.jsx(ImageContainerTitle, { children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ImageContainerText, { children: renderElement({ id: "text" }) }), renderElement({ id: "button" }), jsxRuntime.jsx(ImageContainerBg$1, { children: renderElement({ id: "image" }) })] }));
10747
+ return (jsxRuntime.jsxs(ImageContainerWrapper, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ImageContainerTitle, { children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ImageContainerText, { children: renderElement({ id: "text" }) }), renderElement({ id: "button" }), jsxRuntime.jsx(ImageContainerBg, { children: renderElement({ id: "image" }) })] }));
10576
10748
  });
10577
10749
 
10578
10750
  const LayersContainerWrapper = styled(Container).withConfig({ displayName: "LayersContainerWrapper", componentId: "sc-1a97bv8" }) `
@@ -10630,7 +10802,7 @@ const LayersContainer = React.memo(({ type, elementConfig, renderElement }) => {
10630
10802
  return currentPage.layers;
10631
10803
  return currentPage.layers.filter(({ name }) => layerNames.includes(name));
10632
10804
  }, [currentPage?.layers, layerNames]);
10633
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(LayersContainerWrapper, { ...body, children: jsxRuntime.jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
10805
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(LayersContainerWrapper, { ...body, children: jsxRuntime.jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
10634
10806
  });
10635
10807
 
10636
10808
  const PagesContainer = React.memo(({ type = exports.WidgetType.Dashboard, noBorders }) => {
@@ -10640,6 +10812,7 @@ const PagesContainer = React.memo(({ type = exports.WidgetType.Dashboard, noBord
10640
10812
  const { options } = config || {};
10641
10813
  const { column, width } = options || {};
10642
10814
  const isColumn = column === undefined || column;
10815
+ const bgHost = useBgImageHost(currentPage);
10643
10816
  const filteredChildren = React.useMemo(() => !selectedTabId
10644
10817
  ? currentPage.children
10645
10818
  : currentPage.children.filter(item => !item.options?.tabId || item.options.tabId === selectedTabId), [currentPage.children, selectedTabId]);
@@ -10665,7 +10838,7 @@ const PagesContainer = React.memo(({ type = exports.WidgetType.Dashboard, noBord
10665
10838
  setSelectedTabId,
10666
10839
  type,
10667
10840
  ]);
10668
- return (jsxRuntime.jsx(Container, { id: getRootElementId(type), style: { width }, isMain: true, isColumn: isColumn, noBorders: noBorders, children: jsxRuntime.jsx(ContainerChildren, { type: type, items: filteredChildren, isMain: true, renderElement: renderElement }) }));
10841
+ return (jsxRuntime.jsxs(Container, { id: getRootElementId(type), style: { width }, isMain: true, isColumn: isColumn, noBorders: noBorders, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: currentPage, renderElement: renderElement }), jsxRuntime.jsx(ContainerChildren, { type: type, items: filteredChildren, isMain: true, renderElement: renderElement })] }));
10669
10842
  });
10670
10843
 
10671
10844
  const ProgressContainer = React.memo(({ type, elementConfig, feature, maxValue, index, renderElement }) => {
@@ -10701,10 +10874,11 @@ const ProgressContainer = React.memo(({ type, elementConfig, feature, maxValue,
10701
10874
  wrap: false,
10702
10875
  }), [renderElement]);
10703
10876
  const renderTooltip = React.useMemo(() => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ProgressTooltipAlias, { children: renderTooltipAlias }), jsxRuntime.jsxs(ProgressTooltipValueContainer, { children: [jsxRuntime.jsx(ProgressTooltipValue, { children: renderTooltipValue }), jsxRuntime.jsx(ProgressTooltipValueOf, { children: t("of", { ns: "dashboard", defaultValue: "из" }) }), jsxRuntime.jsx("div", { children: formatAttributeValue({ t, type: valueType, value: currentMaxValue, stringFormat }) })] })] })), [currentMaxValue, renderTooltipAlias, renderTooltipValue, stringFormat, t, valueType]);
10877
+ const bgHost = useBgImageHost(elementConfig);
10704
10878
  const color = React.useMemo(() => colorAttribute
10705
10879
  ? attributes?.find(({ attributeName }) => attributeName === colorAttribute)?.value
10706
10880
  : colors?.[index] || bgColor, [attributes, bgColor, colorAttribute, colors, index]);
10707
- return (jsxRuntime.jsx(uilibGl.Tooltip, { content: renderTooltip, placement: "top", arrow: true, children: ref => (jsxRuntime.jsxs(ProgressContainerWrapper, { ref: ref, id: id, style: innerTemplateStyle || style, children: [renderIcon && jsxRuntime.jsx(ProgressIcon, { children: renderIcon }), jsxRuntime.jsxs(ProgressContent, { children: [!hideTitle && (jsxRuntime.jsxs(ProgressAlias, { children: [jsxRuntime.jsx("div", { children: renderAlias }), jsxRuntime.jsxs(ProgressValue, { children: [renderValue, unitsElement && jsxRuntime.jsx(ProgressUnits, { children: renderElement({ id: "units" }) })] })] })), jsxRuntime.jsxs(ProgressBarContainer, { innerValue: innerValue, children: [jsxRuntime.jsx(ProgressBarWrapper, { children: jsxRuntime.jsx(ProgressBar, { "$width": width, "$color": color }) }), !!(hideTitle || innerValue) && jsxRuntime.jsx(ProgressInnerValue, { children: renderValue })] })] })] })) }));
10881
+ return (jsxRuntime.jsx(uilibGl.Tooltip, { content: renderTooltip, placement: "top", arrow: true, children: ref => (jsxRuntime.jsxs(ProgressContainerWrapper, { ref: ref, id: id, style: innerTemplateStyle || style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), renderIcon && jsxRuntime.jsx(ProgressIcon, { children: renderIcon }), jsxRuntime.jsxs(ProgressContent, { children: [!hideTitle && (jsxRuntime.jsxs(ProgressAlias, { children: [jsxRuntime.jsx("div", { children: renderAlias }), jsxRuntime.jsxs(ProgressValue, { children: [renderValue, unitsElement && jsxRuntime.jsx(ProgressUnits, { children: renderElement({ id: "units" }) })] })] })), jsxRuntime.jsxs(ProgressBarContainer, { innerValue: innerValue, children: [jsxRuntime.jsx(ProgressBarWrapper, { children: jsxRuntime.jsx(ProgressBar, { "$width": width, "$color": color }) }), !!(hideTitle || innerValue) && jsxRuntime.jsx(ProgressInnerValue, { children: renderValue })] })] })] })) }));
10708
10882
  });
10709
10883
 
10710
10884
  const StyledSvgWidthMixin = styled.css `
@@ -10887,6 +11061,8 @@ const RoundedBackgroundContainerWrapper = styled(uilibGl.Flex).withConfig({ disp
10887
11061
  margin-top: auto;
10888
11062
  padding-top: ${innerGapOr("0.25rem")};
10889
11063
  }
11064
+
11065
+ ${bgImageHostMixin};
10890
11066
  `;
10891
11067
 
10892
11068
  const ALIAS_DEFAULT_MAX_LENGTH = 28;
@@ -10904,6 +11080,7 @@ const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, r
10904
11080
  const attributes = lodash.isEmpty(dsAttributes) ? ctxAttributes : dsAttributes;
10905
11081
  const { id, options, style, children } = elementConfig || {};
10906
11082
  const { maxLength, maxLines, wordBreak, center, fontColor, bgColor, innerTemplateStyle, inlineUnits, big, bigIcon, hideEmpty, colorAttribute, columns, innerGap } = options || {};
11083
+ const bgHost = useBgImageHost(elementConfig);
10907
11084
  const iconElement = children?.find(item => item.id === "icon");
10908
11085
  const aliasElement = children?.find(item => item.id === "alias");
10909
11086
  const unitsElement = children?.find(item => item.id === "units");
@@ -10965,7 +11142,7 @@ const RoundedBackgroundContainer = React.memo(({ type, elementConfig, feature, r
10965
11142
  const renderValue = React.useMemo(() => lodash.isNil(value) ? null : (jsxRuntime.jsxs(ContainerValue, { style: valueElement?.style, big: true, children: [value, !!unitsElement && (jsxRuntime.jsx(ContainerUnits, { style: unitsElement?.style, children: unitsContent }))] })), [valueElement?.style, value, unitsElement, unitsContent]);
10966
11143
  if (lodash.isNil(value) && hideEmpty)
10967
11144
  return null;
10968
- return (jsxRuntime.jsxs(RoundedBackgroundContainerWrapper, { id: id, "data-tile": true, style: innerTemplateStyle || style, "$center": center !== false, "$color": color, "$bgColor": bgColor, "$iconColor": iconColor, "$inlineUnits": inlineUnits, "$big": big, "$bigIcon": bigIcon, "$fillWidth": !!columns, "$innerGap": innerGap, children: [jsxRuntime.jsxs(ContainerIconValue, { children: [renderIcon, big ? renderAlias : renderValue] }), big ? renderValue : renderAlias] }));
11145
+ return (jsxRuntime.jsxs(RoundedBackgroundContainerWrapper, { id: id, "data-tile": true, style: innerTemplateStyle || style, "$center": center !== false, "$color": color, "$bgColor": bgColor, "$iconColor": iconColor, "$inlineUnits": inlineUnits, "$big": big, "$bigIcon": bigIcon, "$fillWidth": !!columns, "$innerGap": innerGap, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerIconValue, { children: [renderIcon, big ? renderAlias : renderValue] }), big ? renderValue : renderAlias] }));
10969
11146
  });
10970
11147
 
10971
11148
  const SlideshowContainer = React.memo(({ config, elementConfig, type }) => {
@@ -11004,7 +11181,7 @@ const SlideshowContainer = React.memo(({ config, elementConfig, type }) => {
11004
11181
  // Подпись `alias` не задают почти всегда — тогда обёртку не рендерим, чтобы в DOM не оставался
11005
11182
  // пустой блок, который вдобавок отъедал бы половину ширины у галереи (см. isColumn ниже).
11006
11183
  const aliasNode = render({ id: "alias" });
11007
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: render }), isVisible && (
11184
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: render }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: render }), isVisible && (
11008
11185
  // `isColumn`: подпись над галереей, а сама галерея на всю ширину. Без него Container
11009
11186
  // раскладывает alias и slideshow в ряд, и оба (Flex с `width: 100%`) сжимаются пополам —
11010
11187
  // картинка занимала лишь половину доступной ширины.
@@ -11032,21 +11209,11 @@ const DeleteRowDialog = ({ isOpen, isSourceRow, onConfirm, onCancel }) => {
11032
11209
  return (jsxRuntime.jsxs(uilibGl.Dialog, { isOpen: isOpen, onCloseRequest: onCancel, modal: true, maxWidth: "28rem", minHeight: "0", children: [jsxRuntime.jsxs(uilibGl.DialogTitle, { children: [jsxRuntime.jsx(uilibGl.ActionsGroup, { children: title }), jsxRuntime.jsx(uilibGl.ActionsGroup, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "close", onClick: onCancel }) })] }), jsxRuntime.jsx(uilibGl.DialogContent, { children: message }), jsxRuntime.jsx(uilibGl.DialogActions, { children: jsxRuntime.jsxs(uilibGl.ActionsGroup, { children: [jsxRuntime.jsx(uilibGl.FlatButton, { onClick: onCancel, children: t("actions.cancel", { ns: "common", defaultValue: "Отменить" }) }), jsxRuntime.jsx(uilibGl.RaisedButton, { error: true, onClick: onConfirm, children: t("actions.delete", { ns: "common", defaultValue: "Удалить" }) })] }) })] }));
11033
11210
  };
11034
11211
 
11035
- /**
11036
- * Панель действий: добавление строки слева, запись и откат — справа.
11037
- *
11038
- * Вторая группа прижимается к краю собственным `margin-left: auto`, а не раскладкой панели:
11039
- * родительский `Container` в режиме колонки перебивает выравнивание своих детей
11040
- * (`&&& > * { justify-content: flex-start }`), и `justify-content` здесь не сработал бы.
11041
- */
11212
+ /** Панель действий: добавление строки слева, запись и откат — справа. */
11042
11213
  const StructuredDataToolbar = styled(uilibGl.Flex).withConfig({ displayName: "StructuredDataToolbar", componentId: "sc-w4ck72" }) `
11043
11214
  flex-shrink: 0;
11044
11215
  align-items: center;
11045
11216
  gap: 0.5rem;
11046
-
11047
- > * + * {
11048
- margin-left: auto;
11049
- }
11050
11217
  `;
11051
11218
  /**
11052
11219
  * Группа кнопок панели. `width: auto` обязателен: базовый `Flex` растянут на 100%, и две
@@ -11058,6 +11225,16 @@ const StructuredDataActions = styled(uilibGl.Flex).withConfig({ displayName: "St
11058
11225
  align-items: center;
11059
11226
  gap: 0.5rem;
11060
11227
  `;
11228
+ /**
11229
+ * Откат и запись. К правому краю их прижимает собственный `margin-left: auto`, а не раскладка
11230
+ * панели: родительский `Container` в режиме колонки перебивает выравнивание своих детей
11231
+ * (`&&& > * { justify-content: flex-start }`), и `justify-content` здесь не сработал бы. Отступ
11232
+ * на самой группе, а не на соседе слева, — тогда пара стоит справа и без кнопки добавления
11233
+ * (`editOnly` у представления).
11234
+ */
11235
+ const StructuredDataSaveActions = styled(StructuredDataActions).withConfig({ displayName: "StructuredDataSaveActions", componentId: "sc-1h4vci9" }) `
11236
+ margin-left: auto;
11237
+ `;
11061
11238
  /**
11062
11239
  * Область представления. Прокручивается внутри себя, чтобы длинная таблица не растягивала
11063
11240
  * контейнер за пределы отведённой ему ячейки; `min-height: 0` разрешает flex-ребёнку сжиматься.
@@ -11065,7 +11242,7 @@ const StructuredDataActions = styled(uilibGl.Flex).withConfig({ displayName: "St
11065
11242
  * Собственный бокс таблицы (`options.width`/`height` представления) живёт внутри и на эту
11066
11243
  * прокрутку не влияет: он ограничивает саму таблицу, а не отведённое контейнером место.
11067
11244
  */
11068
- const StructuredDataView = styled(uilibGl.Flex).withConfig({ displayName: "StructuredDataView", componentId: "sc-1ws3t0d" }) `
11245
+ const StructuredDataView = styled(uilibGl.Flex).withConfig({ displayName: "StructuredDataView", componentId: "sc-zyw8uj" }) `
11069
11246
  flex-direction: column;
11070
11247
  min-height: 0;
11071
11248
  overflow: auto;
@@ -11399,7 +11576,8 @@ const useStructuredDataSchema = (type, elementConfig) => {
11399
11576
  * Оркестратор контейнера: собирает схему, черновик и запись в одно состояние экрана.
11400
11577
  *
11401
11578
  * Правку открывает `options.editMode`: не задан или `false` — таблица целиком на чтение, без
11402
- * редакторов ячеек, добавления, удаления и кнопок сохранения.
11579
+ * редакторов ячеек, добавления, удаления и кнопок сохранения. Состав строк закрывается отдельно:
11580
+ * с `editOnly` у представления правка ячеек остаётся, а добавление и удаление уходят.
11403
11581
  *
11404
11582
  * Вид источника на права правки не влияет — от него зависит только адресат «Сохранить». Слой
11405
11583
  * принимает запись через features-API, источник без `layerName` (EQL, python-скрипт, внешний
@@ -11433,6 +11611,10 @@ const useStructuredData = (type, elementConfig) => {
11433
11611
  const loading = hasDataSource && (!dataSource || dataSource.features === undefined);
11434
11612
  const hasError = hasDataSource && dataSource?.features === null;
11435
11613
  const canEdit = !!editMode;
11614
+ // `editOnly` объявлен у представления, а кнопку добавления рисует контейнер — поэтому опцию
11615
+ // разбирает он один и раздаёт готовые права: кнопке — сюда, колонке удаления — в контекст.
11616
+ const editOnly = React.useMemo(() => !!elementConfig?.children?.find(({ id }) => id === STRUCTURED_DATA_VIEW_SLOT)?.options?.editOnly, [elementConfig?.children]);
11617
+ const canChangeRows = canEdit && !editOnly;
11436
11618
  const onSave = React.useCallback(async () => {
11437
11619
  const savedRows = await save(rows);
11438
11620
  if (savedRows) {
@@ -11455,9 +11637,10 @@ const useStructuredData = (type, elementConfig) => {
11455
11637
  rows: visibleRows,
11456
11638
  loading,
11457
11639
  canEdit,
11640
+ canDelete: canChangeRows,
11458
11641
  onCellChange: changeCell,
11459
11642
  onRowDelete,
11460
- }), [canEdit, changeCell, loading, onRowDelete, schema, visibleRows]);
11643
+ }), [canChangeRows, canEdit, changeCell, loading, onRowDelete, schema, visibleRows]);
11461
11644
  return {
11462
11645
  contextValue,
11463
11646
  dirty,
@@ -11465,6 +11648,7 @@ const useStructuredData = (type, elementConfig) => {
11465
11648
  loading,
11466
11649
  hasError,
11467
11650
  canEdit,
11651
+ canAdd: canChangeRows,
11468
11652
  isDeleteConfirmOpen: !!deletingKey,
11469
11653
  isDeletingSourceRow,
11470
11654
  onAddRow: addRow,
@@ -11485,11 +11669,11 @@ const useStructuredData = (type, elementConfig) => {
11485
11669
  const StructuredDataContainer = React.memo(({ type, elementConfig, isVisible, renderElement }) => {
11486
11670
  const { t } = useGlobalContext();
11487
11671
  const { root, body } = useContainerRoot({ elementConfig });
11488
- const { contextValue, dirty, saving, hasError, canEdit, isDeleteConfirmOpen, isDeletingSourceRow, onAddRow, onCancel, onSave, onDeleteConfirm, onDeleteCancel, } = useStructuredData(type, elementConfig);
11672
+ const { contextValue, dirty, saving, hasError, canEdit, canAdd, isDeleteConfirmOpen, isDeletingSourceRow, onAddRow, onCancel, onSave, onDeleteConfirm, onDeleteCancel, } = useStructuredData(type, elementConfig);
11489
11673
  if (hasError) {
11490
11674
  return jsxRuntime.jsx(DataSourceError, { name: elementConfig?.templateName });
11491
11675
  }
11492
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [jsxRuntime.jsx(StructuredDataView, { children: jsxRuntime.jsx(StructuredDataContext.Provider, { value: contextValue, children: renderElement({ id: STRUCTURED_DATA_VIEW_SLOT }) }) }), canEdit && (jsxRuntime.jsxs(StructuredDataToolbar, { children: [jsxRuntime.jsx(StructuredDataActions, { children: jsxRuntime.jsx(AddButtonRow, { kind: "feature_add", tabIndex: 0, disabled: saving, onClick: onAddRow, children: t("actions.add", { ns: "common", defaultValue: "Добавить" }) }) }), dirty && (jsxRuntime.jsxs(StructuredDataActions, { children: [jsxRuntime.jsx(uilibGl.IconButton, { error: true, kind: "close", tabIndex: 0, disabled: saving, title: t("actions.cancel", { ns: "common", defaultValue: "Отменить" }), onClick: onCancel }), jsxRuntime.jsx(uilibGl.IconButton, { primary: true, kind: "success", tabIndex: 0, disabled: saving, title: t("actions.save", { ns: "common", defaultValue: "Сохранить" }), onClick: onSave })] }))] }))] })), jsxRuntime.jsx(DeleteRowDialog, { isOpen: isDeleteConfirmOpen, isSourceRow: isDeletingSourceRow, onConfirm: onDeleteConfirm, onCancel: onDeleteCancel })] }));
11676
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [jsxRuntime.jsx(StructuredDataView, { children: jsxRuntime.jsx(StructuredDataContext.Provider, { value: contextValue, children: renderElement({ id: STRUCTURED_DATA_VIEW_SLOT }) }) }), canEdit && (canAdd || dirty) && (jsxRuntime.jsxs(StructuredDataToolbar, { children: [canAdd && (jsxRuntime.jsx(StructuredDataActions, { children: jsxRuntime.jsx(AddButtonRow, { kind: "feature_add", tabIndex: 0, disabled: saving, onClick: onAddRow, children: t("actions.add", { ns: "common", defaultValue: "Добавить" }) }) })), dirty && (jsxRuntime.jsxs(StructuredDataSaveActions, { children: [jsxRuntime.jsx(uilibGl.IconButton, { error: true, kind: "close", tabIndex: 0, disabled: saving, title: t("actions.cancel", { ns: "common", defaultValue: "Отменить" }), onClick: onCancel }), jsxRuntime.jsx(uilibGl.IconButton, { primary: true, kind: "success", tabIndex: 0, disabled: saving, title: t("actions.save", { ns: "common", defaultValue: "Сохранить" }), onClick: onSave })] }))] }))] })), jsxRuntime.jsx(DeleteRowDialog, { isOpen: isDeleteConfirmOpen, isSourceRow: isDeletingSourceRow, onConfirm: onDeleteConfirm, onCancel: onDeleteCancel })] }));
11493
11677
  });
11494
11678
 
11495
11679
  const TabAnchor = styled.div.withConfig({ displayName: "TabAnchor", componentId: "sc-emqf31" }) `
@@ -11568,13 +11752,19 @@ const SwiperContainer = styled.div.withConfig({ displayName: "SwiperContainer",
11568
11752
  .swiper-wrapper {
11569
11753
  display: flex;
11570
11754
  }
11755
+
11756
+ ${bgImageHostMixin};
11571
11757
  `;
11572
11758
 
11573
- const TabsContainer = React.memo(({ elementConfig, type }) => {
11759
+ const TabsContainer = React.memo(({ elementConfig, type, renderElement }) => {
11574
11760
  const { palette } = styled.useTheme();
11575
11761
  const { selectedTabId, setSelectedTabId } = useWidgetContext(type);
11576
- const { id, options, style, children: tabs } = elementConfig || {};
11762
+ const { id, options, style, children } = elementConfig || {};
11577
11763
  const { radius, column, bgColor, noBg, onlyIcon, shownItems, maxLength = 12, wordBreak } = options || {};
11764
+ // Дети таба — перечисляемые сущности, каждый ребёнок становится вкладкой. Слот фона к ним не
11765
+ // относится: без фильтра он превратился бы в лишнюю пустую вкладку и занял `tabs[0]`.
11766
+ const tabs = React.useMemo(() => (children ?? []).filter(({ id: childId }) => childId !== BG_IMAGE_SLOT_ID), [children]);
11767
+ const bgHost = useBgImageHost(elementConfig);
11578
11768
  const renderIcon = React.useCallback((icon, active) => {
11579
11769
  if (!icon)
11580
11770
  return null;
@@ -11591,7 +11781,7 @@ const TabsContainer = React.memo(({ elementConfig, type }) => {
11591
11781
  setSelectedTabId(tabs[0].id);
11592
11782
  }
11593
11783
  }, []);
11594
- return (jsxRuntime.jsx(SwiperContainer, { id: id, style: style, children: jsxRuntime.jsx(react.Swiper, { spaceBetween: 0, slidesPerView: shownItems || 2, children: tabs.map(({ id: tabId, value, options: tabOptions }) => (jsxRuntime.jsxs(react.SwiperSlide, { children: [jsxRuntime.jsxs(TabContainer, { href: `#${tabId}`, active: selectedTabId === tabId, column: column, bgColor: bgColor, noBg: noBg, radius: radius, onlyIcon: onlyIcon, hasIcon: !!tabOptions?.icon, onClick: () => onClick(tabId), children: [renderIcon(tabOptions?.icon, selectedTabId === tabId), !onlyIcon && (jsxRuntime.jsx(TabValue, { children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength, wordBreak: wordBreak, children: value }) }))] }), jsxRuntime.jsx(TabAnchor, { id: tabId })] }, tabId))) }) }));
11784
+ return (jsxRuntime.jsxs(SwiperContainer, { id: id, style: style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(react.Swiper, { spaceBetween: 0, slidesPerView: shownItems || 2, children: tabs.map(({ id: tabId, value, options: tabOptions }) => (jsxRuntime.jsxs(react.SwiperSlide, { children: [jsxRuntime.jsxs(TabContainer, { href: `#${tabId}`, active: selectedTabId === tabId, column: column, bgColor: bgColor, noBg: noBg, radius: radius, onlyIcon: onlyIcon, hasIcon: !!tabOptions?.icon, onClick: () => onClick(tabId), children: [renderIcon(tabOptions?.icon, selectedTabId === tabId), !onlyIcon && (jsxRuntime.jsx(TabValue, { children: jsxRuntime.jsx(TextTrim, { maxLength: maxLength, wordBreak: wordBreak, children: value }) }))] }), jsxRuntime.jsx(TabAnchor, { id: tabId })] }, tabId))) })] }));
11595
11785
  });
11596
11786
 
11597
11787
  const SvgContainerColorMixin = styled.css `
@@ -11721,6 +11911,7 @@ const TitleContainer = React.memo(({ containerId, templateName, layerNames, font
11721
11911
  const { id, style, options } = elementConfig || {};
11722
11912
  const { simple, downloadById, align } = options || {};
11723
11913
  const isLayers = templateName === exports.ContainerTemplate.Layers;
11914
+ const bgHost = useBgImageHost(elementConfig);
11724
11915
  const { onExport } = useExportPdf(downloadById);
11725
11916
  const onClick = React.useCallback(() => {
11726
11917
  if (!expandable)
@@ -11736,13 +11927,14 @@ const TitleContainer = React.memo(({ containerId, templateName, layerNames, font
11736
11927
  const renderVisibility = React.useMemo(() => isLayers && (jsxRuntime.jsx(uilibGl.FlexSpan, { mr: "-1rem", children: jsxRuntime.jsx(uilibGl.IconToggle, { kind: layersVisibility ? "password_show" : "password_hide", className: "feature-visible", isSelected: layersVisibility, onClick: onToggleVisibility }) })), [isLayers, layersVisibility, onToggleVisibility]);
11737
11928
  const renderToggler = React.useMemo(() => !!containerId &&
11738
11929
  expandable && (jsxRuntime.jsx("div", { children: jsxRuntime.jsx(uilibGl.LegendToggler, { color: palette.icon, toggled: expandedContainers?.[containerId] !== undefined ? expandedContainers[containerId] : expanded, onClick: onClick }) })), [containerId, expandable, expanded, expandedContainers, onClick, palette.icon]);
11739
- return (jsxRuntime.jsx(Container, { id: id, style: style, isTitle: isVisible, children: jsxRuntime.jsxs(ContainerTitle, { simple: simple, "$align": align, children: [jsxRuntime.jsxs(ContainerIconTitle, { fontColor: fontColor, children: [renderElement({ id: "titleIcon", wrap: false }), renderElement({ id: "title" }), !!downloadById && (jsxRuntime.jsx(uilibGl.IconButton, { kind: "download", onClick: onExport })), isLayers && renderToggler] }), !isLayers && renderToggler, renderVisibility] }) }));
11930
+ return (jsxRuntime.jsxs(Container, { id: id, style: style, isTitle: isVisible, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerTitle, { simple: simple, "$align": align, children: [jsxRuntime.jsxs(ContainerIconTitle, { fontColor: fontColor, children: [renderElement({ id: "titleIcon", wrap: false }), renderElement({ id: "title" }), !!downloadById && (jsxRuntime.jsx(uilibGl.IconButton, { kind: "download", onClick: onExport })), isLayers && renderToggler] }), !isLayers && renderToggler, renderVisibility] })] }));
11740
11931
  });
11741
11932
 
11742
11933
  const TwoColumnContainer = React.memo(({ elementConfig, type, renderElement }) => {
11743
11934
  const { width, height, overflow } = elementConfig?.options || {};
11744
11935
  const templateName = elementConfig?.templateName;
11745
- const renderBody = React.useCallback(({ id, value, style, hasIcon, hasUnits, render }) => (jsxRuntime.jsxs(TwoColumnContainerWrapper, { id: id, "data-templatename": templateName, style: style, "$sizeCss": getWrapperSizeStyle({ style, width, height, overflow, defaultWidth: FILL_SIZE }), children: [jsxRuntime.jsxs(ContainerAlias, { children: [hasIcon && (jsxRuntime.jsx(ContainerAliasIcon, { children: render({ id: "icon" }) })), render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxRuntime.jsxs(ContainerValue, { big: true, children: [value, hasUnits && (jsxRuntime.jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName]);
11936
+ const bgHost = useBgImageHost(elementConfig);
11937
+ const renderBody = React.useCallback(({ id, value, style, hasIcon, hasUnits, render }) => (jsxRuntime.jsxs(TwoColumnContainerWrapper, { id: id, "data-templatename": templateName, style: style, "$sizeCss": getWrapperSizeStyle({ style, width, height, overflow, defaultWidth: FILL_SIZE }), ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: render }), jsxRuntime.jsxs(ContainerAlias, { children: [hasIcon && (jsxRuntime.jsx(ContainerAliasIcon, { children: render({ id: "icon" }) })), render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxRuntime.jsxs(ContainerValue, { big: true, children: [value, hasUnits && (jsxRuntime.jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName, bgHost, elementConfig]);
11746
11938
  const { renderContainer, attributesToRender } = useRenderContainer({
11747
11939
  type,
11748
11940
  elementConfig,
@@ -11778,7 +11970,7 @@ const UploadContainer = React.memo(({ type, elementConfig, renderElement }) => {
11778
11970
  const { expandable, expanded } = options || {};
11779
11971
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
11780
11972
  const { root, body } = useContainerRoot({ elementConfig });
11781
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(UploadContainerWrapper, { ...body, children: renderElement({ id: "uploader", wrap: false }) }))] }));
11973
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(UploadContainerWrapper, { ...body, children: renderElement({ id: "uploader", wrap: false }) }))] }));
11782
11974
  });
11783
11975
 
11784
11976
  const ExpandableTitle = React.memo(({ elementConfig, type, renderElement }) => {
@@ -11822,7 +12014,7 @@ const GridGroupView = React.memo(({ elementConfig, type, renderElement }) => {
11822
12014
  elementConfig,
11823
12015
  defaults: autoHeight ? GRID_AUTO_FILL_DEFAULTS : GRID_FILL_DEFAULTS,
11824
12016
  });
11825
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(GridTracks, { node: elementConfig, axis: "row", body: body, gap: gap, renderElement: renderElement }))] }));
12017
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(GridTracks, { node: elementConfig, axis: "row", body: body, gap: gap, renderElement: renderElement }))] }));
11826
12018
  });
11827
12019
 
11828
12020
  /** На сколько частей делит `split`. */
@@ -12395,12 +12587,13 @@ const ContainersGroupContainer = React.memo(props => {
12395
12587
  return jsxRuntime.jsx(FlowGroup, { ...props });
12396
12588
  });
12397
12589
 
12398
- const ExportPdfContainer = React.memo(({ type, elementConfig }) => {
12590
+ const ExportPdfContainer = React.memo(({ type, elementConfig, renderElement }) => {
12399
12591
  const { t } = useGlobalContext();
12400
12592
  const { loading, onExport } = useExportPdf(getRootElementId(type));
12401
12593
  const { id, style, options } = elementConfig || {};
12402
12594
  const { icon, title } = options || {};
12403
- return (jsxRuntime.jsx(Container, { id: id, style: style, children: jsxRuntime.jsx(uilibGl.IconButton, { kind: icon || "download", primary: true, disabled: loading, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) }) }));
12595
+ const bgHost = useBgImageHost(elementConfig);
12596
+ return (jsxRuntime.jsxs(Container, { id: id, style: style, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(uilibGl.IconButton, { kind: icon || "download", primary: true, disabled: loading, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) })] }));
12404
12597
  });
12405
12598
 
12406
12599
  const StatusBadge = styled(uilibGl.Chip).withConfig({ displayName: "StatusBadge", componentId: "sc-1xmfl10" }) `
@@ -12660,12 +12853,12 @@ const TaskContainer = React.memo(({ type, elementConfig, renderElement }) => {
12660
12853
  return runTask({ resourceId, parameters: newParams, script, fileName, methodName });
12661
12854
  }));
12662
12855
  }, [attributes, currentPage.filters, dataSources, ewktGeometry, layerInfo, projectDataSources, relatedResources, runTask, selectedFilters, stopTask, taskId]);
12663
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(TaskContainerWrapper, { ...body, justifyContent: center ? "center" : "flex-start", children: [jsxRuntime.jsx(StatusWaitingButton, { title: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }), icon: icon, status: status, statusColors: statusColors, isWaiting: loading || !!taskId, isDisabled: !relatedResources?.length, onClick: onClick }), !!(log || taskId) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.IconButton, { kind: "info", onClick: openLog }), jsxRuntime.jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: onCloseLog, onMinimize: useNotifications ? onMinimizeLog : undefined })] }))] })] }));
12856
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(TaskContainerWrapper, { ...body, justifyContent: center ? "center" : "flex-start", children: [jsxRuntime.jsx(StatusWaitingButton, { title: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }), icon: icon, status: status, statusColors: statusColors, isWaiting: loading || !!taskId, isDisabled: !relatedResources?.length, onClick: onClick }), !!(log || taskId) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(uilibGl.IconButton, { kind: "info", onClick: openLog }), jsxRuntime.jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: onCloseLog, onMinimize: useNotifications ? onMinimizeLog : undefined })] }))] })] }));
12664
12857
  });
12665
12858
 
12666
12859
  const EditContainer = ({ type, elementConfig, renderElement }) => {
12667
12860
  const { root, body } = useContainerRoot({ elementConfig });
12668
- return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value" }) })] })] }));
12861
+ return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsxs(Container, { ...body, isColumn: true, children: [jsxRuntime.jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsxRuntime.jsx(ContainerValue, { children: renderElement({ id: "value" }) })] })] }));
12669
12862
  };
12670
12863
 
12671
12864
  const getControlTemplateName = (type) => {
@@ -12686,6 +12879,8 @@ const EditGroupContainer = React.memo(({ type, elementConfig, renderElement }) =
12686
12879
  const { config, attributes, layerInfo, expandedContainers } = useWidgetContext(type);
12687
12880
  const { filteredAttributes, filteredControls } = useEditGroupAttributes({ elementConfig, type });
12688
12881
  const getRenderContainerItem = useRenderContainerItem(type, renderElement);
12882
+ const bgHost = useBgImageHost(elementConfig);
12883
+ const needsHost = !!bgHost.$hasBgImage || !!bgHost.$innerPadding;
12689
12884
  const renderContainer = React.useCallback((attributeName) => {
12690
12885
  const control = filteredControls?.find(({ targetAttributeName }) => targetAttributeName === attributeName);
12691
12886
  const itemAttribute = attributes.find(item => item.attributeName === attributeName);
@@ -12694,7 +12889,11 @@ const EditGroupContainer = React.memo(({ type, elementConfig, renderElement }) =
12694
12889
  : getTemplateNameFromAttribute(itemAttribute);
12695
12890
  const itemConfig = {
12696
12891
  ...elementConfig,
12697
- children: elementConfig.children.map(child => ({
12892
+ // Слот фона принадлежит самой группе и в клон поля не уходит: иначе одна и та же
12893
+ // картинка легла бы фоном под КАЖДОЕ поле группы.
12894
+ children: elementConfig.children
12895
+ .filter(({ id: childId }) => childId !== BG_IMAGE_SLOT_ID)
12896
+ .map(child => ({
12698
12897
  ...child,
12699
12898
  attributeName,
12700
12899
  })),
@@ -12717,10 +12916,15 @@ const EditGroupContainer = React.memo(({ type, elementConfig, renderElement }) =
12717
12916
  layerInfo,
12718
12917
  expandedContainers,
12719
12918
  ]);
12720
- if (!filteredControls?.length) {
12721
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: filteredAttributes.map(({ attributeName }) => renderContainer(attributeName)) }));
12722
- }
12723
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: filteredControls.map(({ targetAttributeName }) => renderContainer(targetAttributeName)) }));
12919
+ const fields = React.useMemo(() => !filteredControls?.length
12920
+ ? filteredAttributes.map(({ attributeName }) => renderContainer(attributeName))
12921
+ : filteredControls.map(({ targetAttributeName }) => renderContainer(targetAttributeName)), [filteredControls, filteredAttributes, renderContainer]);
12922
+ // Как и `DefaultAttributes`, группа намеренно отдаёт НЕСКОЛЬКО корней — по одному на поле.
12923
+ // Общая обёртка появляется только под фон или `innerPadding`: без неё им не от чего
12924
+ // отсчитывать бокс.
12925
+ if (!needsHost)
12926
+ return jsxRuntime.jsx(jsxRuntime.Fragment, { children: fields });
12927
+ return (jsxRuntime.jsxs(Container, { isColumn: true, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), fields] }));
12724
12928
  });
12725
12929
 
12726
12930
  const useEditControl = (type, elementConfig) => {
@@ -12766,7 +12970,8 @@ const EditBooleanContainer = ({ type, elementConfig, renderElement, }) => {
12766
12970
  const { t } = useGlobalContext();
12767
12971
  const { value, onChange } = useEditControl(type, elementConfig);
12768
12972
  const { id, style } = elementConfig || {};
12769
- return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { children: jsxRuntime.jsx(uilibGl.Switch, { label: value
12973
+ const bgHost = useBgImageHost(elementConfig);
12974
+ return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { children: jsxRuntime.jsx(uilibGl.Switch, { label: value
12770
12975
  ? t("on", { defaultValue: "Вкл" })
12771
12976
  : t("off", { defaultValue: "Выкл" }), checked: !!value, onChange: () => onChange(!value) }) })] }));
12772
12977
  };
@@ -12780,20 +12985,23 @@ const EditStringContainer = ({ type, elementConfig, renderElement, }) => {
12780
12985
  onControlChange(String(lastSelected?.value ?? ""));
12781
12986
  setValue(lastSelected?.text ?? "");
12782
12987
  }, [onControlChange, setValue]);
12783
- return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { column: true, children: control?.relatedDataSource ? (jsxRuntime.jsx(uilibGl.AutoComplete, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: value, options: options, width: "100%", onChange: onChange, onSelect: onSelect })) : (jsxRuntime.jsx(uilibGl.Input, { value: controlValue, width: "100%", onChange: (e) => onControlChange(e.target.value) })) })] }));
12988
+ const bgHost = useBgImageHost(elementConfig);
12989
+ return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { column: true, children: control?.relatedDataSource ? (jsxRuntime.jsx(uilibGl.AutoComplete, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: value, options: options, width: "100%", onChange: onChange, onSelect: onSelect })) : (jsxRuntime.jsx(uilibGl.Input, { value: controlValue, width: "100%", onChange: (e) => onControlChange(e.target.value) })) })] }));
12784
12990
  };
12785
12991
 
12786
12992
  const EditNumberContainer = ({ type, elementConfig, renderElement, }) => {
12787
12993
  const { value, control, onChange } = useEditControl(type, elementConfig);
12788
12994
  const { id, style } = elementConfig || {};
12789
- return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsxs(ContainerValue, { column: true, children: [jsxRuntime.jsx(uilibGl.Input, { value: value?.toString(), width: "100%", onChange: (e) => onChange(e.target.value) }), jsxRuntime.jsx(uilibGl.Slider, { value: value, min: control?.minValue, max: control?.maxValue, step: control?.step, sliderWidth: "100%", primary: true, onChange: onChange })] })] }));
12995
+ const bgHost = useBgImageHost(elementConfig);
12996
+ return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsxs(ContainerValue, { column: true, children: [jsxRuntime.jsx(uilibGl.Input, { value: value?.toString(), width: "100%", onChange: (e) => onChange(e.target.value) }), jsxRuntime.jsx(uilibGl.Slider, { value: value, min: control?.minValue, max: control?.maxValue, step: control?.step, sliderWidth: "100%", primary: true, onChange: onChange })] })] }));
12790
12997
  };
12791
12998
 
12792
12999
  const EditDropdownContainer = ({ type, elementConfig, renderElement, }) => {
12793
13000
  const { value, control, items, onChange } = useEditControl(type, elementConfig);
12794
13001
  const { id, style } = elementConfig || {};
12795
13002
  const optionsList = React.useMemo(() => items.map(item => ({ text: item, value: item })), [items]);
12796
- return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { column: true, children: jsxRuntime.jsx(uilibGl.Dropdown, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, label: control?.label, placeholder: control?.placeholder, options: optionsList, value: value, width: `${control?.width ?? DEFAULT_DROPDOWN_WIDTH}px`, onChange: ([option]) => onChange(option.value) }) })] }));
13003
+ const bgHost = useBgImageHost(elementConfig);
13004
+ return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { column: true, children: jsxRuntime.jsx(uilibGl.Dropdown, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, label: control?.label, placeholder: control?.placeholder, options: optionsList, value: value, width: `${control?.width ?? DEFAULT_DROPDOWN_WIDTH}px`, onChange: ([option]) => onChange(option.value) }) })] }));
12797
13005
  };
12798
13006
 
12799
13007
  const CheckboxWrapper = styled(ContainerValue).withConfig({ displayName: "CheckboxWrapper", componentId: "sc-169umb6" }) `
@@ -12818,13 +13026,15 @@ const ChipsWrapper = styled(ContainerValue).withConfig({ displayName: "ChipsWrap
12818
13026
  const EditChipsContainer = ({ type, elementConfig, renderElement, }) => {
12819
13027
  const { value, items, onChange } = useEditControl(type, elementConfig);
12820
13028
  const { id, style } = elementConfig || {};
12821
- return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ChipsWrapper, { children: items.map(item => (jsxRuntime.jsx(uilibGl.Chip, { text: item, primary: value === item, onClick: () => onChange(item) }, item))) })] }));
13029
+ const bgHost = useBgImageHost(elementConfig);
13030
+ return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ChipsWrapper, { children: items.map(item => (jsxRuntime.jsx(uilibGl.Chip, { text: item, primary: value === item, onClick: () => onChange(item) }, item))) })] }));
12822
13031
  };
12823
13032
 
12824
13033
  const EditCheckboxContainer = ({ type, elementConfig, renderElement, }) => {
12825
13034
  const { value, items, onChange } = useEditControl(type, elementConfig);
12826
13035
  const { id, style } = elementConfig || {};
12827
- return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(CheckboxWrapper, { children: items.map(item => (jsxRuntime.jsx(uilibGl.Checkbox, { label: item, checked: item === value, onChange: () => onChange(item) }, item))) })] }));
13036
+ const bgHost = useBgImageHost(elementConfig);
13037
+ return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(CheckboxWrapper, { children: items.map(item => (jsxRuntime.jsx(uilibGl.Checkbox, { label: item, checked: item === value, onChange: () => onChange(item) }, item))) })] }));
12828
13038
  };
12829
13039
 
12830
13040
  const EditDateContainer = ({ type, elementConfig, renderElement, }) => {
@@ -12834,7 +13044,8 @@ const EditDateContainer = ({ type, elementConfig, renderElement, }) => {
12834
13044
  const { withTime } = options || {};
12835
13045
  const dateValue = React.useMemo(() => (value ? new Date(value) : undefined), [value]);
12836
13046
  const handleChange = React.useCallback((date) => onChange(date.toISOString()), [onChange]);
12837
- return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { column: true, children: jsxRuntime.jsx(uilibGl.DatePicker, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: dateValue, locale: uilibGl.getLocale(language), withTime: withTime ?? false, withHeader: true, width: "100%", onChange: handleChange }) })] }));
13047
+ const bgHost = useBgImageHost(elementConfig);
13048
+ return (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxRuntime.jsx(ContainerValue, { column: true, children: jsxRuntime.jsx(uilibGl.DatePicker, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: dateValue, locale: uilibGl.getLocale(language), withTime: withTime ?? false, withHeader: true, width: "100%", onChange: handleChange }) })] }));
12838
13049
  };
12839
13050
 
12840
13051
  const AddButton = ({ multiple = true, accept, onSelectFiles, onSelectFromCatalog, onSelectFromLink, }) => {
@@ -12978,6 +13189,7 @@ const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement
12978
13189
  const [uploading, setUploading] = React.useState(false);
12979
13190
  const [isLinkDialogOpen, , setLinkDialogOpen] = useToggle(false);
12980
13191
  const previewImages = useAttachmentPreviewImages({ items, active: previewIndex !== null });
13192
+ const bgHost = useBgImageHost(elementConfig);
12981
13193
  const persist = React.useCallback((next) => onChange(next), [onChange]);
12982
13194
  const handlePreview = React.useCallback((link) => {
12983
13195
  const idx = items.findIndex(item => item.link === link);
@@ -13035,7 +13247,7 @@ const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement
13035
13247
  setUploading(false);
13036
13248
  }
13037
13249
  }, [api, items, parentResourceId, persist]);
13038
- return (jsxRuntime.jsxs(AttachmentsContainer, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), jsxRuntime.jsx(AddButton, { accept: fileExtensions, onSelectFiles: uploading ? () => undefined : handleUpload, onSelectFromCatalog: handleSelectFromCatalog, onSelectFromLink: handleOpenLinkDialog }), jsxRuntime.jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: handleCloseLinkDialog, onSubmit: handleAddByLink }), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview }, previewIndex))] }));
13250
+ return (jsxRuntime.jsxs(AttachmentsContainer, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), jsxRuntime.jsx(AddButton, { accept: fileExtensions, onSelectFiles: uploading ? () => undefined : handleUpload, onSelectFromCatalog: handleSelectFromCatalog, onSelectFromLink: handleOpenLinkDialog }), jsxRuntime.jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: handleCloseLinkDialog, onSubmit: handleAddByLink }), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview }, previewIndex))] }));
13039
13251
  });
13040
13252
 
13041
13253
  // `ProgressContainer` и `RoundedBackgroundContainer` исторически принимают `InnerContainerProps`
@@ -13473,88 +13685,222 @@ const AlertIconContainer = styled(uilibGl.Flex).withConfig({ displayName: "Alert
13473
13685
  width: 2rem;
13474
13686
  height: 2rem;
13475
13687
 
13476
- ${uilibGl.Icon} {
13477
- :after {
13478
- color: ${({ theme: { palette } }) => palette.error};
13688
+ ${uilibGl.Icon} {
13689
+ :after {
13690
+ color: ${({ theme: { palette } }) => palette.error};
13691
+ }
13692
+ }
13693
+ `;
13694
+
13695
+ var img$3 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3cpath d='M20.248 9.67787C18.5318 8.04035 15.9473 7.54977 13.7024 8.43543C11.4576 9.32109 9.99566 11.4081 10 13.721C10 18.2894 16 24 16 24C16 24 22 18.2894 22 13.721C22.0028 12.2054 21.3726 10.7509 20.248 9.67787Z' fill='url(%23paint0_linear_6459_10338)'/%3e %3ccircle cx='16' cy='14' r='2' fill='white'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10338' x1='10' y1='8' x2='25.36' y2='19.52' gradientUnits='userSpaceOnUse'%3e %3cstop stop-color='%230084D6'/%3e %3cstop offset='0.489583' stop-color='%230084D6'/%3e %3cstop offset='0.489683' stop-color='%2305A9FF'/%3e %3cstop offset='0.921875' stop-color='%2305A9FF'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
13696
+
13697
+ var img$2 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3cpath d='M4 17.9574H10.1538L13.5385 12L18.4615 20L22 13.8723H28' stroke='url(%23paint0_linear_6459_10369)' stroke-width='2' stroke-linejoin='round'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10369' x1='4' y1='9.54167' x2='28.7229' y2='20.1484' gradientUnits='userSpaceOnUse'%3e %3cstop offset='0.525942' stop-color='%2306AAFF'/%3e %3cstop offset='0.526042' stop-color='%230184D7'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
13698
+
13699
+ var img$1 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3crect x='8' y='8' width='16' height='16' rx='2' fill='url(%23paint0_linear_6459_10399)'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10399' x1='8' y1='8' x2='24' y2='24' gradientUnits='userSpaceOnUse'%3e %3cstop stop-color='%230084D6'/%3e %3cstop offset='0.489583' stop-color='%230084D6'/%3e %3cstop offset='0.489683' stop-color='%2305A9FF'/%3e %3cstop offset='0.921875' stop-color='%2305A9FF'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
13700
+
13701
+ var img = "data:image/svg+xml,%3csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 24 24' style='enable-background:new 0 0 24 24%3b' xml:space='preserve'%3e %3cstyle type='text/css'%3e .st0%7bfill:%23AEC46F%3b%7d %3c/style%3e %3cg%3e %3cpath class='st0' d='M19%2c4H5C4.4%2c4%2c4%2c4.4%2c4%2c5v14c0%2c0.6%2c0.4%2c1%2c1%2c1h14c0.6%2c0%2c1-0.4%2c1-1V5C20%2c4.4%2c19.6%2c4%2c19%2c4z M6%2c7.5h2.8l-0.7%2c2H6 V7.5z M6%2c13h5v5h-0.4c-0.3-2.4-2.2-4.3-4.6-4.6V13z M18%2c11h-4.3L18%2c6.7V11z M13%2c10.3V6h4.3L13%2c10.3z M17.9%2c13c-0.5%2c1-1.6%2c1.7-3%2c1.7 H13V13H17.9z M13%2c15.7h1.7c0.1%2c0.9%2c0.5%2c1.7%2c1%2c2.3H13V15.7z M15.7%2c15.6c0.9-0.2%2c1.7-0.6%2c2.3-1.2V18h-0.7 C16.5%2c17.6%2c15.9%2c16.7%2c15.7%2c15.6z M11%2c6v5H6v-0.5h2.5c0.2%2c0%2c0.4-0.1%2c0.5-0.3l1-3c0-0.2%2c0-0.4-0.1-0.5C9.8%2c6.6%2c9.7%2c6.5%2c9.5%2c6.5H6V6 H11z M6%2c14.4c1.8%2c0.3%2c3.3%2c1.8%2c3.6%2c3.6H6V14.4z'/%3e %3c/g%3e%3c/svg%3e";
13702
+
13703
+ const LayerIcon = ({ layerInfo, error, innerRef }) => {
13704
+ const geometryType = layerInfo?.configuration?.geometryType;
13705
+ const renderSymbol = React.useMemo(() => {
13706
+ if (layerInfo?.configuration?.layerType === api.LayerServiceType.RemoteTileLayerService) {
13707
+ return jsxRuntime.jsx("img", { src: img, alt: "" });
13708
+ }
13709
+ if (!geometryType || error) {
13710
+ return (jsxRuntime.jsx(AlertIconContainer, { children: jsxRuntime.jsx(uilibGl.Icon, { kind: "warning" }) }));
13711
+ }
13712
+ switch (geometryType) {
13713
+ case api.OgcGeometryType.Point:
13714
+ case api.OgcGeometryType.MultiPoint:
13715
+ return jsxRuntime.jsx("img", { src: img$3, alt: "" });
13716
+ case api.OgcGeometryType.Polygon:
13717
+ case api.OgcGeometryType.MultiPolygon:
13718
+ return jsxRuntime.jsx("img", { src: img$1, alt: "" });
13719
+ case api.OgcGeometryType.LineString:
13720
+ case api.OgcGeometryType.MultiLineString:
13721
+ return jsxRuntime.jsx("img", { src: img$2, alt: "" });
13722
+ default:
13723
+ return jsxRuntime.jsx("img", { src: img$3, alt: "" });
13724
+ }
13725
+ }, [error, geometryType, layerInfo?.configuration?.layerType]);
13726
+ return jsxRuntime.jsx(LayerIconContainer, { ref: innerRef, children: renderSymbol });
13727
+ };
13728
+
13729
+ const LayerIconClickable = styled.div.withConfig({ displayName: "LayerIconClickable", componentId: "sc-1o3bms0" }) `
13730
+ display: flex;
13731
+ align-items: center;
13732
+ cursor: pointer;
13733
+ `;
13734
+ const NoFeatureIcon = styled.div.withConfig({ displayName: "NoFeatureIcon", componentId: "sc-sxo6af" }) `
13735
+ display: flex;
13736
+ align-items: center;
13737
+ justify-content: center;
13738
+ min-width: 1.5rem;
13739
+ height: 1.5rem;
13740
+ margin-top: 0.25rem;
13741
+ margin-right: 1rem;
13742
+ margin-left: 0.25rem;
13743
+
13744
+ ${uilibGl.Icon}::after {
13745
+ font-size: 1.5rem;
13746
+ color: ${({ theme: { palette } }) => palette.iconDisabled};
13747
+ }
13748
+ `;
13749
+
13750
+ const HeaderLayerIcon = ({ noFeature }) => {
13751
+ const { t } = useGlobalContext();
13752
+ const { layerInfo, feature } = useWidgetContext(exports.WidgetType.FeatureCard);
13753
+ const zoomToFeatures = useZoomToFeatures();
13754
+ const getMaxZoomTo = useMaxZoomTo();
13755
+ const [optionsMaxZoomTo, layerMaxZoomTo] = React.useMemo(() => getMaxZoomTo(layerInfo?.name), [layerInfo?.name, getMaxZoomTo]);
13756
+ const handleIconClick = React.useCallback(() => zoomToFeatures([feature], { maxZoom: layerMaxZoomTo ?? optionsMaxZoomTo }), [zoomToFeatures, feature, layerMaxZoomTo, optionsMaxZoomTo]);
13757
+ if (noFeature) {
13758
+ return (jsxRuntime.jsx(NoFeatureIcon, { children: jsxRuntime.jsx(uilibGl.Icon, { kind: "no_geom" }) }));
13759
+ }
13760
+ return (jsxRuntime.jsx(LayerIconClickable, { onClick: handleIconClick, children: jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard", defaultValue: "Приблизить к объекту" }), delay: [600, 0], children: ref => (jsxRuntime.jsx(LayerIcon, { innerRef: ref, layerInfo: layerInfo })) }) }));
13761
+ };
13762
+
13763
+ const FeatureCardDefaultHeader = ({ noFeature }) => {
13764
+ const { themeName: pageThemeName } = useGlobalContext();
13765
+ const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
13766
+ const { header } = config || {};
13767
+ const { options } = header || {};
13768
+ const { themeName, withPadding, column, height, overlay } = options || {};
13769
+ return (jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsxRuntime.jsx(DefaultHeaderWrapper, { withPadding: withPadding, height: height, "$noFeature": noFeature, children: jsxRuntime.jsx(Header, { "$overlay": overlay, "$isRow": !column, "$noFeature": noFeature, children: jsxRuntime.jsxs(HeaderFrontView, { isDefault: !column, children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(HeaderLayerIcon, { noFeature: noFeature }), jsxRuntime.jsx(HeaderTitle, { noFeature: noFeature })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }) }) }) }));
13770
+ };
13771
+
13772
+ const HeaderWrapperMixin = styled.css `
13773
+ ${Header} {
13774
+ min-height: 5.25rem;
13775
+ }
13776
+
13777
+ ${HeaderContainer} {
13778
+ max-width: 100%;
13779
+ width: 100%;
13780
+ }
13781
+
13782
+ ${FeatureControls} {
13783
+ max-width: calc(100% - 2rem);
13784
+ width: calc(100% - 2rem);
13785
+ margin-top: -0.5rem;
13786
+ padding-top: 1rem;
13787
+ border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
13788
+ }
13789
+
13790
+ ${({ $fontColor }) => !!$fontColor && HeaderFontColorMixin};
13791
+ `;
13792
+ const HeaderIcon = styled(uilibGl.Flex).withConfig({ displayName: "HeaderIcon", componentId: "sc-1y7xqr9" }) `
13793
+ position: absolute;
13794
+ top: 0;
13795
+ right: 0;
13796
+ align-items: center;
13797
+ justify-content: center;
13798
+ width: 7.625rem;
13799
+ height: 100%;
13800
+
13801
+ span[kind] {
13802
+ width: 4rem;
13803
+
13804
+ :after {
13805
+ font-size: 4rem;
13806
+ color: rgba(255, 255, 255, 0.36);
13807
+ }
13808
+ }
13809
+
13810
+ span[kind]:after,
13811
+ path,
13812
+ line,
13813
+ circle {
13814
+ fill: rgba(255, 255, 255, 0.36);
13815
+ }
13816
+
13817
+ && > * {
13818
+ display: flex;
13819
+ align-items: center;
13820
+ height: 100%;
13821
+ }
13822
+ `;
13823
+ const BigIconHeaderMixin = styled.css `
13824
+ ${HeaderIcon} {
13825
+ min-width: 14rem;
13826
+ right: -3rem;
13827
+
13828
+ span[kind]:after {
13829
+ font-size: 14rem;
13830
+ }
13831
+ }
13832
+ `;
13833
+ const WithPaddingHeaderMixin = styled.css `
13834
+ ${Header} {
13835
+ width: 100%;
13836
+ margin: -0.5rem -0.5rem 0.5rem -0.5rem;
13837
+ }
13838
+ `;
13839
+ const BottomBlurHeaderMixin = styled.css `
13840
+ ${Header} {
13841
+ margin-bottom: 0;
13842
+
13843
+ &::before {
13844
+ -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13845
+ mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13846
+ }
13847
+ }
13848
+
13849
+ ${ContainerBackgroundLayer} {
13850
+ -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13851
+ mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13852
+ }
13853
+
13854
+ ${HeaderFrontView} {
13855
+ z-index: 100;
13856
+ }
13857
+ `;
13858
+ const BackgroundHeaderWrapper = styled.div.withConfig({ displayName: "BackgroundHeaderWrapper", componentId: "sc-10iuilq" }) `
13859
+ ${Header} {
13860
+ position: relative;
13861
+ width: calc(100% + 1rem);
13862
+ height: ${({ $height }) => $height ? `${$height}px` : "auto"};
13863
+ margin: -1rem -1rem 1rem -1rem;
13864
+ border-radius: 0.5rem;
13865
+ background: transparent;
13866
+ overflow: hidden;
13867
+
13868
+ &::before {
13869
+ content: "";
13870
+ position: absolute;
13871
+ inset: 0;
13872
+ z-index: 100;
13873
+ pointer-events: none;
13874
+ background: ${({ $bgColor }) => $bgColor || "linear-gradient(96.55deg, #FFFCD3 0%, #B4DC47 100%)"};
13479
13875
  }
13480
13876
  }
13481
- `;
13482
-
13483
- var img$3 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3cpath d='M20.248 9.67787C18.5318 8.04035 15.9473 7.54977 13.7024 8.43543C11.4576 9.32109 9.99566 11.4081 10 13.721C10 18.2894 16 24 16 24C16 24 22 18.2894 22 13.721C22.0028 12.2054 21.3726 10.7509 20.248 9.67787Z' fill='url(%23paint0_linear_6459_10338)'/%3e %3ccircle cx='16' cy='14' r='2' fill='white'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10338' x1='10' y1='8' x2='25.36' y2='19.52' gradientUnits='userSpaceOnUse'%3e %3cstop stop-color='%230084D6'/%3e %3cstop offset='0.489583' stop-color='%230084D6'/%3e %3cstop offset='0.489683' stop-color='%2305A9FF'/%3e %3cstop offset='0.921875' stop-color='%2305A9FF'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
13484
-
13485
- var img$2 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3cpath d='M4 17.9574H10.1538L13.5385 12L18.4615 20L22 13.8723H28' stroke='url(%23paint0_linear_6459_10369)' stroke-width='2' stroke-linejoin='round'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10369' x1='4' y1='9.54167' x2='28.7229' y2='20.1484' gradientUnits='userSpaceOnUse'%3e %3cstop offset='0.525942' stop-color='%2306AAFF'/%3e %3cstop offset='0.526042' stop-color='%230184D7'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
13486
-
13487
- var img$1 = "data:image/svg+xml,%3csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3crect width='32' height='32' fill='transparent'/%3e %3crect x='8' y='8' width='16' height='16' rx='2' fill='url(%23paint0_linear_6459_10399)'/%3e %3cdefs%3e %3clinearGradient id='paint0_linear_6459_10399' x1='8' y1='8' x2='24' y2='24' gradientUnits='userSpaceOnUse'%3e %3cstop stop-color='%230084D6'/%3e %3cstop offset='0.489583' stop-color='%230084D6'/%3e %3cstop offset='0.489683' stop-color='%2305A9FF'/%3e %3cstop offset='0.921875' stop-color='%2305A9FF'/%3e %3c/linearGradient%3e %3c/defs%3e%3c/svg%3e";
13488
-
13489
- var img = "data:image/svg+xml,%3csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 24 24' style='enable-background:new 0 0 24 24%3b' xml:space='preserve'%3e %3cstyle type='text/css'%3e .st0%7bfill:%23AEC46F%3b%7d %3c/style%3e %3cg%3e %3cpath class='st0' d='M19%2c4H5C4.4%2c4%2c4%2c4.4%2c4%2c5v14c0%2c0.6%2c0.4%2c1%2c1%2c1h14c0.6%2c0%2c1-0.4%2c1-1V5C20%2c4.4%2c19.6%2c4%2c19%2c4z M6%2c7.5h2.8l-0.7%2c2H6 V7.5z M6%2c13h5v5h-0.4c-0.3-2.4-2.2-4.3-4.6-4.6V13z M18%2c11h-4.3L18%2c6.7V11z M13%2c10.3V6h4.3L13%2c10.3z M17.9%2c13c-0.5%2c1-1.6%2c1.7-3%2c1.7 H13V13H17.9z M13%2c15.7h1.7c0.1%2c0.9%2c0.5%2c1.7%2c1%2c2.3H13V15.7z M15.7%2c15.6c0.9-0.2%2c1.7-0.6%2c2.3-1.2V18h-0.7 C16.5%2c17.6%2c15.9%2c16.7%2c15.7%2c15.6z M11%2c6v5H6v-0.5h2.5c0.2%2c0%2c0.4-0.1%2c0.5-0.3l1-3c0-0.2%2c0-0.4-0.1-0.5C9.8%2c6.6%2c9.7%2c6.5%2c9.5%2c6.5H6V6 H11z M6%2c14.4c1.8%2c0.3%2c3.3%2c1.8%2c3.6%2c3.6H6V14.4z'/%3e %3c/g%3e%3c/svg%3e";
13490
-
13491
- const LayerIcon = ({ layerInfo, error, innerRef }) => {
13492
- const geometryType = layerInfo?.configuration?.geometryType;
13493
- const renderSymbol = React.useMemo(() => {
13494
- if (layerInfo?.configuration?.layerType === api.LayerServiceType.RemoteTileLayerService) {
13495
- return jsxRuntime.jsx("img", { src: img, alt: "" });
13496
- }
13497
- if (!geometryType || error) {
13498
- return (jsxRuntime.jsx(AlertIconContainer, { children: jsxRuntime.jsx(uilibGl.Icon, { kind: "warning" }) }));
13499
- }
13500
- switch (geometryType) {
13501
- case api.OgcGeometryType.Point:
13502
- case api.OgcGeometryType.MultiPoint:
13503
- return jsxRuntime.jsx("img", { src: img$3, alt: "" });
13504
- case api.OgcGeometryType.Polygon:
13505
- case api.OgcGeometryType.MultiPolygon:
13506
- return jsxRuntime.jsx("img", { src: img$1, alt: "" });
13507
- case api.OgcGeometryType.LineString:
13508
- case api.OgcGeometryType.MultiLineString:
13509
- return jsxRuntime.jsx("img", { src: img$2, alt: "" });
13510
- default:
13511
- return jsxRuntime.jsx("img", { src: img$3, alt: "" });
13512
- }
13513
- }, [error, geometryType, layerInfo?.configuration?.layerType]);
13514
- return jsxRuntime.jsx(LayerIconContainer, { ref: innerRef, children: renderSymbol });
13515
- };
13516
-
13517
- const LayerIconClickable = styled.div.withConfig({ displayName: "LayerIconClickable", componentId: "sc-1o3bms0" }) `
13518
- display: flex;
13519
- align-items: center;
13520
- cursor: pointer;
13521
- `;
13522
- const NoFeatureIcon = styled.div.withConfig({ displayName: "NoFeatureIcon", componentId: "sc-sxo6af" }) `
13523
- display: flex;
13524
- align-items: center;
13525
- justify-content: center;
13526
- min-width: 1.5rem;
13527
- height: 1.5rem;
13528
- margin-top: 0.25rem;
13529
- margin-right: 1rem;
13530
- margin-left: 0.25rem;
13531
13877
 
13532
- ${uilibGl.Icon}::after {
13533
- font-size: 1.5rem;
13534
- color: ${({ theme: { palette } }) => palette.iconDisabled};
13535
- }
13878
+ ${HeaderWrapperMixin};
13879
+
13880
+ ${({ $bigIcon }) => $bigIcon && BigIconHeaderMixin};
13881
+
13882
+ ${({ $withPadding }) => $withPadding && WithPaddingHeaderMixin};
13883
+
13884
+ ${({ $bottomBlur }) => $bottomBlur && BottomBlurHeaderMixin};
13536
13885
  `;
13537
13886
 
13538
- const HeaderLayerIcon = ({ noFeature }) => {
13539
- const { t } = useGlobalContext();
13540
- const { layerInfo, feature } = useWidgetContext(exports.WidgetType.FeatureCard);
13541
- const zoomToFeatures = useZoomToFeatures();
13542
- const getMaxZoomTo = useMaxZoomTo();
13543
- const [optionsMaxZoomTo, layerMaxZoomTo] = React.useMemo(() => getMaxZoomTo(layerInfo?.name), [layerInfo?.name, getMaxZoomTo]);
13544
- const handleIconClick = React.useCallback(() => zoomToFeatures([feature], { maxZoom: layerMaxZoomTo ?? optionsMaxZoomTo }), [zoomToFeatures, feature, layerMaxZoomTo, optionsMaxZoomTo]);
13545
- if (noFeature) {
13546
- return (jsxRuntime.jsx(NoFeatureIcon, { children: jsxRuntime.jsx(uilibGl.Icon, { kind: "no_geom" }) }));
13547
- }
13548
- return (jsxRuntime.jsx(LayerIconClickable, { onClick: handleIconClick, children: jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard", defaultValue: "Приблизить к объекту" }), delay: [600, 0], children: ref => (jsxRuntime.jsx(LayerIcon, { innerRef: ref, layerInfo: layerInfo })) }) }));
13549
- };
13550
-
13551
- const FeatureCardDefaultHeader = ({ noFeature }) => {
13887
+ const FeatureCardBackgroundHeader = () => {
13552
13888
  const { themeName: pageThemeName } = useGlobalContext();
13553
13889
  const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
13554
13890
  const { header } = config || {};
13555
13891
  const { options } = header || {};
13556
- const { themeName, withPadding, column, height, overlay } = options || {};
13557
- return (jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsxRuntime.jsx(DefaultHeaderWrapper, { withPadding: withPadding, height: height, "$noFeature": noFeature, children: jsxRuntime.jsx(Header, { "$overlay": overlay, "$isRow": !column, "$noFeature": noFeature, children: jsxRuntime.jsxs(HeaderFrontView, { isDefault: !column, children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(HeaderLayerIcon, { noFeature: noFeature }), jsxRuntime.jsx(HeaderTitle, { noFeature: noFeature })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }) }) }) }));
13892
+ const { fontColor, bgColor, height, overlay, bigIcon, withPadding, bottomBlur, themeName, column } = options || {};
13893
+ const renderElement = useHeaderRender(header);
13894
+ return (jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsxRuntime.jsx(BackgroundHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$height": height, "$bigIcon": bigIcon, "$withPadding": withPadding, "$bottomBlur": bottomBlur, children: jsxRuntime.jsxs(Header, { "$overlay": overlay, "$isRow": !column, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { column: column, children: [jsxRuntime.jsx(HeaderLayerIcon, {}), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
13895
+ id: "title",
13896
+ wrap: false,
13897
+ }), description: renderElement({
13898
+ id: "description",
13899
+ wrap: false,
13900
+ }) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }), jsxRuntime.jsx(ContainerBackground, { elementConfig: header, renderElement: renderElement }), jsxRuntime.jsx(HeaderIcon, { children: renderElement({
13901
+ id: "icon",
13902
+ wrap: false,
13903
+ }) })] }) }) }));
13558
13904
  };
13559
13905
 
13560
13906
  const ImageContainerButton = styled(uilibGl.FlatButton).withConfig({ displayName: "ImageContainerButton", componentId: "sc-nq6mg4" }) `
@@ -14017,13 +14363,17 @@ const ElementIcon = React.memo(({ type, elementConfig, ...rest }) => {
14017
14363
  const ElementImg = styled.img.withConfig({ displayName: "ElementImg", componentId: "sc-7ul8bx" }) `
14018
14364
  max-width: 100%;
14019
14365
 
14020
- /* Картинка заполняет отведённый ей бокс: масштаб по меньшей стороне, излишек обрезается. */
14366
+ /* Картинка заполняет отведённый ей бокс: масштаб по меньшей стороне, излишек обрезается.
14367
+ && — чтобы авторский options.fit перебивал дефолтный cover слоя ContainerBackgroundLayer:
14368
+ тот задаёт его селектором-потомком (.layer img) и иначе выигрывал бы по специфичности. */
14021
14369
  ${({ $fit }) => !!$fit &&
14022
14370
  styled.css `
14023
- width: 100%;
14024
- height: 100%;
14025
- object-position: center;
14026
- object-fit: ${$fit};
14371
+ && {
14372
+ width: 100%;
14373
+ height: 100%;
14374
+ object-position: center;
14375
+ object-fit: ${$fit};
14376
+ }
14027
14377
  `}
14028
14378
 
14029
14379
  ${sizeCssMixin};
@@ -14953,7 +15303,7 @@ const ElementTable = React.memo(({ elementConfig }) => {
14953
15303
  return (jsxRuntime.jsx(TableBox, { "$sizeCss": sizeCss, children: jsxRuntime.jsxs(TableWrapper, { ref: setTable, "$contentWidth": contentWidth, children: [jsxRuntime.jsx(TableHead, { children: jsxRuntime.jsxs("tr", { children: [columns.map(({ attributeName, alias, description }) => {
14954
15304
  const sorted = sort?.attributeName === attributeName;
14955
15305
  return (jsxRuntime.jsx(TableHeadCell, { title: description || alias, "$sortable": sortEnabled, onClick: sortEnabled ? () => onSortToggle(attributeName) : undefined, children: jsxRuntime.jsxs(TableHeadContent, { children: [alias, sortEnabled && (jsxRuntime.jsx(TableSortSlot, { "$active": sorted, children: jsxRuntime.jsx(uilibGl.Icon, { kind: sorted && sort?.direction === "desc" ? "sorting_des" : "sorting_asc" }) }))] }) }, attributeName));
14956
- }), context.canEdit && jsxRuntime.jsx(TableHeadCell, {})] }) }), jsxRuntime.jsx(TableBody, { children: rows.map(row => (jsxRuntime.jsxs(TableRow, { children: [columns.map(attribute => (jsxRuntime.jsx(TableCellWrapper, { children: jsxRuntime.jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }) }, attribute.attributeName))), context.canEdit && (jsxRuntime.jsx(TableActionsCell, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "delete", title: t("actions.delete", { ns: "common", defaultValue: "Удалить" }), onClick: () => context.onRowDelete(row.key) }) }))] }, row.key))) })] }) }));
15306
+ }), context.canDelete && jsxRuntime.jsx(TableHeadCell, {})] }) }), jsxRuntime.jsx(TableBody, { children: rows.map(row => (jsxRuntime.jsxs(TableRow, { children: [columns.map(attribute => (jsxRuntime.jsx(TableCellWrapper, { children: jsxRuntime.jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }) }, attribute.attributeName))), context.canDelete && (jsxRuntime.jsx(TableActionsCell, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "delete", title: t("actions.delete", { ns: "common", defaultValue: "Удалить" }), onClick: () => context.onRowDelete(row.key) }) }))] }, row.key))) })] }) }));
14957
15307
  });
14958
15308
 
14959
15309
  const TooltipIcon = styled(uilibGl.Icon).withConfig({ displayName: "TooltipIcon", componentId: "sc-1lkxudm" }) `
@@ -15021,21 +15371,7 @@ const SlideshowHeaderWrapper = styled.div.withConfig({ displayName: "SlideshowHe
15021
15371
 
15022
15372
  ${({ fontColor }) => !!fontColor && HeaderFontColorMixin};
15023
15373
  `;
15024
- const ImageContainerBg = styled.div.withConfig({ displayName: "ImageContainerBg", componentId: "sc-1yxa8u0" }) `
15025
- position: absolute;
15026
- top: 0;
15027
- bottom: 0;
15028
- left: 0;
15029
- right: 0;
15030
-
15031
- img {
15032
- width: 100%;
15033
- height: 100%;
15034
- object-position: center;
15035
- object-fit: cover;
15036
- }
15037
- `;
15038
- const HeaderSlideshow = styled.div.withConfig({ displayName: "HeaderSlideshow", componentId: "sc-fqw4k7" }) `
15374
+ const HeaderSlideshow = styled.div.withConfig({ displayName: "HeaderSlideshow", componentId: "sc-1yw2skw" }) `
15039
15375
  position: absolute;
15040
15376
  top: 0;
15041
15377
  bottom: ${({ height }) => (height ? `${height}px` : 0)};
@@ -15056,143 +15392,6 @@ const HeaderSlideshow = styled.div.withConfig({ displayName: "HeaderSlideshow",
15056
15392
  }
15057
15393
  `;
15058
15394
 
15059
- const HeaderWrapperMixin = styled.css `
15060
- ${Header} {
15061
- min-height: 5.25rem;
15062
- }
15063
-
15064
- ${HeaderContainer} {
15065
- max-width: 100%;
15066
- width: 100%;
15067
- }
15068
-
15069
- ${FeatureControls} {
15070
- max-width: calc(100% - 2rem);
15071
- width: calc(100% - 2rem);
15072
- margin-top: -0.5rem;
15073
- padding-top: 1rem;
15074
- border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
15075
- }
15076
-
15077
- ${({ $fontColor }) => !!$fontColor && HeaderFontColorMixin};
15078
- `;
15079
- const HeaderIcon = styled(uilibGl.Flex).withConfig({ displayName: "HeaderIcon", componentId: "sc-1y7xqr9" }) `
15080
- position: absolute;
15081
- top: 0;
15082
- right: 0;
15083
- align-items: center;
15084
- justify-content: center;
15085
- width: 7.625rem;
15086
- height: 100%;
15087
-
15088
- span[kind] {
15089
- width: 4rem;
15090
-
15091
- :after {
15092
- font-size: 4rem;
15093
- color: rgba(255, 255, 255, 0.36);
15094
- }
15095
- }
15096
-
15097
- span[kind]:after,
15098
- path,
15099
- line,
15100
- circle {
15101
- fill: rgba(255, 255, 255, 0.36);
15102
- }
15103
-
15104
- && > * {
15105
- display: flex;
15106
- align-items: center;
15107
- height: 100%;
15108
- }
15109
- `;
15110
- const BigIconHeaderMixin = styled.css `
15111
- ${HeaderIcon} {
15112
- min-width: 14rem;
15113
- right: -3rem;
15114
-
15115
- span[kind]:after {
15116
- font-size: 14rem;
15117
- }
15118
- }
15119
- `;
15120
- const WithPaddingHeaderMixin = styled.css `
15121
- ${Header} {
15122
- width: 100%;
15123
- margin: -0.5rem -0.5rem 0.5rem -0.5rem;
15124
- }
15125
- `;
15126
- const BottomBlurHeaderMixin = styled.css `
15127
- ${Header} {
15128
- margin-bottom: 0;
15129
-
15130
- &::before {
15131
- -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15132
- mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15133
- }
15134
- }
15135
-
15136
- ${ImageContainerBg} {
15137
- -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15138
- mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15139
- }
15140
-
15141
- ${HeaderFrontView} {
15142
- z-index: 100;
15143
- }
15144
- `;
15145
- const BackgroundHeaderWrapper = styled.div.withConfig({ displayName: "BackgroundHeaderWrapper", componentId: "sc-10iuilq" }) `
15146
- ${Header} {
15147
- position: relative;
15148
- width: calc(100% + 1rem);
15149
- height: ${({ $height }) => $height ? `${$height}px` : "auto"};
15150
- margin: -1rem -1rem 1rem -1rem;
15151
- border-radius: 0.5rem;
15152
- background: transparent;
15153
- overflow: hidden;
15154
-
15155
- &::before {
15156
- content: "";
15157
- position: absolute;
15158
- inset: 0;
15159
- z-index: 100;
15160
- pointer-events: none;
15161
- background: ${({ $bgColor }) => $bgColor || "linear-gradient(96.55deg, #FFFCD3 0%, #B4DC47 100%)"};
15162
- }
15163
- }
15164
-
15165
- ${HeaderWrapperMixin};
15166
-
15167
- ${({ $bigIcon }) => $bigIcon && BigIconHeaderMixin};
15168
-
15169
- ${({ $withPadding }) => $withPadding && WithPaddingHeaderMixin};
15170
-
15171
- ${({ $bottomBlur }) => $bottomBlur && BottomBlurHeaderMixin};
15172
- `;
15173
-
15174
- const FeatureCardBackgroundHeader = () => {
15175
- const { themeName: pageThemeName } = useGlobalContext();
15176
- const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
15177
- const { header } = config || {};
15178
- const { options } = header || {};
15179
- const { fontColor, bgColor, height, overlay, bigIcon, withPadding, bottomBlur, themeName, column } = options || {};
15180
- const renderElement = useHeaderRender(header);
15181
- return (jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsxRuntime.jsx(BackgroundHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$height": height, "$bigIcon": bigIcon, "$withPadding": withPadding, "$bottomBlur": bottomBlur, children: jsxRuntime.jsxs(Header, { "$overlay": overlay, "$isRow": !column, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { column: column, children: [jsxRuntime.jsx(HeaderLayerIcon, {}), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
15182
- id: "title",
15183
- wrap: false,
15184
- }), description: renderElement({
15185
- id: "description",
15186
- wrap: false,
15187
- }) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }), jsxRuntime.jsx(ImageContainerBg, { children: renderElement({
15188
- id: "bgImage",
15189
- wrap: false,
15190
- }) }), jsxRuntime.jsx(HeaderIcon, { children: renderElement({
15191
- id: "icon",
15192
- wrap: false,
15193
- }) })] }) }) }));
15194
- };
15195
-
15196
15395
  const FeatureCardSlideshowHeader = () => {
15197
15396
  const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
15198
15397
  const { header } = config || {};
@@ -15205,10 +15404,7 @@ const FeatureCardSlideshowHeader = () => {
15205
15404
  }), description: renderElement({
15206
15405
  id: "description",
15207
15406
  wrap: false,
15208
- }) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }), jsxRuntime.jsx(ImageContainerBg, { children: renderElement({
15209
- id: "bgImage",
15210
- wrap: false,
15211
- }) }), jsxRuntime.jsx(HeaderSlideshow, { height: height, children: renderElement({
15407
+ }) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }), jsxRuntime.jsx(ContainerBackground, { elementConfig: header, renderElement: renderElement }), jsxRuntime.jsx(HeaderSlideshow, { height: height, children: renderElement({
15212
15408
  id: "slideshow",
15213
15409
  wrap: false,
15214
15410
  }) })] }) }) }));
@@ -17152,6 +17348,14 @@ const getTotalFromRelatedFeatures = (data) => {
17152
17348
 
17153
17349
  const getRootElementId = (type = exports.WidgetType.Dashboard) => `${type}-root`;
17154
17350
 
17351
+ /**
17352
+ * Есть ли у узла конфига слот фонового изображения.
17353
+ *
17354
+ * Слой фона рисуется ТОЛЬКО по этому признаку: без узла `bgImage` в конфиге пустой
17355
+ * абсолютно позиционированный `div` в DOM не появляется вовсе.
17356
+ */
17357
+ const hasContainerBgImage = (elementConfig) => !!elementConfig?.children?.some(({ id }) => id === BG_IMAGE_SLOT_ID);
17358
+
17155
17359
  const pieChartTooltipFromAttributes = (t, data, attributes) => {
17156
17360
  const attribute = attributes?.find(({ name }) => name === data[0].name);
17157
17361
  const renderValue = attribute
@@ -17530,7 +17734,7 @@ const ChartLegend = ({ data, chartElement, fontSize, type, twoColumns, loading }
17530
17734
  const ContainerChildren = React.memo(({ type, items, isColumn, isMain, renderElement }) => {
17531
17735
  const checkIfEmptyDataSource = useHideIfEmptyDataSource(type);
17532
17736
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: items
17533
- ?.filter(item => !TITLE_SLOT_IDS.includes(item.id))
17737
+ ?.filter(item => !NON_TRACK_SLOT_IDS.includes(item.id))
17534
17738
  ?.map((item, index) => {
17535
17739
  const render = renderElement({
17536
17740
  id: item.id,
@@ -18188,6 +18392,7 @@ exports.AttachmentContainer = AttachmentContainer;
18188
18392
  exports.AttributeGalleryContainer = AttributeGalleryContainer;
18189
18393
  exports.AttributeLabel = AttributeLabel;
18190
18394
  exports.BASE_CONTAINER_STYLE = BASE_CONTAINER_STYLE;
18395
+ exports.BG_IMAGE_SLOT_ID = BG_IMAGE_SLOT_ID;
18191
18396
  exports.CHART_TYPES = CHART_TYPES;
18192
18397
  exports.COMPACT_FRACTION_DIGITS = COMPACT_FRACTION_DIGITS;
18193
18398
  exports.CONFIG_PAGES_ID = CONFIG_PAGES_ID;
@@ -18201,6 +18406,7 @@ exports.ChartContainer = ChartContainer;
18201
18406
  exports.ChartLegend = ChartLegend;
18202
18407
  exports.ChartLoading = ChartLoading;
18203
18408
  exports.Container = Container;
18409
+ exports.ContainerBackground = ContainerBackground;
18204
18410
  exports.ContainerChildren = ContainerChildren;
18205
18411
  exports.ContainerLoading = ContainerLoading;
18206
18412
  exports.ContainerRoot = ContainerRoot;
@@ -18362,6 +18568,7 @@ exports.MIN_TRACK_RATIO = MIN_TRACK_RATIO;
18362
18568
  exports.Map = Map$1;
18363
18569
  exports.MapContext = MapContext;
18364
18570
  exports.MapProvider = MapProvider;
18571
+ exports.NON_TRACK_SLOT_IDS = NON_TRACK_SLOT_IDS;
18365
18572
  exports.NO_CELL_DRAG_SELECTOR = NO_CELL_DRAG_SELECTOR;
18366
18573
  exports.NO_CONTENT_VALUE = NO_CONTENT_VALUE;
18367
18574
  exports.NUMERIC_ATTRIBUTE_TYPES = NUMERIC_ATTRIBUTE_TYPES;
@@ -18519,6 +18726,7 @@ exports.getTrackSize = getTrackSize;
18519
18726
  exports.getTrackSizeKey = getTrackSizeKey;
18520
18727
  exports.getTrackSizes = getTrackSizes;
18521
18728
  exports.getWrapperSizeStyle = getWrapperSizeStyle;
18729
+ exports.hasContainerBgImage = hasContainerBgImage;
18522
18730
  exports.hexToRgba = hexToRgba;
18523
18731
  exports.isEmptyElementValue = isEmptyElementValue;
18524
18732
  exports.isEmptyValue = isEmptyValue;
@@ -18574,6 +18782,7 @@ exports.useAttachmentItems = useAttachmentItems;
18574
18782
  exports.useAttachmentPreviewImages = useAttachmentPreviewImages;
18575
18783
  exports.useAutoCompleteControl = useAutoCompleteControl;
18576
18784
  exports.useBeforeSave = useBeforeSave;
18785
+ exports.useBgImageHost = useBgImageHost;
18577
18786
  exports.useChartChange = useChartChange;
18578
18787
  exports.useChartData = useChartData;
18579
18788
  exports.useContainerAttributes = useContainerAttributes;