@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/react.esm.js CHANGED
@@ -3317,6 +3317,22 @@ const CONFIG_PAGE_ID = "page";
3317
3317
  * `grid-template-*`, иначе слот заголовка съест трек и раскладка съедет.
3318
3318
  */
3319
3319
  const TITLE_SLOT_IDS = ["title", "icon", "titleIcon"];
3320
+ /**
3321
+ * Универсальный slot-id фонового изображения контейнера.
3322
+ *
3323
+ * Допустим у любого контейнера, кроме `Divider`, и поэтому не перечисляется в наборах слотов —
3324
+ * ровно как слоты заголовка. Узел рисуется отдельным слоем `ContainerBackgroundLayer`
3325
+ * (см. `ContainerBackground`), а не через общий рендер детей.
3326
+ */
3327
+ const BG_IMAGE_SLOT_ID = "bgImage";
3328
+ /**
3329
+ * Slot-id, которые контейнер читает по `id` сам и не отдаёт ни в общий рендер тела
3330
+ * (`ContainerChildren`), ни в треки сетки (`gridTracks`/`gridTree`).
3331
+ *
3332
+ * Без `bgImage` в этом наборе фон группы отрисовался бы дважды: слоем и обычным ребёнком —
3333
+ * а в сетке ещё и съел бы трек.
3334
+ */
3335
+ const NON_TRACK_SLOT_IDS = [...TITLE_SLOT_IDS, BG_IMAGE_SLOT_ID];
3320
3336
  const DEFAULT_PAGES_CONFIG = {
3321
3337
  id: CONFIG_PAGES_ID,
3322
3338
  templateName: ContainerTemplate.Pages,
@@ -4732,19 +4748,83 @@ const DashboardChip$1 = styled(Chip).withConfig({ displayName: "DashboardChip",
4732
4748
  ${({ $fontColor, $isDefault }) => !!$fontColor && !$isDefault && CustomChipColorMixin}
4733
4749
  `;
4734
4750
 
4735
- const LayersListWrapper = styled(Flex).withConfig({ displayName: "LayersListWrapper", componentId: "sc-10siqjn" }) `
4736
- flex-direction: column;
4737
- height: 100%;
4738
- width: 100%;
4739
- box-sizing: border-box;
4751
+ /**
4752
+ * Внутренний отступ корня контейнера при `options.innerPadding`.
4753
+ *
4754
+ * Значение фиксировано намеренно: опция булева, автор конфига включает «отступ от краёв фона»,
4755
+ * а не подбирает число — для произвольного отступа есть `options.padding`.
4756
+ */
4757
+ const CONTAINER_INNER_PADDING = "1rem";
4758
+ /**
4759
+ * Вылет слоя `bgImage` за края контейнера при `options.outflow` — по бокам и вверх.
4760
+ *
4761
+ * Ровно `padding` карточки контейнера (`ContainerWrapper` в `Dashboard/styled/containers.ts`): картинка
4762
+ * дотягивается до краёв колонки дашборда, а содержимое остаётся на месте. Вниз слой не
4763
+ * вытекает — там начинается следующий контейнер.
4764
+ */
4765
+ const BG_IMAGE_OUTFLOW = "1.5rem";
4766
+
4767
+ /**
4768
+ * Слой фонового изображения контейнера: единственный ребёнок, который рисуется ПОД содержимым.
4769
+ *
4770
+ * `z-index: -1` работает только внутри собственного stacking-контекста хоста (`isolation: isolate`
4771
+ * в `bgImageHostMixin`): там отрицательный слой ложится поверх фона хоста, но под его контентом.
4772
+ * Без изоляции он ушёл бы под фон ближайшего предка-контекста и пропал.
4773
+ *
4774
+ * `border-radius: inherit` повторяет скругление хоста, `pointer-events: none` оставляет клики
4775
+ * содержимому.
4776
+ *
4777
+ * `options.outflow` растягивает слой отрицательным `inset` — раскладка хоста при этом не
4778
+ * меняется: слой абсолютный, содержимое остаётся в своих границах, вытекает только картинка.
4779
+ * Вылет идёт по бокам и вверх, но НЕ вниз: снизу картинка обязана заканчиваться по краю
4780
+ * контейнера, иначе она наползала бы на следующий контейнер колонки.
4781
+ */
4782
+ const ContainerBackgroundLayer = styled.div.withConfig({ displayName: "ContainerBackgroundLayer", componentId: "sc-1ws6t58" }) `
4783
+ position: absolute;
4784
+ inset: ${({ $outflow }) => ($outflow ? `-${BG_IMAGE_OUTFLOW} -${BG_IMAGE_OUTFLOW} 0` : "0")};
4785
+ z-index: -1;
4786
+ overflow: hidden;
4787
+ border-radius: inherit;
4788
+ pointer-events: none;
4789
+
4790
+ img {
4791
+ width: 100%;
4792
+ height: 100%;
4793
+ object-position: center;
4794
+ object-fit: cover;
4795
+ }
4740
4796
  `;
4741
- const LayerListContainer = styled(Flex).withConfig({ displayName: "LayerListContainer", componentId: "sc-vfvx64" }) `
4742
- flex-grow: 1;
4743
- height: 100%;
4744
- box-sizing: border-box;
4745
- padding-top: 0.25rem;
4797
+ /**
4798
+ * Хост фонового слоя: корень контейнера, у которого в конфиге есть слот `bgImage`.
4799
+ *
4800
+ * Гейт по `$hasBgImage` принципиален — `position: relative` меняет containing block для
4801
+ * абсолютно позиционированных потомков (контролы слайдшоу, подписи прогресса), поэтому
4802
+ * включается только там, где автор конфига действительно попросил фон.
4803
+ *
4804
+ * `$innerPadding` (`options.innerPadding`) — отдельный гейт: отступ содержимого нужен и без
4805
+ * фона, поэтому он не привязан к `$hasBgImage`. `&&` поднимает специфичность до двух классов,
4806
+ * чтобы перебить `padding` из `$sizeCss` и собственных `defaults` контейнера; авторский inline
4807
+ * `style` по-прежнему сильнее — как и задумано.
4808
+ *
4809
+ * Модуль намеренно листовой: его импортирует `Dashboard/styled/containers.ts`, и обратная зависимость
4810
+ * замкнула бы цикл, уронив миксин в TDZ на инициализации.
4811
+ */
4812
+ const bgImageHostMixin = css `
4813
+ ${({ $hasBgImage }) => !!$hasBgImage &&
4814
+ css `
4815
+ position: relative;
4816
+ isolation: isolate;
4817
+ `};
4818
+
4819
+ ${({ $innerPadding }) => !!$innerPadding &&
4820
+ css `
4821
+ && {
4822
+ padding: ${CONTAINER_INNER_PADDING};
4823
+ }
4824
+ `};
4746
4825
  `;
4747
4826
 
4827
+ /** Корень, тело и обёртка контейнера — и общие для них миксины размеров и отступов. */
4748
4828
  /**
4749
4829
  * Размеры контейнера из конфига.
4750
4830
  *
@@ -4783,7 +4863,7 @@ const noMarginMixin = css `
4783
4863
  * `$sizeTransparent` поэтому работает только на контейнерах, которые ещё не переведены
4784
4864
  * на `useContainerRoot`.
4785
4865
  */
4786
- const ElementValueWrapper = styled.div.withConfig({ displayName: "ElementValueWrapper", componentId: "sc-dnq3zl" }) `
4866
+ const ElementValueWrapper = styled.div.withConfig({ displayName: "ElementValueWrapper", componentId: "sc-x3ra9l" }) `
4787
4867
  transition: background-color ${transition.toggle};
4788
4868
 
4789
4869
  ${({ noMargin }) => !!noMargin &&
@@ -4813,14 +4893,15 @@ const ElementValueWrapper = styled.div.withConfig({ displayName: "ElementValueWr
4813
4893
  * Всегда flex-колонка: заголовок и тело раньше были flex-элементами родительского `Container`,
4814
4894
  * и блочная обёртка вернула бы схлопывание вертикальных отступов между ними.
4815
4895
  */
4816
- const ContainerRoot = styled(Flex).withConfig({ displayName: "ContainerRoot", componentId: "sc-2j6lbd" }) `
4896
+ const ContainerRoot = styled(Flex).withConfig({ displayName: "ContainerRoot", componentId: "sc-1m2pft5" }) `
4817
4897
  flex-direction: column;
4818
4898
  min-width: 0;
4819
4899
 
4820
4900
  ${sizeCssMixin};
4821
4901
  ${noMarginMixin};
4902
+ ${bgImageHostMixin};
4822
4903
  `;
4823
- const Container = styled(Flex).withConfig({ displayName: "Container", componentId: "sc-1o8dsu2" }) `
4904
+ const Container = styled(Flex).withConfig({ displayName: "Container", componentId: "sc-px8dv0" }) `
4824
4905
  flex-direction: column;
4825
4906
  width: 100%;
4826
4907
 
@@ -4873,8 +4954,9 @@ const Container = styled(Flex).withConfig({ displayName: "Container", componentI
4873
4954
  `}
4874
4955
 
4875
4956
  ${sizeCssMixin};
4957
+ ${bgImageHostMixin};
4876
4958
  `;
4877
- const ContainerWrapper = styled(Flex).withConfig({ displayName: "ContainerWrapper", componentId: "sc-16tb6s0" }) `
4959
+ const ContainerWrapper = styled(Flex).withConfig({ displayName: "ContainerWrapper", componentId: "sc-1eb7t8v" }) `
4878
4960
  position: relative;
4879
4961
  box-sizing: border-box;
4880
4962
  width: 100%;
@@ -4895,7 +4977,9 @@ const ContainerWrapper = styled(Flex).withConfig({ displayName: "ContainerWrappe
4895
4977
  }
4896
4978
  `}
4897
4979
  `;
4898
- const DashboardChip = styled(Chip).withConfig({ displayName: "DashboardChip", componentId: "sc-19j7obx" }) `
4980
+
4981
+ /** Каркас дашборда: обёртка страницы, область контента, плейсхолдеры и чип значения. */
4982
+ const DashboardChip = styled(Chip).withConfig({ displayName: "DashboardChip", componentId: "sc-a3pqro" }) `
4899
4983
  margin: 0 0.25rem 0.25rem 0;
4900
4984
  background: ${({ $isDefault, $bgColor, theme: { palette } }) => $isDefault ? palette.element : $bgColor || palette.primary};
4901
4985
  border-radius: ${({ $radius, theme: { borderRadius } }) => $radius || borderRadius.medium};
@@ -4911,7 +4995,7 @@ const DashboardChip = styled(Chip).withConfig({ displayName: "DashboardChip", co
4911
4995
  color: ${({ $isDefault, $fontColor, theme: { palette } }) => $isDefault ? palette.icon : $fontColor || "#fff"};
4912
4996
  }
4913
4997
  `;
4914
- const DashboardPlaceholderWrap = styled(Flex).withConfig({ displayName: "DashboardPlaceholderWrap", componentId: "sc-anwihw" }) `
4998
+ const DashboardPlaceholderWrap = styled(Flex).withConfig({ displayName: "DashboardPlaceholderWrap", componentId: "sc-qnoieo" }) `
4915
4999
  flex-grow: 1;
4916
5000
  flex-direction: column;
4917
5001
  justify-content: center;
@@ -4919,7 +5003,7 @@ const DashboardPlaceholderWrap = styled(Flex).withConfig({ displayName: "Dashboa
4919
5003
  width: 100%;
4920
5004
  margin-bottom: 2rem;
4921
5005
  `;
4922
- const DashboardPlaceholder = styled(Flex).withConfig({ displayName: "DashboardPlaceholder", componentId: "sc-jry8vp" }) `
5006
+ const DashboardPlaceholder = styled(Flex).withConfig({ displayName: "DashboardPlaceholder", componentId: "sc-18za1l3" }) `
4923
5007
  flex-direction: column;
4924
5008
  justify-content: center;
4925
5009
  align-items: center;
@@ -4952,7 +5036,7 @@ const DashboardPlaceholder = styled(Flex).withConfig({ displayName: "DashboardPl
4952
5036
  }
4953
5037
  }
4954
5038
  `;
4955
- const DashboardWrapper = styled(Flex).withConfig({ displayName: "DashboardWrapper", componentId: "sc-100ipup" }) `
5039
+ const DashboardWrapper = styled(Flex).withConfig({ displayName: "DashboardWrapper", componentId: "sc-tnxl47" }) `
4956
5040
  flex-direction: column;
4957
5041
  flex-wrap: nowrap;
4958
5042
  flex-grow: 1;
@@ -4965,13 +5049,28 @@ const DashboardWrapper = styled(Flex).withConfig({ displayName: "DashboardWrappe
4965
5049
  margin-top: -0.35rem;
4966
5050
  `}
4967
5051
  `;
4968
- const DashboardContent = styled(Flex).withConfig({ displayName: "DashboardContent", componentId: "sc-77il9k" }) `
5052
+ const DashboardContent = styled(Flex).withConfig({ displayName: "DashboardContent", componentId: "sc-cqvhte" }) `
4969
5053
  flex-grow: 1;
4970
5054
  width: 100%;
4971
5055
  padding: 1.5rem 1.5rem 2rem;
4972
5056
  overflow-y: auto;
4973
5057
  scrollbar-gutter: stable;
4974
5058
  `;
5059
+
5060
+ const LayersListWrapper = styled(Flex).withConfig({ displayName: "LayersListWrapper", componentId: "sc-10siqjn" }) `
5061
+ flex-direction: column;
5062
+ height: 100%;
5063
+ width: 100%;
5064
+ box-sizing: border-box;
5065
+ `;
5066
+ const LayerListContainer = styled(Flex).withConfig({ displayName: "LayerListContainer", componentId: "sc-vfvx64" }) `
5067
+ flex-grow: 1;
5068
+ height: 100%;
5069
+ box-sizing: border-box;
5070
+ padding-top: 0.25rem;
5071
+ `;
5072
+
5073
+ /** Презентационный режим: карточки-панели поверх дашборда и левая панель со списком слоёв. */
4975
5074
  const PresentationWrapperCss = css `
4976
5075
  margin-bottom: 0.75rem;
4977
5076
  padding: 1.5rem;
@@ -4980,16 +5079,16 @@ const PresentationWrapperCss = css `
4980
5079
  border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
4981
5080
  box-shadow: ${shadows.raised};
4982
5081
  `;
4983
- const PresentationWrapper = styled.div.withConfig({ displayName: "PresentationWrapper", componentId: "sc-891z9z" }) `
5082
+ const PresentationWrapper = styled.div.withConfig({ displayName: "PresentationWrapper", componentId: "sc-15hokqp" }) `
4984
5083
  ${PresentationWrapperCss};
4985
5084
  position: relative;
4986
5085
  z-index: 1;
4987
5086
  `;
4988
- const PresentationPanelWrapper = styled(PresentationWrapper).withConfig({ displayName: "PresentationPanelWrapper", componentId: "sc-1ptpbt9" }) `
5087
+ const PresentationPanelWrapper = styled(PresentationWrapper).withConfig({ displayName: "PresentationPanelWrapper", componentId: "sc-qy34j6" }) `
4989
5088
  margin-top: 0.75rem;
4990
5089
  transition: background-color ${transition.toggle};
4991
5090
  `;
4992
- const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHeader", componentId: "sc-182b7wg" }) `
5091
+ const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHeader", componentId: "sc-iysakx" }) `
4993
5092
  margin: -1.5rem -1.5rem 0 -1.5rem;
4994
5093
  padding: 1.5rem;
4995
5094
  // background: url(images.presentationHeader) 0 0 no-repeat;
@@ -5001,7 +5100,7 @@ const PresentationHeader = styled.div.withConfig({ displayName: "PresentationHea
5001
5100
  padding-top: 7rem;
5002
5101
  `};
5003
5102
  `;
5004
- const PresentationHeaderTools = styled(Flex).withConfig({ displayName: "PresentationHeaderTools", componentId: "sc-dms7fm" }) `
5103
+ const PresentationHeaderTools = styled(Flex).withConfig({ displayName: "PresentationHeaderTools", componentId: "sc-16o9l28" }) `
5005
5104
  justify-content: space-between;
5006
5105
  align-items: center;
5007
5106
  margin-bottom: -0.5rem;
@@ -5019,7 +5118,7 @@ const PresentationHeaderTools = styled(Flex).withConfig({ displayName: "Presenta
5019
5118
  }
5020
5119
  }
5021
5120
  `;
5022
- const LayerGroupList = styled(Flex).withConfig({ displayName: "LayerGroupList", componentId: "sc-19uothl" }) `
5121
+ const LayerGroupList = styled(Flex).withConfig({ displayName: "LayerGroupList", componentId: "sc-1o4tem9" }) `
5023
5122
  flex-direction: column;
5024
5123
  height: 100%;
5025
5124
  flex-wrap: nowrap;
@@ -5032,8 +5131,8 @@ const LayerGroupList = styled(Flex).withConfig({ displayName: "LayerGroupList",
5032
5131
  flex-grow: 1;
5033
5132
  }
5034
5133
  `;
5035
- const PresentationHeaderButtons = styled(Flex).withConfig({ displayName: "PresentationHeaderButtons", componentId: "sc-c24t7n" }) ``;
5036
- const PresentationPanelContainer = styled.div.withConfig({ displayName: "PresentationPanelContainer", componentId: "sc-17q0jzw" }) `
5134
+ const PresentationHeaderButtons = styled(Flex).withConfig({ displayName: "PresentationHeaderButtons", componentId: "sc-h3z1ud" }) ``;
5135
+ const PresentationPanelContainer = styled.div.withConfig({ displayName: "PresentationPanelContainer", componentId: "sc-rngq9i" }) `
5037
5136
  position: absolute;
5038
5137
  top: 0;
5039
5138
  left: calc(${({ left }) => left || 0}px + 0.75rem);
@@ -5102,7 +5201,9 @@ const PresentationPanelContainer = styled.div.withConfig({ displayName: "Present
5102
5201
  }
5103
5202
  }
5104
5203
  `;
5105
- const DataSourceErrorContainer = styled(Flex).withConfig({ displayName: "DataSourceErrorContainer", componentId: "sc-nh93ry" }) `
5204
+
5205
+ /** Общее для нескольких разделов: ошибка источника данных, подпись атрибута, кнопки объекта. */
5206
+ const DataSourceErrorContainer = styled(Flex).withConfig({ displayName: "DataSourceErrorContainer", componentId: "sc-1drfyq0" }) `
5106
5207
  align-items: center;
5107
5208
  justify-content: center;
5108
5209
  flex-wrap: nowrap;
@@ -5121,12 +5222,12 @@ const DataSourceErrorContainer = styled(Flex).withConfig({ displayName: "DataSou
5121
5222
  }
5122
5223
  }
5123
5224
  `;
5124
- const AttributeLabel = styled(Description).withConfig({ displayName: "AttributeLabel", componentId: "sc-9u3noy" }) `
5225
+ const AttributeLabel = styled(Description).withConfig({ displayName: "AttributeLabel", componentId: "sc-96skzy" }) `
5125
5226
  margin-top: 0 !important;
5126
5227
  margin-bottom: ${({ forCheckbox }) => forCheckbox ? "0.75rem" : "0.25rem"} !important;
5127
5228
  padding-left: ${({ isEdit }) => (isEdit ? "0.5rem" : "0")};
5128
5229
  `;
5129
- const FeatureControls = styled(Flex).withConfig({ displayName: "FeatureControls", componentId: "sc-1wenq0r" }) `
5230
+ const FeatureControls = styled(Flex).withConfig({ displayName: "FeatureControls", componentId: "sc-zlqfd7" }) `
5130
5231
  align-items: center;
5131
5232
  gap: 1rem;
5132
5233
  flex-wrap: nowrap;
@@ -5641,124 +5742,459 @@ const useWidgetContext = (type = WidgetType.Dashboard) => {
5641
5742
  };
5642
5743
  };
5643
5744
 
5644
- const useRenderContainerItem = (type, renderElement) => {
5645
- const { config, layerInfo, selectedTabId, attributes } = useWidgetContext(type);
5646
- return useCallback((elementConfig, attribute) => {
5647
- const { id, options, style, children } = elementConfig || {};
5648
- const { hideEmpty, innerTemplateStyle } = options || {};
5649
- const hasUnits = children?.some(item => item.id === "units");
5650
- const iconIndex = children?.findIndex(item => item.id === "icon");
5651
- const icon = children?.[iconIndex];
5652
- const hasIcon = !!icon;
5653
- const elementChildren = elementConfig?.children?.map(child => ({
5654
- type: "attributeValue",
5655
- ...child,
5656
- attributeName: attribute,
5657
- options: { noUnits: hasUnits, ...child.options },
5658
- }));
5659
- const attr = getAttributeConfigurationByName(getAttributesConfiguration(layerInfo).attributes, attribute);
5660
- if (hasIcon) {
5661
- elementChildren[iconIndex] = {
5662
- ...elementChildren[iconIndex],
5663
- ...getAttributeIconElement(attr?.icon),
5664
- attributeName: null,
5665
- };
5666
- }
5667
- const render = attribute
5668
- ? getRenderElement({
5669
- config,
5670
- elementConfig: {
5671
- ...elementConfig,
5672
- children: elementChildren,
5673
- },
5674
- selectedTabId,
5675
- attributes,
5676
- layerInfo,
5677
- type,
5678
- })
5679
- : renderElement;
5680
- const value = render({ id: "value" });
5745
+ const parseAttachments = (raw) => {
5746
+ if (!raw)
5747
+ return [];
5748
+ if (Array.isArray(raw))
5749
+ return raw;
5750
+ if (typeof raw !== "string")
5751
+ return [];
5752
+ try {
5753
+ const parsed = JSON.parse(raw);
5754
+ return Array.isArray(parsed) ? parsed : [];
5755
+ }
5756
+ catch {
5757
+ return [];
5758
+ }
5759
+ };
5760
+ const attachmentsFromFeatures = (features, mapping = {}) => {
5761
+ if (!features?.length)
5762
+ return [];
5763
+ const { attributeLink = "link", attributeName = "name", attributeMime = "mimeType", attributeDate = "date", } = mapping;
5764
+ return features
5765
+ .map(feature => {
5766
+ const link = feature.properties?.[attributeLink];
5767
+ if (!link)
5768
+ return null;
5681
5769
  return {
5682
- id,
5683
- value,
5684
- hideEmpty,
5685
- style: innerTemplateStyle || style,
5686
- hasIcon,
5687
- hasUnits,
5688
- render,
5770
+ link,
5771
+ name: feature.properties?.[attributeName] ?? link,
5772
+ mimeType: feature.properties?.[attributeMime] ?? "",
5773
+ date: feature.properties?.[attributeDate],
5774
+ isExternal: /^https?:\/\//.test(link),
5689
5775
  };
5690
- }, [config, layerInfo, selectedTabId, attributes, type, renderElement]);
5776
+ })
5777
+ .filter(Boolean);
5691
5778
  };
5692
5779
 
5693
- const customModes = MapboxDraw.modes;
5694
- const StaticMode = {};
5695
- const InvisibleMode = {};
5696
- StaticMode.onSetup = function () {
5697
- this.setActionableState(undefined);
5698
- return {};
5699
- };
5700
- StaticMode.toDisplayFeatures = function (state, geojson, display) {
5701
- display(geojson);
5780
+ const useAttachmentItems = ({ type, elementConfig, valueOverride, }) => {
5781
+ const { attributes, dataSources } = useWidgetContext(type);
5782
+ const { children, options } = elementConfig || {};
5783
+ const { relatedDataSource, controls } = options || {};
5784
+ const valueElement = useMemo(() => children?.find(({ id }) => id === "value"), [children]);
5785
+ const attributeName = useMemo(() => {
5786
+ const candidate = valueElement?.attributeName ?? elementConfig?.attributeName;
5787
+ return Array.isArray(candidate) ? candidate[0] : candidate;
5788
+ }, [valueElement, elementConfig]);
5789
+ const rawValue = useMemo(() => {
5790
+ if (valueOverride !== undefined)
5791
+ return valueOverride;
5792
+ if (!attributeName)
5793
+ return undefined;
5794
+ return attributes?.find(item => item.attributeName === attributeName)?.value;
5795
+ }, [valueOverride, attributeName, attributes]);
5796
+ const items = useMemo(() => {
5797
+ if (relatedDataSource) {
5798
+ const dataSource = dataSources?.find(({ name }) => name === relatedDataSource);
5799
+ const mapping = controls?.[0];
5800
+ return attachmentsFromFeatures(dataSource?.features, mapping);
5801
+ }
5802
+ return parseAttachments(rawValue);
5803
+ }, [relatedDataSource, dataSources, controls, rawValue]);
5804
+ return {
5805
+ items,
5806
+ attributeName,
5807
+ rawValue,
5808
+ };
5702
5809
  };
5703
- InvisibleMode.onSetup = function () {
5704
- this.setActionableState(undefined);
5705
- return {};
5810
+
5811
+ const useGlobalContext = () => {
5812
+ const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, notification } = useContext(GlobalContext) || {};
5813
+ const translate = useCallback((value, options) => {
5814
+ if (t)
5815
+ return t(value, options);
5816
+ return options?.defaultValue ?? value;
5817
+ }, [t]);
5818
+ return useMemo(() => ({
5819
+ t: translate,
5820
+ language,
5821
+ themeName,
5822
+ api,
5823
+ ewktGeometry,
5824
+ ewktExtent,
5825
+ zoomLevel,
5826
+ notification,
5827
+ }), [language, translate, api, ewktGeometry, ewktExtent, zoomLevel, themeName, notification]);
5706
5828
  };
5707
- InvisibleMode.toDisplayFeatures = function () { };
5708
- customModes.static = StaticMode;
5709
- customModes.invisible = InvisibleMode;
5710
5829
 
5711
- const customStyles = [
5712
- {
5713
- id: "gl-draw-point",
5714
- type: "circle",
5715
- filter: ["all", ["==", "$type", "Point"]],
5716
- paint: {
5717
- "circle-radius": 5,
5718
- "circle-color": "#D20C0C",
5719
- "circle-stroke-color": "#FFFFFF",
5720
- "circle-stroke-width": 3,
5721
- "circle-stroke-opacity": 0.3,
5722
- },
5723
- },
5724
- {
5725
- id: "highlight-inactive-points",
5726
- type: "circle",
5727
- filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "false"]],
5728
- paint: {
5729
- "circle-radius": 5,
5730
- "circle-color": "#D20C0C",
5731
- "circle-stroke-color": "#FFFFFF",
5732
- "circle-stroke-width": 3,
5733
- "circle-stroke-opacity": 0.3,
5734
- },
5735
- },
5736
- {
5737
- id: "highlight-active-points",
5738
- type: "circle",
5739
- filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "true"]],
5740
- paint: {
5741
- "circle-radius": 3,
5742
- "circle-color": "#fbb03b",
5743
- "circle-stroke-color": "#FFFFFF",
5744
- "circle-stroke-width": 1,
5745
- "circle-stroke-opacity": 0.3,
5746
- },
5747
- },
5748
- {
5749
- id: "gl-draw-polygon-fill-static",
5750
- type: "fill",
5751
- filter: ["all", ["==", "$type", "Polygon"]],
5752
- paint: {
5753
- "fill-color": "#D20C0C",
5754
- "fill-outline-color": "#D20C0C",
5755
- "fill-opacity": 0.1,
5756
- },
5757
- },
5758
- {
5759
- id: "gl-draw-line",
5760
- type: "line",
5761
- filter: ["all", ["==", "$type", "LineString"]],
5830
+ const GRID_TILE_SIZE = "4.5rem";
5831
+ const LIST_ICON_SIZE = "1.5rem";
5832
+ const JPG_MIME_TYPE = "image/jpeg";
5833
+ const PNG_MIME_TYPE = "image/png";
5834
+ const IMAGE_MIME_TYPES = [
5835
+ "image/apng",
5836
+ "image/avif",
5837
+ "image/gif",
5838
+ "image/jpeg",
5839
+ "image/png",
5840
+ "image/svg+xml",
5841
+ "image/webp",
5842
+ ];
5843
+ const XLSX_MIME_TYPES = [
5844
+ "application/vnd.ms-excel",
5845
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
5846
+ ];
5847
+ const PDF_MIME_TYPE = "application/pdf";
5848
+ const DOCX_MIME_TYPES = [
5849
+ "application/msword",
5850
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
5851
+ ];
5852
+ const CSV_MIME_TYPE = "text/csv";
5853
+ const JSON_MIME_TYPE = "application/json";
5854
+ const TXT_MIME_TYPE = "text/plain";
5855
+ const PPTX_MIME_TYPES = [
5856
+ "application/vnd.ms-powerpoint",
5857
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
5858
+ ];
5859
+ const SHP_MIME_TYPE = "application/octet-stream";
5860
+ const KML_MIME_TYPE = "application/octet-stream";
5861
+ const ZIP_MIME_TYPE = "application/zip";
5862
+ const PYTHON_MIME_TYPES = ["application/x-python-code", "text/x-python"];
5863
+ var AddAttachmentSource;
5864
+ (function (AddAttachmentSource) {
5865
+ AddAttachmentSource["Pc"] = "pc";
5866
+ AddAttachmentSource["Catalog"] = "catalog";
5867
+ AddAttachmentSource["Link"] = "link";
5868
+ })(AddAttachmentSource || (AddAttachmentSource = {}));
5869
+
5870
+ var FileType;
5871
+ (function (FileType) {
5872
+ FileType[FileType["UNKNOWN"] = 0] = "UNKNOWN";
5873
+ FileType[FileType["XLSX"] = 1] = "XLSX";
5874
+ FileType[FileType["PDF"] = 2] = "PDF";
5875
+ FileType[FileType["CSV"] = 3] = "CSV";
5876
+ FileType[FileType["DOCX"] = 4] = "DOCX";
5877
+ FileType[FileType["IMAGE"] = 5] = "IMAGE";
5878
+ FileType[FileType["TXT"] = 6] = "TXT";
5879
+ FileType[FileType["JSON"] = 7] = "JSON";
5880
+ FileType[FileType["KML"] = 8] = "KML";
5881
+ FileType[FileType["PPTX"] = 9] = "PPTX";
5882
+ FileType[FileType["SHP"] = 10] = "SHP";
5883
+ FileType[FileType["ZIP"] = 11] = "ZIP";
5884
+ FileType[FileType["JPEG"] = 12] = "JPEG";
5885
+ FileType[FileType["JPG"] = 13] = "JPG";
5886
+ FileType[FileType["PNG"] = 14] = "PNG";
5887
+ FileType[FileType["PYTHON"] = 15] = "PYTHON";
5888
+ })(FileType || (FileType = {}));
5889
+ const IMAGE_FILE_TYPES = [
5890
+ FileType.IMAGE,
5891
+ FileType.JPEG,
5892
+ FileType.JPG,
5893
+ FileType.PNG,
5894
+ ];
5895
+
5896
+ const getFileType = (mimeType = "", name = "") => {
5897
+ if (mimeType === PNG_MIME_TYPE)
5898
+ return FileType.PNG;
5899
+ if (mimeType === JPG_MIME_TYPE)
5900
+ return FileType.JPG;
5901
+ if (IMAGE_MIME_TYPES.includes(mimeType))
5902
+ return FileType.IMAGE;
5903
+ if (XLSX_MIME_TYPES.includes(mimeType))
5904
+ return FileType.XLSX;
5905
+ if (DOCX_MIME_TYPES.includes(mimeType))
5906
+ return FileType.DOCX;
5907
+ if (mimeType === CSV_MIME_TYPE)
5908
+ return FileType.CSV;
5909
+ if (mimeType === PDF_MIME_TYPE)
5910
+ return FileType.PDF;
5911
+ if (mimeType === JSON_MIME_TYPE)
5912
+ return FileType.JSON;
5913
+ if (mimeType === KML_MIME_TYPE && (name.endsWith(".kml") || name.endsWith(".kmz"))) {
5914
+ return FileType.KML;
5915
+ }
5916
+ if (PYTHON_MIME_TYPES.includes(mimeType))
5917
+ return FileType.PYTHON;
5918
+ if (mimeType === TXT_MIME_TYPE && name.endsWith(".py"))
5919
+ return FileType.PYTHON;
5920
+ if (mimeType === TXT_MIME_TYPE)
5921
+ return FileType.TXT;
5922
+ if (PPTX_MIME_TYPES.includes(mimeType))
5923
+ return FileType.PPTX;
5924
+ if (mimeType === SHP_MIME_TYPE && name.endsWith(".shp"))
5925
+ return FileType.SHP;
5926
+ if (mimeType === ZIP_MIME_TYPE)
5927
+ return FileType.ZIP;
5928
+ return name.endsWith(".py") ? FileType.PYTHON : FileType.UNKNOWN;
5929
+ };
5930
+
5931
+ 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";
5932
+
5933
+ 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";
5934
+
5935
+ 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";
5936
+
5937
+ 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";
5938
+
5939
+ 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";
5940
+
5941
+ 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";
5942
+
5943
+ 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";
5944
+
5945
+ 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";
5946
+
5947
+ 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";
5948
+
5949
+ 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";
5950
+
5951
+ 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";
5952
+
5953
+ 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";
5954
+
5955
+ 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";
5956
+
5957
+ 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";
5958
+
5959
+ 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";
5960
+
5961
+ const getFileTypeIcon = (fileType) => {
5962
+ switch (fileType) {
5963
+ case FileType.CSV:
5964
+ return img$i;
5965
+ case FileType.XLSX:
5966
+ return img$6;
5967
+ case FileType.DOCX:
5968
+ return img$h;
5969
+ case FileType.PDF:
5970
+ return img$c;
5971
+ case FileType.JSON:
5972
+ return img$e;
5973
+ case FileType.KML:
5974
+ return img$d;
5975
+ case FileType.PPTX:
5976
+ return img$a;
5977
+ case FileType.SHP:
5978
+ return img$8;
5979
+ case FileType.TXT:
5980
+ return img$7;
5981
+ case FileType.ZIP:
5982
+ return img$5;
5983
+ case FileType.IMAGE:
5984
+ case FileType.JPEG:
5985
+ return img$g;
5986
+ case FileType.JPG:
5987
+ return img$f;
5988
+ case FileType.PNG:
5989
+ return img$b;
5990
+ case FileType.PYTHON:
5991
+ return img$9;
5992
+ default:
5993
+ return img$j;
5994
+ }
5995
+ };
5996
+
5997
+ const useAttachmentPreviewImages = ({ items, active, }) => {
5998
+ const { api } = useGlobalContext();
5999
+ const [blobUrls, setBlobUrls] = useState({});
6000
+ const [failedLinks, setFailedLinks] = useState({});
6001
+ const inFlightRef = useRef(new Set());
6002
+ const blobUrlsRef = useRef(blobUrls);
6003
+ blobUrlsRef.current = blobUrls;
6004
+ useEffect(() => {
6005
+ if (!active || !api?.catalog?.getFile)
6006
+ return;
6007
+ items.forEach(item => {
6008
+ const fileType = getFileType(item.mimeType, item.name);
6009
+ const isImage = IMAGE_FILE_TYPES.includes(fileType);
6010
+ if (!isImage || item.isExternal)
6011
+ return;
6012
+ if (blobUrlsRef.current[item.link] || inFlightRef.current.has(item.link))
6013
+ return;
6014
+ inFlightRef.current.add(item.link);
6015
+ api.catalog
6016
+ .getFile(item.link)
6017
+ .then(blob => {
6018
+ const objectUrl = URL.createObjectURL(blob);
6019
+ setBlobUrls(prev => ({ ...prev, [item.link]: objectUrl }));
6020
+ })
6021
+ .catch(() => {
6022
+ setFailedLinks(prev => (prev[item.link] ? prev : { ...prev, [item.link]: true }));
6023
+ })
6024
+ .finally(() => {
6025
+ inFlightRef.current.delete(item.link);
6026
+ });
6027
+ });
6028
+ }, [active, api, items]);
6029
+ useEffect(() => () => {
6030
+ Object.values(blobUrlsRef.current).forEach(URL.revokeObjectURL);
6031
+ }, []);
6032
+ return useMemo(() => items.map(item => {
6033
+ const fileType = getFileType(item.mimeType, item.name);
6034
+ const isImage = IMAGE_FILE_TYPES.includes(fileType);
6035
+ const fileName = item.name;
6036
+ if (!isImage)
6037
+ return { src: getFileTypeIcon(fileType), fileName };
6038
+ if (item.isExternal)
6039
+ return { src: item.link, fileName };
6040
+ const hasError = !!failedLinks[item.link];
6041
+ const blobUrl = blobUrls[item.link];
6042
+ return {
6043
+ src: blobUrl ?? "",
6044
+ fileName,
6045
+ hasError,
6046
+ isLoading: !hasError && !blobUrl,
6047
+ };
6048
+ }), [items, blobUrls, failedLinks]);
6049
+ };
6050
+
6051
+ const useAutoCompleteControl = (items) => {
6052
+ const [value, setValue] = useState("");
6053
+ const [options, setOptions] = useState([]);
6054
+ const staticOptions = useMemo(() => (items ?? [])
6055
+ .filter(Boolean)
6056
+ .map(item => ({ text: String(item), value: String(item) })), [items]);
6057
+ const onChange = useCallback((newValue) => setValue(newValue), []);
6058
+ return {
6059
+ value,
6060
+ setValue,
6061
+ onChange,
6062
+ options: staticOptions.length ? staticOptions : options,
6063
+ setOptions,
6064
+ };
6065
+ };
6066
+
6067
+ /**
6068
+ * Пропсы хоста фонового слоя для корней, которые не берут пропсы из `useWrapperSize`
6069
+ * (ставят `id`/`style` руками — `Title`, `Icon`, `Tabs`, `AddFeature`, `ExportPdf`, …).
6070
+ *
6071
+ * Контейнеры на `useContainerRoot` этот хук напрямую не зовут: `useWrapperSize` вызывает его
6072
+ * сам и кладёт результат в `root` — так признаки хоста считаются в одном месте.
6073
+ */
6074
+ const useBgImageHost = (elementConfig) => {
6075
+ const hasBgImage = useMemo(() => hasContainerBgImage(elementConfig), [elementConfig]);
6076
+ const innerPadding = !!elementConfig?.options?.innerPadding;
6077
+ return useMemo(() => ({ $hasBgImage: hasBgImage, $innerPadding: innerPadding }), [hasBgImage, innerPadding]);
6078
+ };
6079
+
6080
+ const useRenderContainerItem = (type, renderElement) => {
6081
+ const { config, layerInfo, selectedTabId, attributes } = useWidgetContext(type);
6082
+ return useCallback((elementConfig, attribute) => {
6083
+ const { id, options, style, children } = elementConfig || {};
6084
+ const { hideEmpty, innerTemplateStyle } = options || {};
6085
+ const hasUnits = children?.some(item => item.id === "units");
6086
+ const iconIndex = children?.findIndex(item => item.id === "icon");
6087
+ const icon = children?.[iconIndex];
6088
+ const hasIcon = !!icon;
6089
+ const elementChildren = elementConfig?.children?.map(child => ({
6090
+ type: "attributeValue",
6091
+ ...child,
6092
+ attributeName: attribute,
6093
+ options: { noUnits: hasUnits, ...child.options },
6094
+ }));
6095
+ const attr = getAttributeConfigurationByName(getAttributesConfiguration(layerInfo).attributes, attribute);
6096
+ if (hasIcon) {
6097
+ elementChildren[iconIndex] = {
6098
+ ...elementChildren[iconIndex],
6099
+ ...getAttributeIconElement(attr?.icon),
6100
+ attributeName: null,
6101
+ };
6102
+ }
6103
+ const render = attribute
6104
+ ? getRenderElement({
6105
+ config,
6106
+ elementConfig: {
6107
+ ...elementConfig,
6108
+ children: elementChildren,
6109
+ },
6110
+ selectedTabId,
6111
+ attributes,
6112
+ layerInfo,
6113
+ type,
6114
+ })
6115
+ : renderElement;
6116
+ const value = render({ id: "value" });
6117
+ return {
6118
+ id,
6119
+ value,
6120
+ hideEmpty,
6121
+ style: innerTemplateStyle || style,
6122
+ hasIcon,
6123
+ hasUnits,
6124
+ render,
6125
+ };
6126
+ }, [config, layerInfo, selectedTabId, attributes, type, renderElement]);
6127
+ };
6128
+
6129
+ const customModes = MapboxDraw.modes;
6130
+ const StaticMode = {};
6131
+ const InvisibleMode = {};
6132
+ StaticMode.onSetup = function () {
6133
+ this.setActionableState(undefined);
6134
+ return {};
6135
+ };
6136
+ StaticMode.toDisplayFeatures = function (state, geojson, display) {
6137
+ display(geojson);
6138
+ };
6139
+ InvisibleMode.onSetup = function () {
6140
+ this.setActionableState(undefined);
6141
+ return {};
6142
+ };
6143
+ InvisibleMode.toDisplayFeatures = function () { };
6144
+ customModes.static = StaticMode;
6145
+ customModes.invisible = InvisibleMode;
6146
+
6147
+ const customStyles = [
6148
+ {
6149
+ id: "gl-draw-point",
6150
+ type: "circle",
6151
+ filter: ["all", ["==", "$type", "Point"]],
6152
+ paint: {
6153
+ "circle-radius": 5,
6154
+ "circle-color": "#D20C0C",
6155
+ "circle-stroke-color": "#FFFFFF",
6156
+ "circle-stroke-width": 3,
6157
+ "circle-stroke-opacity": 0.3,
6158
+ },
6159
+ },
6160
+ {
6161
+ id: "highlight-inactive-points",
6162
+ type: "circle",
6163
+ filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "false"]],
6164
+ paint: {
6165
+ "circle-radius": 5,
6166
+ "circle-color": "#D20C0C",
6167
+ "circle-stroke-color": "#FFFFFF",
6168
+ "circle-stroke-width": 3,
6169
+ "circle-stroke-opacity": 0.3,
6170
+ },
6171
+ },
6172
+ {
6173
+ id: "highlight-active-points",
6174
+ type: "circle",
6175
+ filter: ["all", ["==", "$type", "Point"], ["==", "meta", "feature"], ["==", "active", "true"]],
6176
+ paint: {
6177
+ "circle-radius": 3,
6178
+ "circle-color": "#fbb03b",
6179
+ "circle-stroke-color": "#FFFFFF",
6180
+ "circle-stroke-width": 1,
6181
+ "circle-stroke-opacity": 0.3,
6182
+ },
6183
+ },
6184
+ {
6185
+ id: "gl-draw-polygon-fill-static",
6186
+ type: "fill",
6187
+ filter: ["all", ["==", "$type", "Polygon"]],
6188
+ paint: {
6189
+ "fill-color": "#D20C0C",
6190
+ "fill-outline-color": "#D20C0C",
6191
+ "fill-opacity": 0.1,
6192
+ },
6193
+ },
6194
+ {
6195
+ id: "gl-draw-line",
6196
+ type: "line",
6197
+ filter: ["all", ["==", "$type", "LineString"]],
5762
6198
  layout: {
5763
6199
  "line-cap": "round",
5764
6200
  "line-join": "round",
@@ -6367,326 +6803,337 @@ const useLayerParams = (layer) => {
6367
6803
  return layerParams;
6368
6804
  };
6369
6805
 
6370
- const parseAttachments = (raw) => {
6371
- if (!raw)
6372
- return [];
6373
- if (Array.isArray(raw))
6374
- return raw;
6375
- if (typeof raw !== "string")
6376
- return [];
6377
- try {
6378
- const parsed = JSON.parse(raw);
6379
- return Array.isArray(parsed) ? parsed : [];
6380
- }
6381
- catch {
6382
- return [];
6383
- }
6384
- };
6385
- const attachmentsFromFeatures = (features, mapping = {}) => {
6386
- if (!features?.length)
6387
- return [];
6388
- const { attributeLink = "link", attributeName = "name", attributeMime = "mimeType", attributeDate = "date", } = mapping;
6389
- return features
6390
- .map(feature => {
6391
- const link = feature.properties?.[attributeLink];
6392
- if (!link)
6393
- return null;
6394
- return {
6395
- link,
6396
- name: feature.properties?.[attributeName] ?? link,
6397
- mimeType: feature.properties?.[attributeMime] ?? "",
6398
- date: feature.properties?.[attributeDate],
6399
- isExternal: /^https?:\/\//.test(link),
6400
- };
6401
- })
6402
- .filter(Boolean);
6403
- };
6404
-
6405
- const useAttachmentItems = ({ type, elementConfig, valueOverride, }) => {
6406
- const { attributes, dataSources } = useWidgetContext(type);
6407
- const { children, options } = elementConfig || {};
6408
- const { relatedDataSource, controls } = options || {};
6409
- const valueElement = useMemo(() => children?.find(({ id }) => id === "value"), [children]);
6410
- const attributeName = useMemo(() => {
6411
- const candidate = valueElement?.attributeName ?? elementConfig?.attributeName;
6412
- return Array.isArray(candidate) ? candidate[0] : candidate;
6413
- }, [valueElement, elementConfig]);
6414
- const rawValue = useMemo(() => {
6415
- if (valueOverride !== undefined)
6416
- return valueOverride;
6417
- if (!attributeName)
6418
- return undefined;
6419
- return attributes?.find(item => item.attributeName === attributeName)?.value;
6420
- }, [valueOverride, attributeName, attributes]);
6421
- const items = useMemo(() => {
6422
- if (relatedDataSource) {
6423
- const dataSource = dataSources?.find(({ name }) => name === relatedDataSource);
6424
- const mapping = controls?.[0];
6425
- return attachmentsFromFeatures(dataSource?.features, mapping);
6806
+ const useMaxZoomTo = () => {
6807
+ const { currentPage } = useWidgetPage();
6808
+ return useCallback((layerName) => {
6809
+ if (!layerName) {
6810
+ return [currentPage?.options?.maxZoomTo, undefined];
6426
6811
  }
6427
- return parseAttachments(rawValue);
6428
- }, [relatedDataSource, dataSources, controls, rawValue]);
6429
- return {
6430
- items,
6431
- attributeName,
6432
- rawValue,
6433
- };
6434
- };
6435
-
6436
- const useGlobalContext = () => {
6437
- const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, notification } = useContext(GlobalContext) || {};
6438
- const translate = useCallback((value, options) => {
6439
- if (t)
6440
- return t(value, options);
6441
- return options?.defaultValue ?? value;
6442
- }, [t]);
6443
- return useMemo(() => ({
6444
- t: translate,
6445
- language,
6446
- themeName,
6447
- api,
6448
- ewktGeometry,
6449
- ewktExtent,
6450
- zoomLevel,
6451
- notification,
6452
- }), [language, translate, api, ewktGeometry, ewktExtent, zoomLevel, themeName, notification]);
6453
- };
6454
-
6455
- const GRID_TILE_SIZE = "4.5rem";
6456
- const LIST_ICON_SIZE = "1.5rem";
6457
- const JPG_MIME_TYPE = "image/jpeg";
6458
- const PNG_MIME_TYPE = "image/png";
6459
- const IMAGE_MIME_TYPES = [
6460
- "image/apng",
6461
- "image/avif",
6462
- "image/gif",
6463
- "image/jpeg",
6464
- "image/png",
6465
- "image/svg+xml",
6466
- "image/webp",
6467
- ];
6468
- const XLSX_MIME_TYPES = [
6469
- "application/vnd.ms-excel",
6470
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
6471
- ];
6472
- const PDF_MIME_TYPE = "application/pdf";
6473
- const DOCX_MIME_TYPES = [
6474
- "application/msword",
6475
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
6476
- ];
6477
- const CSV_MIME_TYPE = "text/csv";
6478
- const JSON_MIME_TYPE = "application/json";
6479
- const TXT_MIME_TYPE = "text/plain";
6480
- const PPTX_MIME_TYPES = [
6481
- "application/vnd.ms-powerpoint",
6482
- "application/vnd.openxmlformats-officedocument.presentationml.presentation",
6483
- ];
6484
- const SHP_MIME_TYPE = "application/octet-stream";
6485
- const KML_MIME_TYPE = "application/octet-stream";
6486
- const ZIP_MIME_TYPE = "application/zip";
6487
- const PYTHON_MIME_TYPES = ["application/x-python-code", "text/x-python"];
6488
- var AddAttachmentSource;
6489
- (function (AddAttachmentSource) {
6490
- AddAttachmentSource["Pc"] = "pc";
6491
- AddAttachmentSource["Catalog"] = "catalog";
6492
- AddAttachmentSource["Link"] = "link";
6493
- })(AddAttachmentSource || (AddAttachmentSource = {}));
6494
-
6495
- var FileType;
6496
- (function (FileType) {
6497
- FileType[FileType["UNKNOWN"] = 0] = "UNKNOWN";
6498
- FileType[FileType["XLSX"] = 1] = "XLSX";
6499
- FileType[FileType["PDF"] = 2] = "PDF";
6500
- FileType[FileType["CSV"] = 3] = "CSV";
6501
- FileType[FileType["DOCX"] = 4] = "DOCX";
6502
- FileType[FileType["IMAGE"] = 5] = "IMAGE";
6503
- FileType[FileType["TXT"] = 6] = "TXT";
6504
- FileType[FileType["JSON"] = 7] = "JSON";
6505
- FileType[FileType["KML"] = 8] = "KML";
6506
- FileType[FileType["PPTX"] = 9] = "PPTX";
6507
- FileType[FileType["SHP"] = 10] = "SHP";
6508
- FileType[FileType["ZIP"] = 11] = "ZIP";
6509
- FileType[FileType["JPEG"] = 12] = "JPEG";
6510
- FileType[FileType["JPG"] = 13] = "JPG";
6511
- FileType[FileType["PNG"] = 14] = "PNG";
6512
- FileType[FileType["PYTHON"] = 15] = "PYTHON";
6513
- })(FileType || (FileType = {}));
6514
- const IMAGE_FILE_TYPES = [
6515
- FileType.IMAGE,
6516
- FileType.JPEG,
6517
- FileType.JPG,
6518
- FileType.PNG,
6519
- ];
6520
-
6521
- const getFileType = (mimeType = "", name = "") => {
6522
- if (mimeType === PNG_MIME_TYPE)
6523
- return FileType.PNG;
6524
- if (mimeType === JPG_MIME_TYPE)
6525
- return FileType.JPG;
6526
- if (IMAGE_MIME_TYPES.includes(mimeType))
6527
- return FileType.IMAGE;
6528
- if (XLSX_MIME_TYPES.includes(mimeType))
6529
- return FileType.XLSX;
6530
- if (DOCX_MIME_TYPES.includes(mimeType))
6531
- return FileType.DOCX;
6532
- if (mimeType === CSV_MIME_TYPE)
6533
- return FileType.CSV;
6534
- if (mimeType === PDF_MIME_TYPE)
6535
- return FileType.PDF;
6536
- if (mimeType === JSON_MIME_TYPE)
6537
- return FileType.JSON;
6538
- if (mimeType === KML_MIME_TYPE && (name.endsWith(".kml") || name.endsWith(".kmz"))) {
6539
- return FileType.KML;
6540
- }
6541
- if (PYTHON_MIME_TYPES.includes(mimeType))
6542
- return FileType.PYTHON;
6543
- if (mimeType === TXT_MIME_TYPE && name.endsWith(".py"))
6544
- return FileType.PYTHON;
6545
- if (mimeType === TXT_MIME_TYPE)
6546
- return FileType.TXT;
6547
- if (PPTX_MIME_TYPES.includes(mimeType))
6548
- return FileType.PPTX;
6549
- if (mimeType === SHP_MIME_TYPE && name.endsWith(".shp"))
6550
- return FileType.SHP;
6551
- if (mimeType === ZIP_MIME_TYPE)
6552
- return FileType.ZIP;
6553
- return name.endsWith(".py") ? FileType.PYTHON : FileType.UNKNOWN;
6812
+ return [currentPage?.options?.maxZoomTo, currentPage?.layers?.find(item => item.name === layerName)?.maxZoomTo];
6813
+ }, [currentPage?.layers, currentPage?.options?.maxZoomTo]);
6554
6814
  };
6555
6815
 
6556
- 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";
6557
-
6558
- 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";
6559
-
6560
- 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";
6561
-
6562
- 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";
6816
+ const useCustomFeatureSelect = () => {
6817
+ const { currentPage } = useWidgetPage();
6818
+ return useCallback((layerName) => {
6819
+ if (!layerName) {
6820
+ return [currentPage?.options?.customFeatureSelect, undefined];
6821
+ }
6822
+ return [
6823
+ currentPage?.options?.customFeatureSelect,
6824
+ currentPage?.layers?.find(item => item.name === layerName)?.customFeatureSelect,
6825
+ ];
6826
+ }, [currentPage?.layers, currentPage?.options?.customFeatureSelect]);
6827
+ };
6563
6828
 
6564
- 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";
6829
+ const useCurrentPageLayers = () => {
6830
+ const { currentPage } = useWidgetPage();
6831
+ return useMemo(() => currentPage?.layers || [], [currentPage?.layers]);
6832
+ };
6565
6833
 
6566
- 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";
6834
+ const useLayerHiddenAttributes = (layerName) => {
6835
+ const { currentPage, updateConfigPage } = useWidgetPage();
6836
+ const layerHiddenAttributes = useMemo(() => {
6837
+ return currentPage?.layers?.find(item => item.name === layerName)?.hiddenAttributes ?? [];
6838
+ }, [currentPage?.layers, layerName]);
6839
+ const updateLayerHiddenAttributes = useCallback((updatedHiddenAttributes) => {
6840
+ updateConfigPage({
6841
+ ...currentPage,
6842
+ layers: currentPage?.layers?.map(item => {
6843
+ return item.name === layerName
6844
+ ? {
6845
+ ...item,
6846
+ hiddenAttributes: updatedHiddenAttributes,
6847
+ }
6848
+ : item;
6849
+ }),
6850
+ });
6851
+ }, [currentPage, layerName, updateConfigPage]);
6852
+ return [layerHiddenAttributes, updateLayerHiddenAttributes];
6853
+ };
6567
6854
 
6568
- 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";
6855
+ const useVisibleProjectItems = (applyMinMaxScale) => {
6856
+ const { map } = useMapContext();
6857
+ const projectItems = useCurrentPageLayers();
6858
+ const zoomChange = useMemo(() => (applyMinMaxScale && map.current?.getZoom() !== undefined ? Math.round(map.current?.getZoom()) : undefined), [applyMinMaxScale, map.current?.getZoom()]);
6859
+ return useMemo(() => {
6860
+ if (map.current?.getZoom() === undefined) {
6861
+ return [];
6862
+ }
6863
+ return (projectItems?.filter(item => item.isVisible &&
6864
+ (!applyMinMaxScale ||
6865
+ (Math.round(map.current.getZoom()) >= (item.minScale ?? 0) &&
6866
+ Math.round(map.current.getZoom()) <= (item.maxScale ?? 30)))) ?? []);
6867
+ }, [projectItems, zoomChange, applyMinMaxScale]);
6868
+ };
6569
6869
 
6570
- 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";
6870
+ const useServerNotificationsContext = () => {
6871
+ return useContext(ServerNotificationsContext);
6872
+ };
6571
6873
 
6572
- 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";
6874
+ const SERVER_NOTIFICATION_EVENT = {
6875
+ ReceiveFeaturesUpdate: "ReceiveFeaturesUpdateNotification",
6876
+ PythonProgressNotification: "ReceivePythonProgressNotification",
6877
+ PythonSandboxStats: "ReceivePythonSandboxStatsNotification",
6878
+ };
6879
+ const POLL_SUBTASK_INTERVAL_MS = 500;
6880
+ const POLL_SUBTASK_TIMEOUT_MS = 15_000;
6573
6881
 
6574
- 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";
6882
+ const usePythonSandbox = () => {
6883
+ const { api } = useGlobalContext();
6884
+ const preparePythonSandbox = useCallback(({ resourceId, isNotebook = false }) => api.remoteTaskManager.post({
6885
+ workerType: "pythonService",
6886
+ methodType: "pythonrunner/prepare",
6887
+ data: { resourceId, isNotebook },
6888
+ }), [api.remoteTaskManager]);
6889
+ return { preparePythonSandbox };
6890
+ };
6575
6891
 
6576
- 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";
6892
+ const FINAL_STATUSES = [
6893
+ RemoteTaskStatus.Completed,
6894
+ RemoteTaskStatus.Error,
6895
+ RemoteTaskStatus.Interrupted,
6896
+ RemoteTaskStatus.Timeout,
6897
+ ];
6898
+ const wait = (ms) => new Promise(resolve => window.setTimeout(resolve, ms));
6899
+ const pollSubtaskCompletion = async ({ taskId, api, intervalMs = POLL_SUBTASK_INTERVAL_MS, timeoutMs = POLL_SUBTASK_TIMEOUT_MS, }) => {
6900
+ const deadline = Date.now() + timeoutMs;
6901
+ let subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
6902
+ while (subTask && !FINAL_STATUSES.includes(subTask.status)) {
6903
+ if (Date.now() >= deadline)
6904
+ return null;
6905
+ await wait(intervalMs);
6906
+ subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
6907
+ }
6908
+ return subTask;
6909
+ };
6577
6910
 
6578
- 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";
6911
+ const usePythonTask = () => {
6912
+ const { api, t } = useGlobalContext();
6913
+ const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
6914
+ const { preparePythonSandbox } = usePythonSandbox();
6915
+ const [status, setStatus] = useState(RemoteTaskStatus.Unknown);
6916
+ const [log, setLog] = useState(null);
6917
+ const [lastMessage, setLastMessage] = useState(null);
6918
+ const [error, setError] = useState(null);
6919
+ const [loading, setLoading] = useState(false);
6920
+ const [executionTime, setExecutionTime] = useState(null);
6921
+ const [taskId, setTaskId] = useState(null);
6922
+ const [subscriptionId, setSubscriptionId] = useState(null);
6923
+ const [isLogDialogOpen, setIsLogDialogOpen] = useState(false);
6924
+ const [result, setResult] = useState(null);
6925
+ const reset = useCallback(() => {
6926
+ setStatus(RemoteTaskStatus.Unknown);
6927
+ setError(null);
6928
+ setLoading(false);
6929
+ setExecutionTime(null);
6930
+ setTaskId(null);
6931
+ setSubscriptionId(null);
6932
+ setResult(null);
6933
+ }, []);
6934
+ const runTask = useCallback(async ({ resourceId, parameters, script, fileName, methodName, }) => {
6935
+ reset();
6936
+ setStatus(RemoteTaskStatus.Process);
6937
+ setLog(null);
6938
+ setLastMessage(null);
6939
+ setLoading(true);
6940
+ const start = Date.now();
6941
+ let prototypeId = await api.remoteTaskManager.createTaskPrototype({
6942
+ enabled: true,
6943
+ startIfPreviousError: true,
6944
+ startIfPreviousNotFinished: true,
6945
+ subTaskSettings: [
6946
+ {
6947
+ type: "pythonService",
6948
+ startParameters: {
6949
+ resourceId,
6950
+ parameters,
6951
+ script,
6952
+ fileName,
6953
+ methodName,
6954
+ method: "pythonrunner/run",
6955
+ },
6956
+ },
6957
+ ],
6958
+ });
6959
+ prototypeId = prototypeId.replace(/["']+/g, "");
6960
+ await preparePythonSandbox({ resourceId });
6961
+ const { id: newTaskId, success } = await api.remoteTaskManager.startTask1(prototypeId);
6962
+ if (!success) {
6963
+ setStatus(RemoteTaskStatus.Error);
6964
+ setLog(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
6965
+ setExecutionTime(Date.now() - start);
6966
+ setLoading(false);
6967
+ }
6968
+ const newSubscriptionId = await addSubscription({
6969
+ tag: "python_task_progress_event",
6970
+ resourceId,
6971
+ });
6972
+ setTaskId(newTaskId);
6973
+ setSubscriptionId(newSubscriptionId);
6974
+ const onNotification = async ({ data }) => {
6975
+ if (data?.taskId === newTaskId) {
6976
+ const isFinished = [RemoteTaskStatus.Completed, RemoteTaskStatus.Error].includes(data.status);
6977
+ setStatus(data.status);
6978
+ setLog(prev => [prev, data.log].filter(Boolean).join(""));
6979
+ if (data.log)
6980
+ setLastMessage(data.log);
6981
+ setExecutionTime(Date.now() - start);
6982
+ setLoading(false);
6983
+ setTaskId(isFinished ? null : newTaskId);
6984
+ setSubscriptionId(isFinished ? null : newSubscriptionId);
6985
+ if (isFinished) {
6986
+ unsubscribeById(newSubscriptionId);
6987
+ connection.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
6988
+ }
6989
+ if (data.status === RemoteTaskStatus.Completed) {
6990
+ try {
6991
+ const subTask = await pollSubtaskCompletion({ taskId: newTaskId, api });
6992
+ if (subTask?.status === RemoteTaskStatus.Completed) {
6993
+ const response = subTask.results?.response;
6994
+ setResult(typeof response === "object" && response !== null
6995
+ ? response
6996
+ : null);
6997
+ }
6998
+ else {
6999
+ setError(new Error(t("taskResultUnavailable", {
7000
+ ns: "devMode",
7001
+ defaultValue: "Не удалось получить результат задачи",
7002
+ })));
7003
+ }
7004
+ }
7005
+ catch (e) {
7006
+ setError(e instanceof Error ? e : new Error(String(e)));
7007
+ }
7008
+ }
7009
+ }
7010
+ };
7011
+ connection.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7012
+ }, [reset, api, preparePythonSandbox, addSubscription, connection, t, unsubscribeById]);
7013
+ const stopTask = useCallback(async () => {
7014
+ await api.remoteTaskManager.stop(taskId);
7015
+ reset();
7016
+ unsubscribeById(subscriptionId);
7017
+ }, [api, reset, unsubscribeById, taskId, subscriptionId]);
7018
+ const openLog = useCallback(() => {
7019
+ setIsLogDialogOpen(true);
7020
+ }, []);
7021
+ const closeLog = useCallback(() => {
7022
+ setIsLogDialogOpen(false);
7023
+ }, []);
7024
+ return {
7025
+ taskId,
7026
+ runTask,
7027
+ stopTask,
7028
+ openLog,
7029
+ log,
7030
+ lastMessage,
7031
+ error,
7032
+ status,
7033
+ loading,
7034
+ executionTime,
7035
+ isLogDialogOpen,
7036
+ closeLog,
7037
+ result,
7038
+ };
7039
+ };
6579
7040
 
6580
- 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";
7041
+ const useRemoteTask = ({ onUpdate } = {}) => {
7042
+ const { api } = useGlobalContext();
7043
+ const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
7044
+ const runTask = useCallback((prototype) => new Promise((resolve, reject) => {
7045
+ const start = async () => {
7046
+ const resourceId = prototype.subTaskSettings?.[0]?.startParameters?.resourceId;
7047
+ let prototypeId = await api.remoteTaskManager.createTaskPrototype(prototype);
7048
+ prototypeId = prototypeId.replace(/["']+/g, "");
7049
+ const { id: taskId, success } = await api.remoteTaskManager.startTask1(prototypeId);
7050
+ if (!success || !taskId) {
7051
+ reject(new Error("startTask returned no taskId"));
7052
+ return;
7053
+ }
7054
+ const subscriptionId = await addSubscription({
7055
+ tag: "python_task_progress_event",
7056
+ resourceId,
7057
+ });
7058
+ const onNotification = ({ data }) => {
7059
+ if (data?.taskId !== taskId) {
7060
+ return;
7061
+ }
7062
+ onUpdate?.({ status: data.status, log: data.log });
7063
+ const isCompleted = data.status === RemoteTaskStatus.Completed;
7064
+ const isError = data.status === RemoteTaskStatus.Error;
7065
+ if (isCompleted || isError) {
7066
+ connection?.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7067
+ if (subscriptionId) {
7068
+ unsubscribeById(subscriptionId);
7069
+ }
7070
+ resolve({
7071
+ taskId,
7072
+ status: isCompleted ? RemoteTaskStatus.Completed : RemoteTaskStatus.Error,
7073
+ log: data.log,
7074
+ });
7075
+ }
7076
+ };
7077
+ connection?.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7078
+ };
7079
+ start().catch(reject);
7080
+ }), [api, addSubscription, connection, unsubscribeById, onUpdate]);
7081
+ return { runTask };
7082
+ };
6581
7083
 
6582
- 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";
7084
+ const useAppHeight = () => {
7085
+ useEffect(() => {
7086
+ const setAppHeight = () => {
7087
+ document.documentElement.style.setProperty("--app-height", `${window.innerHeight}px`);
7088
+ };
7089
+ window.addEventListener("resize", setAppHeight);
7090
+ setAppHeight();
7091
+ return () => {
7092
+ window.removeEventListener("resize", setAppHeight);
7093
+ };
7094
+ }, []);
7095
+ };
6583
7096
 
6584
- 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";
7097
+ const useDebouncedCallback = (interval) => {
7098
+ return useMemo(() => debounce((cb) => {
7099
+ cb();
7100
+ }, interval), [interval]);
7101
+ };
6585
7102
 
6586
- const getFileTypeIcon = (fileType) => {
6587
- switch (fileType) {
6588
- case FileType.CSV:
6589
- return img$i;
6590
- case FileType.XLSX:
6591
- return img$6;
6592
- case FileType.DOCX:
6593
- return img$h;
6594
- case FileType.PDF:
6595
- return img$c;
6596
- case FileType.JSON:
6597
- return img$e;
6598
- case FileType.KML:
6599
- return img$d;
6600
- case FileType.PPTX:
6601
- return img$a;
6602
- case FileType.SHP:
6603
- return img$8;
6604
- case FileType.TXT:
6605
- return img$7;
6606
- case FileType.ZIP:
6607
- return img$5;
6608
- case FileType.IMAGE:
6609
- case FileType.JPEG:
6610
- return img$g;
6611
- case FileType.JPG:
6612
- return img$f;
6613
- case FileType.PNG:
6614
- return img$b;
6615
- case FileType.PYTHON:
6616
- return img$9;
6617
- default:
6618
- return img$j;
6619
- }
7103
+ const useToggle = (initial) => {
7104
+ const [state, setState] = useState(initial !== undefined ? initial : false);
7105
+ const toggle = useCallback(() => setState(!state), [state]);
7106
+ return [state, toggle, setState];
6620
7107
  };
6621
7108
 
6622
- const useAttachmentPreviewImages = ({ items, active, }) => {
6623
- const { api } = useGlobalContext();
6624
- const [blobUrls, setBlobUrls] = useState({});
6625
- const [failedLinks, setFailedLinks] = useState({});
6626
- const inFlightRef = useRef(new Set());
6627
- const blobUrlsRef = useRef(blobUrls);
6628
- blobUrlsRef.current = blobUrls;
7109
+ const DEBOUNCE_DELAY = 144;
7110
+ const useWindowResize = (callback, delay) => {
7111
+ const debounceCallback = useMemo(() => {
7112
+ return callback ? debounce(callback, delay || DEBOUNCE_DELAY) : undefined;
7113
+ }, [callback, delay]);
6629
7114
  useEffect(() => {
6630
- if (!active || !api?.catalog?.getFile)
6631
- return;
6632
- items.forEach(item => {
6633
- const fileType = getFileType(item.mimeType, item.name);
6634
- const isImage = IMAGE_FILE_TYPES.includes(fileType);
6635
- if (!isImage || item.isExternal)
6636
- return;
6637
- if (blobUrlsRef.current[item.link] || inFlightRef.current.has(item.link))
6638
- return;
6639
- inFlightRef.current.add(item.link);
6640
- api.catalog
6641
- .getFile(item.link)
6642
- .then(blob => {
6643
- const objectUrl = URL.createObjectURL(blob);
6644
- setBlobUrls(prev => ({ ...prev, [item.link]: objectUrl }));
6645
- })
6646
- .catch(() => {
6647
- setFailedLinks(prev => (prev[item.link] ? prev : { ...prev, [item.link]: true }));
6648
- })
6649
- .finally(() => {
6650
- inFlightRef.current.delete(item.link);
6651
- });
6652
- });
6653
- }, [active, api, items]);
6654
- useEffect(() => () => {
6655
- Object.values(blobUrlsRef.current).forEach(URL.revokeObjectURL);
6656
- }, []);
6657
- return useMemo(() => items.map(item => {
6658
- const fileType = getFileType(item.mimeType, item.name);
6659
- const isImage = IMAGE_FILE_TYPES.includes(fileType);
6660
- const fileName = item.name;
6661
- if (!isImage)
6662
- return { src: getFileTypeIcon(fileType), fileName };
6663
- if (item.isExternal)
6664
- return { src: item.link, fileName };
6665
- const hasError = !!failedLinks[item.link];
6666
- const blobUrl = blobUrls[item.link];
6667
- return {
6668
- src: blobUrl ?? "",
6669
- fileName,
6670
- hasError,
6671
- isLoading: !hasError && !blobUrl,
6672
- };
6673
- }), [items, blobUrls, failedLinks]);
7115
+ debounceCallback && window.addEventListener("resize", debounceCallback);
7116
+ return () => debounceCallback && window.removeEventListener("resize", debounceCallback);
7117
+ }, [debounceCallback]);
6674
7118
  };
6675
7119
 
6676
- const useAutoCompleteControl = (items) => {
6677
- const [value, setValue] = useState("");
6678
- const [options, setOptions] = useState([]);
6679
- const staticOptions = useMemo(() => (items ?? [])
6680
- .filter(Boolean)
6681
- .map(item => ({ text: String(item), value: String(item) })), [items]);
6682
- const onChange = useCallback((newValue) => setValue(newValue), []);
6683
- return {
6684
- value,
6685
- setValue,
6686
- onChange,
6687
- options: staticOptions.length ? staticOptions : options,
6688
- setOptions,
6689
- };
7120
+ const useContainerAttributes = ({ elementConfig, type, renderElement }) => {
7121
+ const getRenderContainerItem = useRenderContainerItem(type, renderElement);
7122
+ const { options } = elementConfig || {};
7123
+ const { attributes: optionAttributes, useProjectHiddenAttributes } = options || {};
7124
+ const { attributes: contextAttributes, layerInfo } = useWidgetContext(type);
7125
+ const [hiddenAttributes] = useLayerHiddenAttributes(layerInfo?.name ?? "");
7126
+ const attributesToRender = useMemo(() => {
7127
+ if (!optionAttributes)
7128
+ return null;
7129
+ const baseList = optionAttributes.length === 0
7130
+ ? contextAttributes?.map(({ attributeName }) => attributeName) ?? []
7131
+ : optionAttributes;
7132
+ if (!useProjectHiddenAttributes)
7133
+ return baseList;
7134
+ return baseList.filter(attribute => !hiddenAttributes.includes(attribute));
7135
+ }, [optionAttributes, contextAttributes, hiddenAttributes, useProjectHiddenAttributes]);
7136
+ return { getRenderContainerItem, attributesToRender };
6690
7137
  };
6691
7138
 
6692
7139
  /**
@@ -6699,10 +7146,15 @@ const useAutoCompleteControl = (items) => {
6699
7146
  * `data-id` и `$noMargin` раньше жили на внешней обёртке `ElementValueWrapper`; она вешала их
6700
7147
  * на второй узел поверх этого корня, дублируя стили, и для таких контейнеров больше не создаётся
6701
7148
  * (см. `ROOT_OWNING_TEMPLATES`).
7149
+ *
7150
+ * Пропсы хоста фонового слоя (`$hasBgImage`, `$innerPadding`) подмешиваются здесь, а не в каждом
7151
+ * контейнере: корень и так получает пропсы одним спредом, поэтому фон и внутренний отступ
7152
+ * включаются без единой дополнительной строки на месте вызова.
6702
7153
  */
6703
7154
  const useWrapperSize = ({ elementConfig, defaults }) => {
6704
7155
  const { id, style, templateName, options } = elementConfig || {};
6705
7156
  const { width, height, overflow, noMargin, autoHeight } = options || {};
7157
+ const bgHost = useBgImageHost(elementConfig);
6706
7158
  return useMemo(() => ({
6707
7159
  id,
6708
7160
  "data-id": id,
@@ -6718,7 +7170,8 @@ const useWrapperSize = ({ elementConfig, defaults }) => {
6718
7170
  heightAsMin: autoHeight,
6719
7171
  }),
6720
7172
  $noMargin: noMargin,
6721
- }), [id, templateName, style, width, height, overflow, noMargin, autoHeight, defaults]);
7173
+ ...bgHost,
7174
+ }), [id, templateName, style, width, height, overflow, noMargin, autoHeight, defaults, bgHost]);
6722
7175
  };
6723
7176
 
6724
7177
  /**
@@ -7535,110 +7988,55 @@ const useDiffPage = (type) => {
7535
7988
  * Натуральная ширина каждой плитки измеряется через временное inline `width: max-content`
7536
7989
  * (снимает применённое ограничение `--tile-width`, поэтому замер устойчив к динамике данных и не
7537
7990
  * зацикливает ResizeObserver — итоговый максимум совпадает с уже применённым). Возвращаемое число
7538
- * контейнер прокидывает в CSS-переменную `--tile-width`, которую читает каждая плитка.
7539
- *
7540
- * Результат ограничен шириной ячейки ряда: плитка задаёт свою ширину в пикселях и в grid не
7541
- * сжимается вместе с треком (`flex-shrink` там не действует, а `min-width: 0` базового
7542
- * контейнера позволяет треку ужаться), поэтому натуральная ширина шире ячейки означала бы
7543
- * наложение соседних плиток друг на друга.
7544
- *
7545
- * `enabled: false` полностью отключает измерение — ширина берётся из grid-ячейки.
7546
- */
7547
- const useEqualTileWidth = ({ enabled, itemsCount, columns, gap, }) => {
7548
- const ref = useRef(null);
7549
- const [width, setWidth] = useState();
7550
- const measure = useCallback(() => {
7551
- const node = ref.current;
7552
- if (!node)
7553
- return;
7554
- const tiles = Array.from(node.querySelectorAll("[data-tile]"));
7555
- if (!tiles.length)
7556
- return;
7557
- // Ширина ряда снимается до замера: временный `max-content` может распереть содержимое.
7558
- const available = columns > 0 ? (node.clientWidth - gap * (columns - 1)) / columns : 0;
7559
- tiles.forEach(tile => {
7560
- tile.style.width = "max-content";
7561
- });
7562
- let max = 0;
7563
- tiles.forEach(tile => {
7564
- max = Math.max(max, tile.getBoundingClientRect().width);
7565
- });
7566
- tiles.forEach(tile => {
7567
- tile.style.width = "";
7568
- });
7569
- // Ограниченную ширину округляем вниз — иначе округление вернуло бы ряд за границы контейнера.
7570
- const next = available > 0 && max > available ? Math.floor(available) : Math.ceil(max);
7571
- setWidth(previous => (max && previous !== next ? next : previous));
7572
- }, [columns, gap]);
7573
- useEffect(() => {
7574
- if (!enabled) {
7575
- setWidth(undefined);
7576
- return;
7577
- }
7578
- const node = ref.current;
7579
- if (!node)
7580
- return;
7581
- measure();
7582
- const observer = new ResizeObserver(() => measure());
7583
- observer.observe(node);
7584
- return () => observer.disconnect();
7585
- }, [enabled, itemsCount, measure]);
7586
- return [ref, enabled ? width : undefined];
7587
- };
7588
-
7589
- const SERVER_NOTIFICATION_EVENT = {
7590
- ReceiveFeaturesUpdate: "ReceiveFeaturesUpdateNotification",
7591
- PythonProgressNotification: "ReceivePythonProgressNotification",
7592
- PythonSandboxStats: "ReceivePythonSandboxStatsNotification",
7593
- };
7594
- const POLL_SUBTASK_INTERVAL_MS = 500;
7595
- const POLL_SUBTASK_TIMEOUT_MS = 15_000;
7596
-
7597
- const useServerNotificationsContext = () => {
7598
- return useContext(ServerNotificationsContext);
7599
- };
7600
-
7601
- const useRemoteTask = ({ onUpdate } = {}) => {
7602
- const { api } = useGlobalContext();
7603
- const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
7604
- const runTask = useCallback((prototype) => new Promise((resolve, reject) => {
7605
- const start = async () => {
7606
- const resourceId = prototype.subTaskSettings?.[0]?.startParameters?.resourceId;
7607
- let prototypeId = await api.remoteTaskManager.createTaskPrototype(prototype);
7608
- prototypeId = prototypeId.replace(/["']+/g, "");
7609
- const { id: taskId, success } = await api.remoteTaskManager.startTask1(prototypeId);
7610
- if (!success || !taskId) {
7611
- reject(new Error("startTask returned no taskId"));
7612
- return;
7613
- }
7614
- const subscriptionId = await addSubscription({
7615
- tag: "python_task_progress_event",
7616
- resourceId,
7617
- });
7618
- const onNotification = ({ data }) => {
7619
- if (data?.taskId !== taskId) {
7620
- return;
7621
- }
7622
- onUpdate?.({ status: data.status, log: data.log });
7623
- const isCompleted = data.status === RemoteTaskStatus.Completed;
7624
- const isError = data.status === RemoteTaskStatus.Error;
7625
- if (isCompleted || isError) {
7626
- connection?.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7627
- if (subscriptionId) {
7628
- unsubscribeById(subscriptionId);
7629
- }
7630
- resolve({
7631
- taskId,
7632
- status: isCompleted ? RemoteTaskStatus.Completed : RemoteTaskStatus.Error,
7633
- log: data.log,
7634
- });
7635
- }
7636
- };
7637
- connection?.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
7638
- };
7639
- start().catch(reject);
7640
- }), [api, addSubscription, connection, unsubscribeById, onUpdate]);
7641
- return { runTask };
7991
+ * контейнер прокидывает в CSS-переменную `--tile-width`, которую читает каждая плитка.
7992
+ *
7993
+ * Результат ограничен шириной ячейки ряда: плитка задаёт свою ширину в пикселях и в grid не
7994
+ * сжимается вместе с треком (`flex-shrink` там не действует, а `min-width: 0` базового
7995
+ * контейнера позволяет треку ужаться), поэтому натуральная ширина шире ячейки означала бы
7996
+ * наложение соседних плиток друг на друга.
7997
+ *
7998
+ * `enabled: false` полностью отключает измерение — ширина берётся из grid-ячейки.
7999
+ */
8000
+ const useEqualTileWidth = ({ enabled, itemsCount, columns, gap, }) => {
8001
+ const ref = useRef(null);
8002
+ const [width, setWidth] = useState();
8003
+ const measure = useCallback(() => {
8004
+ const node = ref.current;
8005
+ if (!node)
8006
+ return;
8007
+ const tiles = Array.from(node.querySelectorAll("[data-tile]"));
8008
+ if (!tiles.length)
8009
+ return;
8010
+ // Ширина ряда снимается до замера: временный `max-content` может распереть содержимое.
8011
+ const available = columns > 0 ? (node.clientWidth - gap * (columns - 1)) / columns : 0;
8012
+ tiles.forEach(tile => {
8013
+ tile.style.width = "max-content";
8014
+ });
8015
+ let max = 0;
8016
+ tiles.forEach(tile => {
8017
+ max = Math.max(max, tile.getBoundingClientRect().width);
8018
+ });
8019
+ tiles.forEach(tile => {
8020
+ tile.style.width = "";
8021
+ });
8022
+ // Ограниченную ширину округляем вниз — иначе округление вернуло бы ряд за границы контейнера.
8023
+ const next = available > 0 && max > available ? Math.floor(available) : Math.ceil(max);
8024
+ setWidth(previous => (max && previous !== next ? next : previous));
8025
+ }, [columns, gap]);
8026
+ useEffect(() => {
8027
+ if (!enabled) {
8028
+ setWidth(undefined);
8029
+ return;
8030
+ }
8031
+ const node = ref.current;
8032
+ if (!node)
8033
+ return;
8034
+ measure();
8035
+ const observer = new ResizeObserver(() => measure());
8036
+ observer.observe(node);
8037
+ return () => observer.disconnect();
8038
+ }, [enabled, itemsCount, measure]);
8039
+ return [ref, enabled ? width : undefined];
7642
8040
  };
7643
8041
 
7644
8042
  const SAVE_HOOK_RESULT_DURATION = 4000;
@@ -8018,417 +8416,139 @@ const useWidgetFilters = (type, filterName, items) => {
8018
8416
  }, { min: null, max: null }) || {};
8019
8417
  changeFilters({ [filterName]: { value, min, max } }, configFilter?.resetFilters);
8020
8418
  }, [filters, currentPage.filters, filterName, configFilter, items, changeFilters]);
8021
- return { filters, formatFilterColor, hasAnyFilter, isFiltered, onFilter };
8022
- };
8023
-
8024
- const useGetConfigLayer = () => {
8025
- const { currentPage } = useWidgetPage();
8026
- return useCallback((layerName) => currentPage?.layers?.find(({ name }) => name === layerName), [currentPage?.layers]);
8027
- };
8028
-
8029
- const useHideIfEmptyDataSource = (type = WidgetType.Dashboard) => {
8030
- const { dataSources } = useWidgetContext(type);
8031
- return useCallback((dataSourceName) => {
8032
- if (!dataSourceName)
8033
- return false;
8034
- return !getDataSource(dataSourceName, dataSources)?.features?.length;
8035
- }, [dataSources]);
8036
- };
8037
-
8038
- const useProjectDashboardInit = () => {
8039
- const { projectInfo, updateProject } = useWidgetContext();
8040
- return useCallback(() => {
8041
- if (!projectInfo || !isEmpty(projectInfo.content?.dashboardConfiguration)) {
8042
- return;
8043
- }
8044
- const { alias, name } = projectInfo;
8045
- const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
8046
- newProjectInfo.content.dashboardConfiguration = getDefaultConfig({ title: alias || name });
8047
- updateProject(newProjectInfo);
8048
- }, [projectInfo, updateProject]);
8049
- };
8050
-
8051
- const useRelatedDataSourceAttributes = ({ type = WidgetType.Dashboard, elementConfig, dataSources, feature, }) => {
8052
- const { layerInfos } = useWidgetContext(type);
8053
- const { currentPage } = useWidgetPage(type);
8054
- const { options } = elementConfig || {};
8055
- const { relatedDataSource } = options || {};
8056
- const dataSource = useMemo(() => getDataSource(relatedDataSource, dataSources), [dataSources, relatedDataSource]);
8057
- const configDataSource = useMemo(() => currentPage?.dataSources?.find(({ name }) => name === relatedDataSource), [currentPage?.dataSources, relatedDataSource]);
8058
- const layerInfo = useMemo(() => getDataSourceLayerInfo({ layerInfos, configDataSource, fetchedDataSource: dataSource }) ||
8059
- EMPTY_DATA_SOURCE_LAYER_INFO, [configDataSource, dataSource, layerInfos]);
8060
- const attributes = useMemo(() => getFeatureAttributes(feature, layerInfo, dataSource), [dataSource, feature, layerInfo]);
8061
- return { layerInfo, attributes, dataSource, configDataSource };
8062
- };
8063
-
8064
- const useRenderElement = (type = WidgetType.Dashboard, elementConfig) => {
8065
- const { t } = useGlobalContext();
8066
- const { selectedTabId, setSelectedTabId, expandedContainers, layerInfo, attributes } = useWidgetContext(type);
8067
- const { config } = useWidgetConfig(type);
8068
- const { pageIndex } = useWidgetPage(type);
8069
- return useMemo(() => getRenderElement({
8070
- t,
8071
- type,
8072
- config,
8073
- elementConfig,
8074
- layerInfo,
8075
- attributes,
8076
- expandedContainers,
8077
- pageIndex,
8078
- selectedTabId,
8079
- setSelectedTabId,
8080
- }), [
8081
- attributes,
8082
- config,
8083
- elementConfig,
8084
- expandedContainers,
8085
- layerInfo,
8086
- pageIndex,
8087
- selectedTabId,
8088
- setSelectedTabId,
8089
- type,
8090
- ]);
8091
- };
8092
-
8093
- /** Пустой бокс на отключённом пути — стабильная ссылка, чтобы не плодить ре-рендеры. */
8094
- const EMPTY_BOX = {};
8095
- /**
8096
- * Измеряет фактические ширину и высоту DOM-элемента и обновляет их на любой ресайз (ResizeObserver).
8097
- *
8098
- * Возвращает `[ref, box]`, где `box` — `{ width, height }` в пикселях (content-box) либо пустой объект,
8099
- * пока элемент ещё не измерен. Используется для «резинового» графика: d3-графикам нужны конкретные
8100
- * пиксельные размеры, а не CSS `100%`, а для вписывания (fit) нужны обе оси.
8101
- *
8102
- * `enabled: false` полностью отключает наблюдение — обычные (не fill) графики не измеряются
8103
- * и не вызывают лишних ре-рендеров.
8104
- */
8105
- const useResizeBox = (enabled) => {
8106
- const ref = useRef(null);
8107
- const [box, setBox] = useState(EMPTY_BOX);
8108
- useEffect(() => {
8109
- const node = ref.current;
8110
- if (!enabled || !node)
8111
- return;
8112
- const observer = new ResizeObserver(([entry]) => {
8113
- const { width, height } = entry.contentRect;
8114
- setBox({ width, height });
8115
- });
8116
- observer.observe(node);
8117
- return () => observer.disconnect();
8118
- }, [enabled]);
8119
- return [ref, enabled ? box : EMPTY_BOX];
8120
- };
8121
-
8122
- const useShownOtherItems = (options) => {
8123
- const [showMore, onShowMore] = useToggle();
8124
- const { shownItems } = options || {};
8125
- return {
8126
- sliceItems: (items) => sliceShownOtherItems(items, options, showMore),
8127
- checkIsSliced: (items) => !!shownItems && items?.length > shownItems,
8128
- onShowMore,
8129
- showMore,
8130
- };
8131
- };
8132
-
8133
- const useUpdateDataSource = ({ dataSource, config, filters, attributes, layerParams, eqlParameters, }) => {
8134
- const { dataSources } = useWidgetContext();
8135
- const { getDataSourcePromises, getUpdatedDataSources } = useDataSources({
8136
- type: WidgetType.Dashboard,
8137
- config,
8138
- filters,
8139
- attributes,
8140
- layerParams,
8141
- eqlParameters,
8142
- });
8143
- return useCallback(async (newFilters, offset = 0) => {
8144
- return getDataSourcePromises(dataSource, newFilters, offset).then((response) => {
8145
- const settled = { status: "fulfilled", value: response };
8146
- const responseDataSources = getUpdatedDataSources([settled], [dataSource], dataSources);
8147
- return {
8148
- items: responseDataSources.find(({ name }) => name === dataSource.name).features,
8149
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
8150
- totalCount: response.totalCount,
8151
- };
8152
- });
8153
- }, [dataSource, getDataSourcePromises, getUpdatedDataSources, dataSources]);
8154
- };
8155
-
8156
- const useMaxZoomTo = () => {
8157
- const { currentPage } = useWidgetPage();
8158
- return useCallback((layerName) => {
8159
- if (!layerName) {
8160
- return [currentPage?.options?.maxZoomTo, undefined];
8161
- }
8162
- return [currentPage?.options?.maxZoomTo, currentPage?.layers?.find(item => item.name === layerName)?.maxZoomTo];
8163
- }, [currentPage?.layers, currentPage?.options?.maxZoomTo]);
8164
- };
8165
-
8166
- const useCustomFeatureSelect = () => {
8167
- const { currentPage } = useWidgetPage();
8168
- return useCallback((layerName) => {
8169
- if (!layerName) {
8170
- return [currentPage?.options?.customFeatureSelect, undefined];
8171
- }
8172
- return [
8173
- currentPage?.options?.customFeatureSelect,
8174
- currentPage?.layers?.find(item => item.name === layerName)?.customFeatureSelect,
8175
- ];
8176
- }, [currentPage?.layers, currentPage?.options?.customFeatureSelect]);
8177
- };
8178
-
8179
- const useCurrentPageLayers = () => {
8180
- const { currentPage } = useWidgetPage();
8181
- return useMemo(() => currentPage?.layers || [], [currentPage?.layers]);
8182
- };
8183
-
8184
- const useLayerHiddenAttributes = (layerName) => {
8185
- const { currentPage, updateConfigPage } = useWidgetPage();
8186
- const layerHiddenAttributes = useMemo(() => {
8187
- return currentPage?.layers?.find(item => item.name === layerName)?.hiddenAttributes ?? [];
8188
- }, [currentPage?.layers, layerName]);
8189
- const updateLayerHiddenAttributes = useCallback((updatedHiddenAttributes) => {
8190
- updateConfigPage({
8191
- ...currentPage,
8192
- layers: currentPage?.layers?.map(item => {
8193
- return item.name === layerName
8194
- ? {
8195
- ...item,
8196
- hiddenAttributes: updatedHiddenAttributes,
8197
- }
8198
- : item;
8199
- }),
8200
- });
8201
- }, [currentPage, layerName, updateConfigPage]);
8202
- return [layerHiddenAttributes, updateLayerHiddenAttributes];
8203
- };
8204
-
8205
- const useVisibleProjectItems = (applyMinMaxScale) => {
8206
- const { map } = useMapContext();
8207
- const projectItems = useCurrentPageLayers();
8208
- const zoomChange = useMemo(() => (applyMinMaxScale && map.current?.getZoom() !== undefined ? Math.round(map.current?.getZoom()) : undefined), [applyMinMaxScale, map.current?.getZoom()]);
8209
- return useMemo(() => {
8210
- if (map.current?.getZoom() === undefined) {
8211
- return [];
8212
- }
8213
- return (projectItems?.filter(item => item.isVisible &&
8214
- (!applyMinMaxScale ||
8215
- (Math.round(map.current.getZoom()) >= (item.minScale ?? 0) &&
8216
- Math.round(map.current.getZoom()) <= (item.maxScale ?? 30)))) ?? []);
8217
- }, [projectItems, zoomChange, applyMinMaxScale]);
8218
- };
8219
-
8220
- const usePythonSandbox = () => {
8221
- const { api } = useGlobalContext();
8222
- const preparePythonSandbox = useCallback(({ resourceId, isNotebook = false }) => api.remoteTaskManager.post({
8223
- workerType: "pythonService",
8224
- methodType: "pythonrunner/prepare",
8225
- data: { resourceId, isNotebook },
8226
- }), [api.remoteTaskManager]);
8227
- return { preparePythonSandbox };
8419
+ return { filters, formatFilterColor, hasAnyFilter, isFiltered, onFilter };
8228
8420
  };
8229
8421
 
8230
- const FINAL_STATUSES = [
8231
- RemoteTaskStatus.Completed,
8232
- RemoteTaskStatus.Error,
8233
- RemoteTaskStatus.Interrupted,
8234
- RemoteTaskStatus.Timeout,
8235
- ];
8236
- const wait = (ms) => new Promise(resolve => window.setTimeout(resolve, ms));
8237
- const pollSubtaskCompletion = async ({ taskId, api, intervalMs = POLL_SUBTASK_INTERVAL_MS, timeoutMs = POLL_SUBTASK_TIMEOUT_MS, }) => {
8238
- const deadline = Date.now() + timeoutMs;
8239
- let subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
8240
- while (subTask && !FINAL_STATUSES.includes(subTask.status)) {
8241
- if (Date.now() >= deadline)
8242
- return null;
8243
- await wait(intervalMs);
8244
- subTask = (await api.remoteTaskManager.get(taskId))?.[0] ?? null;
8245
- }
8246
- return subTask;
8422
+ const useGetConfigLayer = () => {
8423
+ const { currentPage } = useWidgetPage();
8424
+ return useCallback((layerName) => currentPage?.layers?.find(({ name }) => name === layerName), [currentPage?.layers]);
8247
8425
  };
8248
8426
 
8249
- const usePythonTask = () => {
8250
- const { api, t } = useGlobalContext();
8251
- const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
8252
- const { preparePythonSandbox } = usePythonSandbox();
8253
- const [status, setStatus] = useState(RemoteTaskStatus.Unknown);
8254
- const [log, setLog] = useState(null);
8255
- const [lastMessage, setLastMessage] = useState(null);
8256
- const [error, setError] = useState(null);
8257
- const [loading, setLoading] = useState(false);
8258
- const [executionTime, setExecutionTime] = useState(null);
8259
- const [taskId, setTaskId] = useState(null);
8260
- const [subscriptionId, setSubscriptionId] = useState(null);
8261
- const [isLogDialogOpen, setIsLogDialogOpen] = useState(false);
8262
- const [result, setResult] = useState(null);
8263
- const reset = useCallback(() => {
8264
- setStatus(RemoteTaskStatus.Unknown);
8265
- setError(null);
8266
- setLoading(false);
8267
- setExecutionTime(null);
8268
- setTaskId(null);
8269
- setSubscriptionId(null);
8270
- setResult(null);
8271
- }, []);
8272
- const runTask = useCallback(async ({ resourceId, parameters, script, fileName, methodName, }) => {
8273
- reset();
8274
- setStatus(RemoteTaskStatus.Process);
8275
- setLog(null);
8276
- setLastMessage(null);
8277
- setLoading(true);
8278
- const start = Date.now();
8279
- let prototypeId = await api.remoteTaskManager.createTaskPrototype({
8280
- enabled: true,
8281
- startIfPreviousError: true,
8282
- startIfPreviousNotFinished: true,
8283
- subTaskSettings: [
8284
- {
8285
- type: "pythonService",
8286
- startParameters: {
8287
- resourceId,
8288
- parameters,
8289
- script,
8290
- fileName,
8291
- methodName,
8292
- method: "pythonrunner/run",
8293
- },
8294
- },
8295
- ],
8296
- });
8297
- prototypeId = prototypeId.replace(/["']+/g, "");
8298
- await preparePythonSandbox({ resourceId });
8299
- const { id: newTaskId, success } = await api.remoteTaskManager.startTask1(prototypeId);
8300
- if (!success) {
8301
- setStatus(RemoteTaskStatus.Error);
8302
- setLog(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
8303
- setExecutionTime(Date.now() - start);
8304
- setLoading(false);
8305
- }
8306
- const newSubscriptionId = await addSubscription({
8307
- tag: "python_task_progress_event",
8308
- resourceId,
8309
- });
8310
- setTaskId(newTaskId);
8311
- setSubscriptionId(newSubscriptionId);
8312
- const onNotification = async ({ data }) => {
8313
- if (data?.taskId === newTaskId) {
8314
- const isFinished = [RemoteTaskStatus.Completed, RemoteTaskStatus.Error].includes(data.status);
8315
- setStatus(data.status);
8316
- setLog(prev => [prev, data.log].filter(Boolean).join(""));
8317
- if (data.log)
8318
- setLastMessage(data.log);
8319
- setExecutionTime(Date.now() - start);
8320
- setLoading(false);
8321
- setTaskId(isFinished ? null : newTaskId);
8322
- setSubscriptionId(isFinished ? null : newSubscriptionId);
8323
- if (isFinished) {
8324
- unsubscribeById(newSubscriptionId);
8325
- connection.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
8326
- }
8327
- if (data.status === RemoteTaskStatus.Completed) {
8328
- try {
8329
- const subTask = await pollSubtaskCompletion({ taskId: newTaskId, api });
8330
- if (subTask?.status === RemoteTaskStatus.Completed) {
8331
- const response = subTask.results?.response;
8332
- setResult(typeof response === "object" && response !== null
8333
- ? response
8334
- : null);
8335
- }
8336
- else {
8337
- setError(new Error(t("taskResultUnavailable", {
8338
- ns: "devMode",
8339
- defaultValue: "Не удалось получить результат задачи",
8340
- })));
8341
- }
8342
- }
8343
- catch (e) {
8344
- setError(e instanceof Error ? e : new Error(String(e)));
8345
- }
8346
- }
8347
- }
8348
- };
8349
- connection.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
8350
- }, [reset, api, preparePythonSandbox, addSubscription, connection, t, unsubscribeById]);
8351
- const stopTask = useCallback(async () => {
8352
- await api.remoteTaskManager.stop(taskId);
8353
- reset();
8354
- unsubscribeById(subscriptionId);
8355
- }, [api, reset, unsubscribeById, taskId, subscriptionId]);
8356
- const openLog = useCallback(() => {
8357
- setIsLogDialogOpen(true);
8358
- }, []);
8359
- const closeLog = useCallback(() => {
8360
- setIsLogDialogOpen(false);
8361
- }, []);
8362
- return {
8363
- taskId,
8364
- runTask,
8365
- stopTask,
8366
- openLog,
8367
- log,
8368
- lastMessage,
8369
- error,
8370
- status,
8371
- loading,
8372
- executionTime,
8373
- isLogDialogOpen,
8374
- closeLog,
8375
- result,
8376
- };
8427
+ const useHideIfEmptyDataSource = (type = WidgetType.Dashboard) => {
8428
+ const { dataSources } = useWidgetContext(type);
8429
+ return useCallback((dataSourceName) => {
8430
+ if (!dataSourceName)
8431
+ return false;
8432
+ return !getDataSource(dataSourceName, dataSources)?.features?.length;
8433
+ }, [dataSources]);
8377
8434
  };
8378
8435
 
8379
- const useAppHeight = () => {
8380
- useEffect(() => {
8381
- const setAppHeight = () => {
8382
- document.documentElement.style.setProperty("--app-height", `${window.innerHeight}px`);
8383
- };
8384
- window.addEventListener("resize", setAppHeight);
8385
- setAppHeight();
8386
- return () => {
8387
- window.removeEventListener("resize", setAppHeight);
8388
- };
8389
- }, []);
8436
+ const useProjectDashboardInit = () => {
8437
+ const { projectInfo, updateProject } = useWidgetContext();
8438
+ return useCallback(() => {
8439
+ if (!projectInfo || !isEmpty(projectInfo.content?.dashboardConfiguration)) {
8440
+ return;
8441
+ }
8442
+ const { alias, name } = projectInfo;
8443
+ const newProjectInfo = JSON.parse(JSON.stringify(projectInfo));
8444
+ newProjectInfo.content.dashboardConfiguration = getDefaultConfig({ title: alias || name });
8445
+ updateProject(newProjectInfo);
8446
+ }, [projectInfo, updateProject]);
8390
8447
  };
8391
8448
 
8392
- const useDebouncedCallback = (interval) => {
8393
- return useMemo(() => debounce((cb) => {
8394
- cb();
8395
- }, interval), [interval]);
8449
+ const useRelatedDataSourceAttributes = ({ type = WidgetType.Dashboard, elementConfig, dataSources, feature, }) => {
8450
+ const { layerInfos } = useWidgetContext(type);
8451
+ const { currentPage } = useWidgetPage(type);
8452
+ const { options } = elementConfig || {};
8453
+ const { relatedDataSource } = options || {};
8454
+ const dataSource = useMemo(() => getDataSource(relatedDataSource, dataSources), [dataSources, relatedDataSource]);
8455
+ const configDataSource = useMemo(() => currentPage?.dataSources?.find(({ name }) => name === relatedDataSource), [currentPage?.dataSources, relatedDataSource]);
8456
+ const layerInfo = useMemo(() => getDataSourceLayerInfo({ layerInfos, configDataSource, fetchedDataSource: dataSource }) ||
8457
+ EMPTY_DATA_SOURCE_LAYER_INFO, [configDataSource, dataSource, layerInfos]);
8458
+ const attributes = useMemo(() => getFeatureAttributes(feature, layerInfo, dataSource), [dataSource, feature, layerInfo]);
8459
+ return { layerInfo, attributes, dataSource, configDataSource };
8396
8460
  };
8397
8461
 
8398
- const useToggle = (initial) => {
8399
- const [state, setState] = useState(initial !== undefined ? initial : false);
8400
- const toggle = useCallback(() => setState(!state), [state]);
8401
- return [state, toggle, setState];
8462
+ const useRenderElement = (type = WidgetType.Dashboard, elementConfig) => {
8463
+ const { t } = useGlobalContext();
8464
+ const { selectedTabId, setSelectedTabId, expandedContainers, layerInfo, attributes } = useWidgetContext(type);
8465
+ const { config } = useWidgetConfig(type);
8466
+ const { pageIndex } = useWidgetPage(type);
8467
+ return useMemo(() => getRenderElement({
8468
+ t,
8469
+ type,
8470
+ config,
8471
+ elementConfig,
8472
+ layerInfo,
8473
+ attributes,
8474
+ expandedContainers,
8475
+ pageIndex,
8476
+ selectedTabId,
8477
+ setSelectedTabId,
8478
+ }), [
8479
+ attributes,
8480
+ config,
8481
+ elementConfig,
8482
+ expandedContainers,
8483
+ layerInfo,
8484
+ pageIndex,
8485
+ selectedTabId,
8486
+ setSelectedTabId,
8487
+ type,
8488
+ ]);
8402
8489
  };
8403
8490
 
8404
- const DEBOUNCE_DELAY = 144;
8405
- const useWindowResize = (callback, delay) => {
8406
- const debounceCallback = useMemo(() => {
8407
- return callback ? debounce(callback, delay || DEBOUNCE_DELAY) : undefined;
8408
- }, [callback, delay]);
8491
+ /** Пустой бокс на отключённом пути — стабильная ссылка, чтобы не плодить ре-рендеры. */
8492
+ const EMPTY_BOX = {};
8493
+ /**
8494
+ * Измеряет фактические ширину и высоту DOM-элемента и обновляет их на любой ресайз (ResizeObserver).
8495
+ *
8496
+ * Возвращает `[ref, box]`, где `box` — `{ width, height }` в пикселях (content-box) либо пустой объект,
8497
+ * пока элемент ещё не измерен. Используется для «резинового» графика: d3-графикам нужны конкретные
8498
+ * пиксельные размеры, а не CSS `100%`, а для вписывания (fit) нужны обе оси.
8499
+ *
8500
+ * `enabled: false` полностью отключает наблюдение — обычные (не fill) графики не измеряются
8501
+ * и не вызывают лишних ре-рендеров.
8502
+ */
8503
+ const useResizeBox = (enabled) => {
8504
+ const ref = useRef(null);
8505
+ const [box, setBox] = useState(EMPTY_BOX);
8409
8506
  useEffect(() => {
8410
- debounceCallback && window.addEventListener("resize", debounceCallback);
8411
- return () => debounceCallback && window.removeEventListener("resize", debounceCallback);
8412
- }, [debounceCallback]);
8507
+ const node = ref.current;
8508
+ if (!enabled || !node)
8509
+ return;
8510
+ const observer = new ResizeObserver(([entry]) => {
8511
+ const { width, height } = entry.contentRect;
8512
+ setBox({ width, height });
8513
+ });
8514
+ observer.observe(node);
8515
+ return () => observer.disconnect();
8516
+ }, [enabled]);
8517
+ return [ref, enabled ? box : EMPTY_BOX];
8413
8518
  };
8414
8519
 
8415
- const useContainerAttributes = ({ elementConfig, type, renderElement }) => {
8416
- const getRenderContainerItem = useRenderContainerItem(type, renderElement);
8417
- const { options } = elementConfig || {};
8418
- const { attributes: optionAttributes, useProjectHiddenAttributes } = options || {};
8419
- const { attributes: contextAttributes, layerInfo } = useWidgetContext(type);
8420
- const [hiddenAttributes] = useLayerHiddenAttributes(layerInfo?.name ?? "");
8421
- const attributesToRender = useMemo(() => {
8422
- if (!optionAttributes)
8423
- return null;
8424
- const baseList = optionAttributes.length === 0
8425
- ? contextAttributes?.map(({ attributeName }) => attributeName) ?? []
8426
- : optionAttributes;
8427
- if (!useProjectHiddenAttributes)
8428
- return baseList;
8429
- return baseList.filter(attribute => !hiddenAttributes.includes(attribute));
8430
- }, [optionAttributes, contextAttributes, hiddenAttributes, useProjectHiddenAttributes]);
8431
- return { getRenderContainerItem, attributesToRender };
8520
+ const useShownOtherItems = (options) => {
8521
+ const [showMore, onShowMore] = useToggle();
8522
+ const { shownItems } = options || {};
8523
+ return {
8524
+ sliceItems: (items) => sliceShownOtherItems(items, options, showMore),
8525
+ checkIsSliced: (items) => !!shownItems && items?.length > shownItems,
8526
+ onShowMore,
8527
+ showMore,
8528
+ };
8529
+ };
8530
+
8531
+ const useUpdateDataSource = ({ dataSource, config, filters, attributes, layerParams, eqlParameters, }) => {
8532
+ const { dataSources } = useWidgetContext();
8533
+ const { getDataSourcePromises, getUpdatedDataSources } = useDataSources({
8534
+ type: WidgetType.Dashboard,
8535
+ config,
8536
+ filters,
8537
+ attributes,
8538
+ layerParams,
8539
+ eqlParameters,
8540
+ });
8541
+ return useCallback(async (newFilters, offset = 0) => {
8542
+ return getDataSourcePromises(dataSource, newFilters, offset).then((response) => {
8543
+ const settled = { status: "fulfilled", value: response };
8544
+ const responseDataSources = getUpdatedDataSources([settled], [dataSource], dataSources);
8545
+ return {
8546
+ items: responseDataSources.find(({ name }) => name === dataSource.name).features,
8547
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8548
+ totalCount: response.totalCount,
8549
+ };
8550
+ });
8551
+ }, [dataSource, getDataSourcePromises, getUpdatedDataSources, dataSources]);
8432
8552
  };
8433
8553
 
8434
8554
  const useRenderContainer = ({ elementConfig, type, renderElement, renderBody, }) => {
@@ -8468,6 +8588,7 @@ const useRenderContainer = ({ elementConfig, type, renderElement, renderBody, })
8468
8588
  const OneColumnContainer = memo(({ type, elementConfig, renderElement }) => {
8469
8589
  const { width, height, overflow } = elementConfig?.options || {};
8470
8590
  const templateName = elementConfig?.templateName;
8591
+ const bgHost = useBgImageHost(elementConfig);
8471
8592
  const renderBody = useCallback(({ id, value, style, hasUnits, render }) => (jsxs(Container, { id: id, isColumn: true, "data-templatename": templateName, style: style, "$sizeCss": getWrapperSizeStyle({
8472
8593
  style,
8473
8594
  width,
@@ -8475,7 +8596,7 @@ const OneColumnContainer = memo(({ type, elementConfig, renderElement }) => {
8475
8596
  overflow,
8476
8597
  defaults: BASE_CONTAINER_STYLE,
8477
8598
  defaultWidth: FILL_SIZE,
8478
- }), children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxs(ContainerValue, { children: [value, hasUnits && (jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName]);
8599
+ }), ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: render }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxs(ContainerValue, { children: [value, hasUnits && (jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName, bgHost, elementConfig]);
8479
8600
  const { renderContainer, attributesToRender } = useRenderContainer({
8480
8601
  type,
8481
8602
  elementConfig,
@@ -8493,7 +8614,7 @@ const FlowGroup = memo(({ elementConfig, type, renderElement }) => {
8493
8614
  const isColumn = column === undefined || column;
8494
8615
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
8495
8616
  const { root, body } = useContainerRoot({ elementConfig, defaults: CONTAINERS_GROUP_DEFAULTS });
8496
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(Container, { ...body, isColumn: isColumn, "$alignItems": alignItems, children: jsx(ContainerChildren, { type: type, items: children, elementConfig: elementConfig, isColumn: isColumn, isMain: id?.startsWith(CONFIG_PAGE_ID), renderElement: renderElement }) }))] }));
8617
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(Container, { ...body, isColumn: isColumn, "$alignItems": alignItems, children: jsx(ContainerChildren, { type: type, items: children, elementConfig: elementConfig, isColumn: isColumn, isMain: id?.startsWith(CONFIG_PAGE_ID), renderElement: renderElement }) }))] }));
8497
8618
  });
8498
8619
 
8499
8620
  /**
@@ -8634,17 +8755,39 @@ const GridContextMenu = memo(({ position, onClose }) => {
8634
8755
  return (jsx(Popup, { isVisible: true, interactive: true, appendTo: appendToBody, placement: "bottom-start", onRequestClose: onClose, getReferenceClientRect: getReferenceClientRect, anchor: ref => jsx(MenuAnchor, { ref: ref }), children: jsx(Menu, { options: options, selectOption: handleSelect }) }));
8635
8756
  });
8636
8757
 
8637
- const AddFeatureContainer = memo(({ elementConfig }) => {
8758
+ /**
8759
+ * Фоновое изображение контейнера — универсальный слот `bgImage`.
8760
+ *
8761
+ * Ставится первым ребёнком корня контейнера; корень обязан быть хостом слоя
8762
+ * (`bgImageHostMixin` + проп `$hasBgImage`, у контейнеров на `useContainerRoot` он приходит
8763
+ * готовым в `root`).
8764
+ *
8765
+ * Слота нет в конфиге — в DOM не появляется ничего: ни обёртки, ни пустого слоя.
8766
+ *
8767
+ * `options.outflow` читает слой, а не хост: вылет за края — свойство картинки, а раскладка
8768
+ * контейнера от него не меняется.
8769
+ */
8770
+ const ContainerBackground = memo(({ elementConfig, renderElement }) => {
8771
+ const hasBgImage = useMemo(() => hasContainerBgImage(elementConfig), [elementConfig]);
8772
+ if (!hasBgImage || !renderElement)
8773
+ return null;
8774
+ return (jsx(ContainerBackgroundLayer, { "$outflow": elementConfig?.options?.outflow, children: renderElement({ id: BG_IMAGE_SLOT_ID, wrap: false }) }));
8775
+ });
8776
+
8777
+ const AddFeatureContainer = memo(({ elementConfig, renderElement }) => {
8638
8778
  const { id, children, style } = elementConfig || {};
8639
- return (jsx(Container, { id: id, style: style, children: children
8640
- .filter(({ type }) => type === "button")
8641
- .map(({ options }, index) => (jsx(AddFeatureButton, { icon: options?.icon, title: options?.title, layerName: options?.layerName, geometryType: options?.geometryType }, index))) }));
8779
+ const bgHost = useBgImageHost(elementConfig);
8780
+ return (jsxs(Container, { id: id, style: style, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), children
8781
+ .filter(({ type }) => type === "button")
8782
+ .map(({ options }, index) => (jsx(AddFeatureButton, { icon: options?.icon, title: options?.title, layerName: options?.layerName, geometryType: options?.geometryType }, index)))] }));
8642
8783
  });
8643
8784
 
8644
8785
  const AttachmentsContainer = styled.div.withConfig({ displayName: "AttachmentsContainer", componentId: "sc-1y13q8d" }) `
8645
8786
  display: flex;
8646
8787
  flex-direction: column;
8647
8788
  width: 100%;
8789
+
8790
+ ${bgImageHostMixin};
8648
8791
  `;
8649
8792
  const AttachmentsHeaderRow = styled.div.withConfig({ displayName: "AttachmentsHeaderRow", componentId: "sc-l7u1q7" }) `
8650
8793
  &&& {
@@ -9007,7 +9150,7 @@ const AttachmentContainer = memo(({ type, elementConfig, renderElement }) => {
9007
9150
  const handleClosePreview = useCallback(() => setPreviewIndex(null), []);
9008
9151
  const handleShowMore = useCallback(() => setShowMore(true), [setShowMore]);
9009
9152
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9010
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(Container, { ...body, children: jsxs(Flex, { column: true, children: [jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsx(Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
9153
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(Container, { ...body, children: jsxs(Flex, { column: true, children: [jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsx(Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
9011
9154
  ns: "common",
9012
9155
  defaultValue: "Ресурс недоступен",
9013
9156
  }) }, previewIndex))] }) }))] }));
@@ -9019,7 +9162,7 @@ const CameraContainer = memo(({ elementConfig, type, renderElement }) => {
9019
9162
  const { expandable, expanded } = options || {};
9020
9163
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9021
9164
  const { root, body } = useContainerRoot({ elementConfig });
9022
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxs(Container, { ...body, children: [jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsx(ContainerValue, { children: renderElement({ id: "value", wrap: false }) })] }))] }));
9165
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxs(Container, { ...body, children: [jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsx(ContainerValue, { children: renderElement({ id: "value", wrap: false }) })] }))] }));
9023
9166
  });
