@gemx-dev/heatmap-react 3.5.92-dev.16 → 3.5.92-dev.18

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 (134) hide show
  1. package/dist/esm/components/VizDom/VizDomHeatmap.d.ts.map +1 -1
  2. package/dist/esm/components/VizDom/VizDomRenderer.d.ts +2 -1
  3. package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  4. package/dist/esm/hooks/common/index.d.ts +1 -1
  5. package/dist/esm/hooks/common/index.d.ts.map +1 -1
  6. package/dist/esm/hooks/common/useHeatmapViewportByDevice.d.ts +7 -0
  7. package/dist/esm/hooks/common/useHeatmapViewportByDevice.d.ts.map +1 -0
  8. package/dist/esm/hooks/view-context/useHeatmapVizContext.d.ts +2 -2
  9. package/dist/esm/hooks/view-context/useHeatmapVizContext.d.ts.map +1 -1
  10. package/dist/esm/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  11. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  12. package/dist/esm/hooks/viz-render/useHeatmapIframeProcessor.d.ts +6 -0
  13. package/dist/esm/hooks/viz-render/useHeatmapIframeProcessor.d.ts.map +1 -0
  14. package/dist/esm/hooks/viz-render/useHeatmapRenderByMode.d.ts +3 -2
  15. package/dist/esm/hooks/viz-render/useHeatmapRenderByMode.d.ts.map +1 -1
  16. package/dist/esm/hooks/viz-render/useHeatmapRenderDom.d.ts +5 -0
  17. package/dist/esm/hooks/viz-render/useHeatmapRenderDom.d.ts.map +1 -0
  18. package/dist/esm/hooks/viz-render/useReplayRender.d.ts +2 -2
  19. package/dist/esm/hooks/viz-render/useReplayRender.d.ts.map +1 -1
  20. package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  21. package/dist/esm/hooks/viz-scale/useScaleCalculation.d.ts +1 -2
  22. package/dist/esm/hooks/viz-scale/useScaleCalculation.d.ts.map +1 -1
  23. package/dist/esm/index.js +697 -185
  24. package/dist/esm/index.mjs +697 -185
  25. package/dist/esm/libs/visualizer/GXVisualizer.d.ts +7 -1
  26. package/dist/esm/libs/visualizer/GXVisualizer.d.ts.map +1 -1
  27. package/dist/esm/libs/visualizer/cache/config.d.ts +15 -0
  28. package/dist/esm/libs/visualizer/cache/config.d.ts.map +1 -0
  29. package/dist/esm/libs/visualizer/cache/index.d.ts +16 -0
  30. package/dist/esm/libs/visualizer/cache/index.d.ts.map +1 -0
  31. package/dist/esm/libs/visualizer/index.d.ts +1 -2
  32. package/dist/esm/libs/visualizer/index.d.ts.map +1 -1
  33. package/dist/esm/libs/visualizer/{AttentionMapRenderer.d.ts → renderers/AttentionMapRenderer.d.ts} +1 -1
  34. package/dist/esm/libs/visualizer/renderers/AttentionMapRenderer.d.ts.map +1 -0
  35. package/dist/esm/libs/visualizer/{ClickHeatmapRenderer.d.ts → renderers/ClickHeatmapRenderer.d.ts} +1 -1
  36. package/dist/esm/libs/visualizer/renderers/ClickHeatmapRenderer.d.ts.map +1 -0
  37. package/dist/esm/libs/visualizer/renderers/index.d.ts +3 -0
  38. package/dist/esm/libs/visualizer/renderers/index.d.ts.map +1 -0
  39. package/dist/esm/libs/visualizer/shadow-dom/extractor.d.ts +23 -0
  40. package/dist/esm/libs/visualizer/shadow-dom/extractor.d.ts.map +1 -0
  41. package/dist/esm/libs/visualizer/types/data.d.ts +72 -0
  42. package/dist/esm/libs/visualizer/types/data.d.ts.map +1 -0
  43. package/dist/esm/libs/visualizer/{types.d.ts → types/extend.d.ts} +7 -2
  44. package/dist/esm/libs/visualizer/types/extend.d.ts.map +1 -0
  45. package/dist/esm/libs/visualizer/types/index.d.ts +6 -0
  46. package/dist/esm/libs/visualizer/types/index.d.ts.map +1 -0
  47. package/dist/esm/libs/visualizer/types/layout.d.ts +69 -0
  48. package/dist/esm/libs/visualizer/types/layout.d.ts.map +1 -0
  49. package/dist/esm/libs/visualizer/types/visualize.d.ts +7 -0
  50. package/dist/esm/libs/visualizer/types/visualize.d.ts.map +1 -0
  51. package/dist/esm/stores/viz.d.ts +2 -2
  52. package/dist/esm/stores/viz.d.ts.map +1 -1
  53. package/dist/esm/types/heatmap-info.d.ts +1 -0
  54. package/dist/esm/types/heatmap-info.d.ts.map +1 -1
  55. package/dist/esm/types/heatmap.d.ts +4 -0
  56. package/dist/esm/types/heatmap.d.ts.map +1 -1
  57. package/dist/umd/components/VizDom/VizDomHeatmap.d.ts.map +1 -1
  58. package/dist/umd/components/VizDom/VizDomRenderer.d.ts +2 -1
  59. package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  60. package/dist/umd/hooks/common/index.d.ts +1 -1
  61. package/dist/umd/hooks/common/index.d.ts.map +1 -1
  62. package/dist/umd/hooks/common/useHeatmapViewportByDevice.d.ts +7 -0
  63. package/dist/umd/hooks/common/useHeatmapViewportByDevice.d.ts.map +1 -0
  64. package/dist/umd/hooks/view-context/useHeatmapVizContext.d.ts +2 -2
  65. package/dist/umd/hooks/view-context/useHeatmapVizContext.d.ts.map +1 -1
  66. package/dist/umd/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  67. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  68. package/dist/umd/hooks/viz-render/useHeatmapIframeProcessor.d.ts +6 -0
  69. package/dist/umd/hooks/viz-render/useHeatmapIframeProcessor.d.ts.map +1 -0
  70. package/dist/umd/hooks/viz-render/useHeatmapRenderByMode.d.ts +3 -2
  71. package/dist/umd/hooks/viz-render/useHeatmapRenderByMode.d.ts.map +1 -1
  72. package/dist/umd/hooks/viz-render/useHeatmapRenderDom.d.ts +5 -0
  73. package/dist/umd/hooks/viz-render/useHeatmapRenderDom.d.ts.map +1 -0
  74. package/dist/umd/hooks/viz-render/useReplayRender.d.ts +2 -2
  75. package/dist/umd/hooks/viz-render/useReplayRender.d.ts.map +1 -1
  76. package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  77. package/dist/umd/hooks/viz-scale/useScaleCalculation.d.ts +1 -2
  78. package/dist/umd/hooks/viz-scale/useScaleCalculation.d.ts.map +1 -1
  79. package/dist/umd/index.js +2 -2
  80. package/dist/umd/libs/visualizer/GXVisualizer.d.ts +7 -1
  81. package/dist/umd/libs/visualizer/GXVisualizer.d.ts.map +1 -1
  82. package/dist/umd/libs/visualizer/cache/config.d.ts +15 -0
  83. package/dist/umd/libs/visualizer/cache/config.d.ts.map +1 -0
  84. package/dist/umd/libs/visualizer/cache/index.d.ts +16 -0
  85. package/dist/umd/libs/visualizer/cache/index.d.ts.map +1 -0
  86. package/dist/umd/libs/visualizer/index.d.ts +1 -2
  87. package/dist/umd/libs/visualizer/index.d.ts.map +1 -1
  88. package/dist/umd/libs/visualizer/{AttentionMapRenderer.d.ts → renderers/AttentionMapRenderer.d.ts} +1 -1
  89. package/dist/umd/libs/visualizer/renderers/AttentionMapRenderer.d.ts.map +1 -0
  90. package/dist/umd/libs/visualizer/{ClickHeatmapRenderer.d.ts → renderers/ClickHeatmapRenderer.d.ts} +1 -1
  91. package/dist/umd/libs/visualizer/renderers/ClickHeatmapRenderer.d.ts.map +1 -0
  92. package/dist/umd/libs/visualizer/renderers/index.d.ts +3 -0
  93. package/dist/umd/libs/visualizer/renderers/index.d.ts.map +1 -0
  94. package/dist/umd/libs/visualizer/shadow-dom/extractor.d.ts +23 -0
  95. package/dist/umd/libs/visualizer/shadow-dom/extractor.d.ts.map +1 -0
  96. package/dist/umd/libs/visualizer/types/data.d.ts +72 -0
  97. package/dist/umd/libs/visualizer/types/data.d.ts.map +1 -0
  98. package/dist/umd/libs/visualizer/{types.d.ts → types/extend.d.ts} +7 -2
  99. package/dist/umd/libs/visualizer/types/extend.d.ts.map +1 -0
  100. package/dist/umd/libs/visualizer/types/index.d.ts +6 -0
  101. package/dist/umd/libs/visualizer/types/index.d.ts.map +1 -0
  102. package/dist/umd/libs/visualizer/types/layout.d.ts +69 -0
  103. package/dist/umd/libs/visualizer/types/layout.d.ts.map +1 -0
  104. package/dist/umd/libs/visualizer/types/visualize.d.ts +7 -0
  105. package/dist/umd/libs/visualizer/types/visualize.d.ts.map +1 -0
  106. package/dist/umd/stores/viz.d.ts +2 -2
  107. package/dist/umd/stores/viz.d.ts.map +1 -1
  108. package/dist/umd/types/heatmap-info.d.ts +1 -0
  109. package/dist/umd/types/heatmap-info.d.ts.map +1 -1
  110. package/dist/umd/types/heatmap.d.ts +4 -0
  111. package/dist/umd/types/heatmap.d.ts.map +1 -1
  112. package/package.json +4 -4
  113. package/dist/esm/hooks/common/useHeatmapWidthByDevice.d.ts +0 -2
  114. package/dist/esm/hooks/common/useHeatmapWidthByDevice.d.ts.map +0 -1
  115. package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts +0 -5
  116. package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +0 -1
  117. package/dist/esm/hooks/viz-scale/useContentDimensions.d.ts +0 -9
  118. package/dist/esm/hooks/viz-scale/useContentDimensions.d.ts.map +0 -1
  119. package/dist/esm/libs/visualizer/AttentionMapRenderer.d.ts.map +0 -1
  120. package/dist/esm/libs/visualizer/ClickHeatmapRenderer.d.ts.map +0 -1
  121. package/dist/esm/libs/visualizer/ScrollHeatmapRenderer.d.ts +0 -17
  122. package/dist/esm/libs/visualizer/ScrollHeatmapRenderer.d.ts.map +0 -1
  123. package/dist/esm/libs/visualizer/types.d.ts.map +0 -1
  124. package/dist/umd/hooks/common/useHeatmapWidthByDevice.d.ts +0 -2
  125. package/dist/umd/hooks/common/useHeatmapWidthByDevice.d.ts.map +0 -1
  126. package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts +0 -5
  127. package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +0 -1
  128. package/dist/umd/hooks/viz-scale/useContentDimensions.d.ts +0 -9
  129. package/dist/umd/hooks/viz-scale/useContentDimensions.d.ts.map +0 -1
  130. package/dist/umd/libs/visualizer/AttentionMapRenderer.d.ts.map +0 -1
  131. package/dist/umd/libs/visualizer/ClickHeatmapRenderer.d.ts.map +0 -1
  132. package/dist/umd/libs/visualizer/ScrollHeatmapRenderer.d.ts +0 -17
  133. package/dist/umd/libs/visualizer/ScrollHeatmapRenderer.d.ts.map +0 -1
  134. package/dist/umd/libs/visualizer/types.d.ts.map +0 -1
@@ -162,6 +162,11 @@ var EHeatmapType;
162
162
  EHeatmapType["Click"] = "click";
163
163
  EHeatmapType["Scroll"] = "scroll";
164
164
  })(EHeatmapType || (EHeatmapType = {}));
