@elementor/editor-audits 4.4.0-1100 → 4.4.0-1102

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,18 +6,18 @@ 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 __22 } from "@wordpress/i18n";
9
+ import { ShieldCheckIcon as ShieldCheckIcon3 } from "@elementor/icons";
10
+ import { __ as __24 } from "@wordpress/i18n";
11
11
 
12
12
  // src/editor-panel.tsx
13
13
  import { createFloatingPanel } from "@elementor/editor-floating-panels";
14
14
 
15
15
  // src/components/audit-panel.tsx
16
- import * as React23 from "react";
16
+ import * as React25 from "react";
17
17
  import { getCurrentDocumentId as getCurrentDocumentId2 } from "@elementor/editor-elements";
18
18
  import { FloatingPanelBody, FloatingPanelFooter, FloatingPanelHeader } from "@elementor/editor-floating-panels";
19
- import { Box as Box19, Button as Button5, Typography as Typography15 } from "@elementor/ui";
20
- import { __ as __21 } from "@wordpress/i18n";
19
+ import { Box as Box21, Button as Button5, Typography as Typography16 } from "@elementor/ui";
20
+ import { __ as __23 } from "@wordpress/i18n";
21
21
 
22
22
  // src/hooks/use-audit-report.ts
23
23
  import { useEffect } from "react";
@@ -134,7 +134,7 @@ var CATEGORY_LABELS = {
134
134
  seo: __("SEO", "elementor"),
135
135
  accessibility: __("Accessibility", "elementor"),
136
136
  performance: __("Performance", "elementor"),
137
- compliance: __("Compliance", "elementor")
137
+ compliance: __("Site compliance", "elementor")
138
138
  };
139
139
 
140
140
  // src/utils/audit-status-summary.ts
@@ -733,10 +733,10 @@ function WelcomePage() {
733
733
  }
734
734
 
735
735
  // src/components/report-shell.tsx
736
- import * as React22 from "react";
737
- import { useState as useState4 } from "react";
738
- import { Box as Box18, Divider as Divider2, Tab, Tabs } from "@elementor/ui";
739
- import { __ as __20 } from "@wordpress/i18n";
736
+ import * as React24 from "react";
737
+ import { useState as useState5 } from "react";
738
+ import { Box as Box20, Divider as Divider3, Tab, Tabs } from "@elementor/ui";
739
+ import { __ as __22 } from "@wordpress/i18n";
740
740
 
741
741
  // src/components/pages/all-audits-page.tsx
742
742
  import * as React12 from "react";
@@ -795,7 +795,7 @@ function SubpageHeader({ title, onBack, backLabel, icon }) {
795
795
  import * as React11 from "react";
796
796
  import { useState as useState3 } from "react";
797
797
  import { getElementIcon, getElementTitle } from "@elementor/editor-elements";
798
- import { AlertCircleIcon as AlertCircleIcon2, BulbIcon, CheckIcon, ChevronDownIcon as ChevronDownIcon2, EyeIcon, HelpIcon } from "@elementor/icons";
798
+ import { AlertCircleIcon as AlertCircleIcon2, BulbIcon as BulbIcon2, CheckIcon, ChevronDownIcon as ChevronDownIcon2, EyeIcon, HelpIcon } from "@elementor/icons";
799
799
  import { Alert, AlertTitle, Box as Box7, Collapse as Collapse2, IconButton as IconButton5, Tooltip as Tooltip3, Typography as Typography6 } from "@elementor/ui";
800
800
  import { __ as __11 } from "@wordpress/i18n";
801
801
 
@@ -898,11 +898,11 @@ function FixViolationWithAngie({ prompt }) {
898
898
 
899
899
  // src/components/severity-icons.tsx
900
900
  import * as React8 from "react";
901
- import { AlertCircleIcon, AlertTriangleFilledIcon, InfoCircleIcon } from "@elementor/icons";
901
+ import { AlertCircleIcon, AlertTriangleFilledIcon, BulbIcon } from "@elementor/icons";
902
902
  var SEVERITY_CONFIG = {
903
903
  error: { Icon: AlertTriangleFilledIcon, color: "error" },
904
904
  warning: { Icon: AlertCircleIcon, color: "warning" },
905
- info: { Icon: InfoCircleIcon, color: "info" }
905
+ info: { Icon: BulbIcon, color: "info" }
906
906
  };
907
907
  function SeverityIcon({ severity }) {
908
908
  const { Icon, color } = SEVERITY_CONFIG[severity];
@@ -1005,7 +1005,7 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
1005
1005
  {
1006
1006
  severity: "info",
1007
1007
  sx: { p: 1 },
1008
- icon: /* @__PURE__ */ React11.createElement(BulbIcon, { fontSize: "small", color: "info", "aria-hidden": true })
1008
+ icon: /* @__PURE__ */ React11.createElement(BulbIcon2, { fontSize: "small", color: "info", "aria-hidden": true })
1009
1009
  },
1010
1010
  /* @__PURE__ */ React11.createElement(AlertTitle, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, __11("How to resolve", "elementor"))),
1011
1011
  /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit23.fixHint)
@@ -1099,19 +1099,13 @@ import { Box as Box9 } from "@elementor/ui";
1099
1099
  import { __ as __13 } from "@wordpress/i18n";
1100
1100
 
1101
1101
  // src/components/category-icons.ts
1102
- import {
1103
- ElementorAccessibilityIcon,
1104
- FilterIcon,
1105
- HeartHandShakeIcon,
1106
- Settings2Icon,
1107
- ShieldHalfFilledIcon
1108
- } from "@elementor/icons";
1102
+ import { BoltIcon, ElementorAccessibilityIcon, FileSearchIcon, Settings2Icon, ShieldCheckIcon as ShieldCheckIcon2 } from "@elementor/icons";
1109
1103
  var CATEGORY_ICONS = {
1110
1104
  "best-practices": Settings2Icon,
1111
- seo: FilterIcon,
1105
+ seo: FileSearchIcon,
1112
1106
  accessibility: ElementorAccessibilityIcon,
1113
- performance: ShieldHalfFilledIcon,
1114
- compliance: HeartHandShakeIcon
1107
+ performance: BoltIcon,
1108
+ compliance: ShieldCheckIcon2
1115
1109
  };
1116
1110
 
1117
1111
  // src/components/pages/category-page.tsx
@@ -1139,12 +1133,13 @@ function CategoryPage({ category, report, onBack }) {
1139
1133
  }
1140
1134
 
1141
1135
  // src/components/pages/issues-page.tsx
1142
- import * as React17 from "react";
1143
- import { Box as Box13, Link, Typography as Typography10 } from "@elementor/ui";
1136
+ import * as React18 from "react";
1137
+ import { useState as useState4 } from "react";
1138
+ import { Box as Box14, Link, Typography as Typography10 } from "@elementor/ui";
1144
1139
  import { __ as __17 } from "@wordpress/i18n";
1145
1140
 
1146
1141
  // src/utils/severity-counts.ts
1147
- import { __ as __14, sprintf as sprintf2 } from "@wordpress/i18n";
1142
+ import { __ as __14 } from "@wordpress/i18n";
1148
1143
  var ALL_SEVERITIES = ["error", "warning", "info"];
1149
1144
  function countSeverities(report, category) {
1150
1145
  const counts = { error: 0, warning: 0, info: 0 };
@@ -1169,41 +1164,115 @@ function severityPluralLabel(severity) {
1169
1164
  case "warning":
1170
1165
  return __14("Warnings", "elementor");
1171
1166
  case "info":
1172
- return __14("Info", "elementor");
1167
+ return __14("Suggestions", "elementor");
1173
1168
  }
1174
1169
  }
1175
- function severityRemainingCountLabel(severity, count) {
1176
- switch (severity) {
1177
- case "error":
1178
- return sprintf2(
1179
- /* translators: %d: number of remaining error violations. */
1180
- __14("%d errors", "elementor"),
1181
- count
1182
- );
1183
- case "warning":
1184
- return sprintf2(
1185
- /* translators: %d: number of remaining warning violations. */
1186
- __14("%d warnings", "elementor"),
1187
- count
1188
- );
1189
- case "info":
1190
- return sprintf2(
1191
- /* translators: %d: number of remaining info violations. */
1192
- __14("%d info", "elementor"),
1193
- count
1194
- );
1170
+
1171
+ // src/components/audit-statuses-section.tsx
1172
+ import * as React15 from "react";
1173
+ import { Box as Box11, Divider, Typography as Typography8 } from "@elementor/ui";
1174
+ import { __ as __15, sprintf as sprintf2 } from "@wordpress/i18n";
1175
+
1176
+ // src/components/count-summary-circle.tsx
1177
+ import * as React14 from "react";
1178
+ import { Box as Box10, Chip as Chip2, Typography as Typography7 } from "@elementor/ui";
1179
+ var COUNT_SUMMARY_CIRCLE_SIZE = 64;
1180
+ var COUNT_SUMMARY_BORDER_WIDTH = 4;
1181
+ function chipBorderColor(theme, color) {
1182
+ if (color === "default" || !color) {
1183
+ return theme.palette.text.secondary;
1195
1184
  }
1185
+ return theme.palette[color].main;
1186
+ }
1187
+ function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
1188
+ return /* @__PURE__ */ React14.createElement(
1189
+ Box10,
1190
+ {
1191
+ "aria-label": ariaLabel,
1192
+ component: "button",
1193
+ onClick,
1194
+ type: "button",
1195
+ sx: {
1196
+ alignItems: "center",
1197
+ background: "none",
1198
+ border: "none",
1199
+ cursor: "pointer",
1200
+ display: "flex",
1201
+ flex: 1,
1202
+ flexDirection: "column",
1203
+ gap: 0.5,
1204
+ padding: 0
1205
+ }
1206
+ },
1207
+ /* @__PURE__ */ React14.createElement(
1208
+ Chip2,
1209
+ {
1210
+ color,
1211
+ label: count,
1212
+ size: "small",
1213
+ variant: "standard",
1214
+ sx: (theme) => ({
1215
+ border: `${COUNT_SUMMARY_BORDER_WIDTH}px solid ${chipBorderColor(theme, color)}`,
1216
+ borderRadius: "50%",
1217
+ height: COUNT_SUMMARY_CIRCLE_SIZE,
1218
+ maxWidth: COUNT_SUMMARY_CIRCLE_SIZE,
1219
+ width: COUNT_SUMMARY_CIRCLE_SIZE,
1220
+ "& .MuiChip-label": {
1221
+ fontSize: theme.typography.body2.fontSize,
1222
+ fontWeight: 700,
1223
+ lineHeight: 1,
1224
+ padding: 0
1225
+ }
1226
+ })
1227
+ }
1228
+ ),
1229
+ /* @__PURE__ */ React14.createElement(Typography7, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
1230
+ );
1231
+ }
1232
+
1233
+ // src/components/audit-statuses-section.tsx
1234
+ var STATUS_ARIA_LABELS = {
1235
+ pass: (count) => sprintf2(
1236
+ /* translators: %d: number of passed audits. */
1237
+ __15("%d passed audits, view all", "elementor"),
1238
+ count
1239
+ ),
1240
+ fail: (count) => sprintf2(
1241
+ /* translators: %d: number of failed audit violations. */
1242
+ __15("%d failed audits, view all", "elementor"),
1243
+ count
1244
+ ),
1245
+ skipped: (count) => sprintf2(
1246
+ /* translators: %d: number of skipped audits. */
1247
+ __15("%d skipped audits, view all", "elementor"),
1248
+ count
1249
+ )
1250
+ };
1251
+ var STATUS_GROUPS = ["fail", "pass", "skipped"];
1252
+ function AuditStatusesSection({ report, onStatusClick }) {
1253
+ const statusCounts = auditStatusDisplayCounts(report);
1254
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Typography8, { variant: "subtitle1", fontWeight: "bold" }, __15("Audit statuses", "elementor")), /* @__PURE__ */ React15.createElement(Box11, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React15.createElement(
1255
+ CountSummaryCircle,
1256
+ {
1257
+ key: status,
1258
+ ariaLabel: STATUS_ARIA_LABELS[status](statusCounts[status]),
1259
+ color: auditStatusColor(status),
1260
+ count: statusCounts[status],
1261
+ label: auditStatusLabel(status),
1262
+ onClick: () => onStatusClick(status)
1263
+ }
1264
+ ))), /* @__PURE__ */ React15.createElement(Divider, null));
1196
1265
  }