9024
9167
 
9025
9168
  /**
@@ -9050,7 +9193,7 @@ const ChartContainer = memo(({ elementConfig, isVisible, type, renderElement })
9050
9193
  const hasItems = !!data[0]?.items?.length;
9051
9194
  if (!loading && !hasItems && hideEmpty)
9052
9195
  return null;
9053
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxs(Container, { ...body, isColumn: true, children: [aliasElement && jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsx(ContainerValue, { column: !twoColumns, alignItems: twoColumns && fill ? "stretch" : "center", "$fill": !!fill, children: hasItems ? (jsxs(Fragment$1, { children: [jsx(ContainerChart, { "$fill": !!fill, children: jsx(FillContext.Provider, { value: fillContextValue, children: renderElement({ id: "chart" }) }) }), jsx(ContainerLegend, { justifyContent: legendElement?.options?.center ? "center" : "flex-start", children: renderElement({ id: "legend" }) })] })) : (jsx(Fragment$1, { children: "\u2014" })) })] }))] }));
9196
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxs(Container, { ...body, isColumn: true, children: [aliasElement && jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsx(ContainerValue, { column: !twoColumns, alignItems: twoColumns && fill ? "stretch" : "center", "$fill": !!fill, children: hasItems ? (jsxs(Fragment$1, { children: [jsx(ContainerChart, { "$fill": !!fill, children: jsx(FillContext.Provider, { value: fillContextValue, children: renderElement({ id: "chart" }) }) }), jsx(ContainerLegend, { justifyContent: legendElement?.options?.center ? "center" : "flex-start", children: renderElement({ id: "legend" }) })] })) : (jsx(Fragment$1, { children: "\u2014" })) })] }))] }));
9054
9197
  });
9055
9198
 
9056
9199
  const InnerContainerWrapper = styled.div.withConfig({ displayName: "InnerContainerWrapper", componentId: "sc-1a1fl7q" }) `
@@ -9079,6 +9222,16 @@ const DataSourceInnerContainer = memo(({ config, elementConfig, feature, maxValu
9079
9222
  });
9080
9223
  const { options, children } = elementConfig || {};
9081
9224
  const { relatedDataSource, filterName, column } = options || {};
9225
+ /**
9226
+ * Конфиг записи — тот же узел хоста, но без слота фона.
9227
+ *
9228
+ * У `DataSource`/`DataSourceProgress` дети — слоты ВНУТРЕННЕГО шаблона, поэтому `bgImage`
9229
+ * достался бы и хосту, и каждой записи: одна картинка нарисовалась бы дважды. Фон остаётся
9230
+ * за хостом (он и есть контейнер), а записи получают конфиг без слота.
9231
+ */
9232
+ const innerConfig = useMemo(() => elementConfig && children?.some(({ id }) => id === BG_IMAGE_SLOT_ID)
9233
+ ? { ...elementConfig, children: children.filter(({ id }) => id !== BG_IMAGE_SLOT_ID) }
9234
+ : elementConfig, [elementConfig, children]);
9082
9235
  const aliasElement = useMemo(() => children?.find(({ id }) => id === "alias"), [children]);
