@elementor/editor-audits 4.3.0 → 4.3.1

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.js CHANGED
@@ -45,17 +45,17 @@ var import_editor_app_bar = require("@elementor/editor-app-bar");
45
45
 
46
46
  // src/hooks/use-audit-toggle-props.ts
47
47
  var import_icons12 = require("@elementor/icons");
48
- var import_i18n22 = require("@wordpress/i18n");
48
+ var import_i18n24 = require("@wordpress/i18n");
49
49
 
50
50
  // src/editor-panel.tsx
51
51
  var import_editor_floating_panels2 = require("@elementor/editor-floating-panels");
52
52
 
53
53
  // src/components/audit-panel.tsx
54
- var React23 = __toESM(require("react"));
54
+ var React25 = __toESM(require("react"));
55
55
  var import_editor_elements5 = require("@elementor/editor-elements");
56
56
  var import_editor_floating_panels = require("@elementor/editor-floating-panels");
57
- var import_ui22 = require("@elementor/ui");
58
- var import_i18n21 = require("@wordpress/i18n");
57
+ var import_ui24 = require("@elementor/ui");
58
+ var import_i18n23 = require("@wordpress/i18n");
59
59
 
60
60
  // src/hooks/use-audit-report.ts
61
61
  var import_react = require("react");
@@ -172,7 +172,7 @@ var CATEGORY_LABELS = {
172
172
  seo: (0, import_i18n.__)("SEO", "elementor"),
173
173
  accessibility: (0, import_i18n.__)("Accessibility", "elementor"),
174
174
  performance: (0, import_i18n.__)("Performance", "elementor"),
175
- compliance: (0, import_i18n.__)("Compliance", "elementor")
175
+ compliance: (0, import_i18n.__)("Site compliance", "elementor")
176
176
  };
177
177
 
178
178
  // src/utils/audit-status-summary.ts
@@ -759,10 +759,10 @@ function WelcomePage() {
759
759
  }
760
760
 
761
761
  // src/components/report-shell.tsx
762
- var React22 = __toESM(require("react"));
763
- var import_react5 = require("react");
764
- var import_ui21 = require("@elementor/ui");
765
- var import_i18n20 = require("@wordpress/i18n");
762
+ var React24 = __toESM(require("react"));
763
+ var import_react6 = require("react");
764
+ var import_ui23 = require("@elementor/ui");
765
+ var import_i18n22 = require("@wordpress/i18n");
766
766
 
767
767
  // src/components/pages/all-audits-page.tsx
768
768
  var React12 = __toESM(require("react"));
@@ -928,7 +928,7 @@ var import_icons5 = require("@elementor/icons");
928
928
  var SEVERITY_CONFIG = {
929
929
  error: { Icon: import_icons5.AlertTriangleFilledIcon, color: "error" },
930
930
  warning: { Icon: import_icons5.AlertCircleIcon, color: "warning" },
931
- info: { Icon: import_icons5.InfoCircleIcon, color: "info" }
931
+ info: { Icon: import_icons5.BulbIcon, color: "info" }
932
932
  };
933
933
  function SeverityIcon({ severity }) {
934
934
  const { Icon, color } = SEVERITY_CONFIG[severity];
@@ -1128,10 +1128,10 @@ var import_i18n13 = require("@wordpress/i18n");
1128
1128
  var import_icons8 = require("@elementor/icons");
1129
1129
  var CATEGORY_ICONS = {
1130
1130
  "best-practices": import_icons8.Settings2Icon,
1131
- seo: import_icons8.FilterIcon,
1131
+ seo: import_icons8.FileSearchIcon,
1132
1132
  accessibility: import_icons8.ElementorAccessibilityIcon,
1133
- performance: import_icons8.ShieldHalfFilledIcon,
1134
- compliance: import_icons8.HeartHandShakeIcon
1133
+ performance: import_icons8.BoltIcon,
1134
+ compliance: import_icons8.ShieldCheckIcon
1135
1135
  };
1136
1136
 
1137
1137
  // src/components/pages/category-page.tsx
@@ -1159,8 +1159,9 @@ function CategoryPage({ category, report, onBack }) {
1159
1159
  }
1160
1160
 
1161
1161
  // src/components/pages/issues-page.tsx
1162
- var React17 = __toESM(require("react"));
1163
- var import_ui16 = require("@elementor/ui");
1162
+ var React18 = __toESM(require("react"));
1163
+ var import_react5 = require("react");
1164
+ var import_ui17 = require("@elementor/ui");
1164
1165
  var import_i18n17 = require("@wordpress/i18n");
1165
1166
 
1166
1167
  // src/utils/severity-counts.ts
@@ -1189,41 +1190,115 @@ function severityPluralLabel(severity) {
1189
1190
  case "warning":
1190
1191
  return (0, import_i18n14.__)("Warnings", "elementor");
1191
1192
  case "info":
1192
- return (0, import_i18n14.__)("Info", "elementor");
1193
+ return (0, import_i18n14.__)("Suggestions", "elementor");
1193
1194
  }
1194
1195
  }
1195
- function severityRemainingCountLabel(severity, count) {
1196
- switch (severity) {
1197
- case "error":
1198
- return (0, import_i18n14.sprintf)(
1199
- /* translators: %d: number of remaining error violations. */
1200
- (0, import_i18n14.__)("%d errors", "elementor"),
1201
- count
1202
- );
1203
- case "warning":
1204
- return (0, import_i18n14.sprintf)(
1205
- /* translators: %d: number of remaining warning violations. */
1206
- (0, import_i18n14.__)("%d warnings", "elementor"),
1207
- count
1208
- );
1209
- case "info":
1210
- return (0, import_i18n14.sprintf)(
1211
- /* translators: %d: number of remaining info violations. */
1212
- (0, import_i18n14.__)("%d info", "elementor"),
1213
- count
1214
- );
1196
+
1197
+ // src/components/audit-statuses-section.tsx
1198
+ var React15 = __toESM(require("react"));
1199
+ var import_ui14 = require("@elementor/ui");
1200
+ var import_i18n15 = require("@wordpress/i18n");
1201
+
1202
+ // src/components/count-summary-circle.tsx
1203
+ var React14 = __toESM(require("react"));
1204
+ var import_ui13 = require("@elementor/ui");
1205
+ var COUNT_SUMMARY_CIRCLE_SIZE = 64;
1206
+ var COUNT_SUMMARY_BORDER_WIDTH = 4;
1207
+ function chipBorderColor(theme, color) {
1208
+ if (color === "default" || !color) {
1209
+ return theme.palette.text.secondary;
1215
1210
  }
1211
+ return theme.palette[color].main;
1212
+ }
1213
+ function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
1214
+ return /* @__PURE__ */ React14.createElement(
1215
+ import_ui13.Box,
1216
+ {
1217
+ "aria-label": ariaLabel,
1218
+ component: "button",
1219
+ onClick,
1220
+ type: "button",
1221
+ sx: {
1222
+ alignItems: "center",
1223
+ background: "none",
1224
+ border: "none",
1225
+ cursor: "pointer",
1226
+ display: "flex",
1227
+ flex: 1,
1228
+ flexDirection: "column",
1229
+ gap: 0.5,
1230
+ padding: 0
1231
+ }
1232
+ },
1233
+ /* @__PURE__ */ React14.createElement(
1234
+ import_ui13.Chip,
1235
+ {
1236
+ color,
1237
+ label: count,
1238
+ size: "small",
1239
+ variant: "standard",
1240
+ sx: (theme) => ({
1241
+ border: `${COUNT_SUMMARY_BORDER_WIDTH}px solid ${chipBorderColor(theme, color)}`,
1242
+ borderRadius: "50%",
1243
+ height: COUNT_SUMMARY_CIRCLE_SIZE,
1244
+ maxWidth: COUNT_SUMMARY_CIRCLE_SIZE,
1245
+ width: COUNT_SUMMARY_CIRCLE_SIZE,
1246
+ "& .MuiChip-label": {
1247
+ fontSize: theme.typography.body2.fontSize,
1248
+ fontWeight: 700,
1249
+ lineHeight: 1,
1250
+ padding: 0
1251
+ }
1252
+ })
1253
+ }
1254
+ ),
1255
+ /* @__PURE__ */ React14.createElement(import_ui13.Typography, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
1256
+ );
1257
+ }
1258
+
1259
+ // src/components/audit-statuses-section.tsx
1260
+ var STATUS_ARIA_LABELS = {
1261
+ pass: (count) => (0, import_i18n15.sprintf)(
1262
+ /* translators: %d: number of passed audits. */
1263
+ (0, import_i18n15.__)("%d passed audits, view all", "elementor"),
1264
+ count
1265
+ ),
1266
+ fail: (count) => (0, import_i18n15.sprintf)(
1267
+ /* translators: %d: number of failed audit violations. */
1268
+ (0, import_i18n15.__)("%d failed audits, view all", "elementor"),
1269
+ count
1270
+ ),
1271
+ skipped: (count) => (0, import_i18n15.sprintf)(
1272
+ /* translators: %d: number of skipped audits. */
1273
+ (0, import_i18n15.__)("%d skipped audits, view all", "elementor"),
1274
+ count
1275
+ )
1276
+ };
1277
+ var STATUS_GROUPS = ["fail", "pass", "skipped"];
1278
+ function AuditStatusesSection({ report, onStatusClick }) {
1279
+ const statusCounts = auditStatusDisplayCounts(report);
1280
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(import_ui14.Typography, { variant: "subtitle1", fontWeight: "bold" }, (0, import_i18n15.__)("Audit statuses", "elementor")), /* @__PURE__ */ React15.createElement(import_ui14.Box, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React15.createElement(
1281
+ CountSummaryCircle,
1282
+ {
1283
+ key: status,
1284
+ ariaLabel: STATUS_ARIA_LABELS[status](statusCounts[status]),
1285
+ color: auditStatusColor(status),
1286
+ count: statusCounts[status],
1287
+ label: auditStatusLabel(status),
1288
+ onClick: () => onStatusClick(status)
1289
+ }
1290
+ ))), /* @__PURE__ */ React15.createElement(import_ui14.Divider, null));
1216
1291
  }
1217
1292
 
1218
1293
  // src/components/issues-category-row.tsx
1219
- var React14 = __toESM(require("react"));
1294
+ var React16 = __toESM(require("react"));
1220
1295
  var import_icons9 = require("@elementor/icons");