1197
1266
 
1198
1267
  // src/components/issues-category-row.tsx
1199
- import * as React14 from "react";
1268
+ import * as React16 from "react";
1200
1269
  import { ChevronRightIcon } from "@elementor/icons";
1201
- import { Box as Box10, Rotate as Rotate2, Typography as Typography7, useTheme as useTheme2 } from "@elementor/ui";
1270
+ import { Box as Box12, Rotate as Rotate2, Typography as Typography9, useTheme as useTheme2 } from "@elementor/ui";
1202
1271
  function IssuesCategoryRow({ category, label, counts, onClick }) {
1203
1272
  const isRtl = "rtl" === useTheme2().direction;
1204
1273
  const Icon = CATEGORY_ICONS[category];
1205
- return /* @__PURE__ */ React14.createElement(
1206
- Box10,
1274
+ return /* @__PURE__ */ React16.createElement(
1275
+ Box12,
1207
1276
  {
1208
1277
  role: "button",
1209
1278
  tabIndex: 0,
@@ -1224,21 +1293,112 @@ function IssuesCategoryRow({ category, label, counts, onClick }) {
1224
1293
  "&:focus-visible": { outline: "2px solid", outlineColor: "primary.main" }
1225
1294
  }
1226
1295
  },
1227
- /* @__PURE__ */ React14.createElement(Icon, { fontSize: "small", color: "action" }),
1228
- /* @__PURE__ */ React14.createElement(Typography7, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1229
- /* @__PURE__ */ React14.createElement(Box10, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React14.createElement(Box10, { 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])))),
1230
- /* @__PURE__ */ React14.createElement(Rotate2, { in: isRtl }, /* @__PURE__ */ React14.createElement(ChevronRightIcon, { fontSize: "small", color: "action" }))
1296
+ /* @__PURE__ */ React16.createElement(Icon, { fontSize: "small", color: "action" }),
1297
+ /* @__PURE__ */ React16.createElement(Typography9, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1298
+ /* @__PURE__ */ React16.createElement(Box12, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React16.createElement(Box12, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React16.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React16.createElement(Typography9, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
1299
+ /* @__PURE__ */ React16.createElement(Rotate2, { in: isRtl }, /* @__PURE__ */ React16.createElement(ChevronRightIcon, { fontSize: "small", color: "action" }))
1231
1300
  );
1232
1301
  }
1233
1302
 
1234
- // src/components/promotions.tsx
1235
- import * as React16 from "react";
1236
- import { Box as Box12, Typography as Typography9 } from "@elementor/ui";
1303
+ // src/components/severity-filter-chips.tsx
1304
+ import * as React17 from "react";
1305
+ import { Box as Box13, Chip as Chip3 } from "@elementor/ui";
1237
1306
  import { __ as __16 } from "@wordpress/i18n";
1307
+ function SeverityFilterChips({ selected, onChange }) {
1308
+ return /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", alignItems: "center", gap: 1 } }, /* @__PURE__ */ React17.createElement(
1309
+ FilterChip,
1310
+ {
1311
+ label: __16("All", "elementor"),
1312
+ isSelected: selected === "all",
1313
+ onClick: () => onChange("all")
1314
+ }
1315
+ ), ALL_SEVERITIES.map((severity) => /* @__PURE__ */ React17.createElement(
1316
+ FilterChip,
1317
+ {
1318
+ key: severity,
1319
+ label: severityPluralLabel(severity),
1320
+ icon: /* @__PURE__ */ React17.createElement(SeverityIcon, { severity }),
1321
+ isSelected: selected === severity,
1322
+ onClick: () => onChange(severity)
1323
+ }
1324
+ )));
1325
+ }
1326
+ function FilterChip({ label, icon, isSelected, onClick }) {
1327
+ return /* @__PURE__ */ React17.createElement(
1328
+ Chip3,
1329
+ {
1330
+ label,
1331
+ icon,
1332
+ size: "small",
1333
+ variant: "filled",
1334
+ color: "default",
1335
+ onClick,
1336
+ "aria-pressed": isSelected,
1337
+ sx: { bgcolor: isSelected ? "action.selected" : "transparent" }
1338
+ }
1339
+ );
1340
+ }
1341
+
1342
+ // src/components/pages/issues-page.tsx
1343
+ function filterCounts(counts, filter) {
1344
+ if (filter === "all") {
1345
+ return counts;
1346
+ }
1347
+ return { error: 0, warning: 0, info: 0, [filter]: counts[filter] };
1348
+ }
1349
+ function IssuesPage({ report, onCategoryClick, onAllAuditsClick, onStatusClick }) {
1350
+ const [filter, setFilter] = useState4("all");
1351
+ const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1352
+ const categoryRows = populatedCategories.map((category) => ({ category, counts: filterCounts(countSeverities(report, category), filter) })).filter(({ counts }) => Object.values(counts).some((count) => count > 0));
1353
+ return /* @__PURE__ */ React18.createElement(Box14, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React18.createElement(AuditStatusesSection, { report, onStatusClick }), /* @__PURE__ */ React18.createElement(
1354
+ Link,
1355
+ {
1356
+ component: "button",
1357
+ underline: "none",
1358
+ color: "inherit",
1359
+ onClick: onAllAuditsClick,
1360
+ sx: { textAlign: "start" }
1361
+ },
1362
+ /* @__PURE__ */ React18.createElement(Typography10, { variant: "subtitle1", component: "h2" }, __17("All issues", "elementor"))
1363
+ ), /* @__PURE__ */ React18.createElement(SeverityFilterChips, { selected: filter, onChange: setFilter }), /* @__PURE__ */ React18.createElement(Box14, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, categoryRows.map(({ category, counts }) => /* @__PURE__ */ React18.createElement(
1364
+ IssuesCategoryRow,
1365
+ {
1366
+ key: category,
1367
+ category,
1368
+ label: CATEGORY_LABELS[category],
1369
+ counts,
1370
+ onClick: () => onCategoryClick(category)
1371
+ }
1372
+ ))));
1373
+ }
1374
+
1375
+ // src/components/pages/overview-page.tsx
1376
+ import * as React23 from "react";
1377
+ import { Box as Box19, Chip as Chip4, Typography as Typography15 } from "@elementor/ui";
1378
+ import { __ as __21 } from "@wordpress/i18n";
1379
+
1380
+ // src/utils/score-thresholds.ts
1381
+ import { __ as __18 } from "@wordpress/i18n";
1382
+ var GOOD_THRESHOLD = 90;
1383
+ var OK_THRESHOLD = 50;
1384
+ function getScoreTier(score) {
1385
+ if (score >= GOOD_THRESHOLD) {
1386
+ return { color: "success", label: __18("Good", "elementor") };
1387
+ }
1388
+ if (score >= OK_THRESHOLD) {
1389
+ return { color: "warning", label: __18("Needs work", "elementor") };
1390
+ }
1391
+ return { color: "error", label: __18("At risk", "elementor") };
1392
+ }
1393
+
1394
+ // src/components/promotions.tsx
1395
+ import * as React20 from "react";
1396
+ import { Box as Box16, Divider as Divider2, Typography as Typography12 } from "@elementor/ui";
1397
+ import { __ as __20 } from "@wordpress/i18n";
1238
1398
 
1239
1399
  // src/register-promotions.ts
1240
- import { ElementorCookieIcon, PhotoIcon, ShieldHalfFilledIcon as ShieldHalfFilledIcon2 } from "@elementor/icons";
1241
- import { __ as __15, _n, sprintf as sprintf3 } from "@wordpress/i18n";
1400
+ import { ElementorCookieIcon, PhotoIcon, ShieldHalfFilledIcon } from "@elementor/icons";
1401
+ import { __ as __19, _n, sprintf as sprintf3 } from "@wordpress/i18n";
1242
1402
  function firstFailExternalUrl(run) {
1243
1403
  return run.result.status === "fail" ? run.result.violations[0]?.externalUrl : void 0;
1244
1404
  }
@@ -1246,7 +1406,7 @@ var PROMOTIONS = [
1246
1406
  {
1247
1407
  auditId: "audits/images-alt-text",
1248
1408
  icon: PhotoIcon,
1249
- ctaLabel: __15("Fix with Ally", "elementor"),
1409
+ ctaLabel: __19("Fix with Ally", "elementor"),
1250
1410
  formatSubtitle: (run) => {
1251
1411
  if (run.result.status !== "fail") {
1252
1412
  return null;
@@ -1266,21 +1426,21 @@ var PROMOTIONS = [
1266
1426
  {
1267
1427
  auditId: "audits/cookie-policy",
1268
1428
  icon: ElementorCookieIcon,
1269
- ctaLabel: __15("Fix with Cookiez", "elementor"),
1270
- formatSubtitle: (run) => run.result.status === "fail" ? __15("Generate cookie policy", "elementor") : null,
1429
+ ctaLabel: __19("Fix with Cookiez", "elementor"),
1430
+ formatSubtitle: (run) => run.result.status === "fail" ? __19("Generate cookie policy", "elementor") : null,
1271
1431
  getCtaUrl: firstFailExternalUrl
1272
1432
  },
1273
1433
  {
1274
1434
  auditId: "audits/scan-for-cookies",
1275
1435
  icon: ElementorCookieIcon,
1276
- ctaLabel: __15("Scan", "elementor"),
1277
- formatSubtitle: (run) => run.result.status === "fail" ? __15("Scan this page for cookies", "elementor") : null,
1436
+ ctaLabel: __19("Scan", "elementor"),
1437
+ formatSubtitle: (run) => run.result.status === "fail" ? __19("Scan this page for cookies", "elementor") : null,
1278
1438
  getCtaUrl: firstFailExternalUrl
1279
1439
  },
1280
1440
  {
1281
1441
  auditId: "audits/images-too-large",
1282
- icon: ShieldHalfFilledIcon2,
1283
- ctaLabel: __15("Optimize all", "elementor"),
1442
+ icon: ShieldHalfFilledIcon,
1443
+ ctaLabel: __19("Optimize all", "elementor"),
1284
1444
  formatSubtitle: (run) => {
1285
1445
  if (run.result.status !== "fail") {
1286
1446
  return null;
@@ -1305,11 +1465,11 @@ function findAuditRun(report, auditId) {
1305
1465
  }
1306
1466
 
1307
1467
  // src/components/promotion-card.tsx
1308
- import * as React15 from "react";
1309
- import { Box as Box11, Button as Button4, Typography as Typography8 } from "@elementor/ui";
1468
+ import * as React19 from "react";
1469
+ import { Box as Box15, Button as Button4, Typography as Typography11 } from "@elementor/ui";
1310
1470
  function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle, title }) {
1311
- return /* @__PURE__ */ React15.createElement(
1312
- Box11,
1471
+ return /* @__PURE__ */ React19.createElement(
1472
+ Box15,
1313
1473
  {
1314
1474
  sx: {
1315
1475
  alignItems: "center",
@@ -1322,9 +1482,9 @@ function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle
1322
1482
  py: 1.5
1323
1483
  }
1324
1484
  },
1325
- /* @__PURE__ */ React15.createElement(Icon, { fontSize: "small", color: "action" }),
1326
- /* @__PURE__ */ React15.createElement(Box11, { 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)),
1327
- /* @__PURE__ */ React15.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1485
+ /* @__PURE__ */ React19.createElement(Icon, { fontSize: "small", color: "action" }),
1486
+ /* @__PURE__ */ React19.createElement(Box15, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React19.createElement(Typography11, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React19.createElement(Typography11, { variant: "caption", color: "text.secondary" }, subtitle)),
1487
+ /* @__PURE__ */ React19.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1328
1488
  );
1329
1489
  }
1330
1490
 
@@ -1353,7 +1513,7 @@ function Promotions({ report }) {
1353
1513
  if (cards.length === 0) {
1354
1514
  return null;
1355
1515
  }
1356
- return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Typography9, { variant: "subtitle1", fontWeight: "bold" }, __16("Quick wins", "elementor")), /* @__PURE__ */ React16.createElement(Box12, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React16.createElement(
1516
+ return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(Divider2, null), /* @__PURE__ */ React20.createElement(Typography12, { variant: "subtitle1", fontWeight: "bold" }, __20("Quick actions", "elementor")), /* @__PURE__ */ React20.createElement(Box16, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React20.createElement(
1357
1517
  PromotionCard,
1358
1518
  {
1359
1519
  key,
@@ -1371,115 +1531,14 @@ function Promotions({ report }) {
1371
1531
  ))));
1372
1532
  }
1373
1533
 
1374
- // src/components/pages/issues-page.tsx
1375
- function IssuesPage({ report, onCategoryClick, onAllAuditsClick }) {
1376
- const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1377
- return /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React17.createElement(
1378
- Link,
1379
- {
1380
- component: "button",
1381
- underline: "none",
1382
- color: "inherit",
1383
- onClick: onAllAuditsClick,
1384
- sx: { textAlign: "start" }
1385
- },
1386
- /* @__PURE__ */ React17.createElement(Typography10, { variant: "subtitle1", component: "h2" }, __17("All issues", "elementor"))
1387
- ), /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, populatedCategories.map((category) => /* @__PURE__ */ React17.createElement(
1388
- IssuesCategoryRow,
1389
- {
1390
- key: category,
1391
- category,
1392
- label: CATEGORY_LABELS[category],
1393
- counts: countSeverities(report, category),
1394
- onClick: () => onCategoryClick(category)
1395
- }
1396
- ))), /* @__PURE__ */ React17.createElement(Promotions, { report }));
1397
- }
1398
-
1399
- // src/components/pages/overview-page.tsx
1400
- import * as React21 from "react";
1401
- import { Box as Box17, Chip as Chip3, Divider, Typography as Typography14 } from "@elementor/ui";
1402
- import { __ as __19, sprintf as sprintf4 } from "@wordpress/i18n";
1403
-
1404
- // src/utils/score-thresholds.ts
1405
- import { __ as __18 } from "@wordpress/i18n";
1406
- var GOOD_THRESHOLD = 90;
1407
- var OK_THRESHOLD = 50;
1408
- function getScoreTier(score) {
1409
- if (score >= GOOD_THRESHOLD) {
1410
- return { color: "success", label: __18("Good", "elementor") };
1411
- }
1412
- if (score >= OK_THRESHOLD) {
1413
- return { color: "warning", label: __18("Needs work", "elementor") };
1414
- }
1415
- return { color: "error", label: __18("At risk", "elementor") };
1416
- }
1417
-
1418
- // src/components/count-summary-circle.tsx
1419
- import * as React18 from "react";
1420
- import { Box as Box14, Chip as Chip2, Typography as Typography11 } from "@elementor/ui";
1421
- var COUNT_SUMMARY_CIRCLE_SIZE = 64;
1422
- var COUNT_SUMMARY_BORDER_WIDTH = 4;
1423
- function chipBorderColor(theme, color) {
1424
- if (color === "default" || !color) {
1425
- return theme.palette.text.secondary;
1426
- }
1427
- return theme.palette[color].main;
1428
- }
1429
- function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
1430
- return /* @__PURE__ */ React18.createElement(
1431
- Box14,
1432
- {
1433
- "aria-label": ariaLabel,
1434
- component: "button",
1435
- onClick,
1436
- type: "button",
1437
- sx: {
1438
- alignItems: "center",
1439
- background: "none",
1440
- border: "none",
1441
- cursor: "pointer",
1442
- display: "flex",
1443
- flex: 1,
1444
- flexDirection: "column",
1445
- gap: 0.5,
1446
- padding: 0
1447
- }
1448
- },
1449
- /* @__PURE__ */ React18.createElement(
1450
- Chip2,
1451
- {
1452
- color,
1453
- label: count,
1454
- size: "small",
1455
- variant: "standard",
1456
- sx: (theme) => ({
1457
- border: `${COUNT_SUMMARY_BORDER_WIDTH}px solid ${chipBorderColor(theme, color)}`,
1458
- borderRadius: "50%",
1459
- height: COUNT_SUMMARY_CIRCLE_SIZE,
1460
- maxWidth: COUNT_SUMMARY_CIRCLE_SIZE,
1461
- width: COUNT_SUMMARY_CIRCLE_SIZE,
1462
- "& .MuiChip-label": {
1463
- fontSize: theme.typography.body2.fontSize,
1464
- fontWeight: 700,
1465
- lineHeight: 1,
1466
- padding: 0
1467
- }
1468
- })
1469
- }
1470
- ),
1471
- /* @__PURE__ */ React18.createElement(Typography11, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
1472
- );
1473
- }
1474
-
1475
1534
  // src/components/score-bar.tsx
1476
- import * as React19 from "react";
1535
+ import * as React21 from "react";
1477
1536
  import { ChevronRightIcon as ChevronRightIcon2 } from "@elementor/icons";
1478
- import { Box as Box15, LinearProgress, Rotate as Rotate3, Typography as Typography12, useTheme as useTheme3 } from "@elementor/ui";
1537
+ import { Box as Box17, LinearProgress, Rotate as Rotate3, Typography as Typography13, useTheme as useTheme3 } from "@elementor/ui";
1479
1538
  function ScoreBar({ label, score, onClick }) {
1480
1539
  const isRtl = "rtl" === useTheme3().direction;
1481
- return /* @__PURE__ */ React19.createElement(
1482
- Box15,
1540
+ return /* @__PURE__ */ React21.createElement(
1541
+ Box17,
1483
1542
  {
1484
1543
  role: onClick ? "button" : void 0,
1485
1544
  tabIndex: onClick ? 0 : void 0,
@@ -1495,8 +1554,8 @@ function ScoreBar({ label, score, onClick }) {
1495
1554
  py: 0.5
1496
1555
  }
1497
1556
  },
1498
- /* @__PURE__ */ React19.createElement(Typography12, { variant: "body2", sx: { minWidth: 96 } }, label),
1499
- /* @__PURE__ */ React19.createElement(
1557
+ /* @__PURE__ */ React21.createElement(Typography13, { variant: "body2", sx: { minWidth: 96 } }, label),
1558
+ /* @__PURE__ */ React21.createElement(
1500
1559
  LinearProgress,
1501
1560
  {
1502
1561
  variant: "determinate",
@@ -1505,8 +1564,8 @@ function ScoreBar({ label, score, onClick }) {
1505
1564
  sx: { flex: 1, height: 6, borderRadius: 4, bgcolor: "action.disabledBackground" }
1506
1565
  }
1507
1566
  ),
1508
- /* @__PURE__ */ React19.createElement(
1509
- Typography12,
1567
+ /* @__PURE__ */ React21.createElement(
1568
+ Typography13,
1510
1569
  {
1511
1570
  variant: "body2",
1512
1571
  color: "text.primary",
@@ -1514,19 +1573,19 @@ function ScoreBar({ label, score, onClick }) {
1514
1573
  },
1515
1574
  score
1516
1575
  ),
1517
- onClick && /* @__PURE__ */ React19.createElement(Rotate3, { in: isRtl }, /* @__PURE__ */ React19.createElement(ChevronRightIcon2, { fontSize: "small", color: "action" }))
1576
+ onClick && /* @__PURE__ */ React21.createElement(Rotate3, { in: isRtl }, /* @__PURE__ */ React21.createElement(ChevronRightIcon2, { fontSize: "small", color: "action" }))
1518
1577
  );
1519
1578
  }
1520
1579
 
1521
1580
  // src/components/score-circle.tsx
1522
- import * as React20 from "react";
1523
- import { Box as Box16, CircularProgress as CircularProgress2, Typography as Typography13 } from "@elementor/ui";
1581
+ import * as React22 from "react";
1582
+ import { Box as Box18, CircularProgress as CircularProgress2, Typography as Typography14 } from "@elementor/ui";
1524
1583
  var SCORE_CIRCLE_SIZE = 88;
1525
1584
  var SCORE_CIRCLE_THICKNESS = 3;
1526
1585
  function ScoreCircle({ color, score }) {
1527
1586
  const progressColor = color ?? getScoreTier(score).color;
1528
- return /* @__PURE__ */ React20.createElement(
1529
- Box16,
1587
+ return /* @__PURE__ */ React22.createElement(
1588
+ Box18,
1530
1589
  {
1531
1590
  role: "progressbar",
1532
1591
  "aria-valuenow": score,
@@ -1534,7 +1593,7 @@ function ScoreCircle({ color, score }) {
1534
1593
  "aria-valuemax": 100,
1535
1594
  sx: { position: "relative", display: "inline-flex" }
1536
1595
  },
1537
- /* @__PURE__ */ React20.createElement(
1596
+ /* @__PURE__ */ React22.createElement(
1538
1597
  CircularProgress2,
1539
1598
  {
1540
1599
  variant: "determinate",
@@ -1544,7 +1603,7 @@ function ScoreCircle({ color, score }) {
1544
1603
  sx: { color: "action.disabledBackground" }
1545
1604
  }
1546
1605
  ),
1547
- /* @__PURE__ */ React20.createElement(
1606
+ /* @__PURE__ */ React22.createElement(
1548
1607
  CircularProgress2,
1549
1608
  {
1550
1609
  variant: "determinate",
@@ -1555,8 +1614,8 @@ function ScoreCircle({ color, score }) {
1555
1614
  sx: { position: "absolute", left: 0 }
1556
1615
  }
1557
1616
  ),
1558
- /* @__PURE__ */ React20.createElement(
1559
- Box16,
1617
+ /* @__PURE__ */ React22.createElement(
1618
+ Box18,
1560
1619
  {
1561
1620
  sx: {
1562
1621
  position: "absolute",
@@ -1566,8 +1625,8 @@ function ScoreCircle({ color, score }) {
1566
1625
  justifyContent: "center"
1567
1626
  }
1568
1627
  },
1569
- /* @__PURE__ */ React20.createElement(
1570
- Typography13,
1628
+ /* @__PURE__ */ React22.createElement(
1629
+ Typography14,
1571
1630
  {
1572
1631
  variant: "h4",
1573
1632
  component: "span",
@@ -1581,31 +1640,11 @@ function ScoreCircle({ color, score }) {
1581
1640
  }
1582
1641
 
1583
1642
  // src/components/pages/overview-page.tsx
1584
- var STATUS_ARIA_LABELS = {
1585
- pass: (count) => sprintf4(
1586
- /* translators: %d: number of passed audits. */
1587
- __19("%d passed audits, view all", "elementor"),
1588
- count
1589
- ),
1590
- fail: (count) => sprintf4(
1591
- /* translators: %d: number of failed audit violations. */
1592
- __19("%d failed audits, view all", "elementor"),
1593
- count
1594
- ),
1595
- skipped: (count) => sprintf4(
1596
- /* translators: %d: number of skipped audits. */
1597
- __19("%d skipped audits, view all", "elementor"),
1598
- count
1599
- )
1600
- };
1601
- var STATUS_GROUPS = ["fail", "pass", "skipped"];
1602
- function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1643
+ function OverviewPage({ onCategoryClick, report }) {
1603
1644
  const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1604
- const severityCounts = countSeverities(report);
1605
- const statusCounts = auditStatusDisplayCounts(report);
1606
1645
  const overallScore = getScoreTier(report.overall);
1607
- return /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", alignItems: "center", gap: 2 } }, /* @__PURE__ */ React21.createElement(ScoreCircle, { color: overallScore.color, score: report.overall }), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React21.createElement(
1608
- Chip3,
1646
+ return /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", alignItems: "center", gap: 2 } }, /* @__PURE__ */ React23.createElement(ScoreCircle, { color: overallScore.color, score: report.overall }), /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React23.createElement(
1647
+ Chip4,
1609
1648
  {
1610
1649
  label: overallScore.label,
1611
1650
  color: overallScore.color,
@@ -1613,7 +1652,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1613
1652
  size: "small",
1614
1653
  sx: { fontWeight: 600, alignSelf: "flex-start" }
1615
1654
  }
1616
- ), /* @__PURE__ */ React21.createElement(Typography14, { variant: "body2", color: "text.secondary" }, __19("Overall score", "elementor")))), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React21.createElement(
1655
+ ), /* @__PURE__ */ React23.createElement(Typography15, { variant: "body2", color: "text.secondary" }, __21("Overall score", "elementor")))), /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React23.createElement(
1617
1656
  ScoreBar,
1618
1657
  {
1619
1658
  key: category,
@@ -1621,45 +1660,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1621
1660
  score: report.categories[category].score,
1622
1661
  onClick: () => onCategoryClick(category)
1623
1662
  }
1624
- ))), /* @__PURE__ */ React21.createElement(Divider, null), /* @__PURE__ */ React21.createElement(Typography14, { variant: "subtitle1", fontWeight: "bold" }, __19("Audit statuses", "elementor")), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React21.createElement(
1625
- CountSummaryCircle,
1626
- {
1627
- key: status,
1628
- ariaLabel: STATUS_ARIA_LABELS[status](statusCounts[status]),
1629
- color: auditStatusColor(status),
1630
- count: statusCounts[status],
1631
- label: auditStatusLabel(status),
1632
- onClick: () => onStatusClick(status)
1633
- }
1634
- ))), /* @__PURE__ */ React21.createElement(Divider, null), /* @__PURE__ */ React21.createElement(Typography14, { variant: "subtitle1", fontWeight: "bold" }, __19("Remaining issues", "elementor")), /* @__PURE__ */ React21.createElement(
1635
- Box17,
1636
- {
1637
- component: "ul",
1638
- sx: {
1639
- display: "flex",
1640
- flexDirection: "column",
1641
- gap: 1,
1642
- listStyle: "none",
1643
- m: 0,
1644
- p: 0
1645
- }
1646
- },
1647
- ALL_SEVERITIES.map((severity) => {
1648
- const count = severityCounts[severity];
1649
- return /* @__PURE__ */ React21.createElement(
1650
- Box17,
1651
- {
1652
- "aria-label": severityRemainingCountLabel(severity, count),
1653
- component: "li",
1654
- key: severity,
1655
- sx: { alignItems: "center", display: "flex", gap: 0.5 }
1656
- },
1657
- /* @__PURE__ */ React21.createElement(SeverityIcon, { severity }),
1658
- /* @__PURE__ */ React21.createElement(Typography14, { variant: "body2", fontWeight: "bold" }, count),
1659
- /* @__PURE__ */ React21.createElement(Typography14, { variant: "body2" }, severityPluralLabel(severity))
1660
- );
1661
- })
1662
- ));
1663
+ ))), /* @__PURE__ */ React23.createElement(Promotions, { report }));
1663
1664
  }
1664
1665
 
1665
1666
  // src/components/report-shell.tsx
@@ -1679,7 +1680,7 @@ function isCategoryPage(page) {
1679
1680
  return typeof page === "object" && "category" in page;
1680
1681
  }
1681
1682
  function ReportShell({ report }) {
1682
- const [activePage, setActivePage] = useState4("overview");
1683
+ const [activePage, setActivePage] = useState5("overview");
1683
1684
  const currentTab = activeTab(activePage);
1684
1685
  const handleTabChange = (_, value) => {
1685
1686
  setActivePage(value);
@@ -1695,10 +1696,10 @@ function ReportShell({ report }) {
1695
1696
  setActivePage(activePage.backTo);
1696
1697
  }
1697
1698
  };
1698
- return /* @__PURE__ */ React22.createElement(Box18, null, /* @__PURE__ */ React22.createElement(
1699
+ return /* @__PURE__ */ React24.createElement(Box20, { sx: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 } }, /* @__PURE__ */ React24.createElement(Box20, { sx: { flexShrink: 0 } }, /* @__PURE__ */ React24.createElement(
1699
1700
  Tabs,
1700
1701
  {
1701
- "aria-label": __20("Audit navigation", "elementor"),
1702
+ "aria-label": __22("Audit navigation", "elementor"),
1702
1703
  value: currentTab,
1703
1704
  onChange: handleTabChange,
1704
1705
  textColor: "secondary",
@@ -1707,30 +1708,30 @@ function ReportShell({ report }) {
1707
1708
  centered: true,
1708
1709
  variant: "fullWidth"
1709
1710
  },
1710
- /* @__PURE__ */ React22.createElement(Tab, { value: "overview", label: __20("Overview", "elementor") }),
1711
- /* @__PURE__ */ React22.createElement(Tab, { value: "issues", label: __20("Issues", "elementor") })
1712
- ), /* @__PURE__ */ React22.createElement(Divider2, null), activePage === "overview" && /* @__PURE__ */ React22.createElement(
1711
+ /* @__PURE__ */ React24.createElement(Tab, { value: "overview", label: __22("Overview", "elementor") }),
1712
+ /* @__PURE__ */ React24.createElement(Tab, { value: "issues", label: __22("Issues", "elementor") })
1713
+ ), /* @__PURE__ */ React24.createElement(Divider3, null)), /* @__PURE__ */ React24.createElement(Box20, { sx: { flex: 1, minHeight: 0, overflowY: "auto" } }, activePage === "overview" && /* @__PURE__ */ React24.createElement(
1713
1714
  OverviewPage,
1714
1715
  {
1715
1716
  report,
1716
- onCategoryClick: (category) => openCategory(category, "overview"),
1717
- onStatusClick: (status) => openAllAudits(status, "overview")
1717
+ onCategoryClick: (category) => openCategory(category, "overview")
1718
1718
  }
1719
- ), activePage === "issues" && /* @__PURE__ */ React22.createElement(
1719
+ ), activePage === "issues" && /* @__PURE__ */ React24.createElement(
1720
1720
  IssuesPage,
1721
1721
  {
1722
1722
  report,
1723
1723
  onCategoryClick: (category) => openCategory(category, "issues"),
1724
- onAllAuditsClick: () => openAllAudits()
1724
+ onAllAuditsClick: () => openAllAudits(),
1725
+ onStatusClick: (status) => openAllAudits(status)
1725
1726
  }
1726
- ), isAllAuditsPage(activePage) && /* @__PURE__ */ React22.createElement(
1727
+ ), isAllAuditsPage(activePage) && /* @__PURE__ */ React24.createElement(
1727
1728
  AllAuditsPage,
1728
1729
  {
1729
1730
  report,
1730
1731
  initialExpandedStatus: activePage.expand,
1731
1732
  onBack: backFromSubPage
1732
1733
  }
1733
- ), isCategoryPage(activePage) && /* @__PURE__ */ React22.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage }));
1734
+ ), isCategoryPage(activePage) && /* @__PURE__ */ React24.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage })));
1734
1735
  }
1735
1736
 
1736
1737
  // src/components/audit-panel.tsx
@@ -1739,15 +1740,24 @@ function AuditPanel() {
1739
1740
  const currentDocumentId = getCurrentDocumentId2() ?? 0;
1740
1741
  const onRun = () => run(currentDocumentId);
1741
1742
  const lastScanLabel = report ? new Date(report.runAt).toLocaleTimeString() : null;
1742
- return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(
1743
+ return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(
1743
1744
  FloatingPanelHeader,
1744
1745
  {
1745
1746
  panelId: "audit-panel",
1746
- title: __21("Page Audit", "elementor"),
1747
- badge: __21("Beta", "elementor"),
1747
+ title: __23("Page Audit", "elementor"),
1748
+ badge: __23("Beta", "elementor"),
1748
1749
  titleVariant: "subtitle2"
1749
1750
  }
1750
- ), /* @__PURE__ */ React23.createElement(FloatingPanelBody, null, status === "idle" && /* @__PURE__ */ React23.createElement(WelcomePage, null), status === "loading" && /* @__PURE__ */ React23.createElement(LoadingPage, null), status === "error" && /* @__PURE__ */ React23.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }), status === "ready" && report && /* @__PURE__ */ React23.createElement(ReportShell, { report })), /* @__PURE__ */ React23.createElement(FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React23.createElement(Typography15, { variant: "caption", sx: { flex: 1 } }, __21("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React23.createElement(Box19, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React23.createElement(AuditFeedback, null), /* @__PURE__ */ React23.createElement(
1751
+ ), /* @__PURE__ */ React25.createElement(
1752
+ FloatingPanelBody,
1753
+ {
1754
+ sx: status === "ready" ? { display: "flex", flexDirection: "column", overflow: "hidden", minHeight: 0 } : void 0
1755
+ },
1756
+ status === "idle" && /* @__PURE__ */ React25.createElement(WelcomePage, null),
1757
+ status === "loading" && /* @__PURE__ */ React25.createElement(LoadingPage, null),
1758
+ status === "error" && /* @__PURE__ */ React25.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }),
1759
+ status === "ready" && report && /* @__PURE__ */ React25.createElement(ReportShell, { report })
1760
+ ), /* @__PURE__ */ React25.createElement(FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React25.createElement(Typography16, { variant: "caption", sx: { flex: 1 } }, __23("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React25.createElement(Box21, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React25.createElement(AuditFeedback, null), /* @__PURE__ */ React25.createElement(
1751
1761
  Button5,
1752
1762
  {
1753
1763
  variant: "contained",
@@ -1755,7 +1765,7 @@ function AuditPanel() {
1755
1765
  onClick: onRun,
1756
1766
  disabled: status === "loading" || currentDocumentId === 0
1757
1767
  },
1758
- lastScanLabel ? __21("Re-scan", "elementor") : __21("Run page audit", "elementor")
1768
+ lastScanLabel ? __23("Re-scan", "elementor") : __23("Run page audit", "elementor")
1759
1769
  )));
1760
1770
  }
1761
1771
 
@@ -1780,8 +1790,8 @@ function useAuditToggleProps() {
1780
1790
  const { isOpen } = auditPanel.useFloatingPanelStatus();
1781
1791
  const { toggle } = auditPanel.useFloatingPanelActions();
1782
1792
  return {
1783
- title: __22("Audit Page", "elementor"),
1784
- icon: ShieldCheckIcon2,
1793
+ title: __24("Audit Page", "elementor"),
1794
+ icon: ShieldCheckIcon3,
1785
1795
  selected: isOpen,
1786
1796
  onClick: () => toggle()
1787
1797
  };
@@ -1798,15 +1808,15 @@ function registerAppBarAuditsToggle() {
1798
1808
  }
1799
1809
 
1800
1810
  // src/audits/accessibility-policy.ts
1801
- import { __ as __23 } from "@wordpress/i18n";
1811
+ import { __ as __25 } from "@wordpress/i18n";
1802
1812
  var audit = {
1803
1813
  id: "audits/accessibility-policy",
1804
- title: __23("Accessibility policy", "elementor"),
1805
- description: __23(
1814
+ title: __25("Accessibility policy", "elementor"),
1815
+ description: __25(
1806
1816
  "An accessibility policy demonstrates your commitment to digital inclusion and may be legally required in some regions.",
1807
1817
  "elementor"
1808
1818
  ),
1809
- fixHint: __23("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1819
+ fixHint: __25("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1810
1820
  categories: ["compliance"],
1811
1821
  severity: "info",
1812
1822
  weight: 1,
@@ -1819,7 +1829,7 @@ var audit = {
1819
1829
  violations: [
1820
1830
  {
1821
1831
  auditId: audit.id,
1822
- label: __23("Ally plugin is not installed or active.", "elementor"),
1832
+ label: __25("Ally plugin is not installed or active.", "elementor"),
1823
1833
  externalUrl: ctx.pageContext.ally_plugin_url
1824
1834
  }
1825
1835
  ]
@@ -1828,15 +1838,15 @@ var audit = {
1828
1838
  };
1829
1839
 
1830
1840
  // src/audits/cookie-policy.ts
1831
- import { __ as __24 } from "@wordpress/i18n";
1841
+ import { __ as __26 } from "@wordpress/i18n";
1832
1842
  var audit2 = {
1833
1843
  id: "audits/cookie-policy",
1834
- title: __24("Cookie policy", "elementor"),
1835
- description: __24(
1844
+ title: __26("Cookie policy", "elementor"),
1845
+ description: __26(
1836
1846
  "A cookie policy is required by privacy regulations such as GDPR (EU) or CCPA (US) to inform visitors about tracking and data collection.",
1837
1847
  "elementor"
1838
1848
  ),
1839
- fixHint: __24("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1849
+ fixHint: __26("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1840
1850
  categories: ["compliance"],
1841
1851
  severity: "info",
1842
1852
  weight: 1,
@@ -1849,7 +1859,7 @@ var audit2 = {
1849
1859
  violations: [
1850
1860
  {
1851
1861
  auditId: audit2.id,
1852
- label: __24("Cookiez plugin is not installed or active.", "elementor"),
1862
+ label: __26("Cookiez plugin is not installed or active.", "elementor"),
1853
1863
  externalUrl: ctx.pageContext.cookiez_plugin_url
1854
1864
  }
1855
1865
  ]
@@ -1858,35 +1868,43 @@ var audit2 = {
1858
1868
  };
1859
1869
 
1860
1870
  // src/audits/deep-nesting.ts
1861
- import { __ as __25 } from "@wordpress/i18n";
1871
+ import { getWidgetsCache } from "@elementor/editor-elements";
1872
+ import { __ as __27 } from "@wordpress/i18n";
1862
1873
  var MAX_NESTING_DEPTH = 6;
1874
+ function isNestingElement(node, widgetsCache) {
1875
+ if (node.elType === "container") {
1876
+ return true;
1877
+ }
1878
+ return !!widgetsCache?.[node.elType]?.meta?.is_container;
1879
+ }
1863
1880
  var audit3 = {
1864
1881
  id: "audits/deep-nesting",
1865
- title: __25("Deep container nesting", "elementor"),
1866
- description: __25(
1882
+ title: __27("Deep container nesting", "elementor"),
1883
+ description: __27(
1867
1884
  "Container nesting exceeds the recommended depth. Deep DOM trees hurt rendering performance and readability.",
1868
1885
  "elementor"
1869
1886
  ),
1870
- fixHint: __25("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1887
+ fixHint: __27("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1871
1888
  categories: ["performance", "best-practices"],
1872
1889
  severity: "warning",
1873
1890
  weight: 5,
1874
1891
  evaluate: (ctx) => {
1875
1892
  if (ctx.elements.tree.length === 0) {
1876
- return { status: "skipped", reason: __25("No elements", "elementor") };
1893
+ return { status: "skipped", reason: __27("No elements", "elementor") };
1877
1894
  }
1895
+ const widgetsCache = getWidgetsCache();
1878
1896
  const violations = [];
1879
1897
  walkElements(ctx.elements.tree, (node, parents) => {
1880
- if (node.elType !== "container") {
1898
+ if (!isNestingElement(node, widgetsCache)) {
1881
1899
  return;
1882
1900
  }
1883
- const depth = parents.length + 1;
1901
+ const depth = parents.filter((parent) => isNestingElement(parent, widgetsCache)).length + 1;
1884
1902
  if (depth > MAX_NESTING_DEPTH) {
1885
1903
  violations.push({
1886
1904
  auditId: audit3.id,
1887
1905
  elementId: node.id,
1888
1906
  targetHint: "element-settings",
1889
- label: __25("Container nesting is too deep.", "elementor")
1907
+ label: __27("Container nesting is too deep.", "elementor")
1890
1908
  });
1891
1909
  }
1892
1910
  });
@@ -1895,15 +1913,15 @@ var audit3 = {
1895
1913
  };
1896
1914
 
1897
1915
  // src/audits/default-design-system.ts
1898
- import { __ as __26 } from "@wordpress/i18n";
1916
+ import { __ as __28 } from "@wordpress/i18n";
1899
1917
  var audit4 = {
1900
1918
  id: "audits/default-design-system",
1901
- title: __26("Default website kit", "elementor"),
1902
- description: __26(
1919
+ title: __28("Default website kit", "elementor"),
1920
+ description: __28(
1903
1921
  "Your website is using the default design system colors and fonts. Custom branding makes the website feel uniquely yours.",
1904
1922
  "elementor"
1905
1923
  ),
1906
- fixHint: __26("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1924
+ fixHint: __28("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1907
1925
  categories: ["best-practices"],
1908
1926
  severity: "info",
1909
1927
  weight: 1,
@@ -1916,7 +1934,7 @@ var audit4 = {
1916
1934
  violations: [
1917
1935
  {
1918
1936
  auditId: audit4.id,
1919
- label: __26("Kit appears unchanged from default.", "elementor"),
1937
+ label: __28("Kit appears unchanged from default.", "elementor"),
1920
1938
  targetHint: "site-settings"
1921
1939
  }
1922
1940
  ]
@@ -1925,22 +1943,22 @@ var audit4 = {
1925
1943
  };
1926
1944
 
1927
1945
  // src/audits/deprecated-widgets.ts
1928
- import { getWidgetsCache } from "@elementor/editor-elements";
1929
- import { __ as __27 } from "@wordpress/i18n";
1946
+ import { getWidgetsCache as getWidgetsCache2 } from "@elementor/editor-elements";
1947
+ import { __ as __29 } from "@wordpress/i18n";
1930
1948
  var DEPRECATION_CONTROL_NAME = "deprecation_message";
1931
1949
  var audit5 = {
1932
1950
  id: "audits/deprecated-widgets",
1933
- title: __27("Deprecated widgets", "elementor"),
1934
- description: __27(
1951
+ title: __29("Deprecated widgets", "elementor"),
1952
+ description: __29(
1935
1953
  "Deprecated widgets should not be used. For better capabilities use the recommended replacement.",
1936
1954
  "elementor"
1937
1955
  ),
1938
- fixHint: __27("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1956
+ fixHint: __29("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1939
1957
  categories: ["best-practices", "performance"],
1940
1958
  severity: "warning",
1941
1959
  weight: 7,
1942
1960
  evaluate: (ctx) => {
1943
- const widgetsCache = getWidgetsCache();
1961
+ const widgetsCache = getWidgetsCache2();
1944
1962
  if (!widgetsCache) {
1945
1963
  return { status: "skipped", reason: "widgets-cache-unavailable" };
1946
1964
  }
@@ -1962,7 +1980,7 @@ var audit5 = {
1962
1980
  auditId: audit5.id,
1963
1981
  elementId: node.id,
1964
1982
  targetHint: "element-settings",
1965
- label: __27("Using deprecated widget.", "elementor")
1983
+ label: __29("Using deprecated widget.", "elementor")
1966
1984
  });
1967
1985
  });
1968
1986
  return violations.length === 0 ? { status: "pass" } : { status: "fail", violations };
@@ -1970,7 +1988,7 @@ var audit5 = {
1970
1988
  };
1971
1989
 
1972
1990
  // src/audits/google-consent-mode.ts
1973
- import { __ as __28 } from "@wordpress/i18n";
1991
+ import { __ as __30 } from "@wordpress/i18n";
1974
1992
 
1975
1993
  // src/utils/fetch-rendered-html.ts
1976
1994
  var FETCH_TIMEOUT_MS = 1e4;
@@ -2014,12 +2032,12 @@ function hasConsentDefaultCall(html) {
2014
2032
  // src/audits/google-consent-mode.ts
2015
2033
  var audit6 = {
2016
2034
  id: "audits/google-consent-mode",
2017
- title: __28("Google Consent Mode", "elementor"),
2018
- description: __28(
2035
+ title: __30("Google Consent Mode", "elementor"),
2036
+ description: __30(
2019
2037
  "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.",
2020
2038
  "elementor"
2021
2039
  ),
2022
- fixHint: __28(
2040
+ fixHint: __30(
2023
2041
  "Turn on Google Consent Mode in your cookie consent plugin so Google tags respect visitor consent choices.",
2024
2042
  "elementor"
2025
2043
  ),
@@ -2028,19 +2046,19 @@ var audit6 = {
2028
2046
  weight: 1,
2029
2047
  evaluate: async (ctx) => {
2030
2048
  if (!ctx.pageContext.frontend_url) {
2031
- return { status: "skipped", reason: __28("Page is not published.", "elementor") };
2049
+ return { status: "skipped", reason: __30("Page is not published.", "elementor") };
2032
2050
  }
2033
2051
  const html = await fetchRenderedHtml(ctx.pageContext.frontend_url);
2034
2052
  if (!html) {
2035
- return { status: "skipped", reason: __28("Could not fetch the published page.", "elementor") };
2053
+ return { status: "skipped", reason: __30("Could not fetch the published page.", "elementor") };
2036
2054
  }
2037
2055
  if (!hasGoogleTracking(html)) {
2038
- return { status: "skipped", reason: __28("No Google tracking product detected.", "elementor") };
2056
+ return { status: "skipped", reason: __30("No Google tracking product detected.", "elementor") };
2039
2057
  }
2040
2058
  if (hasConsentDefaultCall(html)) {
2041
2059
  return { status: "pass" };
2042
2060
  }
2043
- const label = __28("No Google Consent Mode signal was found on the page.", "elementor");
2061
+ const label = __30("No Google Consent Mode signal was found on the page.", "elementor");
2044
2062
  const isCookiezReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
2045
2063
  if (isCookiezReady) {
2046
2064
  return {
@@ -2049,7 +2067,7 @@ var audit6 = {
2049
2067
  {
2050
2068
  auditId: audit6.id,
2051
2069
  label,
2052
- ctaLabel: __28("Enable", "elementor"),
2070
+ ctaLabel: __30("Enable", "elementor"),
2053
2071
  externalUrl: ctx.pageContext.cookiez_consent_mode_settings_url
2054
2072
  }
2055
2073
  ]
@@ -2069,7 +2087,7 @@ var audit6 = {
2069
2087
  };
2070
2088
 
2071
2089
  // src/audits/heading-structure.ts
2072
- import { __ as __29 } from "@wordpress/i18n";
2090
+ import { __ as __31 } from "@wordpress/i18n";
2073
2091
  var HEADING_LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
2074
2092
  var HEADING_CONTROLS_REGISTRY = {
2075
2093
  // Core
@@ -2247,27 +2265,27 @@ function extractPageHeadings(tree) {
2247
2265
  }
2248
2266
  var audit7 = {
2249
2267
  id: "audits/heading-structure",
2250
- title: __29("Heading structure", "elementor"),
2251
- description: __29("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2252
- fixHint: __29("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2268
+ title: __31("Heading structure", "elementor"),
2269
+ description: __31("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2270
+ fixHint: __31("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2253
2271
  categories: ["seo", "accessibility"],
2254
2272
  severity: "error",
2255
2273
  weight: 10,
2256
2274
  evaluate: (ctx) => {
2257
2275
  if (ctx.elements.tree.length === 0) {
2258
- return { status: "skipped", reason: __29("No elements", "elementor") };
2276
+ return { status: "skipped", reason: __31("No elements", "elementor") };
2259
2277
  }
2260
2278
  const headings = extractPageHeadings(ctx.elements.tree);
2261
2279
  const violations = [];
2262
2280
  if (headings.length === 0) {
2263
2281
  violations.push({
2264
2282
  auditId: audit7.id,
2265
- label: __29("No headings found on the page.", "elementor")
2283
+ label: __31("No headings found on the page.", "elementor")
2266
2284
  });
2267
2285
  } else {
2268
2286
  const h1Count = headings.filter((h) => h.level === 1).length;
2269
2287
  if (h1Count === 0) {
2270
- violations.push({ auditId: audit7.id, label: __29("No H1 on the page.", "elementor") });
2288
+ violations.push({ auditId: audit7.id, label: __31("No H1 on the page.", "elementor") });
2271
2289
  }
2272
2290
  if (h1Count > 1) {
2273
2291
  headings.filter((h) => h.level === 1).slice(1).forEach(
@@ -2275,7 +2293,7 @@ var audit7 = {
2275
2293
  auditId: audit7.id,
2276
2294
  elementId: h.elementId,
2277
2295
  targetHint: "element-settings",
2278
- label: __29("More than one H1 on the page.", "elementor")
2296
+ label: __31("More than one H1 on the page.", "elementor")
2279
2297
  })
2280
2298
  );
2281
2299
  }
@@ -2285,7 +2303,7 @@ var audit7 = {
2285
2303
  auditId: audit7.id,
2286
2304
  elementId: headings[i].elementId,
2287
2305
  targetHint: "element-settings",
2288
- label: __29("Heading level skipped.", "elementor")
2306
+ label: __31("Heading level skipped.", "elementor")
2289
2307
  });
2290
2308
  }
2291
2309
  }
@@ -2295,24 +2313,24 @@ var audit7 = {
2295
2313
  };
2296
2314
 
2297
2315
  // src/audits/hidden-elements.ts
2298
- import { __ as __30 } from "@wordpress/i18n";
2316
+ import { __ as __32 } from "@wordpress/i18n";
2299
2317
  function isHiddenOnAllDevices(settings) {
2300
2318
  return Boolean(settings.hide_desktop) && Boolean(settings.hide_tablet) && Boolean(settings.hide_mobile);
2301
2319
  }
2302
2320
  var audit8 = {
2303
2321
  id: "audits/hidden-elements",
2304
- title: __30("Hidden elements", "elementor"),
2305
- description: __30(
2322
+ title: __32("Hidden elements", "elementor"),
2323
+ description: __32(
2306
2324
  "Elements hidden on all devices simultaneously are effectively dead code in the page tree.",
2307
2325
  "elementor"
2308
2326
  ),
2309
- fixHint: __30("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2327
+ fixHint: __32("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2310
2328
  categories: ["best-practices", "performance"],
2311
2329
  severity: "info",
2312
2330
  weight: 3,
2313
2331
  evaluate: (ctx) => {
2314
2332
  if (ctx.elements.tree.length === 0) {
2315
- return { status: "skipped", reason: __30("No elements", "elementor") };
2333
+ return { status: "skipped", reason: __32("No elements", "elementor") };
2316
2334
  }
2317
2335
  const violations = [];
2318
2336
  walkElements(ctx.elements.tree, (node) => {
@@ -2321,7 +2339,7 @@ var audit8 = {
2321
2339
  auditId: audit8.id,
2322
2340
  elementId: node.id,
2323
2341
  targetHint: "element-settings",
2324
- label: __30("Element is hidden on all devices.", "elementor")
2342
+ label: __32("Element is hidden on all devices.", "elementor")
2325
2343
  });
2326
2344
  }
2327
2345
  });
@@ -2330,7 +2348,7 @@ var audit8 = {
2330
2348
  };
2331
2349
 
2332
2350
  // src/audits/images-alt-text.ts
2333
- import { __ as __31 } from "@wordpress/i18n";
2351
+ import { __ as __33 } from "@wordpress/i18n";
2334
2352
 
2335
2353
  // src/utils/image-alt.ts
2336
2354
  function hasMeaningfulAlt(media, pageContext) {
@@ -2350,15 +2368,15 @@ function isImageSourcePresent(media) {
2350
2368
  // src/audits/images-alt-text.ts
2351
2369
  var audit9 = {
2352
2370
  id: "audits/images-alt-text",
2353
- title: __31("Images alt text", "elementor"),
2354
- description: __31("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2355
- fixHint: __31("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2371
+ title: __33("Images alt text", "elementor"),
2372
+ description: __33("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2373
+ fixHint: __33("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2356
2374
  categories: ["seo", "accessibility"],
2357
2375
  severity: "error",
2358
2376
  weight: 10,
2359
2377
  evaluate: (ctx) => {
2360
2378
  if (!hasPageImages(ctx.elements.tree)) {
2361
- return { status: "skipped", reason: __31("No images", "elementor") };
2379
+ return { status: "skipped", reason: __33("No images", "elementor") };
2362
2380
  }
2363
2381
  const violations = [];
2364
2382
  const failedWidgetIds = /* @__PURE__ */ new Set();
@@ -2374,7 +2392,7 @@ var audit9 = {
2374
2392
  auditId: audit9.id,
2375
2393
  elementId: node.id,
2376
2394
  targetHint: "element-settings",
2377
- label: __31("Image is missing alt text.", "elementor"),
2395
+ label: __33("Image is missing alt text.", "elementor"),
2378
2396
  externalUrl: ctx.pageContext.ally_plugin_url
2379
2397
  });
2380
2398
  }
@@ -2384,20 +2402,20 @@ var audit9 = {
2384
2402
  };
2385
2403
 
2386
2404
  // src/audits/images-too-large.ts
2387
- import { __ as __32, sprintf as sprintf5 } from "@wordpress/i18n";
2405
+ import { __ as __34, sprintf as sprintf4 } from "@wordpress/i18n";
2388
2406
  var SIZE_THRESHOLD_BYTES = 500 * 1024;
2389
2407
  var BYTES_PER_KB = 1024;
2390
2408
  var audit10 = {
2391
2409
  id: "audits/images-too-large",
2392
- title: __32("Oversized images", "elementor"),
2393
- description: __32("Large image files slow down the page.", "elementor"),
2394
- fixHint: __32("Replace the image with a smaller version or enable image optimization.", "elementor"),
2410
+ title: __34("Oversized images", "elementor"),
2411
+ description: __34("Large image files slow down the page.", "elementor"),
2412
+ fixHint: __34("Replace the image with a smaller version or enable image optimization.", "elementor"),
2395
2413
  categories: ["performance"],
2396
2414
  severity: "warning",
2397
2415
  weight: 7,
2398
2416
  evaluate: (ctx) => {
2399
2417
  if (!hasPageImages(ctx.elements.tree)) {
2400
- return { status: "skipped", reason: __32("No images", "elementor") };
2418
+ return { status: "skipped", reason: __34("No images", "elementor") };
2401
2419
  }
2402
2420
  const widgetMaxKb = /* @__PURE__ */ new Map();
2403
2421
  let oversizedImageCount = 0;
@@ -2419,9 +2437,9 @@ var audit10 = {
2419
2437
  auditId: audit10.id,
2420
2438
  elementId,
2421
2439
  targetHint: "element-settings",
2422
- label: sprintf5(
2440
+ label: sprintf4(
2423
2441
  /* translators: %d is the image file size in kilobytes. */
2424
- __32("Image is %d KB (over 500 KB).", "elementor"),
2442
+ __34("Image is %d KB (over 500 KB).", "elementor"),
2425
2443
  kb
2426
2444
  ),
2427
2445
  externalUrl: ctx.pageContext.image_optimization_plugin_url
@@ -2431,21 +2449,21 @@ var audit10 = {
2431
2449
  };
2432
2450
 
2433
2451
  // src/audits/nested-boxed-containers.ts
2434
- import { __ as __33 } from "@wordpress/i18n";
2452
+ import { __ as __35 } from "@wordpress/i18n";
2435
2453
  function isBoxed(settings) {
2436
2454
  return settings.content_width === "boxed";
2437
2455
  }
2438
2456
  var audit11 = {
2439
2457
  id: "audits/nested-boxed-containers",
2440
- title: __33("Boxed container nested inside a boxed parent", "elementor"),
2441
- description: __33("An inner container does not need to be boxed when its parent already is.", "elementor"),
2442
- fixHint: __33("Change the inner container's content width to Full Width.", "elementor"),
2458
+ title: __35("Boxed container nested inside a boxed parent", "elementor"),
2459
+ description: __35("An inner container does not need to be boxed when its parent already is.", "elementor"),
2460
+ fixHint: __35("Change the inner container's content width to Full Width.", "elementor"),
2443
2461
  categories: ["best-practices", "performance"],
2444
2462
  severity: "info",
2445
2463
  weight: 5,
2446
2464
  evaluate: (ctx) => {
2447
2465
  if (ctx.elements.tree.length === 0) {
2448
- return { status: "skipped", reason: __33("No elements", "elementor") };
2466
+ return { status: "skipped", reason: __35("No elements", "elementor") };
2449
2467
  }
2450
2468
  const violations = [];
2451
2469
  walkElements(ctx.elements.tree, (node, parents) => {
@@ -2458,7 +2476,7 @@ var audit11 = {
2458
2476
  auditId: audit11.id,
2459
2477
  elementId: node.id,
2460
2478
  targetHint: "element-settings",
2461
- label: __33("Nested boxed container.", "elementor")
2479
+ label: __35("Nested boxed container.", "elementor")
2462
2480
  });
2463
2481
  }
2464
2482
  });
@@ -2467,12 +2485,12 @@ var audit11 = {
2467
2485
  };
2468
2486
 
2469
2487
  // src/audits/page-excerpt.ts
2470
- import { __ as __34 } from "@wordpress/i18n";
2488
+ import { __ as __36 } from "@wordpress/i18n";
2471
2489
  var audit12 = {
2472
2490
  id: "audits/page-excerpt",
2473
- title: __34("Page excerpt", "elementor"),
2474
- description: __34("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2475
- fixHint: __34("Open Page Settings and write a short excerpt.", "elementor"),
2491
+ title: __36("Page excerpt", "elementor"),
2492
+ description: __36("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2493
+ fixHint: __36("Open Page Settings and write a short excerpt.", "elementor"),
2476
2494
  categories: ["seo"],
2477
2495
  severity: "warning",
2478
2496
  weight: 5,
@@ -2485,7 +2503,7 @@ var audit12 = {
2485
2503
  violations: [
2486
2504
  {
2487
2505
  auditId: audit12.id,
2488
- label: __34("Page has no excerpt.", "elementor"),
2506
+ label: __36("Page has no excerpt.", "elementor"),
2489
2507
  targetHint: "page-settings",
2490
2508
  angieFix: true
2491
2509
  }
@@ -2495,12 +2513,12 @@ var audit12 = {
2495
2513
  };
2496
2514
 
2497
2515
  // src/audits/page-featured-image.ts
2498
- import { __ as __35 } from "@wordpress/i18n";
2516
+ import { __ as __37 } from "@wordpress/i18n";
2499
2517
  var audit13 = {
2500
2518
  id: "audits/page-featured-image",
2501
- title: __35("Page featured image", "elementor"),
2502
- description: __35("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2503
- fixHint: __35("Open Page Settings and set a featured image.", "elementor"),
2519
+ title: __37("Page featured image", "elementor"),
2520
+ description: __37("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2521
+ fixHint: __37("Open Page Settings and set a featured image.", "elementor"),
2504
2522
  categories: ["seo"],
2505
2523
  severity: "info",
2506
2524
  weight: 5,
@@ -2513,7 +2531,7 @@ var audit13 = {
2513
2531
  violations: [
2514
2532
  {
2515
2533
  auditId: audit13.id,
2516
- label: __35("No featured image set.", "elementor"),
2534
+ label: __37("No featured image set.", "elementor"),
2517
2535
  targetHint: "page-settings"
2518
2536
  }
2519
2537
  ]
@@ -2522,13 +2540,13 @@ var audit13 = {
2522
2540
  };
2523
2541
 
2524
2542
  // src/audits/page-title.ts
2525
- import { __ as __36 } from "@wordpress/i18n";
2543
+ import { __ as __38 } from "@wordpress/i18n";
2526
2544
  var MAX_TITLE_LENGTH = 60;
2527
2545
  var audit14 = {
2528
2546
  id: "audits/page-title",
2529
- title: __36("Page title", "elementor"),
2530
- description: __36("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2531
- fixHint: __36("Open Page Settings and add a title.", "elementor"),
2547
+ title: __38("Page title", "elementor"),
2548
+ description: __38("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2549
+ fixHint: __38("Open Page Settings and add a title.", "elementor"),
2532
2550
  categories: ["seo"],
2533
2551
  severity: "error",
2534
2552
  weight: 10,
@@ -2540,7 +2558,7 @@ var audit14 = {
2540
2558
  violations: [
2541
2559
  {
2542
2560
  auditId: audit14.id,
2543
- label: __36("Page has no title.", "elementor"),
2561
+ label: __38("Page has no title.", "elementor"),
2544
2562
  targetHint: "page-settings",
2545
2563
  angieFix: true
2546
2564
  }
@@ -2553,7 +2571,7 @@ var audit14 = {
2553
2571
  violations: [
2554
2572
  {
2555
2573
  auditId: audit14.id,
2556
- label: __36("Page title is too long.", "elementor"),
2574
+ label: __38("Page title is too long.", "elementor"),
2557
2575
  targetHint: "page-settings",
2558
2576
  angieFix: true
2559
2577
  }
@@ -2565,7 +2583,7 @@ var audit14 = {
2565
2583
  };
2566
2584
 
2567
2585
  // src/audits/prefer-global-colors.ts
2568
- import { __ as __37, sprintf as sprintf6 } from "@wordpress/i18n";
2586
+ import { __ as __39, sprintf as sprintf5 } from "@wordpress/i18n";
2569
2587
 
2570
2588
  // src/utils/collect-hardcoded-colors.ts
2571
2589
  var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2633,18 +2651,18 @@ function findMatchingGlobalByValue(value, globals) {
2633
2651
  // src/audits/prefer-global-colors.ts
2634
2652
  var audit15 = {
2635
2653
  id: "audits/prefer-global-colors",
2636
- title: __37("Prefer global colors", "elementor"),
2637
- description: __37("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2638
- fixHint: __37("Replace the hard-coded value with the matching global color.", "elementor"),
2654
+ title: __39("Prefer global colors", "elementor"),
2655
+ description: __39("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2656
+ fixHint: __39("Replace the hard-coded value with the matching global color.", "elementor"),
2639
2657
  categories: ["best-practices"],
2640
2658
  severity: "info",
2641
2659
  weight: 3,
2642
2660
  evaluate: (ctx) => {
2643
2661
  if (ctx.elements.tree.length === 0) {
2644
- return { status: "skipped", reason: __37("No elements", "elementor") };
2662
+ return { status: "skipped", reason: __39("No elements", "elementor") };
2645
2663
  }
2646
2664
  if (ctx.kit.globals.colors.length === 0) {
2647
- return { status: "skipped", reason: __37("No global colors", "elementor") };
2665
+ return { status: "skipped", reason: __39("No global colors", "elementor") };
2648
2666
  }
2649
2667
  const violations = [];
2650
2668
  walkElements(ctx.elements.tree, (node) => {
@@ -2658,9 +2676,9 @@ var audit15 = {
2658
2676
  elementId: node.id,
2659
2677
  targetHint: "element-settings",
2660
2678
  angieFix: true,
2661
- label: sprintf6(
2679
+ label: sprintf5(
2662
2680
  /* translators: 1: hard-coded color value, 2: global color title. */
2663
- __37('replace "%1$s" with "%2$s" global color', "elementor"),
2681
+ __39('replace "%1$s" with "%2$s" global color', "elementor"),
2664
2682
  value,
2665
2683
  global.title
2666
2684
  )
@@ -2672,7 +2690,7 @@ var audit15 = {
2672
2690
  };
2673
2691
 
2674
2692
  // src/audits/prefer-global-fonts.ts
2675
- import { __ as __38, sprintf as sprintf7 } from "@wordpress/i18n";
2693
+ import { __ as __40, sprintf as sprintf6 } from "@wordpress/i18n";
2676
2694
 
2677
2695
  // src/utils/collect-hardcoded-fonts.ts
2678
2696
  var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2732,18 +2750,18 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
2732
2750
  // src/audits/prefer-global-fonts.ts
2733
2751
  var audit16 = {
2734
2752
  id: "audits/prefer-global-fonts",
2735
- title: __38("Prefer global fonts", "elementor"),
2736
- description: __38("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2737
- fixHint: __38("Replace the hard-coded value with the matching global font.", "elementor"),
2753
+ title: __40("Prefer global fonts", "elementor"),
2754
+ description: __40("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2755
+ fixHint: __40("Replace the hard-coded value with the matching global font.", "elementor"),
2738
2756
  categories: ["best-practices", "performance"],
2739
2757
  severity: "info",
2740
2758
  weight: 3,
2741
2759
  evaluate: (ctx) => {
2742
2760
  if (ctx.elements.tree.length === 0) {
2743
- return { status: "skipped", reason: __38("No elements", "elementor") };
2761
+ return { status: "skipped", reason: __40("No elements", "elementor") };
2744
2762
  }
2745
2763
  if (ctx.kit.globals.fonts.length === 0) {
2746
- return { status: "skipped", reason: __38("No global fonts", "elementor") };
2764
+ return { status: "skipped", reason: __40("No global fonts", "elementor") };
2747
2765
  }
2748
2766
  const violations = [];
2749
2767
  walkElements(ctx.elements.tree, (node) => {
@@ -2756,9 +2774,9 @@ var audit16 = {
2756
2774
  auditId: audit16.id,
2757
2775
  elementId: node.id,
2758
2776
  targetHint: "element-settings",
2759
- label: sprintf7(
2777
+ label: sprintf6(
2760
2778
  /* translators: %s: global font title. */
2761
- __38('replace hardcoded typography with "%s" global font', "elementor"),
2779
+ __40('replace hardcoded typography with "%s" global font', "elementor"),
2762
2780
  global.title
2763
2781
  )
2764
2782
  });
@@ -2769,15 +2787,15 @@ var audit16 = {
2769
2787
  };
2770
2788
 
2771
2789
  // src/audits/privacy-policy.ts
2772
- import { __ as __39 } from "@wordpress/i18n";
2790
+ import { __ as __41 } from "@wordpress/i18n";
2773
2791
  var audit17 = {
2774
2792
  id: "audits/privacy-policy",
2775
- title: __39("Privacy policy", "elementor"),
2776
- description: __39(
2793
+ title: __41("Privacy policy", "elementor"),
2794
+ description: __41(
2777
2795
  "A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
2778
2796
  "elementor"
2779
2797
  ),
2780
- fixHint: __39(
2798
+ fixHint: __41(
2781
2799
  "Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
2782
2800
  "elementor"
2783
2801
  ),
@@ -2793,9 +2811,9 @@ var audit17 = {
2793
2811
  violations: [
2794
2812
  {
2795
2813
  auditId: audit17.id,
2796
- label: __39("No privacy policy page is set.", "elementor"),
2814
+ label: __41("No privacy policy page is set.", "elementor"),
2797
2815
  externalUrl: ctx.pageContext.privacy_settings_url,
2798
- ctaLabel: __39("Create", "elementor")
2816
+ ctaLabel: __41("Create", "elementor")
2799
2817
  }
2800
2818
  ]
2801
2819
  };
@@ -2803,15 +2821,15 @@ var audit17 = {
2803
2821
  };
2804
2822
 
2805
2823
  // src/audits/robots-noindex.ts
2806
- import { __ as __40 } from "@wordpress/i18n";
2824
+ import { __ as __42 } from "@wordpress/i18n";
2807
2825
  var audit18 = {
2808
2826
  id: "audits/robots-noindex",
2809
- title: __40("Search engine visibility", "elementor"),
2810
- description: __40(
2827
+ title: __42("Search engine visibility", "elementor"),
2828
+ description: __42(
2811
2829
  "When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
2812
2830
  "elementor"
2813
2831
  ),
2814
- fixHint: __40(
2832
+ fixHint: __42(
2815
2833
  'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
2816
2834
  "elementor"
2817
2835
  ),
@@ -2827,7 +2845,7 @@ var audit18 = {
2827
2845
  violations: [
2828
2846
  {
2829
2847
  auditId: audit18.id,
2830
- label: __40("Search engines are discouraged from indexing this website.", "elementor"),
2848
+ label: __42("Search engines are discouraged from indexing this website.", "elementor"),
2831
2849
  externalUrl: ctx.pageContext.reading_settings_url
2832
2850
  }
2833
2851
  ]
@@ -2836,15 +2854,15 @@ var audit18 = {
2836
2854
  };
2837
2855
 
2838
2856
  // src/audits/scan-for-cookies.ts
2839
- import { __ as __41 } from "@wordpress/i18n";
2857
+ import { __ as __43 } from "@wordpress/i18n";
2840
2858
  var audit19 = {
2841
2859
  id: "audits/scan-for-cookies",
2842
- title: __41("Scan for cookies", "elementor"),
2843
- description: __41(
2860
+ title: __43("Scan for cookies", "elementor"),
2861
+ description: __43(
2844
2862
  "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.",
2845
2863
  "elementor"
2846
2864
  ),
2847
- fixHint: __41("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2865
+ fixHint: __43("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2848
2866
  categories: ["compliance"],
2849
2867
  severity: "info",
2850
2868
  weight: 0,
@@ -2855,7 +2873,7 @@ var audit19 = {
2855
2873
  violations: [
2856
2874
  {
2857
2875
  auditId: audit19.id,
2858
- label: __41("This page has not been scanned for cookies yet.", "elementor"),
2876
+ label: __43("This page has not been scanned for cookies yet.", "elementor"),
2859
2877
  externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
2860
2878
  }
2861
2879
  ]
@@ -2864,21 +2882,21 @@ var audit19 = {
2864
2882
  };
2865
2883
 
2866
2884
  // src/audits/sections-and-columns.ts
2867
- import { __ as __42 } from "@wordpress/i18n";
2885
+ import { __ as __44 } from "@wordpress/i18n";
2868
2886
  var audit20 = {
2869
2887
  id: "audits/sections-and-columns",
2870
- title: __42("Sections and columns", "elementor"),
2871
- description: __42(
2888
+ title: __44("Sections and columns", "elementor"),
2889
+ description: __44(
2872
2890
  "Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
2873
2891
  "elementor"
2874
2892
  ),
2875
- fixHint: __42("Use the Container Converter to replace each section/column with a container.", "elementor"),
2893
+ fixHint: __44("Use the Container Converter to replace each section/column with a container.", "elementor"),
2876
2894
  categories: ["best-practices", "performance"],
2877
2895
  severity: "warning",
2878
2896
  weight: 7,
2879
2897
  evaluate: (ctx) => {
2880
2898
  if (ctx.elements.tree.length === 0) {
2881
- return { status: "skipped", reason: __42("No elements", "elementor") };
2899
+ return { status: "skipped", reason: __44("No elements", "elementor") };
2882
2900
  }
2883
2901
  const violations = [];
2884
2902
  walkElements(ctx.elements.tree, (node) => {
@@ -2886,7 +2904,7 @@ var audit20 = {
2886
2904
  violations.push({
2887
2905
  auditId: audit20.id,
2888
2906
  elementId: node.id,
2889
- label: node.elType === "section" ? __42("Section element", "elementor") : __42("Column element", "elementor")
2907
+ label: node.elType === "section" ? __44("Section element", "elementor") : __44("Column element", "elementor")
2890
2908
  });
2891
2909
  }
2892
2910
  });
@@ -2895,15 +2913,15 @@ var audit20 = {
2895
2913
  };
2896
2914
 
2897
2915
  // src/audits/site-identity.ts
2898
- import { __ as __43 } from "@wordpress/i18n";
2916
+ import { __ as __45 } from "@wordpress/i18n";
2899
2917
  var audit21 = {
2900
2918
  id: "audits/site-identity",
2901
- title: __43("Site identity", "elementor"),
2902
- description: __43(
2919
+ title: __45("Site identity", "elementor"),
2920
+ description: __45(
2903
2921
  "Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
2904
2922
  "elementor"
2905
2923
  ),
2906
- fixHint: __43("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2924
+ fixHint: __45("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2907
2925
  categories: ["best-practices", "seo"],
2908
2926
  severity: "info",
2909
2927
  weight: 7,
@@ -2913,14 +2931,14 @@ var audit21 = {
2913
2931
  if (!identity.site_name_set) {
2914
2932
  violations.push({
2915
2933
  auditId: audit21.id,
2916
- label: __43("Site name is missing or still uses the default.", "elementor"),
2934
+ label: __45("Site name is missing or still uses the default.", "elementor"),
2917
2935
  targetHint: "site-identity-settings"
2918
2936
  });
2919
2937
  }
2920
2938
  if (!identity.site_description_set) {
2921
2939
  violations.push({
2922
2940
  auditId: audit21.id,
2923
- label: __43("Site description is missing or still uses the default.", "elementor"),
2941
+ label: __45("Site description is missing or still uses the default.", "elementor"),
2924
2942
  targetHint: "site-identity-settings",
2925
2943
  angieFix: true
2926
2944
  });
@@ -2928,14 +2946,14 @@ var audit21 = {
2928
2946
  if (!identity.site_logo_set) {
2929
2947
  violations.push({
2930
2948
  auditId: audit21.id,
2931
- label: __43("Site logo is not set.", "elementor"),
2949
+ label: __45("Site logo is not set.", "elementor"),
2932
2950
  targetHint: "site-identity-settings"
2933
2951
  });
2934
2952
  }
2935
2953
  if (!identity.site_favicon_set) {
2936
2954
  violations.push({
2937
2955
  auditId: audit21.id,
2938
- label: __43("Site favicon is not set.", "elementor"),
2956
+ label: __45("Site favicon is not set.", "elementor"),
2939
2957
  targetHint: "site-identity-settings"
2940
2958
  });
2941
2959
  }
@@ -2950,23 +2968,31 @@ var audit21 = {
2950
2968
  };
2951
2969
 
2952
2970
  // src/audits/too-many-widgets.ts
2953
- import { __ as __44 } from "@wordpress/i18n";
2971
+ import { getWidgetsCache as getWidgetsCache3 } from "@elementor/editor-elements";
2972
+ import { __ as __46 } from "@wordpress/i18n";
2954
2973
  var WIDGET_COUNT_THRESHOLD = 100;
2974
+ function isCountableWidget(node, widgetsCache) {
2975
+ if (node.elType === "widget") {
2976
+ return true;
2977
+ }
2978
+ return !!widgetsCache?.[node.elType]?.meta?.is_compound;
2979
+ }
2955
2980
  var audit22 = {
2956
2981
  id: "audits/too-many-widgets",
2957
- title: __44("Too many widgets", "elementor"),
2958
- description: __44("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2959
- fixHint: __44("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2982
+ title: __46("Too many widgets", "elementor"),
2983
+ description: __46("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2984
+ fixHint: __46("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2960
2985
  categories: ["best-practices", "performance"],
2961
2986
  severity: "warning",
2962
2987
  weight: 5,
2963
2988
  evaluate: (ctx) => {
2964
2989
  if (ctx.elements.tree.length === 0) {
2965
- return { status: "skipped", reason: __44("No elements", "elementor") };
2990
+ return { status: "skipped", reason: __46("No elements", "elementor") };
2966
2991
  }
2992
+ const widgetsCache = getWidgetsCache3();
2967
2993
  let widgetCount = 0;
2968
2994
  walkElements(ctx.elements.tree, (node) => {
2969
- if (node.elType === "widget") {
2995
+ if (isCountableWidget(node, widgetsCache)) {
2970
2996
  widgetCount++;
2971
2997
  }
2972
2998
  });
@@ -2978,7 +3004,7 @@ var audit22 = {
2978
3004
  violations: [
2979
3005
  {
2980
3006
  auditId: audit22.id,
2981
- label: __44("Page has too many widgets.", "elementor")
3007
+ label: __46("Page has too many widgets.", "elementor")
2982
3008
  }
2983
3009
  ]
2984
3010
  };