9083
9236
  const valueElement = useMemo(() => children?.find(({ id }) => id === "value"), [children]);
9084
9237
  const aliasAttribute = useMemo(() => (aliasElement ? attributes?.find(({ attributeName }) => attributeName === aliasElement.attributeName) : null), [aliasElement, attributes]);
@@ -9121,7 +9274,7 @@ const DataSourceInnerContainer = memo(({ config, elementConfig, feature, maxValu
9121
9274
  if (!InnerContainer) {
9122
9275
  return null;
9123
9276
  }
9124
- return (jsx(InnerContainerWrapper, { hasAnyFilter: hasAnyFilter, isFiltered: isFiltered(value), column: column === undefined || column, onClick: filterName ? () => onFilter(value) : undefined, children: jsx(InnerContainer, { config: config, elementConfig: elementConfig, feature: feature, maxValue: maxValue, type: type, index: index, renderElement: render }) }));
9277
+ return (jsx(InnerContainerWrapper, { hasAnyFilter: hasAnyFilter, isFiltered: isFiltered(value), column: column === undefined || column, onClick: filterName ? () => onFilter(value) : undefined, children: jsx(InnerContainer, { config: config, elementConfig: innerConfig, feature: feature, maxValue: maxValue, type: type, index: index, renderElement: render }) }));
9125
9278
  });
9126
9279
 
9127
9280
  const DataSourceProgressContainerWrapper = styled.div.withConfig({ displayName: "DataSourceProgressContainerWrapper", componentId: "sc-d525nv" }) `
@@ -9209,7 +9362,7 @@ const DataSourceContainer = memo(({ config, elementConfig, type, innerComponent,
9209
9362
  if (dataSource && !dataSource.features) {
9210
9363
  return jsx(DataSourceError, { name: elementConfig.templateName });
9211
9364
  }
9212
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxs(Fragment$1, { children: [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) => (jsx(DataSourceInnerContainer, { index: index, type: type, config: config, feature: feature, elementConfig: elementConfig, innerComponent: innerComponent }, index))) }), checkIsSliced(dataSource.features) && (jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore
9365
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxs(Fragment$1, { children: [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) => (jsx(DataSourceInnerContainer, { index: index, type: type, config: config, feature: feature, elementConfig: elementConfig, innerComponent: innerComponent }, index))) }), checkIsSliced(dataSource.features) && (jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore
9213
9366
  ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" })
9214
9367
  : t("showAll", { ns: "dashboard", defaultValue: "Показать все" }) }))] })) : (jsx(ContainerLoading, {}))] }));
9215
9368
  });
@@ -9218,6 +9371,8 @@ const ProgressContainerWrapper = styled(Flex).withConfig({ displayName: "Progres
9218
9371
  align-items: center;
9219
9372
  width: 100%;
9220
9373
  margin-bottom: 1rem;
9374
+
9375
+ ${bgImageHostMixin};
9221
9376
  `;
9222
9377
  const ProgressIcon = styled.div.withConfig({ displayName: "ProgressIcon", componentId: "sc-1e9hoh1" }) `
9223
9378
  margin-right: 0.5rem;
@@ -9353,15 +9508,28 @@ const DataSourceProgressContainer = memo(({ config, elementConfig, type, innerCo
9353
9508
  return jsx(DataSourceError, { name: elementConfig.templateName });
9354
9509
  }
9355
9510
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9356
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxs(DataSourceProgressContainerWrapper, { ...body, children: [sliceItems(dataSource?.features)?.map((feature, index) => (jsx(DataSourceInnerContainer, { type: type, index: index, feature: feature, config: config, elementConfig: elementConfig, maxValue: currentMaxValue, innerComponent: innerComponent }, index))), checkIsSliced(dataSource?.features) && (jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" }) : t("showAll", {
9511
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), !isVisible ? null : dataSource ? (jsxs(DataSourceProgressContainerWrapper, { ...body, children: [sliceItems(dataSource?.features)?.map((feature, index) => (jsx(DataSourceInnerContainer, { type: type, index: index, feature: feature, config: config, elementConfig: elementConfig, maxValue: currentMaxValue, innerComponent: innerComponent }, index))), checkIsSliced(dataSource?.features) && (jsx(ContainerToggler, { toggled: showMore, onClick: onShowMore, children: showMore ? t("hide", { ns: "dashboard", defaultValue: "Свернуть" }) : t("showAll", {
9357
9512
  ns: "dashboard",
9358
9513
  defaultValue: "Показать все",
9359
9514
  }) })), showTotal && (jsxs(Fragment$1, { children: [jsx(Divider, {}), jsxs(ProgressTotal, { children: [jsx(ProgressTotalTitle, { children: t("total", { ns: "dashboard", defaultValue: "Итого" }) }), jsxs(ProgressValue, { children: [totalValue, jsx(ProgressUnits, { children: totalUnits })] })] })] }))] })) : (jsx(ContainerLoading, {})), jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type })] }));
9360
9515
  });
9361
9516
 
9362
- const DefaultAttributesContainer = memo(({ type, renderElement }) => {
9517
+ const DefaultAttributesContainer = memo(({ type, elementConfig, renderElement }) => {
9363
9518
  const { attributes } = useWidgetContext(type);
9364
- return (jsx(Fragment$1, { children: attributes?.map(({ attributeName }) => (jsx(Container, { isColumn: true, children: renderElement({ id: attributeName }) }, attributeName))) }));
9519
+ const bgHost = useBgImageHost(elementConfig);
9520
+ const needsHost = !!bgHost.$hasBgImage || !!bgHost.$innerPadding;
9521
+ /*
9522
+ `isColumn` обязателен: без него срабатывает row-ветка Container, а правило
9523
+ `> * { width: 100% }` есть только в column-ветке. Тогда строка атрибута схлопывается
9524
+ по своему контенту, и подписи со значениями перестают выстраиваться в две колонки.
9525
+ */
9526
+ const rows = useMemo(() => attributes?.map(({ attributeName }) => (jsx(Container, { isColumn: true, children: renderElement({ id: attributeName }) }, attributeName))), [attributes, renderElement]);
9527
+ // Без фона контейнер намеренно отдаёт НЕСКОЛЬКО корней: каждая строка атрибута — отдельная
9528
+ // ячейка родительской колонки. Общая обёртка появляется только под фон или `innerPadding`,
9529
+ // которым иначе не от чего отсчитывать бокс, — и только если автор конфига их попросил.
9530
+ if (!needsHost)
9531
+ return jsx(Fragment$1, { children: rows });
9532
+ return (jsxs(Container, { isColumn: true, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), rows] }));
9365
9533
  });
9366
9534
 
9367
9535
  const ContainerDivider = styled(Divider).withConfig({ displayName: "ContainerDivider", componentId: "sc-9zqdb0" }) `
@@ -9599,7 +9767,7 @@ const FiltersContainer = memo(({ elementConfig, config, type, renderElement }) =
9599
9767
  }, [config, type]);
