@elementor/editor-audits 4.4.0-1118 → 4.4.0-1120

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.
package/dist/index.mjs CHANGED
@@ -6,19 +6,96 @@ import { __registerSlice as registerSlice } from "@elementor/store";
6
6
  import { utilitiesMenu } from "@elementor/editor-app-bar";
7
7
 
8
8
  // src/hooks/use-audit-toggle-props.ts
9
- import { ShieldCheckIcon as ShieldCheckIcon2 } from "@elementor/icons";
10
- import { __ as __17 } from "@wordpress/i18n";
9
+ import { __ as __18 } from "@wordpress/i18n";
10
+
11
+ // src/components/audit-toggle-icon.tsx
12
+ import * as React from "react";
13
+ import { ShieldCheckIcon } from "@elementor/icons";
14
+ import { __useSelector as useSelector } from "@elementor/store";
15
+ import { Badge } from "@elementor/ui";
16
+
17
+ // src/store/slice.ts
18
+ import { __createSlice } from "@elementor/store";
19
+ var initialState = { status: "idle", report: null, error: null, isStale: false };
20
+ var slice = __createSlice({
21
+ name: "audits",
22
+ initialState,
23
+ reducers: {
24
+ runStarted(state) {
25
+ state.status = "loading";
26
+ state.error = null;
27
+ },
28
+ runSucceeded(state, action) {
29
+ state.status = "ready";
30
+ state.report = action.payload;
31
+ state.isStale = false;
32
+ },
33
+ runFailed(state, action) {
34
+ state.status = "error";
35
+ state.error = action.payload;
36
+ },
37
+ runAborted(state) {
38
+ state.status = state.report ? "ready" : "idle";
39
+ },
40
+ reportRestored(state, action) {
41
+ state.status = "ready";
42
+ state.report = action.payload;
43
+ state.error = null;
44
+ state.isStale = false;
45
+ },
46
+ reportCleared(state) {
47
+ state.status = "idle";
48
+ state.report = null;
49
+ state.error = null;
50
+ state.isStale = false;
51
+ },
52
+ reportStale(state) {
53
+ if (state.report) {
54
+ state.isStale = true;
55
+ }
56
+ }
57
+ }
58
+ });
59
+
60
+ // src/store/selectors.ts
61
+ function selectStatus(state) {
62
+ return state.audits.status;
63
+ }
64
+ function selectReport(state) {
65
+ return state.audits.report;
66
+ }
67
+ function selectError(state) {
68
+ return state.audits.error;
69
+ }
70
+ function selectIsStale(state) {
71
+ return state.audits.isStale;
72
+ }
73
+
74
+ // src/components/audit-toggle-icon.tsx
75
+ function AuditToggleIcon() {
76
+ const isStale = useSelector((state) => selectIsStale(state));
77
+ return /* @__PURE__ */ React.createElement(
78
+ Badge,
79
+ {
80
+ variant: "dot",
81
+ color: "warning",
82
+ invisible: !isStale,
83
+ overlap: "circular",
84
+ slotProps: { badge: { "data-testid": "audit-stale-indicator" } }
85
+ },
86
+ /* @__PURE__ */ React.createElement(ShieldCheckIcon, null)
87
+ );
88
+ }
11
89
 
12
90
  // src/editor-panel.tsx
13
91
  import { createFloatingPanel } from "@elementor/editor-floating-panels";
14
92
 
15
93
  // src/components/audit-panel.tsx
16
- import * as React19 from "react";
94
+ import * as React21 from "react";
17
95
  import { getHostDocumentId as getHostDocumentId3 } from "@elementor/editor-elements";
18
96
  import { FloatingPanelBody, FloatingPanelFooter, FloatingPanelHeader } from "@elementor/editor-floating-panels";
19
- import { ReloadIcon } from "@elementor/icons";
20
- import { Box as Box15, Button as Button5, Typography as Typography12 } from "@elementor/ui";
21
- import { __ as __16 } from "@wordpress/i18n";
97
+ import { Box as Box15, Typography as Typography12 } from "@elementor/ui";
98
+ import { __ as __17 } from "@wordpress/i18n";
22
99
 
23
100
  // src/constants.ts
24
101
  import { __ } from "@wordpress/i18n";
@@ -50,7 +127,7 @@ var CATEGORY_LABELS = {
50
127
  // src/hooks/use-audit-report.ts
51
128
  import { useEffect } from "react";
52
129
  import { getHostDocumentId as getHostDocumentId2 } from "@elementor/editor-elements";
53
- import { __useDispatch as useDispatch, __useSelector as useSelector } from "@elementor/store";
130
+ import { __useDispatch as useDispatch, __useSelector as useSelector2 } from "@elementor/store";
54
131
 
55
132
  // src/runner.ts
56
133
  import { getHostDocumentElements, getHostDocumentId } from "@elementor/editor-elements";
@@ -550,52 +627,6 @@ async function runPageAudit(documentId) {
550
627
  return computeReport(documentId, auditResults);
551
628
  }
552
629
 
553
- // src/store/slice.ts
554
- import { __createSlice } from "@elementor/store";
555
- var initialState = { status: "idle", report: null, error: null };
556
- var slice = __createSlice({
557
- name: "audits",
558
- initialState,
559
- reducers: {
560
- runStarted(state) {
561
- state.status = "loading";
562
- state.error = null;
563
- },
564
- runSucceeded(state, action) {
565
- state.status = "ready";
566
- state.report = action.payload;
567
- },
568
- runFailed(state, action) {
569
- state.status = "error";
570
- state.error = action.payload;
571
- },
572
- runAborted(state) {
573
- state.status = state.report ? "ready" : "idle";
574
- },
575
- reportRestored(state, action) {
576
- state.status = "ready";
577
- state.report = action.payload;
578
- state.error = null;
579
- },
580
- reportCleared(state) {
581
- state.status = "idle";
582
- state.report = null;
583
- state.error = null;
584
- }
585
- }
586
- });
587
-
588
- // src/store/selectors.ts
589
- function selectStatus(state) {
590
- return state.audits.status;
591
- }
592
- function selectReport(state) {
593
- return state.audits.report;
594
- }
595
- function selectError(state) {
596
- return state.audits.error;
597
- }
598
-
599
630
  // src/utils/report-storage.ts
600
631
  import { getSessionStorageItem, setSessionStorageItem } from "@elementor/session";
601
632
  function getStorageKey(documentId) {
@@ -610,10 +641,11 @@ function persistReport(documentId, report) {
610
641
 
611
642
  // src/hooks/use-audit-report.ts
612
643
  function useAuditReport() {
613
- const status = useSelector((state) => selectStatus(state));
614
- const report = useSelector((state) => selectReport(state));
615
- const error = useSelector((state) => selectError(state));
616
- const dispatch = useDispatch();
644
+ const status = useSelector2((state) => selectStatus(state));
645
+ const report = useSelector2((state) => selectReport(state));
646
+ const error = useSelector2((state) => selectError(state));
647
+ const isStale = useSelector2((state) => selectIsStale(state));
648
+ const dispatch2 = useDispatch();
617
649
  const documentId = getHostDocumentId2() ?? 0;
618
650
  useEffect(() => {
619
651
  if (!documentId || report?.documentId === documentId) {
@@ -621,30 +653,30 @@ function useAuditReport() {
621
653
  }
622
654
  const persisted = getPersistedReport(documentId);
623
655
  if (persisted) {
624
- dispatch(slice.actions.reportRestored(persisted));
656
+ dispatch2(slice.actions.reportRestored(persisted));
625
657
  } else if (report) {
626
- dispatch(slice.actions.reportCleared());
658
+ dispatch2(slice.actions.reportCleared());
627
659
  }
628
- }, [documentId, report, dispatch]);
660
+ }, [documentId, report, dispatch2]);
629
661
  const run = async (documentIdToRun) => {
630
- dispatch(slice.actions.runStarted());
662
+ dispatch2(slice.actions.runStarted());
631
663
  try {
632
664
  const nextReport = await runPageAudit(documentIdToRun);
633
- dispatch(slice.actions.runSucceeded(nextReport));
665
+ dispatch2(slice.actions.runSucceeded(nextReport));
634
666
  persistReport(documentIdToRun, nextReport);
635
667
  } catch (e) {
636
668
  if (e instanceof SessionExpiredError) {
637
- dispatch(slice.actions.runAborted());
669
+ dispatch2(slice.actions.runAborted());
638
670
  return;
639
671
  }
640
- dispatch(slice.actions.runFailed(e instanceof Error ? e.message : "Unknown error"));
672
+ dispatch2(slice.actions.runFailed(e instanceof Error ? e.message : "Unknown error"));
641
673
  }
642
674
  };
643
- return { status, report, error, run };
675
+ return { status, report, error, isStale, run };
644
676
  }
645
677
 
646
678
  // src/components/audit-feedback.tsx
647
- import * as React from "react";
679
+ import * as React2 from "react";
648
680
  import { useState } from "react";
649
681
  import { useFloatingPanelZIndex } from "@elementor/editor-floating-panels";
650
682
  import { notify } from "@elementor/editor-notifications";
@@ -730,7 +762,7 @@ function AuditFeedback() {
730
762
  trackEvent(FEEDBACK_SENT_EVENT, { entry_point: FEEDBACK_ENTRY_POINT });
731
763
  }).catch(notifyError).finally(() => setIsSubmitting(false));
732
764
  };