1221
- var import_ui13 = require("@elementor/ui");
1296
+ var import_ui15 = require("@elementor/ui");
1222
1297
  function IssuesCategoryRow({ category, label, counts, onClick }) {
1223
- const isRtl = "rtl" === (0, import_ui13.useTheme)().direction;
1298
+ const isRtl = "rtl" === (0, import_ui15.useTheme)().direction;
1224
1299
  const Icon = CATEGORY_ICONS[category];
1225
- return /* @__PURE__ */ React14.createElement(
1226
- import_ui13.Box,
1300
+ return /* @__PURE__ */ React16.createElement(
1301
+ import_ui15.Box,
1227
1302
  {
1228
1303
  role: "button",
1229
1304
  tabIndex: 0,
@@ -1244,21 +1319,112 @@ function IssuesCategoryRow({ category, label, counts, onClick }) {
1244
1319
  "&:focus-visible": { outline: "2px solid", outlineColor: "primary.main" }
1245
1320
  }
1246
1321
  },
1247
- /* @__PURE__ */ React14.createElement(Icon, { fontSize: "small", color: "action" }),
1248
- /* @__PURE__ */ React14.createElement(import_ui13.Typography, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1249
- /* @__PURE__ */ React14.createElement(import_ui13.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React14.createElement(import_ui13.Box, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React14.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React14.createElement(import_ui13.Typography, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
1250
- /* @__PURE__ */ React14.createElement(import_ui13.Rotate, { in: isRtl }, /* @__PURE__ */ React14.createElement(import_icons9.ChevronRightIcon, { fontSize: "small", color: "action" }))
1322
+ /* @__PURE__ */ React16.createElement(Icon, { fontSize: "small", color: "action" }),
1323
+ /* @__PURE__ */ React16.createElement(import_ui15.Typography, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1324
+ /* @__PURE__ */ React16.createElement(import_ui15.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React16.createElement(import_ui15.Box, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React16.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React16.createElement(import_ui15.Typography, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
1325
+ /* @__PURE__ */ React16.createElement(import_ui15.Rotate, { in: isRtl }, /* @__PURE__ */ React16.createElement(import_icons9.ChevronRightIcon, { fontSize: "small", color: "action" }))
1251
1326
  );
1252
1327
  }
1253
1328
 
1254
- // src/components/promotions.tsx
1255
- var React16 = __toESM(require("react"));
1256
- var import_ui15 = require("@elementor/ui");
1329
+ // src/components/severity-filter-chips.tsx
1330
+ var React17 = __toESM(require("react"));
1331
+ var import_ui16 = require("@elementor/ui");
1257
1332
  var import_i18n16 = require("@wordpress/i18n");
1333
+ function SeverityFilterChips({ selected, onChange }) {
1334
+ return /* @__PURE__ */ React17.createElement(import_ui16.Box, { sx: { display: "flex", alignItems: "center", gap: 1 } }, /* @__PURE__ */ React17.createElement(
1335
+ FilterChip,
1336
+ {
1337
+ label: (0, import_i18n16.__)("All", "elementor"),
1338
+ isSelected: selected === "all",
1339
+ onClick: () => onChange("all")
1340
+ }
1341
+ ), ALL_SEVERITIES.map((severity) => /* @__PURE__ */ React17.createElement(
1342
+ FilterChip,
1343
+ {
1344
+ key: severity,
1345
+ label: severityPluralLabel(severity),
1346
+ icon: /* @__PURE__ */ React17.createElement(SeverityIcon, { severity }),
1347
+ isSelected: selected === severity,
1348
+ onClick: () => onChange(severity)
1349
+ }
1350
+ )));
1351
+ }
1352
+ function FilterChip({ label, icon, isSelected, onClick }) {
1353
+ return /* @__PURE__ */ React17.createElement(
1354
+ import_ui16.Chip,
1355
+ {
1356
+ label,
1357
+ icon,
1358
+ size: "small",
1359
+ variant: "filled",
1360
+ color: "default",
1361
+ onClick,
1362
+ "aria-pressed": isSelected,
1363
+ sx: { bgcolor: isSelected ? "action.selected" : "transparent" }
1364
+ }
1365
+ );
1366
+ }
1367
+
1368
+ // src/components/pages/issues-page.tsx
1369
+ function filterCounts(counts, filter) {
1370
+ if (filter === "all") {
1371
+ return counts;
1372
+ }
1373
+ return { error: 0, warning: 0, info: 0, [filter]: counts[filter] };
1374
+ }
1375
+ function IssuesPage({ report, onCategoryClick, onAllAuditsClick, onStatusClick }) {
1376
+ const [filter, setFilter] = (0, import_react5.useState)("all");
1377
+ const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1378
+ const categoryRows = populatedCategories.map((category) => ({ category, counts: filterCounts(countSeverities(report, category), filter) })).filter(({ counts }) => Object.values(counts).some((count) => count > 0));
1379
+ return /* @__PURE__ */ React18.createElement(import_ui17.Box, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React18.createElement(AuditStatusesSection, { report, onStatusClick }), /* @__PURE__ */ React18.createElement(
1380
+ import_ui17.Link,
1381
+ {
1382
+ component: "button",
1383
+ underline: "none",
1384
+ color: "inherit",
1385
+ onClick: onAllAuditsClick,
1386
+ sx: { textAlign: "start" }
1387
+ },
1388
+ /* @__PURE__ */ React18.createElement(import_ui17.Typography, { variant: "subtitle1", component: "h2" }, (0, import_i18n17.__)("All issues", "elementor"))
1389
+ ), /* @__PURE__ */ React18.createElement(SeverityFilterChips, { selected: filter, onChange: setFilter }), /* @__PURE__ */ React18.createElement(import_ui17.Box, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, categoryRows.map(({ category, counts }) => /* @__PURE__ */ React18.createElement(
1390
+ IssuesCategoryRow,
1391
+ {
1392
+ key: category,
1393
+ category,
1394
+ label: CATEGORY_LABELS[category],
1395
+ counts,
1396
+ onClick: () => onCategoryClick(category)
1397
+ }
1398
+ ))));
1399
+ }
1400
+
1401
+ // src/components/pages/overview-page.tsx
1402
+ var React23 = __toESM(require("react"));
1403
+ var import_ui22 = require("@elementor/ui");
1404
+ var import_i18n21 = require("@wordpress/i18n");
1405
+
1406
+ // src/utils/score-thresholds.ts
1407
+ var import_i18n18 = require("@wordpress/i18n");
1408
+ var GOOD_THRESHOLD = 90;
1409
+ var OK_THRESHOLD = 50;
1410
+ function getScoreTier(score) {
1411
+ if (score >= GOOD_THRESHOLD) {
1412
+ return { color: "success", label: (0, import_i18n18.__)("Good", "elementor") };
1413
+ }
1414
+ if (score >= OK_THRESHOLD) {
1415
+ return { color: "warning", label: (0, import_i18n18.__)("Needs work", "elementor") };
1416
+ }
1417
+ return { color: "error", label: (0, import_i18n18.__)("At risk", "elementor") };
1418
+ }
1419
+
1420
+ // src/components/promotions.tsx
1421
+ var React20 = __toESM(require("react"));
1422
+ var import_ui19 = require("@elementor/ui");
1423
+ var import_i18n20 = require("@wordpress/i18n");
1258
1424
 
1259
1425
  // src/register-promotions.ts
1260
1426
  var import_icons10 = require("@elementor/icons");
1261
- var import_i18n15 = require("@wordpress/i18n");
1427
+ var import_i18n19 = require("@wordpress/i18n");
1262
1428
  function firstFailExternalUrl(run) {
1263
1429
  return run.result.status === "fail" ? run.result.violations[0]?.externalUrl : void 0;
1264
1430
  }
@@ -1266,7 +1432,7 @@ var PROMOTIONS = [
1266
1432
  {
1267
1433
  auditId: "audits/images-alt-text",
1268
1434
  icon: import_icons10.PhotoIcon,
1269
- ctaLabel: (0, import_i18n15.__)("Fix with Ally", "elementor"),
1435
+ ctaLabel: (0, import_i18n19.__)("Fix with Ally", "elementor"),
1270
1436
  formatSubtitle: (run) => {
1271
1437
  if (run.result.status !== "fail") {
1272
1438
  return null;
@@ -1275,9 +1441,9 @@ var PROMOTIONS = [
1275
1441
  if (count === 0) {
1276
1442
  return null;
1277
1443
  }
1278
- return (0, import_i18n15.sprintf)(
1444
+ return (0, import_i18n19.sprintf)(
1279
1445
  /* translators: %d: number of images missing alt text. */
1280
- (0, import_i18n15._n)("%d image", "%d images", count, "elementor"),
1446
+ (0, import_i18n19._n)("%d image", "%d images", count, "elementor"),
1281
1447
  count
1282
1448
  );
1283
1449
  },
@@ -1286,21 +1452,21 @@ var PROMOTIONS = [
1286
1452
  {
1287
1453
  auditId: "audits/cookie-policy",
1288
1454
  icon: import_icons10.ElementorCookieIcon,
1289
- ctaLabel: (0, import_i18n15.__)("Fix with Cookiez", "elementor"),
1290
- formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n15.__)("Generate cookie policy", "elementor") : null,
1455
+ ctaLabel: (0, import_i18n19.__)("Fix with Cookiez", "elementor"),
1456
+ formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n19.__)("Generate cookie policy", "elementor") : null,
1291
1457
  getCtaUrl: firstFailExternalUrl
1292
1458
  },
1293
1459
  {
1294
1460
  auditId: "audits/scan-for-cookies",
1295
1461
  icon: import_icons10.ElementorCookieIcon,
1296
- ctaLabel: (0, import_i18n15.__)("Scan", "elementor"),
1297
- formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n15.__)("Scan this page for cookies", "elementor") : null,
1462
+ ctaLabel: (0, import_i18n19.__)("Scan", "elementor"),
1463
+ formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n19.__)("Scan this page for cookies", "elementor") : null,
1298
1464
  getCtaUrl: firstFailExternalUrl
1299
1465
  },
1300
1466
  {
1301
1467
  auditId: "audits/images-too-large",
1302
1468
  icon: import_icons10.ShieldHalfFilledIcon,
1303
- ctaLabel: (0, import_i18n15.__)("Optimize all", "elementor"),
1469
+ ctaLabel: (0, import_i18n19.__)("Optimize all", "elementor"),
1304
1470
  formatSubtitle: (run) => {
1305
1471
  if (run.result.status !== "fail") {
1306
1472
  return null;
@@ -1309,9 +1475,9 @@ var PROMOTIONS = [
1309
1475
  if (count === 0) {
1310
1476
  return null;
1311
1477
  }
1312
- return (0, import_i18n15.sprintf)(
1478
+ return (0, import_i18n19.sprintf)(
1313
1479
  /* translators: %d: number of oversized images. */
1314
- (0, import_i18n15._n)("%d image", "%d images", count, "elementor"),
1480
+ (0, import_i18n19._n)("%d image", "%d images", count, "elementor"),
1315
1481
  count
1316
1482
  );
1317
1483
  },
@@ -1325,11 +1491,11 @@ function findAuditRun(report, auditId) {
1325
1491
  }
1326
1492
 
1327
1493
  // src/components/promotion-card.tsx
1328
- var React15 = __toESM(require("react"));
1329
- var import_ui14 = require("@elementor/ui");
1494
+ var React19 = __toESM(require("react"));
1495
+ var import_ui18 = require("@elementor/ui");
1330
1496
  function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle, title }) {
1331
- return /* @__PURE__ */ React15.createElement(
1332
- import_ui14.Box,
1497
+ return /* @__PURE__ */ React19.createElement(
1498
+ import_ui18.Box,
1333
1499
  {
1334
1500
  sx: {
1335
1501
  alignItems: "center",
@@ -1342,9 +1508,9 @@ function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle
1342
1508
  py: 1.5
1343
1509
  }
1344
1510
  },
1345
- /* @__PURE__ */ React15.createElement(Icon, { fontSize: "small", color: "action" }),
1346
- /* @__PURE__ */ React15.createElement(import_ui14.Box, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React15.createElement(import_ui14.Typography, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React15.createElement(import_ui14.Typography, { variant: "caption", color: "text.secondary" }, subtitle)),
1347
- /* @__PURE__ */ React15.createElement(import_ui14.Button, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1511
+ /* @__PURE__ */ React19.createElement(Icon, { fontSize: "small", color: "action" }),
1512
+ /* @__PURE__ */ React19.createElement(import_ui18.Box, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React19.createElement(import_ui18.Typography, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React19.createElement(import_ui18.Typography, { variant: "caption", color: "text.secondary" }, subtitle)),
1513
+ /* @__PURE__ */ React19.createElement(import_ui18.Button, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1348
1514
  );
1349
1515
  }
1350
1516
 
@@ -1373,7 +1539,7 @@ function Promotions({ report }) {
1373
1539
  if (cards.length === 0) {
1374
1540
  return null;
1375
1541
  }
1376
- return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(import_ui15.Typography, { variant: "subtitle1", fontWeight: "bold" }, (0, import_i18n16.__)("Quick wins", "elementor")), /* @__PURE__ */ React16.createElement(import_ui15.Box, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React16.createElement(
1542
+ return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(import_ui19.Divider, null), /* @__PURE__ */ React20.createElement(import_ui19.Typography, { variant: "subtitle1", fontWeight: "bold" }, (0, import_i18n20.__)("Quick actions", "elementor")), /* @__PURE__ */ React20.createElement(import_ui19.Box, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React20.createElement(
1377
1543
  PromotionCard,
1378
1544
  {
1379
1545
  key,
@@ -1391,115 +1557,14 @@ function Promotions({ report }) {
1391
1557
  ))));
1392
1558
  }
1393
1559
 
1394
- // src/components/pages/issues-page.tsx
1395
- function IssuesPage({ report, onCategoryClick, onAllAuditsClick }) {
1396
- const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1397
- return /* @__PURE__ */ React17.createElement(import_ui16.Box, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React17.createElement(
1398
- import_ui16.Link,
1399
- {
1400
- component: "button",
1401
- underline: "none",
1402
- color: "inherit",
1403
- onClick: onAllAuditsClick,
1404
- sx: { textAlign: "start" }
1405
- },
1406
- /* @__PURE__ */ React17.createElement(import_ui16.Typography, { variant: "subtitle1", component: "h2" }, (0, import_i18n17.__)("All issues", "elementor"))
1407
- ), /* @__PURE__ */ React17.createElement(import_ui16.Box, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, populatedCategories.map((category) => /* @__PURE__ */ React17.createElement(
1408
- IssuesCategoryRow,
1409
- {
1410
- key: category,
1411
- category,
1412
- label: CATEGORY_LABELS[category],
1413
- counts: countSeverities(report, category),
1414
- onClick: () => onCategoryClick(category)
1415
- }
1416
- ))), /* @__PURE__ */ React17.createElement(Promotions, { report }));
1417
- }
1418
-
1419
- // src/components/pages/overview-page.tsx
1420
- var React21 = __toESM(require("react"));
1421
- var import_ui20 = require("@elementor/ui");
1422
- var import_i18n19 = require("@wordpress/i18n");
1423
-
1424
- // src/utils/score-thresholds.ts
1425
- var import_i18n18 = require("@wordpress/i18n");
1426
- var GOOD_THRESHOLD = 90;
1427
- var OK_THRESHOLD = 50;
1428
- function getScoreTier(score) {
1429
- if (score >= GOOD_THRESHOLD) {
1430
- return { color: "success", label: (0, import_i18n18.__)("Good", "elementor") };
1431
- }
1432
- if (score >= OK_THRESHOLD) {
1433
- return { color: "warning", label: (0, import_i18n18.__)("Needs work", "elementor") };
1434
- }
1435
- return { color: "error", label: (0, import_i18n18.__)("At risk", "elementor") };
1436
- }
1437
-
1438
- // src/components/count-summary-circle.tsx
1439
- var React18 = __toESM(require("react"));
1440
- var import_ui17 = require("@elementor/ui");
1441
- var COUNT_SUMMARY_CIRCLE_SIZE = 64;
1442
- var COUNT_SUMMARY_BORDER_WIDTH = 4;
1443
- function chipBorderColor(theme, color) {
1444
- if (color === "default" || !color) {
1445
- return theme.palette.text.secondary;
1446
- }
1447
- return theme.palette[color].main;
1448
- }
1449
- function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
1450
- return /* @__PURE__ */ React18.createElement(
1451
- import_ui17.Box,
1452
- {
1453
- "aria-label": ariaLabel,
1454
- component: "button",
1455
- onClick,
1456
- type: "button",
1457
- sx: {
1458
- alignItems: "center",
1459
- background: "none",
1460
- border: "none",
1461
- cursor: "pointer",
1462
- display: "flex",
1463
- flex: 1,
1464
- flexDirection: "column",
1465
- gap: 0.5,
1466
- padding: 0
1467
- }
1468
- },
1469
- /* @__PURE__ */ React18.createElement(
1470
- import_ui17.Chip,
1471
- {
1472
- color,
1473
- label: count,
1474
- size: "small",
1475
- variant: "standard",
1476
- sx: (theme) => ({
1477
- border: `${COUNT_SUMMARY_BORDER_WIDTH}px solid ${chipBorderColor(theme, color)}`,
1478
- borderRadius: "50%",
1479
- height: COUNT_SUMMARY_CIRCLE_SIZE,
1480
- maxWidth: COUNT_SUMMARY_CIRCLE_SIZE,
1481
- width: COUNT_SUMMARY_CIRCLE_SIZE,
1482
- "& .MuiChip-label": {
1483
- fontSize: theme.typography.body2.fontSize,
1484
- fontWeight: 700,
1485
- lineHeight: 1,
1486
- padding: 0
1487
- }
1488
- })
1489
- }
1490
- ),
1491
- /* @__PURE__ */ React18.createElement(import_ui17.Typography, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
1492
- );
1493
- }
1494
-
1495
1560
  // src/components/score-bar.tsx
1496
- var React19 = __toESM(require("react"));
1561
+ var React21 = __toESM(require("react"));
1497
1562
  var import_icons11 = require("@elementor/icons");
1498
- var import_ui18 = require("@elementor/ui");
1563
+ var import_ui20 = require("@elementor/ui");
1499
1564
  function ScoreBar({ label, score, onClick }) {
1500
- const isRtl = "rtl" === (0, import_ui18.useTheme)().direction;
1501
- return /* @__PURE__ */ React19.createElement(
1502
- import_ui18.Box,
1565
+ const isRtl = "rtl" === (0, import_ui20.useTheme)().direction;
1566
+ return /* @__PURE__ */ React21.createElement(
1567
+ import_ui20.Box,
1503
1568
  {
1504
1569
  role: onClick ? "button" : void 0,
1505
1570
  tabIndex: onClick ? 0 : void 0,
@@ -1515,9 +1580,9 @@ function ScoreBar({ label, score, onClick }) {
1515
1580
  py: 0.5
1516
1581
  }
1517
1582
  },
1518
- /* @__PURE__ */ React19.createElement(import_ui18.Typography, { variant: "body2", sx: { minWidth: 96 } }, label),
1519
- /* @__PURE__ */ React19.createElement(
1520
- import_ui18.LinearProgress,
1583
+ /* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "body2", sx: { minWidth: 96 } }, label),
1584
+ /* @__PURE__ */ React21.createElement(
1585
+ import_ui20.LinearProgress,
1521
1586
  {
1522
1587
  variant: "determinate",
1523
1588
  value: score,
@@ -1525,8 +1590,8 @@ function ScoreBar({ label, score, onClick }) {
1525
1590
  sx: { flex: 1, height: 6, borderRadius: 4, bgcolor: "action.disabledBackground" }
1526
1591
  }
1527
1592
  ),
1528
- /* @__PURE__ */ React19.createElement(
1529
- import_ui18.Typography,
1593
+ /* @__PURE__ */ React21.createElement(
1594
+ import_ui20.Typography,
1530
1595
  {
1531
1596
  variant: "body2",
1532
1597
  color: "text.primary",
@@ -1534,19 +1599,19 @@ function ScoreBar({ label, score, onClick }) {
1534
1599
  },
1535
1600
  score
1536
1601
  ),
1537
- onClick && /* @__PURE__ */ React19.createElement(import_ui18.Rotate, { in: isRtl }, /* @__PURE__ */ React19.createElement(import_icons11.ChevronRightIcon, { fontSize: "small", color: "action" }))
1602
+ onClick && /* @__PURE__ */ React21.createElement(import_ui20.Rotate, { in: isRtl }, /* @__PURE__ */ React21.createElement(import_icons11.ChevronRightIcon, { fontSize: "small", color: "action" }))
1538
1603
  );
1539
1604
  }
1540
1605
 
1541
1606
  // src/components/score-circle.tsx
1542
- var React20 = __toESM(require("react"));
1543
- var import_ui19 = require("@elementor/ui");
1607
+ var React22 = __toESM(require("react"));
1608
+ var import_ui21 = require("@elementor/ui");
1544
1609
  var SCORE_CIRCLE_SIZE = 88;
1545
1610
  var SCORE_CIRCLE_THICKNESS = 3;
1546
1611
  function ScoreCircle({ color, score }) {
1547
1612
  const progressColor = color ?? getScoreTier(score).color;
1548
- return /* @__PURE__ */ React20.createElement(
1549
- import_ui19.Box,
1613
+ return /* @__PURE__ */ React22.createElement(
1614
+ import_ui21.Box,
1550
1615
  {
1551
1616
  role: "progressbar",
1552
1617
  "aria-valuenow": score,
@@ -1554,8 +1619,8 @@ function ScoreCircle({ color, score }) {
1554
1619
  "aria-valuemax": 100,
1555
1620
  sx: { position: "relative", display: "inline-flex" }
1556
1621
  },
1557
- /* @__PURE__ */ React20.createElement(
1558
- import_ui19.CircularProgress,
1622
+ /* @__PURE__ */ React22.createElement(
1623
+ import_ui21.CircularProgress,
1559
1624
  {
1560
1625
  variant: "determinate",
1561
1626
  value: 100,
@@ -1564,8 +1629,8 @@ function ScoreCircle({ color, score }) {
1564
1629
  sx: { color: "action.disabledBackground" }
1565
1630
  }
1566
1631
  ),
1567
- /* @__PURE__ */ React20.createElement(
1568
- import_ui19.CircularProgress,
1632
+ /* @__PURE__ */ React22.createElement(
1633
+ import_ui21.CircularProgress,
1569
1634
  {
1570
1635
  variant: "determinate",
1571
1636
  value: score,
@@ -1575,8 +1640,8 @@ function ScoreCircle({ color, score }) {
1575
1640
  sx: { position: "absolute", left: 0 }
1576
1641
  }
1577
1642
  ),
1578
- /* @__PURE__ */ React20.createElement(
1579
- import_ui19.Box,
1643
+ /* @__PURE__ */ React22.createElement(
1644
+ import_ui21.Box,
1580
1645
  {
1581
1646
  sx: {
1582
1647
  position: "absolute",
@@ -1586,8 +1651,8 @@ function ScoreCircle({ color, score }) {
1586
1651
  justifyContent: "center"
1587
1652
  }
1588
1653
  },
1589
- /* @__PURE__ */ React20.createElement(
1590
- import_ui19.Typography,
1654
+ /* @__PURE__ */ React22.createElement(
1655
+ import_ui21.Typography,
1591
1656
  {
1592
1657
  variant: "h4",
1593
1658
  component: "span",
@@ -1601,31 +1666,11 @@ function ScoreCircle({ color, score }) {
1601
1666
  }
1602
1667
 
1603
1668
  // src/components/pages/overview-page.tsx
1604
- var STATUS_ARIA_LABELS = {
1605
- pass: (count) => (0, import_i18n19.sprintf)(
1606
- /* translators: %d: number of passed audits. */
1607
- (0, import_i18n19.__)("%d passed audits, view all", "elementor"),
1608
- count
1609
- ),
1610
- fail: (count) => (0, import_i18n19.sprintf)(
1611
- /* translators: %d: number of failed audit violations. */
1612
- (0, import_i18n19.__)("%d failed audits, view all", "elementor"),
1613
- count
1614
- ),
1615
- skipped: (count) => (0, import_i18n19.sprintf)(
1616
- /* translators: %d: number of skipped audits. */
1617
- (0, import_i18n19.__)("%d skipped audits, view all", "elementor"),
1618
- count
1619
- )
1620
- };
1621
- var STATUS_GROUPS = ["fail", "pass", "skipped"];
1622
- function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1669
+ function OverviewPage({ onCategoryClick, report }) {
1623
1670
  const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1624
- const severityCounts = countSeverities(report);
1625
- const statusCounts = auditStatusDisplayCounts(report);
1626
1671
  const overallScore = getScoreTier(report.overall);
1627
- return /* @__PURE__ */ React21.createElement(import_ui20.Box, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React21.createElement(import_ui20.Box, { sx: { display: "flex", alignItems: "center", gap: 2 } }, /* @__PURE__ */ React21.createElement(ScoreCircle, { color: overallScore.color, score: report.overall }), /* @__PURE__ */ React21.createElement(import_ui20.Box, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React21.createElement(
1628
- import_ui20.Chip,
1672
+ return /* @__PURE__ */ React23.createElement(import_ui22.Box, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React23.createElement(import_ui22.Box, { sx: { display: "flex", alignItems: "center", gap: 2 } }, /* @__PURE__ */ React23.createElement(ScoreCircle, { color: overallScore.color, score: report.overall }), /* @__PURE__ */ React23.createElement(import_ui22.Box, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React23.createElement(
1673
+ import_ui22.Chip,
1629
1674
  {
1630
1675
  label: overallScore.label,
1631
1676
  color: overallScore.color,
@@ -1633,7 +1678,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1633
1678
  size: "small",
1634
1679
  sx: { fontWeight: 600, alignSelf: "flex-start" }
1635
1680
  }
1636
- ), /* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "body2", color: "text.secondary" }, (0, import_i18n19.__)("Overall score", "elementor")))), /* @__PURE__ */ React21.createElement(import_ui20.Box, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React21.createElement(
1681
+ ), /* @__PURE__ */ React23.createElement(import_ui22.Typography, { variant: "body2", color: "text.secondary" }, (0, import_i18n21.__)("Overall score", "elementor")))), /* @__PURE__ */ React23.createElement(import_ui22.Box, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React23.createElement(
1637
1682
  ScoreBar,
1638
1683
  {
1639
1684
  key: category,
@@ -1641,45 +1686,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1641
1686
  score: report.categories[category].score,
1642
1687
  onClick: () => onCategoryClick(category)
1643
1688
  }
1644
- ))), /* @__PURE__ */ React21.createElement(import_ui20.Divider, null), /* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "subtitle1", fontWeight: "bold" }, (0, import_i18n19.__)("Audit statuses", "elementor")), /* @__PURE__ */ React21.createElement(import_ui20.Box, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React21.createElement(
1645
- CountSummaryCircle,
1646
- {
1647
- key: status,
1648
- ariaLabel: STATUS_ARIA_LABELS[status](statusCounts[status]),
1649
- color: auditStatusColor(status),
1650
- count: statusCounts[status],
1651
- label: auditStatusLabel(status),
1652
- onClick: () => onStatusClick(status)
1653
- }
1654
- ))), /* @__PURE__ */ React21.createElement(import_ui20.Divider, null), /* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "subtitle1", fontWeight: "bold" }, (0, import_i18n19.__)("Remaining issues", "elementor")), /* @__PURE__ */ React21.createElement(
1655
- import_ui20.Box,
1656
- {
1657
- component: "ul",
1658
- sx: {
1659
- display: "flex",
1660
- flexDirection: "column",
1661
- gap: 1,
1662
- listStyle: "none",
1663
- m: 0,
1664
- p: 0
1665
- }
1666
- },
1667
- ALL_SEVERITIES.map((severity) => {
1668
- const count = severityCounts[severity];
1669
- return /* @__PURE__ */ React21.createElement(
1670
- import_ui20.Box,
1671
- {
1672
- "aria-label": severityRemainingCountLabel(severity, count),
1673
- component: "li",
1674
- key: severity,
1675
- sx: { alignItems: "center", display: "flex", gap: 0.5 }
1676
- },
1677
- /* @__PURE__ */ React21.createElement(SeverityIcon, { severity }),
1678
- /* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "body2", fontWeight: "bold" }, count),
1679
- /* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "body2" }, severityPluralLabel(severity))
1680
- );
1681
- })
1682
- ));
1689
+ ))), /* @__PURE__ */ React23.createElement(Promotions, { report }));
1683
1690
  }
1684
1691
 
1685
1692
  // src/components/report-shell.tsx
@@ -1699,7 +1706,7 @@ function isCategoryPage(page) {
1699
1706
  return typeof page === "object" && "category" in page;
1700
1707
  }
1701
1708
  function ReportShell({ report }) {
1702
- const [activePage, setActivePage] = (0, import_react5.useState)("overview");
1709
+ const [activePage, setActivePage] = (0, import_react6.useState)("overview");
1703
1710
  const currentTab = activeTab(activePage);
1704
1711
  const handleTabChange = (_, value) => {
1705
1712
  setActivePage(value);
@@ -1715,10 +1722,10 @@ function ReportShell({ report }) {
1715
1722
  setActivePage(activePage.backTo);
1716
1723
  }
1717
1724
  };
1718
- return /* @__PURE__ */ React22.createElement(import_ui21.Box, null, /* @__PURE__ */ React22.createElement(
1719
- import_ui21.Tabs,
1725
+ return /* @__PURE__ */ React24.createElement(import_ui23.Box, { sx: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 } }, /* @__PURE__ */ React24.createElement(import_ui23.Box, { sx: { flexShrink: 0 } }, /* @__PURE__ */ React24.createElement(
1726
+ import_ui23.Tabs,
1720
1727
  {
1721
- "aria-label": (0, import_i18n20.__)("Audit navigation", "elementor"),
1728
+ "aria-label": (0, import_i18n22.__)("Audit navigation", "elementor"),
1722
1729
  value: currentTab,
1723
1730
  onChange: handleTabChange,
1724
1731
  textColor: "secondary",
@@ -1727,30 +1734,30 @@ function ReportShell({ report }) {
1727
1734
  centered: true,
1728
1735
  variant: "fullWidth"
1729
1736
  },
1730
- /* @__PURE__ */ React22.createElement(import_ui21.Tab, { value: "overview", label: (0, import_i18n20.__)("Overview", "elementor") }),
1731
- /* @__PURE__ */ React22.createElement(import_ui21.Tab, { value: "issues", label: (0, import_i18n20.__)("Issues", "elementor") })
1732
- ), /* @__PURE__ */ React22.createElement(import_ui21.Divider, null), activePage === "overview" && /* @__PURE__ */ React22.createElement(
1737
+ /* @__PURE__ */ React24.createElement(import_ui23.Tab, { value: "overview", label: (0, import_i18n22.__)("Overview", "elementor") }),
1738
+ /* @__PURE__ */ React24.createElement(import_ui23.Tab, { value: "issues", label: (0, import_i18n22.__)("Issues", "elementor") })
1739
+ ), /* @__PURE__ */ React24.createElement(import_ui23.Divider, null)), /* @__PURE__ */ React24.createElement(import_ui23.Box, { sx: { flex: 1, minHeight: 0, overflowY: "auto" } }, activePage === "overview" && /* @__PURE__ */ React24.createElement(
1733
1740
  OverviewPage,
1734
1741
  {
1735
1742
  report,
1736
- onCategoryClick: (category) => openCategory(category, "overview"),
1737
- onStatusClick: (status) => openAllAudits(status, "overview")
1743
+ onCategoryClick: (category) => openCategory(category, "overview")
1738
1744
  }
1739
- ), activePage === "issues" && /* @__PURE__ */ React22.createElement(
1745
+ ), activePage === "issues" && /* @__PURE__ */ React24.createElement(
1740
1746
  IssuesPage,
1741
1747
  {
1742
1748
  report,
1743
1749
  onCategoryClick: (category) => openCategory(category, "issues"),
1744
- onAllAuditsClick: () => openAllAudits()
1750
+ onAllAuditsClick: () => openAllAudits(),
1751
+ onStatusClick: (status) => openAllAudits(status)
1745
1752
  }
1746
- ), isAllAuditsPage(activePage) && /* @__PURE__ */ React22.createElement(
1753
+ ), isAllAuditsPage(activePage) && /* @__PURE__ */ React24.createElement(
1747
1754
  AllAuditsPage,
1748
1755
  {
1749
1756
  report,
1750
1757
  initialExpandedStatus: activePage.expand,
1751
1758
  onBack: backFromSubPage
1752
1759
  }
1753
- ), isCategoryPage(activePage) && /* @__PURE__ */ React22.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage }));
1760
+ ), isCategoryPage(activePage) && /* @__PURE__ */ React24.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage })));
1754
1761
  }
1755
1762
 
1756
1763
  // src/components/audit-panel.tsx
@@ -1759,23 +1766,32 @@ function AuditPanel() {
1759
1766
  const currentDocumentId = (0, import_editor_elements5.getCurrentDocumentId)() ?? 0;
1760
1767
  const onRun = () => run(currentDocumentId);
1761
1768
  const lastScanLabel = report ? new Date(report.runAt).toLocaleTimeString() : null;
1762
- return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(
1769
+ return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(
1763
1770
  import_editor_floating_panels.FloatingPanelHeader,
1764
1771
  {
1765
1772
  panelId: "audit-panel",
1766
- title: (0, import_i18n21.__)("Page Audit", "elementor"),
1767
- badge: (0, import_i18n21.__)("Beta", "elementor"),
1773
+ title: (0, import_i18n23.__)("Page Audit", "elementor"),
1774
+ badge: (0, import_i18n23.__)("Beta", "elementor"),
1768
1775
  titleVariant: "subtitle2"
1769
1776
  }
1770
- ), /* @__PURE__ */ React23.createElement(import_editor_floating_panels.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(import_editor_floating_panels.FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React23.createElement(import_ui22.Typography, { variant: "caption", sx: { flex: 1 } }, (0, import_i18n21.__)("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React23.createElement(import_ui22.Box, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React23.createElement(AuditFeedback, null), /* @__PURE__ */ React23.createElement(
1771
- import_ui22.Button,
1777
+ ), /* @__PURE__ */ React25.createElement(
1778
+ import_editor_floating_panels.FloatingPanelBody,
1779
+ {
1780
+ sx: status === "ready" ? { display: "flex", flexDirection: "column", overflow: "hidden", minHeight: 0 } : void 0
1781
+ },
1782
+ status === "idle" && /* @__PURE__ */ React25.createElement(WelcomePage, null),
1783
+ status === "loading" && /* @__PURE__ */ React25.createElement(LoadingPage, null),
1784
+ status === "error" && /* @__PURE__ */ React25.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }),
1785
+ status === "ready" && report && /* @__PURE__ */ React25.createElement(ReportShell, { report })
1786
+ ), /* @__PURE__ */ React25.createElement(import_editor_floating_panels.FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React25.createElement(import_ui24.Typography, { variant: "caption", sx: { flex: 1 } }, (0, import_i18n23.__)("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React25.createElement(import_ui24.Box, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React25.createElement(AuditFeedback, null), /* @__PURE__ */ React25.createElement(
1787
+ import_ui24.Button,
1772
1788
  {
1773
1789
  variant: "contained",
1774
1790
  size: "small",
1775
1791
  onClick: onRun,
1776
1792
  disabled: status === "loading" || currentDocumentId === 0
1777
1793
  },
1778
- lastScanLabel ? (0, import_i18n21.__)("Re-scan", "elementor") : (0, import_i18n21.__)("Run page audit", "elementor")
1794
+ lastScanLabel ? (0, import_i18n23.__)("Re-scan", "elementor") : (0, import_i18n23.__)("Run page audit", "elementor")
1779
1795
  )));
1780
1796
  }
1781
1797
 
@@ -1800,7 +1816,7 @@ function useAuditToggleProps() {
1800
1816
  const { isOpen } = auditPanel.useFloatingPanelStatus();
1801
1817
  const { toggle } = auditPanel.useFloatingPanelActions();
1802
1818
  return {
1803
- title: (0, import_i18n22.__)("Audit Page", "elementor"),
1819
+ title: (0, import_i18n24.__)("Audit Page", "elementor"),
1804
1820
  icon: import_icons12.ShieldCheckIcon,
1805
1821
  selected: isOpen,
1806
1822
  onClick: () => toggle()
@@ -1818,15 +1834,15 @@ function registerAppBarAuditsToggle() {
1818
1834
  }
1819
1835
 
1820
1836
  // src/audits/accessibility-policy.ts
1821
- var import_i18n23 = require("@wordpress/i18n");
1837
+ var import_i18n25 = require("@wordpress/i18n");
1822
1838
  var audit = {
1823
1839
  id: "audits/accessibility-policy",
1824
- title: (0, import_i18n23.__)("Accessibility policy", "elementor"),
1825
- description: (0, import_i18n23.__)(
1840
+ title: (0, import_i18n25.__)("Accessibility policy", "elementor"),
1841
+ description: (0, import_i18n25.__)(
1826
1842
  "An accessibility policy demonstrates your commitment to digital inclusion and may be legally required in some regions.",
1827
1843
  "elementor"
1828
1844
  ),
1829
- fixHint: (0, import_i18n23.__)("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1845
+ fixHint: (0, import_i18n25.__)("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1830
1846
  categories: ["compliance"],
1831
1847
  severity: "info",
1832
1848
  weight: 1,
@@ -1839,7 +1855,7 @@ var audit = {
1839
1855
  violations: [
1840
1856
  {
1841
1857
  auditId: audit.id,
1842
- label: (0, import_i18n23.__)("Ally plugin is not installed or active.", "elementor"),
1858
+ label: (0, import_i18n25.__)("Ally plugin is not installed or active.", "elementor"),
1843
1859
  externalUrl: ctx.pageContext.ally_plugin_url
1844
1860
  }
1845
1861
  ]
@@ -1848,15 +1864,15 @@ var audit = {
1848
1864
  };
1849
1865
 
1850
1866
  // src/audits/cookie-policy.ts
1851
- var import_i18n24 = require("@wordpress/i18n");
1867
+ var import_i18n26 = require("@wordpress/i18n");
1852
1868
  var audit2 = {
1853
1869
  id: "audits/cookie-policy",
1854
- title: (0, import_i18n24.__)("Cookie policy", "elementor"),
1855
- description: (0, import_i18n24.__)(
1870
+ title: (0, import_i18n26.__)("Cookie policy", "elementor"),
1871
+ description: (0, import_i18n26.__)(
1856
1872
  "A cookie policy is required by privacy regulations such as GDPR (EU) or CCPA (US) to inform visitors about tracking and data collection.",
1857
1873
  "elementor"
1858
1874
  ),
1859
- fixHint: (0, import_i18n24.__)("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1875
+ fixHint: (0, import_i18n26.__)("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1860
1876
  categories: ["compliance"],
1861
1877
  severity: "info",
1862
1878
  weight: 1,
@@ -1869,7 +1885,7 @@ var audit2 = {
1869
1885
  violations: [
1870
1886
  {
1871
1887
  auditId: audit2.id,
1872
- label: (0, import_i18n24.__)("Cookiez plugin is not installed or active.", "elementor"),
1888
+ label: (0, import_i18n26.__)("Cookiez plugin is not installed or active.", "elementor"),
1873
1889
  externalUrl: ctx.pageContext.cookiez_plugin_url
1874
1890
  }
1875
1891
  ]
@@ -1878,35 +1894,43 @@ var audit2 = {
1878
1894
  };
1879
1895
 
1880
1896
  // src/audits/deep-nesting.ts
1881
- var import_i18n25 = require("@wordpress/i18n");
1897
+ var import_editor_elements6 = require("@elementor/editor-elements");
1898
+ var import_i18n27 = require("@wordpress/i18n");
1882
1899
  var MAX_NESTING_DEPTH = 6;
1900
+ function isNestingElement(node, widgetsCache) {
1901
+ if (node.elType === "container") {
1902
+ return true;
1903
+ }
1904
+ return !!widgetsCache?.[node.elType]?.meta?.is_container;
1905
+ }
1883
1906
  var audit3 = {
1884
1907
  id: "audits/deep-nesting",
1885
- title: (0, import_i18n25.__)("Deep container nesting", "elementor"),
1886
- description: (0, import_i18n25.__)(
1908
+ title: (0, import_i18n27.__)("Deep container nesting", "elementor"),
1909
+ description: (0, import_i18n27.__)(
1887
1910
  "Container nesting exceeds the recommended depth. Deep DOM trees hurt rendering performance and readability.",
1888
1911
  "elementor"
1889
1912
  ),
1890
- fixHint: (0, import_i18n25.__)("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1913
+ fixHint: (0, import_i18n27.__)("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1891
1914
  categories: ["performance", "best-practices"],
1892
1915
  severity: "warning",
1893
1916
  weight: 5,
1894
1917
  evaluate: (ctx) => {
1895
1918
  if (ctx.elements.tree.length === 0) {
1896
- return { status: "skipped", reason: (0, import_i18n25.__)("No elements", "elementor") };
1919
+ return { status: "skipped", reason: (0, import_i18n27.__)("No elements", "elementor") };
1897
1920
  }
1921
+ const widgetsCache = (0, import_editor_elements6.getWidgetsCache)();
1898
1922
  const violations = [];
1899
1923
  walkElements(ctx.elements.tree, (node, parents) => {
1900
- if (node.elType !== "container") {
1924
+ if (!isNestingElement(node, widgetsCache)) {
1901
1925
  return;
1902
1926
  }
1903
- const depth = parents.length + 1;
1927
+ const depth = parents.filter((parent) => isNestingElement(parent, widgetsCache)).length + 1;
1904
1928
  if (depth > MAX_NESTING_DEPTH) {
1905
1929
  violations.push({
1906
1930
  auditId: audit3.id,
1907
1931
  elementId: node.id,
1908
1932
  targetHint: "element-settings",
1909
- label: (0, import_i18n25.__)("Container nesting is too deep.", "elementor")
1933
+ label: (0, import_i18n27.__)("Container nesting is too deep.", "elementor")
1910
1934
  });
1911
1935
  }
1912
1936
  });
@@ -1915,15 +1939,15 @@ var audit3 = {
1915
1939
  };
1916
1940
 
1917
1941
  // src/audits/default-design-system.ts
1918
- var import_i18n26 = require("@wordpress/i18n");
1942
+ var import_i18n28 = require("@wordpress/i18n");
1919
1943
  var audit4 = {
1920
1944
  id: "audits/default-design-system",
1921
- title: (0, import_i18n26.__)("Default website kit", "elementor"),
1922
- description: (0, import_i18n26.__)(
1945
+ title: (0, import_i18n28.__)("Default website kit", "elementor"),
1946
+ description: (0, import_i18n28.__)(
1923
1947
  "Your website is using the default design system colors and fonts. Custom branding makes the website feel uniquely yours.",
1924
1948
  "elementor"
1925
1949
  ),
1926
- fixHint: (0, import_i18n26.__)("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1950
+ fixHint: (0, import_i18n28.__)("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1927
1951
  categories: ["best-practices"],
1928
1952
  severity: "info",
1929
1953
  weight: 1,
@@ -1936,7 +1960,7 @@ var audit4 = {
1936
1960
  violations: [
1937
1961
  {
1938
1962
  auditId: audit4.id,
1939
- label: (0, import_i18n26.__)("Kit appears unchanged from default.", "elementor"),
1963
+ label: (0, import_i18n28.__)("Kit appears unchanged from default.", "elementor"),
1940
1964
  targetHint: "site-settings"
1941
1965
  }
1942
1966
  ]
@@ -1945,22 +1969,22 @@ var audit4 = {
1945
1969
  };
1946
1970
 
1947
1971
  // src/audits/deprecated-widgets.ts
1948
- var import_editor_elements6 = require("@elementor/editor-elements");
1949
- var import_i18n27 = require("@wordpress/i18n");
1972
+ var import_editor_elements7 = require("@elementor/editor-elements");
1973
+ var import_i18n29 = require("@wordpress/i18n");
1950
1974
  var DEPRECATION_CONTROL_NAME = "deprecation_message";
1951
1975
  var audit5 = {
1952
1976
  id: "audits/deprecated-widgets",
1953
- title: (0, import_i18n27.__)("Deprecated widgets", "elementor"),
1954
- description: (0, import_i18n27.__)(
1977
+ title: (0, import_i18n29.__)("Deprecated widgets", "elementor"),
1978
+ description: (0, import_i18n29.__)(
1955
1979
  "Deprecated widgets should not be used. For better capabilities use the recommended replacement.",
1956
1980
  "elementor"
1957
1981
  ),
1958
- fixHint: (0, import_i18n27.__)("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1982
+ fixHint: (0, import_i18n29.__)("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1959
1983
  categories: ["best-practices", "performance"],
1960
1984
  severity: "warning",
1961
1985
  weight: 7,
1962
1986
  evaluate: (ctx) => {
1963
- const widgetsCache = (0, import_editor_elements6.getWidgetsCache)();
1987
+ const widgetsCache = (0, import_editor_elements7.getWidgetsCache)();
1964
1988
  if (!widgetsCache) {
1965
1989
  return { status: "skipped", reason: "widgets-cache-unavailable" };
1966
1990
  }
@@ -1982,7 +2006,7 @@ var audit5 = {
1982
2006
  auditId: audit5.id,
1983
2007
  elementId: node.id,
1984
2008
  targetHint: "element-settings",
1985
- label: (0, import_i18n27.__)("Using deprecated widget.", "elementor")
2009
+ label: (0, import_i18n29.__)("Using deprecated widget.", "elementor")
1986
2010
  });
1987
2011
  });
1988
2012
  return violations.length === 0 ? { status: "pass" } : { status: "fail", violations };
@@ -1990,7 +2014,7 @@ var audit5 = {
1990
2014
  };
1991
2015
 
1992
2016
  // src/audits/google-consent-mode.ts
1993
- var import_i18n28 = require("@wordpress/i18n");
2017
+ var import_i18n30 = require("@wordpress/i18n");
1994
2018
 
1995
2019
  // src/utils/fetch-rendered-html.ts
1996
2020
  var FETCH_TIMEOUT_MS = 1e4;
@@ -2034,12 +2058,12 @@ function hasConsentDefaultCall(html) {
2034
2058
  // src/audits/google-consent-mode.ts
2035
2059
  var audit6 = {
2036
2060
  id: "audits/google-consent-mode",
2037
- title: (0, import_i18n28.__)("Google Consent Mode", "elementor"),
2038
- description: (0, import_i18n28.__)(
2061
+ title: (0, import_i18n30.__)("Google Consent Mode", "elementor"),
2062
+ description: (0, import_i18n30.__)(
2039
2063
  "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.",
2040
2064
  "elementor"
2041
2065
  ),
2042
- fixHint: (0, import_i18n28.__)(
2066
+ fixHint: (0, import_i18n30.__)(
2043
2067
  "Turn on Google Consent Mode in your cookie consent plugin so Google tags respect visitor consent choices.",
2044
2068
  "elementor"
2045
2069
  ),
@@ -2048,19 +2072,19 @@ var audit6 = {
2048
2072
  weight: 1,
2049
2073
  evaluate: async (ctx) => {
2050
2074
  if (!ctx.pageContext.frontend_url) {
2051
- return { status: "skipped", reason: (0, import_i18n28.__)("Page is not published.", "elementor") };
2075
+ return { status: "skipped", reason: (0, import_i18n30.__)("Page is not published.", "elementor") };
2052
2076
  }
2053
2077
  const html = await fetchRenderedHtml(ctx.pageContext.frontend_url);
2054
2078
  if (!html) {
2055
- return { status: "skipped", reason: (0, import_i18n28.__)("Could not fetch the published page.", "elementor") };
2079
+ return { status: "skipped", reason: (0, import_i18n30.__)("Could not fetch the published page.", "elementor") };
2056
2080
  }
2057
2081
  if (!hasGoogleTracking(html)) {
2058
- return { status: "skipped", reason: (0, import_i18n28.__)("No Google tracking product detected.", "elementor") };
2082
+ return { status: "skipped", reason: (0, import_i18n30.__)("No Google tracking product detected.", "elementor") };
2059
2083
  }
2060
2084
  if (hasConsentDefaultCall(html)) {
2061
2085
  return { status: "pass" };
2062
2086
  }
2063
- const label = (0, import_i18n28.__)("No Google Consent Mode signal was found on the page.", "elementor");
2087
+ const label = (0, import_i18n30.__)("No Google Consent Mode signal was found on the page.", "elementor");
2064
2088
  const isCookiezReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
2065
2089
  if (isCookiezReady) {
2066
2090
  return {
@@ -2069,7 +2093,7 @@ var audit6 = {
2069
2093
  {
2070
2094
  auditId: audit6.id,
2071
2095
  label,
2072
- ctaLabel: (0, import_i18n28.__)("Enable", "elementor"),
2096
+ ctaLabel: (0, import_i18n30.__)("Enable", "elementor"),
2073
2097
  externalUrl: ctx.pageContext.cookiez_consent_mode_settings_url
2074
2098
  }
2075
2099
  ]
@@ -2089,7 +2113,7 @@ var audit6 = {
2089
2113
  };
2090
2114
 
2091
2115
  // src/audits/heading-structure.ts
2092
- var import_i18n29 = require("@wordpress/i18n");
2116
+ var import_i18n31 = require("@wordpress/i18n");
2093
2117
  var HEADING_LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
2094
2118
  var HEADING_CONTROLS_REGISTRY = {
2095
2119
  // Core
@@ -2267,27 +2291,27 @@ function extractPageHeadings(tree) {
2267
2291
  }
2268
2292
  var audit7 = {
2269
2293
  id: "audits/heading-structure",
2270
- title: (0, import_i18n29.__)("Heading structure", "elementor"),
2271
- description: (0, import_i18n29.__)("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2272
- fixHint: (0, import_i18n29.__)("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2294
+ title: (0, import_i18n31.__)("Heading structure", "elementor"),
2295
+ description: (0, import_i18n31.__)("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2296
+ fixHint: (0, import_i18n31.__)("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2273
2297
  categories: ["seo", "accessibility"],
2274
2298
  severity: "error",
2275
2299
  weight: 10,
2276
2300
  evaluate: (ctx) => {
2277
2301
  if (ctx.elements.tree.length === 0) {
2278
- return { status: "skipped", reason: (0, import_i18n29.__)("No elements", "elementor") };
2302
+ return { status: "skipped", reason: (0, import_i18n31.__)("No elements", "elementor") };
2279
2303
  }
2280
2304
  const headings = extractPageHeadings(ctx.elements.tree);
2281
2305
  const violations = [];
2282
2306
  if (headings.length === 0) {
2283
2307
  violations.push({
2284
2308
  auditId: audit7.id,
2285
- label: (0, import_i18n29.__)("No headings found on the page.", "elementor")
2309
+ label: (0, import_i18n31.__)("No headings found on the page.", "elementor")
2286
2310
  });
2287
2311
  } else {
2288
2312
  const h1Count = headings.filter((h) => h.level === 1).length;
2289
2313
  if (h1Count === 0) {
2290
- violations.push({ auditId: audit7.id, label: (0, import_i18n29.__)("No H1 on the page.", "elementor") });
2314
+ violations.push({ auditId: audit7.id, label: (0, import_i18n31.__)("No H1 on the page.", "elementor") });
2291
2315
  }
2292
2316
  if (h1Count > 1) {
2293
2317
  headings.filter((h) => h.level === 1).slice(1).forEach(
@@ -2295,7 +2319,7 @@ var audit7 = {
2295
2319
  auditId: audit7.id,
2296
2320
  elementId: h.elementId,
2297
2321
  targetHint: "element-settings",
2298
- label: (0, import_i18n29.__)("More than one H1 on the page.", "elementor")
2322
+ label: (0, import_i18n31.__)("More than one H1 on the page.", "elementor")
2299
2323
  })
2300
2324
  );
2301
2325
  }
@@ -2305,7 +2329,7 @@ var audit7 = {
2305
2329
  auditId: audit7.id,
2306
2330
  elementId: headings[i].elementId,
2307
2331
  targetHint: "element-settings",
2308
- label: (0, import_i18n29.__)("Heading level skipped.", "elementor")
2332
+ label: (0, import_i18n31.__)("Heading level skipped.", "elementor")
2309
2333
  });
2310
2334
  }
2311
2335
  }
@@ -2315,24 +2339,24 @@ var audit7 = {
2315
2339
  };
2316
2340
 
2317
2341
  // src/audits/hidden-elements.ts
2318
- var import_i18n30 = require("@wordpress/i18n");
2342
+ var import_i18n32 = require("@wordpress/i18n");
2319
2343
  function isHiddenOnAllDevices(settings) {
2320
2344
  return Boolean(settings.hide_desktop) && Boolean(settings.hide_tablet) && Boolean(settings.hide_mobile);
2321
2345
  }
2322
2346
  var audit8 = {
2323
2347
  id: "audits/hidden-elements",
2324
- title: (0, import_i18n30.__)("Hidden elements", "elementor"),
2325
- description: (0, import_i18n30.__)(
2348
+ title: (0, import_i18n32.__)("Hidden elements", "elementor"),
2349
+ description: (0, import_i18n32.__)(
2326
2350
  "Elements hidden on all devices simultaneously are effectively dead code in the page tree.",
2327
2351
  "elementor"
2328
2352
  ),
2329
- fixHint: (0, import_i18n30.__)("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2353
+ fixHint: (0, import_i18n32.__)("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2330
2354
  categories: ["best-practices", "performance"],
2331
2355
  severity: "info",
2332
2356
  weight: 3,
2333
2357
  evaluate: (ctx) => {
2334
2358
  if (ctx.elements.tree.length === 0) {
2335
- return { status: "skipped", reason: (0, import_i18n30.__)("No elements", "elementor") };
2359
+ return { status: "skipped", reason: (0, import_i18n32.__)("No elements", "elementor") };
2336
2360
  }
2337
2361
  const violations = [];
2338
2362
  walkElements(ctx.elements.tree, (node) => {
@@ -2341,7 +2365,7 @@ var audit8 = {
2341
2365
  auditId: audit8.id,
2342
2366
  elementId: node.id,
2343
2367
  targetHint: "element-settings",
2344
- label: (0, import_i18n30.__)("Element is hidden on all devices.", "elementor")
2368
+ label: (0, import_i18n32.__)("Element is hidden on all devices.", "elementor")
2345
2369
  });
2346
2370
  }
2347
2371
  });
@@ -2350,7 +2374,7 @@ var audit8 = {
2350
2374
  };
2351
2375
 
2352
2376
  // src/audits/images-alt-text.ts
2353
- var import_i18n31 = require("@wordpress/i18n");
2377
+ var import_i18n33 = require("@wordpress/i18n");
2354
2378
 
2355
2379
  // src/utils/image-alt.ts
2356
2380
  function hasMeaningfulAlt(media, pageContext) {
@@ -2370,15 +2394,15 @@ function isImageSourcePresent(media) {
2370
2394
  // src/audits/images-alt-text.ts
2371
2395
  var audit9 = {
2372
2396
  id: "audits/images-alt-text",
2373
- title: (0, import_i18n31.__)("Images alt text", "elementor"),
2374
- description: (0, import_i18n31.__)("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2375
- fixHint: (0, import_i18n31.__)("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2397
+ title: (0, import_i18n33.__)("Images alt text", "elementor"),
2398
+ description: (0, import_i18n33.__)("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2399
+ fixHint: (0, import_i18n33.__)("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2376
2400
  categories: ["seo", "accessibility"],
2377
2401
  severity: "error",
2378
2402
  weight: 10,
2379
2403
  evaluate: (ctx) => {
2380
2404
  if (!hasPageImages(ctx.elements.tree)) {
2381
- return { status: "skipped", reason: (0, import_i18n31.__)("No images", "elementor") };
2405
+ return { status: "skipped", reason: (0, import_i18n33.__)("No images", "elementor") };
2382
2406
  }
2383
2407
  const violations = [];
2384
2408
  const failedWidgetIds = /* @__PURE__ */ new Set();
@@ -2394,7 +2418,7 @@ var audit9 = {
2394
2418
  auditId: audit9.id,
2395
2419
  elementId: node.id,
2396
2420
  targetHint: "element-settings",
2397
- label: (0, import_i18n31.__)("Image is missing alt text.", "elementor"),
2421
+ label: (0, import_i18n33.__)("Image is missing alt text.", "elementor"),
2398
2422
  externalUrl: ctx.pageContext.ally_plugin_url
2399
2423
  });
2400
2424
  }
@@ -2404,20 +2428,20 @@ var audit9 = {
2404
2428
  };
2405
2429
 
2406
2430
  // src/audits/images-too-large.ts
2407
- var import_i18n32 = require("@wordpress/i18n");
2431
+ var import_i18n34 = require("@wordpress/i18n");
2408
2432
  var SIZE_THRESHOLD_BYTES = 500 * 1024;
2409
2433
  var BYTES_PER_KB = 1024;
2410
2434
  var audit10 = {
2411
2435
  id: "audits/images-too-large",
2412
- title: (0, import_i18n32.__)("Oversized images", "elementor"),
2413
- description: (0, import_i18n32.__)("Large image files slow down the page.", "elementor"),
2414
- fixHint: (0, import_i18n32.__)("Replace the image with a smaller version or enable image optimization.", "elementor"),
2436
+ title: (0, import_i18n34.__)("Oversized images", "elementor"),
2437
+ description: (0, import_i18n34.__)("Large image files slow down the page.", "elementor"),
2438
+ fixHint: (0, import_i18n34.__)("Replace the image with a smaller version or enable image optimization.", "elementor"),
2415
2439
  categories: ["performance"],
2416
2440
  severity: "warning",
2417
2441
  weight: 7,
2418
2442
  evaluate: (ctx) => {
2419
2443
  if (!hasPageImages(ctx.elements.tree)) {
2420
- return { status: "skipped", reason: (0, import_i18n32.__)("No images", "elementor") };
2444
+ return { status: "skipped", reason: (0, import_i18n34.__)("No images", "elementor") };
2421
2445
  }
2422
2446
  const widgetMaxKb = /* @__PURE__ */ new Map();
2423
2447
  let oversizedImageCount = 0;
@@ -2439,9 +2463,9 @@ var audit10 = {
2439
2463
  auditId: audit10.id,
2440
2464
  elementId,
2441
2465
  targetHint: "element-settings",
2442
- label: (0, import_i18n32.sprintf)(
2466
+ label: (0, import_i18n34.sprintf)(
2443
2467
  /* translators: %d is the image file size in kilobytes. */
2444
- (0, import_i18n32.__)("Image is %d KB (over 500 KB).", "elementor"),
2468
+ (0, import_i18n34.__)("Image is %d KB (over 500 KB).", "elementor"),
2445
2469
  kb
2446
2470
  ),
2447
2471
  externalUrl: ctx.pageContext.image_optimization_plugin_url
@@ -2451,21 +2475,21 @@ var audit10 = {
2451
2475
  };
2452
2476
 
2453
2477
  // src/audits/nested-boxed-containers.ts
2454
- var import_i18n33 = require("@wordpress/i18n");
2478
+ var import_i18n35 = require("@wordpress/i18n");
2455
2479
  function isBoxed(settings) {
2456
2480
  return settings.content_width === "boxed";
2457
2481
  }
2458
2482
  var audit11 = {
2459
2483
  id: "audits/nested-boxed-containers",
2460
- title: (0, import_i18n33.__)("Boxed container nested inside a boxed parent", "elementor"),
2461
- description: (0, import_i18n33.__)("An inner container does not need to be boxed when its parent already is.", "elementor"),
2462
- fixHint: (0, import_i18n33.__)("Change the inner container's content width to Full Width.", "elementor"),
2484
+ title: (0, import_i18n35.__)("Boxed container nested inside a boxed parent", "elementor"),
2485
+ description: (0, import_i18n35.__)("An inner container does not need to be boxed when its parent already is.", "elementor"),
2486
+ fixHint: (0, import_i18n35.__)("Change the inner container's content width to Full Width.", "elementor"),
2463
2487
  categories: ["best-practices", "performance"],
2464
2488
  severity: "info",
2465
2489
  weight: 5,
2466
2490
  evaluate: (ctx) => {
2467
2491
  if (ctx.elements.tree.length === 0) {
2468
- return { status: "skipped", reason: (0, import_i18n33.__)("No elements", "elementor") };
2492
+ return { status: "skipped", reason: (0, import_i18n35.__)("No elements", "elementor") };
2469
2493
  }
2470
2494
  const violations = [];
2471
2495
  walkElements(ctx.elements.tree, (node, parents) => {
@@ -2478,7 +2502,7 @@ var audit11 = {
2478
2502
  auditId: audit11.id,
2479
2503
  elementId: node.id,
2480
2504
  targetHint: "element-settings",
2481
- label: (0, import_i18n33.__)("Nested boxed container.", "elementor")
2505
+ label: (0, import_i18n35.__)("Nested boxed container.", "elementor")
2482
2506
  });
2483
2507
  }
2484
2508
  });
@@ -2487,12 +2511,12 @@ var audit11 = {
2487
2511
  };
2488
2512
 
2489
2513
  // src/audits/page-excerpt.ts
2490
- var import_i18n34 = require("@wordpress/i18n");
2514
+ var import_i18n36 = require("@wordpress/i18n");
2491
2515
  var audit12 = {
2492
2516
  id: "audits/page-excerpt",
2493
- title: (0, import_i18n34.__)("Page excerpt", "elementor"),
2494
- description: (0, import_i18n34.__)("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2495
- fixHint: (0, import_i18n34.__)("Open Page Settings and write a short excerpt.", "elementor"),
2517
+ title: (0, import_i18n36.__)("Page excerpt", "elementor"),
2518
+ description: (0, import_i18n36.__)("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2519
+ fixHint: (0, import_i18n36.__)("Open Page Settings and write a short excerpt.", "elementor"),
2496
2520
  categories: ["seo"],
2497
2521
  severity: "warning",
2498
2522
  weight: 5,
@@ -2505,7 +2529,7 @@ var audit12 = {
2505
2529
  violations: [
2506
2530
  {
2507
2531
  auditId: audit12.id,
2508
- label: (0, import_i18n34.__)("Page has no excerpt.", "elementor"),
2532
+ label: (0, import_i18n36.__)("Page has no excerpt.", "elementor"),
2509
2533
  targetHint: "page-settings",
2510
2534
  angieFix: true
2511
2535
  }
@@ -2515,12 +2539,12 @@ var audit12 = {
2515
2539
  };
2516
2540
 
2517
2541
  // src/audits/page-featured-image.ts
2518
- var import_i18n35 = require("@wordpress/i18n");
2542
+ var import_i18n37 = require("@wordpress/i18n");
2519
2543
  var audit13 = {
2520
2544
  id: "audits/page-featured-image",
2521
- title: (0, import_i18n35.__)("Page featured image", "elementor"),
2522
- description: (0, import_i18n35.__)("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2523
- fixHint: (0, import_i18n35.__)("Open Page Settings and set a featured image.", "elementor"),
2545
+ title: (0, import_i18n37.__)("Page featured image", "elementor"),
2546
+ description: (0, import_i18n37.__)("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2547
+ fixHint: (0, import_i18n37.__)("Open Page Settings and set a featured image.", "elementor"),
2524
2548
  categories: ["seo"],
2525
2549
  severity: "info",
2526
2550
  weight: 5,
@@ -2533,7 +2557,7 @@ var audit13 = {
2533
2557
  violations: [
2534
2558
  {
2535
2559
  auditId: audit13.id,
2536
- label: (0, import_i18n35.__)("No featured image set.", "elementor"),
2560
+ label: (0, import_i18n37.__)("No featured image set.", "elementor"),
2537
2561
  targetHint: "page-settings"
2538
2562
  }
2539
2563
  ]
@@ -2542,13 +2566,13 @@ var audit13 = {
2542
2566
  };
2543
2567
 
2544
2568
  // src/audits/page-title.ts
2545
- var import_i18n36 = require("@wordpress/i18n");
2569
+ var import_i18n38 = require("@wordpress/i18n");
2546
2570
  var MAX_TITLE_LENGTH = 60;
2547
2571
  var audit14 = {
2548
2572
  id: "audits/page-title",
2549
- title: (0, import_i18n36.__)("Page title", "elementor"),
2550
- description: (0, import_i18n36.__)("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2551
- fixHint: (0, import_i18n36.__)("Open Page Settings and add a title.", "elementor"),
2573
+ title: (0, import_i18n38.__)("Page title", "elementor"),
2574
+ description: (0, import_i18n38.__)("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2575
+ fixHint: (0, import_i18n38.__)("Open Page Settings and add a title.", "elementor"),
2552
2576
  categories: ["seo"],
2553
2577
  severity: "error",
2554
2578
  weight: 10,
@@ -2560,7 +2584,7 @@ var audit14 = {
2560
2584
  violations: [
2561
2585
  {
2562
2586
  auditId: audit14.id,
2563
- label: (0, import_i18n36.__)("Page has no title.", "elementor"),
2587
+ label: (0, import_i18n38.__)("Page has no title.", "elementor"),
2564
2588
  targetHint: "page-settings",
2565
2589
  angieFix: true
2566
2590
  }
@@ -2573,7 +2597,7 @@ var audit14 = {
2573
2597
  violations: [
2574
2598
  {
2575
2599
  auditId: audit14.id,
2576
- label: (0, import_i18n36.__)("Page title is too long.", "elementor"),
2600
+ label: (0, import_i18n38.__)("Page title is too long.", "elementor"),
2577
2601
  targetHint: "page-settings",
2578
2602
  angieFix: true
2579
2603
  }
@@ -2585,7 +2609,7 @@ var audit14 = {
2585
2609
  };
2586
2610
 
2587
2611
  // src/audits/prefer-global-colors.ts
2588
- var import_i18n37 = require("@wordpress/i18n");
2612
+ var import_i18n39 = require("@wordpress/i18n");
2589
2613
 
2590
2614
  // src/utils/collect-hardcoded-colors.ts
2591
2615
  var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2653,18 +2677,18 @@ function findMatchingGlobalByValue(value, globals) {
2653
2677
  // src/audits/prefer-global-colors.ts
2654
2678
  var audit15 = {
2655
2679
  id: "audits/prefer-global-colors",
2656
- title: (0, import_i18n37.__)("Prefer global colors", "elementor"),
2657
- description: (0, import_i18n37.__)("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2658
- fixHint: (0, import_i18n37.__)("Replace the hard-coded value with the matching global color.", "elementor"),
2680
+ title: (0, import_i18n39.__)("Prefer global colors", "elementor"),
2681
+ description: (0, import_i18n39.__)("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2682
+ fixHint: (0, import_i18n39.__)("Replace the hard-coded value with the matching global color.", "elementor"),
2659
2683
  categories: ["best-practices"],
2660
2684
  severity: "info",
2661
2685
  weight: 3,
2662
2686
  evaluate: (ctx) => {
2663
2687
  if (ctx.elements.tree.length === 0) {
2664
- return { status: "skipped", reason: (0, import_i18n37.__)("No elements", "elementor") };
2688
+ return { status: "skipped", reason: (0, import_i18n39.__)("No elements", "elementor") };
2665
2689
  }
2666
2690
  if (ctx.kit.globals.colors.length === 0) {
2667
- return { status: "skipped", reason: (0, import_i18n37.__)("No global colors", "elementor") };
2691
+ return { status: "skipped", reason: (0, import_i18n39.__)("No global colors", "elementor") };
2668
2692
  }
2669
2693
  const violations = [];
2670
2694
  walkElements(ctx.elements.tree, (node) => {
@@ -2678,9 +2702,9 @@ var audit15 = {
2678
2702
  elementId: node.id,
2679
2703
  targetHint: "element-settings",
2680
2704
  angieFix: true,
2681
- label: (0, import_i18n37.sprintf)(
2705
+ label: (0, import_i18n39.sprintf)(
2682
2706
  /* translators: 1: hard-coded color value, 2: global color title. */
2683
- (0, import_i18n37.__)('replace "%1$s" with "%2$s" global color', "elementor"),
2707
+ (0, import_i18n39.__)('replace "%1$s" with "%2$s" global color', "elementor"),
2684
2708
  value,
2685
2709
  global.title
2686
2710
  )
@@ -2692,7 +2716,7 @@ var audit15 = {
2692
2716
  };
2693
2717
 
2694
2718
  // src/audits/prefer-global-fonts.ts
2695
- var import_i18n38 = require("@wordpress/i18n");
2719
+ var import_i18n40 = require("@wordpress/i18n");
2696
2720
 
2697
2721
  // src/utils/collect-hardcoded-fonts.ts
2698
2722
  var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2752,18 +2776,18 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
2752
2776
  // src/audits/prefer-global-fonts.ts
2753
2777
  var audit16 = {
2754
2778
  id: "audits/prefer-global-fonts",
2755
- title: (0, import_i18n38.__)("Prefer global fonts", "elementor"),
2756
- description: (0, import_i18n38.__)("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2757
- fixHint: (0, import_i18n38.__)("Replace the hard-coded value with the matching global font.", "elementor"),
2779
+ title: (0, import_i18n40.__)("Prefer global fonts", "elementor"),
2780
+ description: (0, import_i18n40.__)("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2781
+ fixHint: (0, import_i18n40.__)("Replace the hard-coded value with the matching global font.", "elementor"),
2758
2782
  categories: ["best-practices", "performance"],
2759
2783
  severity: "info",
2760
2784
  weight: 3,
2761
2785
  evaluate: (ctx) => {
2762
2786
  if (ctx.elements.tree.length === 0) {
2763
- return { status: "skipped", reason: (0, import_i18n38.__)("No elements", "elementor") };
2787
+ return { status: "skipped", reason: (0, import_i18n40.__)("No elements", "elementor") };
2764
2788
  }
2765
2789
  if (ctx.kit.globals.fonts.length === 0) {
2766
- return { status: "skipped", reason: (0, import_i18n38.__)("No global fonts", "elementor") };
2790
+ return { status: "skipped", reason: (0, import_i18n40.__)("No global fonts", "elementor") };
2767
2791
  }
2768
2792
  const violations = [];
2769
2793
  walkElements(ctx.elements.tree, (node) => {
@@ -2776,9 +2800,9 @@ var audit16 = {
2776
2800
  auditId: audit16.id,
2777
2801
  elementId: node.id,
2778
2802
  targetHint: "element-settings",
2779
- label: (0, import_i18n38.sprintf)(
2803
+ label: (0, import_i18n40.sprintf)(
2780
2804
  /* translators: %s: global font title. */
2781
- (0, import_i18n38.__)('replace hardcoded typography with "%s" global font', "elementor"),
2805
+ (0, import_i18n40.__)('replace hardcoded typography with "%s" global font', "elementor"),
2782
2806
  global.title
2783
2807
  )
2784
2808
  });
@@ -2789,15 +2813,15 @@ var audit16 = {
2789
2813
  };
2790
2814
 
2791
2815
  // src/audits/privacy-policy.ts
2792
- var import_i18n39 = require("@wordpress/i18n");
2816
+ var import_i18n41 = require("@wordpress/i18n");
2793
2817
  var audit17 = {
2794
2818
  id: "audits/privacy-policy",
2795
- title: (0, import_i18n39.__)("Privacy policy", "elementor"),
2796
- description: (0, import_i18n39.__)(
2819
+ title: (0, import_i18n41.__)("Privacy policy", "elementor"),
2820
+ description: (0, import_i18n41.__)(
2797
2821
  "A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
2798
2822
  "elementor"
2799
2823
  ),
2800
- fixHint: (0, import_i18n39.__)(
2824
+ fixHint: (0, import_i18n41.__)(
2801
2825
  "Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
2802
2826
  "elementor"
2803
2827
  ),
@@ -2813,9 +2837,9 @@ var audit17 = {
2813
2837
  violations: [
2814
2838
  {
2815
2839
  auditId: audit17.id,
2816
- label: (0, import_i18n39.__)("No privacy policy page is set.", "elementor"),
2840
+ label: (0, import_i18n41.__)("No privacy policy page is set.", "elementor"),
2817
2841
  externalUrl: ctx.pageContext.privacy_settings_url,
2818
- ctaLabel: (0, import_i18n39.__)("Create", "elementor")
2842
+ ctaLabel: (0, import_i18n41.__)("Create", "elementor")
2819
2843
  }
2820
2844
  ]
2821
2845
  };
@@ -2823,15 +2847,15 @@ var audit17 = {
2823
2847
  };
2824
2848
 
2825
2849
  // src/audits/robots-noindex.ts
2826
- var import_i18n40 = require("@wordpress/i18n");
2850
+ var import_i18n42 = require("@wordpress/i18n");
2827
2851
  var audit18 = {
2828
2852
  id: "audits/robots-noindex",
2829
- title: (0, import_i18n40.__)("Search engine visibility", "elementor"),
2830
- description: (0, import_i18n40.__)(
2853
+ title: (0, import_i18n42.__)("Search engine visibility", "elementor"),
2854
+ description: (0, import_i18n42.__)(
2831
2855
  "When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
2832
2856
  "elementor"
2833
2857
  ),
2834
- fixHint: (0, import_i18n40.__)(
2858
+ fixHint: (0, import_i18n42.__)(
2835
2859
  'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
2836
2860
  "elementor"
2837
2861
  ),
@@ -2847,7 +2871,7 @@ var audit18 = {
2847
2871
  violations: [
2848
2872
  {
2849
2873
  auditId: audit18.id,
2850
- label: (0, import_i18n40.__)("Search engines are discouraged from indexing this website.", "elementor"),
2874
+ label: (0, import_i18n42.__)("Search engines are discouraged from indexing this website.", "elementor"),
2851
2875
  externalUrl: ctx.pageContext.reading_settings_url
2852
2876
  }
2853
2877
  ]
@@ -2856,15 +2880,15 @@ var audit18 = {
2856
2880
  };
2857
2881
 
2858
2882
  // src/audits/scan-for-cookies.ts
2859
- var import_i18n41 = require("@wordpress/i18n");
2883
+ var import_i18n43 = require("@wordpress/i18n");
2860
2884
  var audit19 = {
2861
2885
  id: "audits/scan-for-cookies",
2862
- title: (0, import_i18n41.__)("Scan for cookies", "elementor"),
2863
- description: (0, import_i18n41.__)(
2886
+ title: (0, import_i18n43.__)("Scan for cookies", "elementor"),
2887
+ description: (0, import_i18n43.__)(
2864
2888
  "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.",
2865
2889
  "elementor"
2866
2890
  ),
2867
- fixHint: (0, import_i18n41.__)("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2891
+ fixHint: (0, import_i18n43.__)("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2868
2892
  categories: ["compliance"],
2869
2893
  severity: "info",
2870
2894
  weight: 0,
@@ -2875,7 +2899,7 @@ var audit19 = {
2875
2899
  violations: [
2876
2900
  {
2877
2901
  auditId: audit19.id,
2878
- label: (0, import_i18n41.__)("This page has not been scanned for cookies yet.", "elementor"),
2902
+ label: (0, import_i18n43.__)("This page has not been scanned for cookies yet.", "elementor"),
2879
2903
  externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
2880
2904
  }
2881
2905
  ]
@@ -2884,21 +2908,21 @@ var audit19 = {
2884
2908
  };
2885
2909
 
2886
2910
  // src/audits/sections-and-columns.ts
2887
- var import_i18n42 = require("@wordpress/i18n");
2911
+ var import_i18n44 = require("@wordpress/i18n");
2888
2912
  var audit20 = {
2889
2913
  id: "audits/sections-and-columns",
2890
- title: (0, import_i18n42.__)("Sections and columns", "elementor"),
2891
- description: (0, import_i18n42.__)(
2914
+ title: (0, import_i18n44.__)("Sections and columns", "elementor"),
2915
+ description: (0, import_i18n44.__)(
2892
2916
  "Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
2893
2917
  "elementor"
2894
2918
  ),
2895
- fixHint: (0, import_i18n42.__)("Use the Container Converter to replace each section/column with a container.", "elementor"),
2919
+ fixHint: (0, import_i18n44.__)("Use the Container Converter to replace each section/column with a container.", "elementor"),
2896
2920
  categories: ["best-practices", "performance"],
2897
2921
  severity: "warning",
2898
2922
  weight: 7,
2899
2923
  evaluate: (ctx) => {
2900
2924
  if (ctx.elements.tree.length === 0) {
2901
- return { status: "skipped", reason: (0, import_i18n42.__)("No elements", "elementor") };
2925
+ return { status: "skipped", reason: (0, import_i18n44.__)("No elements", "elementor") };
2902
2926
  }
2903
2927
  const violations = [];
2904
2928
  walkElements(ctx.elements.tree, (node) => {
@@ -2906,7 +2930,7 @@ var audit20 = {
2906
2930
  violations.push({
2907
2931
  auditId: audit20.id,
2908
2932
  elementId: node.id,
2909
- label: node.elType === "section" ? (0, import_i18n42.__)("Section element", "elementor") : (0, import_i18n42.__)("Column element", "elementor")
2933
+ label: node.elType === "section" ? (0, import_i18n44.__)("Section element", "elementor") : (0, import_i18n44.__)("Column element", "elementor")
2910
2934
  });
2911
2935
  }
2912
2936
  });
@@ -2915,15 +2939,15 @@ var audit20 = {
2915
2939
  };
2916
2940
 
2917
2941
  // src/audits/site-identity.ts
2918
- var import_i18n43 = require("@wordpress/i18n");
2942
+ var import_i18n45 = require("@wordpress/i18n");
2919
2943
  var audit21 = {
2920
2944
  id: "audits/site-identity",
2921
- title: (0, import_i18n43.__)("Site identity", "elementor"),
2922
- description: (0, import_i18n43.__)(
2945
+ title: (0, import_i18n45.__)("Site identity", "elementor"),
2946
+ description: (0, import_i18n45.__)(
2923
2947
  "Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
2924
2948
  "elementor"
2925
2949
  ),
2926
- fixHint: (0, import_i18n43.__)("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2950
+ fixHint: (0, import_i18n45.__)("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2927
2951
  categories: ["best-practices", "seo"],
2928
2952
  severity: "info",
2929
2953
  weight: 7,
@@ -2933,14 +2957,14 @@ var audit21 = {
2933
2957
  if (!identity.site_name_set) {
2934
2958
  violations.push({
2935
2959
  auditId: audit21.id,
2936
- label: (0, import_i18n43.__)("Site name is missing or still uses the default.", "elementor"),
2960
+ label: (0, import_i18n45.__)("Site name is missing or still uses the default.", "elementor"),
2937
2961
  targetHint: "site-identity-settings"
2938
2962
  });
2939
2963
  }
2940
2964
  if (!identity.site_description_set) {
2941
2965
  violations.push({
2942
2966
  auditId: audit21.id,
2943
- label: (0, import_i18n43.__)("Site description is missing or still uses the default.", "elementor"),
2967
+ label: (0, import_i18n45.__)("Site description is missing or still uses the default.", "elementor"),
2944
2968
  targetHint: "site-identity-settings",
2945
2969
  angieFix: true
2946
2970
  });
@@ -2948,14 +2972,14 @@ var audit21 = {
2948
2972
  if (!identity.site_logo_set) {
2949
2973
  violations.push({
2950
2974
  auditId: audit21.id,
2951
- label: (0, import_i18n43.__)("Site logo is not set.", "elementor"),
2975
+ label: (0, import_i18n45.__)("Site logo is not set.", "elementor"),
2952
2976
  targetHint: "site-identity-settings"
2953
2977
  });
2954
2978
  }
2955
2979
  if (!identity.site_favicon_set) {
2956
2980
  violations.push({
2957
2981
  auditId: audit21.id,
2958
- label: (0, import_i18n43.__)("Site favicon is not set.", "elementor"),
2982
+ label: (0, import_i18n45.__)("Site favicon is not set.", "elementor"),
2959
2983
  targetHint: "site-identity-settings"
2960
2984
  });
2961
2985
  }
@@ -2970,23 +2994,31 @@ var audit21 = {
2970
2994
  };
2971
2995
 
2972
2996
  // src/audits/too-many-widgets.ts
2973
- var import_i18n44 = require("@wordpress/i18n");
2997
+ var import_editor_elements8 = require("@elementor/editor-elements");
2998
+ var import_i18n46 = require("@wordpress/i18n");
2974
2999
  var WIDGET_COUNT_THRESHOLD = 100;
3000
+ function isCountableWidget(node, widgetsCache) {
3001
+ if (node.elType === "widget") {
3002
+ return true;
3003
+ }
3004
+ return !!widgetsCache?.[node.elType]?.meta?.is_compound;
3005
+ }
2975
3006
  var audit22 = {
2976
3007
  id: "audits/too-many-widgets",
2977
- title: (0, import_i18n44.__)("Too many widgets", "elementor"),
2978
- description: (0, import_i18n44.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2979
- fixHint: (0, import_i18n44.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
3008
+ title: (0, import_i18n46.__)("Too many widgets", "elementor"),
3009
+ description: (0, import_i18n46.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
3010
+ fixHint: (0, import_i18n46.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2980
3011
  categories: ["best-practices", "performance"],
2981
3012
  severity: "warning",
2982
3013
  weight: 5,
2983
3014
  evaluate: (ctx) => {
2984
3015
  if (ctx.elements.tree.length === 0) {
2985
- return { status: "skipped", reason: (0, import_i18n44.__)("No elements", "elementor") };
3016
+ return { status: "skipped", reason: (0, import_i18n46.__)("No elements", "elementor") };
2986
3017
  }
3018
+ const widgetsCache = (0, import_editor_elements8.getWidgetsCache)();
2987
3019
  let widgetCount = 0;
2988
3020
  walkElements(ctx.elements.tree, (node) => {
2989
- if (node.elType === "widget") {
3021
+ if (isCountableWidget(node, widgetsCache)) {
2990
3022
  widgetCount++;
2991
3023
  }
2992
3024
  });
@@ -2998,7 +3030,7 @@ var audit22 = {
2998
3030
  violations: [
2999
3031
  {
3000
3032
  auditId: audit22.id,
3001
- label: (0, import_i18n44.__)("Page has too many widgets.", "elementor")
3033
+ label: (0, import_i18n46.__)("Page has too many widgets.", "elementor")
3002
3034
  }
3003
3035
  ]
3004
3036
  };