9600
9768
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
9601
9769
  const selectedItems = useMemo(() => getFilterSelectedItems(filterItems, filters, configFilters), [configFilters, filters, filterItems]);
9602
- return (jsxs(ContainerRoot, { ...root, children: [jsx(Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsx(ContainerLoading, {}), !isLoading && isVisible && (jsx(FiltersContainerWrapper, { ...body, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0]?.options?.filterName })] }));
9770
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsx(ContainerLoading, {}), !isLoading && isVisible && (jsx(FiltersContainerWrapper, { ...body, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0]?.options?.filterName })] }));
9603
9771
  });
9604
9772
 
9605
9773
  /** Размер, при котором контейнер занимает всю ячейку родителя. */
@@ -9855,10 +10023,10 @@ const readTrackPixels = (grid, axis) => {
9855
10023
  /**
9856
10024
  * Дети, которые реально становятся треками.
9857
10025
  *
9858
- * `ContainerChildren` не рендерит слоты заголовка, поэтому и в `grid-template-*` их быть не
9859
- * должно — иначе треков окажется больше, чем ячеек, и раскладка съедет.
10026
+ * `ContainerChildren` не рендерит слоты заголовка и фон, поэтому и в `grid-template-*` их быть
10027
+ * не должно — иначе треков окажется больше, чем ячеек, и раскладка съедет.
9860
10028
  */
9861
- const getLayoutChildren = (node) => (node?.children ?? []).filter(({ id }) => !TITLE_SLOT_IDS.includes(id));
10029
+ const getLayoutChildren = (node) => (node?.children ?? []).filter(({ id }) => !NON_TRACK_SLOT_IDS.includes(id));
9862
10030
  /** Опция, в которой лежит доля трека: у строки это высота, у ячейки — ширина. */
9863
10031
  const getTrackSizeKey = (axis) => (axis === "row" ? "height" : "width");
9864
10032
  /**
@@ -10224,14 +10392,14 @@ const GridTrackContent = styled.div.withConfig({ displayName: "GridTrackContent"
10224
10392
  /** Узел-сетка: `ContainersGroup`, у которого включена опция `grid`. */
10225
10393
  const isGridNode = (node) => !!node?.options?.grid;
10226
10394
  /**
10227
- * Подменяет «раскладочных» детей узла, сохраняя слоты заголовка.
10395
+ * Подменяет «раскладочных» детей узла, сохраняя слоты заголовка и фона.
10228
10396
  *
10229
10397
  * Слоты кладутся первыми: их порядок относительно тела ни на что не влияет — тело их отфильтровывает,
10230
- * а `ExpandableTitle` ищет по `id`.
10398
+ * а `ExpandableTitle` и `ContainerBackground` ищут по `id`.
10231
10399
  */
10232
10400
  const setLayoutChildren = (node, children) => ({
10233
10401
  ...node,
10234
- children: [...(node.children ?? []).filter(({ id }) => TITLE_SLOT_IDS.includes(id)), ...children],
10402
+ children: [...(node.children ?? []).filter(({ id }) => NON_TRACK_SLOT_IDS.includes(id)), ...children],
10235
10403
  });
10236
10404
  /**
10237
10405
  * Иммутабельно применяет `mapper` к узлу с заданным `id` где угодно в поддереве.
@@ -10449,7 +10617,7 @@ const GridRowContainer = memo(({ elementConfig, renderElement }) => {
10449
10617
  elementConfig,
10450
10618
  defaults: autoHeight ? GRID_AUTO_FILL_DEFAULTS : GRID_FILL_DEFAULTS,
10451
10619
  });
10452
- return (jsx(ContainerRoot, { ...root, children: jsx(GridTracks, { node: elementConfig, axis: "column", body: body, gap: gap, renderElement: renderElement }) }));
10620
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(GridTracks, { node: elementConfig, axis: "column", body: body, gap: gap, renderElement: renderElement })] }));
10453
10621
  });
10454
10622
 
10455
10623
  const IconContainerWrapper = styled(Flex).withConfig({ displayName: "IconContainerWrapper", componentId: "sc-1eg4h9n" }) `
@@ -10460,6 +10628,8 @@ const IconContainerWrapper = styled(Flex).withConfig({ displayName: "IconContain
10460
10628
  background-color: ${({ theme: { palette } }) => palette.element};
10461
10629
  border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
10462
10630
  overflow: hidden;
10631
+
10632
+ ${bgImageHostMixin};
10463
10633
  `;
10464
10634
  const IconContainerHeaderWrapper = styled(Flex).withConfig({ displayName: "IconContainerHeaderWrapper", componentId: "sc-1johipv" }) `
10465
10635
  justify-content: space-between;
@@ -10502,10 +10672,11 @@ const IconContainerText = styled.div.withConfig({ displayName: "IconContainerTex
10502
10672
 
10503
10673
  const IconContainer = memo(({ elementConfig, renderElement }) => {
10504
10674
  const { id, style } = elementConfig || {};
10505
- return (jsxs(IconContainerWrapper, { id: id, style: style, children: [jsxs(IconContainerHeaderWrapper, { children: [jsxs(IconContainerHeader, { children: [renderElement({ id: "icon" }), jsx(IconContainerTitle, { children: renderElement({ id: "alias" }) })] }), renderElement({ id: "link" })] }), jsx(IconContainerText, { children: renderElement({ id: "text" }) })] }));
10675
+ const bgHost = useBgImageHost(elementConfig);
10676
+ return (jsxs(IconContainerWrapper, { id: id, style: style, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(IconContainerHeaderWrapper, { children: [jsxs(IconContainerHeader, { children: [renderElement({ id: "icon" }), jsx(IconContainerTitle, { children: renderElement({ id: "alias" }) })] }), renderElement({ id: "link" })] }), jsx(IconContainerText, { children: renderElement({ id: "text" }) })] }));
10506
10677
  });
10507
10678
 
10508
- const ImageContainerBg$1 = styled.div.withConfig({ displayName: "ImageContainerBg", componentId: "sc-cezopj" }) `
10679
+ const ImageContainerBg = styled.div.withConfig({ displayName: "ImageContainerBg", componentId: "sc-cezopj" }) `
10509
10680
  position: absolute;
10510
10681
  top: 0;
10511
10682
  bottom: 0;
@@ -10566,11 +10737,12 @@ const ImageContainerWrapper = styled(Flex).withConfig({ displayName: "ImageConta
10566
10737
 
10567
10738
  ${sizeCssMixin};
10568
10739
  ${noMarginMixin};
10740
+ ${bgImageHostMixin};
10569
10741
  `;
10570
10742
 
10571
10743
  const ImageContainer = memo(({ elementConfig, renderElement }) => {
10572
10744
  const root = useWrapperSize({ elementConfig });
10573
- return (jsxs(ImageContainerWrapper, { ...root, children: [jsx(ImageContainerTitle, { children: renderElement({ id: "alias" }) }), jsx(ImageContainerText, { children: renderElement({ id: "text" }) }), renderElement({ id: "button" }), jsx(ImageContainerBg$1, { children: renderElement({ id: "image" }) })] }));
10745
+ return (jsxs(ImageContainerWrapper, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ImageContainerTitle, { children: renderElement({ id: "alias" }) }), jsx(ImageContainerText, { children: renderElement({ id: "text" }) }), renderElement({ id: "button" }), jsx(ImageContainerBg, { children: renderElement({ id: "image" }) })] }));
10574
10746
  });
10575
10747
 
10576
10748
  const LayersContainerWrapper = styled(Container).withConfig({ displayName: "LayersContainerWrapper", componentId: "sc-1a97bv8" }) `
@@ -10628,7 +10800,7 @@ const LayersContainer = memo(({ type, elementConfig, renderElement }) => {
10628
10800
  return currentPage.layers;
10629
10801
  return currentPage.layers.filter(({ name }) => layerNames.includes(name));
10630
10802
  }, [currentPage?.layers, layerNames]);
10631
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(LayersContainerWrapper, { ...body, children: jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
10803
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(LayersContainerWrapper, { ...body, children: jsx(LayerTree, { layers: layers, onlyMainTools: true }) }))] }));
10632
10804
  });
10633
10805
 
10634
10806
  const PagesContainer = memo(({ type = WidgetType.Dashboard, noBorders }) => {
@@ -10638,6 +10810,7 @@ const PagesContainer = memo(({ type = WidgetType.Dashboard, noBorders }) => {
10638
10810
  const { options } = config || {};
10639
10811
  const { column, width } = options || {};
10640
10812
  const isColumn = column === undefined || column;
10813
+ const bgHost = useBgImageHost(currentPage);
10641
10814
  const filteredChildren = useMemo(() => !selectedTabId
10642
10815
  ? currentPage.children
10643
10816
  : currentPage.children.filter(item => !item.options?.tabId || item.options.tabId === selectedTabId), [currentPage.children, selectedTabId]);
@@ -10663,7 +10836,7 @@ const PagesContainer = memo(({ type = WidgetType.Dashboard, noBorders }) => {
10663
10836
  setSelectedTabId,
10664
10837
  type,
10665
10838
  ]);
10666
- return (jsx(Container, { id: getRootElementId(type), style: { width }, isMain: true, isColumn: isColumn, noBorders: noBorders, children: jsx(ContainerChildren, { type: type, items: filteredChildren, isMain: true, renderElement: renderElement }) }));
10839
+ return (jsxs(Container, { id: getRootElementId(type), style: { width }, isMain: true, isColumn: isColumn, noBorders: noBorders, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: currentPage, renderElement: renderElement }), jsx(ContainerChildren, { type: type, items: filteredChildren, isMain: true, renderElement: renderElement })] }));
10667
10840
  });
10668
10841
 
10669
10842
  const ProgressContainer = memo(({ type, elementConfig, feature, maxValue, index, renderElement }) => {
@@ -10699,10 +10872,11 @@ const ProgressContainer = memo(({ type, elementConfig, feature, maxValue, index,
10699
10872
  wrap: false,
10700
10873
  }), [renderElement]);
10701
10874
  const renderTooltip = useMemo(() => (jsxs(Fragment$1, { children: [jsx(ProgressTooltipAlias, { children: renderTooltipAlias }), jsxs(ProgressTooltipValueContainer, { children: [jsx(ProgressTooltipValue, { children: renderTooltipValue }), jsx(ProgressTooltipValueOf, { children: t("of", { ns: "dashboard", defaultValue: "из" }) }), jsx("div", { children: formatAttributeValue({ t, type: valueType, value: currentMaxValue, stringFormat }) })] })] })), [currentMaxValue, renderTooltipAlias, renderTooltipValue, stringFormat, t, valueType]);
10875
+ const bgHost = useBgImageHost(elementConfig);
10702
10876
  const color = useMemo(() => colorAttribute
10703
10877
  ? attributes?.find(({ attributeName }) => attributeName === colorAttribute)?.value
10704
10878
  : colors?.[index] || bgColor, [attributes, bgColor, colorAttribute, colors, index]);
10705
- return (jsx(Tooltip$1, { content: renderTooltip, placement: "top", arrow: true, children: ref => (jsxs(ProgressContainerWrapper, { ref: ref, id: id, style: innerTemplateStyle || style, children: [renderIcon && jsx(ProgressIcon, { children: renderIcon }), jsxs(ProgressContent, { children: [!hideTitle && (jsxs(ProgressAlias, { children: [jsx("div", { children: renderAlias }), jsxs(ProgressValue, { children: [renderValue, unitsElement && jsx(ProgressUnits, { children: renderElement({ id: "units" }) })] })] })), jsxs(ProgressBarContainer, { innerValue: innerValue, children: [jsx(ProgressBarWrapper, { children: jsx(ProgressBar, { "$width": width, "$color": color }) }), !!(hideTitle || innerValue) && jsx(ProgressInnerValue, { children: renderValue })] })] })] })) }));
10879
+ return (jsx(Tooltip$1, { content: renderTooltip, placement: "top", arrow: true, children: ref => (jsxs(ProgressContainerWrapper, { ref: ref, id: id, style: innerTemplateStyle || style, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), renderIcon && jsx(ProgressIcon, { children: renderIcon }), jsxs(ProgressContent, { children: [!hideTitle && (jsxs(ProgressAlias, { children: [jsx("div", { children: renderAlias }), jsxs(ProgressValue, { children: [renderValue, unitsElement && jsx(ProgressUnits, { children: renderElement({ id: "units" }) })] })] })), jsxs(ProgressBarContainer, { innerValue: innerValue, children: [jsx(ProgressBarWrapper, { children: jsx(ProgressBar, { "$width": width, "$color": color }) }), !!(hideTitle || innerValue) && jsx(ProgressInnerValue, { children: renderValue })] })] })] })) }));
10706
10880
  });
10707
10881
 
10708
10882
  const StyledSvgWidthMixin = css `
@@ -10885,6 +11059,8 @@ const RoundedBackgroundContainerWrapper = styled(Flex).withConfig({ displayName:
10885
11059
  margin-top: auto;
10886
11060
  padding-top: ${innerGapOr("0.25rem")};
10887
11061
  }
11062
+
11063
+ ${bgImageHostMixin};
10888
11064
  `;
10889
11065
 
10890
11066
  const ALIAS_DEFAULT_MAX_LENGTH = 28;
@@ -10902,6 +11078,7 @@ const RoundedBackgroundContainer = memo(({ type, elementConfig, feature, renderE
10902
11078
  const attributes = isEmpty(dsAttributes) ? ctxAttributes : dsAttributes;
10903
11079
  const { id, options, style, children } = elementConfig || {};
10904
11080
  const { maxLength, maxLines, wordBreak, center, fontColor, bgColor, innerTemplateStyle, inlineUnits, big, bigIcon, hideEmpty, colorAttribute, columns, innerGap } = options || {};
11081
+ const bgHost = useBgImageHost(elementConfig);
10905
11082
  const iconElement = children?.find(item => item.id === "icon");
10906
11083
  const aliasElement = children?.find(item => item.id === "alias");
10907
11084
  const unitsElement = children?.find(item => item.id === "units");
@@ -10963,7 +11140,7 @@ const RoundedBackgroundContainer = memo(({ type, elementConfig, feature, renderE
10963
11140
  const renderValue = useMemo(() => isNil(value) ? null : (jsxs(ContainerValue, { style: valueElement?.style, big: true, children: [value, !!unitsElement && (jsx(ContainerUnits, { style: unitsElement?.style, children: unitsContent }))] })), [valueElement?.style, value, unitsElement, unitsContent]);
10964
11141
  if (isNil(value) && hideEmpty)
10965
11142
  return null;
10966
- return (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: [jsxs(ContainerIconValue, { children: [renderIcon, big ? renderAlias : renderValue] }), big ? renderValue : renderAlias] }));
11143
+ return (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: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerIconValue, { children: [renderIcon, big ? renderAlias : renderValue] }), big ? renderValue : renderAlias] }));
10967
11144
  });
10968
11145
 
10969
11146
  const SlideshowContainer = memo(({ config, elementConfig, type }) => {
@@ -11002,7 +11179,7 @@ const SlideshowContainer = memo(({ config, elementConfig, type }) => {
11002
11179
  // Подпись `alias` не задают почти всегда — тогда обёртку не рендерим, чтобы в DOM не оставался
11003
11180
  // пустой блок, который вдобавок отъедал бы половину ширины у галереи (см. isColumn ниже).
11004
11181
  const aliasNode = render({ id: "alias" });
11005
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: render }), isVisible && (
11182
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: render }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: render }), isVisible && (
11006
11183
  // `isColumn`: подпись над галереей, а сама галерея на всю ширину. Без него Container
11007
11184
  // раскладывает alias и slideshow в ряд, и оба (Flex с `width: 100%`) сжимаются пополам —
11008
11185
  // картинка занимала лишь половину доступной ширины.
@@ -11030,21 +11207,11 @@ const DeleteRowDialog = ({ isOpen, isSourceRow, onConfirm, onCancel }) => {
11030
11207
  return (jsxs(Dialog, { isOpen: isOpen, onCloseRequest: onCancel, modal: true, maxWidth: "28rem", minHeight: "0", children: [jsxs(DialogTitle, { children: [jsx(ActionsGroup, { children: title }), jsx(ActionsGroup, { children: jsx(IconButton, { kind: "close", onClick: onCancel }) })] }), jsx(DialogContent, { children: message }), jsx(DialogActions, { children: jsxs(ActionsGroup, { children: [jsx(FlatButton, { onClick: onCancel, children: t("actions.cancel", { ns: "common", defaultValue: "Отменить" }) }), jsx(RaisedButton, { error: true, onClick: onConfirm, children: t("actions.delete", { ns: "common", defaultValue: "Удалить" }) })] }) })] }));
11031
11208
  };
11032
11209
 
11033
- /**
11034
- * Панель действий: добавление строки слева, запись и откат — справа.
11035
- *
11036
- * Вторая группа прижимается к краю собственным `margin-left: auto`, а не раскладкой панели:
11037
- * родительский `Container` в режиме колонки перебивает выравнивание своих детей
11038
- * (`&&& > * { justify-content: flex-start }`), и `justify-content` здесь не сработал бы.
11039
- */
11210
+ /** Панель действий: добавление строки слева, запись и откат — справа. */
11040
11211
  const StructuredDataToolbar = styled(Flex).withConfig({ displayName: "StructuredDataToolbar", componentId: "sc-w4ck72" }) `
11041
11212
  flex-shrink: 0;
11042
11213
  align-items: center;
11043
11214
  gap: 0.5rem;
11044
-
11045
- > * + * {
11046
- margin-left: auto;
11047
- }
11048
11215
  `;
11049
11216
  /**
11050
11217
  * Группа кнопок панели. `width: auto` обязателен: базовый `Flex` растянут на 100%, и две
@@ -11056,6 +11223,16 @@ const StructuredDataActions = styled(Flex).withConfig({ displayName: "Structured
11056
11223
  align-items: center;
11057
11224
  gap: 0.5rem;
11058
11225
  `;
11226
+ /**
11227
+ * Откат и запись. К правому краю их прижимает собственный `margin-left: auto`, а не раскладка
11228
+ * панели: родительский `Container` в режиме колонки перебивает выравнивание своих детей
11229
+ * (`&&& > * { justify-content: flex-start }`), и `justify-content` здесь не сработал бы. Отступ
11230
+ * на самой группе, а не на соседе слева, — тогда пара стоит справа и без кнопки добавления
11231
+ * (`editOnly` у представления).
11232
+ */
11233
+ const StructuredDataSaveActions = styled(StructuredDataActions).withConfig({ displayName: "StructuredDataSaveActions", componentId: "sc-1h4vci9" }) `
11234
+ margin-left: auto;
11235
+ `;
11059
11236
  /**
11060
11237
  * Область представления. Прокручивается внутри себя, чтобы длинная таблица не растягивала
11061
11238
  * контейнер за пределы отведённой ему ячейки; `min-height: 0` разрешает flex-ребёнку сжиматься.
@@ -11063,7 +11240,7 @@ const StructuredDataActions = styled(Flex).withConfig({ displayName: "Structured
11063
11240
  * Собственный бокс таблицы (`options.width`/`height` представления) живёт внутри и на эту
11064
11241
  * прокрутку не влияет: он ограничивает саму таблицу, а не отведённое контейнером место.
11065
11242
  */
11066
- const StructuredDataView = styled(Flex).withConfig({ displayName: "StructuredDataView", componentId: "sc-1ws3t0d" }) `
11243
+ const StructuredDataView = styled(Flex).withConfig({ displayName: "StructuredDataView", componentId: "sc-zyw8uj" }) `
11067
11244
  flex-direction: column;
11068
11245
  min-height: 0;
11069
11246
  overflow: auto;
@@ -11397,7 +11574,8 @@ const useStructuredDataSchema = (type, elementConfig) => {
11397
11574
  * Оркестратор контейнера: собирает схему, черновик и запись в одно состояние экрана.
11398
11575
  *
11399
11576
  * Правку открывает `options.editMode`: не задан или `false` — таблица целиком на чтение, без
11400
- * редакторов ячеек, добавления, удаления и кнопок сохранения.
11577
+ * редакторов ячеек, добавления, удаления и кнопок сохранения. Состав строк закрывается отдельно:
11578
+ * с `editOnly` у представления правка ячеек остаётся, а добавление и удаление уходят.
11401
11579
  *
11402
11580
  * Вид источника на права правки не влияет — от него зависит только адресат «Сохранить». Слой
11403
11581
  * принимает запись через features-API, источник без `layerName` (EQL, python-скрипт, внешний
@@ -11431,6 +11609,10 @@ const useStructuredData = (type, elementConfig) => {
11431
11609
  const loading = hasDataSource && (!dataSource || dataSource.features === undefined);
11432
11610
  const hasError = hasDataSource && dataSource?.features === null;
11433
11611
  const canEdit = !!editMode;
11612
+ // `editOnly` объявлен у представления, а кнопку добавления рисует контейнер — поэтому опцию
11613
+ // разбирает он один и раздаёт готовые права: кнопке — сюда, колонке удаления — в контекст.
11614
+ const editOnly = useMemo(() => !!elementConfig?.children?.find(({ id }) => id === STRUCTURED_DATA_VIEW_SLOT)?.options?.editOnly, [elementConfig?.children]);
11615
+ const canChangeRows = canEdit && !editOnly;
11434
11616
  const onSave = useCallback(async () => {
11435
11617
  const savedRows = await save(rows);
11436
11618
  if (savedRows) {
@@ -11453,9 +11635,10 @@ const useStructuredData = (type, elementConfig) => {
11453
11635
  rows: visibleRows,
11454
11636
  loading,
11455
11637
  canEdit,
11638
+ canDelete: canChangeRows,
11456
11639
  onCellChange: changeCell,
11457
11640
  onRowDelete,
11458
- }), [canEdit, changeCell, loading, onRowDelete, schema, visibleRows]);
11641
+ }), [canChangeRows, canEdit, changeCell, loading, onRowDelete, schema, visibleRows]);
11459
11642
  return {
11460
11643
  contextValue,
11461
11644
  dirty,
@@ -11463,6 +11646,7 @@ const useStructuredData = (type, elementConfig) => {
11463
11646
  loading,
11464
11647
  hasError,
11465
11648
  canEdit,
11649
+ canAdd: canChangeRows,
11466
11650
  isDeleteConfirmOpen: !!deletingKey,
11467
11651
  isDeletingSourceRow,
11468
11652
  onAddRow: addRow,
@@ -11483,11 +11667,11 @@ const useStructuredData = (type, elementConfig) => {
11483
11667
  const StructuredDataContainer = memo(({ type, elementConfig, isVisible, renderElement }) => {
11484
11668
  const { t } = useGlobalContext();
11485
11669
  const { root, body } = useContainerRoot({ elementConfig });
11486
- const { contextValue, dirty, saving, hasError, canEdit, isDeleteConfirmOpen, isDeletingSourceRow, onAddRow, onCancel, onSave, onDeleteConfirm, onDeleteCancel, } = useStructuredData(type, elementConfig);
11670
+ const { contextValue, dirty, saving, hasError, canEdit, canAdd, isDeleteConfirmOpen, isDeletingSourceRow, onAddRow, onCancel, onSave, onDeleteConfirm, onDeleteCancel, } = useStructuredData(type, elementConfig);
11487
11671
  if (hasError) {
11488
11672
  return jsx(DataSourceError, { name: elementConfig?.templateName });
11489
11673
  }
11490
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxs(Container, { ...body, isColumn: true, children: [jsx(StructuredDataView, { children: jsx(StructuredDataContext.Provider, { value: contextValue, children: renderElement({ id: STRUCTURED_DATA_VIEW_SLOT }) }) }), canEdit && (jsxs(StructuredDataToolbar, { children: [jsx(StructuredDataActions, { children: jsx(AddButtonRow, { kind: "feature_add", tabIndex: 0, disabled: saving, onClick: onAddRow, children: t("actions.add", { ns: "common", defaultValue: "Добавить" }) }) }), dirty && (jsxs(StructuredDataActions, { children: [jsx(IconButton, { error: true, kind: "close", tabIndex: 0, disabled: saving, title: t("actions.cancel", { ns: "common", defaultValue: "Отменить" }), onClick: onCancel }), jsx(IconButton, { primary: true, kind: "success", tabIndex: 0, disabled: saving, title: t("actions.save", { ns: "common", defaultValue: "Сохранить" }), onClick: onSave })] }))] }))] })), jsx(DeleteRowDialog, { isOpen: isDeleteConfirmOpen, isSourceRow: isDeletingSourceRow, onConfirm: onDeleteConfirm, onCancel: onDeleteCancel })] }));
11674
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxs(Container, { ...body, isColumn: true, children: [jsx(StructuredDataView, { children: jsx(StructuredDataContext.Provider, { value: contextValue, children: renderElement({ id: STRUCTURED_DATA_VIEW_SLOT }) }) }), canEdit && (canAdd || dirty) && (jsxs(StructuredDataToolbar, { children: [canAdd && (jsx(StructuredDataActions, { children: jsx(AddButtonRow, { kind: "feature_add", tabIndex: 0, disabled: saving, onClick: onAddRow, children: t("actions.add", { ns: "common", defaultValue: "Добавить" }) }) })), dirty && (jsxs(StructuredDataSaveActions, { children: [jsx(IconButton, { error: true, kind: "close", tabIndex: 0, disabled: saving, title: t("actions.cancel", { ns: "common", defaultValue: "Отменить" }), onClick: onCancel }), jsx(IconButton, { primary: true, kind: "success", tabIndex: 0, disabled: saving, title: t("actions.save", { ns: "common", defaultValue: "Сохранить" }), onClick: onSave })] }))] }))] })), jsx(DeleteRowDialog, { isOpen: isDeleteConfirmOpen, isSourceRow: isDeletingSourceRow, onConfirm: onDeleteConfirm, onCancel: onDeleteCancel })] }));
11491
11675
  });