733
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Tooltip, { title: triggerLabel, placement: "top", PopperProps: { sx: { zIndex: panelZIndex } } }, /* @__PURE__ */ React.createElement(IconButton, { size: "small", "aria-label": triggerLabel, onClick: handleOpen }, /* @__PURE__ */ React.createElement(MessageLinesIcon, { fontSize: "small" }))), /* @__PURE__ */ React.createElement(
765
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Tooltip, { title: triggerLabel, placement: "top", PopperProps: { sx: { zIndex: panelZIndex } } }, /* @__PURE__ */ React2.createElement(IconButton, { size: "small", "aria-label": triggerLabel, onClick: handleOpen }, /* @__PURE__ */ React2.createElement(MessageLinesIcon, { fontSize: "small" }))), /* @__PURE__ */ React2.createElement(
734
766
  Dialog,
735
767
  {
736
768
  open: isOpen,
@@ -739,8 +771,8 @@ function AuditFeedback() {
739
771
  "aria-describedby": DIALOG_DESCRIPTION_ID,
740
772
  PaperProps: { sx: { borderRadius: 1 } }
741
773
  },
742
- /* @__PURE__ */ React.createElement(DialogHeader, { logo: false, onClose: handleClose }, /* @__PURE__ */ React.createElement(DialogTitle, { id: DIALOG_TITLE_ID }, __2("Let us know what you think", "elementor"))),
743
- /* @__PURE__ */ React.createElement(DialogContent, { dividers: true }, /* @__PURE__ */ React.createElement(Stack, { direction: "column", gap: 2 }, /* @__PURE__ */ React.createElement(TextField, { value: FEEDBACK_SUBJECT_LABEL, disabled: true, fullWidth: true, size: "small" }), /* @__PURE__ */ React.createElement(
774
+ /* @__PURE__ */ React2.createElement(DialogHeader, { logo: false, onClose: handleClose }, /* @__PURE__ */ React2.createElement(DialogTitle, { id: DIALOG_TITLE_ID }, __2("Let us know what you think", "elementor"))),
775
+ /* @__PURE__ */ React2.createElement(DialogContent, { dividers: true }, /* @__PURE__ */ React2.createElement(Stack, { direction: "column", gap: 2 }, /* @__PURE__ */ React2.createElement(TextField, { value: FEEDBACK_SUBJECT_LABEL, disabled: true, fullWidth: true, size: "small" }), /* @__PURE__ */ React2.createElement(
744
776
  TextField,
745
777
  {
746
778
  placeholder: __2(
@@ -754,11 +786,11 @@ function AuditFeedback() {
754
786
  onChange: (event) => setFeedbackText(event.target.value),
755
787
  value: feedbackText
756
788
  }
757
- ), /* @__PURE__ */ React.createElement(Typography, { id: DIALOG_DESCRIPTION_ID, variant: "caption", color: "text.secondary" }, __2(
789
+ ), /* @__PURE__ */ React2.createElement(Typography, { id: DIALOG_DESCRIPTION_ID, variant: "caption", color: "text.secondary" }, __2(
758
790
  "We appreciate your feedback! While we review all submissions, we can't guarantee that every suggestion will result in a change or update.",
759
791
  "elementor"
760
792
  )))),
761
- /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(Button, { variant: "text", color: "secondary", onClick: handleCancel }, __2("Cancel", "elementor")), /* @__PURE__ */ React.createElement(
793
+ /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { variant: "text", color: "secondary", onClick: handleCancel }, __2("Cancel", "elementor")), /* @__PURE__ */ React2.createElement(
762
794
  Button,
763
795
  {
764
796
  variant: "contained",
@@ -772,29 +804,29 @@ function AuditFeedback() {
772
804
  }
773
805
 
774
806
  // src/components/pages/error-page.tsx
775
- import * as React2 from "react";
807
+ import * as React3 from "react";
776
808
  import { Box, Button as Button2, Typography as Typography2 } from "@elementor/ui";
777
809
  import { __ as __3 } from "@wordpress/i18n";
778
810
  function ErrorPage({ message, onRetry }) {
779
- return /* @__PURE__ */ React2.createElement(Box, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 1.5, p: 4 } }, /* @__PURE__ */ React2.createElement(Typography2, { variant: "body2", color: "error", textAlign: "center" }, message), /* @__PURE__ */ React2.createElement(Button2, { variant: "contained", size: "small", onClick: onRetry }, __3("Try again", "elementor")));
811
+ return /* @__PURE__ */ React3.createElement(Box, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 1.5, p: 4 } }, /* @__PURE__ */ React3.createElement(Typography2, { variant: "body2", color: "error", textAlign: "center" }, message), /* @__PURE__ */ React3.createElement(Button2, { variant: "contained", size: "small", onClick: onRetry }, __3("Try again", "elementor")));
780
812
  }
781
813
 
782
814
  // src/components/pages/loading-page.tsx
783
- import * as React3 from "react";
815
+ import * as React4 from "react";
784
816
  import { Box as Box2, CircularProgress, Typography as Typography3 } from "@elementor/ui";
785
817
  import { __ as __4 } from "@wordpress/i18n";
786
818
  function LoadingPage() {
787
- return /* @__PURE__ */ React3.createElement(Box2, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 1.5, p: 4 } }, /* @__PURE__ */ React3.createElement(CircularProgress, { size: 32 }), /* @__PURE__ */ React3.createElement(Typography3, { variant: "body2" }, __4("Audit in progress.", "elementor")));
819
+ return /* @__PURE__ */ React4.createElement(Box2, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 1.5, p: 4 } }, /* @__PURE__ */ React4.createElement(CircularProgress, { size: 32 }), /* @__PURE__ */ React4.createElement(Typography3, { variant: "body2" }, __4("Audit in progress.", "elementor")));
788
820
  }
789
821
 
790
822
  // src/components/pages/welcome-page.tsx
791
- import * as React4 from "react";
823
+ import * as React5 from "react";
792
824
  import { Box as Box3, Typography as Typography4 } from "@elementor/ui";
793
825
  import { __ as __5 } from "@wordpress/i18n";
794
826
  var INFORMATION_IMAGE_PATH = "images/information.svg";
795
827
  function WelcomePage() {
796
828
  const assetsUrl = window.elementorCommon?.config?.urls?.assets ?? "";
797
- return /* @__PURE__ */ React4.createElement(
829
+ return /* @__PURE__ */ React5.createElement(
798
830
  Box3,
799
831
  {
800
832
  sx: {
@@ -806,7 +838,7 @@ function WelcomePage() {
806
838
  p: 3
807
839
  }
808
840
  },
809
- /* @__PURE__ */ React4.createElement(
841
+ /* @__PURE__ */ React5.createElement(
810
842
  "img",
811
843
  {
812
844
  className: "elementor-nerd-box-icon",
@@ -815,8 +847,8 @@ function WelcomePage() {
815
847
  alt: __5("Elementor", "elementor")
816
848
  }
817
849
  ),
818
- /* @__PURE__ */ React4.createElement(Typography4, { variant: "subtitle1", component: "h3", sx: { marginBlockStart: 2 } }, __5("Audit your page!", "elementor")),
819
- /* @__PURE__ */ React4.createElement(Typography4, { variant: "caption", textAlign: "center" }, __5(
850
+ /* @__PURE__ */ React5.createElement(Typography4, { variant: "subtitle1", component: "h3", sx: { marginBlockStart: 2 } }, __5("Audit your page!", "elementor")),
851
+ /* @__PURE__ */ React5.createElement(Typography4, { variant: "caption", textAlign: "center" }, __5(
820
852
  'Check SEO, accessibility, performance, and best practices. Click "Run page audit" to begin.',
821
853
  "elementor"
822
854
  ))
@@ -824,12 +856,12 @@ function WelcomePage() {
824
856
  }
825
857
 
826
858
  // src/components/report-shell.tsx
827
- import * as React18 from "react";
859
+ import * as React19 from "react";
828
860
  import { useState as useState4 } from "react";
829
861
  import { Box as Box14 } from "@elementor/ui";
830
862
 
831
863
  // src/components/pages/category-page.tsx
832
- import * as React12 from "react";
864
+ import * as React13 from "react";
833
865
  import { Box as Box8 } from "@elementor/ui";
834
866
  import { __ as __11 } from "@wordpress/i18n";
835
867
 
@@ -844,39 +876,39 @@ function useSingleExpandedCard(initialId = null) {
844
876
  }
845
877
 
846
878
  // src/components/category-icons.ts
847
- import { BoltIcon, ElementorAccessibilityIcon, FileSearchIcon, Settings2Icon, ShieldCheckIcon } from "@elementor/icons";
879
+ import { BoltIcon, ElementorAccessibilityIcon, FileSearchIcon, Settings2Icon, ShieldCheckIcon as ShieldCheckIcon2 } from "@elementor/icons";
848
880
  var CATEGORY_ICONS = {
849
881
  "best-practices": Settings2Icon,
850
882
  seo: FileSearchIcon,
851
883
  accessibility: ElementorAccessibilityIcon,
852
884
  performance: BoltIcon,
853
- compliance: ShieldCheckIcon
885
+ compliance: ShieldCheckIcon2
854
886
  };
855
887
 
856
888
  // src/components/status-section.tsx
857
- import * as React5 from "react";
889
+ import * as React6 from "react";
858
890
  import { useState as useState3 } from "react";
859
891
  import { ChevronDownIcon } from "@elementor/icons";
860
892
  import { Box as Box4, Chip, Collapse, IconButton as IconButton2 } from "@elementor/ui";
861
893
  import { __ as __6 } from "@wordpress/i18n";
862
894
  function StatusSection({ label, count, color = "default", defaultExpanded = false, children }) {
863
895
  const [expanded, setExpanded] = useState3(defaultExpanded);
864
- if (React5.Children.count(children) === 0) {
896
+ if (React6.Children.count(children) === 0) {
865
897
  return null;
866
898
  }
867
- return /* @__PURE__ */ React5.createElement(Box4, { sx: { paddingBlock: 1 } }, /* @__PURE__ */ React5.createElement(
899
+ return /* @__PURE__ */ React6.createElement(Box4, { sx: { paddingBlock: 1 } }, /* @__PURE__ */ React6.createElement(
868
900
  Box4,
869
901
  {
870
902
  sx: { display: "flex", alignItems: "center", gap: 0.5, cursor: "pointer" },
871
903
  onClick: () => setExpanded((v) => !v)
872
904
  },
873
- /* @__PURE__ */ React5.createElement(
905
+ /* @__PURE__ */ React6.createElement(
874
906
  IconButton2,
875
907
  {
876
908
  size: "small",
877
909
  "aria-label": expanded ? __6("Collapse", "elementor") : __6("Expand", "elementor")
878
910
  },
879
- /* @__PURE__ */ React5.createElement(
911
+ /* @__PURE__ */ React6.createElement(
880
912
  ChevronDownIcon,
881
913
  {
882
914
  fontSize: "small",
@@ -887,22 +919,22 @@ function StatusSection({ label, count, color = "default", defaultExpanded = fals
887
919
  }
888
920
  )
889
921
  ),
890
- /* @__PURE__ */ React5.createElement(Chip, { label: `${label} (${count})`, size: "small", color, variant: "standard" })
891
- ), /* @__PURE__ */ React5.createElement(Collapse, { in: expanded }, /* @__PURE__ */ React5.createElement(Box4, { sx: { paddingInlineStart: 4.25, paddingBlock: 2 } }, children)));
922
+ /* @__PURE__ */ React6.createElement(Chip, { label: `${label} (${count})`, size: "small", color, variant: "standard" })
923
+ ), /* @__PURE__ */ React6.createElement(Collapse, { in: expanded }, /* @__PURE__ */ React6.createElement(Box4, { sx: { paddingInlineStart: 4.25, paddingBlock: 2 } }, children)));
892
924
  }
893
925
 
894
926
  // src/components/subpage-header.tsx
895
- import * as React6 from "react";
927
+ import * as React7 from "react";
896
928
  import { ArrowLeftIcon } from "@elementor/icons";
897
929
  import { Box as Box5, IconButton as IconButton3, Rotate, Typography as Typography5, useTheme } from "@elementor/ui";
898
930
  import { __ as __7 } from "@wordpress/i18n";
899
931
  function SubpageHeader({ title, onBack, backLabel, icon }) {
900
932
  const isRtl = "rtl" === useTheme().direction;
901
- return /* @__PURE__ */ React6.createElement(Box5, { sx: { display: "flex", alignItems: "center", gap: 0.5, p: 1 } }, /* @__PURE__ */ React6.createElement(IconButton3, { size: "small", onClick: onBack, "aria-label": backLabel ?? __7("Back", "elementor") }, /* @__PURE__ */ React6.createElement(Rotate, { in: isRtl }, /* @__PURE__ */ React6.createElement(ArrowLeftIcon, { fontSize: "small" }))), icon, /* @__PURE__ */ React6.createElement(Typography5, { variant: "subtitle2", fontWeight: "bold" }, title));
933
+ return /* @__PURE__ */ React7.createElement(Box5, { sx: { display: "flex", alignItems: "center", gap: 0.5, p: 1 } }, /* @__PURE__ */ React7.createElement(IconButton3, { size: "small", onClick: onBack, "aria-label": backLabel ?? __7("Back", "elementor") }, /* @__PURE__ */ React7.createElement(Rotate, { in: isRtl }, /* @__PURE__ */ React7.createElement(ArrowLeftIcon, { fontSize: "small" }))), icon, /* @__PURE__ */ React7.createElement(Typography5, { variant: "subtitle2", fontWeight: "bold" }, title));
902
934
  }
903
935
 
904
936
  // src/components/violation-row.tsx
905
- import * as React11 from "react";
937
+ import * as React12 from "react";
906
938
  import { getElementIcon, getElementTitle } from "@elementor/editor-elements";
907
939
  import { useFloatingPanelZIndex as useFloatingPanelZIndex2 } from "@elementor/editor-floating-panels";
908
940
  import { CheckIcon, ChevronDownIcon as ChevronDownIcon2, HelpIcon, InfoCircleIcon, WandIcon as WandIcon2 } from "@elementor/icons";
@@ -968,7 +1000,7 @@ function onKeyboardClick(callback) {
968
1000
  }
969
1001
 
970
1002
  // src/components/fix-violation-with-angie.tsx
971
- import * as React7 from "react";
1003
+ import * as React8 from "react";
972
1004
  import { isAngieAvailable, sendPromptToAngie } from "@elementor/editor-mcp";
973
1005
  import { AngieIcon } from "@elementor/icons";
974
1006
  import { IconButton as IconButton4, Tooltip as Tooltip2 } from "@elementor/ui";
@@ -992,11 +1024,11 @@ function FixViolationWithAngie({ prompt, panelZIndex }) {
992
1024
  })
993
1025
  );
994
1026
  };
995
- return /* @__PURE__ */ React7.createElement(Tooltip2, { title: label, placement: "top", PopperProps: { sx: { zIndex: panelZIndex } } }, /* @__PURE__ */ React7.createElement(IconButton4, { component: "a", href, size: "small", "aria-label": label, onClick: handleClick }, /* @__PURE__ */ React7.createElement(AngieIcon, { fontSize: "tiny" })));
1027
+ return /* @__PURE__ */ React8.createElement(Tooltip2, { title: label, placement: "top", PopperProps: { sx: { zIndex: panelZIndex } } }, /* @__PURE__ */ React8.createElement(IconButton4, { component: "a", href, size: "small", "aria-label": label, onClick: handleClick }, /* @__PURE__ */ React8.createElement(AngieIcon, { fontSize: "tiny" })));
996
1028
  }
997
1029
 
998
1030
  // src/components/severity-icons.tsx
999
- import * as React8 from "react";
1031
+ import * as React9 from "react";
1000
1032
  import { AlertCircleIcon, AlertTriangleFilledIcon, BulbIcon } from "@elementor/icons";
1001
1033
  var SEVERITY_CONFIG = {
1002
1034
  error: { Icon: AlertTriangleFilledIcon, color: "error" },
@@ -1005,11 +1037,11 @@ var SEVERITY_CONFIG = {
1005
1037
  };
1006
1038
  function SeverityIcon({ severity }) {
1007
1039
  const { Icon, color } = SEVERITY_CONFIG[severity];
1008
- return /* @__PURE__ */ React8.createElement(Icon, { fontSize: "small", color });
1040
+ return /* @__PURE__ */ React9.createElement(Icon, { fontSize: "small", color });
1009
1041
  }
1010
1042
 
1011
1043
  // src/components/violation-cta-button.tsx
1012
- import * as React9 from "react";
1044
+ import * as React10 from "react";
1013
1045
  import { WandIcon } from "@elementor/icons";
1014
1046
  import { Button as Button3 } from "@elementor/ui";
1015
1047
  function ViolationCtaButton({ ctaLabel, externalUrl, variant = "outlined", withIcon = false }) {
@@ -1018,13 +1050,13 @@ function ViolationCtaButton({ ctaLabel, externalUrl, variant = "outlined", withI
1018
1050
  event.preventDefault();
1019
1051
  window.open(externalUrl, "_blank", "noopener");
1020
1052
  };
1021
- return /* @__PURE__ */ React9.createElement(
1053
+ return /* @__PURE__ */ React10.createElement(
1022
1054
  Button3,
1023
1055
  {
1024
1056
  variant,
1025
1057
  color: "secondary",
1026
1058
  size: "small",
1027
- startIcon: withIcon ? /* @__PURE__ */ React9.createElement(WandIcon, { fontSize: "tiny", "aria-hidden": true }) : void 0,
1059
+ startIcon: withIcon ? /* @__PURE__ */ React10.createElement(WandIcon, { fontSize: "tiny", "aria-hidden": true }) : void 0,
1028
1060
  onClick: handleClick
1029
1061
  },
1030
1062
  ctaLabel
@@ -1032,12 +1064,12 @@ function ViolationCtaButton({ ctaLabel, externalUrl, variant = "outlined", withI
1032
1064
  }
1033
1065
 
1034
1066
  // src/components/violation-icons.tsx
1035
- import * as React10 from "react";
1067
+ import * as React11 from "react";
1036
1068
  import { FileSettingsIcon, SettingsIcon } from "@elementor/icons";
1037
1069
  import { Box as Box6 } from "@elementor/ui";
1038
1070
  function ViolationIcon({ violation, widgetIcon }) {
1039
1071
  if (widgetIcon) {
1040
- return /* @__PURE__ */ React10.createElement(
1072
+ return /* @__PURE__ */ React11.createElement(
1041
1073
  Box6,
1042
1074
  {
1043
1075
  component: "i",
@@ -1048,37 +1080,37 @@ function ViolationIcon({ violation, widgetIcon }) {
1048
1080
  );
1049
1081
  }
1050
1082
  if (violation.targetHint === "page-settings") {
1051
- return /* @__PURE__ */ React10.createElement(FileSettingsIcon, { fontSize: "inherit", "aria-hidden": true });
1083
+ return /* @__PURE__ */ React11.createElement(FileSettingsIcon, { fontSize: "inherit", "aria-hidden": true });
1052
1084
  }
1053
1085
  if (violation.targetHint === "site-settings" || violation.targetHint === "site-identity-settings") {
1054
- return /* @__PURE__ */ React10.createElement(SettingsIcon, { fontSize: "inherit", "aria-hidden": true });
1086
+ return /* @__PURE__ */ React11.createElement(SettingsIcon, { fontSize: "inherit", "aria-hidden": true });
1055
1087
  }
1056
- return /* @__PURE__ */ React10.createElement(SettingsIcon, { fontSize: "inherit", "aria-hidden": true });
1088
+ return /* @__PURE__ */ React11.createElement(SettingsIcon, { fontSize: "inherit", "aria-hidden": true });
1057
1089
  }
1058
1090
 
1059
1091
  // src/components/violation-row.tsx
1060
1092
  function SkipReasonTooltip({ reason }) {
1061
- return /* @__PURE__ */ React11.createElement(Tooltip3, { title: reason, placement: "top" }, /* @__PURE__ */ React11.createElement(Box7, { "aria-label": reason, component: "span", sx: { display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React11.createElement(HelpIcon, { fontSize: "small", color: "action" })));
1093
+ return /* @__PURE__ */ React12.createElement(Tooltip3, { title: reason, placement: "top" }, /* @__PURE__ */ React12.createElement(Box7, { "aria-label": reason, component: "span", sx: { display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React12.createElement(HelpIcon, { fontSize: "small", color: "action" })));
1062
1094
  }
1063
1095
  function StatusIndicator({ audit: audit26, violations }) {
1064
1096
  if (violations) {
1065
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit26.severity }), isScoredAudit(audit26) && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length));
1097
+ return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(SeverityIcon, { severity: audit26.severity }), isScoredAudit(audit26) && /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length));
1066
1098
  }
1067
- return /* @__PURE__ */ React11.createElement(CheckIcon, { fontSize: "small", color: "success" });
1099
+ return /* @__PURE__ */ React12.createElement(CheckIcon, { fontSize: "small", color: "success" });
1068
1100
  }
1069
1101
  function GuidanceAction({ violation }) {
1070
1102
  const hasPrimaryCta = !!(violation.ctaLabel && violation.externalUrl);
1071
1103
  if (!hasPrimaryCta) {
1072
1104
  return null;
1073
1105
  }
1074
- return /* @__PURE__ */ React11.createElement(Box7, { display: "flex", alignItems: "center", gap: 1, mt: 1 }, /* @__PURE__ */ React11.createElement(
1106
+ return /* @__PURE__ */ React12.createElement(Box7, { display: "flex", alignItems: "center", gap: 1, mt: 1 }, /* @__PURE__ */ React12.createElement(
1075
1107
  ViolationCtaButton,
1076
1108
  {
1077
1109
  ctaLabel: violation.ctaLabel,
1078
1110
  externalUrl: violation.externalUrl,
1079
1111
  withIcon: true
1080
1112
  }
1081
- ), violation.secondaryCtaLabel && violation.secondaryCtaUrl && /* @__PURE__ */ React11.createElement(
1113
+ ), violation.secondaryCtaLabel && violation.secondaryCtaUrl && /* @__PURE__ */ React12.createElement(
1082
1114
  ViolationCtaButton,
1083
1115
  {
1084
1116
  ctaLabel: violation.secondaryCtaLabel,
@@ -1096,7 +1128,7 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
1096
1128
  focusViolation(primaryViolation);
1097
1129
  }
1098
1130
  };
1099
- return /* @__PURE__ */ React11.createElement(Box7, { sx: { borderBottom: 1, borderColor: "divider", paddingBlock: 0.5 } }, /* @__PURE__ */ React11.createElement(Box7, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React11.createElement(
1131
+ return /* @__PURE__ */ React12.createElement(Box7, { sx: { borderBottom: 1, borderColor: "divider", paddingBlock: 0.5 } }, /* @__PURE__ */ React12.createElement(Box7, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React12.createElement(
1100
1132
  Box7,
1101
1133
  {
1102
1134
  sx: {
@@ -1109,16 +1141,16 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
1109
1141
  },
1110
1142
  onClick: onToggleExpand
1111
1143
  },
1112
- /* @__PURE__ */ React11.createElement(Typography6, { variant: "subtitle2", color: "text.secondary", sx: { flex: 1 } }, audit26.title),
1113
- !skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit26, violations })
1114
- ), skipReason && /* @__PURE__ */ React11.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React11.createElement(
1144
+ /* @__PURE__ */ React12.createElement(Typography6, { variant: "subtitle2", color: "text.secondary", sx: { flex: 1 } }, audit26.title),
1145
+ !skipReason && /* @__PURE__ */ React12.createElement(StatusIndicator, { audit: audit26, violations })
1146
+ ), skipReason && /* @__PURE__ */ React12.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React12.createElement(
1115
1147
  IconButton5,
1116
1148
  {
1117
1149
  size: "small",
1118
1150
  "aria-label": expanded ? __10("Collapse", "elementor") : __10("Expand", "elementor"),
1119
1151
  onClick: onToggleExpand
1120
1152
  },
1121
- /* @__PURE__ */ React11.createElement(
1153
+ /* @__PURE__ */ React12.createElement(
1122
1154
  ChevronDownIcon2,
1123
1155
  {
1124
1156
  fontSize: "small",
@@ -1128,24 +1160,24 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
1128
1160
  }
1129
1161
  }
1130
1162
  )
1131
- )), /* @__PURE__ */ React11.createElement(Collapse2, { in: expanded }, /* @__PURE__ */ React11.createElement(Box7, { paddingBlock: 1 }, /* @__PURE__ */ React11.createElement(Tooltip3, { title: audit26.fixHint, placement: "top" }, /* @__PURE__ */ React11.createElement(
1163
+ )), /* @__PURE__ */ React12.createElement(Collapse2, { in: expanded }, /* @__PURE__ */ React12.createElement(Box7, { paddingBlock: 1 }, /* @__PURE__ */ React12.createElement(Tooltip3, { title: audit26.fixHint, placement: "top" }, /* @__PURE__ */ React12.createElement(
1132
1164
  Alert,
1133
1165
  {
1134
1166
  severity: "secondary",
1135
1167
  sx: { p: 1, cursor: isGuidanceFocusable ? "pointer" : void 0 },
1136
- icon: /* @__PURE__ */ React11.createElement(InfoCircleIcon, { fontSize: "small", "aria-hidden": true }),
1168
+ icon: /* @__PURE__ */ React12.createElement(InfoCircleIcon, { fontSize: "small", "aria-hidden": true }),
1137
1169
  role: isGuidanceFocusable ? "button" : void 0,
1138
1170
  tabIndex: isGuidanceFocusable ? 0 : void 0,
1139
1171
  onClick: isGuidanceFocusable ? handleGuidanceClick : void 0,
1140
1172
  onKeyDown: isGuidanceFocusable ? onKeyboardClick(handleGuidanceClick) : void 0
1141
1173
  },
1142
- /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit26.description),
1143
- primaryViolation && /* @__PURE__ */ React11.createElement(GuidanceAction, { violation: primaryViolation })
1144
- ))), violations && violations.length > 0 && /* @__PURE__ */ React11.createElement(Box7, { role: "list", sx: { paddingBlockEnd: 1 } }, violations.map((violation, idx) => {
1174
+ /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit26.description),
1175
+ primaryViolation && /* @__PURE__ */ React12.createElement(GuidanceAction, { violation: primaryViolation })
1176
+ ))), violations && violations.length > 0 && /* @__PURE__ */ React12.createElement(Box7, { role: "list", sx: { paddingBlockEnd: 1 } }, violations.map((violation, idx) => {
1145
1177
  const widgetIcon = violation.elementId ? getElementIcon(violation.elementId) : null;
1146
1178
  const elementTitle = violation.elementId ? getElementTitle(violation.elementId) : null;
1147
1179
  const rowLabel = elementTitle ? `${elementTitle} - ${violation.label}` : violation.label;
1148
- return /* @__PURE__ */ React11.createElement(
1180
+ return /* @__PURE__ */ React12.createElement(
1149
1181
  Box7,
1150
1182
  {
1151
1183
  key: idx,
@@ -1164,15 +1196,15 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
1164
1196
  "&:hover": { bgcolor: "action.hover" }
1165
1197
  }
1166
1198
  },
1167
- /* @__PURE__ */ React11.createElement(ViolationIcon, { violation, widgetIcon }),
1168
- /* @__PURE__ */ React11.createElement(Box7, { sx: { flex: 1 } }, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption" }, rowLabel), violation.detail && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary" }, violation.detail)),
1169
- violation.angieFix ? /* @__PURE__ */ React11.createElement(
1199
+ /* @__PURE__ */ React12.createElement(ViolationIcon, { violation, widgetIcon }),
1200
+ /* @__PURE__ */ React12.createElement(Box7, { sx: { flex: 1 } }, /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption" }, rowLabel), violation.detail && /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption", color: "text.secondary" }, violation.detail)),
1201
+ violation.angieFix ? /* @__PURE__ */ React12.createElement(
1170
1202
  FixViolationWithAngie,
1171
1203
  {
1172
1204
  prompt: violation.angiePrompt ?? buildAngiePrompt(rowLabel),
1173
1205
  panelZIndex
1174
1206
  }
1175
- ) : /* @__PURE__ */ React11.createElement(WandIcon2, { fontSize: "tiny", "aria-hidden": true })
1207
+ ) : /* @__PURE__ */ React12.createElement(WandIcon2, { fontSize: "tiny", "aria-hidden": true })
1176
1208
  );
1177
1209
  }))));
1178
1210
  }
@@ -1182,15 +1214,15 @@ function CategoryPage({ category, report, onBack }) {
1182
1214
  const Icon = CATEGORY_ICONS[category];
1183
1215
  const { failed, passed, skipped, totalViolations } = partitionAuditResults(report, { category });
1184
1216
  const { expandedId, toggle } = useSingleExpandedCard();
1185
- return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(
1217
+ return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
1186
1218
  SubpageHeader,
1187
1219
  {
1188
1220
  title: CATEGORY_LABELS[category],
1189
1221
  onBack,
1190
1222
  backLabel: __11("Back to all issues", "elementor"),
1191
- icon: /* @__PURE__ */ React12.createElement(Icon, { fontSize: "small", color: "action" })
1223
+ icon: /* @__PURE__ */ React13.createElement(Icon, { fontSize: "small", color: "action" })
1192
1224
  }
1193
- ), /* @__PURE__ */ React12.createElement(Box8, { sx: { p: 1 } }, /* @__PURE__ */ React12.createElement(
1225
+ ), /* @__PURE__ */ React13.createElement(Box8, { sx: { p: 1 } }, /* @__PURE__ */ React13.createElement(
1194
1226
  StatusSection,
1195
1227
  {
1196
1228
  label: __11("Failed audits", "elementor"),
@@ -1198,7 +1230,7 @@ function CategoryPage({ category, report, onBack }) {
1198
1230
  color: "error",
1199
1231
  defaultExpanded: true
1200
1232
  },
1201
- failed.map((r) => /* @__PURE__ */ React12.createElement(
1233
+ failed.map((r) => /* @__PURE__ */ React13.createElement(
1202
1234
  ViolationRow,
1203
1235
  {
1204
1236
  key: r.audit.id,
@@ -1208,7 +1240,7 @@ function CategoryPage({ category, report, onBack }) {
1208
1240
  onToggleExpand: () => toggle(r.audit.id)
1209
1241
  }
1210
1242
  ))
1211
- ), /* @__PURE__ */ React12.createElement(StatusSection, { label: __11("Passed audits", "elementor"), count: passed.length, color: "success" }, passed.map((r) => /* @__PURE__ */ React12.createElement(
1243
+ ), /* @__PURE__ */ React13.createElement(StatusSection, { label: __11("Passed audits", "elementor"), count: passed.length, color: "success" }, passed.map((r) => /* @__PURE__ */ React13.createElement(
1212
1244
  ViolationRow,
1213
1245
  {
1214
1246
  key: r.audit.id,
@@ -1216,7 +1248,7 @@ function CategoryPage({ category, report, onBack }) {
1216
1248
  expanded: expandedId === r.audit.id,
1217
1249
  onToggleExpand: () => toggle(r.audit.id)
1218
1250
  }
1219
- ))), /* @__PURE__ */ React12.createElement(StatusSection, { label: __11("Skipped audits", "elementor"), count: skipped.length, color: "default" }, skipped.map((r) => /* @__PURE__ */ React12.createElement(
1251
+ ))), /* @__PURE__ */ React13.createElement(StatusSection, { label: __11("Skipped audits", "elementor"), count: skipped.length, color: "default" }, skipped.map((r) => /* @__PURE__ */ React13.createElement(
1220
1252
  ViolationRow,
1221
1253
  {
1222
1254
  key: r.audit.id,
@@ -1229,7 +1261,7 @@ function CategoryPage({ category, report, onBack }) {
1229
1261
  }
1230
1262
 
1231
1263
  // src/components/pages/overview-page.tsx
1232
- import * as React17 from "react";
1264
+ import * as React18 from "react";
1233
1265
  import { Box as Box13, Typography as Typography11 } from "@elementor/ui";
1234
1266
  import { __ as __15 } from "@wordpress/i18n";
1235
1267
 
@@ -1264,13 +1296,13 @@ function severityPluralLabel(severity) {
1264
1296
  }
1265
1297
 
1266
1298
  // src/components/issues-category-row.tsx
1267
- import * as React13 from "react";
1299
+ import * as React14 from "react";
1268
1300
  import { ChevronRightIcon } from "@elementor/icons";
1269
1301
  import { Box as Box9, Rotate as Rotate2, Typography as Typography7, useTheme as useTheme2 } from "@elementor/ui";
1270
1302
  function IssuesCategoryRow({ category, label, counts, onClick }) {
1271
1303
  const isRtl = "rtl" === useTheme2().direction;
1272
1304
  const Icon = CATEGORY_ICONS[category];
1273
- return /* @__PURE__ */ React13.createElement(
1305
+ return /* @__PURE__ */ React14.createElement(
1274
1306
  Box9,
1275
1307
  {
1276
1308
  role: "button",
@@ -1292,15 +1324,15 @@ function IssuesCategoryRow({ category, label, counts, onClick }) {
1292
1324
  "&:focus-visible": { outline: "2px solid", outlineColor: "primary.main" }
1293
1325
  }
1294
1326
  },
1295
- /* @__PURE__ */ React13.createElement(Icon, { fontSize: "small", color: "action" }),
1296
- /* @__PURE__ */ React13.createElement(Typography7, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1297
- /* @__PURE__ */ React13.createElement(Box9, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React13.createElement(Box9, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React13.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React13.createElement(Typography7, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
1298
- /* @__PURE__ */ React13.createElement(Rotate2, { in: isRtl }, /* @__PURE__ */ React13.createElement(ChevronRightIcon, { fontSize: "small", color: "action" }))
1327
+ /* @__PURE__ */ React14.createElement(Icon, { fontSize: "small", color: "action" }),
1328
+ /* @__PURE__ */ React14.createElement(Typography7, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1329
+ /* @__PURE__ */ React14.createElement(Box9, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React14.createElement(Box9, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React14.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React14.createElement(Typography7, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
1330
+ /* @__PURE__ */ React14.createElement(Rotate2, { in: isRtl }, /* @__PURE__ */ React14.createElement(ChevronRightIcon, { fontSize: "small", color: "action" }))
1299
1331
  );
1300
1332
  }
1301
1333
 
1302
1334
  // src/components/promotions.tsx
1303
- import * as React15 from "react";
1335
+ import * as React16 from "react";
1304
1336
  import { Box as Box11, Divider, Typography as Typography9 } from "@elementor/ui";
1305
1337
  import { __ as __14 } from "@wordpress/i18n";
1306
1338
 
@@ -1373,10 +1405,10 @@ function findAuditRun(report, auditId) {
1373
1405
  }
1374
1406
 
1375
1407
  // src/components/promotion-card.tsx
1376
- import * as React14 from "react";
1408
+ import * as React15 from "react";
1377
1409
  import { Box as Box10, Button as Button4, Typography as Typography8 } from "@elementor/ui";
1378
1410
  function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle, title }) {
1379
- return /* @__PURE__ */ React14.createElement(
1411
+ return /* @__PURE__ */ React15.createElement(
1380
1412
  Box10,
1381
1413
  {
1382
1414
  sx: {
@@ -1390,9 +1422,9 @@ function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle
1390
1422
  py: 1.5
1391
1423
  }
1392
1424
  },
1393
- /* @__PURE__ */ React14.createElement(Icon, { fontSize: "small", color: "action" }),
1394
- /* @__PURE__ */ React14.createElement(Box10, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React14.createElement(Typography8, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React14.createElement(Typography8, { variant: "caption", color: "text.secondary" }, subtitle)),
1395
- /* @__PURE__ */ React14.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1425
+ /* @__PURE__ */ React15.createElement(Icon, { fontSize: "small", color: "action" }),
1426
+ /* @__PURE__ */ React15.createElement(Box10, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React15.createElement(Typography8, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React15.createElement(Typography8, { variant: "caption", color: "text.secondary" }, subtitle)),
1427
+ /* @__PURE__ */ React15.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1396
1428
  );
1397
1429
  }
1398
1430
 
@@ -1421,7 +1453,7 @@ function Promotions({ report }) {
1421
1453
  if (cards.length === 0) {
1422
1454
  return null;
1423
1455
  }
1424
- return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Divider, null), /* @__PURE__ */ React15.createElement(Typography9, { variant: "subtitle1", fontWeight: "bold" }, __14("Quick actions", "elementor")), /* @__PURE__ */ React15.createElement(Box11, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React15.createElement(
1456
+ return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Divider, null), /* @__PURE__ */ React16.createElement(Typography9, { variant: "subtitle1", fontWeight: "bold" }, __14("Quick actions", "elementor")), /* @__PURE__ */ React16.createElement(Box11, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React16.createElement(
1425
1457
  PromotionCard,
1426
1458
  {
1427
1459
  key,
@@ -1440,14 +1472,14 @@ function Promotions({ report }) {
1440
1472
  }
1441
1473
 
1442
1474
  // src/components/severity-summary-cards.tsx
1443
- import * as React16 from "react";
1475
+ import * as React17 from "react";
1444
1476
  import { Box as Box12, Typography as Typography10 } from "@elementor/ui";
1445
1477
  function SeveritySummaryCards({ report }) {
1446
1478
  const counts = countSeverities(report);
1447
- return /* @__PURE__ */ React16.createElement(Box12, { display: "flex", gap: 1.5 }, ALL_SEVERITIES.map((severity) => /* @__PURE__ */ React16.createElement(SeverityCard, { key: severity, severity, count: counts[severity] })));
1479
+ return /* @__PURE__ */ React17.createElement(Box12, { display: "flex", gap: 1.5 }, ALL_SEVERITIES.map((severity) => /* @__PURE__ */ React17.createElement(SeverityCard, { key: severity, severity, count: counts[severity] })));
1448
1480
  }
1449
1481
  function SeverityCard({ severity, count }) {
1450
- return /* @__PURE__ */ React16.createElement(
1482
+ return /* @__PURE__ */ React17.createElement(
1451
1483
  Box12,
1452
1484
  {
1453
1485
  display: "flex",
@@ -1459,8 +1491,8 @@ function SeverityCard({ severity, count }) {
1459
1491
  px: 1.5,
1460
1492
  py: 1
1461
1493
  },
1462
- /* @__PURE__ */ React16.createElement(SeverityIcon, { severity }),
1463
- /* @__PURE__ */ React16.createElement(Box12, { display: "flex", flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Typography10, { variant: "h5", fontWeight: 700, component: "span" }, count), /* @__PURE__ */ React16.createElement(Typography10, { variant: "caption", color: "text.secondary" }, severityPluralLabel(severity)))
1494
+ /* @__PURE__ */ React17.createElement(SeverityIcon, { severity }),
1495
+ /* @__PURE__ */ React17.createElement(Box12, { display: "flex", flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Typography10, { variant: "h5", fontWeight: 700, component: "span" }, count), /* @__PURE__ */ React17.createElement(Typography10, { variant: "caption", color: "text.secondary" }, severityPluralLabel(severity)))
1464
1496
  );
1465
1497
  }
1466
1498
 
@@ -1468,7 +1500,7 @@ function SeverityCard({ severity, count }) {
1468
1500
  function OverviewPage({ onCategoryClick, report }) {
1469
1501
  const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1470
1502
  const categoryRows = populatedCategories.map((category) => ({ category, counts: countSeverities(report, category) })).filter(({ counts }) => Object.values(counts).some((count) => count > 0));
1471
- return /* @__PURE__ */ React17.createElement(Box13, { display: "flex", flexDirection: "column", gap: 3, p: 2 }, /* @__PURE__ */ React17.createElement(SeveritySummaryCards, { report }), /* @__PURE__ */ React17.createElement(Box13, { display: "flex", flexDirection: "column", gap: 1 }, /* @__PURE__ */ React17.createElement(Typography11, { variant: "subtitle1", component: "h2" }, __15("All issues", "elementor")), /* @__PURE__ */ React17.createElement(Box13, { display: "flex", flexDirection: "column", gap: 1 }, categoryRows.map(({ category, counts }) => /* @__PURE__ */ React17.createElement(
1503
+ return /* @__PURE__ */ React18.createElement(Box13, { display: "flex", flexDirection: "column", gap: 3, p: 2 }, /* @__PURE__ */ React18.createElement(SeveritySummaryCards, { report }), /* @__PURE__ */ React18.createElement(Box13, { display: "flex", flexDirection: "column", gap: 1 }, /* @__PURE__ */ React18.createElement(Typography11, { variant: "subtitle1", component: "h2" }, __15("All issues", "elementor")), /* @__PURE__ */ React18.createElement(Box13, { display: "flex", flexDirection: "column", gap: 1 }, categoryRows.map(({ category, counts }) => /* @__PURE__ */ React18.createElement(
1472
1504
  IssuesCategoryRow,
1473
1505
  {
1474
1506
  key: category,
@@ -1477,7 +1509,7 @@ function OverviewPage({ onCategoryClick, report }) {
1477
1509
  counts,
1478
1510
  onClick: () => onCategoryClick(category)
1479
1511
  }
1480
- )))), /* @__PURE__ */ React17.createElement(Promotions, { report }));
1512
+ )))), /* @__PURE__ */ React18.createElement(Promotions, { report }));
1481
1513
  }
1482
1514
 
1483
1515
  // src/components/report-shell.tsx
@@ -1488,42 +1520,69 @@ function ReportShell({ report }) {
1488
1520
  const [activePage, setActivePage] = useState4("overview");
1489
1521
  const openCategory = (category) => setActivePage({ category });
1490
1522
  const backToOverview = () => setActivePage("overview");
1491
- return /* @__PURE__ */ React18.createElement(Box14, { sx: { flex: 1, minHeight: 0, overflowY: "auto" } }, activePage === "overview" && /* @__PURE__ */ React18.createElement(OverviewPage, { report, onCategoryClick: openCategory }), isCategoryPage(activePage) && /* @__PURE__ */ React18.createElement(CategoryPage, { category: activePage.category, report, onBack: backToOverview }));
1523
+ return /* @__PURE__ */ React19.createElement(Box14, { sx: { flex: 1, minHeight: 0, overflowY: "auto" } }, activePage === "overview" && /* @__PURE__ */ React19.createElement(OverviewPage, { report, onCategoryClick: openCategory }), isCategoryPage(activePage) && /* @__PURE__ */ React19.createElement(CategoryPage, { category: activePage.category, report, onBack: backToOverview }));
1524
+ }
1525
+
1526
+ // src/components/rescan-button.tsx
1527
+ import * as React20 from "react";
1528
+ import { useFloatingPanelZIndex as useFloatingPanelZIndex3 } from "@elementor/editor-floating-panels";
1529
+ import { ReloadIcon } from "@elementor/icons";
1530
+ import { Badge as Badge2, Button as Button5, Tooltip as Tooltip4 } from "@elementor/ui";
1531
+ import { __ as __16 } from "@wordpress/i18n";
1532
+ function RescanButton({ hasScanned, isStale, disabled, onClick }) {
1533
+ const panelZIndex = useFloatingPanelZIndex3(AUDIT_PANEL_ID);
1534
+ return /* @__PURE__ */ React20.createElement(
1535
+ Tooltip4,
1536
+ {
1537
+ title: __16("Page content changed - rescan advised", "elementor"),
1538
+ disableHoverListener: !isStale,
1539
+ PopperProps: { sx: { zIndex: panelZIndex } }
1540
+ },
1541
+ /* @__PURE__ */ React20.createElement(Badge2, { variant: "dot", color: "warning", invisible: !isStale, overlap: "rectangular" }, /* @__PURE__ */ React20.createElement(
1542
+ Button5,
1543
+ {
1544
+ variant: "contained",
1545
+ size: "small",
1546
+ startIcon: hasScanned ? /* @__PURE__ */ React20.createElement(ReloadIcon, { fontSize: "small" }) : void 0,
1547
+ onClick,
1548
+ disabled
1549
+ },
1550
+ hasScanned ? __16("Rescan", "elementor") : __16("Run page audit", "elementor")
1551
+ ))
1552
+ );
1492
1553
  }
1493
1554
 
1494
1555
  // src/components/audit-panel.tsx
1495
1556
  function AuditPanel() {
1496
- const { status, report, error, run } = useAuditReport();
1557
+ const { status, report, error, isStale, run } = useAuditReport();
1497
1558
  const hostDocumentId = getHostDocumentId3() ?? 0;
1498
1559
  const onRun = () => run(hostDocumentId);
1499
1560
  const lastScanLabel = report ? new Date(report.runAt).toLocaleTimeString() : null;
1500
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(
1561
+ return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
1501
1562
  FloatingPanelHeader,
1502
1563
  {
1503
1564
  panelId: AUDIT_PANEL_ID,
1504
- title: __16("Page Audit", "elementor"),
1505
- badge: __16("Beta", "elementor"),
1565
+ title: __17("Page Audit", "elementor"),
1566
+ badge: __17("Beta", "elementor"),
1506
1567
  titleVariant: "subtitle2"
1507
1568
  }
1508
- ), /* @__PURE__ */ React19.createElement(
1569
+ ), /* @__PURE__ */ React21.createElement(
1509
1570
  FloatingPanelBody,
1510
1571
  {
1511
1572
  sx: status === "ready" ? { display: "flex", flexDirection: "column", overflow: "hidden", minHeight: 0 } : void 0
1512
1573
  },
1513
- status === "idle" && /* @__PURE__ */ React19.createElement(WelcomePage, null),
1514
- status === "loading" && /* @__PURE__ */ React19.createElement(LoadingPage, null),
1515
- status === "error" && /* @__PURE__ */ React19.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }),
1516
- status === "ready" && report && /* @__PURE__ */ React19.createElement(ReportShell, { report })
1517
- ), /* @__PURE__ */ React19.createElement(FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React19.createElement(Typography12, { variant: "caption", sx: { flex: 1 } }, __16("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React19.createElement(Box15, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React19.createElement(AuditFeedback, null), /* @__PURE__ */ React19.createElement(
1518
- Button5,
1574
+ status === "idle" && /* @__PURE__ */ React21.createElement(WelcomePage, null),
1575
+ status === "loading" && /* @__PURE__ */ React21.createElement(LoadingPage, null),
1576
+ status === "error" && /* @__PURE__ */ React21.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }),
1577
+ status === "ready" && report && /* @__PURE__ */ React21.createElement(ReportShell, { report })
1578
+ ), /* @__PURE__ */ React21.createElement(FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React21.createElement(Typography12, { variant: "caption", sx: { flex: 1 } }, __17("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React21.createElement(Box15, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React21.createElement(AuditFeedback, null), /* @__PURE__ */ React21.createElement(
1579
+ RescanButton,
1519
1580
  {
1520
- variant: "contained",
1521
- size: "small",
1522
- startIcon: lastScanLabel ? /* @__PURE__ */ React19.createElement(ReloadIcon, { fontSize: "small" }) : void 0,
1523
- onClick: onRun,
1524
- disabled: status === "loading" || hostDocumentId === 0
1525
- },
1526
- lastScanLabel ? __16("Rescan", "elementor") : __16("Run page audit", "elementor")
1581
+ hasScanned: Boolean(lastScanLabel),
1582
+ isStale,
1583
+ disabled: status === "loading" || hostDocumentId === 0,
1584
+ onClick: onRun
1585
+ }
1527
1586
  )));
1528
1587
  }
1529
1588
 
@@ -1548,8 +1607,8 @@ function useAuditToggleProps() {
1548
1607
  const { isOpen } = auditPanel.useFloatingPanelStatus();
1549
1608
  const { toggle } = auditPanel.useFloatingPanelActions();
1550
1609
  return {
1551
- title: __17("Audit Page", "elementor"),
1552
- icon: ShieldCheckIcon2,
1610
+ title: __18("Audit Page", "elementor"),
1611
+ icon: AuditToggleIcon,
1553
1612
  selected: isOpen,
1554
1613
  onClick: () => toggle()
1555
1614
  };
@@ -1566,15 +1625,15 @@ function registerAppBarAuditsToggle() {
1566
1625
  }
1567
1626
 
1568
1627
  // src/audits/accessibility-policy.ts
1569
- import { __ as __18 } from "@wordpress/i18n";
1628
+ import { __ as __19 } from "@wordpress/i18n";
1570
1629
  var audit = {
1571
1630
  id: "audits/accessibility-policy",
1572
- title: __18("Accessibility policy", "elementor"),
1573
- description: __18(
1631
+ title: __19("Accessibility policy", "elementor"),
1632
+ description: __19(
1574
1633
  "An accessibility policy demonstrates your commitment to digital inclusion and may be legally required in some regions.",
1575
1634
  "elementor"
1576
1635
  ),
1577
- fixHint: __18("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1636
+ fixHint: __19("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1578
1637
  categories: ["compliance"],
1579
1638
  severity: "info",
1580
1639
  weight: 1,
@@ -1587,7 +1646,7 @@ var audit = {
1587
1646
  violations: [
1588
1647
  {
1589
1648
  auditId: audit.id,
1590
- label: __18("Ally plugin is not installed or active.", "elementor"),
1649
+ label: __19("Ally plugin is not installed or active.", "elementor"),
1591
1650
  externalUrl: ctx.pageContext.ally_plugin_url
1592
1651
  }
1593
1652
  ]
@@ -1596,15 +1655,15 @@ var audit = {
1596
1655
  };
1597
1656
 
1598
1657
  // src/audits/accessibility-statement.ts
1599
- import { __ as __19 } from "@wordpress/i18n";
1658
+ import { __ as __20 } from "@wordpress/i18n";
1600
1659
  var audit2 = {
1601
1660
  id: "audits/accessibility-statement",
1602
- title: __19("Create an accessibility statement", "elementor"),
1603
- description: __19(
1661
+ title: __20("Create an accessibility statement", "elementor"),
1662
+ description: __20(
1604
1663
  "An accessibility statement showcases your efforts to create an inclusive online space, highlighting helpful features and a commitment to accessibility.",
1605
1664
  "elementor"
1606
1665
  ),
1607
- fixHint: __19("Use Ally to create and publish an accessibility statement for your site.", "elementor"),
1666
+ fixHint: __20("Use Ally to create and publish an accessibility statement for your site.", "elementor"),
1608
1667
  categories: ["accessibility"],
1609
1668
  severity: "info",
1610
1669
  weight: 1,
@@ -1618,10 +1677,10 @@ var audit2 = {
1618
1677
  violations: [
1619
1678
  {
1620
1679
  auditId: audit2.id,
1621
- label: __19("No accessibility statement has been created for this site.", "elementor"),
1680
+ label: __20("No accessibility statement has been created for this site.", "elementor"),
1622
1681
  externalUrl: isReady ? ctx.pageContext.ally_accessibility_statement_url : ctx.pageContext.ally_plugin_url,
1623
- ctaLabel: __19("Create", "elementor"),
1624
- secondaryCtaLabel: __19("Learn more", "elementor"),
1682
+ ctaLabel: __20("Create", "elementor"),
1683
+ secondaryCtaLabel: __20("Learn more", "elementor"),
1625
1684
  secondaryCtaUrl: "https://elementor.com/help/start-using-ally/#statement"
1626
1685
  }
1627
1686
  ]
@@ -1630,7 +1689,7 @@ var audit2 = {
1630
1689
  };
1631
1690
 
1632
1691
  // src/audits/accessibility-widget.ts
1633
- import { __ as __20 } from "@wordpress/i18n";
1692
+ import { __ as __21 } from "@wordpress/i18n";
1634
1693
 
1635
1694
  // src/utils/scan-accessibility-widgets.ts
1636
1695
  var ACCESSIBILITY_WIDGET_SCRIPT_SOURCES = ["cdn.elementor.com/a11y/widget.js"];
@@ -1641,18 +1700,18 @@ function hasAccessibilityWidgetScript(html) {
1641
1700
  // src/audits/accessibility-widget.ts
1642
1701
  var audit3 = {
1643
1702
  id: "audits/accessibility-widget",
1644
- title: __20("Add an accessibility widget", "elementor"),
1645
- description: __20("Make your site more inclusive by adding an accessibility widget.", "elementor"),
1646
- fixHint: __20("Activate Ally\u2019s accessibility widget to give visitors on-page accessibility tools.", "elementor"),
1703
+ title: __21("Add an accessibility widget", "elementor"),
1704
+ description: __21("Make your site more inclusive by adding an accessibility widget.", "elementor"),
1705
+ fixHint: __21("Activate Ally\u2019s accessibility widget to give visitors on-page accessibility tools.", "elementor"),
1647
1706
  categories: ["accessibility"],
1648
1707
  severity: "info",
1649
1708
  weight: 1,
1650
1709
  evaluate: (ctx) => {
1651
1710
  if (!ctx.pageContext.frontend_url) {
1652
- return { status: "skipped", reason: __20("Page is not published.", "elementor") };
1711
+ return { status: "skipped", reason: __21("Page is not published.", "elementor") };
1653
1712
  }
1654
1713
  if (!ctx.renderedHtml) {
1655
- return { status: "skipped", reason: __20("Could not fetch the published page.", "elementor") };
1714
+ return { status: "skipped", reason: __21("Could not fetch the published page.", "elementor") };
1656
1715
  }
1657
1716
  if (hasAccessibilityWidgetScript(ctx.renderedHtml)) {
1658
1717
  return { status: "pass" };
@@ -1663,9 +1722,9 @@ var audit3 = {
1663
1722
  violations: [
1664
1723
  {
1665
1724
  auditId: audit3.id,
1666
- label: __20("No accessibility widget is active on this site.", "elementor"),
1725
+ label: __21("No accessibility widget is active on this site.", "elementor"),
1667
1726
  externalUrl: isReady ? ctx.pageContext.ally_widget_settings_url : ctx.pageContext.ally_plugin_url,
1668
- ctaLabel: __20("Activate", "elementor")
1727
+ ctaLabel: __21("Activate", "elementor")
1669
1728
  }
1670
1729
  ]
1671
1730
  };
@@ -1673,15 +1732,15 @@ var audit3 = {
1673
1732
  };
1674
1733
 
1675
1734
  // src/audits/cookie-policy.ts
1676
- import { __ as __21 } from "@wordpress/i18n";
1735
+ import { __ as __22 } from "@wordpress/i18n";
1677
1736
  var audit4 = {
1678
1737
  id: "audits/cookie-policy",
1679
- title: __21("Cookie policy", "elementor"),
1680
- description: __21(
1738
+ title: __22("Cookie policy", "elementor"),
1739
+ description: __22(
1681
1740
  "A cookie policy is required by privacy regulations such as GDPR (EU) or CCPA (US) to inform visitors about tracking and data collection.",
1682
1741
  "elementor"
1683
1742
  ),
1684
- fixHint: __21("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1743
+ fixHint: __22("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1685
1744
  categories: ["compliance"],
1686
1745
  severity: "info",
1687
1746
  weight: 1,
@@ -1694,9 +1753,9 @@ var audit4 = {
1694
1753
  violations: [
1695
1754
  {
1696
1755
  auditId: audit4.id,
1697
- label: __21("Cookiez plugin is not installed or active.", "elementor"),
1756
+ label: __22("Cookiez plugin is not installed or active.", "elementor"),
1698
1757
  externalUrl: ctx.pageContext.cookiez_plugin_url,
1699
- ctaLabel: __21("Set up cookie consent", "elementor")
1758
+ ctaLabel: __22("Set up cookie consent", "elementor")
1700
1759
  }
1701
1760
  ]
1702
1761
  };
@@ -1705,7 +1764,7 @@ var audit4 = {
1705
1764
 
1706
1765
  // src/audits/deep-nesting.ts
1707
1766
  import { getWidgetsCache } from "@elementor/editor-elements";
1708
- import { __ as __22 } from "@wordpress/i18n";
1767
+ import { __ as __23 } from "@wordpress/i18n";
1709
1768
  var MAX_NESTING_DEPTH = 6;
1710
1769
  function isNestingElement(node, widgetsCache) {
1711
1770
  if (node.elType === "container") {
@@ -1715,18 +1774,18 @@ function isNestingElement(node, widgetsCache) {
1715
1774
  }
1716
1775
  var audit5 = {
1717
1776
  id: "audits/deep-nesting",
1718
- title: __22("Deep container nesting", "elementor"),
1719
- description: __22(
1777
+ title: __23("Deep container nesting", "elementor"),
1778
+ description: __23(
1720
1779
  "Container nesting exceeds the recommended depth. Deep DOM trees hurt rendering performance and readability.",
1721
1780
  "elementor"
1722
1781
  ),
1723
- fixHint: __22("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1782
+ fixHint: __23("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1724
1783
  categories: ["performance", "best-practices"],
1725
1784
  severity: "warning",
1726
1785
  weight: 5,
1727
1786
  evaluate: (ctx) => {
1728
1787
  if (ctx.elements.tree.length === 0) {
1729
- return { status: "skipped", reason: __22("No elements", "elementor") };
1788
+ return { status: "skipped", reason: __23("No elements", "elementor") };
1730
1789
  }
1731
1790
  const widgetsCache = getWidgetsCache();
1732
1791
  const violations = [];
@@ -1740,7 +1799,7 @@ var audit5 = {
1740
1799
  auditId: audit5.id,
1741
1800
  elementId: node.id,
1742
1801
  targetHint: "element-settings",
1743
- label: __22("Container nesting is too deep.", "elementor")
1802
+ label: __23("Container nesting is too deep.", "elementor")
1744
1803
  });
1745
1804
  }
1746
1805
  });
@@ -1749,15 +1808,15 @@ var audit5 = {
1749
1808
  };
1750
1809
 
1751
1810
  // src/audits/default-design-system.ts
1752
- import { __ as __23 } from "@wordpress/i18n";
1811
+ import { __ as __24 } from "@wordpress/i18n";
1753
1812
  var audit6 = {
1754
1813
  id: "audits/default-design-system",
1755
- title: __23("Default website kit", "elementor"),
1756
- description: __23(
1814
+ title: __24("Default website kit", "elementor"),
1815
+ description: __24(
1757
1816
  "Your website is using the default design system colors and fonts. Custom branding makes the website feel uniquely yours.",
1758
1817
  "elementor"
1759
1818
  ),
1760
- fixHint: __23("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1819
+ fixHint: __24("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1761
1820
  categories: ["best-practices"],
1762
1821
  severity: "info",
1763
1822
  weight: 1,
@@ -1770,7 +1829,7 @@ var audit6 = {
1770
1829
  violations: [
1771
1830
  {
1772
1831
  auditId: audit6.id,
1773
- label: __23("Kit appears unchanged from default.", "elementor"),
1832
+ label: __24("Kit appears unchanged from default.", "elementor"),
1774
1833
  targetHint: "site-settings"
1775
1834
  }
1776
1835
  ]
@@ -1780,16 +1839,16 @@ var audit6 = {
1780
1839
 
1781
1840
  // src/audits/deprecated-widgets.ts
1782
1841
  import { getWidgetsCache as getWidgetsCache2 } from "@elementor/editor-elements";
1783
- import { __ as __24 } from "@wordpress/i18n";
1842
+ import { __ as __25 } from "@wordpress/i18n";
1784
1843
  var DEPRECATION_CONTROL_NAME = "deprecation_message";
1785
1844
  var audit7 = {
1786
1845
  id: "audits/deprecated-widgets",
1787
- title: __24("Deprecated widgets", "elementor"),
1788
- description: __24(
1846
+ title: __25("Deprecated widgets", "elementor"),
1847
+ description: __25(
1789
1848
  "Deprecated widgets should not be used. For better capabilities use the recommended replacement.",
1790
1849
  "elementor"
1791
1850
  ),
1792
- fixHint: __24("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1851
+ fixHint: __25("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1793
1852
  categories: ["best-practices", "performance"],
1794
1853
  severity: "warning",
1795
1854
  weight: 7,
@@ -1816,7 +1875,7 @@ var audit7 = {
1816
1875
  auditId: audit7.id,
1817
1876
  elementId: node.id,
1818
1877
  targetHint: "element-settings",
1819
- label: __24("Using deprecated widget.", "elementor")
1878
+ label: __25("Using deprecated widget.", "elementor")
1820
1879
  });
1821
1880
  });
1822
1881
  return violations.length === 0 ? { status: "pass" } : { status: "fail", violations };
@@ -1824,7 +1883,7 @@ var audit7 = {
1824
1883
  };
1825
1884
 
1826
1885
  // src/audits/google-consent-mode.ts
1827
- import { __ as __25 } from "@wordpress/i18n";
1886
+ import { __ as __26 } from "@wordpress/i18n";
1828
1887
 
1829
1888
  // src/utils/scan-consent-signals.ts
1830
1889
  var GOOGLE_TRACKING_PATTERNS = [
@@ -1847,12 +1906,12 @@ function hasConsentDefaultCall(html) {
1847
1906
  // src/audits/google-consent-mode.ts
1848
1907
  var audit8 = {
1849
1908
  id: "audits/google-consent-mode",
1850
- title: __25("Google Consent Mode", "elementor"),
1851
- description: __25(
1909
+ title: __26("Google Consent Mode", "elementor"),
1910
+ description: __26(
1852
1911
  "Google Analytics, Ads, or Tag Manager are running on this site and may not receive a consent signal, which risks losing conversion/analytics data and compliance exposure.",
1853
1912
  "elementor"
1854
1913
  ),
1855
- fixHint: __25(
1914
+ fixHint: __26(
1856
1915
  "Turn on Google Consent Mode in your cookie consent plugin so Google tags respect visitor consent choices.",
1857
1916
  "elementor"
1858
1917
  ),
@@ -1861,18 +1920,18 @@ var audit8 = {
1861
1920
  weight: 1,
1862
1921
  evaluate: (ctx) => {
1863
1922
  if (!ctx.pageContext.frontend_url) {
1864
- return { status: "skipped", reason: __25("Page is not published.", "elementor") };
1923
+ return { status: "skipped", reason: __26("Page is not published.", "elementor") };
1865
1924
  }
1866
1925
  if (!ctx.renderedHtml) {
1867
- return { status: "skipped", reason: __25("Could not fetch the published page.", "elementor") };
1926
+ return { status: "skipped", reason: __26("Could not fetch the published page.", "elementor") };
1868
1927
  }
1869
1928
  if (!hasGoogleTracking(ctx.renderedHtml)) {
1870
- return { status: "skipped", reason: __25("No Google tracking product detected.", "elementor") };
1929
+ return { status: "skipped", reason: __26("No Google tracking product detected.", "elementor") };
1871
1930
  }
1872
1931
  if (hasConsentDefaultCall(ctx.renderedHtml)) {
1873
1932
  return { status: "pass" };
1874
1933
  }
1875
- const label = __25("No Google Consent Mode signal was found on the page.", "elementor");
1934
+ const label = __26("No Google Consent Mode signal was found on the page.", "elementor");
1876
1935
  const isCookiezReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
1877
1936
  if (isCookiezReady) {
1878
1937
  return {
@@ -1881,7 +1940,7 @@ var audit8 = {
1881
1940
  {
1882
1941
  auditId: audit8.id,
1883
1942
  label,
1884
- ctaLabel: __25("Enable", "elementor"),
1943
+ ctaLabel: __26("Enable", "elementor"),
1885
1944
  externalUrl: ctx.pageContext.cookiez_consent_mode_settings_url
1886
1945
  }
1887
1946
  ]
@@ -1901,7 +1960,7 @@ var audit8 = {
1901
1960
  };
1902
1961
 
1903
1962
  // src/audits/heading-structure.ts
1904
- import { __ as __26 } from "@wordpress/i18n";
1963
+ import { __ as __27 } from "@wordpress/i18n";
1905
1964
  var HEADING_LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
1906
1965
  var HEADING_CONTROLS_REGISTRY = {
1907
1966
  // Core
@@ -2079,27 +2138,27 @@ function extractPageHeadings(tree) {
2079
2138
  }
2080
2139
  var audit9 = {
2081
2140
  id: "audits/heading-structure",
2082
- title: __26("Heading structure", "elementor"),
2083
- description: __26("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2084
- fixHint: __26("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2141
+ title: __27("Heading structure", "elementor"),
2142
+ description: __27("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2143
+ fixHint: __27("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2085
2144
  categories: ["seo", "accessibility"],
2086
2145
  severity: "error",
2087
2146
  weight: 10,
2088
2147
  evaluate: (ctx) => {
2089
2148
  if (ctx.elements.tree.length === 0) {
2090
- return { status: "skipped", reason: __26("No elements", "elementor") };
2149
+ return { status: "skipped", reason: __27("No elements", "elementor") };
2091
2150
  }
2092
2151
  const headings = extractPageHeadings(ctx.elements.tree);
2093
2152
  const violations = [];
2094
2153
  if (headings.length === 0) {
2095
2154
  violations.push({
2096
2155
  auditId: audit9.id,
2097
- label: __26("No headings found on the page.", "elementor")
2156
+ label: __27("No headings found on the page.", "elementor")
2098
2157
  });
2099
2158
  } else {
2100
2159
  const h1Count = headings.filter((h) => h.level === 1).length;
2101
2160
  if (h1Count === 0) {
2102
- violations.push({ auditId: audit9.id, label: __26("No H1 on the page.", "elementor") });
2161
+ violations.push({ auditId: audit9.id, label: __27("No H1 on the page.", "elementor") });
2103
2162
  }
2104
2163
  if (h1Count > 1) {
2105
2164
  headings.filter((h) => h.level === 1).slice(1).forEach(
@@ -2107,7 +2166,7 @@ var audit9 = {
2107
2166
  auditId: audit9.id,
2108
2167
  elementId: h.elementId,
2109
2168
  targetHint: "element-settings",
2110
- label: __26("More than one H1 on the page.", "elementor")
2169
+ label: __27("More than one H1 on the page.", "elementor")
2111
2170
  })
2112
2171
  );
2113
2172
  }
@@ -2117,7 +2176,7 @@ var audit9 = {
2117
2176
  auditId: audit9.id,
2118
2177
  elementId: headings[i].elementId,
2119
2178
  targetHint: "element-settings",
2120
- label: __26("Heading level skipped.", "elementor")
2179
+ label: __27("Heading level skipped.", "elementor")
2121
2180
  });
2122
2181
  }
2123
2182
  }
@@ -2127,24 +2186,24 @@ var audit9 = {
2127
2186
  };
2128
2187
 
2129
2188
  // src/audits/hidden-elements.ts
2130
- import { __ as __27 } from "@wordpress/i18n";
2189
+ import { __ as __28 } from "@wordpress/i18n";
2131
2190
  function isHiddenOnAllDevices(settings) {
2132
2191
  return Boolean(settings.hide_desktop) && Boolean(settings.hide_tablet) && Boolean(settings.hide_mobile);
2133
2192
  }
2134
2193
  var audit10 = {
2135
2194
  id: "audits/hidden-elements",
2136
- title: __27("Hidden elements", "elementor"),
2137
- description: __27(
2195
+ title: __28("Hidden elements", "elementor"),
2196
+ description: __28(
2138
2197
  "Elements hidden on all devices simultaneously are effectively dead code in the page tree.",
2139
2198
  "elementor"
2140
2199
  ),
2141
- fixHint: __27("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2200
+ fixHint: __28("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2142
2201
  categories: ["best-practices", "performance"],
2143
2202
  severity: "info",
2144
2203
  weight: 3,
2145
2204
  evaluate: (ctx) => {
2146
2205
  if (ctx.elements.tree.length === 0) {
2147
- return { status: "skipped", reason: __27("No elements", "elementor") };
2206
+ return { status: "skipped", reason: __28("No elements", "elementor") };
2148
2207
  }
2149
2208
  const violations = [];
2150
2209
  walkElements(ctx.elements.tree, (node) => {
@@ -2153,7 +2212,7 @@ var audit10 = {
2153
2212
  auditId: audit10.id,
2154
2213
  elementId: node.id,
2155
2214
  targetHint: "element-settings",
2156
- label: __27("Element is hidden on all devices.", "elementor")
2215
+ label: __28("Element is hidden on all devices.", "elementor")
2157
2216
  });
2158
2217
  }
2159
2218
  });
@@ -2162,7 +2221,7 @@ var audit10 = {
2162
2221
  };
2163
2222
 
2164
2223
  // src/audits/images-alt-text.ts
2165
- import { __ as __28 } from "@wordpress/i18n";
2224
+ import { __ as __29 } from "@wordpress/i18n";
2166
2225
 
2167
2226
  // src/utils/image-alt.ts
2168
2227
  function hasMeaningfulAlt(media, pageContext) {
@@ -2183,15 +2242,15 @@ function isImageSourcePresent(media) {
2183
2242
  // src/audits/images-alt-text.ts
2184
2243
  var audit11 = {
2185
2244
  id: "audits/images-alt-text",
2186
- title: __28("Images alt text", "elementor"),
2187
- description: __28("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2188
- fixHint: __28("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2245
+ title: __29("Images alt text", "elementor"),
2246
+ description: __29("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2247
+ fixHint: __29("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2189
2248
  categories: ["seo", "accessibility"],
2190
2249
  severity: "error",
2191
2250
  weight: 10,
2192
2251
  evaluate: (ctx) => {
2193
2252
  if (!hasPageImages(ctx.elements.tree)) {
2194
- return { status: "skipped", reason: __28("No images", "elementor") };
2253
+ return { status: "skipped", reason: __29("No images", "elementor") };
2195
2254
  }
2196
2255
  const violations = [];
2197
2256
  const failedWidgetIds = /* @__PURE__ */ new Set();
@@ -2207,9 +2266,9 @@ var audit11 = {
2207
2266
  auditId: audit11.id,
2208
2267
  elementId: node.id,
2209
2268
  targetHint: "element-settings",
2210
- label: __28("Image is missing alt text.", "elementor"),
2269
+ label: __29("Image is missing alt text.", "elementor"),
2211
2270
  externalUrl: ctx.pageContext.ally_plugin_url,
2212
- ctaLabel: __28("Fix with Ally", "elementor")
2271
+ ctaLabel: __29("Fix with Ally", "elementor")
2213
2272
  });
2214
2273
  }
2215
2274
  });
@@ -2218,13 +2277,13 @@ var audit11 = {
2218
2277
  };
2219
2278
 
2220
2279
  // src/audits/images-inefficient-format.ts
2221
- import { __ as __29 } from "@wordpress/i18n";
2280
+ import { __ as __30 } from "@wordpress/i18n";
2222
2281
  var LEGACY_RASTER_MIME_TYPES = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/gif", "image/bmp", "image/tiff"]);
2223
2282
  var audit12 = {
2224
2283
  id: "audits/images-inefficient-format",
2225
- title: __29("Inefficient image format", "elementor"),
2226
- description: __29("Image isn't served in a modern, efficient format like WebP or AVIF.", "elementor"),
2227
- fixHint: __29("Convert the image to a modern format like WebP or AVIF, or enable image optimization.", "elementor"),
2284
+ title: __30("Inefficient image format", "elementor"),
2285
+ description: __30("Image isn't served in a modern, efficient format like WebP or AVIF.", "elementor"),
2286
+ fixHint: __30("Convert the image to a modern format like WebP or AVIF, or enable image optimization.", "elementor"),
2228
2287
  categories: ["performance"],
2229
2288
  severity: "info",
2230
2289
  weight: 1,
@@ -2252,29 +2311,29 @@ var audit12 = {
2252
2311
  walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2253
2312
  walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2254
2313
  if (!hasAnyImage) {
2255
- return { status: "skipped", reason: __29("No images", "elementor") };
2314
+ return { status: "skipped", reason: __30("No images", "elementor") };
2256
2315
  }
2257
2316
  const violations = Array.from(offendingElementIds).map((elementId) => ({
2258
2317
  auditId: audit12.id,
2259
2318
  elementId,
2260
2319
  targetHint: "element-settings",
2261
- label: __29("Image isn't served in a modern format like WebP or AVIF.", "elementor"),
2320
+ label: __30("Image isn't served in a modern format like WebP or AVIF.", "elementor"),
2262
2321
  externalUrl: ctx.pageContext.image_optimization_plugin_url,
2263
- ctaLabel: __29("Optimize all", "elementor")
2322
+ ctaLabel: __30("Optimize all", "elementor")
2264
2323
  }));
2265
2324
  return violations.length === 0 ? { status: "pass" } : { status: "fail", violations, metadata: { inefficientImageFormatCount } };
2266
2325
  }
2267
2326
  };
2268
2327
 
2269
2328
  // src/audits/images-too-large.ts
2270
- import { __ as __30, sprintf as sprintf3 } from "@wordpress/i18n";
2329
+ import { __ as __31, sprintf as sprintf3 } from "@wordpress/i18n";
2271
2330
  var SIZE_THRESHOLD_BYTES = 500 * 1024;
2272
2331
  var BYTES_PER_KB = 1024;
2273
2332
  var audit13 = {
2274
2333
  id: "audits/images-too-large",
2275
- title: __30("Oversized images", "elementor"),
2276
- description: __30("Large image files slow down the page.", "elementor"),
2277
- fixHint: __30("Replace the image with a smaller version or enable image optimization.", "elementor"),
2334
+ title: __31("Oversized images", "elementor"),
2335
+ description: __31("Large image files slow down the page.", "elementor"),
2336
+ fixHint: __31("Replace the image with a smaller version or enable image optimization.", "elementor"),
2278
2337
  categories: ["performance"],
2279
2338
  severity: "warning",
2280
2339
  weight: 7,
@@ -2304,7 +2363,7 @@ var audit13 = {
2304
2363
  walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2305
2364
  walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2306
2365
  if (!hasAnyImage) {
2307
- return { status: "skipped", reason: __30("No images", "elementor") };
2366
+ return { status: "skipped", reason: __31("No images", "elementor") };
2308
2367
  }
2309
2368
  const violations = Array.from(widgetMaxKb.entries()).map(([elementId, kb]) => ({
2310
2369
  auditId: audit13.id,
@@ -2312,32 +2371,32 @@ var audit13 = {
2312
2371
  targetHint: "element-settings",
2313
2372
  label: sprintf3(
2314
2373
  /* translators: %d is the image file size in kilobytes. */
2315
- __30("Image is %d KB (over 500 KB).", "elementor"),
2374
+ __31("Image is %d KB (over 500 KB).", "elementor"),
2316
2375
  kb
2317
2376
  ),
2318
2377
  externalUrl: ctx.pageContext.image_optimization_plugin_url,
2319
- ctaLabel: __30("Optimize all", "elementor")
2378
+ ctaLabel: __31("Optimize all", "elementor")
2320
2379
  }));
2321
2380
  return violations.length === 0 ? { status: "pass" } : { status: "fail", violations, metadata: { oversizedImageCount } };
2322
2381
  }
2323
2382
  };
2324
2383
 
2325
2384
  // src/audits/nested-boxed-containers.ts
2326
- import { __ as __31 } from "@wordpress/i18n";
2385
+ import { __ as __32 } from "@wordpress/i18n";
2327
2386
  function isBoxed(settings) {
2328
2387
  return settings.content_width === "boxed";
2329
2388
  }
2330
2389
  var audit14 = {
2331
2390
  id: "audits/nested-boxed-containers",
2332
- title: __31("Boxed container nested inside a boxed parent", "elementor"),
2333
- description: __31("An inner container does not need to be boxed when its parent already is.", "elementor"),
2334
- fixHint: __31("Change the inner container's content width to Full Width.", "elementor"),
2391
+ title: __32("Boxed container nested inside a boxed parent", "elementor"),
2392
+ description: __32("An inner container does not need to be boxed when its parent already is.", "elementor"),
2393
+ fixHint: __32("Change the inner container's content width to Full Width.", "elementor"),
2335
2394
  categories: ["best-practices", "performance"],
2336
2395
  severity: "info",
2337
2396
  weight: 5,
2338
2397
  evaluate: (ctx) => {
2339
2398
  if (ctx.elements.tree.length === 0) {
2340
- return { status: "skipped", reason: __31("No elements", "elementor") };
2399
+ return { status: "skipped", reason: __32("No elements", "elementor") };
2341
2400
  }
2342
2401
  const violations = [];
2343
2402
  walkElements(ctx.elements.tree, (node, parents) => {
@@ -2350,7 +2409,7 @@ var audit14 = {
2350
2409
  auditId: audit14.id,
2351
2410
  elementId: node.id,
2352
2411
  targetHint: "element-settings",
2353
- label: __31("Nested boxed container.", "elementor")
2412
+ label: __32("Nested boxed container.", "elementor")
2354
2413
  });
2355
2414
  }
2356
2415
  });
@@ -2359,12 +2418,12 @@ var audit14 = {
2359
2418
  };
2360
2419
 
2361
2420
  // src/audits/page-excerpt.ts
2362
- import { __ as __32 } from "@wordpress/i18n";
2421
+ import { __ as __33 } from "@wordpress/i18n";
2363
2422
  var audit15 = {
2364
2423
  id: "audits/page-excerpt",
2365
- title: __32("Page excerpt", "elementor"),
2366
- description: __32("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2367
- fixHint: __32("Open Page Settings and write a short excerpt.", "elementor"),
2424
+ title: __33("Page excerpt", "elementor"),
2425
+ description: __33("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2426
+ fixHint: __33("Open Page Settings and write a short excerpt.", "elementor"),
2368
2427
  categories: ["seo"],
2369
2428
  severity: "warning",
2370
2429
  weight: 5,
@@ -2377,7 +2436,7 @@ var audit15 = {
2377
2436
  violations: [
2378
2437
  {
2379
2438
  auditId: audit15.id,
2380
- label: __32("Page has no excerpt.", "elementor"),
2439
+ label: __33("Page has no excerpt.", "elementor"),
2381
2440
  targetHint: "page-settings",
2382
2441
  angieFix: true
2383
2442
  }
@@ -2387,12 +2446,12 @@ var audit15 = {
2387
2446
  };
2388
2447
 
2389
2448
  // src/audits/page-featured-image.ts
2390
- import { __ as __33 } from "@wordpress/i18n";
2449
+ import { __ as __34 } from "@wordpress/i18n";
2391
2450
  var audit16 = {
2392
2451
  id: "audits/page-featured-image",
2393
- title: __33("Page featured image", "elementor"),
2394
- description: __33("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2395
- fixHint: __33("Open Page Settings and set a featured image.", "elementor"),
2452
+ title: __34("Page featured image", "elementor"),
2453
+ description: __34("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2454
+ fixHint: __34("Open Page Settings and set a featured image.", "elementor"),
2396
2455
  categories: ["seo"],
2397
2456
  severity: "info",
2398
2457
  weight: 5,
@@ -2405,7 +2464,7 @@ var audit16 = {
2405
2464
  violations: [
2406
2465
  {
2407
2466
  auditId: audit16.id,
2408
- label: __33("No featured image set.", "elementor"),
2467
+ label: __34("No featured image set.", "elementor"),
2409
2468
  targetHint: "page-settings"
2410
2469
  }
2411
2470
  ]
@@ -2414,13 +2473,13 @@ var audit16 = {
2414
2473
  };
2415
2474
 
2416
2475
  // src/audits/page-title.ts
2417
- import { __ as __34 } from "@wordpress/i18n";
2476
+ import { __ as __35 } from "@wordpress/i18n";
2418
2477
  var MAX_TITLE_LENGTH = 60;
2419
2478
  var audit17 = {
2420
2479
  id: "audits/page-title",
2421
- title: __34("Page title", "elementor"),
2422
- description: __34("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2423
- fixHint: __34("Open Page Settings and add a title.", "elementor"),
2480
+ title: __35("Page title", "elementor"),
2481
+ description: __35("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2482
+ fixHint: __35("Open Page Settings and add a title.", "elementor"),
2424
2483
  categories: ["seo"],
2425
2484
  severity: "error",
2426
2485
  weight: 10,
@@ -2432,10 +2491,10 @@ var audit17 = {
2432
2491
  violations: [
2433
2492
  {
2434
2493
  auditId: audit17.id,
2435
- label: __34("Page has no title.", "elementor"),
2494
+ label: __35("Page has no title.", "elementor"),
2436
2495
  targetHint: "page-settings",
2437
2496
  angieFix: true,
2438
- angiePrompt: __34(
2497
+ angiePrompt: __35(
2439
2498
  "Based on this page's contents, generate a title for this page.",
2440
2499
  "elementor"
2441
2500
  )
@@ -2449,7 +2508,7 @@ var audit17 = {
2449
2508
  violations: [
2450
2509
  {
2451
2510
  auditId: audit17.id,
2452
- label: __34("Page title is too long.", "elementor"),
2511
+ label: __35("Page title is too long.", "elementor"),
2453
2512
  targetHint: "page-settings",
2454
2513
  angieFix: true
2455
2514
  }
@@ -2461,7 +2520,7 @@ var audit17 = {
2461
2520
  };
2462
2521
 
2463
2522
  // src/audits/prefer-global-colors.ts
2464
- import { __ as __35, sprintf as sprintf4 } from "@wordpress/i18n";
2523
+ import { __ as __36, sprintf as sprintf4 } from "@wordpress/i18n";
2465
2524
 
2466
2525
  // src/utils/collect-hardcoded-colors.ts
2467
2526
  var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2529,18 +2588,18 @@ function findMatchingGlobalByValue(value, globals) {
2529
2588
  // src/audits/prefer-global-colors.ts
2530
2589
  var audit18 = {
2531
2590
  id: "audits/prefer-global-colors",
2532
- title: __35("Prefer global colors", "elementor"),
2533
- description: __35("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2534
- fixHint: __35("Replace the hard-coded value with the matching global color.", "elementor"),
2591
+ title: __36("Prefer global colors", "elementor"),
2592
+ description: __36("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2593
+ fixHint: __36("Replace the hard-coded value with the matching global color.", "elementor"),
2535
2594
  categories: ["best-practices"],
2536
2595
  severity: "info",
2537
2596
  weight: 3,
2538
2597
  evaluate: (ctx) => {
2539
2598
  if (ctx.elements.tree.length === 0) {
2540
- return { status: "skipped", reason: __35("No elements", "elementor") };
2599
+ return { status: "skipped", reason: __36("No elements", "elementor") };
2541
2600
  }
2542
2601
  if (ctx.kit.globals.colors.length === 0) {
2543
- return { status: "skipped", reason: __35("No global colors", "elementor") };
2602
+ return { status: "skipped", reason: __36("No global colors", "elementor") };
2544
2603
  }
2545
2604
  const violations = [];
2546
2605
  walkElements(ctx.elements.tree, (node) => {
@@ -2556,7 +2615,7 @@ var audit18 = {
2556
2615
  angieFix: true,
2557
2616
  label: sprintf4(
2558
2617
  /* translators: 1: hard-coded color value, 2: global color title. */
2559
- __35('replace "%1$s" with "%2$s" global color', "elementor"),
2618
+ __36('replace "%1$s" with "%2$s" global color', "elementor"),
2560
2619
  value,
2561
2620
  global.title
2562
2621
  )
@@ -2568,7 +2627,7 @@ var audit18 = {
2568
2627
  };
2569
2628
 
2570
2629
  // src/audits/prefer-global-fonts.ts
2571
- import { __ as __36, sprintf as sprintf5 } from "@wordpress/i18n";
2630
+ import { __ as __37, sprintf as sprintf5 } from "@wordpress/i18n";
2572
2631
 
2573
2632
  // src/utils/collect-hardcoded-fonts.ts
2574
2633
  var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2628,18 +2687,18 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
2628
2687
  // src/audits/prefer-global-fonts.ts
2629
2688
  var audit19 = {
2630
2689
  id: "audits/prefer-global-fonts",
2631
- title: __36("Prefer global fonts", "elementor"),
2632
- description: __36("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2633
- fixHint: __36("Replace the hard-coded value with the matching global font.", "elementor"),
2690
+ title: __37("Prefer global fonts", "elementor"),
2691
+ description: __37("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2692
+ fixHint: __37("Replace the hard-coded value with the matching global font.", "elementor"),
2634
2693
  categories: ["best-practices", "performance"],
2635
2694
  severity: "info",
2636
2695
  weight: 3,
2637
2696
  evaluate: (ctx) => {
2638
2697
  if (ctx.elements.tree.length === 0) {
2639
- return { status: "skipped", reason: __36("No elements", "elementor") };
2698
+ return { status: "skipped", reason: __37("No elements", "elementor") };
2640
2699
  }
2641
2700
  if (ctx.kit.globals.fonts.length === 0) {
2642
- return { status: "skipped", reason: __36("No global fonts", "elementor") };
2701
+ return { status: "skipped", reason: __37("No global fonts", "elementor") };
2643
2702
  }
2644
2703
  const violations = [];
2645
2704
  walkElements(ctx.elements.tree, (node) => {
@@ -2654,7 +2713,7 @@ var audit19 = {
2654
2713
  targetHint: "element-settings",
2655
2714
  label: sprintf5(
2656
2715
  /* translators: %s: global font title. */
2657
- __36('replace hardcoded typography with "%s" global font', "elementor"),
2716
+ __37('replace hardcoded typography with "%s" global font', "elementor"),
2658
2717
  global.title
2659
2718
  )
2660
2719
  });
@@ -2665,15 +2724,15 @@ var audit19 = {
2665
2724
  };
2666
2725
 
2667
2726
  // src/audits/privacy-policy.ts
2668
- import { __ as __37 } from "@wordpress/i18n";
2727
+ import { __ as __38 } from "@wordpress/i18n";
2669
2728
  var audit20 = {
2670
2729
  id: "audits/privacy-policy",
2671
- title: __37("Privacy policy", "elementor"),
2672
- description: __37(
2730
+ title: __38("Privacy policy", "elementor"),
2731
+ description: __38(
2673
2732
  "A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
2674
2733
  "elementor"
2675
2734
  ),
2676
- fixHint: __37(
2735
+ fixHint: __38(
2677
2736
  "Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
2678
2737
  "elementor"
2679
2738
  ),
@@ -2689,9 +2748,9 @@ var audit20 = {
2689
2748
  violations: [
2690
2749
  {
2691
2750
  auditId: audit20.id,
2692
- label: __37("No privacy policy page is set.", "elementor"),
2751
+ label: __38("No privacy policy page is set.", "elementor"),
2693
2752
  externalUrl: ctx.pageContext.privacy_settings_url,
2694
- ctaLabel: __37("Create", "elementor")
2753
+ ctaLabel: __38("Create", "elementor")
2695
2754
  }
2696
2755
  ]
2697
2756
  };
@@ -2699,15 +2758,15 @@ var audit20 = {
2699
2758
  };
2700
2759
 
2701
2760
  // src/audits/robots-noindex.ts
2702
- import { __ as __38 } from "@wordpress/i18n";
2761
+ import { __ as __39 } from "@wordpress/i18n";
2703
2762
  var audit21 = {
2704
2763
  id: "audits/robots-noindex",
2705
- title: __38("Search engine visibility", "elementor"),
2706
- description: __38(
2764
+ title: __39("Search engine visibility", "elementor"),
2765
+ description: __39(
2707
2766
  "When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
2708
2767
  "elementor"
2709
2768
  ),
2710
- fixHint: __38(
2769
+ fixHint: __39(
2711
2770
  'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
2712
2771
  "elementor"
2713
2772
  ),
@@ -2723,7 +2782,7 @@ var audit21 = {
2723
2782
  violations: [
2724
2783
  {
2725
2784
  auditId: audit21.id,
2726
- label: __38("Search engines are discouraged from indexing this website.", "elementor"),
2785
+ label: __39("Search engines are discouraged from indexing this website.", "elementor"),
2727
2786
  externalUrl: ctx.pageContext.reading_settings_url
2728
2787
  }
2729
2788
  ]
@@ -2732,15 +2791,15 @@ var audit21 = {
2732
2791
  };
2733
2792
 
2734
2793
  // src/audits/scan-for-cookies.ts
2735
- import { __ as __39 } from "@wordpress/i18n";
2794
+ import { __ as __40 } from "@wordpress/i18n";
2736
2795
  var audit22 = {
2737
2796
  id: "audits/scan-for-cookies",
2738
- title: __39("Scan for cookies", "elementor"),
2739
- description: __39(
2797
+ title: __40("Scan for cookies", "elementor"),
2798
+ description: __40(
2740
2799
  "Your site may be setting cookies you haven't disclosed. Some countries require a banner even without a full consent policy. Scan to see what needs disclosure.",
2741
2800
  "elementor"
2742
2801
  ),
2743
- fixHint: __39("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2802
+ fixHint: __40("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2744
2803
  categories: ["compliance"],
2745
2804
  severity: "info",
2746
2805
  weight: 0,
@@ -2751,7 +2810,7 @@ var audit22 = {
2751
2810
  violations: [
2752
2811
  {
2753
2812
  auditId: audit22.id,
2754
- label: __39("This page has not been scanned for cookies yet.", "elementor"),
2813
+ label: __40("This page has not been scanned for cookies yet.", "elementor"),
2755
2814
  externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
2756
2815
  }
2757
2816
  ]
@@ -2760,21 +2819,21 @@ var audit22 = {
2760
2819
  };
2761
2820
 
2762
2821
  // src/audits/sections-and-columns.ts
2763
- import { __ as __40 } from "@wordpress/i18n";
2822
+ import { __ as __41 } from "@wordpress/i18n";
2764
2823
  var audit23 = {
2765
2824
  id: "audits/sections-and-columns",
2766
- title: __40("Sections and columns", "elementor"),
2767
- description: __40(
2825
+ title: __41("Sections and columns", "elementor"),
2826
+ description: __41(
2768
2827
  "Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
2769
2828
  "elementor"
2770
2829
  ),
2771
- fixHint: __40("Use the Container Converter to replace each section/column with a container.", "elementor"),
2830
+ fixHint: __41("Use the Container Converter to replace each section/column with a container.", "elementor"),
2772
2831
  categories: ["best-practices", "performance"],
2773
2832
  severity: "warning",
2774
2833
  weight: 7,
2775
2834
  evaluate: (ctx) => {
2776
2835
  if (ctx.elements.tree.length === 0) {
2777
- return { status: "skipped", reason: __40("No elements", "elementor") };
2836
+ return { status: "skipped", reason: __41("No elements", "elementor") };
2778
2837
  }
2779
2838
  const violations = [];
2780
2839
  walkElements(ctx.elements.tree, (node) => {
@@ -2782,7 +2841,7 @@ var audit23 = {
2782
2841
  violations.push({
2783
2842
  auditId: audit23.id,
2784
2843
  elementId: node.id,
2785
- label: node.elType === "section" ? __40("Section element", "elementor") : __40("Column element", "elementor")
2844
+ label: node.elType === "section" ? __41("Section element", "elementor") : __41("Column element", "elementor")
2786
2845
  });
2787
2846
  }
2788
2847
  });
@@ -2791,15 +2850,15 @@ var audit23 = {
2791
2850
  };
2792
2851
 
2793
2852
  // src/audits/site-identity.ts
2794
- import { __ as __41 } from "@wordpress/i18n";
2853
+ import { __ as __42 } from "@wordpress/i18n";
2795
2854
  var audit24 = {
2796
2855
  id: "audits/site-identity",
2797
- title: __41("Site identity", "elementor"),
2798
- description: __41(
2856
+ title: __42("Site identity", "elementor"),
2857
+ description: __42(
2799
2858
  "Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
2800
2859
  "elementor"
2801
2860
  ),
2802
- fixHint: __41("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2861
+ fixHint: __42("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2803
2862
  categories: ["best-practices", "seo"],
2804
2863
  severity: "info",
2805
2864
  weight: 7,
@@ -2809,14 +2868,14 @@ var audit24 = {
2809
2868
  if (!identity.site_name_set) {
2810
2869
  violations.push({
2811
2870
  auditId: audit24.id,
2812
- label: __41("Site name is missing or still uses the default.", "elementor"),
2871
+ label: __42("Site name is missing or still uses the default.", "elementor"),
2813
2872
  targetHint: "site-identity-settings"
2814
2873
  });
2815
2874
  }
2816
2875
  if (!identity.site_description_set) {
2817
2876
  violations.push({
2818
2877
  auditId: audit24.id,
2819
- label: __41("Site description is missing or still uses the default.", "elementor"),
2878
+ label: __42("Site description is missing or still uses the default.", "elementor"),
2820
2879
  targetHint: "site-identity-settings",
2821
2880
  angieFix: true
2822
2881
  });
@@ -2824,14 +2883,14 @@ var audit24 = {
2824
2883
  if (!identity.site_logo_set) {
2825
2884
  violations.push({
2826
2885
  auditId: audit24.id,
2827
- label: __41("Site logo is not set.", "elementor"),
2886
+ label: __42("Site logo is not set.", "elementor"),
2828
2887
  targetHint: "site-identity-settings"
2829
2888
  });
2830
2889
  }
2831
2890
  if (!identity.site_favicon_set) {
2832
2891
  violations.push({
2833
2892
  auditId: audit24.id,
2834
- label: __41("Site favicon is not set.", "elementor"),
2893
+ label: __42("Site favicon is not set.", "elementor"),
2835
2894
  targetHint: "site-identity-settings"
2836
2895
  });
2837
2896
  }
@@ -2847,7 +2906,7 @@ var audit24 = {
2847
2906
 
2848
2907
  // src/audits/too-many-widgets.ts
2849
2908
  import { getWidgetsCache as getWidgetsCache3 } from "@elementor/editor-elements";
2850
- import { __ as __42 } from "@wordpress/i18n";
2909
+ import { __ as __43 } from "@wordpress/i18n";
2851
2910
  var WIDGET_COUNT_THRESHOLD = 100;
2852
2911
  function isCountableWidget(node, widgetsCache) {
2853
2912
  if (node.elType === "widget") {
@@ -2857,15 +2916,15 @@ function isCountableWidget(node, widgetsCache) {
2857
2916
  }
2858
2917
  var audit25 = {
2859
2918
  id: "audits/too-many-widgets",
2860
- title: __42("Too many widgets", "elementor"),
2861
- description: __42("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2862
- fixHint: __42("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2919
+ title: __43("Too many widgets", "elementor"),
2920
+ description: __43("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2921
+ fixHint: __43("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2863
2922
  categories: ["best-practices", "performance"],
2864
2923
  severity: "warning",
2865
2924
  weight: 5,
2866
2925
  evaluate: (ctx) => {
2867
2926
  if (ctx.elements.tree.length === 0) {
2868
- return { status: "skipped", reason: __42("No elements", "elementor") };
2927
+ return { status: "skipped", reason: __43("No elements", "elementor") };
2869
2928
  }
2870
2929
  const widgetsCache = getWidgetsCache3();
2871
2930
  let widgetCount = 0;
@@ -2882,7 +2941,7 @@ var audit25 = {
2882
2941
  violations: [
2883
2942
  {
2884
2943
  auditId: audit25.id,
2885
- label: __42("Page has too many widgets.", "elementor")
2944
+ label: __43("Page has too many widgets.", "elementor")
2886
2945
  }
2887
2946
  ]
2888
2947
  };
@@ -2923,12 +2982,25 @@ function registerAllAudits() {
2923
2982
  }
2924
2983
  }
2925
2984
 
2985
+ // src/sync-report-staleness.ts
2986
+ import { __privateListenTo as listenTo, commandEndEvent } from "@elementor/editor-v1-adapters";
2987
+ import { __dispatch as dispatch } from "@elementor/store";
2988
+ function syncReportStaleness() {
2989
+ listenTo(commandEndEvent("document/save/set-is-modified"), (e) => {
2990
+ const event = e;
2991
+ if (event.args?.status) {
2992
+ dispatch(slice.actions.reportStale());
2993
+ }
2994
+ });
2995
+ }
2996
+
2926
2997
  // src/init.ts
2927
2998
  function init() {
2928
2999
  registerSlice(slice);
2929
3000
  registerAllAudits();
2930
3001
  registerFloatingPanel(auditPanel.panel);
2931
3002
  registerAppBarAuditsToggle();
3003
+ syncReportStaleness();
2932
3004
  }
2933
3005
  export {
2934
3006
  init,