165
+ var EHeatmapMode;
166
+ (function (EHeatmapMode) {
167
+ EHeatmapMode["Heatmap"] = "heatmap";
168
+ EHeatmapMode["Replay"] = "replay";
169
+ })(EHeatmapMode || (EHeatmapMode = {}));
165
170
  var EClickType;
166
171
  (function (EClickType) {
167
172
  /** Return all clicks (default) */
@@ -198,7 +203,6 @@ var EScrollType;
198
203
  EScrollType["Attention"] = "ATTENTION";
199
204
  EScrollType["Revenue"] = "REVENUE";
200
205
  })(EScrollType || (EScrollType = {}));
201
- var EHeatmapMode;
202
206
  (function (EHeatmapMode) {
203
207
  EHeatmapMode["Single"] = "single";
204
208
  EHeatmapMode["Live"] = "live";
@@ -620,16 +624,16 @@ const useHeatmapSettingStore = create()(subscribeWithSelector((set) => {
620
624
 
621
625
  const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
622
626
  return {
623
- isRenderedViz: new Map([[DEFAULT_VIEW_ID, false]]),
627
+ isDomLoaded: new Map([[DEFAULT_VIEW_ID, false]]),
624
628
  zoomRatio: new Map([[DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO.DEFAULT]]),
625
629
  minZoomRatio: new Map([[DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO.MIN]]),
626
630
  maxZoomRatio: new Map([[DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO.MAX]]),
627
631
  scale: new Map([[DEFAULT_VIEW_ID, 1]]),
628
632
  isScaledToFit: new Map([[DEFAULT_VIEW_ID, false]]),
629
- setIsRenderedViz: (isRenderedViz, viewId = DEFAULT_VIEW_ID) => set((prev) => {
630
- const newIsRenderedViz = new Map(prev.isRenderedViz);
631
- newIsRenderedViz.set(viewId, isRenderedViz);
632
- return { isRenderedViz: newIsRenderedViz };
633
+ setIsDomLoaded: (isDomLoaded, viewId = DEFAULT_VIEW_ID) => set((prev) => {
634
+ const newIsDomLoaded = new Map(prev.isDomLoaded);
635
+ newIsDomLoaded.set(viewId, isDomLoaded);
636
+ return { isDomLoaded: newIsDomLoaded };
633
637
  }),
634
638
  setZoomRatio: (zoomRatio, viewId = DEFAULT_VIEW_ID) => set((prev) => {
635
639
  const newZoomRatio = new Map(prev.zoomRatio);
@@ -657,18 +661,18 @@ const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
657
661
  return { isScaledToFit: newIsScaledToFit };
658
662
  }),
659
663
  copyView: (fromViewId, toViewId) => set((prev) => {
660
- const newIsRenderedViz = new Map(prev.isRenderedViz);
664
+ const newIsDomLoaded = new Map(prev.isDomLoaded);
661
665
  const newZoomRatio = new Map(prev.zoomRatio);
662
666
  const newMinZoomRatio = new Map(prev.minZoomRatio);
663
667
  const newScale = new Map(prev.scale);
664
668
  const newIsScaledToFit = new Map(prev.isScaledToFit);
665
- newIsRenderedViz.set(toViewId, prev.isRenderedViz.get(fromViewId) ?? false);
669
+ newIsDomLoaded.set(toViewId, prev.isDomLoaded.get(fromViewId) ?? false);
666
670
  newZoomRatio.set(toViewId, prev.zoomRatio.get(fromViewId) ?? 100);
667
671
  newMinZoomRatio.set(toViewId, prev.minZoomRatio.get(fromViewId) ?? 10);
668
672
  newScale.set(toViewId, prev.scale.get(fromViewId) ?? 1);
669
673
  newIsScaledToFit.set(toViewId, prev.isScaledToFit.get(fromViewId) ?? false);
670
674
  return {
671
- isRenderedViz: newIsRenderedViz,
675
+ isDomLoaded: newIsDomLoaded,
672
676
  zoomRatio: newZoomRatio,
673
677
  minZoomRatio: newMinZoomRatio,
674
678
  scale: newScale,
@@ -676,18 +680,18 @@ const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
676
680
  };
677
681
  }),
678
682
  clearView: (viewId) => set((prev) => {
679
- const newIsRenderedViz = new Map(prev.isRenderedViz);
683
+ const newIsDomLoaded = new Map(prev.isDomLoaded);
680
684
  const newZoomRatio = new Map(prev.zoomRatio);
681
685
  const newMinZoomRatio = new Map(prev.minZoomRatio);
682
686
  const newScale = new Map(prev.scale);
683
687
  const newIsScaledToFit = new Map(prev.isScaledToFit);
684
- newIsRenderedViz.delete(viewId);
688
+ newIsDomLoaded.delete(viewId);
685
689
  newZoomRatio.delete(viewId);
686
690
  newMinZoomRatio.delete(viewId);
687
691
  newScale.delete(viewId);
688
692
  newIsScaledToFit.delete(viewId);
689
693
  return {
690
- isRenderedViz: newIsRenderedViz,
694
+ isDomLoaded: newIsDomLoaded,
691
695
  zoomRatio: newZoomRatio,
692
696
  minZoomRatio: newMinZoomRatio,
693
697
  scale: newScale,
@@ -695,7 +699,7 @@ const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
695
699
  };
696
700
  }),
697
701
  resetAll: () => set({
698
- isRenderedViz: new Map([[DEFAULT_VIEW_ID, false]]),
702
+ isDomLoaded: new Map([[DEFAULT_VIEW_ID, false]]),
699
703
  zoomRatio: new Map([[DEFAULT_VIEW_ID, 100]]),
700
704
  minZoomRatio: new Map([[DEFAULT_VIEW_ID, 10]]),
701
705
  scale: new Map([[DEFAULT_VIEW_ID, 1]]),
@@ -1415,7 +1419,7 @@ const useHeatmapSettingContext = createViewContextHook({
1415
1419
  const useHeatmapVizContext = createViewContextHook({
1416
1420
  useStore: useHeatmapVizStore,
1417
1421
  getState: (store, viewId) => ({
1418
- isRenderedViz: store.isRenderedViz.get(viewId) ?? false,
1422
+ isDomLoaded: store.isDomLoaded.get(viewId) ?? false,
1419
1423
  zoomRatio: store.zoomRatio.get(viewId) ?? DEFAULT_ZOOM_RATIO.DEFAULT,
1420
1424
  minZoomRatio: store.minZoomRatio.get(viewId) ?? DEFAULT_ZOOM_RATIO.MIN,
1421
1425
  maxZoomRatio: store.maxZoomRatio.get(viewId) ?? DEFAULT_ZOOM_RATIO.MAX,
@@ -1423,7 +1427,7 @@ const useHeatmapVizContext = createViewContextHook({
1423
1427
  isScaledToFit: store.isScaledToFit.get(viewId) ?? false,
1424
1428
  }),
1425
1429
  getActions: (store, viewId) => ({
1426
- setIsRenderedViz: (value) => store.setIsRenderedViz(value, viewId),
1430
+ setIsDomLoaded: (value) => store.setIsDomLoaded(value, viewId),
1427
1431
  setZoomRatio: (value) => store.setZoomRatio(value, viewId),
1428
1432
  setMinZoomRatio: (value) => store.setMinZoomRatio(value, viewId),
1429
1433
  setMaxZoomRatio: (value) => store.setMaxZoomRatio(value, viewId),
@@ -1525,10 +1529,11 @@ const useHeatmapCopyView = () => {
1525
1529
  };
1526
1530
  };
1527
1531
 
1528
- const useHeatmapWidthByDevice = () => {
1532
+ const useHeatmapViewportByDevice = () => {
1529
1533
  const deviceType = useHeatmapSettingContext((state) => state.deviceType);
1530
1534
  const width = useMemo(() => calcWidthByDeviceType(deviceType), [deviceType]);
1531
- return width;
1535
+ const height = useMemo(() => calcHeightByDeviceType(deviceType), [deviceType]);
1536
+ return { width, height };
1532
1537
  function calcWidthByDeviceType(deviceType) {
1533
1538
  if (!deviceType)
1534
1539
  return 1440;
@@ -1543,6 +1548,20 @@ const useHeatmapWidthByDevice = () => {
1543
1548
  return 375;
1544
1549
  }
1545
1550
  }
1551
+ function calcHeightByDeviceType(deviceType) {
1552
+ if (!deviceType)
1553
+ return 900;
1554
+ switch (deviceType) {
1555
+ case EDeviceType.DesktopLarge:
1556
+ return 1080; // 1920×1080
1557
+ case EDeviceType.Desktop:
1558
+ return 900; // 1440×900
1559
+ case EDeviceType.Tablet:
1560
+ return 1024; // 768×1024 (iPad portrait)
1561
+ case EDeviceType.Mobile:
1562
+ return 812; // 375×812 (iPhone X/11/12/13)
1563
+ }
1564
+ }
1546
1565
  };
1547
1566
 
1548
1567
  const useRegisterConfig = ({ shopId, isLoading, isLoadingCanvas, excludeClassNames, }) => {
@@ -1567,7 +1586,7 @@ const useRegisterConfig = ({ shopId, isLoading, isLoadingCanvas, excludeClassNam
1567
1586
  setIsRendering(true);
1568
1587
  setTimeout(() => {
1569
1588
  setIsRendering(false);
1570
- }, 100);
1589
+ }, 500);
1571
1590
  }, [mode, deviceType, sidebarWidth]); // eslint-disable-line react-hooks/exhaustive-deps
1572
1591
  useEffect(() => {
1573
1592
  setIsRendering(!!isLoading);
@@ -3504,18 +3523,31 @@ const useAreaClickmap = () => {
3504
3523
  const useClickmap = () => {
3505
3524
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
3506
3525
  const clickmap = useHeatmapDataContext((s) => s.clickmap);
3507
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
3526
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
3527
+ const timerRef = useRef(null);
3508
3528
  const start = useCallback(() => {
3509
- if (!vizRef || !clickmap || clickmap.length === 0 || !isRenderedViz)
3529
+ if (!vizRef || !clickmap || clickmap.length === 0 || !isDomLoaded)
3510
3530
  return;
3511
3531
  try {
3512
- vizRef?.clearmap?.();
3513
- vizRef?.clickmap?.(clickmap);
3532
+ if (timerRef.current)
3533
+ clearTimeout(timerRef.current);
3534
+ timerRef.current = setTimeout(() => {
3535
+ vizRef?.clearmap?.();
3536
+ vizRef?.clickmap?.(clickmap);
3537
+ }, 100);
3514
3538
  }
3515
3539
  catch (error) {
3516
3540
  console.error(`🚀 🐥 ~ useClickmap ~ error:`, error);
3517
3541
  }
3518
- }, [vizRef, clickmap, isRenderedViz]);
3542
+ finally {
3543
+ timerRef.current = null;
3544
+ }
3545
+ }, [vizRef, clickmap, isDomLoaded]);
3546
+ useEffect(() => {
3547
+ return () => {
3548
+ timerRef.current && clearTimeout(timerRef.current);
3549
+ };
3550
+ }, []);
3519
3551
  return { start };
3520
3552
  };
3521
3553
 
@@ -3523,6 +3555,7 @@ const useScrollmap = () => {
3523
3555
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
3524
3556
  const scrollType = useHeatmapSettingContext((s) => s.scrollType);
3525
3557
  const scrollmap = useHeatmapDataContext((s) => s.scrollmap);
3558
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
3526
3559
  useMemo(() => {
3527
3560
  switch (scrollType) {
3528
3561
  case EScrollType.Depth:
@@ -3536,7 +3569,7 @@ const useScrollmap = () => {
3536
3569
  }
3537
3570
  }, [scrollmap, scrollType]);
3538
3571
  const start = useCallback(() => {
3539
- if (!vizRef || !scrollmap || scrollmap.length === 0)
3572
+ if (!vizRef || !scrollmap || scrollmap.length === 0 || !isDomLoaded)
3540
3573
  return;
3541
3574
  try {
3542
3575
  vizRef?.clearmap?.();
@@ -3545,7 +3578,7 @@ const useScrollmap = () => {
3545
3578
  catch (error) {
3546
3579
  logger$4.error(`🚀 🐥 ~ useScrollmap ~ error:`, error);
3547
3580
  }
3548
- }, [vizRef, scrollmap]);
3581
+ }, [vizRef, scrollmap, isDomLoaded]);
3549
3582
  return { start };
3550
3583
  };
3551
3584
 
@@ -3709,7 +3742,7 @@ const useHeatmapEffects = ({ isVisible }) => {
3709
3742
  };
3710
3743
 
3711
3744
  const useHeatmapElementPosition = ({ iframeRef, wrapperRef, visualizer }) => {
3712
- const heatmapWidth = useHeatmapWidthByDevice();
3745
+ const viewport = useHeatmapViewportByDevice();
3713
3746
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
3714
3747
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
3715
3748
  const getRect = useCallback((element) => {
@@ -3737,17 +3770,17 @@ const useHeatmapElementPosition = ({ iframeRef, wrapperRef, visualizer }) => {
3737
3770
  const outOfBounds = adjustedTop < 0 ||
3738
3771
  adjustedTop > (iframeHeight || Infinity) ||
3739
3772
  layout.left < 0 ||
3740
- (typeof heatmapWidth === 'number' && layout.left > heatmapWidth);
3773
+ (typeof viewport.width === 'number' && layout.left > viewport.width);
3741
3774
  if (outOfBounds)
3742
3775
  return null;
3743
3776
  return {
3744
3777
  left: layout.left,
3745
3778
  top: adjustedTop,
3746
- width: Math.min(layout.width, heatmapWidth || layout.width),
3779
+ width: Math.min(layout.width, viewport.width || layout.width),
3747
3780
  height: layout.height,
3748
3781
  outOfBounds,
3749
3782
  };
3750
- }, [iframeRef, wrapperRef, visualizer, heatmapWidth, iframeHeight, widthScale]);
3783
+ }, [iframeRef, wrapperRef, visualizer, viewport, iframeHeight, widthScale]);
3751
3784
  return { getRect };
3752
3785
  };
3753
3786
 
@@ -4148,7 +4181,7 @@ function flush() {
4148
4181
  window.__gemxPerf = getReport();
4149
4182
  }
4150
4183
  // ── Global singleton export ───────────────────────────────────────────────────
4151
- const perf$1 = {
4184
+ const perf$2 = {
4152
4185
  startSession,
4153
4186
  endSession,
4154
4187
  mark: globalMark,
@@ -4941,7 +4974,7 @@ const YIELD_EVERY_RULES = 100;
4941
4974
  * Uses `scheduler.yield()` (Chrome 115+) when available; falls back to a
4942
4975
  * zero-timeout macrotask which is universally supported.
4943
4976
  */
4944
- function yieldToMain() {
4977
+ function yieldToMain$1() {
4945
4978
  if (typeof globalThis !== 'undefined' && 'scheduler' in globalThis) {
4946
4979
  return globalThis.scheduler.yield();
4947
4980
  }
@@ -5101,7 +5134,7 @@ async function processStylesheets(ctx) {
5101
5134
  rulesSinceYield++;
5102
5135
  if (rulesSinceYield >= YIELD_EVERY_RULES) {
5103
5136
  rulesSinceYield = 0;
5104
- await yieldToMain();
5137
+ await yieldToMain$1();
5105
5138
  }
5106
5139
  }
5107
5140
  }
@@ -5384,52 +5417,52 @@ function configure(debug) {
5384
5417
  }
5385
5418
  async function run$1(ctx, activeGlobal, shopFix) {
5386
5419
  // ── Phase 1: beforeProcess ────────────────────────────────────────────────
5387
- const t1 = perf$1.mark('phase1.beforeProcess');
5420
+ const t1 = perf$2.mark('phase1.beforeProcess');
5388
5421
  for (const fix of activeGlobal) {
5389
5422
  if (fix.beforeProcess) {
5390
5423
  logger.log(`[beforeProcess] ${fix.name}`);
5391
- const t = perf$1.mark(`phase1.${fix.name}.beforeProcess`);
5424
+ const t = perf$2.mark(`phase1.${fix.name}.beforeProcess`);
5392
5425
  await fix.beforeProcess(ctx);
5393
- perf$1.measure(`phase1.${fix.name}.beforeProcess`, t);
5426
+ perf$2.measure(`phase1.${fix.name}.beforeProcess`, t);
5394
5427
  }
5395
5428
  }
5396
5429
  if (shopFix?.beforeProcess) {
5397
5430
  logger.log('[beforeProcess] shop');
5398
- const t = perf$1.mark('phase1.shop.beforeProcess');
5431
+ const t = perf$2.mark('phase1.shop.beforeProcess');
5399
5432
  await shopFix.beforeProcess(ctx);
5400
- perf$1.measure('phase1.shop.beforeProcess', t);
5433
+ perf$2.measure('phase1.shop.beforeProcess', t);
5401
5434
  }
5402
- perf$1.measure('phase1.beforeProcess', t1);
5435
+ perf$2.measure('phase1.beforeProcess', t1);
5403
5436
  // ── Phase 2: process ──────────────────────────────────────────────────────
5404
- const t2 = perf$1.mark('phase2.process');
5437
+ const t2 = perf$2.mark('phase2.process');
5405
5438
  for (const fix of activeGlobal) {
5406
5439
  if (fix.process) {
5407
5440
  logger.log(`[process] ${fix.name}`);
5408
- const t = perf$1.mark(`phase2.${fix.name}.process`);
5441
+ const t = perf$2.mark(`phase2.${fix.name}.process`);
5409
5442
  await fix.process(ctx);
5410
- perf$1.measure(`phase2.${fix.name}.process`, t);
5443
+ perf$2.measure(`phase2.${fix.name}.process`, t);
5411
5444
  }
5412
5445
  }
5413
- perf$1.measure('phase2.process', t2);
5446
+ perf$2.measure('phase2.process', t2);
5414
5447
  // ── Phase 3: afterProcess ─────────────────────────────────────────────────
5415
- const t3 = perf$1.mark('phase3.afterProcess');
5448
+ const t3 = perf$2.mark('phase3.afterProcess');
5416
5449
  if (shopFix?.afterProcess) {
5417
5450
  logger.log('[afterProcess] shop');
5418
- const t = perf$1.mark('phase3.shop.afterProcess');
5451
+ const t = perf$2.mark('phase3.shop.afterProcess');
5419
5452
  await shopFix.afterProcess(ctx);
5420
- perf$1.measure('phase3.shop.afterProcess', t);
5453
+ perf$2.measure('phase3.shop.afterProcess', t);
5421
5454
  }
5422
5455
  for (const fix of activeGlobal) {
5423
5456
  if (fix.afterProcess) {
5424
5457
  logger.log(`[afterProcess] ${fix.name}`);
5425
- const t = perf$1.mark(`phase3.${fix.name}.afterProcess`);
5458
+ const t = perf$2.mark(`phase3.${fix.name}.afterProcess`);
5426
5459
  await fix.afterProcess(ctx);
5427
- perf$1.measure(`phase3.${fix.name}.afterProcess`, t);
5460
+ perf$2.measure(`phase3.${fix.name}.afterProcess`, t);
5428
5461
  }
5429
5462
  }
5430
- perf$1.measure('phase3.afterProcess', t3);
5463
+ perf$2.measure('phase3.afterProcess', t3);
5431
5464
  // ── Phase 4: getDimensions ────────────────────────────────────────────────
5432
- const t4 = perf$1.mark('phase4.getDimensions');
5465
+ const t4 = perf$2.mark('phase4.getDimensions');
5433
5466
  return new Promise((resolve) => {
5434
5467
  requestAnimationFrame(() => {
5435
5468
  let dimensions = null;
@@ -5454,7 +5487,7 @@ async function run$1(ctx, activeGlobal, shopFix) {
5454
5487
  dimensions = { height: getFinalHeight(ctx.doc, ctx.win), width: getFinalWidth(ctx.doc) };
5455
5488
  }
5456
5489
  logger.log('Final dimensions:', dimensions);
5457
- perf$1.measure('phase4.getDimensions', t4);
5490
+ perf$2.measure('phase4.getDimensions', t4);
5458
5491
  resolve(dimensions);
5459
5492
  });
5460
5493
  });
@@ -5582,14 +5615,14 @@ async function run(s) {
5582
5615
  const activeGlobal = getActiveFixes(ctx);
5583
5616
  if (activeGlobal.length > 0)
5584
5617
  s.logger.log(`Active global fixes: ${activeGlobal.map((f) => f.name).join(', ')}`);
5585
- const tRun = perf$1.mark('viewport.run');
5618
+ const tRun = perf$2.mark('viewport.run');
5586
5619
  try {
5587
5620
  const result = await run$1(ctx, activeGlobal, s.shopFix);
5588
- perf$1.measure('viewport.run', tRun);
5621
+ perf$2.measure('viewport.run', tRun);
5589
5622
  return result;
5590
5623
  }
5591
5624
  catch (err) {
5592
- perf$1.measure('viewport.run', tRun);
5625
+ perf$2.measure('viewport.run', tRun);
5593
5626
  s.logger.error('Critical error:', err);
5594
5627
  return { height: s.doc.body?.scrollHeight || 1000, width: s.doc.body?.scrollWidth || 1000 };
5595
5628
  }
@@ -5639,22 +5672,22 @@ async function process(s) {
5639
5672
  return;
5640
5673
  }
5641
5674
  const sessionId = `render-${Date.now()}`;
5642
- perf$1.startSession(sessionId);
5643
- const t0 = perf$1.mark('orchestrator.process');
5675
+ perf$2.startSession(sessionId);
5676
+ const t0 = perf$2.mark('orchestrator.process');
5644
5677
  try {
5645
5678
  s.logger.log('Processing viewport units...');
5646
5679
  s.viewportReplacer.start(s.iframe, s.config);
5647
5680
  s.navigationBlocker.start(s.iframe, { debug: s.config.debug });
5648
5681
  const result = await s.viewportReplacer.run();
5649
- perf$1.measure('orchestrator.process', t0);
5650
- perf$1.endSession();
5682
+ perf$2.measure('orchestrator.process', t0);
5683
+ perf$2.endSession();
5651
5684
  s.logger.log('Process completed:', result);
5652
5685
  s.config.onSuccess?.(result);
5653
5686
  dispatchDimensionsEvent(result);
5654
5687
  }
5655
5688
  catch (error) {
5656
- perf$1.measure('orchestrator.process', t0);
5657
- perf$1.endSession();
5689
+ perf$2.measure('orchestrator.process', t0);
5690
+ perf$2.endSession();
5658
5691
  s.logger.error('Failed to process:', error);
5659
5692
  s.config.onError?.(error);
5660
5693
  }
@@ -5805,13 +5838,13 @@ function useVizLiveRender() {
5805
5838
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
5806
5839
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
5807
5840
  const wrapperWidth = useHeatmapVizRectContext((s) => s.wrapperWidth);
5808
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
5841
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
5809
5842
  const htmlContent = useHeatmapLiveContext((s) => s.htmlContent);
5810
5843
  const targetUrl = useHeatmapLiveContext((s) => s.targetUrl);
5811
5844
  const deviceType = useHeatmapSettingContext((s) => s.deviceType);
5812
5845
  const renderMode = useHeatmapLiveContext((s) => s.renderMode);
5813
5846
  const storefrontPassword = useHeatmapLiveContext((s) => s.storefrontPassword);
5814
- useHeatmapWidthByDevice();
5847
+ useHeatmapViewportByDevice();
5815
5848
  const { iframeRef, isReady } = useVizLiveIframeMsg();
5816
5849
  // Handle iframe rendering based on mode
5817
5850
  useEffect(() => {
@@ -5851,10 +5884,10 @@ function useVizLiveRender() {
5851
5884
  const hasContent = (renderMode === 'portal' && targetUrl) || (renderMode === 'inline' && htmlContent);
5852
5885
  if (!iframe || !hasContent)
5853
5886
  return;
5854
- setIsRenderedViz(true);
5887
+ setIsDomLoaded(true);
5855
5888
  startIframe$1(iframe, deviceType, { width: wrapperWidth, height: wrapperHeight }, (height) => {
5856
5889
  height && setIframeHeight(height);
5857
- setIsRenderedViz(true);
5890
+ setIsDomLoaded(true);
5858
5891
  });
5859
5892
  return () => { };
5860
5893
  }, [
@@ -5866,7 +5899,7 @@ function useVizLiveRender() {
5866
5899
  targetUrl,
5867
5900
  htmlContent,
5868
5901
  iframeRef,
5869
- setIsRenderedViz,
5902
+ setIsDomLoaded,
5870
5903
  setIframeHeight,
5871
5904
  ]);
5872
5905
  return {
@@ -5901,6 +5934,109 @@ function startIframe$1(iframe, deviceType = EDeviceType.Desktop, rect, onSuccess
5901
5934
  iframeHelper.enableNavigationBlocking();
5902
5935
  }
5903
5936
 
5937
+ const DEFAULT_CONFIG = {
5938
+ dbName: 'gx-viz-html-cache',
5939
+ maxEntries: 20,
5940
+ ttlMs: 24 * 60 * 60 * 1000, // 24 hours
5941
+ cacheVersion: 3.0,
5942
+ };
5943
+ let _config = { ...DEFAULT_CONFIG };
5944
+ function getHtmlCacheConfig() {
5945
+ return _config;
5946
+ }
5947
+ /** Build a full cache key that includes the cache version to handle invalidation. */
5948
+ function buildCacheKey(baseKey, shortCircuitStrategy) {
5949
+ return `v${_config.cacheVersion}:${baseKey}:${shortCircuitStrategy}`;
5950
+ }
5951
+
5952
+ const STORE_NAME = 'entries';
5953
+ const IDB_SCHEMA_VERSION = 1;
5954
+ function openDb() {
5955
+ const { dbName } = getHtmlCacheConfig();
5956
+ return new Promise((resolve, reject) => {
5957
+ const req = indexedDB.open(dbName, IDB_SCHEMA_VERSION);
5958
+ req.onupgradeneeded = () => {
5959
+ const db = req.result;
5960
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
5961
+ const store = db.createObjectStore(STORE_NAME, { keyPath: 'key' });
5962
+ store.createIndex('timestamp', 'timestamp');
5963
+ }
5964
+ };
5965
+ req.onsuccess = () => resolve(req.result);
5966
+ req.onerror = () => reject(req.error);
5967
+ });
5968
+ }
5969
+ async function evict(db) {
5970
+ const { maxEntries } = getHtmlCacheConfig();
5971
+ return new Promise((resolve) => {
5972
+ const tx = db.transaction(STORE_NAME, 'readwrite');
5973
+ const store = tx.objectStore(STORE_NAME);
5974
+ const countReq = store.count();
5975
+ countReq.onsuccess = () => {
5976
+ if (countReq.result <= maxEntries) {
5977
+ resolve();
5978
+ return;
5979
+ }
5980
+ const idx = store.index('timestamp');
5981
+ const cursorReq = idx.openCursor();
5982
+ let toDelete = countReq.result - maxEntries;
5983
+ cursorReq.onsuccess = () => {
5984
+ const cursor = cursorReq.result;
5985
+ if (cursor && toDelete > 0) {
5986
+ cursor.delete();
5987
+ toDelete--;
5988
+ cursor.continue();
5989
+ }
5990
+ else {
5991
+ resolve();
5992
+ }
5993
+ };
5994
+ cursorReq.onerror = () => resolve();
5995
+ };
5996
+ countReq.onerror = () => resolve();
5997
+ });
5998
+ }
5999
+ const htmlCache = {
6000
+ async get(key) {
6001
+ try {
6002
+ const { ttlMs } = getHtmlCacheConfig();
6003
+ const db = await openDb();
6004
+ return new Promise((resolve) => {
6005
+ const tx = db.transaction(STORE_NAME, 'readonly');
6006
+ const req = tx.objectStore(STORE_NAME).get(key);
6007
+ req.onsuccess = () => {
6008
+ const entry = req.result;
6009
+ if (!entry || Date.now() - entry.timestamp > ttlMs) {
6010
+ resolve(null);
6011
+ }
6012
+ else {
6013
+ resolve(entry);
6014
+ }
6015
+ };
6016
+ req.onerror = () => resolve(null);
6017
+ });
6018
+ }
6019
+ catch {
6020
+ return null;
6021
+ }
6022
+ },
6023
+ async set(entry) {
6024
+ try {
6025
+ const db = await openDb();
6026
+ await new Promise((resolve, reject) => {
6027
+ const tx = db.transaction(STORE_NAME, 'readwrite');
6028
+ tx.objectStore(STORE_NAME).put(entry);
6029
+ tx.oncomplete = () => resolve();
6030
+ tx.onerror = () => reject(tx.error);
6031
+ });
6032
+ await evict(db);
6033
+ }
6034
+ catch {
6035
+ // ignore cache write errors
6036
+ }
6037
+ },
6038
+ };
6039
+
5904
6040
  const CANVAS_ID = 'clarity-heatmap-canvas';
5905
6041
  const ATTENTION_HUES = [240, 210, 180, 150, 120, 90, 60, 30, 0];
5906
6042
  const CANVAS_MAX_HEIGHT = 65535;
@@ -6109,6 +6245,250 @@ class AttentionMapRenderer {
6109
6245
  };
6110
6246
  }
6111
6247
 
6248
+ var Event;
6249
+ (function (Event) {
6250
+ /* Data */
6251
+ Event[Event["Metric"] = 0] = "Metric";
6252
+ Event[Event["Dimension"] = 1] = "Dimension";
6253
+ Event[Event["Upload"] = 2] = "Upload";
6254
+ Event[Event["Upgrade"] = 3] = "Upgrade";
6255
+ Event[Event["Baseline"] = 4] = "Baseline";
6256
+ Event[Event["Discover"] = 5] = "Discover";
6257
+ Event[Event["Mutation"] = 6] = "Mutation";
6258
+ Event[Event["Region"] = 7] = "Region";
6259
+ Event[Event["Document"] = 8] = "Document";
6260
+ Event[Event["Click"] = 9] = "Click";
6261
+ Event[Event["Scroll"] = 10] = "Scroll";
6262
+ Event[Event["Resize"] = 11] = "Resize";
6263
+ Event[Event["MouseMove"] = 12] = "MouseMove";
6264
+ Event[Event["MouseDown"] = 13] = "MouseDown";
6265
+ Event[Event["MouseUp"] = 14] = "MouseUp";
6266
+ Event[Event["MouseWheel"] = 15] = "MouseWheel";
6267
+ Event[Event["DoubleClick"] = 16] = "DoubleClick";
6268
+ Event[Event["TouchStart"] = 17] = "TouchStart";
6269
+ Event[Event["TouchEnd"] = 18] = "TouchEnd";
6270
+ Event[Event["TouchMove"] = 19] = "TouchMove";
6271
+ Event[Event["TouchCancel"] = 20] = "TouchCancel";
6272
+ Event[Event["Selection"] = 21] = "Selection";
6273
+ Event[Event["Timeline"] = 22] = "Timeline";
6274
+ Event[Event["Page"] = 23] = "Page";
6275
+ Event[Event["Custom"] = 24] = "Custom";
6276
+ Event[Event["Ping"] = 25] = "Ping";
6277
+ Event[Event["Unload"] = 26] = "Unload";
6278
+ Event[Event["Input"] = 27] = "Input";
6279
+ Event[Event["Visibility"] = 28] = "Visibility";
6280
+ Event[Event["Navigation"] = 29] = "Navigation";
6281
+ /**
6282
+ * @deprecated No longer support Network Connection
6283
+ */
6284
+ Event[Event["Connection"] = 30] = "Connection";
6285
+ Event[Event["ScriptError"] = 31] = "ScriptError";
6286
+ /**
6287
+ * @deprecated No longer support Image Error
6288
+ */
6289
+ Event[Event["ImageError"] = 32] = "ImageError";
6290
+ Event[Event["Log"] = 33] = "Log";
6291
+ Event[Event["Variable"] = 34] = "Variable";
6292
+ Event[Event["Limit"] = 35] = "Limit";
6293
+ Event[Event["Summary"] = 36] = "Summary";
6294
+ /**
6295
+ * @deprecated No longer support Box event
6296
+ */
6297
+ Event[Event["Box"] = 37] = "Box";
6298
+ Event[Event["Clipboard"] = 38] = "Clipboard";
6299
+ Event[Event["Submit"] = 39] = "Submit";
6300
+ Event[Event["Extract"] = 40] = "Extract";
6301
+ Event[Event["Fraud"] = 41] = "Fraud";
6302
+ Event[Event["Change"] = 42] = "Change";
6303
+ Event[Event["Snapshot"] = 43] = "Snapshot";
6304
+ Event[Event["Animation"] = 44] = "Animation";
6305
+ Event[Event["StyleSheetAdoption"] = 45] = "StyleSheetAdoption";
6306
+ Event[Event["StyleSheetUpdate"] = 46] = "StyleSheetUpdate";
6307
+ Event[Event["Consent"] = 47] = "Consent";
6308
+ Event[Event["ContextMenu"] = 48] = "ContextMenu";
6309
+ // 49 is reserved for internal use
6310
+ Event[Event["Focus"] = 50] = "Focus";
6311
+ Event[Event["CustomElement"] = 51] = "CustomElement";
6312
+ Event[Event["Chat"] = 52] = "Chat";
6313
+ // Apps specific events
6314
+ Event[Event["WebViewDiscover"] = 100] = "WebViewDiscover";
6315
+ Event[Event["WebViewMutation"] = 101] = "WebViewMutation";
6316
+ Event[Event["MutationError"] = 102] = "MutationError";
6317
+ Event[Event["FragmentVisibility"] = 103] = "FragmentVisibility";
6318
+ Event[Event["Keystrokes"] = 104] = "Keystrokes";
6319
+ Event[Event["BackGesture"] = 105] = "BackGesture";
6320
+ Event[Event["WebViewStatus"] = 106] = "WebViewStatus";
6321
+ Event[Event["AppInstallReferrer"] = 107] = "AppInstallReferrer";
6322
+ // 200-300 reserved for internal use
6323
+ })(Event || (Event = {}));
6324
+
6325
+ var Constant;
6326
+ (function (Constant) {
6327
+ Constant["Empty"] = "";
6328
+ Constant["SvgPrefix"] = "svg:";
6329
+ Constant["DataPrefix"] = "data:";
6330
+ Constant["IFramePrefix"] = "iframe:";
6331
+ Constant["SvgNamespace"] = "http://www.w3.org/2000/svg";
6332
+ Constant["Id"] = "id";
6333
+ Constant["Class"] = "class";
6334
+ Constant["Style"] = "style";
6335
+ Constant["Href"] = "href";
6336
+ Constant["Src"] = "src";
6337
+ Constant["Srcset"] = "srcset";
6338
+ Constant["Hash"] = "#";
6339
+ Constant["Dot"] = ".";
6340
+ Constant["Separator"] = ">";
6341
+ Constant["Tilde"] = "~";
6342
+ Constant["Bang"] = "!";
6343
+ Constant["Period"] = ".";
6344
+ Constant["Comma"] = ",";
6345
+ Constant["DataAttribute"] = "data-";
6346
+ Constant["MaskData"] = "data-clarity-mask";
6347
+ Constant["UnmaskData"] = "data-clarity-unmask";
6348
+ Constant["RegionData"] = "data-clarity-region";
6349
+ Constant["GXDialogModal"] = "gx-dialog-modal";
6350
+ Constant["Type"] = "type";
6351
+ Constant["Submit"] = "submit";
6352
+ Constant["Name"] = "name";
6353
+ Constant["Base"] = "*B";
6354
+ Constant["SameOrigin"] = "*O";
6355
+ Constant["Object"] = "object";
6356
+ Constant["Function"] = "function";
6357
+ Constant["StyleTag"] = "STYLE";
6358
+ Constant["LinkTag"] = "LINK";
6359
+ Constant["InputTag"] = "INPUT";
6360
+ Constant["IFrameTag"] = "IFRAME";
6361
+ Constant["ImageTag"] = "IMG";
6362
+ Constant["TitleTag"] = "TITLE";
6363
+ Constant["BodyTag"] = "BODY";
6364
+ Constant["SvgTag"] = "svg:svg";
6365
+ Constant["BaseTag"] = "BASE";
6366
+ Constant["NativeCode"] = "[native code]";
6367
+ Constant["DocumentTag"] = "*D";
6368
+ Constant["ShadowDomTag"] = "*S";
6369
+ Constant["PolyfillShadowDomTag"] = "*P";
6370
+ Constant["TextTag"] = "*T";
6371
+ Constant["SuspendMutationTag"] = "*M";
6372
+ Constant["ChildList"] = "childList";
6373
+ Constant["Attributes"] = "attributes";
6374
+ Constant["CharacterData"] = "characterData";
6375
+ Constant["Throttle"] = "throttle";
6376
+ Constant["LoadEvent"] = "load";
6377
+ Constant["Pixel"] = "px";
6378
+ Constant["BorderBox"] = "border-box";
6379
+ Constant["Value"] = "value";
6380
+ Constant["MutationObserver"] = "MutationObserver";
6381
+ Constant["JsonLD"] = "application/ld+json";
6382
+ Constant["String"] = "string";
6383
+ Constant["Number"] = "number";
6384
+ Constant["Disable"] = "disable";
6385
+ Constant["HTML"] = "HTML";
6386
+ Constant["Property"] = "property";
6387
+ Constant["Content"] = "content";
6388
+ Constant["Generator"] = "generator";
6389
+ Constant["ogType"] = "og:type";
6390
+ Constant["ogTitle"] = "og:title";
6391
+ Constant["SvgStyle"] = "svg:style";
6392
+ Constant["StyleSheet"] = "stylesheet";
6393
+ })(Constant || (Constant = {}));
6394
+
6395
+ var ShortCircuitStrategy;
6396
+ (function (ShortCircuitStrategy) {
6397
+ ShortCircuitStrategy[ShortCircuitStrategy["None"] = 0] = "None";
6398
+ ShortCircuitStrategy[ShortCircuitStrategy["HashFirstTimestamp"] = 1] = "HashFirstTimestamp";
6399
+ ShortCircuitStrategy[ShortCircuitStrategy["HashFirstTimestampPlusBuffer"] = 2] = "HashFirstTimestampPlusBuffer";
6400
+ ShortCircuitStrategy[ShortCircuitStrategy["HashBeforeDeleted"] = 3] = "HashBeforeDeleted";
6401
+ })(ShortCircuitStrategy || (ShortCircuitStrategy = {}));
6402
+
6403
+ function isShadowDomNode(tag) {
6404
+ return tag === Constant.ShadowDomTag || tag === Constant.PolyfillShadowDomTag;
6405
+ }
6406
+ /** Scan the rendered DOM (including nested shadow roots) to collect tag names of shadow host elements. */
6407
+ function collectShadowHostTags(root, tags = new Set()) {
6408
+ root.querySelectorAll('*').forEach((el) => {
6409
+ if (el.shadowRoot) {
6410
+ tags.add(el.tagName);
6411
+ collectShadowHostTags(el.shadowRoot, tags);
6412
+ }
6413
+ });
6414
+ return tags;
6415
+ }
6416
+ /** Build a shadow subtree ID set from all DOM events.
6417
+ * Two-pass cascade to handle any event ordering:
6418
+ * Pass 1 — seed *S/*P node IDs.
6419
+ * Pass 2 — cascade: any node whose parent is in the set is also in the set (repeat until stable). */
6420
+ function buildShadowSubtreeIds(allDomEvents) {
6421
+ const subtreeIds = new Set();
6422
+ for (const e of allDomEvents) {
6423
+ const data = e.data;
6424
+ for (const node of data ?? []) {
6425
+ if (isShadowDomNode(node.tag))
6426
+ subtreeIds.add(node.id);
6427
+ }
6428
+ }
6429
+ let changed = true;
6430
+ while (changed) {
6431
+ changed = false;
6432
+ for (const e of allDomEvents) {
6433
+ const data = e.data;
6434
+ for (const node of data ?? []) {
6435
+ if (!subtreeIds.has(node.id) && subtreeIds.has(node.parent)) {
6436
+ subtreeIds.add(node.id);
6437
+ changed = true;
6438
+ }
6439
+ }
6440
+ }
6441
+ }
6442
+ return subtreeIds;
6443
+ }
6444
+ function filterShadowNodes(data, subtreeIds, shadowHostTags) {
6445
+ return (data?.filter((node) => {
6446
+ if (isShadowDomNode(node.tag))
6447
+ return true;
6448
+ if (shadowHostTags.has(node.tag ?? '') && subtreeIds.has(node.parent))
6449
+ return true;
6450
+ return subtreeIds.has(node.id);
6451
+ }) ?? []);
6452
+ }
6453
+ /** Extract shadow DOM nodes from merged.dom (initial Discover event, processed by setup()).
6454
+ * Returns a filtered copy of the dom event, or null if no shadow DOM present. */
6455
+ function extractSpecialDom(dom, events, shadowHostTags) {
6456
+ const mutationEvents = events.filter((e) => e.event === Event.Mutation);
6457
+ const subtreeIds = buildShadowSubtreeIds([dom, ...mutationEvents]);
6458
+ const shadowNodes = filterShadowNodes(dom.data, subtreeIds, shadowHostTags);
6459
+ return shadowNodes.length ? { ...dom, data: shadowNodes } : null;
6460
+ }
6461
+ /** Extract shadow DOM mutations + StyleSheet + CustomElement events from merged.events. */
6462
+ function extractSpecialEvents(events, dom, shadowHostTags) {
6463
+ const mutationEvents = events.filter((e) => e.event === Event.Mutation);
6464
+ const subtreeIds = buildShadowSubtreeIds([dom, ...mutationEvents]);
6465
+ const result = [];
6466
+ for (const e of events) {
6467
+ const ev = e.event;
6468
+ if (ev === Event.StyleSheetAdoption ||
6469
+ ev === Event.StyleSheetUpdate ||
6470
+ ev === Event.CustomElement) {
6471
+ result.push(e);
6472
+ continue;
6473
+ }
6474
+ if (ev === Event.Mutation) {
6475
+ const shadowNodes = filterShadowNodes(e.data, subtreeIds, shadowHostTags);
6476
+ if (shadowNodes.length)
6477
+ result.push({ ...e, data: shadowNodes });
6478
+ }
6479
+ }
6480
+ return result;
6481
+ }
6482
+
6483
+ const YIELD_INTERVAL_MS = 16;
6484
+ async function yieldToMain() {
6485
+ if ('scheduler' in globalThis && typeof globalThis.scheduler?.yield === 'function') {
6486
+ await globalThis.scheduler.yield();
6487
+ }
6488
+ else {
6489
+ await new Promise((resolve) => setTimeout(resolve, 0));
6490
+ }
6491
+ }
6112
6492
  class GXVisualizer extends Visualizer {
6113
6493
  attentionMap;
6114
6494
  originalClearmap;
@@ -6120,6 +6500,7 @@ class GXVisualizer extends Visualizer {
6120
6500
  this.originalClearmap = this.clearmap;
6121
6501
  this.clearmap = this.clearmapOverride;
6122
6502
  this.setup = this.setupOverride;
6503
+ this.html = this.htmlOverride;
6123
6504
  }
6124
6505
  setupOverride = async (target, options) => {
6125
6506
  this.attentionMap?.clear();
@@ -6131,6 +6512,99 @@ class GXVisualizer extends Visualizer {
6131
6512
  this.originalClearmap();
6132
6513
  this.attentionMap?.clear();
6133
6514
  };
6515
+ renderLoop = async (v, events, hash, useproxy, shortCircuitStrategy) => {
6516
+ let lastYield = performance.now();
6517
+ for (let i = 0; i < events.length; i++) {
6518
+ const now = performance.now();
6519
+ if (now - lastYield > YIELD_INTERVAL_MS) {
6520
+ await yieldToMain();
6521
+ lastYield = performance.now();
6522
+ }
6523
+ const entry = events[i];
6524
+ const entryEvent = entry.event;
6525
+ switch (entryEvent) {
6526
+ case Event.StyleSheetAdoption:
6527
+ case Event.StyleSheetUpdate:
6528
+ v.layout.styleChange(entry);
6529
+ break;
6530
+ case Event.CustomElement:
6531
+ v.layout.customElement(entry);
6532
+ break;
6533
+ case Event.Mutation: {
6534
+ const domEvent = entry;
6535
+ this.renderTime = domEvent.time;
6536
+ if (v.shortCircuitRendering(shortCircuitStrategy, domEvent, hash))
6537
+ return;
6538
+ v.layout.markup(domEvent, useproxy);
6539
+ break;
6540
+ }
6541
+ }
6542
+ }
6543
+ };
6544
+ htmlOverride = async (decoded, target, portalCanvasId, hash = '', useproxy, logerror, shortCircuitStrategy = ShortCircuitStrategy.None) => {
6545
+ if (decoded && decoded.length > 0 && target) {
6546
+ try {
6547
+ const v = this;
6548
+ const merged = v.mergeForHtml(decoded);
6549
+ await this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy, portalCanvasId });
6550
+ await this.renderLoop(v, merged.events, hash, useproxy, shortCircuitStrategy);
6551
+ }
6552
+ catch (e) {
6553
+ if (logerror)
6554
+ logerror(e);
6555
+ }
6556
+ }
6557
+ return this;
6558
+ };
6559
+ htmlCached = async (cacheKey, decoded, target, portalCanvasId, hash = '', useproxy, logerror, shortCircuitStrategy = 0) => {
6560
+ if (!decoded || decoded.length === 0 || !target)
6561
+ return this;
6562
+ const fullKey = buildCacheKey(cacheKey, shortCircuitStrategy);
6563
+ const cached = await htmlCache.get(fullKey);
6564
+ if (cached) {
6565
+ try {
6566
+ const v = this;
6567
+ await this.setup(target, { version: cached.version, useproxy, portalCanvasId });
6568
+ target.document.open();
6569
+ target.document.write(cached.html);
6570
+ target.document.close();
6571
+ v.layout.hydrate(target.document);
6572
+ // Replay shadow DOM from initial Discover event (was processed by setup() in full render)
6573
+ if (cached.specialDom) {
6574
+ v.layout.markup(cached.specialDom, useproxy);
6575
+ }
6576
+ // Replay shadow DOM mutations + StyleSheet + CustomElement
6577
+ await this.renderLoop(v, cached.specialEvents, '', useproxy, 0);
6578
+ return this;
6579
+ }
6580
+ catch (e) {
6581
+ if (logerror)
6582
+ logerror(e);
6583
+ }
6584
+ }
6585
+ try {
6586
+ const v = this;
6587
+ const merged = v.mergeForHtml(decoded);
6588
+ await this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy, portalCanvasId });
6589
+ await this.renderLoop(v, merged.events, hash, useproxy, shortCircuitStrategy);
6590
+ const shadowHostTags = collectShadowHostTags(target.document);
6591
+ const specialDom = extractSpecialDom(merged.dom, merged.events, shadowHostTags);
6592
+ const specialEvents = extractSpecialEvents(merged.events, merged.dom, shadowHostTags);
6593
+ void htmlCache.set({
6594
+ key: fullKey,
6595
+ html: target.document.documentElement.outerHTML,
6596
+ specialDom: specialDom,
6597
+ specialEvents,
6598
+ version: decoded[0].envelope.version,
6599
+ timestamp: Date.now(),
6600
+ });
6601
+ }
6602
+ catch (e) {
6603
+ if (logerror)
6604
+ logerror(e);
6605
+ }
6606
+ return this;
6607
+ };
6134
6608
  /**
6135
6609
  * Render attention/engagement map.
6136
6610
  * @param attentionData - Array of attention data points with start/end element hashes and time spent
@@ -6143,93 +6617,72 @@ class GXVisualizer extends Visualizer {
6143
6617
  };
6144
6618
  }
6145
6619
 
6146
- const perf = createPerfTimer('Render');
6147
- const useHeatmapRender = () => {
6148
- const viewId = useViewIdContext();
6149
- const data = useHeatmapDataContext((s) => s.data);
6620
+ const perf$1 = createPerfTimer('Render');
6621
+ const useHeatmapIframeProcessor = () => {
6150
6622
  const shopId = useHeatmapConfigStore((s) => s.shopId);
6151
- const excludeClassNames = useHeatmapConfigStore((s) => s.excludeClassNames);
6152
- const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
6153
- const setVizRef = useHeatmapVizRectContext((s) => s.setVizRef);
6154
- const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6155
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
6156
- const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
6157
- const contentWidth = useHeatmapWidthByDevice();
6158
6623
  const deviceType = useHeatmapSettingContext((s) => s.deviceType);
6159
- const iframeRef = useRef(null);
6624
+ const viewport = useHeatmapViewportByDevice();
6625
+ const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6626
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
6160
6627
  const helperRef = useRef(null);
6161
- const abortRef = useRef(null);
6162
- const pendingDataRef = useRef(null);
6163
- const wrapperHeightRef = useRef(wrapperHeight);
6164
- wrapperHeightRef.current = wrapperHeight;
6165
- const contentWidthRef = useRef(contentWidth);
6166
- contentWidthRef.current = contentWidth;
6167
- const renderHeatmap = useCallback(async (payloads) => {
6168
- if (contentWidthRef.current === 0 || wrapperHeightRef.current === 0) {
6169
- pendingDataRef.current = payloads;
6628
+ const pendingRef = useRef(null);
6629
+ const reset = useCallback(() => {
6630
+ pendingRef.current = null;
6631
+ }, []);
6632
+ const run = useCallback((iframe, t0, abort) => {
6633
+ if (viewport.width === 0 || viewport.height === 0) {
6634
+ pendingRef.current = { iframe, t0, abort };
6170
6635
  return;
6171
6636
  }
6172
- pendingDataRef.current = null;
6173
- if (!payloads || payloads.length === 0)
6174
- return;
6175
- const iframe = iframeRef.current;
6176
- if (!iframe?.contentWindow)
6177
- return;
6178
- abortRef.current?.abort();
6179
- const abort = new AbortController();
6180
- abortRef.current = abort;
6181
- const t0 = perf.mark('renderHeatmap start');
6182
- const visualizer = vizRef ?? new GXVisualizer();
6183
- if (!vizRef)
6184
- setVizRef(visualizer);
6185
- visualizer.configure({ excludeClassNames });
6186
- setIsRenderedViz(false);
6187
- await perf.wrap('visualizer.html', () => visualizer.html(payloads, iframe.contentWindow, viewId));
6188
- if (abort.signal.aborted)
6189
- return;
6190
- const size = { width: contentWidthRef.current, height: wrapperHeightRef.current };
6191
6637
  startIframe({
6192
6638
  helperRef,
6193
6639
  iframe,
6194
6640
  shopId,
6195
6641
  deviceType,
6196
- size,
6642
+ size: viewport,
6197
6643
  t0,
6198
6644
  onSuccess: (height) => {
6199
6645
  if (abort.signal.aborted)
6200
6646
  return;
6201
6647
  if (height)
6202
6648
  setIframeHeight(height);
6203
- setIsRenderedViz(true);
6649
+ setIsDomLoaded(true);
6204
6650
  },
6205
6651
  });
6206
6652
  }, [deviceType]);
6653
+ // Retry when dims become available
6207
6654
  useEffect(() => {
6208
- if (!data || data.length === 0)
6655
+ if (viewport.width === 0 || viewport.height === 0)
6209
6656
  return;
6210
- const decoded = decodeArrayClarity(data);
6211
- renderHeatmap(decoded);
6212
- return () => { };
6213
- }, [data, renderHeatmap]);
6214
- // Retry pending render when dimensions become available
6215
- useEffect(() => {
6216
- if (contentWidth === 0 || wrapperHeight === 0)
6657
+ if (!pendingRef.current)
6217
6658
  return;
6218
- if (!pendingDataRef.current)
6659
+ const { iframe, t0, abort } = pendingRef.current;
6660
+ pendingRef.current = null;
6661
+ if (abort.signal.aborted)
6219
6662
  return;
6220
- const pending = pendingDataRef.current;
6221
- pendingDataRef.current = null;
6222
- renderHeatmap(pending);
6223
- }, [contentWidth, wrapperHeight, renderHeatmap]);
6663
+ startIframe({
6664
+ helperRef,
6665
+ iframe,
6666
+ shopId,
6667
+ deviceType,
6668
+ size: viewport,
6669
+ t0,
6670
+ onSuccess: (height) => {
6671
+ if (abort.signal.aborted)
6672
+ return;
6673
+ if (height)
6674
+ setIframeHeight(height);
6675
+ setIsDomLoaded(true);
6676
+ },
6677
+ });
6678
+ }, [viewport]); // eslint-disable-line react-hooks/exhaustive-deps
6224
6679
  useEffect(() => {
6225
6680
  return () => {
6226
- setVizRef(null);
6227
- abortRef.current?.abort();
6228
6681
  helperRef.current?.stop();
6229
6682
  helperRef.current = null;
6230
6683
  };
6231
- }, [setVizRef]);
6232
- return { iframeRef };
6684
+ }, []);
6685
+ return { run, reset };
6233
6686
  };
6234
6687
  // ── Helpers ───────────────────────────────────────────────────────────────────
6235
6688
  function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Desktop, size, t0, onSuccess, }) {
@@ -6238,7 +6691,7 @@ function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Deskt
6238
6691
  if (docHeight === 0)
6239
6692
  return;
6240
6693
  helperRef.current?.stop();
6241
- const tHelper = perf.mark('IframeHelper.start');
6694
+ const tHelper = perf$1.mark('IframeHelper.start');
6242
6695
  const helper = createIframeHelper();
6243
6696
  helperRef.current = helper;
6244
6697
  helper.start({
@@ -6249,17 +6702,88 @@ function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Deskt
6249
6702
  debug: true,
6250
6703
  shopId,
6251
6704
  onSuccess: (data) => {
6252
- perf.measure('IframeHelper processing', tHelper);
6253
- perf.measure('Total render', t0);
6705
+ perf$1.measure('IframeHelper processing', tHelper);
6706
+ perf$1.measure('Total render', t0);
6254
6707
  iframe.style.height = `${data.height}px`;
6255
6708
  onSuccess(data.height);
6256
6709
  },
6257
6710
  });
6258
6711
  }
6259
6712
 
6713
+ const EShortCircuitStrategy = {
6714
+ None: 0,
6715
+ HashFirstTimestamp: 1,
6716
+ HashFirstTimestampPlusBuffer: 2,
6717
+ HashBeforeDeleted: 3,
6718
+ };
6719
+ const perf = createPerfTimer('Render');
6720
+ const useHeatmapRenderDom = () => {
6721
+ const viewId = useViewIdContext();
6722
+ const data = useHeatmapDataContext((s) => s.data);
6723
+ const excludeClassNames = useHeatmapConfigStore((s) => s.excludeClassNames);
6724
+ const setVizRef = useHeatmapVizRectContext((s) => s.setVizRef);
6725
+ const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
6726
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
6727
+ const deviceType = useHeatmapSettingContext((s) => s.deviceType);
6728
+ const heatmapType = useHeatmapSettingContext((s) => s.heatmapType);
6729
+ const elementToShow = useHeatmapDataContext((s) => s.dataInfo?.elementToShow);
6730
+ const dataHash = useHeatmapDataContext((s) => s.dataHash);
6731
+ const iframeRef = useRef(null);
6732
+ const abortRef = useRef(null);
6733
+ const elementToShowRef = useRef(null);
6734
+ const dataHashRef = useRef(null);
6735
+ const heatmapTypeRef = useRef(heatmapType);
6736
+ elementToShowRef.current = elementToShow ?? null;
6737
+ dataHashRef.current = dataHash ?? null;
6738
+ heatmapTypeRef.current = heatmapType;
6739
+ const { run: runIframeSetup, reset: resetIframeSetup } = useHeatmapIframeProcessor();
6740
+ const renderHeatmap = useCallback(async (payloads) => {
6741
+ if (!payloads || payloads.length === 0)
6742
+ return;
6743
+ const iframe = iframeRef.current;
6744
+ const contentWindow = iframe?.contentWindow;
6745
+ if (!contentWindow)
6746
+ return;
6747
+ abortRef.current?.abort();
6748
+ const abort = new AbortController();
6749
+ abortRef.current = abort;
6750
+ resetIframeSetup();
6751
+ const t0 = perf.mark('renderHeatmap start');
6752
+ const visualizer = vizRef ?? new GXVisualizer();
6753
+ if (!vizRef)
6754
+ setVizRef(visualizer);
6755
+ visualizer.configure({ excludeClassNames });
6756
+ setIsDomLoaded(false);
6757
+ // Phase 1: render DOM — does not depend on contentWidth/wrapperHeight
6758
+ const hash = elementToShowRef.current ?? undefined;
6759
+ const cacheKey = dataHashRef.current;
6760
+ const strategy = hash ? EShortCircuitStrategy.HashFirstTimestampPlusBuffer : EShortCircuitStrategy.None;
6761
+ await perf.wrap('visualizer.html', () => cacheKey
6762
+ ? visualizer.htmlCached(cacheKey, payloads, contentWindow, viewId, hash, undefined, undefined, strategy)
6763
+ : visualizer.html(payloads, contentWindow, viewId, hash, undefined, undefined, strategy));
6764
+ if (abort.signal.aborted)
6765
+ return;
6766
+ // Phase 2: iframe setup — deferred to useIframeSetup (handles dims dependency)
6767
+ runIframeSetup(iframe, t0, abort);
6768
+ }, [deviceType]);
6769
+ useEffect(() => {
6770
+ if (!data || data.length === 0)
6771
+ return;
6772
+ renderHeatmap(decodeArrayClarity(data));
6773
+ }, [data, renderHeatmap]);
6774
+ useEffect(() => {
6775
+ return () => {
6776
+ iframeRef.current = null;
6777
+ setVizRef(null);
6778
+ // abortRef.current?.abort(); // cancel Phase 2 callbacks
6779
+ };
6780
+ }, [setVizRef]);
6781
+ return { iframeRef };
6782
+ };
6783
+
6260
6784
  const useReplayRender = () => {
6261
6785
  const data = useHeatmapDataContext((s) => s.data);
6262
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
6786
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
6263
6787
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6264
6788
  const visualizerRef = useRef(null);
6265
6789
  const iframeRef = useRef(null);
@@ -6279,7 +6803,7 @@ const useReplayRender = () => {
6279
6803
  version: envelope.version,
6280
6804
  onresize: (height) => {
6281
6805
  height && setIframeHeight(height);
6282
- setIsRenderedViz(true);
6806
+ setIsDomLoaded(true);
6283
6807
  },
6284
6808
  mobile,
6285
6809
  vNext: true,
@@ -6382,10 +6906,12 @@ const useReplayRender = () => {
6382
6906
  const useHeatmapRenderByMode = (mode) => {
6383
6907
  const heatmapResult = useMemo(() => {
6384
6908
  switch (mode) {
6385
- case 'heatmap':
6386
- return useHeatmapRender;
6387
- case 'replay':
6909
+ case EHeatmapMode.Heatmap:
6910
+ return useHeatmapRenderDom;
6911
+ case EHeatmapMode.Replay:
6388
6912
  return useReplayRender;
6913
+ default:
6914
+ return useHeatmapRenderDom;
6389
6915
  }
6390
6916
  }, [mode]);
6391
6917
  return heatmapResult();
@@ -6420,22 +6946,10 @@ const useContainerDimensions = (props) => {
6420
6946
  return { containerWidth, containerHeight };
6421
6947
  };
6422
6948
 
6423
- const useContentDimensions = ({ iframeRef }) => {
6424
- const contentWidth = useHeatmapWidthByDevice();
6425
- useEffect(() => {
6426
- if (!contentWidth)
6427
- return;
6428
- if (!iframeRef.current)
6429
- return;
6430
- // iframeRef.current.width = `${contentWidth}px`;
6431
- }, [contentWidth, iframeRef]);
6432
- return { contentWidth };
6433
- };
6434
-
6435
6949
  const useObserveIframeHeight = (props) => {
6436
6950
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
6437
6951
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6438
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
6952
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
6439
6953
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
6440
6954
  const { iframeRef } = props;
6441
6955
  const resizeObserverRef = useRef(null);
@@ -6496,7 +7010,7 @@ const useObserveIframeHeight = (props) => {
6496
7010
  }, [updateIframeHeight]);
6497
7011
  useEffect(() => {
6498
7012
  const iframe = iframeRef.current;
6499
- if (!iframe || !iframeHeight || !isRenderedViz)
7013
+ if (!iframe || !iframeHeight || !isDomLoaded)
6500
7014
  return;
6501
7015
  const setupObservers = () => {
6502
7016
  try {
@@ -6558,7 +7072,7 @@ const useObserveIframeHeight = (props) => {
6558
7072
  }
6559
7073
  iframe.removeEventListener('load', setupObservers);
6560
7074
  };
6561
- }, [iframeRef, iframeHeight, isRenderedViz]);
7075
+ }, [iframeRef, iframeHeight, isDomLoaded]);
6562
7076
  return {};
6563
7077
  };
6564
7078
 
@@ -6571,9 +7085,10 @@ const useScaleCalculation = (props) => {
6571
7085
  const setScale = useHeatmapVizContext((s) => s.setScale);
6572
7086
  const setIsScaledToFit = useHeatmapVizContext((s) => s.setIsScaledToFit);
6573
7087
  const setMinZoomRatio = useHeatmapVizContext((s) => s.setMinZoomRatio);
6574
- const { containerWidth, containerHeight, contentWidth, contentHeight } = props;
7088
+ const viewport = useHeatmapViewportByDevice();
7089
+ const { containerWidth, containerHeight, iframeHeight } = props;
6575
7090
  const calculateScaleResult = useCallback(() => {
6576
- if (containerWidth > 0 && contentWidth > 0 && containerHeight > 0 && contentHeight > 0) {
7091
+ if (containerWidth > 0 && viewport.width > 0 && containerHeight > 0 && iframeHeight > 0) {
6577
7092
  // 1. Calculate available dimensions
6578
7093
  const availableWidth = containerWidth - HEATMAP_CONFIG['padding'] * 2;
6579
7094
  const toolbarHeight = HEATMAP_CONFIG['heightToolbar'] || 0;
@@ -6581,12 +7096,12 @@ const useScaleCalculation = (props) => {
6581
7096
  const availableHeight = containerHeight - toolbarHeight - paddingTotal;
6582
7097
  // 2. Calculate widthScale (base scale to fit content width into container width)
6583
7098
  // This represents 100% zoom (fit to width)
6584
- const widthScale = Math.min(availableWidth / contentWidth, 1);
7099
+ const widthScale = Math.min(availableWidth / viewport.width, 1);
6585
7100
  // 3. Calculate minZoomRatio (zoom ratio to fit height)
6586
7101
  // At minZoomRatio, the content should fit entirely within the container height
6587
- // Formula: contentHeight * widthScale * (minZoomRatio / 100) = availableHeight
6588
- // => minZoomRatio = (availableHeight / (contentHeight * widthScale)) * 100
6589
- const calculatedMinZoomRatio = (availableHeight / (contentHeight * widthScale)) * 100;
7102
+ // Formula: iframeHeight * widthScale * (minZoomRatio / 100) = availableHeight
7103
+ // => minZoomRatio = (availableHeight / (iframeHeight * widthScale)) * 100
7104
+ const calculatedMinZoomRatio = (availableHeight / (iframeHeight * widthScale)) * 100;
6590
7105
  // Limit minZoomRatio: cannot exceed MAX_ZOOM_RATIO (100%)
6591
7106
  // and should have a reasonable minimum (e.g., 1%)
6592
7107
  const finalMinZoomRatio = Math.max(1, Math.min(calculatedMinZoomRatio, maxZoomRatio));
@@ -6605,7 +7120,7 @@ const useScaleCalculation = (props) => {
6605
7120
  setIsScaledToFit(isCurrentlyFitted);
6606
7121
  setMinZoomRatio(finalMinZoomRatio);
6607
7122
  }
6608
- }, [containerWidth, containerHeight, contentWidth, contentHeight, zoomRatio, maxZoomRatio]);
7123
+ }, [containerWidth, containerHeight, viewport.width, iframeHeight, zoomRatio, maxZoomRatio]);
6609
7124
  useEffect(() => {
6610
7125
  calculateScaleResult();
6611
7126
  }, [calculateScaleResult]);
@@ -6638,20 +7153,15 @@ const useHeatmapScale = (props) => {
6638
7153
  // 1. Observe container dimensions
6639
7154
  const { containerWidth, containerHeight } = useContainerDimensions({ wrapperRef });
6640
7155
  // 2. Get content dimensions from config
6641
- const { contentWidth } = useContentDimensions({ iframeRef });
7156
+ const viewport = useHeatmapViewportByDevice();
6642
7157
  // 3. Observe iframe height (now reacts to width changes)
6643
7158
  useObserveIframeHeight({ iframeRef });
6644
7159
  // 4. Calculate scale
6645
- const { widthScale } = useScaleCalculation({
6646
- containerWidth,
6647
- containerHeight,
6648
- contentWidth,
6649
- contentHeight: iframeHeight,
6650
- });
7160
+ const { widthScale } = useScaleCalculation({ containerWidth, containerHeight, iframeHeight });
6651
7161
  // 5. Setup scroll sync
6652
7162
  const { handleScroll } = useScrollSync({ widthScale, iframeRef });
6653
7163
  const scaledHeight = iframeHeight * widthScale;
6654
- const scaledWidth = contentWidth * widthScale;
7164
+ const scaledWidth = viewport.width * widthScale;
6655
7165
  return {
6656
7166
  scaledWidth,
6657
7167
  scaledHeight,
@@ -7690,11 +8200,11 @@ const AutoScrollHandler = ({ visualRef }) => {
7690
8200
  };
7691
8201
 
7692
8202
  const PortalAreaRenderer = ({ iframeRef, visualRef, shadowRoot, onAreaCreated, onAreaClick, }) => {
7693
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
8203
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
7694
8204
  const iframeDocument = iframeRef.current?.contentDocument || undefined;
7695
8205
  const { shadowContainer, isReady } = useAreaRendererContainer(iframeDocument, shadowRoot);
7696
- useAreaRectSync({ iframeDocument, shadowRoot, enabled: isReady && isRenderedViz });
7697
- useAreaPositionsUpdater({ iframeRef, visualRef, enabled: isReady && isRenderedViz });
8206
+ useAreaRectSync({ iframeDocument, shadowRoot, enabled: isReady && isDomLoaded });
8207
+ useAreaPositionsUpdater({ iframeRef, visualRef, enabled: isReady && isDomLoaded });
7698
8208
  if (!shadowContainer || !isReady)
7699
8209
  return null;
7700
8210
  return (jsxs(Fragment$1, { children: [jsx(AutoScrollHandler, { visualRef: visualRef }), jsx(AreasPortal, { shadowContainer: shadowContainer, onAreaClick: onAreaClick }), jsx(AreaEditHighlightPortal, { shadowContainer: shadowContainer, iframeRef: iframeRef, customShadowRoot: shadowRoot, onAreaCreated: onAreaCreated })] }));
@@ -7703,7 +8213,7 @@ const PortalAreaRenderer = ({ iframeRef, visualRef, shadowRoot, onAreaCreated, o
7703
8213
  const VizAreaClick = ({ iframeRef, visualRef, shadowRoot, autoCreateTopN = 10, enableOverlapResolution = true, onAreaClick, }) => {
7704
8214
  const clickAreas = useHeatmapDataContext((s) => s.clickAreas);
7705
8215
  const resetView = useHeatmapAreaClickContext((s) => s.resetView);
7706
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
8216
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
7707
8217
  useAreaTopAutoDetect({ autoCreateTopN, shadowRoot, disabled: !!clickAreas?.length });
7708
8218
  useAreaFilterVisible({ iframeRef, enableOverlapResolution });
7709
8219
  useAreaHydration({ shadowRoot });
@@ -7712,7 +8222,7 @@ const VizAreaClick = ({ iframeRef, visualRef, shadowRoot, autoCreateTopN = 10, e
7712
8222
  resetView();
7713
8223
  };
7714
8224
  }, []);
7715
- if (!iframeRef.current || !isRenderedViz)
8225
+ if (!iframeRef.current || !isDomLoaded)
7716
8226
  return null;
7717
8227
  return (jsx(Fragment, { children: jsx(PortalAreaRenderer, { iframeRef: iframeRef, visualRef: visualRef, shadowRoot: shadowRoot, onAreaClick: onAreaClick }) }));
7718
8228
  };
@@ -7843,7 +8353,7 @@ const useAnchorPosition = (calloutRef, props) => {
7843
8353
  const ElementMissing = ({ show = true, visualRef }) => {
7844
8354
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
7845
8355
  const missingElementRef = useRef(null);
7846
- const wrapperWidth = useHeatmapWidthByDevice();
8356
+ const viewport = useHeatmapViewportByDevice();
7847
8357
  const [scrollPosition, setScrollPosition] = useState({ scrollTop: 0, scrollLeft: 0 });
7848
8358
  useEffect(() => {
7849
8359
  const container = visualRef.current;
@@ -7873,7 +8383,7 @@ const ElementMissing = ({ show = true, visualRef }) => {
7873
8383
  const containerHeight = containerRect?.height ?? 0;
7874
8384
  const topPosition = scrollTop + (containerHeight + elementHeightCenter) / 2;
7875
8385
  const topPositionScaled = topPosition / widthScale;
7876
- const leftPosition = wrapperWidth / 2;
8386
+ const leftPosition = viewport.width / 2;
7877
8387
  return (jsxs(Fragment, { children: [jsx("div", { className: "missingElement-backdrop", style: {
7878
8388
  position: 'absolute',
7879
8389
  top: 0,
@@ -7998,7 +8508,7 @@ const ElementOverlayComponent = (props) => {
7998
8508
  const { type, element, onClick, elementId, hideOutline } = props;
7999
8509
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
8000
8510
  const viewportHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8001
- const viewportWidth = useHeatmapWidthByDevice();
8511
+ const viewport = useHeatmapViewportByDevice();
8002
8512
  const overlayStyle = useMemo(() => {
8003
8513
  const isInvalid = !element || (element.width === 0 && element.height === 0);
8004
8514
  if (isInvalid)
@@ -8015,7 +8525,7 @@ const ElementOverlayComponent = (props) => {
8015
8525
  const isHovered = type === 'hovered';
8016
8526
  const badgeWidthScale = isHovered ? 1 : widthScale;
8017
8527
  const showCallout = !!element?.mousePosition && !isHovered;
8018
- return (jsxs(Fragment$1, { children: [jsx("div", { onClick: onClick, className: `heatmapElement heatmapElement--${type} ${hideOutline ? 'heatmapElement--hide-outline' : ''}`, id: elementId, style: overlayStyle, children: showCallout && jsx(ElementCalloutOverlay, { ...props }) }), jsx(BackdropCanvas, { activeElement: overlayStyle, viewportWidth: viewportWidth, viewportHeight: viewportHeight, show: !isHovered }), jsx(RankBadge, { hash: element.hash, show: isHovered, index: element.rank, elementRect: element, widthScale: badgeWidthScale, clickOnElement: onClick })] }));
8528
+ return (jsxs(Fragment$1, { children: [jsx("div", { onClick: onClick, className: `heatmapElement heatmapElement--${type} ${hideOutline ? 'heatmapElement--hide-outline' : ''}`, id: elementId, style: overlayStyle, children: showCallout && jsx(ElementCalloutOverlay, { ...props }) }), jsx(BackdropCanvas, { activeElement: overlayStyle, viewportWidth: viewport.width, viewportHeight: viewportHeight, show: !isHovered }), jsx(RankBadge, { hash: element.hash, show: isHovered, index: element.rank, elementRect: element, widthScale: badgeWidthScale, clickOnElement: onClick })] }));
8019
8529
  };
8020
8530
  ElementOverlayComponent.displayName = 'ElementOverlay';
8021
8531
  const ElementOverlay = memo(ElementOverlayComponent);
@@ -8080,7 +8590,7 @@ const HeatmapElements = (props) => {
8080
8590
  };
8081
8591
 
8082
8592
  const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
8083
- const contentWidth = useHeatmapWidthByDevice();
8593
+ const viewport = useHeatmapViewportByDevice();
8084
8594
  const dataInfo = useHeatmapDataContext((s) => s.dataInfo);
8085
8595
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
8086
8596
  const visualizer = {
@@ -8094,7 +8604,7 @@ const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
8094
8604
  if (!iframeRef.current)
8095
8605
  return null;
8096
8606
  return (jsx(HeatmapElements, { visualizer: visualizer, visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef, heatmapInfo: dataInfo, isVisible: true, positionMode: DEFAULT_POSITION_MODE, isHideTopRank: true, iframeDimensions: {
8097
- width: contentWidth,
8607
+ width: viewport.width,
8098
8608
  position: 'absolute',
8099
8609
  top: 0,
8100
8610
  left: 0,
@@ -8358,7 +8868,7 @@ const VizLoadingCanvas = () => {
8358
8868
  const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHeight, onScroll, }) => {
8359
8869
  const isLoadingCanvas = useHeatmapSettingContext((state) => state.isLoadingCanvas);
8360
8870
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
8361
- const contentWidth = useHeatmapWidthByDevice();
8871
+ const viewport = useHeatmapViewportByDevice();
8362
8872
  const contentHeight = calcContentHeight();
8363
8873
  return (jsx("div", { ref: visualRef, className: "gx-hm-visual Polaris-Scrollable Polaris-Scrollable--vertical Polaris-Scrollable--scrollbarWidthThin Polaris-Scrollable--scrollbarGutterStable", onScroll: onScroll, style: {
8364
8874
  overflowX: 'hidden',
@@ -8380,7 +8890,7 @@ const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHe
8380
8890
  paddingBottom: HEATMAP_STYLE['viz']['paddingBottom'],
8381
8891
  background: HEATMAP_STYLE['viz']['background'],
8382
8892
  }, children: jsx("div", { className: "gx-hm-wrapper", ref: wrapperRef, style: {
8383
- width: contentWidth,
8893
+ width: viewport.width,
8384
8894
  height: iframeHeight,
8385
8895
  transform: `scale(${widthScale})`,
8386
8896
  transformOrigin: 'top center',
@@ -8393,14 +8903,14 @@ const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHe
8393
8903
  }
8394
8904
  };
8395
8905
 
8396
- const VizDomRenderer = ({ mode = 'heatmap' }) => {
8906
+ const VizDomRenderer = ({ mode }) => {
8397
8907
  const viewId = useViewIdContext();
8398
- const contentWidth = useHeatmapWidthByDevice();
8908
+ const viewport = useHeatmapViewportByDevice();
8399
8909
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8400
8910
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
8401
8911
  const wrapperRef = useRef(null);
8402
8912
  const visualRef = useRef(null);
8403
- const { iframeRef } = useHeatmapRenderByMode(mode);
8913
+ const { iframeRef } = useHeatmapRenderDom();
8404
8914
  const { scaledHeight, handleScroll } = useHeatmapScale({ wrapperRef, iframeRef, visualRef });
8405
8915
  useHeatmapCanvas();
8406
8916
  useRenderCount('VizDomRenderer');
@@ -8408,7 +8918,7 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
8408
8918
  const scrollTop = e.currentTarget.scrollTop;
8409
8919
  handleScroll(scrollTop);
8410
8920
  };
8411
- return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [jsx(VizClickmap, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ...HEATMAP_IFRAME, id: `clarity-iframe-${viewId}`, ref: iframeRef, width: contentWidth, height: wrapperHeight }), jsx(VizLoadingCanvas, {}), jsx(VizScrollMap, { visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef })] }));
8921
+ return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [jsx(VizClickmap, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ...HEATMAP_IFRAME, id: `clarity-iframe-${viewId}`, ref: iframeRef, width: viewport.width, height: wrapperHeight }), jsx(VizLoadingCanvas, {}), jsx(VizScrollMap, { visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef })] }));
8412
8922
  };
8413
8923
 
8414
8924
  const VizLoading = () => {
@@ -8425,8 +8935,9 @@ const VizLoading = () => {
8425
8935
  const VizDomHeatmap = () => {
8426
8936
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8427
8937
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
8938
+ const setWrapperHeight = useHeatmapVizRectContext((s) => s.setWrapperHeight);
8428
8939
  const setVizRef = useHeatmapVizRectContext((s) => s.setVizRef);
8429
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
8940
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
8430
8941
  const setSelectedElement = useHeatmapClickContext((s) => s.setSelectedElement);
8431
8942
  const setHoveredElement = useHeatmapHoverContext((s) => s.setHoveredElement);
8432
8943
  // const setSelectedArea = useHeatmapAreaClickContext((s) => s.setSelectedArea);
@@ -8436,7 +8947,8 @@ const VizDomHeatmap = () => {
8436
8947
  const cleanUp = () => {
8437
8948
  setVizRef(null);
8438
8949
  setIframeHeight(0);
8439
- setIsRenderedViz(false);
8950
+ setWrapperHeight(0);
8951
+ setIsDomLoaded(false);
8440
8952
  setSelectedElement(null);
8441
8953
  setHoveredElement(null);
8442
8954
  // setSelectedArea(null);
@@ -8445,13 +8957,13 @@ const VizDomHeatmap = () => {
8445
8957
  };
8446
8958
  useEffect(() => {
8447
8959
  return cleanUp;
8448
- }, []);
8449
- return (jsxs(VizContainer, { isActive: true, children: [jsx(VizDomRenderer, {}), iframeHeight === 0 && jsx(VizLoading, {})] }));
8960
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
8961
+ return (jsxs(VizContainer, { isActive: true, children: [jsx(VizDomRenderer, { mode: EHeatmapMode.Heatmap }), iframeHeight === 0 && jsx(VizLoading, {})] }));
8450
8962
  };
8451
8963
  VizDomHeatmap.displayName = 'VizDomHeatmap';
8452
8964
 
8453
8965
  const VizLiveRenderer = () => {
8454
- const contentWidth = useHeatmapWidthByDevice();
8966
+ const viewport = useHeatmapViewportByDevice();
8455
8967
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8456
8968
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
8457
8969
  const visualRef = useRef(null);
@@ -8462,7 +8974,7 @@ const VizLiveRenderer = () => {
8462
8974
  const scrollTop = e.currentTarget.scrollTop;
8463
8975
  handleScroll(scrollTop);
8464
8976
  };
8465
- return (jsx(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, iframeHeight: iframeHeight, onScroll: onScroll, children: jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth, height: wrapperHeight, scrolling: "no" }) }));
8977
+ return (jsx(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, iframeHeight: iframeHeight, onScroll: onScroll, children: jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: viewport.width, height: wrapperHeight, scrolling: "no" }) }));
8466
8978
  };
8467
8979
 
8468
8980
  const VizLiveHeatmap = () => {
@@ -8553,4 +9065,4 @@ const HeatmapLayout = ({ shopId, data, clickmap, clickAreas, scrollmap, attentio
8553
9065
  }
8554
9066
  };
8555
9067
 
8556
- export { BACKDROP_CONFIG, DEFAULT_SIDEBAR_WIDTH, DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO, EClickMode, EClickRankType, EClickType, EDeviceType, EHeatmapDataSource, EHeatmapMode, EHeatmapType, ELM_CALLOUT_CONFIG, EScrollType, GraphView, HEATMAP_CONFIG, HEATMAP_IFRAME, HEATMAP_STYLE, HeatmapLayout, ViewIdContext, Z_INDEX$1 as Z_INDEX, compareViewPerformance, convertViewportToIframeCoords, createStorePerformanceTracker, createViewContextHook, decodeArrayClarity, decodeClarity, downloadPerformanceReport, getCompareViewId, getMetricsByViewId, getPerformanceReportJSON, getScrollGradientColor, performanceLogger, printPerformanceSummary, scrollToElementIfNeeded, sendPerformanceReport, serializeAreas, trackStoreAction, useAreaCreation, useAreaEditMode, useAreaFilterVisible, useAreaHydration, useAreaInteraction, useAreaPositionsUpdater, useAreaRectSync, useAreaRendererContainer, useAreaTopAutoDetect, useClickedElement, useDebounceCallback, useElementCalloutVisible, useHeatmapAreaClickContext, useHeatmapCanvas, useHeatmapClickContext, useHeatmapCompareStore, useHeatmapConfigStore, useHeatmapCopyView, useHeatmapDataContext, useHeatmapEffects, useHeatmapElementPosition, useHeatmapHoverContext, useHeatmapLiveContext, useHeatmapRenderByMode, useHeatmapScale, useHeatmapScroll, useHeatmapScrollContext, useHeatmapSettingContext, useHeatmapVizContext, useHeatmapVizRectContext, useHeatmapWidthByDevice, useHoveredElement, useMeasureFunction, useRegisterConfig, useRegisterControl, useRegisterData, useRegisterHeatmap, useRenderCount, useScrollmapZones, useTrackHookCall, useViewIdContext, useVizLiveRender, useWhyDidYouUpdate, useWrapperRefHeight, useZonePositions, withPerformanceTracking };
9068
+ export { BACKDROP_CONFIG, DEFAULT_SIDEBAR_WIDTH, DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO, EClickMode, EClickRankType, EClickType, EDeviceType, EHeatmapDataSource, EHeatmapMode, EHeatmapType, ELM_CALLOUT_CONFIG, EScrollType, GraphView, HEATMAP_CONFIG, HEATMAP_IFRAME, HEATMAP_STYLE, HeatmapLayout, ViewIdContext, Z_INDEX$1 as Z_INDEX, compareViewPerformance, convertViewportToIframeCoords, createStorePerformanceTracker, createViewContextHook, decodeArrayClarity, decodeClarity, downloadPerformanceReport, getCompareViewId, getMetricsByViewId, getPerformanceReportJSON, getScrollGradientColor, performanceLogger, printPerformanceSummary, scrollToElementIfNeeded, sendPerformanceReport, serializeAreas, trackStoreAction, useAreaCreation, useAreaEditMode, useAreaFilterVisible, useAreaHydration, useAreaInteraction, useAreaPositionsUpdater, useAreaRectSync, useAreaRendererContainer, useAreaTopAutoDetect, useClickedElement, useDebounceCallback, useElementCalloutVisible, useHeatmapAreaClickContext, useHeatmapCanvas, useHeatmapClickContext, useHeatmapCompareStore, useHeatmapConfigStore, useHeatmapCopyView, useHeatmapDataContext, useHeatmapEffects, useHeatmapElementPosition, useHeatmapHoverContext, useHeatmapLiveContext, useHeatmapRenderByMode, useHeatmapScale, useHeatmapScroll, useHeatmapScrollContext, useHeatmapSettingContext, useHeatmapViewportByDevice, useHeatmapVizContext, useHeatmapVizRectContext, useHoveredElement, useMeasureFunction, useRegisterConfig, useRegisterControl, useRegisterData, useRegisterHeatmap, useRenderCount, useScrollmapZones, useTrackHookCall, useViewIdContext, useVizLiveRender, useWhyDidYouUpdate, useWrapperRefHeight, useZonePositions, withPerformanceTracking };