11492
11676
 
11493
11677
  const TabAnchor = styled.div.withConfig({ displayName: "TabAnchor", componentId: "sc-emqf31" }) `
@@ -11566,13 +11750,19 @@ const SwiperContainer = styled.div.withConfig({ displayName: "SwiperContainer",
11566
11750
  .swiper-wrapper {
11567
11751
  display: flex;
11568
11752
  }
11753
+
11754
+ ${bgImageHostMixin};
11569
11755
  `;
11570
11756
 
11571
- const TabsContainer = memo(({ elementConfig, type }) => {
11757
+ const TabsContainer = memo(({ elementConfig, type, renderElement }) => {
11572
11758
  const { palette } = useTheme();
11573
11759
  const { selectedTabId, setSelectedTabId } = useWidgetContext(type);
11574
- const { id, options, style, children: tabs } = elementConfig || {};
11760
+ const { id, options, style, children } = elementConfig || {};
11575
11761
  const { radius, column, bgColor, noBg, onlyIcon, shownItems, maxLength = 12, wordBreak } = options || {};
11762
+ // Дети таба — перечисляемые сущности, каждый ребёнок становится вкладкой. Слот фона к ним не
11763
+ // относится: без фильтра он превратился бы в лишнюю пустую вкладку и занял `tabs[0]`.
11764
+ const tabs = useMemo(() => (children ?? []).filter(({ id: childId }) => childId !== BG_IMAGE_SLOT_ID), [children]);
11765
+ const bgHost = useBgImageHost(elementConfig);
11576
11766
  const renderIcon = useCallback((icon, active) => {
11577
11767
  if (!icon)
11578
11768
  return null;
@@ -11589,7 +11779,7 @@ const TabsContainer = memo(({ elementConfig, type }) => {
11589
11779
  setSelectedTabId(tabs[0].id);
11590
11780
  }
11591
11781
  }, []);
11592
- return (jsx(SwiperContainer, { id: id, style: style, children: jsx(Swiper, { spaceBetween: 0, slidesPerView: shownItems || 2, children: tabs.map(({ id: tabId, value, options: tabOptions }) => (jsxs(SwiperSlide, { children: [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 && (jsx(TabValue, { children: jsx(TextTrim, { maxLength: maxLength, wordBreak: wordBreak, children: value }) }))] }), jsx(TabAnchor, { id: tabId })] }, tabId))) }) }));
11782
+ return (jsxs(SwiperContainer, { id: id, style: style, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(Swiper, { spaceBetween: 0, slidesPerView: shownItems || 2, children: tabs.map(({ id: tabId, value, options: tabOptions }) => (jsxs(SwiperSlide, { children: [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 && (jsx(TabValue, { children: jsx(TextTrim, { maxLength: maxLength, wordBreak: wordBreak, children: value }) }))] }), jsx(TabAnchor, { id: tabId })] }, tabId))) })] }));
11593
11783
  });
11594
11784
 
11595
11785
  const SvgContainerColorMixin = css `
@@ -11719,6 +11909,7 @@ const TitleContainer = memo(({ containerId, templateName, layerNames, fontColor,
11719
11909
  const { id, style, options } = elementConfig || {};
11720
11910
  const { simple, downloadById, align } = options || {};
11721
11911
  const isLayers = templateName === ContainerTemplate.Layers;
11912
+ const bgHost = useBgImageHost(elementConfig);
11722
11913
  const { onExport } = useExportPdf(downloadById);
11723
11914
  const onClick = useCallback(() => {
11724
11915
  if (!expandable)
@@ -11734,13 +11925,14 @@ const TitleContainer = memo(({ containerId, templateName, layerNames, fontColor,
11734
11925
  const renderVisibility = useMemo(() => isLayers && (jsx(FlexSpan, { mr: "-1rem", children: jsx(IconToggle, { kind: layersVisibility ? "password_show" : "password_hide", className: "feature-visible", isSelected: layersVisibility, onClick: onToggleVisibility }) })), [isLayers, layersVisibility, onToggleVisibility]);
11735
11926
  const renderToggler = useMemo(() => !!containerId &&
11736
11927
  expandable && (jsx("div", { children: jsx(LegendToggler, { color: palette.icon, toggled: expandedContainers?.[containerId] !== undefined ? expandedContainers[containerId] : expanded, onClick: onClick }) })), [containerId, expandable, expanded, expandedContainers, onClick, palette.icon]);
11737
- return (jsx(Container, { id: id, style: style, isTitle: isVisible, children: jsxs(ContainerTitle, { simple: simple, "$align": align, children: [jsxs(ContainerIconTitle, { fontColor: fontColor, children: [renderElement({ id: "titleIcon", wrap: false }), renderElement({ id: "title" }), !!downloadById && (jsx(IconButton, { kind: "download", onClick: onExport })), isLayers && renderToggler] }), !isLayers && renderToggler, renderVisibility] }) }));
11928
+ return (jsxs(Container, { id: id, style: style, isTitle: isVisible, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerTitle, { simple: simple, "$align": align, children: [jsxs(ContainerIconTitle, { fontColor: fontColor, children: [renderElement({ id: "titleIcon", wrap: false }), renderElement({ id: "title" }), !!downloadById && (jsx(IconButton, { kind: "download", onClick: onExport })), isLayers && renderToggler] }), !isLayers && renderToggler, renderVisibility] })] }));
11738
11929
  });
11739
11930
 
11740
11931
  const TwoColumnContainer = memo(({ elementConfig, type, renderElement }) => {
11741
11932
  const { width, height, overflow } = elementConfig?.options || {};
11742
11933
  const templateName = elementConfig?.templateName;
11743
- const renderBody = useCallback(({ id, value, style, hasIcon, hasUnits, render }) => (jsxs(TwoColumnContainerWrapper, { id: id, "data-templatename": templateName, style: style, "$sizeCss": getWrapperSizeStyle({ style, width, height, overflow, defaultWidth: FILL_SIZE }), children: [jsxs(ContainerAlias, { children: [hasIcon && (jsx(ContainerAliasIcon, { children: render({ id: "icon" }) })), render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxs(ContainerValue, { big: true, children: [value, hasUnits && (jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName]);
11934
+ const bgHost = useBgImageHost(elementConfig);
11935
+ const renderBody = useCallback(({ id, value, style, hasIcon, hasUnits, render }) => (jsxs(TwoColumnContainerWrapper, { id: id, "data-templatename": templateName, style: style, "$sizeCss": getWrapperSizeStyle({ style, width, height, overflow, defaultWidth: FILL_SIZE }), ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: render }), jsxs(ContainerAlias, { children: [hasIcon && (jsx(ContainerAliasIcon, { children: render({ id: "icon" }) })), render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxs(ContainerValue, { big: true, children: [value, hasUnits && (jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), [width, height, overflow, templateName, bgHost, elementConfig]);
11744
11936
  const { renderContainer, attributesToRender } = useRenderContainer({
11745
11937
  type,
11746
11938
  elementConfig,
@@ -11776,7 +11968,7 @@ const UploadContainer = memo(({ type, elementConfig, renderElement }) => {
11776
11968
  const { expandable, expanded } = options || {};
11777
11969
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
11778
11970
  const { root, body } = useContainerRoot({ elementConfig });
11779
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(UploadContainerWrapper, { ...body, children: renderElement({ id: "uploader", wrap: false }) }))] }));
11971
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(UploadContainerWrapper, { ...body, children: renderElement({ id: "uploader", wrap: false }) }))] }));
11780
11972
  });
11781
11973
 
11782
11974
  const ExpandableTitle = memo(({ elementConfig, type, renderElement }) => {
@@ -11820,7 +12012,7 @@ const GridGroupView = memo(({ elementConfig, type, renderElement }) => {
11820
12012
  elementConfig,
11821
12013
  defaults: autoHeight ? GRID_AUTO_FILL_DEFAULTS : GRID_FILL_DEFAULTS,
11822
12014
  });
11823
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(GridTracks, { node: elementConfig, axis: "row", body: body, gap: gap, renderElement: renderElement }))] }));
12015
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsx(GridTracks, { node: elementConfig, axis: "row", body: body, gap: gap, renderElement: renderElement }))] }));
11824
12016
  });
11825
12017
 
11826
12018
  /** На сколько частей делит `split`. */
@@ -12393,12 +12585,13 @@ const ContainersGroupContainer = memo(props => {
12393
12585
  return jsx(FlowGroup, { ...props });
12394
12586
  });
12395
12587
 
12396
- const ExportPdfContainer = memo(({ type, elementConfig }) => {
12588
+ const ExportPdfContainer = memo(({ type, elementConfig, renderElement }) => {
12397
12589
  const { t } = useGlobalContext();
12398
12590
  const { loading, onExport } = useExportPdf(getRootElementId(type));
12399
12591
  const { id, style, options } = elementConfig || {};
12400
12592
  const { icon, title } = options || {};
12401
- return (jsx(Container, { id: id, style: style, children: jsx(IconButton, { kind: icon || "download", primary: true, disabled: loading, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) }) }));
12593
+ const bgHost = useBgImageHost(elementConfig);
12594
+ return (jsxs(Container, { id: id, style: style, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(IconButton, { kind: icon || "download", primary: true, disabled: loading, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) })] }));
12402
12595
  });
12403
12596
 
12404
12597
  const StatusBadge = styled(Chip).withConfig({ displayName: "StatusBadge", componentId: "sc-1xmfl10" }) `
@@ -12658,12 +12851,12 @@ const TaskContainer = memo(({ type, elementConfig, renderElement }) => {
12658
12851
  return runTask({ resourceId, parameters: newParams, script, fileName, methodName });
12659
12852
  }));
12660
12853
  }, [attributes, currentPage.filters, dataSources, ewktGeometry, layerInfo, projectDataSources, relatedResources, runTask, selectedFilters, stopTask, taskId]);
12661
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxs(TaskContainerWrapper, { ...body, justifyContent: center ? "center" : "flex-start", children: [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) && (jsxs(Fragment$1, { children: [jsx(IconButton, { kind: "info", onClick: openLog }), jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: onCloseLog, onMinimize: useNotifications ? onMinimizeLog : undefined })] }))] })] }));
12854
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxs(TaskContainerWrapper, { ...body, justifyContent: center ? "center" : "flex-start", children: [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) && (jsxs(Fragment$1, { children: [jsx(IconButton, { kind: "info", onClick: openLog }), jsx(LogDialog, { logs: log, status: status, statusColors: statusColors, isOpen: isLogDialogOpen, onClose: onCloseLog, onMinimize: useNotifications ? onMinimizeLog : undefined })] }))] })] }));
12662
12855
  });
12663
12856
 
12664
12857
  const EditContainer = ({ type, elementConfig, renderElement }) => {
12665
12858
  const { root, body } = useContainerRoot({ elementConfig });
12666
- return (jsxs(ContainerRoot, { ...root, children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxs(Container, { ...body, isColumn: true, children: [jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsx(ContainerValue, { children: renderElement({ id: "value" }) })] })] }));
12859
+ return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxs(Container, { ...body, isColumn: true, children: [jsx(ContainerAlias, { hasBottomMargin: true, children: renderElement({ id: "alias" }) }), jsx(ContainerValue, { children: renderElement({ id: "value" }) })] })] }));
12667
12860
  };
12668
12861
 
12669
12862
  const getControlTemplateName = (type) => {
@@ -12684,6 +12877,8 @@ const EditGroupContainer = memo(({ type, elementConfig, renderElement }) => {
12684
12877
  const { config, attributes, layerInfo, expandedContainers } = useWidgetContext(type);
12685
12878
  const { filteredAttributes, filteredControls } = useEditGroupAttributes({ elementConfig, type });
12686
12879
  const getRenderContainerItem = useRenderContainerItem(type, renderElement);
12880
+ const bgHost = useBgImageHost(elementConfig);
12881
+ const needsHost = !!bgHost.$hasBgImage || !!bgHost.$innerPadding;
12687
12882
  const renderContainer = useCallback((attributeName) => {
12688
12883
  const control = filteredControls?.find(({ targetAttributeName }) => targetAttributeName === attributeName);
12689
12884
  const itemAttribute = attributes.find(item => item.attributeName === attributeName);
@@ -12692,7 +12887,11 @@ const EditGroupContainer = memo(({ type, elementConfig, renderElement }) => {
12692
12887
  : getTemplateNameFromAttribute(itemAttribute);
12693
12888
  const itemConfig = {
12694
12889
  ...elementConfig,
12695
- children: elementConfig.children.map(child => ({
12890
+ // Слот фона принадлежит самой группе и в клон поля не уходит: иначе одна и та же
12891
+ // картинка легла бы фоном под КАЖДОЕ поле группы.
12892
+ children: elementConfig.children
12893
+ .filter(({ id: childId }) => childId !== BG_IMAGE_SLOT_ID)
12894
+ .map(child => ({
12696
12895
  ...child,
12697
12896
  attributeName,
12698
12897
  })),
@@ -12715,10 +12914,15 @@ const EditGroupContainer = memo(({ type, elementConfig, renderElement }) => {
12715
12914
  layerInfo,
12716
12915
  expandedContainers,
12717
12916
  ]);
12718
- if (!filteredControls?.length) {
12719
- return (jsx(Fragment$1, { children: filteredAttributes.map(({ attributeName }) => renderContainer(attributeName)) }));
12720
- }
12721
- return (jsx(Fragment$1, { children: filteredControls.map(({ targetAttributeName }) => renderContainer(targetAttributeName)) }));
12917
+ const fields = useMemo(() => !filteredControls?.length
12918
+ ? filteredAttributes.map(({ attributeName }) => renderContainer(attributeName))
12919
+ : filteredControls.map(({ targetAttributeName }) => renderContainer(targetAttributeName)), [filteredControls, filteredAttributes, renderContainer]);
12920
+ // Как и `DefaultAttributes`, группа намеренно отдаёт НЕСКОЛЬКО корней — по одному на поле.
12921
+ // Общая обёртка появляется только под фон или `innerPadding`: без неё им не от чего
12922
+ // отсчитывать бокс.
12923
+ if (!needsHost)
12924
+ return jsx(Fragment$1, { children: fields });
12925
+ return (jsxs(Container, { isColumn: true, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), fields] }));
12722
12926
  });
12723
12927
 
12724
12928
  const useEditControl = (type, elementConfig) => {
@@ -12764,7 +12968,8 @@ const EditBooleanContainer = ({ type, elementConfig, renderElement, }) => {
12764
12968
  const { t } = useGlobalContext();
12765
12969
  const { value, onChange } = useEditControl(type, elementConfig);
12766
12970
  const { id, style } = elementConfig || {};
12767
- return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { children: jsx(Switch, { label: value
12971
+ const bgHost = useBgImageHost(elementConfig);
12972
+ return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { children: jsx(Switch, { label: value
12768
12973
  ? t("on", { defaultValue: "Вкл" })
12769
12974
  : t("off", { defaultValue: "Выкл" }), checked: !!value, onChange: () => onChange(!value) }) })] }));
12770
12975
  };
@@ -12778,20 +12983,23 @@ const EditStringContainer = ({ type, elementConfig, renderElement, }) => {
12778
12983
  onControlChange(String(lastSelected?.value ?? ""));
12779
12984
  setValue(lastSelected?.text ?? "");
12780
12985
  }, [onControlChange, setValue]);
12781
- return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { column: true, children: control?.relatedDataSource ? (jsx(AutoComplete, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: value, options: options, width: "100%", onChange: onChange, onSelect: onSelect })) : (jsx(Input, { value: controlValue, width: "100%", onChange: (e) => onControlChange(e.target.value) })) })] }));
12986
+ const bgHost = useBgImageHost(elementConfig);
12987
+ return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { column: true, children: control?.relatedDataSource ? (jsx(AutoComplete, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: value, options: options, width: "100%", onChange: onChange, onSelect: onSelect })) : (jsx(Input, { value: controlValue, width: "100%", onChange: (e) => onControlChange(e.target.value) })) })] }));
12782
12988
  };
12783
12989
 
12784
12990
  const EditNumberContainer = ({ type, elementConfig, renderElement, }) => {
12785
12991
  const { value, control, onChange } = useEditControl(type, elementConfig);
12786
12992
  const { id, style } = elementConfig || {};
12787
- return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxs(ContainerValue, { column: true, children: [jsx(Input, { value: value?.toString(), width: "100%", onChange: (e) => onChange(e.target.value) }), jsx(Slider, { value: value, min: control?.minValue, max: control?.maxValue, step: control?.step, sliderWidth: "100%", primary: true, onChange: onChange })] })] }));
12993
+ const bgHost = useBgImageHost(elementConfig);
12994
+ return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsxs(ContainerValue, { column: true, children: [jsx(Input, { value: value?.toString(), width: "100%", onChange: (e) => onChange(e.target.value) }), jsx(Slider, { value: value, min: control?.minValue, max: control?.maxValue, step: control?.step, sliderWidth: "100%", primary: true, onChange: onChange })] })] }));
12788
12995
  };
12789
12996
 
12790
12997
  const EditDropdownContainer = ({ type, elementConfig, renderElement, }) => {
12791
12998
  const { value, control, items, onChange } = useEditControl(type, elementConfig);
12792
12999
  const { id, style } = elementConfig || {};
12793
13000
  const optionsList = useMemo(() => items.map(item => ({ text: item, value: item })), [items]);
12794
- return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { column: true, children: jsx(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) }) })] }));
13001
+ const bgHost = useBgImageHost(elementConfig);
13002
+ return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { column: true, children: jsx(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) }) })] }));
12795
13003
  };
12796
13004
 
12797
13005
  const CheckboxWrapper = styled(ContainerValue).withConfig({ displayName: "CheckboxWrapper", componentId: "sc-169umb6" }) `
@@ -12816,13 +13024,15 @@ const ChipsWrapper = styled(ContainerValue).withConfig({ displayName: "ChipsWrap
12816
13024
  const EditChipsContainer = ({ type, elementConfig, renderElement, }) => {
12817
13025
  const { value, items, onChange } = useEditControl(type, elementConfig);
12818
13026
  const { id, style } = elementConfig || {};
12819
- return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ChipsWrapper, { children: items.map(item => (jsx(Chip, { text: item, primary: value === item, onClick: () => onChange(item) }, item))) })] }));
13027
+ const bgHost = useBgImageHost(elementConfig);
13028
+ return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ChipsWrapper, { children: items.map(item => (jsx(Chip, { text: item, primary: value === item, onClick: () => onChange(item) }, item))) })] }));
12820
13029
  };
12821
13030
 
12822
13031
  const EditCheckboxContainer = ({ type, elementConfig, renderElement, }) => {
12823
13032
  const { value, items, onChange } = useEditControl(type, elementConfig);
12824
13033
  const { id, style } = elementConfig || {};
12825
- return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(CheckboxWrapper, { children: items.map(item => (jsx(Checkbox, { label: item, checked: item === value, onChange: () => onChange(item) }, item))) })] }));
13034
+ const bgHost = useBgImageHost(elementConfig);
13035
+ return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(CheckboxWrapper, { children: items.map(item => (jsx(Checkbox, { label: item, checked: item === value, onChange: () => onChange(item) }, item))) })] }));
12826
13036
  };
12827
13037
 
12828
13038
  const EditDateContainer = ({ type, elementConfig, renderElement, }) => {
@@ -12832,7 +13042,8 @@ const EditDateContainer = ({ type, elementConfig, renderElement, }) => {
12832
13042
  const { withTime } = options || {};
12833
13043
  const dateValue = useMemo(() => (value ? new Date(value) : undefined), [value]);
12834
13044
  const handleChange = useCallback((date) => onChange(date.toISOString()), [onChange]);
12835
- return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { column: true, children: jsx(DatePicker, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: dateValue, locale: getLocale(language), withTime: withTime ?? false, withHeader: true, width: "100%", onChange: handleChange }) })] }));
13045
+ const bgHost = useBgImageHost(elementConfig);
13046
+ return (jsxs(Container, { id: id, isColumn: true, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxs(ContainerAlias, { hasBottomMargin: true, children: [renderElement({ id: "alias" }), renderElement({ id: "tooltip" })] }), jsx(ContainerValue, { column: true, children: jsx(DatePicker, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, value: dateValue, locale: getLocale(language), withTime: withTime ?? false, withHeader: true, width: "100%", onChange: handleChange }) })] }));
12836
13047
  };
12837
13048
 
12838
13049
  const AddButton = ({ multiple = true, accept, onSelectFiles, onSelectFromCatalog, onSelectFromLink, }) => {
@@ -12976,6 +13187,7 @@ const EditAttachmentContainer = memo(({ type, elementConfig, renderElement }) =>
12976
13187
  const [uploading, setUploading] = useState(false);
12977
13188
  const [isLinkDialogOpen, , setLinkDialogOpen] = useToggle(false);
12978
13189
  const previewImages = useAttachmentPreviewImages({ items, active: previewIndex !== null });
13190
+ const bgHost = useBgImageHost(elementConfig);
12979
13191
  const persist = useCallback((next) => onChange(next), [onChange]);
12980
13192
  const handlePreview = useCallback((link) => {
12981
13193
  const idx = items.findIndex(item => item.link === link);
@@ -13033,7 +13245,7 @@ const EditAttachmentContainer = memo(({ type, elementConfig, renderElement }) =>
13033
13245
  setUploading(false);
13034
13246
  }
13035
13247
  }, [api, items, parentResourceId, persist]);
13036
- return (jsxs(AttachmentsContainer, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsx(AttachmentsGrid, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) : (jsx(AttachmentsList, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) }), hasMore && !showMore && (jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), jsx(AddButton, { accept: fileExtensions, onSelectFiles: uploading ? () => undefined : handleUpload, onSelectFromCatalog: handleSelectFromCatalog, onSelectFromLink: handleOpenLinkDialog }), jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: handleCloseLinkDialog, onSubmit: handleAddByLink }), previewIndex !== null && (jsx(Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview }, previewIndex))] }));
13248
+ return (jsxs(AttachmentsContainer, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsx(AttachmentsGrid, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) : (jsx(AttachmentsList, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) }), hasMore && !showMore && (jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), jsx(AddButton, { accept: fileExtensions, onSelectFiles: uploading ? () => undefined : handleUpload, onSelectFromCatalog: handleSelectFromCatalog, onSelectFromLink: handleOpenLinkDialog }), jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: handleCloseLinkDialog, onSubmit: handleAddByLink }), previewIndex !== null && (jsx(Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview }, previewIndex))] }));
13037
13249
  });
13038
13250
 
13039
13251
  // `ProgressContainer` и `RoundedBackgroundContainer` исторически принимают `InnerContainerProps`
@@ -13471,88 +13683,222 @@ const AlertIconContainer = styled(Flex).withConfig({ displayName: "AlertIconCont
13471
13683
  width: 2rem;
13472
13684
  height: 2rem;
13473
13685
 
13474
- ${Icon} {
13475
- :after {
13476
- color: ${({ theme: { palette } }) => palette.error};
13686
+ ${Icon} {
13687
+ :after {
13688
+ color: ${({ theme: { palette } }) => palette.error};
13689
+ }
13690
+ }
13691
+ `;
13692
+
13693
+ 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";
13694
+
13695
+ 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";
13696
+
13697
+ 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";
13698
+
13699
+ 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";
13700
+
13701
+ const LayerIcon = ({ layerInfo, error, innerRef }) => {
13702
+ const geometryType = layerInfo?.configuration?.geometryType;
13703
+ const renderSymbol = useMemo(() => {
13704
+ if (layerInfo?.configuration?.layerType === LayerServiceType.RemoteTileLayerService) {
13705
+ return jsx("img", { src: img, alt: "" });
13706
+ }
13707
+ if (!geometryType || error) {
13708
+ return (jsx(AlertIconContainer, { children: jsx(Icon, { kind: "warning" }) }));
13709
+ }
13710
+ switch (geometryType) {
13711
+ case OgcGeometryType.Point:
13712
+ case OgcGeometryType.MultiPoint:
13713
+ return jsx("img", { src: img$3, alt: "" });
13714
+ case OgcGeometryType.Polygon:
13715
+ case OgcGeometryType.MultiPolygon:
13716
+ return jsx("img", { src: img$1, alt: "" });
13717
+ case OgcGeometryType.LineString:
13718
+ case OgcGeometryType.MultiLineString:
13719
+ return jsx("img", { src: img$2, alt: "" });
13720
+ default:
13721
+ return jsx("img", { src: img$3, alt: "" });
13722
+ }
13723
+ }, [error, geometryType, layerInfo?.configuration?.layerType]);
13724
+ return jsx(LayerIconContainer, { ref: innerRef, children: renderSymbol });
13725
+ };
13726
+
13727
+ const LayerIconClickable = styled.div.withConfig({ displayName: "LayerIconClickable", componentId: "sc-1o3bms0" }) `
13728
+ display: flex;
13729
+ align-items: center;
13730
+ cursor: pointer;
13731
+ `;
13732
+ const NoFeatureIcon = styled.div.withConfig({ displayName: "NoFeatureIcon", componentId: "sc-sxo6af" }) `
13733
+ display: flex;
13734
+ align-items: center;
13735
+ justify-content: center;
13736
+ min-width: 1.5rem;
13737
+ height: 1.5rem;
13738
+ margin-top: 0.25rem;
13739
+ margin-right: 1rem;
13740
+ margin-left: 0.25rem;
13741
+
13742
+ ${Icon}::after {
13743
+ font-size: 1.5rem;
13744
+ color: ${({ theme: { palette } }) => palette.iconDisabled};
13745
+ }
13746
+ `;
13747
+
13748
+ const HeaderLayerIcon = ({ noFeature }) => {
13749
+ const { t } = useGlobalContext();
13750
+ const { layerInfo, feature } = useWidgetContext(WidgetType.FeatureCard);
13751
+ const zoomToFeatures = useZoomToFeatures();
13752
+ const getMaxZoomTo = useMaxZoomTo();
13753
+ const [optionsMaxZoomTo, layerMaxZoomTo] = useMemo(() => getMaxZoomTo(layerInfo?.name), [layerInfo?.name, getMaxZoomTo]);
13754
+ const handleIconClick = useCallback(() => zoomToFeatures([feature], { maxZoom: layerMaxZoomTo ?? optionsMaxZoomTo }), [zoomToFeatures, feature, layerMaxZoomTo, optionsMaxZoomTo]);
13755
+ if (noFeature) {
13756
+ return (jsx(NoFeatureIcon, { children: jsx(Icon, { kind: "no_geom" }) }));
13757
+ }
13758
+ return (jsx(LayerIconClickable, { onClick: handleIconClick, children: jsx(Tooltip$1, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard", defaultValue: "Приблизить к объекту" }), delay: [600, 0], children: ref => (jsx(LayerIcon, { innerRef: ref, layerInfo: layerInfo })) }) }));
13759
+ };
13760
+
13761
+ const FeatureCardDefaultHeader = ({ noFeature }) => {
13762
+ const { themeName: pageThemeName } = useGlobalContext();
13763
+ const { config } = useWidgetConfig(WidgetType.FeatureCard);
13764
+ const { header } = config || {};
13765
+ const { options } = header || {};
13766
+ const { themeName, withPadding, column, height, overlay } = options || {};
13767
+ return (jsx(ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsx(DefaultHeaderWrapper, { withPadding: withPadding, height: height, "$noFeature": noFeature, children: jsx(Header, { "$overlay": overlay, "$isRow": !column, "$noFeature": noFeature, children: jsxs(HeaderFrontView, { isDefault: !column, children: [jsxs(HeaderContainer, { children: [jsx(HeaderLayerIcon, { noFeature: noFeature }), jsx(HeaderTitle, { noFeature: noFeature })] }), jsx(FeatureCardButtons, {})] }) }) }) }));
13768
+ };
13769
+
13770
+ const HeaderWrapperMixin = css `
13771
+ ${Header} {
13772
+ min-height: 5.25rem;
13773
+ }
13774
+
13775
+ ${HeaderContainer} {
13776
+ max-width: 100%;
13777
+ width: 100%;
13778
+ }
13779
+
13780
+ ${FeatureControls} {
13781
+ max-width: calc(100% - 2rem);
13782
+ width: calc(100% - 2rem);
13783
+ margin-top: -0.5rem;
13784
+ padding-top: 1rem;
13785
+ border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
13786
+ }
13787
+
13788
+ ${({ $fontColor }) => !!$fontColor && HeaderFontColorMixin};
13789
+ `;
13790
+ const HeaderIcon = styled(Flex).withConfig({ displayName: "HeaderIcon", componentId: "sc-1y7xqr9" }) `
13791
+ position: absolute;
13792
+ top: 0;
13793
+ right: 0;
13794
+ align-items: center;
13795
+ justify-content: center;
13796
+ width: 7.625rem;
13797
+ height: 100%;
13798
+
13799
+ span[kind] {
13800
+ width: 4rem;
13801
+
13802
+ :after {
13803
+ font-size: 4rem;
13804
+ color: rgba(255, 255, 255, 0.36);
13805
+ }
13806
+ }
13807
+
13808
+ span[kind]:after,
13809
+ path,
13810
+ line,
13811
+ circle {
13812
+ fill: rgba(255, 255, 255, 0.36);
13813
+ }
13814
+
13815
+ && > * {
13816
+ display: flex;
13817
+ align-items: center;
13818
+ height: 100%;
13819
+ }
13820
+ `;
13821
+ const BigIconHeaderMixin = css `
13822
+ ${HeaderIcon} {
13823
+ min-width: 14rem;
13824
+ right: -3rem;
13825
+
13826
+ span[kind]:after {
13827
+ font-size: 14rem;
13828
+ }
13829
+ }
13830
+ `;
13831
+ const WithPaddingHeaderMixin = css `
13832
+ ${Header} {
13833
+ width: 100%;
13834
+ margin: -0.5rem -0.5rem 0.5rem -0.5rem;
13835
+ }
13836
+ `;
13837
+ const BottomBlurHeaderMixin = css `
13838
+ ${Header} {
13839
+ margin-bottom: 0;
13840
+
13841
+ &::before {
13842
+ -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13843
+ mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13844
+ }
13845
+ }
13846
+
13847
+ ${ContainerBackgroundLayer} {
13848
+ -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13849
+ mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
13850
+ }
13851
+
13852
+ ${HeaderFrontView} {
13853
+ z-index: 100;
13854
+ }
13855
+ `;
13856
+ const BackgroundHeaderWrapper = styled.div.withConfig({ displayName: "BackgroundHeaderWrapper", componentId: "sc-10iuilq" }) `
13857
+ ${Header} {
13858
+ position: relative;
13859
+ width: calc(100% + 1rem);
13860
+ height: ${({ $height }) => $height ? `${$height}px` : "auto"};
13861
+ margin: -1rem -1rem 1rem -1rem;
13862
+ border-radius: 0.5rem;
13863
+ background: transparent;
13864
+ overflow: hidden;
13865
+
13866
+ &::before {
13867
+ content: "";
13868
+ position: absolute;
13869
+ inset: 0;
13870
+ z-index: 100;
13871
+ pointer-events: none;
13872
+ background: ${({ $bgColor }) => $bgColor || "linear-gradient(96.55deg, #FFFCD3 0%, #B4DC47 100%)"};
13477
13873
  }
13478
13874
  }
13479
- `;
13480
-
13481
- 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";
13482
-
13483
- 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";
13484
-
13485
- 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";
13486
-
13487
- 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";
13488
-
13489
- const LayerIcon = ({ layerInfo, error, innerRef }) => {
13490
- const geometryType = layerInfo?.configuration?.geometryType;
13491
- const renderSymbol = useMemo(() => {
13492
- if (layerInfo?.configuration?.layerType === LayerServiceType.RemoteTileLayerService) {
13493
- return jsx("img", { src: img, alt: "" });
13494
- }
13495
- if (!geometryType || error) {
13496
- return (jsx(AlertIconContainer, { children: jsx(Icon, { kind: "warning" }) }));
13497
- }
13498
- switch (geometryType) {
13499
- case OgcGeometryType.Point:
13500
- case OgcGeometryType.MultiPoint:
13501
- return jsx("img", { src: img$3, alt: "" });
13502
- case OgcGeometryType.Polygon:
13503
- case OgcGeometryType.MultiPolygon:
13504
- return jsx("img", { src: img$1, alt: "" });
13505
- case OgcGeometryType.LineString:
13506
- case OgcGeometryType.MultiLineString:
13507
- return jsx("img", { src: img$2, alt: "" });
13508
- default:
13509
- return jsx("img", { src: img$3, alt: "" });
13510
- }
13511
- }, [error, geometryType, layerInfo?.configuration?.layerType]);
13512
- return jsx(LayerIconContainer, { ref: innerRef, children: renderSymbol });
13513
- };
13514
-
13515
- const LayerIconClickable = styled.div.withConfig({ displayName: "LayerIconClickable", componentId: "sc-1o3bms0" }) `
13516
- display: flex;
13517
- align-items: center;
13518
- cursor: pointer;
13519
- `;
13520
- const NoFeatureIcon = styled.div.withConfig({ displayName: "NoFeatureIcon", componentId: "sc-sxo6af" }) `
13521
- display: flex;
13522
- align-items: center;
13523
- justify-content: center;
13524
- min-width: 1.5rem;
13525
- height: 1.5rem;
13526
- margin-top: 0.25rem;
13527
- margin-right: 1rem;
13528
- margin-left: 0.25rem;
13529
13875
 
13530
- ${Icon}::after {
13531
- font-size: 1.5rem;
13532
- color: ${({ theme: { palette } }) => palette.iconDisabled};
13533
- }
13876
+ ${HeaderWrapperMixin};
13877
+
13878
+ ${({ $bigIcon }) => $bigIcon && BigIconHeaderMixin};
13879
+
13880
+ ${({ $withPadding }) => $withPadding && WithPaddingHeaderMixin};
13881
+
13882
+ ${({ $bottomBlur }) => $bottomBlur && BottomBlurHeaderMixin};
13534
13883
  `;
13535
13884
 
13536
- const HeaderLayerIcon = ({ noFeature }) => {
13537
- const { t } = useGlobalContext();
13538
- const { layerInfo, feature } = useWidgetContext(WidgetType.FeatureCard);
13539
- const zoomToFeatures = useZoomToFeatures();
13540
- const getMaxZoomTo = useMaxZoomTo();
13541
- const [optionsMaxZoomTo, layerMaxZoomTo] = useMemo(() => getMaxZoomTo(layerInfo?.name), [layerInfo?.name, getMaxZoomTo]);
13542
- const handleIconClick = useCallback(() => zoomToFeatures([feature], { maxZoom: layerMaxZoomTo ?? optionsMaxZoomTo }), [zoomToFeatures, feature, layerMaxZoomTo, optionsMaxZoomTo]);
13543
- if (noFeature) {
13544
- return (jsx(NoFeatureIcon, { children: jsx(Icon, { kind: "no_geom" }) }));
13545
- }
13546
- return (jsx(LayerIconClickable, { onClick: handleIconClick, children: jsx(Tooltip$1, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard", defaultValue: "Приблизить к объекту" }), delay: [600, 0], children: ref => (jsx(LayerIcon, { innerRef: ref, layerInfo: layerInfo })) }) }));
13547
- };
13548
-
13549
- const FeatureCardDefaultHeader = ({ noFeature }) => {
13885
+ const FeatureCardBackgroundHeader = () => {
13550
13886
  const { themeName: pageThemeName } = useGlobalContext();
13551
13887
  const { config } = useWidgetConfig(WidgetType.FeatureCard);
13552
13888
  const { header } = config || {};
13553
13889
  const { options } = header || {};
13554
- const { themeName, withPadding, column, height, overlay } = options || {};
13555
- return (jsx(ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsx(DefaultHeaderWrapper, { withPadding: withPadding, height: height, "$noFeature": noFeature, children: jsx(Header, { "$overlay": overlay, "$isRow": !column, "$noFeature": noFeature, children: jsxs(HeaderFrontView, { isDefault: !column, children: [jsxs(HeaderContainer, { children: [jsx(HeaderLayerIcon, { noFeature: noFeature }), jsx(HeaderTitle, { noFeature: noFeature })] }), jsx(FeatureCardButtons, {})] }) }) }) }));
13890
+ const { fontColor, bgColor, height, overlay, bigIcon, withPadding, bottomBlur, themeName, column } = options || {};
13891
+ const renderElement = useHeaderRender(header);
13892
+ return (jsx(ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsx(BackgroundHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$height": height, "$bigIcon": bigIcon, "$withPadding": withPadding, "$bottomBlur": bottomBlur, children: jsxs(Header, { "$overlay": overlay, "$isRow": !column, children: [jsxs(HeaderFrontView, { children: [jsxs(HeaderContainer, { column: column, children: [jsx(HeaderLayerIcon, {}), jsx(FeatureCardTitle, { title: renderElement({
13893
+ id: "title",
13894
+ wrap: false,
13895
+ }), description: renderElement({
13896
+ id: "description",
13897
+ wrap: false,
13898
+ }) })] }), jsx(FeatureCardButtons, {})] }), jsx(ContainerBackground, { elementConfig: header, renderElement: renderElement }), jsx(HeaderIcon, { children: renderElement({
13899
+ id: "icon",
13900
+ wrap: false,
13901
+ }) })] }) }) }));
13556
13902
  };
13557
13903
 
13558
13904
  const ImageContainerButton = styled(FlatButton).withConfig({ displayName: "ImageContainerButton", componentId: "sc-nq6mg4" }) `
@@ -14015,13 +14361,17 @@ const ElementIcon = memo(({ type, elementConfig, ...rest }) => {
14015
14361
  const ElementImg = styled.img.withConfig({ displayName: "ElementImg", componentId: "sc-7ul8bx" }) `
14016
14362
  max-width: 100%;
14017
14363
 
14018
- /* Картинка заполняет отведённый ей бокс: масштаб по меньшей стороне, излишек обрезается. */
14364
+ /* Картинка заполняет отведённый ей бокс: масштаб по меньшей стороне, излишек обрезается.
14365
+ && — чтобы авторский options.fit перебивал дефолтный cover слоя ContainerBackgroundLayer:
14366
+ тот задаёт его селектором-потомком (.layer img) и иначе выигрывал бы по специфичности. */
14019
14367
  ${({ $fit }) => !!$fit &&
14020
14368
  css `
14021
- width: 100%;
14022
- height: 100%;
14023
- object-position: center;
14024
- object-fit: ${$fit};
14369
+ && {
14370
+ width: 100%;
14371
+ height: 100%;
14372
+ object-position: center;
14373
+ object-fit: ${$fit};
14374
+ }
14025
14375
  `}
14026
14376
 
14027
14377
  ${sizeCssMixin};
@@ -14951,7 +15301,7 @@ const ElementTable = memo(({ elementConfig }) => {
14951
15301
  return (jsx(TableBox, { "$sizeCss": sizeCss, children: jsxs(TableWrapper, { ref: setTable, "$contentWidth": contentWidth, children: [jsx(TableHead, { children: jsxs("tr", { children: [columns.map(({ attributeName, alias, description }) => {
14952
15302
  const sorted = sort?.attributeName === attributeName;
14953
15303
  return (jsx(TableHeadCell, { title: description || alias, "$sortable": sortEnabled, onClick: sortEnabled ? () => onSortToggle(attributeName) : undefined, children: jsxs(TableHeadContent, { children: [alias, sortEnabled && (jsx(TableSortSlot, { "$active": sorted, children: jsx(Icon, { kind: sorted && sort?.direction === "desc" ? "sorting_des" : "sorting_asc" }) }))] }) }, attributeName));
14954
- }), context.canEdit && jsx(TableHeadCell, {})] }) }), jsx(TableBody, { children: rows.map(row => (jsxs(TableRow, { children: [columns.map(attribute => (jsx(TableCellWrapper, { children: jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }) }, attribute.attributeName))), context.canEdit && (jsx(TableActionsCell, { children: jsx(IconButton, { kind: "delete", title: t("actions.delete", { ns: "common", defaultValue: "Удалить" }), onClick: () => context.onRowDelete(row.key) }) }))] }, row.key))) })] }) }));
15304
+ }), context.canDelete && jsx(TableHeadCell, {})] }) }), jsx(TableBody, { children: rows.map(row => (jsxs(TableRow, { children: [columns.map(attribute => (jsx(TableCellWrapper, { children: jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }) }, attribute.attributeName))), context.canDelete && (jsx(TableActionsCell, { children: jsx(IconButton, { kind: "delete", title: t("actions.delete", { ns: "common", defaultValue: "Удалить" }), onClick: () => context.onRowDelete(row.key) }) }))] }, row.key))) })] }) }));
14955
15305
  });
14956
15306
 
14957
15307
  const TooltipIcon = styled(Icon).withConfig({ displayName: "TooltipIcon", componentId: "sc-1lkxudm" }) `
@@ -15019,21 +15369,7 @@ const SlideshowHeaderWrapper = styled.div.withConfig({ displayName: "SlideshowHe
15019
15369
 
15020
15370
  ${({ fontColor }) => !!fontColor && HeaderFontColorMixin};
15021
15371
  `;
15022
- const ImageContainerBg = styled.div.withConfig({ displayName: "ImageContainerBg", componentId: "sc-1yxa8u0" }) `
15023
- position: absolute;
15024
- top: 0;
15025
- bottom: 0;
15026
- left: 0;
15027
- right: 0;
15028
-
15029
- img {
15030
- width: 100%;
15031
- height: 100%;
15032
- object-position: center;
15033
- object-fit: cover;
15034
- }
15035
- `;
15036
- const HeaderSlideshow = styled.div.withConfig({ displayName: "HeaderSlideshow", componentId: "sc-fqw4k7" }) `
15372
+ const HeaderSlideshow = styled.div.withConfig({ displayName: "HeaderSlideshow", componentId: "sc-1yw2skw" }) `
15037
15373
  position: absolute;
15038
15374
  top: 0;
15039
15375
  bottom: ${({ height }) => (height ? `${height}px` : 0)};
@@ -15054,143 +15390,6 @@ const HeaderSlideshow = styled.div.withConfig({ displayName: "HeaderSlideshow",
15054
15390
  }
15055
15391
  `;
15056
15392
 
15057
- const HeaderWrapperMixin = css `
15058
- ${Header} {
15059
- min-height: 5.25rem;
15060
- }
15061
-
15062
- ${HeaderContainer} {
15063
- max-width: 100%;
15064
- width: 100%;
15065
- }
15066
-
15067
- ${FeatureControls} {
15068
- max-width: calc(100% - 2rem);
15069
- width: calc(100% - 2rem);
15070
- margin-top: -0.5rem;
15071
- padding-top: 1rem;
15072
- border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
15073
- }
15074
-
15075
- ${({ $fontColor }) => !!$fontColor && HeaderFontColorMixin};
15076
- `;
15077
- const HeaderIcon = styled(Flex).withConfig({ displayName: "HeaderIcon", componentId: "sc-1y7xqr9" }) `
15078
- position: absolute;
15079
- top: 0;
15080
- right: 0;
15081
- align-items: center;
15082
- justify-content: center;
15083
- width: 7.625rem;
15084
- height: 100%;
15085
-
15086
- span[kind] {
15087
- width: 4rem;
15088
-
15089
- :after {
15090
- font-size: 4rem;
15091
- color: rgba(255, 255, 255, 0.36);
15092
- }
15093
- }
15094
-
15095
- span[kind]:after,
15096
- path,
15097
- line,
15098
- circle {
15099
- fill: rgba(255, 255, 255, 0.36);
15100
- }
15101
-
15102
- && > * {
15103
- display: flex;
15104
- align-items: center;
15105
- height: 100%;
15106
- }
15107
- `;
15108
- const BigIconHeaderMixin = css `
15109
- ${HeaderIcon} {
15110
- min-width: 14rem;
15111
- right: -3rem;
15112
-
15113
- span[kind]:after {
15114
- font-size: 14rem;
15115
- }
15116
- }
15117
- `;
15118
- const WithPaddingHeaderMixin = css `
15119
- ${Header} {
15120
- width: 100%;
15121
- margin: -0.5rem -0.5rem 0.5rem -0.5rem;
15122
- }
15123
- `;
15124
- const BottomBlurHeaderMixin = css `
15125
- ${Header} {
15126
- margin-bottom: 0;
15127
-
15128
- &::before {
15129
- -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15130
- mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15131
- }
15132
- }
15133
-
15134
- ${ImageContainerBg} {
15135
- -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15136
- mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
15137
- }
15138
-
15139
- ${HeaderFrontView} {
15140
- z-index: 100;
15141
- }
15142
- `;
15143
- const BackgroundHeaderWrapper = styled.div.withConfig({ displayName: "BackgroundHeaderWrapper", componentId: "sc-10iuilq" }) `
15144
- ${Header} {
15145
- position: relative;
15146
- width: calc(100% + 1rem);
15147
- height: ${({ $height }) => $height ? `${$height}px` : "auto"};
15148
- margin: -1rem -1rem 1rem -1rem;
15149
- border-radius: 0.5rem;
15150
- background: transparent;
15151
- overflow: hidden;
15152
-
15153
- &::before {
15154
- content: "";
15155
- position: absolute;
15156
- inset: 0;
15157
- z-index: 100;
15158
- pointer-events: none;
15159
- background: ${({ $bgColor }) => $bgColor || "linear-gradient(96.55deg, #FFFCD3 0%, #B4DC47 100%)"};
15160
- }
15161
- }
15162
-
15163
- ${HeaderWrapperMixin};
15164
-
15165
- ${({ $bigIcon }) => $bigIcon && BigIconHeaderMixin};
15166
-
15167
- ${({ $withPadding }) => $withPadding && WithPaddingHeaderMixin};
15168
-
15169
- ${({ $bottomBlur }) => $bottomBlur && BottomBlurHeaderMixin};
15170
- `;
15171
-
15172
- const FeatureCardBackgroundHeader = () => {
15173
- const { themeName: pageThemeName } = useGlobalContext();
15174
- const { config } = useWidgetConfig(WidgetType.FeatureCard);
15175
- const { header } = config || {};
15176
- const { options } = header || {};
15177
- const { fontColor, bgColor, height, overlay, bigIcon, withPadding, bottomBlur, themeName, column } = options || {};
15178
- const renderElement = useHeaderRender(header);
15179
- return (jsx(ThemeProvider, { theme: getThemeByName(themeName ?? pageThemeName), children: jsx(BackgroundHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$height": height, "$bigIcon": bigIcon, "$withPadding": withPadding, "$bottomBlur": bottomBlur, children: jsxs(Header, { "$overlay": overlay, "$isRow": !column, children: [jsxs(HeaderFrontView, { children: [jsxs(HeaderContainer, { column: column, children: [jsx(HeaderLayerIcon, {}), jsx(FeatureCardTitle, { title: renderElement({
15180
- id: "title",
15181
- wrap: false,
15182
- }), description: renderElement({
15183
- id: "description",
15184
- wrap: false,
15185
- }) })] }), jsx(FeatureCardButtons, {})] }), jsx(ImageContainerBg, { children: renderElement({
15186
- id: "bgImage",
15187
- wrap: false,
15188
- }) }), jsx(HeaderIcon, { children: renderElement({
15189
- id: "icon",
15190
- wrap: false,
15191
- }) })] }) }) }));
15192
- };
15193
-
15194
15393
  const FeatureCardSlideshowHeader = () => {
15195
15394
  const { config } = useWidgetConfig(WidgetType.FeatureCard);
15196
15395
  const { header } = config || {};
@@ -15203,10 +15402,7 @@ const FeatureCardSlideshowHeader = () => {
15203
15402
  }), description: renderElement({
15204
15403
  id: "description",
15205
15404
  wrap: false,
15206
- }) })] }), jsx(FeatureCardButtons, {})] }), jsx(ImageContainerBg, { children: renderElement({
15207
- id: "bgImage",
15208
- wrap: false,
15209
- }) }), jsx(HeaderSlideshow, { height: height, children: renderElement({
15405
+ }) })] }), jsx(FeatureCardButtons, {})] }), jsx(ContainerBackground, { elementConfig: header, renderElement: renderElement }), jsx(HeaderSlideshow, { height: height, children: renderElement({
15210
15406
  id: "slideshow",
15211
15407
  wrap: false,
15212
15408
  }) })] }) }) }));
@@ -17150,6 +17346,14 @@ const getTotalFromRelatedFeatures = (data) => {
17150
17346
 
17151
17347
  const getRootElementId = (type = WidgetType.Dashboard) => `${type}-root`;
17152
17348
 
17349
+ /**
17350
+ * Есть ли у узла конфига слот фонового изображения.
17351
+ *
17352
+ * Слой фона рисуется ТОЛЬКО по этому признаку: без узла `bgImage` в конфиге пустой
17353
+ * абсолютно позиционированный `div` в DOM не появляется вовсе.
17354
+ */
17355
+ const hasContainerBgImage = (elementConfig) => !!elementConfig?.children?.some(({ id }) => id === BG_IMAGE_SLOT_ID);
17356
+
17153
17357
  const pieChartTooltipFromAttributes = (t, data, attributes) => {
17154
17358
  const attribute = attributes?.find(({ name }) => name === data[0].name);
17155
17359
  const renderValue = attribute
@@ -17528,7 +17732,7 @@ const ChartLegend = ({ data, chartElement, fontSize, type, twoColumns, loading }
17528
17732
  const ContainerChildren = memo(({ type, items, isColumn, isMain, renderElement }) => {
17529
17733
  const checkIfEmptyDataSource = useHideIfEmptyDataSource(type);
17530
17734
  return (jsx(Fragment$1, { children: items
17531
- ?.filter(item => !TITLE_SLOT_IDS.includes(item.id))
17735
+ ?.filter(item => !NON_TRACK_SLOT_IDS.includes(item.id))
17532
17736
  ?.map((item, index) => {
17533
17737
  const render = renderElement({
17534
17738
  id: item.id,
@@ -18175,5 +18379,5 @@ const DEFAULT_HEATMAP_STYLE = {
18175
18379
  ],
18176
18380
  };
18177
18381
 
18178
- export { ALIGNMENTS, ALIGN_ITEMS, ATTRIBUTE_ICON_ELEMENT_TYPES, AddButtonRow, AddFeatureButton, AddFeatureContainer, AlertIconContainer, AttachmentContainer, AttributeGalleryContainer, AttributeLabel, BASE_CONTAINER_STYLE, BaseMapTheme, CHART_TYPES, COMPACT_FRACTION_DIGITS, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CONTAINERS_GROUP_DEFAULTS, CONTAINER_BODY_ATTRIBUTE, CONTAINER_BODY_FILL_STYLE, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, Container, ContainerChildren, ContainerLoading, ContainerRoot, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DASHBOARD_OVERLAY_Z_INDEX, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_BLUR, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_RADIUS, DEFAULT_CIRCLE_STROKE_WIDTH, DEFAULT_CIRCLE_STYLE, DEFAULT_COLOR, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_DROPDOWN_WIDTH, DEFAULT_FILL_EXTRUSION_BASE, DEFAULT_FILL_EXTRUSION_HEIGHT, DEFAULT_FILL_EXTRUSION_STYLE, DEFAULT_FILL_EXTRUSION_VERTICAL_GRADIENT, DEFAULT_FILL_STYLE, DEFAULT_FILTER_PADDING, DEFAULT_GRID_GAP, DEFAULT_HEATMAP_COLOR, DEFAULT_HEATMAP_INTENSITY, DEFAULT_HEATMAP_RADIUS, DEFAULT_HEATMAP_STYLE, DEFAULT_HEATMAP_WEIGHT, DEFAULT_ICON_ANCHOR, DEFAULT_ICON_OVERLAP, DEFAULT_ICON_PADDING, DEFAULT_ICON_ROTATE, DEFAULT_ICON_SIZE, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_CAP, DEFAULT_LINE_JOIN, DEFAULT_LINE_STYLE, DEFAULT_LINE_WIDTH, DEFAULT_LNG, DEFAULT_OPACITY, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_SYMBOL_COLOR, DEFAULT_SYMBOL_HALO_COLOR, DEFAULT_SYMBOL_PLACEMENT, DEFAULT_SYMBOL_SPACING, DEFAULT_SYMBOL_STYLE, DEFAULT_TEXT_ANCHOR, DEFAULT_TEXT_JUSTIFY, DEFAULT_TEXT_SIZE, DEFAULT_TEXT_TRANSFORM, DEFAULT_TRACK_FR, DEFAULT_TRANSLATE, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EMPTY_DATA_SOURCE_LAYER_INFO, EXTENT_FILTER_NAME, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementControl, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementMarkdown, ElementSlideshow, ElementSvg, ElementTable, ElementTooltip, ElementValueWrapper, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILL_SIZE, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FR_PRECISION, FeatureCardBackgroundHeader, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GEOMETRY_FILTER_NAME, GRID_AUTO_FILL_DEFAULTS, GRID_CELL_ATTR, GRID_CELL_ID_PREFIX, GRID_DRAGGING_ATTR, GRID_DRAG_SOURCE_ATTR, GRID_DROP_TARGET_ATTR, GRID_FILL_DEFAULTS, GRID_HANDLE_ATTR, GRID_HANDLE_PROPS, GRID_ROW_ID_PREFIX, GlobalContext, GlobalProvider, GridRowContainer, HANDLE_BLEED_PX, Header, HeaderContainer, HeaderFontColorMixin, HeaderFrontView, HeaderTemplate, HeaderTitleContainer, HiddenTitleItems, IconContainer, ImageContainer, LEFT_PANEL_HEADER_HEIGHT, Layer, LayerDescription, LayerGroupList, LayerIcon, LayerIconContainer, LayerListContainer, LayerTree, LayersContainer, LayersListWrapper, LinearProgressContainer, LogTerminal, LogoContainer, MAP_VIEW_FILTER_NAMES, MAX_CHART_WIDTH, MAX_TRACKS, MIN_TRACK_PX, MIN_TRACK_RATIO, Map$1 as Map, MapContext, MapProvider, NO_CELL_DRAG_SELECTOR, NO_CONTENT_VALUE, NUMERIC_ATTRIBUTE_TYPES, NoLiveSnapshotContainer, OBJECT_FITS, OVERFLOWS, OneColumnContainer, PIE_CHART_TOOLTIP_STYLE, POLL_SUBTASK_INTERVAL_MS, POLL_SUBTASK_TIMEOUT_MS, PROVIDER_PREFIX, PageNavigator, PageTitle, PageTitleContainer, PagesContainer, Pagination, PresentationHeader, PresentationHeaderButtons, PresentationHeaderTools, PresentationPanelContainer, PresentationPanelWrapper, PresentationWrapper, ProgressContainer, ProviderPrefix, QUERY_DESCRIPTION_CACHE_TTL, RoundedBackgroundContainer, SAVE_HOOK_RESULT_DURATION, SERVER_NOTIFICATION_EVENT, STACK_BAR_TOTAL_HEIGHT, ScalingFactor, ServerNotificationsContext, ServerNotificationsProvider, SlideshowContainer, SmallPreviewContainer$1 as SmallPreviewContainer, SmallPreviewControl, SmallPreviewCounter, SmallPreviewImages, SmallPreviewLeft, SmallPreviewRight, StackBar, StructuredDataContainer, SvgImage, TILE_ALIGNMENTS, TIME_ZONE_FORMAT, TITLE_SLOT_IDS, TabsContainer, TextTrim, ThemeName, TitleContainer, TopContainer, TopContainerButtons, TwoColumnContainer, UploadContainer, VIEW_MODES, WidgetType, ZOOM_FILTER_NAME, addDataSource, addDataSources, adjustColor, applyFiltersToCondition, applyQueryFilters, applyTreeFilterToCondition, applyVarsToCondition, asAttributeName, asChartId, asContainerId, asDataSourceName, asFilterName, asLayerName, asModalId, asResourceId, asTabId, buildGridTemplate, buildTrackTemplate, checkEqualOrIncludes, checkIsLoading, collectConfigIds, containsNodeId, createConfigLayer, createConfigPage, createGridCell, createGridIdFactory, createGridRow, createNewPageId, createSaveNotificationId, dateOptions, debounce, decimalOpacityToHex, enrichStyleItemsWithIds, enrichStyleModelsWithIds, eqlParametersToPayload, fetchQueryDescription, findAttributeInExpression, findCellContext, formatArea, formatAttributeValue, formatChartRelatedValue, formatConditionValue, formatDataSourceCondition, formatDate$1 as formatDate, formatElementValue, formatLength, formatNumber, formatPolygonMeasure, geometryToEwkt, getActualExtrusionHeight, getAttributeByName, getAttributeConfigurationByName, getAttributeIconElement, getAttributeIconUrl, getAttributeValue, getAttributesConfiguration, getAverageTrackSize, getChartAxes, getChartFilterName, getChartMarkers, getConfigFilter, getContainerComponent, getDashboardHeader, getDataFromAttributes, getDataFromRelatedFeatures, getDataSource, getDataSourceFilterValue, getDataSourceLayerInfo, getDate, getDefaultConfig, getDisplayTemplateNameFromAttribute, getElementValue, getFeatureAttributes, getFeatureCardHeader, getFilterComponent, getFilterSelectedItems, getFilterValue, getFormattedAttributes, getGradientColors, getImageUrl, getLayerClientStyle, getLayerInfo, getLayerInfoAttribute, getLayerInfoFromDataSources, getLayoutChildren, getMapViewDataSources, getPagesFromConfig, getPagesFromProjectInfo, getProxyService, getRelatedAttribute, getRenderElement, getResourceUrl, getRootElementId, getSelectedFilterValue, getSlideshowImages, getStyleAttributes, getSvgUrl, getTemplateNameFromAttribute, getThemeByName, getTotalFromAttributes, getTotalFromRelatedFeatures, getTrackSize, getTrackSizeKey, getTrackSizes, getWrapperSizeStyle, hexToRgba, isEmptyElementValue, isEmptyValue, isFeaturesFilterValue, isFillSize, isFrSize, isGridNode, isHiddenEmptyValue, isHookActive, isLayerService, isNotValidSelectedTab, isNumeric, isObject, isProxyService, isRootOwningContainer, isTreeFilterValue, isVisibleContainer, mapNodeById, mergeAttributeConfigurations, metersPerPixel, noMarginMixin, numberOptions, parseFrValue, parseIconNames, parseIconNamesFromClientStyle, pieChartTooltipFromAttributes, pieChartTooltipFromRelatedFeatures, pointOptions, removeDataSource, removeTracks, replaceNodesByIds, rgbToHex, roundFr, roundTotalSum, setLayoutChildren, sizeCssMixin, sliceShownOtherItems, stretchPalette, timeOptions, toConditionsArray, toCssSize, toFrSize, toPxNumber, toRenderableValue, tooltipNameFromAttributes, tooltipValueFromAttributes, tooltipValueFromRelatedFeatures, transparentizeColor, updateDataSource, useAfterSave, useAppHeight, useAttachmentItems, useAttachmentPreviewImages, useAutoCompleteControl, useBeforeSave, useChartChange, useChartData, useContainerAttributes, useContainerRoot, useCurrentPageLayers, useCustomFeatureSelect, useDashboardHeader, useDataSourceLoading, useDataSources, useDebouncedCallback, useDiffPage, useEditGroupAttributes, useEqualTileWidth, useExpandableContainers, useExportPdf, useFeatureSaveHooks, useFetchImageWithAuth, useFetchWithAuth, useGetConfigLayer, useGlobalContext, useHeaderRender, useHideIfEmptyDataSource, useIconsFromLayers, useLayerHiddenAttributes, useLayerParams, useMapContext, useMapDraw, useMapImages, useMaxZoomTo, useProjectDashboardInit, usePythonSandbox, usePythonTask, useRedrawLayer, useRelatedDataSourceAttributes, useRemoteTask, useRenderElement, useResizeBox, useSavePrototypeBuilder, useServerNotificationsContext, useShownOtherItems, useToggle, useUpdateDataSource, useVisibleProjectItems, useWidgetConfig, useWidgetContext, useWidgetFilters, useWidgetPage, useWindowResize, useWrapperSize, useZoomToFeatures, useZoomToPoint, withTrackSize };
18382
+ export { ALIGNMENTS, ALIGN_ITEMS, ATTRIBUTE_ICON_ELEMENT_TYPES, AddButtonRow, AddFeatureButton, AddFeatureContainer, AlertIconContainer, AttachmentContainer, AttributeGalleryContainer, AttributeLabel, BASE_CONTAINER_STYLE, BG_IMAGE_SLOT_ID, BaseMapTheme, CHART_TYPES, COMPACT_FRACTION_DIGITS, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CONTAINERS_GROUP_DEFAULTS, CONTAINER_BODY_ATTRIBUTE, CONTAINER_BODY_FILL_STYLE, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, Container, ContainerBackground, ContainerChildren, ContainerLoading, ContainerRoot, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DASHBOARD_OVERLAY_Z_INDEX, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_BLUR, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_RADIUS, DEFAULT_CIRCLE_STROKE_WIDTH, DEFAULT_CIRCLE_STYLE, DEFAULT_COLOR, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_DROPDOWN_WIDTH, DEFAULT_FILL_EXTRUSION_BASE, DEFAULT_FILL_EXTRUSION_HEIGHT, DEFAULT_FILL_EXTRUSION_STYLE, DEFAULT_FILL_EXTRUSION_VERTICAL_GRADIENT, DEFAULT_FILL_STYLE, DEFAULT_FILTER_PADDING, DEFAULT_GRID_GAP, DEFAULT_HEATMAP_COLOR, DEFAULT_HEATMAP_INTENSITY, DEFAULT_HEATMAP_RADIUS, DEFAULT_HEATMAP_STYLE, DEFAULT_HEATMAP_WEIGHT, DEFAULT_ICON_ANCHOR, DEFAULT_ICON_OVERLAP, DEFAULT_ICON_PADDING, DEFAULT_ICON_ROTATE, DEFAULT_ICON_SIZE, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_CAP, DEFAULT_LINE_JOIN, DEFAULT_LINE_STYLE, DEFAULT_LINE_WIDTH, DEFAULT_LNG, DEFAULT_OPACITY, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_SYMBOL_COLOR, DEFAULT_SYMBOL_HALO_COLOR, DEFAULT_SYMBOL_PLACEMENT, DEFAULT_SYMBOL_SPACING, DEFAULT_SYMBOL_STYLE, DEFAULT_TEXT_ANCHOR, DEFAULT_TEXT_JUSTIFY, DEFAULT_TEXT_SIZE, DEFAULT_TEXT_TRANSFORM, DEFAULT_TRACK_FR, DEFAULT_TRANSLATE, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EMPTY_DATA_SOURCE_LAYER_INFO, EXTENT_FILTER_NAME, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementControl, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementMarkdown, ElementSlideshow, ElementSvg, ElementTable, ElementTooltip, ElementValueWrapper, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILL_SIZE, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FR_PRECISION, FeatureCardBackgroundHeader, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GEOMETRY_FILTER_NAME, GRID_AUTO_FILL_DEFAULTS, GRID_CELL_ATTR, GRID_CELL_ID_PREFIX, GRID_DRAGGING_ATTR, GRID_DRAG_SOURCE_ATTR, GRID_DROP_TARGET_ATTR, GRID_FILL_DEFAULTS, GRID_HANDLE_ATTR, GRID_HANDLE_PROPS, GRID_ROW_ID_PREFIX, GlobalContext, GlobalProvider, GridRowContainer, HANDLE_BLEED_PX, Header, HeaderContainer, HeaderFontColorMixin, HeaderFrontView, HeaderTemplate, HeaderTitleContainer, HiddenTitleItems, IconContainer, ImageContainer, LEFT_PANEL_HEADER_HEIGHT, Layer, LayerDescription, LayerGroupList, LayerIcon, LayerIconContainer, LayerListContainer, LayerTree, LayersContainer, LayersListWrapper, LinearProgressContainer, LogTerminal, LogoContainer, MAP_VIEW_FILTER_NAMES, MAX_CHART_WIDTH, MAX_TRACKS, MIN_TRACK_PX, MIN_TRACK_RATIO, Map$1 as Map, MapContext, MapProvider, NON_TRACK_SLOT_IDS, NO_CELL_DRAG_SELECTOR, NO_CONTENT_VALUE, NUMERIC_ATTRIBUTE_TYPES, NoLiveSnapshotContainer, OBJECT_FITS, OVERFLOWS, OneColumnContainer, PIE_CHART_TOOLTIP_STYLE, POLL_SUBTASK_INTERVAL_MS, POLL_SUBTASK_TIMEOUT_MS, PROVIDER_PREFIX, PageNavigator, PageTitle, PageTitleContainer, PagesContainer, Pagination, PresentationHeader, PresentationHeaderButtons, PresentationHeaderTools, PresentationPanelContainer, PresentationPanelWrapper, PresentationWrapper, ProgressContainer, ProviderPrefix, QUERY_DESCRIPTION_CACHE_TTL, RoundedBackgroundContainer, SAVE_HOOK_RESULT_DURATION, SERVER_NOTIFICATION_EVENT, STACK_BAR_TOTAL_HEIGHT, ScalingFactor, ServerNotificationsContext, ServerNotificationsProvider, SlideshowContainer, SmallPreviewContainer$1 as SmallPreviewContainer, SmallPreviewControl, SmallPreviewCounter, SmallPreviewImages, SmallPreviewLeft, SmallPreviewRight, StackBar, StructuredDataContainer, SvgImage, TILE_ALIGNMENTS, TIME_ZONE_FORMAT, TITLE_SLOT_IDS, TabsContainer, TextTrim, ThemeName, TitleContainer, TopContainer, TopContainerButtons, TwoColumnContainer, UploadContainer, VIEW_MODES, WidgetType, ZOOM_FILTER_NAME, addDataSource, addDataSources, adjustColor, applyFiltersToCondition, applyQueryFilters, applyTreeFilterToCondition, applyVarsToCondition, asAttributeName, asChartId, asContainerId, asDataSourceName, asFilterName, asLayerName, asModalId, asResourceId, asTabId, buildGridTemplate, buildTrackTemplate, checkEqualOrIncludes, checkIsLoading, collectConfigIds, containsNodeId, createConfigLayer, createConfigPage, createGridCell, createGridIdFactory, createGridRow, createNewPageId, createSaveNotificationId, dateOptions, debounce, decimalOpacityToHex, enrichStyleItemsWithIds, enrichStyleModelsWithIds, eqlParametersToPayload, fetchQueryDescription, findAttributeInExpression, findCellContext, formatArea, formatAttributeValue, formatChartRelatedValue, formatConditionValue, formatDataSourceCondition, formatDate$1 as formatDate, formatElementValue, formatLength, formatNumber, formatPolygonMeasure, geometryToEwkt, getActualExtrusionHeight, getAttributeByName, getAttributeConfigurationByName, getAttributeIconElement, getAttributeIconUrl, getAttributeValue, getAttributesConfiguration, getAverageTrackSize, getChartAxes, getChartFilterName, getChartMarkers, getConfigFilter, getContainerComponent, getDashboardHeader, getDataFromAttributes, getDataFromRelatedFeatures, getDataSource, getDataSourceFilterValue, getDataSourceLayerInfo, getDate, getDefaultConfig, getDisplayTemplateNameFromAttribute, getElementValue, getFeatureAttributes, getFeatureCardHeader, getFilterComponent, getFilterSelectedItems, getFilterValue, getFormattedAttributes, getGradientColors, getImageUrl, getLayerClientStyle, getLayerInfo, getLayerInfoAttribute, getLayerInfoFromDataSources, getLayoutChildren, getMapViewDataSources, getPagesFromConfig, getPagesFromProjectInfo, getProxyService, getRelatedAttribute, getRenderElement, getResourceUrl, getRootElementId, getSelectedFilterValue, getSlideshowImages, getStyleAttributes, getSvgUrl, getTemplateNameFromAttribute, getThemeByName, getTotalFromAttributes, getTotalFromRelatedFeatures, getTrackSize, getTrackSizeKey, getTrackSizes, getWrapperSizeStyle, hasContainerBgImage, hexToRgba, isEmptyElementValue, isEmptyValue, isFeaturesFilterValue, isFillSize, isFrSize, isGridNode, isHiddenEmptyValue, isHookActive, isLayerService, isNotValidSelectedTab, isNumeric, isObject, isProxyService, isRootOwningContainer, isTreeFilterValue, isVisibleContainer, mapNodeById, mergeAttributeConfigurations, metersPerPixel, noMarginMixin, numberOptions, parseFrValue, parseIconNames, parseIconNamesFromClientStyle, pieChartTooltipFromAttributes, pieChartTooltipFromRelatedFeatures, pointOptions, removeDataSource, removeTracks, replaceNodesByIds, rgbToHex, roundFr, roundTotalSum, setLayoutChildren, sizeCssMixin, sliceShownOtherItems, stretchPalette, timeOptions, toConditionsArray, toCssSize, toFrSize, toPxNumber, toRenderableValue, tooltipNameFromAttributes, tooltipValueFromAttributes, tooltipValueFromRelatedFeatures, transparentizeColor, updateDataSource, useAfterSave, useAppHeight, useAttachmentItems, useAttachmentPreviewImages, useAutoCompleteControl, useBeforeSave, useBgImageHost, useChartChange, useChartData, useContainerAttributes, useContainerRoot, useCurrentPageLayers, useCustomFeatureSelect, useDashboardHeader, useDataSourceLoading, useDataSources, useDebouncedCallback, useDiffPage, useEditGroupAttributes, useEqualTileWidth, useExpandableContainers, useExportPdf, useFeatureSaveHooks, useFetchImageWithAuth, useFetchWithAuth, useGetConfigLayer, useGlobalContext, useHeaderRender, useHideIfEmptyDataSource, useIconsFromLayers, useLayerHiddenAttributes, useLayerParams, useMapContext, useMapDraw, useMapImages, useMaxZoomTo, useProjectDashboardInit, usePythonSandbox, usePythonTask, useRedrawLayer, useRelatedDataSourceAttributes, useRemoteTask, useRenderElement, useResizeBox, useSavePrototypeBuilder, useServerNotificationsContext, useShownOtherItems, useToggle, useUpdateDataSource, useVisibleProjectItems, useWidgetConfig, useWidgetContext, useWidgetFilters, useWidgetPage, useWindowResize, useWrapperSize, useZoomToFeatures, useZoomToPoint, withTrackSize };
18179
18383
  //# sourceMappingURL=react.esm.js.map