@accesslint/core 0.3.9 → 0.3.10

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
@@ -1,8 +1,8 @@
1
- let O = /* @__PURE__ */ new WeakMap();
2
- function ve() {
3
- O = /* @__PURE__ */ new WeakMap();
1
+ let B = /* @__PURE__ */ new WeakMap();
2
+ function we() {
3
+ B = /* @__PURE__ */ new WeakMap();
4
4
  }
5
- function ue(t) {
5
+ function de(t) {
6
6
  var i;
7
7
  const a = t.tagName.toLowerCase(), e = (i = t.getAttribute("type")) == null ? void 0 : i.toLowerCase();
8
8
  switch (a) {
@@ -117,30 +117,30 @@ function ue(t) {
117
117
  return null;
118
118
  }
119
119
  }
120
- function L(t) {
120
+ function q(t) {
121
121
  var n;
122
- const a = O.get(t);
122
+ const a = B.get(t);
123
123
  if (a !== void 0) return a;
124
- const i = ((n = t.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase()) || null || ue(t);
125
- return O.set(t, i), i;
124
+ const i = ((n = t.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase()) || null || de(t);
125
+ return B.set(t, i), i;
126
126
  }
127
127
  let F = /* @__PURE__ */ new WeakMap();
128
- function ye() {
128
+ function Ae() {
129
129
  F = /* @__PURE__ */ new WeakMap();
130
130
  }
131
131
  function v(t) {
132
132
  const a = F.get(t);
133
133
  if (a !== void 0) return a;
134
- const e = we(t);
134
+ const e = xe(t);
135
135
  return F.set(t, e), e;
136
136
  }
137
- function we(t) {
137
+ function xe(t) {
138
138
  var r, o, s, l, h;
139
139
  const a = t.getAttribute("aria-labelledby");
140
140
  if (a) {
141
- const c = a.split(/\s+/).map((d) => {
142
- const g = t.ownerDocument.getElementById(d);
143
- return g ? w(g).trim() : "";
141
+ const c = a.split(/\s+/).map((u) => {
142
+ const p = t.ownerDocument.getElementById(u);
143
+ return p ? A(p).trim() : "";
144
144
  }).filter(Boolean);
145
145
  if (c.length) return c.join(" ");
146
146
  }
@@ -148,11 +148,11 @@ function we(t) {
148
148
  if (e) return e;
149
149
  if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) {
150
150
  if (t.id) {
151
- const g = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`), b = g ? w(g).trim() : "";
151
+ const p = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`), b = p ? A(p).trim() : "";
152
152
  if (b) return b;
153
153
  }
154
- const c = t.closest("label"), d = c ? w(c).trim() : "";
155
- if (d) return d;
154
+ const c = t.closest("label"), u = c ? A(c).trim() : "";
155
+ if (u) return u;
156
156
  }
157
157
  const i = (o = t.getAttribute("title")) == null ? void 0 : o.trim();
158
158
  if (i) return i;
@@ -164,24 +164,24 @@ function we(t) {
164
164
  if (n === "fieldset") {
165
165
  const c = t.querySelector(":scope > legend");
166
166
  if (c) {
167
- const d = w(c).trim();
168
- if (d) return d;
167
+ const u = A(c).trim();
168
+ if (u) return u;
169
169
  }
170
170
  }
171
171
  if (n === "table") {
172
172
  const c = t.querySelector(":scope > caption");
173
173
  if (c) {
174
- const d = w(c).trim();
175
- if (d) return d;
174
+ const u = A(c).trim();
175
+ if (u) return u;
176
176
  }
177
177
  }
178
178
  if (!(t instanceof HTMLInputElement)) {
179
- const c = w(t).trim();
179
+ const c = A(t).trim();
180
180
  if (c) return c;
181
181
  }
182
182
  return t instanceof HTMLImageElement || t instanceof HTMLAreaElement ? ((l = t.alt) == null ? void 0 : l.trim()) ?? "" : t instanceof HTMLInputElement && t.type === "image" ? ((h = t.alt) == null ? void 0 : h.trim()) ?? "" : "";
183
183
  }
184
- const Ae = /* @__PURE__ */ new Set([
184
+ const Se = /* @__PURE__ */ new Set([
185
185
  "alert",
186
186
  "alertdialog",
187
187
  "application",
@@ -265,24 +265,36 @@ const Ae = /* @__PURE__ */ new Set([
265
265
  "treegrid",
266
266
  "treeitem"
267
267
  ]);
268
- function xe(t) {
268
+ function ke(t) {
269
269
  const a = t.trim().toLowerCase().replace(/[\u201C\u201D\u2018\u2019\u00AB\u00BB]/g, "");
270
- return Ae.has(a);
270
+ return Se.has(a);
271
271
  }
272
- let B = /* @__PURE__ */ new WeakMap();
273
- function Se() {
274
- B = /* @__PURE__ */ new WeakMap();
272
+ function T(t) {
273
+ let a = t;
274
+ for (; a; ) {
275
+ if (a.getAttribute("aria-hidden") === "true" || a instanceof HTMLElement && a.hidden) return !0;
276
+ if (typeof getComputedStyle == "function") {
277
+ const e = getComputedStyle(a);
278
+ if (e.display === "none" || e.visibility === "hidden") return !0;
279
+ } else if (a instanceof HTMLElement && a.style.display === "none") return !0;
280
+ a = a.parentElement;
281
+ }
282
+ return !1;
275
283
  }
276
- function p(t) {
277
- const a = B.get(t);
284
+ let W = /* @__PURE__ */ new WeakMap();
285
+ function Ie() {
286
+ W = /* @__PURE__ */ new WeakMap();
287
+ }
288
+ function g(t) {
289
+ const a = W.get(t);
278
290
  if (a !== void 0) return a;
279
291
  let e;
280
- return t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none") ? e = !0 : t.parentElement ? e = p(t.parentElement) : e = !1, B.set(t, e), e;
292
+ return t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none") ? e = !0 : t.parentElement ? e = g(t.parentElement) : e = !1, W.set(t, e), e;
281
293
  }
282
- function ke(t) {
294
+ function Te(t) {
283
295
  return !!(t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none"));
284
296
  }
285
- function w(t) {
297
+ function A(t) {
286
298
  var e, i, n, r, o;
287
299
  let a = "";
288
300
  for (const s of t.childNodes)
@@ -290,17 +302,17 @@ function w(t) {
290
302
  a += s.textContent ?? "";
291
303
  else if (s.nodeType === 1) {
292
304
  const l = s;
293
- if (!ke(l)) {
305
+ if (!Te(l)) {
294
306
  const h = (e = l.tagName) == null ? void 0 : e.toLowerCase();
295
307
  if (h === "img" || h === "area") {
296
308
  const c = l.getAttribute("aria-labelledby");
297
309
  if (c) {
298
- const d = c.split(/\s+/).map((g) => {
310
+ const u = c.split(/\s+/).map((p) => {
299
311
  var b, f;
300
- return ((f = (b = l.ownerDocument.getElementById(g)) == null ? void 0 : b.textContent) == null ? void 0 : f.trim()) ?? "";
312
+ return ((f = (b = l.ownerDocument.getElementById(p)) == null ? void 0 : b.textContent) == null ? void 0 : f.trim()) ?? "";
301
313
  }).filter(Boolean);
302
- if (d.length) {
303
- a += d.join(" ");
314
+ if (u.length) {
315
+ a += u.join(" ");
304
316
  continue;
305
317
  }
306
318
  }
@@ -310,22 +322,22 @@ function w(t) {
310
322
  if (c)
311
323
  a += c;
312
324
  else {
313
- const d = l.querySelector("title");
314
- d && (a += d.textContent ?? "");
325
+ const u = l.querySelector("title");
326
+ u && (a += u.textContent ?? "");
315
327
  }
316
- } else (o = l.getAttribute("aria-label")) != null && o.trim() ? a += l.getAttribute("aria-label").trim() : a += w(l);
328
+ } else (o = l.getAttribute("aria-label")) != null && o.trim() ? a += l.getAttribute("aria-label").trim() : a += A(l);
317
329
  }
318
330
  }
319
331
  return a;
320
332
  }
321
- let W = /* @__PURE__ */ new WeakMap();
322
- function Ie() {
323
- W = /* @__PURE__ */ new WeakMap();
333
+ let _ = /* @__PURE__ */ new WeakMap();
334
+ function Ee() {
335
+ _ = /* @__PURE__ */ new WeakMap();
324
336
  }
325
- function Te(t) {
337
+ function Ce(t) {
326
338
  return t.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
327
339
  }
328
- const Ee = [
340
+ const Le = [
329
341
  "data-testid",
330
342
  "data-test-id",
331
343
  "data-cy",
@@ -335,12 +347,12 @@ const Ee = [
335
347
  "for",
336
348
  "aria-label"
337
349
  ];
338
- function Ce(t) {
350
+ function qe(t) {
339
351
  const a = t.tagName.toLowerCase();
340
- for (const i of Ee) {
352
+ for (const i of Le) {
341
353
  const n = t.getAttribute(i);
342
354
  if (n != null && n.length > 0 && n.length < 100)
343
- return `${a}[${i}="${Te(n)}"]`;
355
+ return `${a}[${i}="${Ce(n)}"]`;
344
356
  }
345
357
  const e = t.parentElement;
346
358
  if (e) {
@@ -352,7 +364,7 @@ function Ce(t) {
352
364
  }
353
365
  return a;
354
366
  }
355
- function M(t) {
367
+ function H(t) {
356
368
  if (t.id) return `#${CSS.escape(t.id)}`;
357
369
  const a = t.getRootNode(), e = a instanceof ShadowRoot ? null : a.documentElement, i = [];
358
370
  let n = t;
@@ -361,7 +373,7 @@ function M(t) {
361
373
  i.unshift(`#${CSS.escape(n.id)}`);
362
374
  break;
363
375
  }
364
- if (i.unshift(Ce(n)), i.length >= 2) {
376
+ if (i.unshift(qe(n)), i.length >= 2) {
365
377
  const r = i.join(" > ");
366
378
  try {
367
379
  const o = a.querySelectorAll(r);
@@ -375,28 +387,28 @@ function M(t) {
375
387
  }
376
388
  function m(t) {
377
389
  var r;
378
- const a = W.get(t);
390
+ const a = _.get(t);
379
391
  if (a !== void 0) return a;
380
392
  const e = [];
381
393
  let i = t;
382
394
  for (; i; ) {
383
395
  const o = i.getRootNode();
384
396
  if (o instanceof ShadowRoot)
385
- e.unshift({ selector: M(i), delimiter: " >>> " }), i = o.host;
397
+ e.unshift({ selector: H(i), delimiter: " >>> " }), i = o.host;
386
398
  else {
387
399
  const s = (r = o.defaultView) == null ? void 0 : r.frameElement;
388
400
  if (s)
389
- e.unshift({ selector: M(i), delimiter: " >>>iframe> " }), i = s;
401
+ e.unshift({ selector: H(i), delimiter: " >>>iframe> " }), i = s;
390
402
  else {
391
- e.unshift({ selector: M(i), delimiter: "" });
403
+ e.unshift({ selector: H(i), delimiter: "" });
392
404
  break;
393
405
  }
394
406
  }
395
407
  }
396
408
  const n = e.map((o, s) => (s === 0 ? "" : o.delimiter) + o.selector).join("");
397
- return W.set(t, n), n;
409
+ return _.set(t, n), n;
398
410
  }
399
- function wi(t) {
411
+ function Ii(t) {
400
412
  const a = [], e = [];
401
413
  let i = t;
402
414
  for (; i; ) {
@@ -429,11 +441,11 @@ function wi(t) {
429
441
  }
430
442
  return null;
431
443
  }
432
- function u(t) {
444
+ function d(t) {
433
445
  const a = t.outerHTML;
434
446
  return a.length > 200 ? a.slice(0, 200) + "..." : a;
435
447
  }
436
- const Le = /* @__PURE__ */ new Set([
448
+ const Re = /* @__PURE__ */ new Set([
437
449
  "aria-activedescendant",
438
450
  "aria-atomic",
439
451
  "aria-autocomplete",
@@ -487,7 +499,7 @@ const Le = /* @__PURE__ */ new Set([
487
499
  "aria-valuemin",
488
500
  "aria-valuenow",
489
501
  "aria-valuetext"
490
- ]), G = /* @__PURE__ */ new Set([
502
+ ]), Y = /* @__PURE__ */ new Set([
491
503
  "aria-atomic",
492
504
  "aria-busy",
493
505
  "aria-disabled",
@@ -498,7 +510,7 @@ const Le = /* @__PURE__ */ new Set([
498
510
  "aria-multiselectable",
499
511
  "aria-readonly",
500
512
  "aria-required"
501
- ]), X = /* @__PURE__ */ new Set(["aria-checked", "aria-pressed"]), qe = /* @__PURE__ */ new Set([
513
+ ]), X = /* @__PURE__ */ new Set(["aria-checked", "aria-pressed"]), Ne = /* @__PURE__ */ new Set([
502
514
  "aria-colcount",
503
515
  "aria-colindex",
504
516
  "aria-colspan",
@@ -508,11 +520,11 @@ const Le = /* @__PURE__ */ new Set([
508
520
  "aria-rowindex",
509
521
  "aria-rowspan",
510
522
  "aria-setsize"
511
- ]), Re = /* @__PURE__ */ new Set([
523
+ ]), $e = /* @__PURE__ */ new Set([
512
524
  "aria-valuemax",
513
525
  "aria-valuemin",
514
526
  "aria-valuenow"
515
- ]), Y = {
527
+ ]), K = {
516
528
  "aria-autocomplete": /* @__PURE__ */ new Set(["inline", "list", "both", "none"]),
517
529
  "aria-expanded": /* @__PURE__ */ new Set(["true", "false", "undefined"]),
518
530
  "aria-current": /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"]),
@@ -523,7 +535,7 @@ const Le = /* @__PURE__ */ new Set([
523
535
  "aria-orientation": /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]),
524
536
  "aria-relevant": /* @__PURE__ */ new Set(["additions", "all", "removals", "text"]),
525
537
  "aria-sort": /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"])
526
- }, K = /* @__PURE__ */ new Set([
538
+ }, J = /* @__PURE__ */ new Set([
527
539
  "caption",
528
540
  "code",
529
541
  "deletion",
@@ -540,7 +552,7 @@ const Le = /* @__PURE__ */ new Set([
540
552
  "suggestion",
541
553
  "term",
542
554
  "time"
543
- ]), Ne = {
555
+ ]), Me = {
544
556
  abbr: !0,
545
557
  bdi: !0,
546
558
  bdo: !0,
@@ -568,7 +580,7 @@ const Le = /* @__PURE__ */ new Set([
568
580
  u: !0,
569
581
  var: !0,
570
582
  wbr: !0
571
- }, $e = {
583
+ }, He = {
572
584
  alert: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
573
585
  article: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
574
586
  banner: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
@@ -601,13 +613,13 @@ const Le = /* @__PURE__ */ new Set([
601
613
  time: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
602
614
  tooltip: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"])
603
615
  };
604
- let E = null, C = null;
605
- function Me() {
606
- E = null, C = null;
616
+ let C = null, L = null;
617
+ function De() {
618
+ C = null, L = null;
607
619
  }
608
- function z(t) {
620
+ function U(t) {
609
621
  var n;
610
- if (C && (E == null ? void 0 : E.deref()) === t) return C;
622
+ if (L && (C == null ? void 0 : C.deref()) === t) return L;
611
623
  const a = [], e = [], i = [];
612
624
  for (const r of t.querySelectorAll("*")) {
613
625
  let o = !1;
@@ -618,14 +630,14 @@ function z(t) {
618
630
  }
619
631
  if (!o) continue;
620
632
  let s, l;
621
- const h = () => (s === void 0 && (s = m(r), l = u(r)), { selector: s, html: l });
633
+ const h = () => (s === void 0 && (s = m(r), l = d(r)), { selector: s, html: l });
622
634
  for (const c of r.attributes)
623
- if (c.name.startsWith("aria-") && !Le.has(c.name)) {
624
- const d = h();
635
+ if (c.name.startsWith("aria-") && !Re.has(c.name)) {
636
+ const u = h();
625
637
  a.push({
626
638
  ruleId: "aria-valid-attr",
627
- selector: d.selector,
628
- html: d.html,
639
+ selector: u.selector,
640
+ html: u.html,
629
641
  impact: "critical",
630
642
  message: `Invalid ARIA attribute "${c.name}".`
631
643
  });
@@ -633,85 +645,85 @@ function z(t) {
633
645
  }
634
646
  for (const c of r.attributes) {
635
647
  if (!c.name.startsWith("aria-")) continue;
636
- const d = c.value.trim();
637
- if (!(d === "" && !G.has(c.name) && !X.has(c.name))) {
638
- if (G.has(c.name)) {
639
- if (d !== "true" && d !== "false") {
640
- const g = h();
648
+ const u = c.value.trim();
649
+ if (!(u === "" && !Y.has(c.name) && !X.has(c.name))) {
650
+ if (Y.has(c.name)) {
651
+ if (u !== "true" && u !== "false") {
652
+ const p = h();
641
653
  e.push({
642
654
  ruleId: "aria-valid-attr-value",
643
- selector: g.selector,
644
- html: g.html,
655
+ selector: p.selector,
656
+ html: p.html,
645
657
  impact: "critical",
646
- message: `${c.name} must be "true" or "false", got "${d}".`
658
+ message: `${c.name} must be "true" or "false", got "${u}".`
647
659
  });
648
660
  }
649
661
  } else if (X.has(c.name)) {
650
- if (d !== "true" && d !== "false" && d !== "mixed") {
651
- const g = h();
662
+ if (u !== "true" && u !== "false" && u !== "mixed") {
663
+ const p = h();
652
664
  e.push({
653
665
  ruleId: "aria-valid-attr-value",
654
- selector: g.selector,
655
- html: g.html,
666
+ selector: p.selector,
667
+ html: p.html,
656
668
  impact: "critical",
657
- message: `${c.name} must be "true", "false", or "mixed", got "${d}".`
669
+ message: `${c.name} must be "true", "false", or "mixed", got "${u}".`
658
670
  });
659
671
  }
660
- } else if (qe.has(c.name)) {
661
- if (d === "" || !/^-?\d+$/.test(d)) {
662
- const g = h();
672
+ } else if (Ne.has(c.name)) {
673
+ if (u === "" || !/^-?\d+$/.test(u)) {
674
+ const p = h();
663
675
  e.push({
664
676
  ruleId: "aria-valid-attr-value",
665
- selector: g.selector,
666
- html: g.html,
677
+ selector: p.selector,
678
+ html: p.html,
667
679
  impact: "critical",
668
- message: `${c.name} must be an integer, got "${d}".`
680
+ message: `${c.name} must be an integer, got "${u}".`
669
681
  });
670
682
  }
671
- } else if (Re.has(c.name)) {
672
- if (d === "" || isNaN(Number(d))) {
673
- const g = h();
683
+ } else if ($e.has(c.name)) {
684
+ if (u === "" || isNaN(Number(u))) {
685
+ const p = h();
674
686
  e.push({
675
687
  ruleId: "aria-valid-attr-value",
676
- selector: g.selector,
677
- html: g.html,
688
+ selector: p.selector,
689
+ html: p.html,
678
690
  impact: "critical",
679
- message: `${c.name} must be a number, got "${d}".`
691
+ message: `${c.name} must be a number, got "${u}".`
680
692
  });
681
693
  }
682
- } else if (Y[c.name]) {
683
- const g = d.split(/\s+/);
684
- for (const b of g)
685
- if (!Y[c.name].has(b)) {
694
+ } else if (K[c.name]) {
695
+ const p = u.split(/\s+/);
696
+ for (const b of p)
697
+ if (!K[c.name].has(b)) {
686
698
  const f = h();
687
699
  e.push({
688
700
  ruleId: "aria-valid-attr-value",
689
701
  selector: f.selector,
690
702
  html: f.html,
691
703
  impact: "critical",
692
- message: `Invalid value "${d}" for ${c.name}.`
704
+ message: `Invalid value "${u}" for ${c.name}.`
693
705
  });
694
706
  break;
695
707
  }
696
708
  }
697
709
  }
698
710
  }
699
- if (!p(r)) {
700
- const c = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase(), d = r.tagName.toLowerCase();
701
- if (!c && Ne[d]) {
702
- const g = r.hasAttribute("aria-label"), b = r.hasAttribute("aria-labelledby");
703
- if (g || b) {
711
+ if (!g(r)) {
712
+ const c = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase(), u = r.tagName.toLowerCase();
713
+ if (!c && Me[u]) {
714
+ const p = r.hasAttribute("aria-label"), b = r.hasAttribute("aria-labelledby");
715
+ if (p || b) {
704
716
  const f = h();
705
717
  i.push({
706
718
  ruleId: "aria-prohibited-attr",
707
719
  selector: f.selector,
708
720
  html: f.html,
709
721
  impact: "serious",
710
- message: `aria-label and aria-labelledby are prohibited on <${d}> elements.`
722
+ message: `aria-label and aria-labelledby are prohibited on <${u}> elements.`
711
723
  });
712
724
  }
713
725
  } else if (c) {
714
- if (K.has(c)) {
726
+ if (J.has(c)) {
715
727
  const b = r.hasAttribute("aria-label"), f = r.hasAttribute("aria-labelledby");
716
728
  if (b || f) {
717
729
  const y = h();
@@ -724,11 +736,11 @@ function z(t) {
724
736
  });
725
737
  }
726
738
  }
727
- const g = $e[c];
728
- if (g) {
739
+ const p = He[c];
740
+ if (p) {
729
741
  for (const b of r.attributes)
730
- if (b.name.startsWith("aria-") && g.has(b.name)) {
731
- if ((b.name === "aria-label" || b.name === "aria-labelledby") && K.has(c))
742
+ if (b.name.startsWith("aria-") && p.has(b.name)) {
743
+ if ((b.name === "aria-label" || b.name === "aria-labelledby") && J.has(c))
732
744
  continue;
733
745
  const f = h();
734
746
  i.push({
@@ -743,28 +755,28 @@ function z(t) {
743
755
  }
744
756
  }
745
757
  }
746
- return E = new WeakRef(t), C = { validAttr: a, validAttrValue: e, prohibitedAttr: i }, C;
758
+ return C = new WeakRef(t), L = { validAttr: a, validAttrValue: e, prohibitedAttr: i }, L;
747
759
  }
748
- let _ = /* @__PURE__ */ new WeakMap(), P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap();
749
- function He() {
750
- _ = /* @__PURE__ */ new WeakMap(), P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap();
760
+ let P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap();
761
+ function Oe() {
762
+ P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap();
751
763
  }
752
- function A(t) {
753
- let a = _.get(t);
754
- return a || (a = getComputedStyle(t), _.set(t, a), a);
764
+ function w(t) {
765
+ let a = P.get(t);
766
+ return a || (a = getComputedStyle(t), P.set(t, a), a);
755
767
  }
756
- function q(t, a, e) {
768
+ function R(t, a, e) {
757
769
  const [i, n, r] = [t, a, e].map((o) => {
758
770
  const s = o / 255;
759
771
  return s <= 0.04045 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
760
772
  });
761
773
  return 0.2126 * i + 0.7152 * n + 0.0722 * r;
762
774
  }
763
- function de(t, a) {
775
+ function me(t, a) {
764
776
  const e = Math.max(t, a), i = Math.min(t, a);
765
777
  return (e + 0.05) / (i + 0.05);
766
778
  }
767
- const J = {
779
+ const Q = {
768
780
  black: [0, 0, 0],
769
781
  white: [255, 255, 255],
770
782
  red: [255, 0, 0],
@@ -784,9 +796,9 @@ const J = {
784
796
  lime: [0, 255, 0],
785
797
  olive: [128, 128, 0]
786
798
  };
787
- function R(t) {
799
+ function N(t) {
788
800
  const a = t.trim().toLowerCase();
789
- if (J[a]) return J[a];
801
+ if (Q[a]) return Q[a];
790
802
  const e = a.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);
791
803
  if (e)
792
804
  return [parseInt(e[1] + e[1], 16), parseInt(e[2] + e[2], 16), parseInt(e[3] + e[3], 16)];
@@ -803,16 +815,16 @@ function R(t) {
803
815
  );
804
816
  return r ? [parseInt(r[1]), parseInt(r[2]), parseInt(r[3])] : null;
805
817
  }
806
- function De(t) {
807
- const a = P.get(t);
818
+ function Be(t) {
819
+ const a = j.get(t);
808
820
  if (a !== void 0) return a;
809
- const e = Oe(t);
810
- return P.set(t, e), e;
821
+ const e = Fe(t);
822
+ return j.set(t, e), e;
811
823
  }
812
- function Oe(t) {
824
+ function Fe(t) {
813
825
  let a = t;
814
826
  for (; a; ) {
815
- const e = A(a), i = e.backgroundImage;
827
+ const e = w(a), i = e.backgroundImage;
816
828
  if (i && i !== "none" && i !== "initial") return null;
817
829
  const n = e.backgroundColor;
818
830
  if (n === "transparent" || n === "rgba(0, 0, 0, 0)" || n === "rgba(0 0 0 / 0)") {
@@ -824,26 +836,26 @@ function Oe(t) {
824
836
  a = a.parentElement;
825
837
  continue;
826
838
  }
827
- return R(n);
839
+ return N(n);
828
840
  }
829
841
  return [255, 255, 255];
830
842
  }
831
- const Fe = /* @__PURE__ */ new Set(["IMG", "PICTURE", "VIDEO", "SVG"]);
832
- function Be(t) {
833
- const a = j.get(t);
843
+ const We = /* @__PURE__ */ new Set(["IMG", "PICTURE", "VIDEO", "SVG"]);
844
+ function _e(t) {
845
+ const a = V.get(t);
834
846
  if (a !== void 0) return a;
835
- const e = We(t);
836
- return j.set(t, e), e;
847
+ const e = Pe(t);
848
+ return V.set(t, e), e;
837
849
  }
838
- function We(t) {
850
+ function Pe(t) {
839
851
  let a = t, e = !1;
840
852
  for (; a; ) {
841
- const i = A(a).position;
853
+ const i = w(a).position;
842
854
  if ((i === "absolute" || i === "fixed") && (e = !0), a !== t && i !== "static") {
843
855
  for (const n of a.children)
844
- if (!(n === t || n.contains(t)) && Fe.has(n.tagName)) {
856
+ if (!(n === t || n.contains(t)) && We.has(n.tagName)) {
845
857
  if (e) return !0;
846
- const r = A(n).position;
858
+ const r = w(n).position;
847
859
  if (r === "absolute" || r === "fixed") return !0;
848
860
  }
849
861
  if (e) break;
@@ -852,15 +864,15 @@ function We(t) {
852
864
  }
853
865
  return !1;
854
866
  }
855
- function _e(t) {
867
+ function je(t) {
856
868
  const a = parseFloat(t);
857
869
  return t.endsWith("pt") ? a * (4 / 3) : a;
858
870
  }
859
- function Pe(t) {
860
- const a = A(t), e = _e(a.fontSize), i = parseInt(a.fontWeight) || (a.fontWeight === "bold" ? 700 : 400);
871
+ function Ve(t) {
872
+ const a = w(t), e = je(a.fontSize), i = parseInt(a.fontWeight) || (a.fontWeight === "bold" ? 700 : 400);
861
873
  return e >= 23.5 || e >= 18.5 && i >= 700;
862
874
  }
863
- function H(t) {
875
+ function D(t) {
864
876
  var r, o;
865
877
  const a = [], e = t.closest("a");
866
878
  if (e) {
@@ -880,7 +892,7 @@ function H(t) {
880
892
  return a.length > 0 ? a.join(`
881
893
  `) : void 0;
882
894
  }
883
- function Q(t) {
895
+ function Z(t) {
884
896
  let a = t;
885
897
  for (; a; ) {
886
898
  if (a instanceof HTMLElement && a.style.visibility === "hidden") return !0;
@@ -888,7 +900,7 @@ function Q(t) {
888
900
  }
889
901
  return !1;
890
902
  }
891
- const je = {
903
+ const ze = {
892
904
  id: "img-alt",
893
905
  wcag: ["1.1.1"],
894
906
  level: "A",
@@ -898,7 +910,7 @@ const je = {
898
910
  run(t) {
899
911
  const a = [];
900
912
  for (const e of t.querySelectorAll("img")) {
901
- if (p(e) || Q(e)) continue;
913
+ if (g(e) || Z(e)) continue;
902
914
  const i = e.getAttribute("role");
903
915
  if (i === "presentation" || i === "none") {
904
916
  const r = e.getAttribute("tabindex");
@@ -909,41 +921,41 @@ const je = {
909
921
  a.push({
910
922
  ruleId: "img-alt",
911
923
  selector: m(e),
912
- html: u(e),
924
+ html: d(e),
913
925
  impact: "critical",
914
926
  message: 'Image has whitespace-only alt text. Use alt="" for decorative images or provide descriptive text.',
915
- context: H(e)
927
+ context: D(e)
916
928
  });
917
929
  continue;
918
930
  }
919
931
  !e.hasAttribute("alt") && !v(e) && a.push({
920
932
  ruleId: "img-alt",
921
933
  selector: m(e),
922
- html: u(e),
934
+ html: d(e),
923
935
  impact: "critical",
924
936
  message: "Image element missing alt attribute.",
925
- context: H(e)
937
+ context: D(e)
926
938
  });
927
939
  }
928
940
  for (const e of t.querySelectorAll('[role="img"]:not(img):not(svg)'))
929
- p(e) || Q(e) || v(e) || a.push({
941
+ g(e) || Z(e) || v(e) || a.push({
930
942
  ruleId: "img-alt",
931
943
  selector: m(e),
932
- html: u(e),
944
+ html: d(e),
933
945
  impact: "critical",
934
946
  message: 'Element with role="img" has no accessible name. Add aria-label or aria-labelledby.',
935
- context: H(e)
947
+ context: D(e)
936
948
  });
937
949
  return a;
938
950
  }
939
951
  };
940
- function Ve(t) {
952
+ function Ue(t) {
941
953
  var r, o, s;
942
954
  const a = t.getAttribute("aria-labelledby");
943
955
  if (a) {
944
956
  const l = a.split(/\s+/).map((h) => {
945
- var c, d;
946
- return ((d = (c = t.ownerDocument.getElementById(h)) == null ? void 0 : c.textContent) == null ? void 0 : d.trim()) ?? "";
957
+ var c, u;
958
+ return ((u = (c = t.ownerDocument.getElementById(h)) == null ? void 0 : c.textContent) == null ? void 0 : u.trim()) ?? "";
947
959
  }).filter(Boolean);
948
960
  if (l.length) return l.join(" ");
949
961
  }
@@ -954,7 +966,7 @@ function Ve(t) {
954
966
  const n = (s = t.getAttribute("title")) == null ? void 0 : s.trim();
955
967
  return n || "";
956
968
  }
957
- const ze = {
969
+ const Ge = {
958
970
  id: "svg-img-alt",
959
971
  wcag: ["1.1.1"],
960
972
  level: "A",
@@ -964,13 +976,13 @@ const ze = {
964
976
  run(t) {
965
977
  const a = [], e = 'svg[role="img"], [role="graphics-document"], [role="graphics-symbol"]';
966
978
  for (const i of t.querySelectorAll(e)) {
967
- if (p(i)) continue;
968
- if (!Ve(i)) {
979
+ if (g(i)) continue;
980
+ if (!Ue(i)) {
969
981
  const r = i.getAttribute("role");
970
982
  a.push({
971
983
  ruleId: "svg-img-alt",
972
984
  selector: m(i),
973
- html: u(i),
985
+ html: d(i),
974
986
  impact: "serious",
975
987
  message: `${i.tagName.toLowerCase()} with role='${r}' has no accessible name.`
976
988
  });
@@ -978,7 +990,7 @@ const ze = {
978
990
  }
979
991
  return a;
980
992
  }
981
- }, Ue = {
993
+ }, Ye = {
982
994
  id: "input-image-alt",
983
995
  wcag: ["1.1.1", "4.1.2"],
984
996
  level: "A",
@@ -988,16 +1000,16 @@ const ze = {
988
1000
  run(t) {
989
1001
  const a = [];
990
1002
  for (const e of t.querySelectorAll('input[type="image"]'))
991
- p(e) || v(e) || a.push({
1003
+ g(e) || v(e) || a.push({
992
1004
  ruleId: "input-image-alt",
993
1005
  selector: m(e),
994
- html: u(e),
1006
+ html: d(e),
995
1007
  impact: "critical",
996
1008
  message: "Image input missing alt text."
997
1009
  });
998
1010
  return a;
999
1011
  }
1000
- }, Ge = {
1012
+ }, Xe = {
1001
1013
  id: "image-redundant-alt",
1002
1014
  wcag: [],
1003
1015
  level: "A",
@@ -1019,7 +1031,7 @@ const ze = {
1019
1031
  a.push({
1020
1032
  ruleId: "image-redundant-alt",
1021
1033
  selector: m(i),
1022
- html: u(i),
1034
+ html: d(i),
1023
1035
  impact: "minor",
1024
1036
  message: `Alt text "${i.getAttribute("alt")}" duplicates surrounding ${s} text.`,
1025
1037
  context: `Duplicated text: "${i.getAttribute("alt")}", parent element: <${s}>${l ? ` href="${l}"` : ""}`
@@ -1029,7 +1041,7 @@ const ze = {
1029
1041
  }
1030
1042
  return a;
1031
1043
  }
1032
- }, Xe = ["image", "picture", "photo", "graphic", "icon", "img"], Ye = {
1044
+ }, Ke = ["image", "picture", "photo", "graphic", "icon", "img"], Je = {
1033
1045
  id: "image-alt-redundant-words",
1034
1046
  wcag: [],
1035
1047
  level: "A",
@@ -1042,11 +1054,11 @@ const ze = {
1042
1054
  for (const e of t.querySelectorAll("img[alt]")) {
1043
1055
  const i = e.getAttribute("alt").toLowerCase();
1044
1056
  if (!i) continue;
1045
- const n = Xe.filter((r) => i.split(/\s+/).includes(r));
1057
+ const n = Ke.filter((r) => i.split(/\s+/).includes(r));
1046
1058
  n.length > 0 && a.push({
1047
1059
  ruleId: "image-alt-redundant-words",
1048
1060
  selector: m(e),
1049
- html: u(e),
1061
+ html: d(e),
1050
1062
  impact: "minor",
1051
1063
  message: `Alt text "${e.getAttribute("alt")}" contains redundant word(s): ${n.join(", ")}.`,
1052
1064
  context: `Current alt: "${e.getAttribute("alt")}", redundant word(s): ${n.join(", ")}`
@@ -1054,7 +1066,7 @@ const ze = {
1054
1066
  }
1055
1067
  return a;
1056
1068
  }
1057
- }, Ke = {
1069
+ }, Qe = {
1058
1070
  id: "area-alt",
1059
1071
  wcag: ["1.1.1", "4.1.2"],
1060
1072
  level: "A",
@@ -1064,11 +1076,11 @@ const ze = {
1064
1076
  run(t) {
1065
1077
  const a = [];
1066
1078
  for (const e of t.querySelectorAll("area[href]")) {
1067
- if (p(e)) continue;
1079
+ if (g(e)) continue;
1068
1080
  v(e) || a.push({
1069
1081
  ruleId: "area-alt",
1070
1082
  selector: m(e),
1071
- html: u(e),
1083
+ html: d(e),
1072
1084
  impact: "critical",
1073
1085
  message: "Image map <area> element is missing alternative text."
1074
1086
  });
@@ -1076,7 +1088,7 @@ const ze = {
1076
1088
  return a;
1077
1089
  }
1078
1090
  };
1079
- function Je(t) {
1091
+ function Ze(t) {
1080
1092
  var n, r;
1081
1093
  const a = t.getAttribute("aria-labelledby");
1082
1094
  if (a) {
@@ -1091,7 +1103,7 @@ function Je(t) {
1091
1103
  const i = (r = t.getAttribute("title")) == null ? void 0 : r.trim();
1092
1104
  return i || "";
1093
1105
  }
1094
- const Qe = {
1106
+ const et = {
1095
1107
  id: "object-alt",
1096
1108
  wcag: ["1.1.1"],
1097
1109
  level: "A",
@@ -1102,7 +1114,7 @@ const Qe = {
1102
1114
  var e;
1103
1115
  const a = [];
1104
1116
  for (const i of t.querySelectorAll("object")) {
1105
- if (p(i) || i instanceof HTMLElement && i.style.visibility === "hidden") continue;
1117
+ if (g(i) || i instanceof HTMLElement && i.style.visibility === "hidden") continue;
1106
1118
  let n = i.parentElement, r = !1;
1107
1119
  for (; n; ) {
1108
1120
  if (n instanceof HTMLElement && n.style.visibility === "hidden") {
@@ -1111,7 +1123,7 @@ const Qe = {
1111
1123
  }
1112
1124
  n = n.parentElement;
1113
1125
  }
1114
- if (r || i.getAttribute("role") === "presentation" || i.getAttribute("role") === "none" || Je(i)) continue;
1126
+ if (r || i.getAttribute("role") === "presentation" || i.getAttribute("role") === "none" || Ze(i)) continue;
1115
1127
  const o = i.getAttribute("data") || "";
1116
1128
  if (!((i.getAttribute("type") || "").startsWith("image/") || /\.(png|jpg|jpeg|gif|svg|webp|bmp|ico)$/i.test(o))) {
1117
1129
  const h = i.querySelector("img[alt]");
@@ -1120,14 +1132,14 @@ const Qe = {
1120
1132
  a.push({
1121
1133
  ruleId: "object-alt",
1122
1134
  selector: m(i),
1123
- html: u(i),
1135
+ html: d(i),
1124
1136
  impact: "serious",
1125
1137
  message: "<object> element is missing alternative text. Add aria-label, aria-labelledby, or a title attribute."
1126
1138
  });
1127
1139
  }
1128
1140
  return a;
1129
1141
  }
1130
- }, Ze = {
1142
+ }, tt = {
1131
1143
  id: "role-img-alt",
1132
1144
  wcag: ["1.1.1"],
1133
1145
  level: "A",
@@ -1137,11 +1149,11 @@ const Qe = {
1137
1149
  run(t) {
1138
1150
  const a = [];
1139
1151
  for (const e of t.querySelectorAll('[role="img"]')) {
1140
- if (p(e) || e.tagName.toLowerCase() === "svg" || e.tagName.toLowerCase() === "img") continue;
1152
+ if (g(e) || e.tagName.toLowerCase() === "svg" || e.tagName.toLowerCase() === "img") continue;
1141
1153
  v(e) || a.push({
1142
1154
  ruleId: "role-img-alt",
1143
1155
  selector: m(e),
1144
- html: u(e),
1156
+ html: d(e),
1145
1157
  impact: "serious",
1146
1158
  message: "Element with role='img' has no accessible name. Add aria-label or aria-labelledby."
1147
1159
  });
@@ -1149,7 +1161,7 @@ const Qe = {
1149
1161
  return a;
1150
1162
  }
1151
1163
  };
1152
- function Ai(t) {
1164
+ function Ti(t) {
1153
1165
  if (typeof t != "object" || t === null)
1154
1166
  return "Rule spec must be an object";
1155
1167
  const a = t;
@@ -1179,10 +1191,10 @@ function Ai(t) {
1179
1191
  return "Rule must have a wcag array";
1180
1192
  if (typeof a.level != "string" || !["A", "AA"].includes(a.level))
1181
1193
  return "Rule must have level A or AA";
1182
- const n = et(e);
1194
+ const n = at(e);
1183
1195
  return n || null;
1184
1196
  }
1185
- function et(t) {
1197
+ function at(t) {
1186
1198
  switch (t.type) {
1187
1199
  case "selector-exists":
1188
1200
  return null;
@@ -1219,112 +1231,118 @@ function k(t) {
1219
1231
  guidance: t.guidance,
1220
1232
  prompt: t.prompt,
1221
1233
  run(e) {
1234
+ var n, r;
1222
1235
  const i = [];
1223
1236
  switch (t.check.type) {
1224
1237
  case "selector-exists": {
1225
- for (const n of e.querySelectorAll(t.selector))
1226
- a && p(n) || i.push({
1238
+ for (const o of e.querySelectorAll(t.selector))
1239
+ a && g(o) || i.push({
1227
1240
  ruleId: t.id,
1228
- selector: m(n),
1229
- html: u(n),
1241
+ selector: m(o),
1242
+ html: d(o),
1230
1243
  impact: t.impact,
1231
- message: S(t.message, n, t.check),
1232
- element: n
1244
+ message: S(t.message, o, t.check),
1245
+ element: o
1233
1246
  });
1234
1247
  break;
1235
1248
  }
1236
1249
  case "attribute-value": {
1237
- const { attribute: n, operator: r, value: o } = t.check;
1238
- for (const s of e.querySelectorAll(t.selector)) {
1239
- if (a && p(s)) continue;
1240
- const l = s.getAttribute(n);
1241
- l !== null && tt(l, r, o) && i.push({
1250
+ const { attribute: o, operator: s, value: l } = t.check;
1251
+ for (const h of e.querySelectorAll(t.selector)) {
1252
+ if (a && g(h)) continue;
1253
+ const c = h.getAttribute(o);
1254
+ c !== null && it(c, s, l) && i.push({
1242
1255
  ruleId: t.id,
1243
- selector: m(s),
1244
- html: u(s),
1256
+ selector: m(h),
1257
+ html: d(h),
1245
1258
  impact: t.impact,
1246
- message: S(t.message, s, t.check),
1247
- element: s
1259
+ message: S(t.message, h, t.check),
1260
+ element: h
1248
1261
  });
1249
1262
  }
1250
1263
  break;
1251
1264
  }
1252
1265
  case "attribute-missing": {
1253
- const { attribute: n } = t.check;
1254
- for (const r of e.querySelectorAll(t.selector))
1255
- a && p(r) || r.hasAttribute(n) || i.push({
1266
+ const { attribute: o } = t.check;
1267
+ for (const s of e.querySelectorAll(t.selector))
1268
+ a && g(s) || s.hasAttribute(o) || i.push({
1256
1269
  ruleId: t.id,
1257
- selector: m(r),
1258
- html: u(r),
1270
+ selector: m(s),
1271
+ html: d(s),
1259
1272
  impact: t.impact,
1260
- message: S(t.message, r, t.check),
1261
- element: r
1273
+ message: S(t.message, s, t.check),
1274
+ element: s
1262
1275
  });
1263
1276
  break;
1264
1277
  }
1265
1278
  case "attribute-regex": {
1266
- const { attribute: n, pattern: r, flags: o, shouldMatch: s } = t.check;
1267
- let l;
1279
+ const { attribute: o, pattern: s, flags: l, shouldMatch: h } = t.check;
1280
+ let c;
1268
1281
  try {
1269
- l = new RegExp(r, o);
1282
+ c = new RegExp(s, l);
1270
1283
  } catch {
1271
1284
  break;
1272
1285
  }
1273
- for (const h of e.querySelectorAll(t.selector)) {
1274
- if (a && p(h)) continue;
1275
- const c = h.getAttribute(n);
1276
- if (c === null) continue;
1277
- const d = l.test(c);
1278
- s && !d ? i.push({
1286
+ for (const u of e.querySelectorAll(t.selector)) {
1287
+ if (a && g(u)) continue;
1288
+ const p = u.getAttribute(o);
1289
+ if (p === null) continue;
1290
+ const b = c.test(p);
1291
+ h && !b ? i.push({
1279
1292
  ruleId: t.id,
1280
- selector: m(h),
1281
- html: u(h),
1293
+ selector: m(u),
1294
+ html: d(u),
1282
1295
  impact: t.impact,
1283
- message: S(t.message, h, t.check),
1284
- element: h
1285
- }) : !s && d && i.push({
1296
+ message: S(t.message, u, t.check),
1297
+ element: u
1298
+ }) : !h && b && i.push({
1286
1299
  ruleId: t.id,
1287
- selector: m(h),
1288
- html: u(h),
1300
+ selector: m(u),
1301
+ html: d(u),
1289
1302
  impact: t.impact,
1290
- message: S(t.message, h, t.check),
1291
- element: h
1303
+ message: S(t.message, u, t.check),
1304
+ element: u
1292
1305
  });
1293
1306
  }
1294
1307
  break;
1295
1308
  }
1296
1309
  case "child-required": {
1297
- const { childSelector: n } = t.check;
1298
- for (const r of e.querySelectorAll(t.selector))
1299
- a && p(r) || r.querySelector(n) || i.push({
1310
+ const { childSelector: o } = t.check;
1311
+ for (const s of e.querySelectorAll(t.selector))
1312
+ a && g(s) || s.querySelector(o) || i.push({
1300
1313
  ruleId: t.id,
1301
- selector: m(r),
1302
- html: u(r),
1314
+ selector: m(s),
1315
+ html: d(s),
1303
1316
  impact: t.impact,
1304
- message: S(t.message, r, t.check),
1305
- element: r
1317
+ message: S(t.message, s, t.check),
1318
+ element: s
1306
1319
  });
1307
1320
  break;
1308
1321
  }
1309
1322
  case "child-invalid": {
1310
- const n = new Set(
1311
- t.check.allowedChildren.map((r) => r.toLowerCase())
1312
- );
1313
- for (const r of e.querySelectorAll(t.selector))
1314
- if (!(a && p(r))) {
1315
- for (const o of r.children)
1316
- if (!n.has(o.tagName.toLowerCase())) {
1323
+ const o = new Set(
1324
+ t.check.allowedChildren.map((l) => l.toLowerCase())
1325
+ ), s = t.check.allowedChildRoles ? new Set(t.check.allowedChildRoles.map((l) => l.toLowerCase())) : null;
1326
+ for (const l of e.querySelectorAll(t.selector)) {
1327
+ if (a && g(l)) continue;
1328
+ const h = (n = l.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase();
1329
+ if (!(h === "presentation" || h === "none"))
1330
+ for (const c of l.children) {
1331
+ if (o.has(c.tagName.toLowerCase())) continue;
1332
+ const u = (r = c.getAttribute("role")) == null ? void 0 : r.trim().toLowerCase();
1333
+ if (!(u && (s != null && s.has(u))) && !(u === "presentation" || u === "none")) {
1317
1334
  i.push({
1318
1335
  ruleId: t.id,
1319
- selector: m(o),
1320
- html: u(o),
1336
+ selector: m(c),
1337
+ html: d(c),
1321
1338
  impact: t.impact,
1322
- message: S(t.message, o, t.check),
1323
- element: o
1339
+ message: S(t.message, c, t.check),
1340
+ element: c
1324
1341
  });
1325
1342
  break;
1326
1343
  }
1327
- }
1344
+ }
1345
+ }
1328
1346
  break;
1329
1347
  }
1330
1348
  }
@@ -1332,7 +1350,7 @@ function k(t) {
1332
1350
  }
1333
1351
  };
1334
1352
  }
1335
- function tt(t, a, e) {
1353
+ function it(t, a, e) {
1336
1354
  switch (a) {
1337
1355
  case ">":
1338
1356
  return parseFloat(t) > e;
@@ -1350,7 +1368,7 @@ function tt(t, a, e) {
1350
1368
  return !1;
1351
1369
  }
1352
1370
  }
1353
- const at = {
1371
+ const nt = {
1354
1372
  id: "server-side-image-map",
1355
1373
  selector: "img[ismap], input[type='image'][ismap]",
1356
1374
  check: { type: "selector-exists" },
@@ -1361,7 +1379,7 @@ const at = {
1361
1379
  level: "A",
1362
1380
  guidance: "Server-side image maps (using ismap attribute) send click coordinates to the server, which is inaccessible to keyboard users and screen readers who can't precisely click specific regions. Replace with client-side image maps (<map> with <area> elements) that provide keyboard access and accessible names, or use linked images/buttons instead.",
1363
1381
  prompt: "Explain that the ismap attribute should be removed and the functionality replaced with a client-side <map> element with <area> children, or separate linked images/buttons."
1364
- }, it = k(at), nt = [
1382
+ }, rt = k(nt), ot = [
1365
1383
  '[role="checkbox"]',
1366
1384
  '[role="combobox"]',
1367
1385
  '[role="listbox"]',
@@ -1373,13 +1391,13 @@ const at = {
1373
1391
  '[role="spinbutton"]',
1374
1392
  '[role="switch"]',
1375
1393
  '[role="textbox"]'
1376
- ].join(", "), rt = /* @__PURE__ */ new Set([
1394
+ ].join(", "), st = /* @__PURE__ */ new Set([
1377
1395
  "checkbox",
1378
1396
  "menuitemcheckbox",
1379
1397
  "menuitemradio",
1380
1398
  "radio",
1381
1399
  "switch"
1382
- ]), ot = /* @__PURE__ */ new Set([
1400
+ ]), lt = /* @__PURE__ */ new Set([
1383
1401
  "combobox",
1384
1402
  "listbox",
1385
1403
  "searchbox",
@@ -1387,16 +1405,16 @@ const at = {
1387
1405
  "spinbutton",
1388
1406
  "textbox"
1389
1407
  ]);
1390
- function st(t) {
1408
+ function ct(t) {
1391
1409
  var o, s, l, h;
1392
1410
  const a = (o = t.getAttribute("role")) == null ? void 0 : o.trim().toLowerCase();
1393
- if (a && rt.has(a) || (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement) && !(a && ot.has(a)))
1411
+ if (a && st.has(a) || (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement) && !(a && lt.has(a)))
1394
1412
  return v(t);
1395
1413
  const i = t.getAttribute("aria-labelledby");
1396
1414
  if (i) {
1397
- const c = i.split(/\s+/).map((d) => {
1398
- const g = t.ownerDocument.getElementById(d);
1399
- return g ? w(g).trim() : "";
1415
+ const c = i.split(/\s+/).map((u) => {
1416
+ const p = t.ownerDocument.getElementById(u);
1417
+ return p ? A(p).trim() : "";
1400
1418
  }).filter(Boolean);
1401
1419
  if (c.length) return c.join(" ");
1402
1420
  }
@@ -1404,16 +1422,16 @@ function st(t) {
1404
1422
  if (n) return n;
1405
1423
  if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) {
1406
1424
  if (t.id) {
1407
- const d = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`);
1408
- if (d) {
1409
- const g = w(d).trim();
1410
- if (g) return g;
1425
+ const u = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`);
1426
+ if (u) {
1427
+ const p = A(u).trim();
1428
+ if (p) return p;
1411
1429
  }
1412
1430
  }
1413
1431
  const c = t.closest("label");
1414
1432
  if (c) {
1415
- const d = w(c).trim();
1416
- if (d) return d;
1433
+ const u = A(c).trim();
1434
+ if (u) return u;
1417
1435
  }
1418
1436
  }
1419
1437
  const r = (l = t.getAttribute("title")) == null ? void 0 : l.trim();
@@ -1424,7 +1442,7 @@ function st(t) {
1424
1442
  }
1425
1443
  return "";
1426
1444
  }
1427
- const lt = {
1445
+ const ut = {
1428
1446
  id: "label",
1429
1447
  wcag: ["4.1.2"],
1430
1448
  level: "A",
@@ -1433,23 +1451,23 @@ const lt = {
1433
1451
  prompt: `This form field has no accessible label. Based on the context (input type, name attribute, placeholder, or surrounding elements), suggest adding a <label for="id"> element with descriptive text, or an aria-label attribute. The label should describe what information the user should enter, not the field type. For example: 'Email address', 'Search', 'Phone number'.`,
1434
1452
  run(t) {
1435
1453
  var n;
1436
- const a = [], i = t.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select, ${nt}`);
1454
+ const a = [], i = t.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select, ${ot}`);
1437
1455
  for (const r of i) {
1438
- if (p(r) || r instanceof HTMLElement && (r.hidden || r.style.display === "none")) continue;
1456
+ if (g(r) || T(r) || (r instanceof HTMLInputElement || r instanceof HTMLTextAreaElement || r instanceof HTMLSelectElement || r instanceof HTMLButtonElement) && r.disabled || r.closest("fieldset[disabled]") || r.getAttribute("aria-disabled") === "true") continue;
1439
1457
  const o = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase();
1440
1458
  if (o === "presentation" || o === "none") continue;
1441
- if (!st(r)) {
1459
+ if (!ct(r)) {
1442
1460
  const l = [], h = r.tagName.toLowerCase(), c = r.getAttribute("type");
1443
1461
  c && h === "input" && l.push(`type: ${c}`);
1444
- const d = r.getAttribute("name");
1445
- d && l.push(`name: "${d}"`);
1446
- const g = r.getAttribute("placeholder");
1447
- g && l.push(`placeholder: "${g}"`), o && l.push(`role: ${o}`);
1462
+ const u = r.getAttribute("name");
1463
+ u && l.push(`name: "${u}"`);
1464
+ const p = r.getAttribute("placeholder");
1465
+ p && l.push(`placeholder: "${p}"`), o && l.push(`role: ${o}`);
1448
1466
  const b = r.getAttribute("id");
1449
1467
  b && l.push(`id: "${b}"`), a.push({
1450
1468
  ruleId: "label",
1451
1469
  selector: m(r),
1452
- html: u(r),
1470
+ html: d(r),
1453
1471
  impact: "critical",
1454
1472
  message: "Form element has no accessible label.",
1455
1473
  context: l.length > 0 ? l.join(", ") : void 0
@@ -1458,7 +1476,7 @@ const lt = {
1458
1476
  }
1459
1477
  return a;
1460
1478
  }
1461
- }, ct = {
1479
+ }, dt = {
1462
1480
  id: "form-field-multiple-labels",
1463
1481
  wcag: [],
1464
1482
  level: "A",
@@ -1469,7 +1487,7 @@ const lt = {
1469
1487
  run(t) {
1470
1488
  const a = [], e = t.querySelectorAll('input:not([type="hidden"]), textarea, select');
1471
1489
  for (const i of e) {
1472
- if (p(i) || !i.id) continue;
1490
+ if (g(i) || !i.id) continue;
1473
1491
  const n = t.querySelectorAll(`label[for="${CSS.escape(i.id)}"]`);
1474
1492
  let r = 0, o = i.parentElement;
1475
1493
  for (; o; ) {
@@ -1483,14 +1501,14 @@ const lt = {
1483
1501
  s > 1 && a.push({
1484
1502
  ruleId: "form-field-multiple-labels",
1485
1503
  selector: m(i),
1486
- html: u(i),
1504
+ html: d(i),
1487
1505
  impact: "moderate",
1488
1506
  message: `Form field has ${s} labels. Use a single label element.`
1489
1507
  });
1490
1508
  }
1491
1509
  return a;
1492
1510
  }
1493
- }, ut = {
1511
+ }, mt = {
1494
1512
  id: "select-name",
1495
1513
  wcag: ["4.1.2"],
1496
1514
  level: "A",
@@ -1500,16 +1518,16 @@ const lt = {
1500
1518
  run(t) {
1501
1519
  const a = [];
1502
1520
  for (const e of t.querySelectorAll("select"))
1503
- p(e) || v(e) || a.push({
1521
+ g(e) || v(e) || a.push({
1504
1522
  ruleId: "select-name",
1505
1523
  selector: m(e),
1506
- html: u(e),
1524
+ html: d(e),
1507
1525
  impact: "critical",
1508
1526
  message: "Select element has no accessible name."
1509
1527
  });
1510
1528
  return a;
1511
1529
  }
1512
- }, dt = {
1530
+ }, ht = {
1513
1531
  id: "input-button-name",
1514
1532
  wcag: ["4.1.2"],
1515
1533
  level: "A",
@@ -1522,19 +1540,19 @@ const lt = {
1522
1540
  for (const n of t.querySelectorAll(
1523
1541
  'input[type="submit"], input[type="button"], input[type="reset"]'
1524
1542
  )) {
1525
- if (p(n)) continue;
1543
+ if (g(n)) continue;
1526
1544
  const r = (e = n.getAttribute("value")) == null ? void 0 : e.trim(), o = (i = n.getAttribute("type")) == null ? void 0 : i.toLowerCase(), s = (o === "submit" || o === "reset") && !n.hasAttribute("value");
1527
1545
  !r && !s && !v(n) && a.push({
1528
1546
  ruleId: "input-button-name",
1529
1547
  selector: m(n),
1530
- html: u(n),
1548
+ html: d(n),
1531
1549
  impact: "critical",
1532
1550
  message: "Input button has no discernible text."
1533
1551
  });
1534
1552
  }
1535
1553
  return a;
1536
1554
  }
1537
- }, mt = /* @__PURE__ */ new Set([
1555
+ }, pt = /* @__PURE__ */ new Set([
1538
1556
  "off",
1539
1557
  "on",
1540
1558
  "name",
@@ -1589,7 +1607,7 @@ const lt = {
1589
1607
  "impp",
1590
1608
  "url",
1591
1609
  "photo"
1592
- ]), ht = /* @__PURE__ */ new Set([
1610
+ ]), gt = /* @__PURE__ */ new Set([
1593
1611
  "tel",
1594
1612
  "tel-country-code",
1595
1613
  "tel-national",
@@ -1598,18 +1616,18 @@ const lt = {
1598
1616
  "tel-extension",
1599
1617
  "email",
1600
1618
  "impp"
1601
- ]), pt = /* @__PURE__ */ new Set(["home", "work", "mobile", "fax", "pager"]), gt = /* @__PURE__ */ new Set(["shipping", "billing"]), bt = /* @__PURE__ */ new Set(["webauthn"]);
1602
- function ft(t) {
1619
+ ]), bt = /* @__PURE__ */ new Set(["home", "work", "mobile", "fax", "pager"]), ft = /* @__PURE__ */ new Set(["shipping", "billing"]), vt = /* @__PURE__ */ new Set(["webauthn"]);
1620
+ function yt(t) {
1603
1621
  const a = t.toLowerCase().split(/\s+/).filter(Boolean);
1604
1622
  if (a.length === 0) return !0;
1605
1623
  let e = 0;
1606
- a[e].startsWith("section-") && e++, e < a.length && gt.has(a[e]) && e++;
1624
+ a[e].startsWith("section-") && e++, e < a.length && ft.has(a[e]) && e++;
1607
1625
  let i = !1;
1608
- if (e < a.length && pt.has(a[e]) && (i = !0, e++), e >= a.length) return !1;
1626
+ if (e < a.length && bt.has(a[e]) && (i = !0, e++), e >= a.length) return !1;
1609
1627
  const n = a[e];
1610
- return !mt.has(n) || i && !ht.has(n) ? !1 : (e++, e < a.length && bt.has(a[e]) && e++, e === a.length);
1628
+ return !pt.has(n) || i && !gt.has(n) ? !1 : (e++, e < a.length && vt.has(a[e]) && e++, e === a.length);
1611
1629
  }
1612
- const vt = {
1630
+ const wt = {
1613
1631
  id: "autocomplete-valid",
1614
1632
  wcag: ["1.3.5"],
1615
1633
  level: "AA",
@@ -1619,12 +1637,12 @@ const vt = {
1619
1637
  run(t) {
1620
1638
  const a = [];
1621
1639
  for (const e of t.querySelectorAll("[autocomplete]")) {
1622
- if (p(e) || e instanceof HTMLElement && e.style.display === "none" || e.disabled || e.getAttribute("aria-disabled") === "true") continue;
1640
+ if (g(e) || e instanceof HTMLElement && e.style.display === "none" || e.disabled || e.getAttribute("aria-disabled") === "true") continue;
1623
1641
  const i = e.getAttribute("autocomplete").trim();
1624
- i && (ft(i) || a.push({
1642
+ i && (yt(i) || a.push({
1625
1643
  ruleId: "autocomplete-valid",
1626
1644
  selector: m(e),
1627
- html: u(e),
1645
+ html: d(e),
1628
1646
  impact: "serious",
1629
1647
  message: `Invalid autocomplete value "${i}".`
1630
1648
  }));
@@ -1632,16 +1650,16 @@ const vt = {
1632
1650
  return a;
1633
1651
  }
1634
1652
  };
1635
- function Z(t) {
1653
+ function ee(t) {
1636
1654
  return t.toLowerCase().replace(/\s+/g, " ").trim();
1637
1655
  }
1638
- function ee(t, a) {
1639
- const e = Z(t), i = Z(a);
1656
+ function te(t, a) {
1657
+ const e = ee(t), i = ee(a);
1640
1658
  if (!e || !i || e.includes(i) || i.includes(e)) return !0;
1641
1659
  const n = i.split(/\s+/).map((r) => r.replace(/[.,;:!?\u2026]+$/g, "")).filter((r) => r.length > 2);
1642
1660
  return n.length >= 2 && n.filter((o) => e.includes(o)).length / n.length > 0.5;
1643
1661
  }
1644
- function V(t) {
1662
+ function z(t) {
1645
1663
  let a = "";
1646
1664
  for (const e of t.childNodes)
1647
1665
  if (e.nodeType === 3)
@@ -1651,57 +1669,58 @@ function V(t) {
1651
1669
  if (n === "style" || n === "script" || n === "svg" || i.getAttribute("aria-hidden") === "true" || i instanceof HTMLElement && i.style.display === "none") continue;
1652
1670
  const r = i.getAttribute("role");
1653
1671
  if (r === "img" || r === "presentation" || r === "none") continue;
1654
- a += V(i);
1672
+ a += z(i);
1655
1673
  }
1656
1674
  return a;
1657
1675
  }
1658
- const yt = {
1676
+ const At = {
1659
1677
  id: "label-content-name-mismatch",
1660
- wcag: ["2.5.3"],
1678
+ wcag: [],
1661
1679
  level: "A",
1680
+ tags: ["best-practice"],
1662
1681
  description: "Interactive elements with visible text must have accessible names that contain that text.",
1663
1682
  guidance: "For voice control users who activate controls by speaking their visible label, the accessible name must include the visible text. If aria-label is 'Submit form' but the button shows 'Send', voice users saying 'click Send' won't activate it. Ensure aria-label/aria-labelledby contains or matches the visible text.",
1664
1683
  prompt: "Show the mismatch between the visible text and accessible name, and suggest updating aria-label to include the visible text.",
1665
1684
  run(t) {
1666
1685
  const a = [];
1667
1686
  for (const e of t.querySelectorAll('button, [role="button"], a[href], input[type="submit"], input[type="button"]')) {
1668
- if (p(e)) continue;
1687
+ if (g(e)) continue;
1669
1688
  const i = v(e);
1670
1689
  if (!i) continue;
1671
1690
  let n = "";
1672
- e instanceof HTMLInputElement ? n = e.value || "" : n = V(e);
1691
+ e instanceof HTMLInputElement ? n = e.value || "" : n = z(e);
1673
1692
  const r = n.trim();
1674
1693
  if (!r || r.length <= 2) continue;
1675
1694
  const o = e.hasAttribute("aria-label"), s = e.hasAttribute("aria-labelledby");
1676
- !o && !s || ee(i, n) || a.push({
1695
+ !o && !s || te(i, n) || a.push({
1677
1696
  ruleId: "label-content-name-mismatch",
1678
1697
  selector: m(e),
1679
- html: u(e),
1698
+ html: d(e),
1680
1699
  impact: "serious",
1681
1700
  message: `Accessible name "${i}" does not contain visible text "${n.trim()}".`
1682
1701
  });
1683
1702
  }
1684
1703
  for (const e of t.querySelectorAll("input, select, textarea")) {
1685
- if (p(e) || e instanceof HTMLInputElement && ["hidden", "submit", "button", "image"].includes(e.type)) continue;
1704
+ if (g(e) || e instanceof HTMLInputElement && ["hidden", "submit", "button", "image"].includes(e.type)) continue;
1686
1705
  const i = v(e);
1687
1706
  if (!i || !e.hasAttribute("aria-label")) continue;
1688
1707
  const r = e.id;
1689
1708
  let o = "";
1690
1709
  if (r) {
1691
1710
  const s = t.querySelector(`label[for="${CSS.escape(r)}"]`);
1692
- s && (o = V(s));
1711
+ s && (o = z(s));
1693
1712
  }
1694
- o.trim() && (ee(i, o) || a.push({
1713
+ o.trim() && (te(i, o) || a.push({
1695
1714
  ruleId: "label-content-name-mismatch",
1696
1715
  selector: m(e),
1697
- html: u(e),
1716
+ html: d(e),
1698
1717
  impact: "serious",
1699
1718
  message: `Accessible name "${i}" does not contain visible label "${o.trim()}".`
1700
1719
  }));
1701
1720
  }
1702
1721
  return a;
1703
1722
  }
1704
- }, wt = {
1723
+ }, xt = {
1705
1724
  id: "label-title-only",
1706
1725
  wcag: [],
1707
1726
  level: "A",
@@ -1715,26 +1734,26 @@ const yt = {
1715
1734
  'input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select'
1716
1735
  );
1717
1736
  for (const s of e) {
1718
- if (p(s)) continue;
1737
+ if (g(s)) continue;
1719
1738
  const l = s.hasAttribute("title") && ((i = s.getAttribute("title")) == null ? void 0 : i.trim()), h = s.hasAttribute("aria-label") && ((n = s.getAttribute("aria-label")) == null ? void 0 : n.trim()), c = s.hasAttribute("aria-labelledby");
1720
- let d = !1;
1721
- const g = s.id;
1722
- if (g) {
1723
- const f = s.ownerDocument.querySelector(`label[for="${CSS.escape(g)}"]`);
1724
- (r = f == null ? void 0 : f.textContent) != null && r.trim() && (d = !0);
1739
+ let u = !1;
1740
+ const p = s.id;
1741
+ if (p) {
1742
+ const f = s.ownerDocument.querySelector(`label[for="${CSS.escape(p)}"]`);
1743
+ (r = f == null ? void 0 : f.textContent) != null && r.trim() && (u = !0);
1725
1744
  }
1726
1745
  const b = s.closest("label");
1727
- (o = b == null ? void 0 : b.textContent) != null && o.trim() && (d = !0), l && !h && !c && !d && a.push({
1746
+ (o = b == null ? void 0 : b.textContent) != null && o.trim() && (u = !0), l && !h && !c && !u && a.push({
1728
1747
  ruleId: "label-title-only",
1729
1748
  selector: m(s),
1730
- html: u(s),
1749
+ html: d(s),
1731
1750
  impact: "serious",
1732
1751
  message: "Form element uses title attribute as only label. Use <label>, aria-label, or aria-labelledby instead."
1733
1752
  });
1734
1753
  }
1735
1754
  return a;
1736
1755
  }
1737
- }, At = {
1756
+ }, St = {
1738
1757
  id: "tabindex",
1739
1758
  selector: "[tabindex]",
1740
1759
  check: { type: "attribute-value", attribute: "tabindex", operator: ">", value: 0 },
@@ -1746,7 +1765,7 @@ const yt = {
1746
1765
  tags: ["best-practice"],
1747
1766
  guidance: "Positive tabindex values force elements to the front of the tab order regardless of DOM position, creating unpredictable navigation for keyboard users. Use tabindex='0' to add elements to the natural tab order, or tabindex='-1' to make elements programmatically focusable but not in tab order. Rely on DOM order for tab sequence.",
1748
1767
  prompt: "Change the positive tabindex value to tabindex='0' and rely on DOM order for tab sequence instead."
1749
- }, xt = k(At), St = /* @__PURE__ */ new Set([
1768
+ }, kt = k(St), It = /* @__PURE__ */ new Set([
1750
1769
  "div",
1751
1770
  "span",
1752
1771
  "p",
@@ -1773,7 +1792,7 @@ const yt = {
1773
1792
  "tr",
1774
1793
  "td",
1775
1794
  "th"
1776
- ]), kt = {
1795
+ ]), Tt = {
1777
1796
  id: "focus-order-semantics",
1778
1797
  wcag: [],
1779
1798
  tags: ["best-practice"],
@@ -1785,18 +1804,18 @@ const yt = {
1785
1804
  const a = [];
1786
1805
  for (const e of t.querySelectorAll('[tabindex="0"]')) {
1787
1806
  const i = e.tagName.toLowerCase();
1788
- if (!St.has(i)) continue;
1807
+ if (!It.has(i)) continue;
1789
1808
  e.getAttribute("role") || a.push({
1790
1809
  ruleId: "focus-order-semantics",
1791
1810
  selector: m(e),
1792
- html: u(e),
1811
+ html: d(e),
1793
1812
  impact: "moderate",
1794
1813
  message: `Non-interactive <${i}> with tabindex="0" has no interactive role.`
1795
1814
  });
1796
1815
  }
1797
1816
  return a;
1798
1817
  }
1799
- }, It = /* @__PURE__ */ new Set([
1818
+ }, Et = /* @__PURE__ */ new Set([
1800
1819
  "a",
1801
1820
  "audio",
1802
1821
  "button",
@@ -1805,7 +1824,7 @@ const yt = {
1805
1824
  "select",
1806
1825
  "textarea",
1807
1826
  "video"
1808
- ]), Tt = /* @__PURE__ */ new Set([
1827
+ ]), Ct = /* @__PURE__ */ new Set([
1809
1828
  "button",
1810
1829
  "checkbox",
1811
1830
  "combobox",
@@ -1829,7 +1848,7 @@ const yt = {
1829
1848
  "tabpanel",
1830
1849
  "textbox",
1831
1850
  "treeitem"
1832
- ]), Et = {
1851
+ ]), Lt = {
1833
1852
  grid: /* @__PURE__ */ new Set(["gridcell", "row", "columnheader", "rowheader"]),
1834
1853
  listbox: /* @__PURE__ */ new Set(["option"]),
1835
1854
  menu: /* @__PURE__ */ new Set(["menuitem", "menuitemcheckbox", "menuitemradio"]),
@@ -1839,26 +1858,26 @@ const yt = {
1839
1858
  tree: /* @__PURE__ */ new Set(["treeitem"]),
1840
1859
  treegrid: /* @__PURE__ */ new Set(["gridcell", "row", "columnheader", "rowheader", "treeitem"])
1841
1860
  };
1842
- function Ct(t, a) {
1861
+ function qt(t, a) {
1843
1862
  var n, r, o;
1844
1863
  const e = (n = t.getAttribute("role")) == null ? void 0 : n.toLowerCase(), i = (r = a.getAttribute("role")) == null ? void 0 : r.toLowerCase();
1845
- return !e || !i ? !1 : ((o = Et[e]) == null ? void 0 : o.has(i)) ?? !1;
1864
+ return !e || !i ? !1 : ((o = Lt[e]) == null ? void 0 : o.has(i)) ?? !1;
1846
1865
  }
1847
- function Lt(t) {
1866
+ function Rt(t) {
1848
1867
  var n;
1849
1868
  const a = t.tagName.toLowerCase();
1850
- if (It.has(a))
1869
+ if (Et.has(a))
1851
1870
  return a === "a" && !t.hasAttribute("href") ? !1 : a === "audio" || a === "video" ? t.hasAttribute("controls") : !(a === "img" && !t.hasAttribute("usemap") || a === "input" && t.type === "hidden" || t.disabled);
1852
1871
  const e = (n = t.getAttribute("role")) == null ? void 0 : n.toLowerCase();
1853
- if (e && Tt.has(e)) return !0;
1872
+ if (e && Ct.has(e)) return !0;
1854
1873
  const i = t.getAttribute("tabindex");
1855
1874
  return i !== null && i !== "-1" || t.getAttribute("contenteditable") === "true";
1856
1875
  }
1857
- function qt(t) {
1876
+ function Nt(t) {
1858
1877
  const a = t.tagName.toLowerCase();
1859
1878
  return !!(a === "a" && t.hasAttribute("href") || a === "button" && !t.disabled);
1860
1879
  }
1861
- const Rt = {
1880
+ const $t = {
1862
1881
  id: "nested-interactive",
1863
1882
  wcag: ["4.1.2"],
1864
1883
  level: "A",
@@ -1873,24 +1892,24 @@ const Rt = {
1873
1892
  for (; o; ) {
1874
1893
  for (; r.length > 0 && !r[r.length - 1].contains(o); )
1875
1894
  r.pop();
1876
- if (!p(o) && Lt(o)) {
1895
+ if (!g(o) && Rt(o)) {
1877
1896
  if (r.length > 0) {
1878
1897
  const s = r[r.length - 1];
1879
- Ct(s, o) || a.push({
1898
+ qt(s, o) || a.push({
1880
1899
  ruleId: "nested-interactive",
1881
1900
  selector: m(o),
1882
- html: u(o),
1901
+ html: d(o),
1883
1902
  impact: "serious",
1884
1903
  message: `Interactive element <${o.tagName.toLowerCase()}> is nested inside <${s.tagName.toLowerCase()}>.`
1885
1904
  });
1886
1905
  }
1887
- qt(o) && r.push(o);
1906
+ Nt(o) && r.push(o);
1888
1907
  }
1889
1908
  o = n.nextNode();
1890
1909
  }
1891
1910
  return a;
1892
1911
  }
1893
- }, Nt = {
1912
+ }, Mt = {
1894
1913
  id: "scrollable-region-focusable",
1895
1914
  wcag: ["2.1.1"],
1896
1915
  level: "A",
@@ -1898,31 +1917,36 @@ const Rt = {
1898
1917
  guidance: "Content that scrolls must be accessible to keyboard users. If a region has overflow:scroll or overflow:auto and contains scrollable content, it needs either tabindex='0' to be focusable, or it must contain focusable elements. Without this, keyboard users cannot scroll the content.",
1899
1918
  prompt: "Explain how to make this scrollable region keyboard accessible.",
1900
1919
  run(t) {
1920
+ var e;
1901
1921
  const a = [];
1902
- for (const e of t.querySelectorAll("*")) {
1903
- if (p(e) || !(e instanceof HTMLElement)) continue;
1904
- const i = A(e), n = i.overflowX, r = i.overflowY;
1905
- if (!(n === "scroll" || n === "auto" || r === "scroll" || r === "auto")) continue;
1906
- if (e.scrollHeight > 0 || e.clientHeight > 0) {
1907
- if (e.scrollHeight <= e.clientHeight && e.scrollWidth <= e.clientWidth) continue;
1922
+ for (const i of t.querySelectorAll("*")) {
1923
+ if (g(i) || !(i instanceof HTMLElement)) continue;
1924
+ const n = i.tagName.toLowerCase();
1925
+ if (n === "body" || n === "html") continue;
1926
+ const r = i.getAttribute("role");
1927
+ if (r === "presentation" || r === "none") continue;
1928
+ const o = w(i), s = o.overflowX, l = o.overflowY;
1929
+ if (!(s === "scroll" || s === "auto" || l === "scroll" || l === "auto")) continue;
1930
+ if (i.scrollHeight > 0 || i.clientHeight > 0) {
1931
+ if (i.scrollHeight <= i.clientHeight && i.scrollWidth <= i.clientWidth || i.clientWidth < 64 && i.clientHeight < 64) continue;
1908
1932
  } else {
1909
- const c = i.height !== "" || i.maxHeight !== "", d = e.textContent != null && e.textContent.trim().length > 0;
1910
- if (!c || !d) continue;
1933
+ const b = o.height !== "" || o.maxHeight !== "", f = ((e = i.textContent) == null ? void 0 : e.trim().length) ?? 0;
1934
+ if (!b || f <= 50) continue;
1911
1935
  }
1912
- const l = e.getAttribute("tabindex");
1913
- l !== null && l !== "-1" || e.querySelector(
1936
+ const u = i.getAttribute("tabindex");
1937
+ u !== null && u !== "-1" || i.querySelector(
1914
1938
  'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
1915
1939
  ) || a.push({
1916
1940
  ruleId: "scrollable-region-focusable",
1917
- selector: m(e),
1918
- html: u(e),
1941
+ selector: m(i),
1942
+ html: d(i),
1919
1943
  impact: "serious",
1920
1944
  message: "Scrollable region is not keyboard accessible. Add tabindex='0' or include focusable elements."
1921
1945
  });
1922
1946
  }
1923
1947
  return a;
1924
1948
  }
1925
- }, $t = {
1949
+ }, Ht = {
1926
1950
  id: "accesskeys",
1927
1951
  wcag: [],
1928
1952
  level: "A",
@@ -1934,7 +1958,7 @@ const Rt = {
1934
1958
  var i;
1935
1959
  const a = [], e = /* @__PURE__ */ new Map();
1936
1960
  for (const n of t.querySelectorAll("[accesskey]")) {
1937
- if (p(n)) continue;
1961
+ if (g(n)) continue;
1938
1962
  const r = (i = n.getAttribute("accesskey")) == null ? void 0 : i.trim().toLowerCase();
1939
1963
  if (!r) continue;
1940
1964
  const o = e.get(r) || [];
@@ -1946,13 +1970,13 @@ const Rt = {
1946
1970
  a.push({
1947
1971
  ruleId: "accesskeys",
1948
1972
  selector: m(o),
1949
- html: u(o),
1973
+ html: d(o),
1950
1974
  impact: "serious",
1951
1975
  message: `Duplicate accesskey "${n}". Each accesskey must be unique.`
1952
1976
  });
1953
1977
  return a;
1954
1978
  }
1955
- }, Mt = {
1979
+ }, Dt = {
1956
1980
  id: "heading-order",
1957
1981
  wcag: [],
1958
1982
  level: "A",
@@ -1964,20 +1988,20 @@ const Rt = {
1964
1988
  const a = [], e = t.querySelectorAll("h1, h2, h3, h4, h5, h6, [role='heading']");
1965
1989
  let i = 0, n = null;
1966
1990
  for (const r of e) {
1967
- if (p(r)) continue;
1991
+ if (g(r)) continue;
1968
1992
  let o;
1969
1993
  r.hasAttribute("aria-level") ? o = parseInt(r.getAttribute("aria-level"), 10) : o = parseInt(r.tagName[1], 10), i > 0 && o > i + 1 && a.push({
1970
1994
  ruleId: "heading-order",
1971
1995
  selector: m(r),
1972
- html: u(r),
1996
+ html: d(r),
1973
1997
  impact: "moderate",
1974
1998
  message: `Heading level ${o} skipped from level ${i}.`,
1975
- context: n ? `Previous heading: ${u(n)}` : void 0
1999
+ context: n ? `Previous heading: ${d(n)}` : void 0
1976
2000
  }), i = o, n = r;
1977
2001
  }
1978
2002
  return a;
1979
2003
  }
1980
- }, N = 'article, aside, main, nav, section, [role="article"], [role="complementary"], [role="main"], [role="navigation"], [role="region"]', te = 'main, [role="main"], header, [role="banner"], footer, [role="contentinfo"], nav, [role="navigation"], aside, [role="complementary"], section[aria-label], section[aria-labelledby], [role="region"][aria-label], [role="region"][aria-labelledby], form[aria-label], form[aria-labelledby], [role="form"][aria-label], [role="form"][aria-labelledby], [role="search"]', Ht = {
2004
+ }, $ = 'article, aside, main, nav, section, [role="article"], [role="complementary"], [role="main"], [role="navigation"], [role="region"]', ae = 'main, [role="main"], header, [role="banner"], footer, [role="contentinfo"], nav, [role="navigation"], aside, [role="complementary"], section[aria-label], section[aria-labelledby], [role="region"][aria-label], [role="region"][aria-labelledby], form[aria-label], form[aria-labelledby], [role="form"][aria-label], [role="form"][aria-labelledby], [role="search"]', Ot = {
1981
2005
  id: "landmark-one-main",
1982
2006
  wcag: [],
1983
2007
  level: "A",
@@ -1996,12 +2020,12 @@ const Rt = {
1996
2020
  }] : a.length > 1 ? Array.from(a).slice(1).map((e) => ({
1997
2021
  ruleId: "landmark-one-main",
1998
2022
  selector: m(e),
1999
- html: u(e),
2023
+ html: d(e),
2000
2024
  impact: "moderate",
2001
2025
  message: "Page has multiple main landmarks."
2002
2026
  })) : [];
2003
2027
  }
2004
- }, Dt = {
2028
+ }, Bt = {
2005
2029
  id: "landmark-no-duplicate-banner",
2006
2030
  wcag: [],
2007
2031
  level: "A",
@@ -2010,18 +2034,18 @@ const Rt = {
2010
2034
  guidance: "The banner landmark (typically <header>) identifies site-oriented content like logos and search. Only one top-level banner is allowed per page. If you need multiple headers, nest them inside sectioning elements (article, section, aside) where they become scoped headers rather than page-level banners.",
2011
2035
  prompt: "Explain whether to remove this duplicate banner or nest it inside a sectioning element.",
2012
2036
  run(t) {
2013
- const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest(N));
2037
+ const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest($));
2014
2038
  return i.length > 1 && i.slice(1).forEach(
2015
2039
  (n) => a.push({
2016
2040
  ruleId: "landmark-no-duplicate-banner",
2017
2041
  selector: m(n),
2018
- html: u(n),
2042
+ html: d(n),
2019
2043
  impact: "moderate",
2020
2044
  message: "Page has multiple banner landmarks."
2021
2045
  })
2022
2046
  ), a;
2023
2047
  }
2024
- }, Ot = {
2048
+ }, Ft = {
2025
2049
  id: "landmark-no-duplicate-contentinfo",
2026
2050
  wcag: [],
2027
2051
  level: "A",
@@ -2030,18 +2054,18 @@ const Rt = {
2030
2054
  guidance: "The contentinfo landmark (typically <footer>) contains information about the page like copyright and contact info. Only one top-level contentinfo is allowed per page. Nest additional footers inside sectioning elements to scope them.",
2031
2055
  prompt: "Explain whether to remove this duplicate footer or nest it inside a sectioning element.",
2032
2056
  run(t) {
2033
- const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest(N));
2057
+ const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest($));
2034
2058
  return i.length > 1 && i.slice(1).forEach(
2035
2059
  (n) => a.push({
2036
2060
  ruleId: "landmark-no-duplicate-contentinfo",
2037
2061
  selector: m(n),
2038
- html: u(n),
2062
+ html: d(n),
2039
2063
  impact: "moderate",
2040
2064
  message: "Page has multiple contentinfo landmarks."
2041
2065
  })
2042
2066
  ), a;
2043
2067
  }
2044
- }, Ft = {
2068
+ }, Wt = {
2045
2069
  id: "landmark-no-duplicate-main",
2046
2070
  wcag: [],
2047
2071
  level: "A",
@@ -2055,13 +2079,13 @@ const Rt = {
2055
2079
  (i) => a.push({
2056
2080
  ruleId: "landmark-no-duplicate-main",
2057
2081
  selector: m(i),
2058
- html: u(i),
2082
+ html: d(i),
2059
2083
  impact: "moderate",
2060
2084
  message: "Page has multiple main landmarks."
2061
2085
  })
2062
2086
  ), a;
2063
2087
  }
2064
- }, Bt = {
2088
+ }, _t = {
2065
2089
  id: "landmark-banner-is-top-level",
2066
2090
  wcag: [],
2067
2091
  level: "A",
@@ -2072,16 +2096,16 @@ const Rt = {
2072
2096
  run(t) {
2073
2097
  const a = [], e = t.querySelectorAll('[role="banner"]');
2074
2098
  for (const i of e)
2075
- i.closest(N) && a.push({
2099
+ i.closest($) && a.push({
2076
2100
  ruleId: "landmark-banner-is-top-level",
2077
2101
  selector: m(i),
2078
- html: u(i),
2102
+ html: d(i),
2079
2103
  impact: "moderate",
2080
2104
  message: "Banner landmark is nested within another landmark."
2081
2105
  });
2082
2106
  return a;
2083
2107
  }
2084
- }, Wt = {
2108
+ }, Pt = {
2085
2109
  id: "landmark-contentinfo-is-top-level",
2086
2110
  wcag: [],
2087
2111
  level: "A",
@@ -2092,16 +2116,16 @@ const Rt = {
2092
2116
  run(t) {
2093
2117
  const a = [], e = t.querySelectorAll('[role="contentinfo"]');
2094
2118
  for (const i of e)
2095
- i.closest(N) && a.push({
2119
+ i.closest($) && a.push({
2096
2120
  ruleId: "landmark-contentinfo-is-top-level",
2097
2121
  selector: m(i),
2098
- html: u(i),
2122
+ html: d(i),
2099
2123
  impact: "moderate",
2100
2124
  message: "Contentinfo landmark is nested within another landmark."
2101
2125
  });
2102
2126
  return a;
2103
2127
  }
2104
- }, _t = {
2128
+ }, jt = {
2105
2129
  id: "landmark-main-is-top-level",
2106
2130
  wcag: [],
2107
2131
  level: "A",
@@ -2116,14 +2140,14 @@ const Rt = {
2116
2140
  n != null && n.closest('article, aside, nav, section, [role="article"], [role="complementary"], [role="navigation"], [role="region"]') && a.push({
2117
2141
  ruleId: "landmark-main-is-top-level",
2118
2142
  selector: m(i),
2119
- html: u(i),
2143
+ html: d(i),
2120
2144
  impact: "moderate",
2121
2145
  message: "Main landmark is nested within another landmark."
2122
2146
  });
2123
2147
  }
2124
2148
  return a;
2125
2149
  }
2126
- }, Pt = {
2150
+ }, Vt = {
2127
2151
  id: "landmark-complementary-is-top-level",
2128
2152
  wcag: [],
2129
2153
  level: "A",
@@ -2138,14 +2162,14 @@ const Rt = {
2138
2162
  n && !n.matches('body, main, [role="main"]') && i.closest('article, nav, section, [role="article"], [role="navigation"], [role="region"]') && a.push({
2139
2163
  ruleId: "landmark-complementary-is-top-level",
2140
2164
  selector: m(i),
2141
- html: u(i),
2165
+ html: d(i),
2142
2166
  impact: "moderate",
2143
2167
  message: "Complementary landmark should be top-level."
2144
2168
  });
2145
2169
  }
2146
2170
  return a;
2147
2171
  }
2148
- }, jt = {
2172
+ }, zt = {
2149
2173
  id: "landmark-unique",
2150
2174
  wcag: [],
2151
2175
  level: "A",
@@ -2161,7 +2185,7 @@ const Rt = {
2161
2185
  { selector: 'form[aria-label], form[aria-labelledby], [role="form"], [role="search"]', type: "form" }
2162
2186
  ];
2163
2187
  for (const { selector: i, type: n } of e) {
2164
- const r = Array.from(t.querySelectorAll(i)).filter((s) => !p(s));
2188
+ const r = Array.from(t.querySelectorAll(i)).filter((s) => !g(s));
2165
2189
  if (r.length <= 1) continue;
2166
2190
  const o = /* @__PURE__ */ new Map();
2167
2191
  for (const s of r) {
@@ -2174,14 +2198,14 @@ const Rt = {
2174
2198
  a.push({
2175
2199
  ruleId: "landmark-unique",
2176
2200
  selector: m(h),
2177
- html: u(h),
2201
+ html: d(h),
2178
2202
  impact: "moderate",
2179
2203
  message: s ? `Multiple ${n} landmarks have the same label "${s}".` : `Multiple ${n} landmarks have no label. Add unique aria-label attributes.`
2180
2204
  });
2181
2205
  }
2182
2206
  return a;
2183
2207
  }
2184
- }, Vt = {
2208
+ }, Ut = {
2185
2209
  id: "region",
2186
2210
  wcag: [],
2187
2211
  level: "A",
@@ -2194,22 +2218,22 @@ const Rt = {
2194
2218
  const a = [], e = t.body;
2195
2219
  if (!e) return [];
2196
2220
  for (const n of e.children) {
2197
- if (p(n) || n instanceof HTMLScriptElement || n instanceof HTMLStyleElement || n.tagName === "NOSCRIPT" || n instanceof HTMLElement && n.hidden || n.matches('a[href^="#"]')) continue;
2198
- const r = n.matches(te), o = (i = n.textContent) == null ? void 0 : i.trim();
2199
- !r && o && (n.querySelector(te) || a.push({
2221
+ if (g(n) || n instanceof HTMLScriptElement || n instanceof HTMLStyleElement || n.tagName === "NOSCRIPT" || n instanceof HTMLElement && n.hidden || n.matches('a[href^="#"]')) continue;
2222
+ const r = n.matches(ae), o = (i = n.textContent) == null ? void 0 : i.trim();
2223
+ !r && o && (n.querySelector(ae) || a.push({
2200
2224
  ruleId: "region",
2201
2225
  selector: m(n),
2202
- html: u(n),
2226
+ html: d(n),
2203
2227
  impact: "moderate",
2204
2228
  message: "Content is not contained within a landmark region."
2205
2229
  }));
2206
2230
  }
2207
2231
  return a;
2208
2232
  }
2209
- }, zt = {
2233
+ }, Gt = {
2210
2234
  id: "list",
2211
2235
  selector: "ul, ol",
2212
- check: { type: "child-invalid", allowedChildren: ["li", "script", "template"] },
2236
+ check: { type: "child-invalid", allowedChildren: ["li", "script", "template"], allowedChildRoles: ["listitem"] },
2213
2237
  impact: "serious",
2214
2238
  message: "List contains non-<li> child <{{tag}}>.",
2215
2239
  description: "<ul> and <ol> must only contain <li>, <script>, or <template> as direct children.",
@@ -2217,7 +2241,7 @@ const Rt = {
2217
2241
  level: "A",
2218
2242
  guidance: "Screen readers announce list structure ('list with 5 items') based on proper markup. Placing non-<li> elements directly inside <ul> or <ol> breaks this structure. Wrap content in <li> elements, or if you need wrapper divs for styling, restructure your CSS to style the <li> elements directly.",
2219
2243
  prompt: "Explain how to restructure this element within the list properly."
2220
- }, Ut = k(zt), Gt = {
2244
+ }, Yt = k(Gt), Xt = {
2221
2245
  id: "dlitem",
2222
2246
  wcag: ["1.3.1"],
2223
2247
  level: "A",
@@ -2230,13 +2254,13 @@ const Rt = {
2230
2254
  (!e.parentElement || e.parentElement.tagName.toLowerCase() !== "dl") && a.push({
2231
2255
  ruleId: "dlitem",
2232
2256
  selector: m(e),
2233
- html: u(e),
2257
+ html: d(e),
2234
2258
  impact: "serious",
2235
2259
  message: `<${e.tagName.toLowerCase()}> is not contained in a <dl>.`
2236
2260
  });
2237
2261
  return a;
2238
2262
  }
2239
- }, Xt = {
2263
+ }, Kt = {
2240
2264
  id: "definition-list",
2241
2265
  selector: "dl",
2242
2266
  check: { type: "child-invalid", allowedChildren: ["dt", "dd", "div", "script", "template"] },
@@ -2247,7 +2271,7 @@ const Rt = {
2247
2271
  level: "A",
2248
2272
  guidance: "Definition lists have strict content requirements. Only <dt> (terms), <dd> (definitions), and <div> (for grouping dt/dd pairs) are valid children. Other elements break the list structure for screen readers. Move invalid elements outside the <dl>, or restructure using proper definition list markup.",
2249
2273
  prompt: "Explain whether to move this element outside the <dl> or convert it to dt/dd."
2250
- }, Yt = k(Xt), Kt = {
2274
+ }, Jt = k(Kt), Qt = {
2251
2275
  id: "document-title",
2252
2276
  wcag: ["2.4.2"],
2253
2277
  level: "A",
@@ -2277,10 +2301,11 @@ const Rt = {
2277
2301
  }
2278
2302
  return [];
2279
2303
  }
2280
- }, Jt = {
2304
+ }, Zt = {
2281
2305
  id: "bypass",
2282
- wcag: ["2.4.1"],
2306
+ wcag: [],
2283
2307
  level: "A",
2308
+ tags: ["best-practice"],
2284
2309
  description: "Page must have a mechanism to bypass repeated blocks of content.",
2285
2310
  guidance: 'Keyboard users must be able to skip repetitive content like navigation. Provide a skip link at the top of the page that links to the main content (e.g., <a href="#main">Skip to main content</a>), or use a <main> landmark. Screen readers can jump directly to landmarks, so a properly marked-up <main> element satisfies this requirement.',
2286
2311
  prompt: 'The page has no mechanism for keyboard users to skip repeated content. The simplest fix is to wrap the primary content area in a <main> element — screen readers can jump directly to it. Alternatively, add a skip link as the first element in <body>: <a href="#main" class="skip-link">Skip to main content</a>, with a matching id on the target element. Use the context to understand what the page is missing.',
@@ -2307,7 +2332,7 @@ const Rt = {
2307
2332
  context: `Missing: ${n.join(", ")}`
2308
2333
  }];
2309
2334
  }
2310
- }, Qt = {
2335
+ }, ea = {
2311
2336
  id: "page-has-heading-one",
2312
2337
  wcag: [],
2313
2338
  level: "A",
@@ -2339,13 +2364,13 @@ const Rt = {
2339
2364
  }];
2340
2365
  }
2341
2366
  };
2342
- function me(t) {
2367
+ function he(t) {
2343
2368
  if (!(t instanceof HTMLElement)) return !1;
2344
2369
  if (t.style.display === "none" || t.style.visibility === "hidden") return !0;
2345
2370
  const a = t.getAttribute("width"), e = t.getAttribute("height");
2346
2371
  return (a === "0" || a === "1") && (e === "0" || e === "1");
2347
2372
  }
2348
- const Zt = {
2373
+ const ta = {
2349
2374
  id: "frame-title",
2350
2375
  wcag: ["4.1.2"],
2351
2376
  level: "A",
@@ -2355,13 +2380,13 @@ const Zt = {
2355
2380
  run(t) {
2356
2381
  const a = [];
2357
2382
  for (const e of t.querySelectorAll("iframe, frame")) {
2358
- if (p(e) || me(e)) continue;
2383
+ if (g(e) || he(e)) continue;
2359
2384
  if (!v(e)) {
2360
2385
  const n = e.getAttribute("src");
2361
2386
  a.push({
2362
2387
  ruleId: "frame-title",
2363
2388
  selector: m(e),
2364
- html: u(e),
2389
+ html: d(e),
2365
2390
  impact: "serious",
2366
2391
  message: "Frame is missing an accessible name. Add a title attribute.",
2367
2392
  context: n ? `src: "${n}"` : void 0
@@ -2370,7 +2395,7 @@ const Zt = {
2370
2395
  }
2371
2396
  return a;
2372
2397
  }
2373
- }, ea = {
2398
+ }, aa = {
2374
2399
  id: "frame-title-unique",
2375
2400
  wcag: ["4.1.2"],
2376
2401
  level: "A",
@@ -2382,7 +2407,7 @@ const Zt = {
2382
2407
  var n;
2383
2408
  const a = [], e = Array.from(t.querySelectorAll("iframe[title], frame[title]")), i = /* @__PURE__ */ new Map();
2384
2409
  for (const r of e) {
2385
- if (p(r) || me(r)) continue;
2410
+ if (g(r) || he(r)) continue;
2386
2411
  const o = (n = r.getAttribute("title")) == null ? void 0 : n.trim().toLowerCase();
2387
2412
  if (o) {
2388
2413
  const s = i.get(o) || [];
@@ -2395,13 +2420,13 @@ const Zt = {
2395
2420
  a.push({
2396
2421
  ruleId: "frame-title-unique",
2397
2422
  selector: m(o),
2398
- html: u(o),
2423
+ html: d(o),
2399
2424
  impact: "moderate",
2400
2425
  message: "Frame title is not unique. Use a distinct title for each frame."
2401
2426
  });
2402
2427
  return a;
2403
2428
  }
2404
- }, ta = {
2429
+ }, ia = {
2405
2430
  id: "empty-heading",
2406
2431
  wcag: [],
2407
2432
  level: "A",
@@ -2413,7 +2438,7 @@ const Zt = {
2413
2438
  var i;
2414
2439
  const a = [], e = t.querySelectorAll('h1, h2, h3, h4, h5, h6, [role="heading"]');
2415
2440
  for (const n of e)
2416
- if (!p(n) && !v(n)) {
2441
+ if (!g(n) && !v(n)) {
2417
2442
  let r;
2418
2443
  const o = n.nextElementSibling;
2419
2444
  if (o) {
@@ -2423,7 +2448,7 @@ const Zt = {
2423
2448
  a.push({
2424
2449
  ruleId: "empty-heading",
2425
2450
  selector: m(n),
2426
- html: u(n),
2451
+ html: d(n),
2427
2452
  impact: "minor",
2428
2453
  message: "Heading is empty. Add text content or remove the heading element.",
2429
2454
  context: r ? `Following content: "${r}"` : void 0
@@ -2431,7 +2456,7 @@ const Zt = {
2431
2456
  }
2432
2457
  return a;
2433
2458
  }
2434
- }, aa = {
2459
+ }, na = {
2435
2460
  id: "meta-viewport",
2436
2461
  wcag: ["1.4.4"],
2437
2462
  level: "AA",
@@ -2445,7 +2470,7 @@ const Zt = {
2445
2470
  (/user-scalable\s*=\s*no/i.test(n) || /user-scalable\s*=\s*0/i.test(n)) && a.push({
2446
2471
  ruleId: "meta-viewport",
2447
2472
  selector: m(e),
2448
- html: u(e),
2473
+ html: d(e),
2449
2474
  impact: "critical",
2450
2475
  message: "Viewport disables user scaling. Remove user-scalable=no.",
2451
2476
  context: `content: "${i}"`
@@ -2456,7 +2481,7 @@ const Zt = {
2456
2481
  s < 2 && a.push({
2457
2482
  ruleId: "meta-viewport",
2458
2483
  selector: m(e),
2459
- html: u(e),
2484
+ html: d(e),
2460
2485
  impact: "critical",
2461
2486
  message: `Viewport maximum-scale=${s} restricts zooming. Set to at least 2 or remove.`,
2462
2487
  context: `content: "${i}"`
@@ -2464,7 +2489,7 @@ const Zt = {
2464
2489
  }
2465
2490
  return a;
2466
2491
  }
2467
- }, ia = {
2492
+ }, ra = {
2468
2493
  id: "meta-refresh",
2469
2494
  wcag: ["2.2.1", "2.2.4", "3.2.5"],
2470
2495
  level: "A",
@@ -2480,7 +2505,7 @@ const Zt = {
2480
2505
  return n > 0 && n <= 72e3 ? [{
2481
2506
  ruleId: "meta-refresh",
2482
2507
  selector: m(a),
2483
- html: u(a),
2508
+ html: d(a),
2484
2509
  impact: "critical",
2485
2510
  message: `Page redirects after ${n} seconds without warning. Use server-side redirect.`
2486
2511
  }] : [];
@@ -2488,14 +2513,14 @@ const Zt = {
2488
2513
  return [{
2489
2514
  ruleId: "meta-refresh",
2490
2515
  selector: m(a),
2491
- html: u(a),
2516
+ html: d(a),
2492
2517
  impact: "critical",
2493
2518
  message: `Page auto-refreshes after ${n} seconds. Provide user control over refresh.`
2494
2519
  }];
2495
2520
  }
2496
2521
  return [];
2497
2522
  }
2498
- }, na = {
2523
+ }, oa = {
2499
2524
  id: "blink",
2500
2525
  selector: "blink",
2501
2526
  check: { type: "selector-exists" },
@@ -2506,7 +2531,7 @@ const Zt = {
2506
2531
  level: "A",
2507
2532
  guidance: "Blinking content can cause seizures in users with photosensitive epilepsy and is distracting for users with attention disorders. The <blink> element is deprecated and should never be used. If you need to draw attention to content, use less intrusive methods like color, borders, or icons.",
2508
2533
  prompt: "Suggest static alternatives to the blinking effect."
2509
- }, ra = k(na), oa = {
2534
+ }, sa = k(oa), la = {
2510
2535
  id: "marquee",
2511
2536
  selector: "marquee",
2512
2537
  check: { type: "selector-exists" },
@@ -2517,7 +2542,7 @@ const Zt = {
2517
2542
  level: "A",
2518
2543
  guidance: "Scrolling or moving content is difficult for many users to read, especially those with cognitive or visual disabilities. The <marquee> element is deprecated. Replace scrolling text with static content. If content must scroll, provide pause/stop controls and ensure it stops after 5 seconds.",
2519
2544
  prompt: "Suggest static alternatives or accessible carousel patterns."
2520
- }, sa = k(oa), la = {
2545
+ }, ca = k(la), ua = {
2521
2546
  id: "p-as-heading",
2522
2547
  wcag: [],
2523
2548
  level: "A",
@@ -2529,14 +2554,14 @@ const Zt = {
2529
2554
  var e, i;
2530
2555
  const a = [];
2531
2556
  for (const n of t.querySelectorAll("p")) {
2532
- if (p(n)) continue;
2533
- const r = n.getAttribute("style") || "", o = /font-weight\s*:\s*(bold|[6-9]00)/i.test(r), s = /font-size\s*:\s*(\d+)\s*(px|em|rem)/i.test(r), l = ((e = n.className) == null ? void 0 : e.toLowerCase()) || "", h = /\bh[1-6]\b|\bheading\b/.test(l), c = ((i = n.textContent) == null ? void 0 : i.trim()) || "", d = c.length > 0 && c.length < 50, g = !c.match(/[.!?,;:]$/);
2534
- if ((o && s || o && h) && d && g) {
2557
+ if (g(n)) continue;
2558
+ const r = n.getAttribute("style") || "", o = /font-weight\s*:\s*(bold|[6-9]00)/i.test(r), s = /font-size\s*:\s*(\d+)\s*(px|em|rem)/i.test(r), l = ((e = n.className) == null ? void 0 : e.toLowerCase()) || "", h = /\bh[1-6]\b|\bheading\b/.test(l), c = ((i = n.textContent) == null ? void 0 : i.trim()) || "", u = c.length > 0 && c.length < 50, p = !c.match(/[.!?,;:]$/);
2559
+ if ((o && s || o && h) && u && p) {
2535
2560
  const y = n.nextElementSibling;
2536
2561
  y && (y.tagName === "P" || y.tagName === "DIV" || y.tagName === "UL") && a.push({
2537
2562
  ruleId: "p-as-heading",
2538
2563
  selector: m(n),
2539
- html: u(n),
2564
+ html: d(n),
2540
2565
  impact: "serious",
2541
2566
  message: "Paragraph appears to be styled as a heading. Use an h1-h6 element instead."
2542
2567
  });
@@ -2544,7 +2569,7 @@ const Zt = {
2544
2569
  }
2545
2570
  return a;
2546
2571
  }
2547
- }, ca = {
2572
+ }, da = {
2548
2573
  id: "aria-roles",
2549
2574
  wcag: ["4.1.2"],
2550
2575
  level: "A",
@@ -2555,17 +2580,17 @@ const Zt = {
2555
2580
  const a = [];
2556
2581
  for (const e of t.querySelectorAll("[role]")) {
2557
2582
  const r = e.getAttribute("role").replace(/[\u201C\u201D\u2018\u2019\u00AB\u00BB]/g, "").split(/\s+/).filter(Boolean);
2558
- !r.some((s) => xe(s)) && r.length > 0 && a.push({
2583
+ !r.some((s) => ke(s)) && r.length > 0 && a.push({
2559
2584
  ruleId: "aria-roles",
2560
2585
  selector: m(e),
2561
- html: u(e),
2586
+ html: d(e),
2562
2587
  impact: "critical",
2563
2588
  message: `Invalid ARIA role "${r[0]}".`
2564
2589
  });
2565
2590
  }
2566
2591
  return a;
2567
2592
  }
2568
- }, ua = {
2593
+ }, ma = {
2569
2594
  id: "aria-valid-attr",
2570
2595
  wcag: ["4.1.2"],
2571
2596
  level: "A",
@@ -2573,9 +2598,9 @@ const Zt = {
2573
2598
  guidance: "Misspelled ARIA attributes are ignored by assistive technologies. Check the spelling against the WAI-ARIA specification. Common mistakes: aria-labeledby (should be aria-labelledby), aria-role (should be role), aria-description (valid in ARIA 1.3+).",
2574
2599
  prompt: "Identify the misspelled attribute and provide the correct spelling.",
2575
2600
  run(t) {
2576
- return z(t).validAttr;
2601
+ return U(t).validAttr;
2577
2602
  }
2578
- }, da = {
2603
+ }, ha = {
2579
2604
  id: "aria-valid-attr-value",
2580
2605
  wcag: ["4.1.2"],
2581
2606
  level: "A",
@@ -2583,9 +2608,9 @@ const Zt = {
2583
2608
  guidance: "Each ARIA attribute accepts specific value types. Boolean attributes (aria-hidden, aria-disabled) accept only 'true' or 'false'. Tristate attributes (aria-checked, aria-pressed) also accept 'mixed'. Token attributes (aria-live, aria-autocomplete) accept predefined values. ID reference attributes (aria-labelledby, aria-describedby) must reference existing element IDs.",
2584
2609
  prompt: "Show the invalid value and list the valid values for this specific attribute.",
2585
2610
  run(t) {
2586
- return z(t).validAttrValue;
2611
+ return U(t).validAttrValue;
2587
2612
  }
2588
- }, ma = {
2613
+ }, pa = {
2589
2614
  checkbox: ["aria-checked"],
2590
2615
  combobox: ["aria-expanded"],
2591
2616
  heading: ["aria-level"],
@@ -2599,7 +2624,7 @@ const Zt = {
2599
2624
  slider: ["aria-valuenow"],
2600
2625
  spinbutton: ["aria-valuenow"],
2601
2626
  switch: ["aria-checked"]
2602
- }, ha = {
2627
+ }, ga = {
2603
2628
  id: "aria-required-attr",
2604
2629
  wcag: ["4.1.2"],
2605
2630
  level: "A",
@@ -2609,8 +2634,8 @@ const Zt = {
2609
2634
  run(t) {
2610
2635
  const a = [];
2611
2636
  for (const e of t.querySelectorAll("[role]")) {
2612
- if (p(e) || e instanceof HTMLElement && e.style.display === "none") continue;
2613
- const i = e.getAttribute("role").trim().toLowerCase(), n = ma[i];
2637
+ if (g(e) || e instanceof HTMLElement && e.style.display === "none") continue;
2638
+ const i = e.getAttribute("role").trim().toLowerCase(), n = pa[i];
2614
2639
  if (n && !(i === "checkbox" && e instanceof HTMLInputElement && e.type === "checkbox") && !(i === "radio" && e instanceof HTMLInputElement && e.type === "radio") && !(i === "option" && e instanceof HTMLOptionElement) && !(i === "heading" && /^h[1-6]$/i.test(e.tagName))) {
2615
2640
  if (i === "separator") {
2616
2641
  const r = e.getAttribute("tabindex");
@@ -2622,7 +2647,7 @@ const Zt = {
2622
2647
  a.push({
2623
2648
  ruleId: "aria-required-attr",
2624
2649
  selector: m(e),
2625
- html: u(e),
2650
+ html: d(e),
2626
2651
  impact: "critical",
2627
2652
  message: `Role "${i}" requires attribute "${r}".`
2628
2653
  });
@@ -2634,7 +2659,7 @@ const Zt = {
2634
2659
  return a;
2635
2660
  }
2636
2661
  };
2637
- function pa(t) {
2662
+ function ba(t) {
2638
2663
  var r, o, s;
2639
2664
  const a = [], e = t.className;
2640
2665
  e && typeof e == "string" && e.trim() && a.push(`Classes: ${e.trim().slice(0, 100)}`);
@@ -2651,7 +2676,7 @@ function pa(t) {
2651
2676
  return a.length > 0 ? a.join(`
2652
2677
  `) : void 0;
2653
2678
  }
2654
- const ga = {
2679
+ const fa = {
2655
2680
  id: "button-name",
2656
2681
  wcag: ["4.1.2"],
2657
2682
  level: "A",
@@ -2661,21 +2686,21 @@ const ga = {
2661
2686
  run(t) {
2662
2687
  const a = [];
2663
2688
  for (const e of t.querySelectorAll('button, [role="button"]')) {
2664
- if (p(e)) continue;
2689
+ if (g(e) || T(e)) continue;
2665
2690
  const i = e.getAttribute("role");
2666
2691
  if ((i === "none" || i === "presentation") && !(e.matches('button:not([disabled]), [tabindex]:not([tabindex="-1"])') || e.tagName.toLowerCase() === "button" && !e.disabled) || e.getRootNode() instanceof ShadowRoot) continue;
2667
2692
  v(e) || a.push({
2668
2693
  ruleId: "button-name",
2669
2694
  selector: m(e),
2670
- html: u(e),
2695
+ html: d(e),
2671
2696
  impact: "critical",
2672
2697
  message: "Button has no discernible text.",
2673
- context: pa(e)
2698
+ context: ba(e)
2674
2699
  });
2675
2700
  }
2676
2701
  return a;
2677
2702
  }
2678
- }, ba = {
2703
+ }, va = {
2679
2704
  alert: /* @__PURE__ */ new Set(["aria-atomic", "aria-busy", "aria-live", "aria-relevant"]),
2680
2705
  alertdialog: /* @__PURE__ */ new Set(["aria-describedby", "aria-modal"]),
2681
2706
  application: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-expanded", "aria-haspopup", "aria-invalid"]),
@@ -2747,7 +2772,7 @@ const ga = {
2747
2772
  tree: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-invalid", "aria-multiselectable", "aria-orientation", "aria-required"]),
2748
2773
  treegrid: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-colcount", "aria-disabled", "aria-errormessage", "aria-invalid", "aria-multiselectable", "aria-orientation", "aria-readonly", "aria-required", "aria-rowcount"]),
2749
2774
  treeitem: /* @__PURE__ */ new Set(["aria-checked", "aria-disabled", "aria-expanded", "aria-haspopup", "aria-level", "aria-posinset", "aria-selected", "aria-setsize"])
2750
- }, fa = /* @__PURE__ */ new Set([
2775
+ }, ya = /* @__PURE__ */ new Set([
2751
2776
  "aria-atomic",
2752
2777
  "aria-busy",
2753
2778
  "aria-controls",
@@ -2771,7 +2796,7 @@ const ga = {
2771
2796
  "aria-roledescription",
2772
2797
  "aria-braillelabel",
2773
2798
  "aria-brailleroledescription"
2774
- ]), va = {
2799
+ ]), wa = {
2775
2800
  id: "aria-allowed-attr",
2776
2801
  wcag: ["4.1.2"],
2777
2802
  level: "A",
@@ -2781,18 +2806,18 @@ const ga = {
2781
2806
  run(t) {
2782
2807
  const a = [];
2783
2808
  for (const e of t.querySelectorAll("[role], [aria-*]")) {
2784
- if (p(e)) continue;
2785
- const i = L(e);
2809
+ if (g(e)) continue;
2810
+ const i = q(e);
2786
2811
  if (!i) continue;
2787
- const n = ba[i];
2812
+ const n = va[i];
2788
2813
  if (n)
2789
2814
  for (const r of e.attributes) {
2790
- if (!r.name.startsWith("aria-") || fa.has(r.name) || n.has(r.name)) continue;
2815
+ if (!r.name.startsWith("aria-") || ya.has(r.name) || n.has(r.name)) continue;
2791
2816
  const o = n.size > 0 ? [...n].join(", ") : "none (only global ARIA attributes)";
2792
2817
  a.push({
2793
2818
  ruleId: "aria-allowed-attr",
2794
2819
  selector: m(e),
2795
- html: u(e),
2820
+ html: d(e),
2796
2821
  impact: "critical",
2797
2822
  message: `ARIA attribute "${r.name}" is not allowed on role "${i}".`,
2798
2823
  context: `Attribute: ${r.name}="${r.value}", role: ${i}, allowed role-specific attributes: ${o}`
@@ -2801,7 +2826,7 @@ const ga = {
2801
2826
  }
2802
2827
  return a;
2803
2828
  }
2804
- }, ya = /* @__PURE__ */ new Set([
2829
+ }, Aa = /* @__PURE__ */ new Set([
2805
2830
  "base",
2806
2831
  "col",
2807
2832
  "colgroup",
@@ -2816,7 +2841,7 @@ const ga = {
2816
2841
  "template",
2817
2842
  "title",
2818
2843
  "track"
2819
- ]), T = {
2844
+ ]), E = {
2820
2845
  a: /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem", "link"]),
2821
2846
  "a[href]": /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem"]),
2822
2847
  abbr: "any",
@@ -2923,22 +2948,22 @@ const ga = {
2923
2948
  video: /* @__PURE__ */ new Set(["application"]),
2924
2949
  wbr: /* @__PURE__ */ new Set(["none", "presentation"])
2925
2950
  };
2926
- function wa(t) {
2951
+ function xa(t) {
2927
2952
  var e;
2928
2953
  const a = t.tagName.toLowerCase();
2929
- if (ya.has(a))
2954
+ if (Aa.has(a))
2930
2955
  return "none";
2931
2956
  if (a === "a" && t.hasAttribute("href"))
2932
- return T["a[href]"];
2957
+ return E["a[href]"];
2933
2958
  if (a === "img" && t.getAttribute("alt") === "")
2934
- return T["img[alt='']"];
2959
+ return E["img[alt='']"];
2935
2960
  if (a === "input") {
2936
2961
  const n = `input[type=${((e = t.getAttribute("type")) == null ? void 0 : e.toLowerCase()) || "text"}]`;
2937
- return n in T ? T[n] : "none";
2962
+ return n in E ? E[n] : "none";
2938
2963
  }
2939
- return T[a] || "any";
2964
+ return E[a] || "any";
2940
2965
  }
2941
- const Aa = {
2966
+ const Sa = {
2942
2967
  id: "aria-allowed-role",
2943
2968
  wcag: ["4.1.2"],
2944
2969
  level: "A",
@@ -2949,29 +2974,29 @@ const Aa = {
2949
2974
  var e;
2950
2975
  const a = [];
2951
2976
  for (const i of t.querySelectorAll("[role]")) {
2952
- if (p(i)) continue;
2977
+ if (g(i)) continue;
2953
2978
  const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
2954
2979
  if (!n) continue;
2955
- const r = ue(i);
2980
+ const r = de(i);
2956
2981
  if (r && n === r) continue;
2957
- const o = wa(i);
2982
+ const o = xa(i);
2958
2983
  o === "none" ? a.push({
2959
2984
  ruleId: "aria-allowed-role",
2960
2985
  selector: m(i),
2961
- html: u(i),
2986
+ html: d(i),
2962
2987
  impact: "minor",
2963
2988
  message: `Element <${i.tagName.toLowerCase()}> should not have an explicit role.`
2964
2989
  }) : o !== "any" && !o.has(n) && a.push({
2965
2990
  ruleId: "aria-allowed-role",
2966
2991
  selector: m(i),
2967
- html: u(i),
2992
+ html: d(i),
2968
2993
  impact: "minor",
2969
2994
  message: `Role "${n}" is not allowed on element <${i.tagName.toLowerCase()}>.`
2970
2995
  });
2971
2996
  }
2972
2997
  return a;
2973
2998
  }
2974
- }, ae = {
2999
+ }, ie = {
2975
3000
  // Each array is an OR group - at least one of each inner array must be present
2976
3001
  combobox: [["listbox", "tree", "grid", "dialog", "textbox"]],
2977
3002
  // Must own/contain one of these
@@ -2988,7 +3013,7 @@ const Aa = {
2988
3013
  tablist: [["tab"]],
2989
3014
  tree: [["treeitem", "group"]],
2990
3015
  treegrid: [["row", "rowgroup"]]
2991
- }, ie = {
3016
+ }, ne = {
2992
3017
  caption: ["figure", "table", "grid", "treegrid"],
2993
3018
  // cell/gridcell/columnheader/rowheader must be in a row
2994
3019
  // but we skip checking native td/th since they're handled by HTML semantics
@@ -3002,25 +3027,25 @@ const Aa = {
3002
3027
  tab: ["tablist"],
3003
3028
  treeitem: ["tree", "group"]
3004
3029
  };
3005
- function xa(t, a) {
3030
+ function ka(t, a) {
3006
3031
  var r;
3007
3032
  const e = ((r = t.getAttribute("aria-owns")) == null ? void 0 : r.split(/\s+/)) || [], i = t.ownerDocument, n = /* @__PURE__ */ new Set();
3008
3033
  for (const o of t.querySelectorAll("*")) {
3009
- const s = L(o);
3010
- s && !p(o) && n.add(s);
3034
+ const s = q(o);
3035
+ s && !g(o) && n.add(s);
3011
3036
  }
3012
3037
  for (const o of e) {
3013
3038
  const s = i.getElementById(o);
3014
3039
  if (s) {
3015
- const l = L(s);
3016
- l && !p(s) && n.add(l);
3040
+ const l = q(s);
3041
+ l && !g(s) && n.add(l);
3017
3042
  }
3018
3043
  }
3019
3044
  for (const o of a)
3020
3045
  if (!o.some((l) => n.has(l))) return !1;
3021
3046
  return !0;
3022
3047
  }
3023
- const Sa = {
3048
+ const Ia = {
3024
3049
  id: "aria-required-children",
3025
3050
  wcag: ["4.1.2"],
3026
3051
  level: "A",
@@ -3031,16 +3056,16 @@ const Sa = {
3031
3056
  var e;
3032
3057
  const a = [];
3033
3058
  for (const i of t.querySelectorAll("[role]")) {
3034
- if (p(i)) continue;
3059
+ if (g(i)) continue;
3035
3060
  const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
3036
- if (!n || !(n in ae)) continue;
3037
- const r = ae[n];
3038
- if (!xa(i, r)) {
3061
+ if (!n || !(n in ie)) continue;
3062
+ const r = ie[n];
3063
+ if (!ka(i, r)) {
3039
3064
  const o = r.map((s) => s.join(" or ")).join(", ");
3040
3065
  a.push({
3041
3066
  ruleId: "aria-required-children",
3042
3067
  selector: m(i),
3043
- html: u(i),
3068
+ html: d(i),
3044
3069
  impact: "critical",
3045
3070
  message: `Role "${n}" requires children with role: ${o}.`
3046
3071
  });
@@ -3048,7 +3073,7 @@ const Sa = {
3048
3073
  }
3049
3074
  return a;
3050
3075
  }
3051
- }, ka = {
3076
+ }, Ta = {
3052
3077
  id: "aria-required-parent",
3053
3078
  wcag: ["4.1.2"],
3054
3079
  level: "A",
@@ -3059,13 +3084,13 @@ const Sa = {
3059
3084
  var e;
3060
3085
  const a = [];
3061
3086
  for (const i of t.querySelectorAll("[role]")) {
3062
- if (p(i)) continue;
3087
+ if (g(i)) continue;
3063
3088
  const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
3064
- if (!n || !(n in ie)) continue;
3065
- const r = ie[n];
3089
+ if (!n || !(n in ne)) continue;
3090
+ const r = ne[n];
3066
3091
  let o = i.parentElement, s = !1;
3067
3092
  for (; o && o !== t.documentElement; ) {
3068
- const l = L(o);
3093
+ const l = q(o);
3069
3094
  if (l && r.includes(l)) {
3070
3095
  s = !0;
3071
3096
  break;
@@ -3075,14 +3100,14 @@ const Sa = {
3075
3100
  s || a.push({
3076
3101
  ruleId: "aria-required-parent",
3077
3102
  selector: m(i),
3078
- html: u(i),
3103
+ html: d(i),
3079
3104
  impact: "critical",
3080
3105
  message: `Role "${n}" must be contained within: ${r.join(", ")}.`
3081
3106
  });
3082
3107
  }
3083
3108
  return a;
3084
3109
  }
3085
- }, ne = [
3110
+ }, re = [
3086
3111
  "a[href]",
3087
3112
  "button:not([disabled])",
3088
3113
  'input:not([disabled]):not([type="hidden"])',
@@ -3098,7 +3123,7 @@ const Sa = {
3098
3123
  "embed",
3099
3124
  "area[href]"
3100
3125
  ].join(", ");
3101
- function Ia(t) {
3126
+ function Ea(t) {
3102
3127
  let a = t;
3103
3128
  const e = t.ownerDocument, i = e.defaultView;
3104
3129
  for (; a && a !== e.body; ) {
@@ -3111,7 +3136,7 @@ function Ia(t) {
3111
3136
  }
3112
3137
  return !0;
3113
3138
  }
3114
- const Ta = {
3139
+ const Ca = {
3115
3140
  id: "aria-hidden-body",
3116
3141
  selector: 'body[aria-hidden="true"]',
3117
3142
  check: { type: "selector-exists" },
@@ -3123,7 +3148,7 @@ const Ta = {
3123
3148
  guidance: "Setting aria-hidden='true' on the body element hides all page content from assistive technologies, making the page completely inaccessible to screen reader users. Remove aria-hidden from the body element. If you need to hide content temporarily (e.g., behind a modal), use aria-hidden on specific sections instead.",
3124
3149
  prompt: "Instruct to remove aria-hidden='true' from the body element.",
3125
3150
  skipAriaHidden: !1
3126
- }, Ea = k(Ta), Ca = {
3151
+ }, La = k(Ca), qa = {
3127
3152
  id: "aria-hidden-focus",
3128
3153
  wcag: ["4.1.2"],
3129
3154
  level: "A",
@@ -3134,12 +3159,12 @@ const Ta = {
3134
3159
  const a = [];
3135
3160
  for (const e of t.querySelectorAll('[aria-hidden="true"]')) {
3136
3161
  if (e === t.body) continue;
3137
- const i = [...e.querySelectorAll(ne)];
3138
- e.matches(ne) && i.push(e);
3162
+ const i = [...e.querySelectorAll(re)];
3163
+ e.matches(re) && i.push(e);
3139
3164
  for (const n of i)
3140
3165
  if (n instanceof HTMLElement) {
3141
3166
  const r = n.getAttribute("tabindex");
3142
- if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !Ia(n)) continue;
3167
+ if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !Ea(n)) continue;
3143
3168
  const o = n.tagName.toLowerCase();
3144
3169
  let s;
3145
3170
  r !== null ? s = `has tabindex="${r}"` : o === "a" && n.hasAttribute("href") ? s = "is a link with href" : o === "button" ? s = "is a <button>" : o === "input" ? s = `is an <input type="${n.type}">` : o === "select" ? s = "is a <select>" : o === "textarea" ? s = "is a <textarea>" : o === "iframe" ? s = "is an <iframe>" : s = `is a natively focusable <${o}>`;
@@ -3147,16 +3172,16 @@ const Ta = {
3147
3172
  a.push({
3148
3173
  ruleId: "aria-hidden-focus",
3149
3174
  selector: m(n),
3150
- html: u(n),
3175
+ html: d(n),
3151
3176
  impact: "serious",
3152
3177
  message: "Focusable element is inside an aria-hidden region.",
3153
- context: `Focusable because: ${s}. aria-hidden ancestor: ${l ? u(l) : "unknown"}`
3178
+ context: `Focusable because: ${s}. aria-hidden ancestor: ${l ? d(l) : "unknown"}`
3154
3179
  });
3155
3180
  }
3156
3181
  }
3157
3182
  return a;
3158
3183
  }
3159
- }, La = {
3184
+ }, Ra = {
3160
3185
  id: "aria-command-name",
3161
3186
  wcag: ["4.1.2"],
3162
3187
  level: "A",
@@ -3167,14 +3192,14 @@ const Ta = {
3167
3192
  var e;
3168
3193
  const a = [];
3169
3194
  for (const i of t.querySelectorAll('[role="button"], [role="link"], [role="menuitem"]')) {
3170
- if (p(i) || i.tagName.toLowerCase() === "button" || i.tagName.toLowerCase() === "a") continue;
3195
+ if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.tagName.toLowerCase() === "button" || i.tagName.toLowerCase() === "a") continue;
3171
3196
  if (!v(i)) {
3172
3197
  const r = i.querySelector("img[alt]");
3173
3198
  if ((e = r == null ? void 0 : r.getAttribute("alt")) != null && e.trim()) continue;
3174
3199
  a.push({
3175
3200
  ruleId: "aria-command-name",
3176
3201
  selector: m(i),
3177
- html: u(i),
3202
+ html: d(i),
3178
3203
  impact: "serious",
3179
3204
  message: "ARIA command has no accessible name."
3180
3205
  });
@@ -3182,7 +3207,7 @@ const Ta = {
3182
3207
  }
3183
3208
  return a;
3184
3209
  }
3185
- }, qa = {
3210
+ }, Na = {
3186
3211
  id: "aria-input-field-name",
3187
3212
  wcag: ["4.1.2"],
3188
3213
  level: "A",
@@ -3192,18 +3217,18 @@ const Ta = {
3192
3217
  run(t) {
3193
3218
  const a = [], e = '[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]';
3194
3219
  for (const i of t.querySelectorAll(e)) {
3195
- if (p(i) || i.matches("input, select, textarea")) continue;
3220
+ if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches("input, select, textarea")) continue;
3196
3221
  v(i) || a.push({
3197
3222
  ruleId: "aria-input-field-name",
3198
3223
  selector: m(i),
3199
- html: u(i),
3224
+ html: d(i),
3200
3225
  impact: "serious",
3201
3226
  message: "ARIA input field has no accessible name."
3202
3227
  });
3203
3228
  }
3204
3229
  return a;
3205
3230
  }
3206
- }, Ra = {
3231
+ }, $a = {
3207
3232
  id: "aria-toggle-field-name",
3208
3233
  wcag: ["4.1.2"],
3209
3234
  level: "A",
@@ -3213,18 +3238,18 @@ const Ta = {
3213
3238
  run(t) {
3214
3239
  const a = [], e = '[role="checkbox"], [role="switch"], [role="radio"], [role="menuitemcheckbox"], [role="menuitemradio"]';
3215
3240
  for (const i of t.querySelectorAll(e)) {
3216
- if (p(i) || i.matches('input[type="checkbox"], input[type="radio"]')) continue;
3241
+ if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches('input[type="checkbox"], input[type="radio"]')) continue;
3217
3242
  v(i) || a.push({
3218
3243
  ruleId: "aria-toggle-field-name",
3219
3244
  selector: m(i),
3220
- html: u(i),
3245
+ html: d(i),
3221
3246
  impact: "serious",
3222
3247
  message: "ARIA toggle field has no accessible name."
3223
3248
  });
3224
3249
  }
3225
3250
  return a;
3226
3251
  }
3227
- }, Na = {
3252
+ }, Ma = {
3228
3253
  id: "aria-meter-name",
3229
3254
  wcag: ["4.1.2"],
3230
3255
  level: "A",
@@ -3234,18 +3259,18 @@ const Ta = {
3234
3259
  run(t) {
3235
3260
  const a = [];
3236
3261
  for (const e of t.querySelectorAll('[role="meter"], meter')) {
3237
- if (p(e)) continue;
3262
+ if (g(e)) continue;
3238
3263
  v(e) || a.push({
3239
3264
  ruleId: "aria-meter-name",
3240
3265
  selector: m(e),
3241
- html: u(e),
3266
+ html: d(e),
3242
3267
  impact: "serious",
3243
3268
  message: "Meter has no accessible name."
3244
3269
  });
3245
3270
  }
3246
3271
  return a;
3247
3272
  }
3248
- }, $a = {
3273
+ }, Ha = {
3249
3274
  id: "aria-progressbar-name",
3250
3275
  wcag: ["4.1.2"],
3251
3276
  level: "A",
@@ -3255,18 +3280,18 @@ const Ta = {
3255
3280
  run(t) {
3256
3281
  const a = [];
3257
3282
  for (const e of t.querySelectorAll('[role="progressbar"], progress')) {
3258
- if (p(e)) continue;
3283
+ if (g(e)) continue;
3259
3284
  v(e) || a.push({
3260
3285
  ruleId: "aria-progressbar-name",
3261
3286
  selector: m(e),
3262
- html: u(e),
3287
+ html: d(e),
3263
3288
  impact: "serious",
3264
3289
  message: "Progressbar has no accessible name."
3265
3290
  });
3266
3291
  }
3267
3292
  return a;
3268
3293
  }
3269
- }, Ma = {
3294
+ }, Da = {
3270
3295
  id: "aria-dialog-name",
3271
3296
  wcag: ["4.1.2"],
3272
3297
  level: "A",
@@ -3276,18 +3301,18 @@ const Ta = {
3276
3301
  run(t) {
3277
3302
  const a = [];
3278
3303
  for (const e of t.querySelectorAll('[role="dialog"], [role="alertdialog"], dialog')) {
3279
- if (p(e)) continue;
3304
+ if (g(e)) continue;
3280
3305
  v(e) || a.push({
3281
3306
  ruleId: "aria-dialog-name",
3282
3307
  selector: m(e),
3283
- html: u(e),
3308
+ html: d(e),
3284
3309
  impact: "serious",
3285
3310
  message: "Dialog has no accessible name."
3286
3311
  });
3287
3312
  }
3288
3313
  return a;
3289
3314
  }
3290
- }, Ha = {
3315
+ }, Oa = {
3291
3316
  id: "aria-tooltip-name",
3292
3317
  wcag: ["4.1.2"],
3293
3318
  level: "A",
@@ -3297,18 +3322,18 @@ const Ta = {
3297
3322
  run(t) {
3298
3323
  const a = [];
3299
3324
  for (const e of t.querySelectorAll('[role="tooltip"]')) {
3300
- if (p(e)) continue;
3325
+ if (g(e)) continue;
3301
3326
  v(e) || a.push({
3302
3327
  ruleId: "aria-tooltip-name",
3303
3328
  selector: m(e),
3304
- html: u(e),
3329
+ html: d(e),
3305
3330
  impact: "serious",
3306
3331
  message: "Tooltip has no accessible name."
3307
3332
  });
3308
3333
  }
3309
3334
  return a;
3310
3335
  }
3311
- }, Da = {
3336
+ }, Ba = {
3312
3337
  id: "aria-treeitem-name",
3313
3338
  wcag: ["4.1.2"],
3314
3339
  level: "A",
@@ -3318,18 +3343,18 @@ const Ta = {
3318
3343
  run(t) {
3319
3344
  const a = [];
3320
3345
  for (const e of t.querySelectorAll('[role="treeitem"]')) {
3321
- if (p(e)) continue;
3346
+ if (g(e)) continue;
3322
3347
  v(e) || a.push({
3323
3348
  ruleId: "aria-treeitem-name",
3324
3349
  selector: m(e),
3325
- html: u(e),
3350
+ html: d(e),
3326
3351
  impact: "serious",
3327
3352
  message: "Treeitem has no accessible name."
3328
3353
  });
3329
3354
  }
3330
3355
  return a;
3331
3356
  }
3332
- }, Oa = {
3357
+ }, Fa = {
3333
3358
  id: "aria-prohibited-attr",
3334
3359
  wcag: ["4.1.2"],
3335
3360
  level: "A",
@@ -3337,16 +3362,16 @@ const Ta = {
3337
3362
  guidance: "Some ARIA roles prohibit certain attributes. For example, roles like 'none', 'presentation', 'generic', and text-level roles (code, emphasis, strong) prohibit aria-label and aria-labelledby because naming is not supported for these roles. Remove the prohibited attributes or change the role.",
3338
3363
  prompt: "Identify the prohibited attribute and recommend removing it from this element.",
3339
3364
  run(t) {
3340
- return z(t).prohibitedAttr;
3365
+ return U(t).prohibitedAttr;
3341
3366
  }
3342
- }, Fa = [
3367
+ }, Wa = [
3343
3368
  "a[href]",
3344
3369
  "button:not([disabled])",
3345
3370
  'input:not([disabled]):not([type="hidden"])',
3346
3371
  "select:not([disabled])",
3347
3372
  "textarea:not([disabled])",
3348
3373
  '[tabindex]:not([tabindex="-1"])'
3349
- ].join(", "), Ba = [
3374
+ ].join(", "), _a = [
3350
3375
  "aria-atomic",
3351
3376
  "aria-busy",
3352
3377
  "aria-controls",
@@ -3361,17 +3386,17 @@ const Ta = {
3361
3386
  "aria-owns",
3362
3387
  "aria-relevant"
3363
3388
  ];
3364
- function re(t) {
3389
+ function oe(t) {
3365
3390
  const a = [];
3366
- t.matches(Fa) && a.push("element is focusable");
3367
- for (const e of Ba)
3391
+ t.matches(Wa) && a.push("element is focusable");
3392
+ for (const e of _a)
3368
3393
  if (t.hasAttribute(e)) {
3369
3394
  a.push(`has ${e}`);
3370
3395
  break;
3371
3396
  }
3372
3397
  return (t.hasAttribute("aria-label") || t.hasAttribute("aria-labelledby")) && a.push("has accessible name"), a;
3373
3398
  }
3374
- const Wa = {
3399
+ const Pa = {
3375
3400
  id: "presentation-role-conflict",
3376
3401
  wcag: ["4.1.2"],
3377
3402
  level: "A",
@@ -3381,30 +3406,30 @@ const Wa = {
3381
3406
  run(t) {
3382
3407
  const a = [];
3383
3408
  for (const e of t.querySelectorAll('[role="presentation"], [role="none"]')) {
3384
- if (p(e)) continue;
3385
- const i = re(e);
3409
+ if (g(e)) continue;
3410
+ const i = oe(e);
3386
3411
  i.length > 0 && a.push({
3387
3412
  ruleId: "presentation-role-conflict",
3388
3413
  selector: m(e),
3389
- html: u(e),
3414
+ html: d(e),
3390
3415
  impact: "serious",
3391
3416
  message: `Presentation role conflicts with: ${i.join(", ")}. The role will be ignored.`
3392
3417
  });
3393
3418
  }
3394
3419
  for (const e of t.querySelectorAll('img[alt=""]')) {
3395
- if (p(e) || e.hasAttribute("role")) continue;
3396
- const i = re(e);
3420
+ if (g(e) || e.hasAttribute("role")) continue;
3421
+ const i = oe(e);
3397
3422
  i.length > 0 && a.push({
3398
3423
  ruleId: "presentation-role-conflict",
3399
3424
  selector: m(e),
3400
- html: u(e),
3425
+ html: d(e),
3401
3426
  impact: "serious",
3402
3427
  message: `Element with implicit presentation role (alt="") conflicts with: ${i.join(", ")}. The decorative role will be ignored.`
3403
3428
  });
3404
3429
  }
3405
3430
  return a;
3406
3431
  }
3407
- }, _a = {
3432
+ }, ja = {
3408
3433
  id: "summary-name",
3409
3434
  wcag: ["4.1.2"],
3410
3435
  level: "A",
@@ -3414,11 +3439,11 @@ const Wa = {
3414
3439
  run(t) {
3415
3440
  const a = [];
3416
3441
  for (const e of t.querySelectorAll("details > summary:first-of-type")) {
3417
- if (p(e)) continue;
3442
+ if (g(e)) continue;
3418
3443
  v(e) || a.push({
3419
3444
  ruleId: "summary-name",
3420
3445
  selector: m(e),
3421
- html: u(e),
3446
+ html: d(e),
3422
3447
  impact: "serious",
3423
3448
  message: "<summary> element has no accessible name. Add descriptive text."
3424
3449
  });
@@ -3426,7 +3451,7 @@ const Wa = {
3426
3451
  return a;
3427
3452
  }
3428
3453
  };
3429
- function Pa(t) {
3454
+ function Va(t) {
3430
3455
  var n, r;
3431
3456
  const a = [], e = t.getAttribute("href");
3432
3457
  e && a.push(`href: ${e}`);
@@ -3443,7 +3468,7 @@ function Pa(t) {
3443
3468
  return a.length > 0 ? a.join(`
3444
3469
  `) : void 0;
3445
3470
  }
3446
- const ja = {
3471
+ const za = {
3447
3472
  id: "link-name",
3448
3473
  wcag: ["2.4.4", "4.1.2"],
3449
3474
  level: "A",
@@ -3453,19 +3478,19 @@ const ja = {
3453
3478
  run(t) {
3454
3479
  const a = [];
3455
3480
  for (const e of t.querySelectorAll('a[href], area[href], [role="link"]')) {
3456
- if (p(e)) continue;
3481
+ if (g(e) || T(e) || e.getRootNode() instanceof ShadowRoot) continue;
3457
3482
  v(e) || a.push({
3458
3483
  ruleId: "link-name",
3459
3484
  selector: m(e),
3460
- html: u(e),
3485
+ html: d(e),
3461
3486
  impact: "serious",
3462
3487
  message: "Link has no discernible text.",
3463
- context: Pa(e)
3488
+ context: Va(e)
3464
3489
  });
3465
3490
  }
3466
3491
  return a;
3467
3492
  }
3468
- }, Va = {
3493
+ }, Ua = {
3469
3494
  id: "skip-link",
3470
3495
  wcag: ["2.4.1"],
3471
3496
  level: "A",
@@ -3478,20 +3503,20 @@ const ja = {
3478
3503
  for (const i of e) {
3479
3504
  const n = i.getAttribute("href");
3480
3505
  if (!n || n === "#") continue;
3481
- const r = w(i).toLowerCase();
3506
+ const r = A(i).toLowerCase();
3482
3507
  if (!(r.includes("skip") || r.includes("jump") || r.includes("main content") || r.includes("navigation"))) continue;
3483
3508
  const s = n.slice(1);
3484
3509
  t.getElementById(s) || a.push({
3485
3510
  ruleId: "skip-link",
3486
3511
  selector: m(i),
3487
- html: u(i),
3512
+ html: d(i),
3488
3513
  impact: "moderate",
3489
3514
  message: `Skip link points to "#${s}" which does not exist on the page.`
3490
3515
  });
3491
3516
  }
3492
3517
  return a;
3493
3518
  }
3494
- }, za = /* @__PURE__ */ new Set([
3519
+ }, Ga = /* @__PURE__ */ new Set([
3495
3520
  "block",
3496
3521
  "flex",
3497
3522
  "grid",
@@ -3499,23 +3524,23 @@ const ja = {
3499
3524
  "table-cell",
3500
3525
  "list-item",
3501
3526
  "flow-root"
3502
- ]), Ua = /* @__PURE__ */ new Set([
3527
+ ]), Ya = /* @__PURE__ */ new Set([
3503
3528
  "inline",
3504
3529
  "inline-block",
3505
3530
  "inline-flex",
3506
3531
  "inline-grid"
3507
3532
  ]);
3508
- function Ga(t) {
3533
+ function Xa(t) {
3509
3534
  let a = t.parentElement;
3510
3535
  for (; a; ) {
3511
- const e = A(a).display;
3512
- if (za.has(e))
3513
- return Xa(a) ? a : null;
3536
+ const e = w(a).display;
3537
+ if (Ga.has(e))
3538
+ return Ka(a) ? a : null;
3514
3539
  a = a.parentElement;
3515
3540
  }
3516
3541
  return null;
3517
3542
  }
3518
- function Xa(t) {
3543
+ function Ka(t) {
3519
3544
  const a = t.ownerDocument.createTreeWalker(
3520
3545
  t,
3521
3546
  NodeFilter.SHOW_TEXT
@@ -3535,7 +3560,7 @@ function Xa(t) {
3535
3560
  }
3536
3561
  return /[a-zA-Z\u00C0-\u024F]{2,}/.test(e);
3537
3562
  }
3538
- function Ya(t, a) {
3563
+ function Ja(t, a) {
3539
3564
  const e = t.ownerDocument.createTreeWalker(
3540
3565
  t,
3541
3566
  NodeFilter.SHOW_TEXT
@@ -3552,11 +3577,11 @@ function Ya(t, a) {
3552
3577
  o = o.parentElement;
3553
3578
  }
3554
3579
  if (!r && n)
3555
- return R(A(n).color);
3580
+ return N(w(n).color);
3556
3581
  }
3557
3582
  return null;
3558
3583
  }
3559
- function Ka(t, a) {
3584
+ function Qa(t, a) {
3560
3585
  const e = t.textDecorationLine || t.textDecoration || "", i = a.textDecorationLine || a.textDecoration || "";
3561
3586
  if ((e.includes("underline") || e.includes("line-through")) && e !== i)
3562
3587
  return !0;
@@ -3569,19 +3594,19 @@ function Ka(t, a) {
3569
3594
  const l = t.backgroundImage || "";
3570
3595
  if (l && l !== "none" && l !== "initial")
3571
3596
  return !0;
3572
- const h = oe(t.fontWeight), c = oe(a.fontWeight);
3597
+ const h = se(t.fontWeight), c = se(a.fontWeight);
3573
3598
  if (Math.abs(h - c) >= 300 || t.fontStyle !== a.fontStyle)
3574
3599
  return !0;
3575
- const d = parseFloat(t.fontSize) || 16, g = parseFloat(a.fontSize) || 16;
3576
- return g > 0 && d / g >= 1.2;
3600
+ const u = parseFloat(t.fontSize) || 16, p = parseFloat(a.fontSize) || 16;
3601
+ return p > 0 && u / p >= 1.2;
3577
3602
  }
3578
- function oe(t) {
3603
+ function se(t) {
3579
3604
  return t === "bold" ? 700 : t === "normal" ? 400 : parseInt(t) || 400;
3580
3605
  }
3581
- function se(t, a, e) {
3606
+ function le(t, a, e) {
3582
3607
  return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
3583
3608
  }
3584
- const Ja = {
3609
+ const Za = {
3585
3610
  id: "link-in-text-block",
3586
3611
  wcag: ["1.4.1"],
3587
3612
  level: "A",
@@ -3591,22 +3616,22 @@ const Ja = {
3591
3616
  run(t) {
3592
3617
  const a = [];
3593
3618
  for (const e of t.querySelectorAll("a[href]")) {
3594
- if (p(e) || !w(e).trim() || e.closest('nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]')) continue;
3595
- const i = A(e), n = i.display || "inline";
3596
- if (!Ua.has(n)) continue;
3597
- const r = Ga(e);
3619
+ if (g(e) || !A(e).trim() || e.closest('nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]')) continue;
3620
+ const i = w(e), n = i.display || "inline";
3621
+ if (!Ya.has(n)) continue;
3622
+ const r = Xa(e);
3598
3623
  if (!r) continue;
3599
- const o = A(r);
3600
- if (Ka(i, o)) continue;
3601
- const s = R(i.color), l = Ya(r);
3624
+ const o = w(r);
3625
+ if (Qa(i, o)) continue;
3626
+ const s = N(i.color), l = Ja(r);
3602
3627
  if (!s || !l) continue;
3603
- const h = q(...s), c = q(...l), d = de(h, c);
3604
- if (d >= 3) continue;
3605
- const g = se(...s), b = se(...l), f = `link color: ${g} rgb(${s.join(", ")}), surrounding text: ${b} rgb(${l.join(", ")}), ratio: ${d.toFixed(2)}:1`;
3628
+ const h = R(...s), c = R(...l), u = me(h, c);
3629
+ if (u >= 3) continue;
3630
+ const p = le(...s), b = le(...l), f = `link color: ${p} rgb(${s.join(", ")}), surrounding text: ${b} rgb(${l.join(", ")}), ratio: ${u.toFixed(2)}:1`;
3606
3631
  a.push({
3607
3632
  ruleId: "link-in-text-block",
3608
3633
  selector: m(e),
3609
- html: u(e),
3634
+ html: d(e),
3610
3635
  impact: "serious",
3611
3636
  message: "Link in text block is not visually distinguishable from surrounding text. Add an underline, border, or ensure 3:1 color contrast with surrounding text.",
3612
3637
  context: f
@@ -3614,7 +3639,7 @@ const Ja = {
3614
3639
  }
3615
3640
  return a;
3616
3641
  }
3617
- }, Qa = {
3642
+ }, ei = {
3618
3643
  id: "html-has-lang",
3619
3644
  wcag: ["3.1.1"],
3620
3645
  level: "A",
@@ -3640,7 +3665,7 @@ const Ja = {
3640
3665
  return [{
3641
3666
  ruleId: "html-has-lang",
3642
3667
  selector: m(a),
3643
- html: u(a),
3668
+ html: d(a),
3644
3669
  impact: "serious",
3645
3670
  message: "<html> element missing lang attribute.",
3646
3671
  context: n ? `Page text sample: "${n}"` : void 0
@@ -3648,17 +3673,17 @@ const Ja = {
3648
3673
  }
3649
3674
  return [];
3650
3675
  }
3651
- }, Za = new Set(
3676
+ }, ti = new Set(
3652
3677
  "aa ab ae af ak am an ar as av ay az ba be bg bh bi bm bn bo br bs ca ce ch co cr cs cu cv cy da de dv dz ee el en eo es et eu fa ff fi fj fo fr fy ga gd gl gn gu gv ha he hi ho hr ht hu hy hz ia id ie ig ii ik io is it iu ja jv ka kg ki kj kk kl km kn ko kr ks ku kv kw ky la lb lg li ln lo lt lu lv mg mh mi mk ml mn mr ms mt my na nb nd ne ng nl nn no nr nv ny oc oj om or os pa pi pl ps pt qu rm rn ro ru rw sa sc sd se sg si sk sl sm sn so sq sr ss st su sv sw ta te tg th ti tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa wo xh yi yo za zh zu".split(" ")
3653
- ), ei = new Set(
3678
+ ), ai = new Set(
3654
3679
  "aar abk afr aka amh ara arg asm ava ave aym aze bak bam bel ben bih bis bod bos bre bul cat ces cha che chu chv cor cos cre cym dan deu div dzo ell eng epo est eus ewe fao fas fij fin fra fry ful gla gle glg glv grn guj hat hau hbs heb her hin hmo hrv hun hye ibo iii iku ile ina ind ipk isl ita jav jpn kal kan kas kat kau kaz khm kik kin kir kom kon kor kua kur lao lat lav lim lin lit ltz lub lug mah mal mar mkd mlg mlt mon mri msa mya nau nav nbl nde ndo nep nld nno nob nor nya oci oji ori orm oss pan pli pol por pus que roh ron run rus sag san sin slk slv sme smo sna snd som sot spa sqi srd srp ssw sun swa swe tah tam tat tel tgk tgl tha tir ton tsn tso tuk tur twi uig ukr urd uzb ven vie vol wln wol xho yid yor zha zho zul".split(" ")
3655
- ), ti = /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i;
3656
- function he(t) {
3657
- if (!ti.test(t)) return !1;
3680
+ ), ii = /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i;
3681
+ function pe(t) {
3682
+ if (!ii.test(t)) return !1;
3658
3683
  const a = t.split("-")[0].toLowerCase();
3659
- return a.length === 2 ? Za.has(a) : a.length === 3 ? !ei.has(a) : !1;
3684
+ return a.length === 2 ? ti.has(a) : a.length === 3 ? !ai.has(a) : !1;
3660
3685
  }
3661
- const ai = {
3686
+ const ni = {
3662
3687
  id: "html-lang-valid",
3663
3688
  wcag: ["3.1.1"],
3664
3689
  level: "A",
@@ -3668,16 +3693,16 @@ const ai = {
3668
3693
  run(t) {
3669
3694
  var e;
3670
3695
  const a = (e = t.documentElement.getAttribute("lang")) == null ? void 0 : e.trim();
3671
- return a && !he(a) ? [{
3696
+ return a && !pe(a) ? [{
3672
3697
  ruleId: "html-lang-valid",
3673
3698
  selector: "html",
3674
- html: u(t.documentElement),
3699
+ html: d(t.documentElement),
3675
3700
  impact: "serious",
3676
3701
  message: `Invalid lang attribute value "${a}".`
3677
3702
  }] : [];
3678
3703
  }
3679
3704
  };
3680
- function le(t) {
3705
+ function ce(t) {
3681
3706
  var i;
3682
3707
  const a = t.ownerDocument.createTreeWalker(t, NodeFilter.SHOW_TEXT);
3683
3708
  let e;
@@ -3709,7 +3734,7 @@ function le(t) {
3709
3734
  }
3710
3735
  return !1;
3711
3736
  }
3712
- const ii = {
3737
+ const ri = {
3713
3738
  id: "valid-lang",
3714
3739
  wcag: ["3.1.2"],
3715
3740
  level: "AA",
@@ -3719,29 +3744,29 @@ const ii = {
3719
3744
  run(t) {
3720
3745
  const a = [];
3721
3746
  for (const e of t.querySelectorAll("[lang]")) {
3722
- if (p(e) || e === t.documentElement) continue;
3747
+ if (g(e) || e === t.documentElement) continue;
3723
3748
  const i = e.getAttribute("lang"), n = i == null ? void 0 : i.trim();
3724
3749
  if (i && !n) {
3725
- le(e) && a.push({
3750
+ ce(e) && a.push({
3726
3751
  ruleId: "valid-lang",
3727
3752
  selector: m(e),
3728
- html: u(e),
3753
+ html: d(e),
3729
3754
  impact: "serious",
3730
3755
  message: "Empty lang attribute value."
3731
3756
  });
3732
3757
  continue;
3733
3758
  }
3734
- n && le(e) && (he(n) || a.push({
3759
+ n && ce(e) && (pe(n) || a.push({
3735
3760
  ruleId: "valid-lang",
3736
3761
  selector: m(e),
3737
- html: u(e),
3762
+ html: d(e),
3738
3763
  impact: "serious",
3739
3764
  message: `Invalid lang attribute value "${n}".`
3740
3765
  }));
3741
3766
  }
3742
3767
  return a;
3743
3768
  }
3744
- }, ni = {
3769
+ }, oi = {
3745
3770
  id: "html-xml-lang-mismatch",
3746
3771
  wcag: ["3.1.1"],
3747
3772
  level: "A",
@@ -3757,14 +3782,14 @@ const ii = {
3757
3782
  return [{
3758
3783
  ruleId: "html-xml-lang-mismatch",
3759
3784
  selector: "html",
3760
- html: u(a),
3785
+ html: d(a),
3761
3786
  impact: "moderate",
3762
3787
  message: `lang="${e}" and xml:lang="${i}" do not match.`
3763
3788
  }];
3764
3789
  }
3765
3790
  return [];
3766
3791
  }
3767
- }, ri = {
3792
+ }, si = {
3768
3793
  id: "td-headers-attr",
3769
3794
  wcag: ["1.3.1"],
3770
3795
  level: "A",
@@ -3774,7 +3799,7 @@ const ii = {
3774
3799
  run(t) {
3775
3800
  const a = [];
3776
3801
  for (const e of t.querySelectorAll("td[headers]")) {
3777
- if (p(e)) continue;
3802
+ if (g(e)) continue;
3778
3803
  const i = e.closest("table");
3779
3804
  if (!i) continue;
3780
3805
  const n = e.getAttribute("id"), r = e.getAttribute("headers").split(/\s+/);
@@ -3783,7 +3808,7 @@ const ii = {
3783
3808
  a.push({
3784
3809
  ruleId: "td-headers-attr",
3785
3810
  selector: m(e),
3786
- html: u(e),
3811
+ html: d(e),
3787
3812
  impact: "serious",
3788
3813
  message: `Headers attribute references the cell itself ("${o}").`
3789
3814
  });
@@ -3793,7 +3818,7 @@ const ii = {
3793
3818
  a.push({
3794
3819
  ruleId: "td-headers-attr",
3795
3820
  selector: m(e),
3796
- html: u(e),
3821
+ html: d(e),
3797
3822
  impact: "serious",
3798
3823
  message: `Headers attribute references non-existent ID "${o}".`
3799
3824
  });
@@ -3803,7 +3828,7 @@ const ii = {
3803
3828
  }
3804
3829
  return a;
3805
3830
  }
3806
- }, oi = {
3831
+ }, li = {
3807
3832
  id: "th-has-data-cells",
3808
3833
  wcag: ["1.3.1"],
3809
3834
  level: "A",
@@ -3813,19 +3838,19 @@ const ii = {
3813
3838
  run(t) {
3814
3839
  const a = [];
3815
3840
  for (const e of t.querySelectorAll("table")) {
3816
- if (p(e) || e.getAttribute("role") === "presentation" || e.getAttribute("role") === "none") continue;
3841
+ if (g(e) || e.getAttribute("role") === "presentation" || e.getAttribute("role") === "none") continue;
3817
3842
  const i = e.querySelectorAll("th"), n = e.querySelectorAll("td");
3818
3843
  i.length > 0 && n.length === 0 && a.push({
3819
3844
  ruleId: "th-has-data-cells",
3820
3845
  selector: m(e),
3821
- html: u(e),
3846
+ html: d(e),
3822
3847
  impact: "serious",
3823
3848
  message: "Table has header cells but no data cells."
3824
3849
  });
3825
3850
  }
3826
3851
  return a;
3827
3852
  }
3828
- }, si = {
3853
+ }, ci = {
3829
3854
  id: "td-has-header",
3830
3855
  wcag: ["1.3.1"],
3831
3856
  level: "A",
@@ -3836,24 +3861,24 @@ const ii = {
3836
3861
  var e, i;
3837
3862
  const a = [];
3838
3863
  for (const n of t.querySelectorAll("table")) {
3839
- if (p(n) || n.getAttribute("role") === "presentation" || n.getAttribute("role") === "none") continue;
3864
+ if (g(n) || n.getAttribute("role") === "presentation" || n.getAttribute("role") === "none") continue;
3840
3865
  const r = n.querySelectorAll("tr"), o = r.length;
3841
3866
  let s = 0;
3842
- for (const d of r) {
3843
- const g = d.querySelectorAll("td, th");
3867
+ for (const u of r) {
3868
+ const p = u.querySelectorAll("td, th");
3844
3869
  let b = 0;
3845
- for (const f of g)
3870
+ for (const f of p)
3846
3871
  b += parseInt(f.getAttribute("colspan") || "1", 10);
3847
3872
  s = Math.max(s, b);
3848
3873
  }
3849
3874
  if (o <= 3 && s <= 3) continue;
3850
3875
  const l = n.querySelector("th") !== null, h = n.querySelector("th[scope]") !== null, c = n.querySelector("td[headers]") !== null;
3851
3876
  if (l)
3852
- for (const d of n.querySelectorAll("td")) {
3853
- if (p(d) || d.hasAttribute("headers")) continue;
3854
- const g = d.closest("tr");
3855
- if (!g) continue;
3856
- const b = g.querySelector("th") !== null, f = Array.from(g.children).indexOf(d);
3877
+ for (const u of n.querySelectorAll("td")) {
3878
+ if (g(u) || u.hasAttribute("headers")) continue;
3879
+ const p = u.closest("tr");
3880
+ if (!p) continue;
3881
+ const b = p.querySelector("th") !== null, f = Array.from(p.children).indexOf(u);
3857
3882
  let y = !1;
3858
3883
  const I = n.querySelector("thead");
3859
3884
  if (I) {
@@ -3867,8 +3892,8 @@ const ii = {
3867
3892
  if (!b && !y && !h && !c) {
3868
3893
  a.push({
3869
3894
  ruleId: "td-has-header",
3870
- selector: m(d),
3871
- html: u(d),
3895
+ selector: m(u),
3896
+ html: d(u),
3872
3897
  impact: "serious",
3873
3898
  message: "Data cell has no associated header. Add th elements with scope, or headers attribute."
3874
3899
  });
@@ -3878,7 +3903,7 @@ const ii = {
3878
3903
  }
3879
3904
  return a;
3880
3905
  }
3881
- }, li = {
3906
+ }, ui = {
3882
3907
  id: "scope-attr-valid",
3883
3908
  wcag: ["1.3.1"],
3884
3909
  level: "A",
@@ -3889,19 +3914,19 @@ const ii = {
3889
3914
  var i;
3890
3915
  const a = [], e = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
3891
3916
  for (const n of t.querySelectorAll("th[scope]")) {
3892
- if (p(n)) continue;
3917
+ if (g(n)) continue;
3893
3918
  const r = (i = n.getAttribute("scope")) == null ? void 0 : i.toLowerCase();
3894
3919
  r && !e.has(r) && a.push({
3895
3920
  ruleId: "scope-attr-valid",
3896
3921
  selector: m(n),
3897
- html: u(n),
3922
+ html: d(n),
3898
3923
  impact: "moderate",
3899
3924
  message: `Invalid scope value "${r}". Use row, col, rowgroup, or colgroup.`
3900
3925
  });
3901
3926
  }
3902
3927
  return a;
3903
3928
  }
3904
- }, ci = {
3929
+ }, di = {
3905
3930
  id: "empty-table-header",
3906
3931
  wcag: [],
3907
3932
  level: "A",
@@ -3912,19 +3937,19 @@ const ii = {
3912
3937
  run(t) {
3913
3938
  const a = [];
3914
3939
  for (const e of t.querySelectorAll("th")) {
3915
- if (p(e)) continue;
3940
+ if (g(e)) continue;
3916
3941
  const i = e.closest("table");
3917
3942
  (i == null ? void 0 : i.getAttribute("role")) === "presentation" || (i == null ? void 0 : i.getAttribute("role")) === "none" || v(e) || a.push({
3918
3943
  ruleId: "empty-table-header",
3919
3944
  selector: m(e),
3920
- html: u(e),
3945
+ html: d(e),
3921
3946
  impact: "minor",
3922
3947
  message: "Table header cell is empty. Add text or use aria-label."
3923
3948
  });
3924
3949
  }
3925
3950
  return a;
3926
3951
  }
3927
- }, D = ["aria-labelledby", "aria-describedby", "aria-controls", "aria-owns", "aria-flowto"], ui = {
3952
+ }, O = ["aria-labelledby", "aria-describedby", "aria-controls", "aria-owns", "aria-flowto"], mi = {
3928
3953
  id: "duplicate-id-aria",
3929
3954
  wcag: ["4.1.2"],
3930
3955
  level: "A",
@@ -3934,7 +3959,7 @@ const ii = {
3934
3959
  run(t) {
3935
3960
  const a = [], e = /* @__PURE__ */ new Set();
3936
3961
  for (const n of t.querySelectorAll("[aria-labelledby], [aria-describedby], [aria-controls], [aria-owns], [aria-flowto]"))
3937
- for (const r of D) {
3962
+ for (const r of O) {
3938
3963
  const o = n.getAttribute(r);
3939
3964
  o && o.split(/\s+/).forEach((s) => e.add(s));
3940
3965
  }
@@ -3948,14 +3973,14 @@ const ii = {
3948
3973
  for (const [n, r] of i) {
3949
3974
  if (r <= 1) continue;
3950
3975
  const o = t.querySelectorAll(`#${CSS.escape(n)}`), s = t.querySelector(
3951
- D.map((c) => `[${c}~="${CSS.escape(n)}"]`).join(", ")
3976
+ O.map((c) => `[${c}~="${CSS.escape(n)}"]`).join(", ")
3952
3977
  ), l = t.querySelector(`label[for="${CSS.escape(n)}"]`);
3953
3978
  let h;
3954
3979
  if (s) {
3955
- const c = D.find(
3956
- (d) => {
3957
- var g;
3958
- return (g = s.getAttribute(d)) == null ? void 0 : g.split(/\s+/).includes(n);
3980
+ const c = O.find(
3981
+ (u) => {
3982
+ var p;
3983
+ return (p = s.getAttribute(u)) == null ? void 0 : p.split(/\s+/).includes(n);
3959
3984
  }
3960
3985
  );
3961
3986
  c && (h = c);
@@ -3963,16 +3988,16 @@ const ii = {
3963
3988
  a.push({
3964
3989
  ruleId: "duplicate-id-aria",
3965
3990
  selector: m(o[1]),
3966
- html: u(o[1]),
3991
+ html: d(o[1]),
3967
3992
  impact: "critical",
3968
3993
  message: `Duplicate ID "${n}" referenced by ${h ?? "an accessibility attribute"}.`,
3969
- context: `First element: ${u(o[0])}${h ? `
3994
+ context: `First element: ${d(o[0])}${h ? `
3970
3995
  Referenced by: ${h}` : ""}`
3971
3996
  });
3972
3997
  }
3973
3998
  return a;
3974
3999
  }
3975
- }, di = {
4000
+ }, hi = {
3976
4001
  id: "video-caption",
3977
4002
  wcag: ["1.2.2"],
3978
4003
  level: "A",
@@ -3982,18 +4007,18 @@ Referenced by: ${h}` : ""}`
3982
4007
  run(t) {
3983
4008
  const a = [];
3984
4009
  for (const e of t.querySelectorAll("video")) {
3985
- if (p(e) || e.hasAttribute("muted") || e.hasAttribute("autoplay")) continue;
4010
+ if (g(e) || e.hasAttribute("muted") || e.hasAttribute("autoplay")) continue;
3986
4011
  e.querySelector('track[kind="captions"], track[kind="subtitles"]') || a.push({
3987
4012
  ruleId: "video-caption",
3988
4013
  selector: m(e),
3989
- html: u(e),
4014
+ html: d(e),
3990
4015
  impact: "critical",
3991
4016
  message: "Video element has no captions track."
3992
4017
  });
3993
4018
  }
3994
4019
  return a;
3995
4020
  }
3996
- }, mi = {
4021
+ }, pi = {
3997
4022
  id: "audio-caption",
3998
4023
  wcag: ["1.2.1"],
3999
4024
  level: "A",
@@ -4003,19 +4028,19 @@ Referenced by: ${h}` : ""}`
4003
4028
  run(t) {
4004
4029
  const a = [];
4005
4030
  for (const e of t.querySelectorAll("audio")) {
4006
- if (p(e) || e.querySelector('track[kind="captions"], track[kind="descriptions"]') || e.hasAttribute("aria-describedby")) continue;
4031
+ if (g(e) || e.querySelector('track[kind="captions"], track[kind="descriptions"]') || e.hasAttribute("aria-describedby")) continue;
4007
4032
  const n = e.parentElement;
4008
4033
  n && n.querySelector('a[href*="transcript"], a[href*="text"]') || a.push({
4009
4034
  ruleId: "audio-caption",
4010
4035
  selector: m(e),
4011
- html: u(e),
4036
+ html: d(e),
4012
4037
  impact: "critical",
4013
4038
  message: "Audio element has no transcript or text alternative. Add a transcript or track element."
4014
4039
  });
4015
4040
  }
4016
4041
  return a;
4017
4042
  }
4018
- }, hi = /* @__PURE__ */ new Set([
4043
+ }, gi = /* @__PURE__ */ new Set([
4019
4044
  "SCRIPT",
4020
4045
  "STYLE",
4021
4046
  "NOSCRIPT",
@@ -4031,13 +4056,13 @@ Referenced by: ${h}` : ""}`
4031
4056
  "BR",
4032
4057
  "HR"
4033
4058
  ]);
4034
- function ce([t, a, e]) {
4059
+ function ue([t, a, e]) {
4035
4060
  return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
4036
4061
  }
4037
- function pi(t) {
4062
+ function bi(t) {
4038
4063
  return t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement || t instanceof HTMLButtonElement ? t.disabled : !!(t.closest("fieldset[disabled]") || t.getAttribute("aria-disabled") === "true");
4039
4064
  }
4040
- function gi(t, a) {
4065
+ function fi(t, a) {
4041
4066
  if (t.tagName !== "LABEL") return !1;
4042
4067
  const e = t, i = e.htmlFor;
4043
4068
  if (i) {
@@ -4049,7 +4074,7 @@ function gi(t, a) {
4049
4074
  const r = e.id;
4050
4075
  return !!(r && a.querySelector(`[aria-labelledby~="${r}"][aria-disabled="true"]`));
4051
4076
  }
4052
- function bi(t) {
4077
+ function vi(t) {
4053
4078
  const a = t.clip;
4054
4079
  if (a && a.startsWith("rect(")) {
4055
4080
  const i = a.match(/[\d.]+/g);
@@ -4063,17 +4088,41 @@ function bi(t) {
4063
4088
  }
4064
4089
  return !1;
4065
4090
  }
4066
- function fi(t) {
4067
- if (p(t)) return !0;
4091
+ function yi(t) {
4092
+ if (g(t)) return !0;
4093
+ let a = t;
4094
+ for (; a; ) {
4095
+ const e = w(a);
4096
+ if (e.display === "none" || e.visibility === "hidden" || vi(e)) return !0;
4097
+ a = a.parentElement;
4098
+ }
4099
+ return !1;
4100
+ }
4101
+ function wi(t) {
4102
+ let a = 1, e = t;
4103
+ for (; e; ) {
4104
+ const i = w(e), n = parseFloat(i.opacity);
4105
+ isNaN(n) || (a *= n), e = e.parentElement;
4106
+ }
4107
+ return a;
4108
+ }
4109
+ function Ai(t) {
4068
4110
  let a = t;
4069
4111
  for (; a; ) {
4070
- const e = A(a);
4071
- if (e.display === "none" || e.visibility === "hidden" || bi(e)) return !0;
4112
+ const e = w(a), i = e.filter;
4113
+ if (i && i !== "none" && i !== "initial") return !0;
4114
+ const n = e.mixBlendMode;
4115
+ if (n && n !== "normal" && n !== "initial") return !0;
4116
+ const r = e.backdropFilter;
4117
+ if (r && r !== "none" && r !== "initial") return !0;
4072
4118
  a = a.parentElement;
4073
4119
  }
4074
4120
  return !1;
4075
4121
  }
4076
- const vi = {
4122
+ function xi(t) {
4123
+ return t.closest("select") !== null;
4124
+ }
4125
+ const Si = {
4077
4126
  id: "color-contrast",
4078
4127
  wcag: ["1.4.3"],
4079
4128
  level: "AA",
@@ -4088,95 +4137,95 @@ const vi = {
4088
4137
  for (; r = i.nextNode(); ) {
4089
4138
  if (!r.textContent || !r.textContent.trim()) continue;
4090
4139
  const o = r.parentElement;
4091
- if (!o || n.has(o) || (n.add(o), hi.has(o.tagName)) || pi(o) || gi(o, t) || fi(o)) continue;
4092
- const s = A(o);
4093
- if (parseFloat(s.opacity) === 0) continue;
4094
- const l = s.textShadow;
4095
- if (l && l !== "none" && l !== "initial") continue;
4096
- const h = R(s.color);
4097
- if (!h) continue;
4098
- const c = s.color.match(/rgba\(.+?,\s*([\d.]+)\s*\)/) || s.color.match(/rgba?\(.+?\/\s*([\d.]+%?)\s*\)/);
4099
- if (c && (c[1].endsWith("%") ? parseFloat(c[1]) / 100 : parseFloat(c[1])) === 0 || Be(o)) continue;
4100
- const d = De(o);
4101
- if (!d) continue;
4102
- const g = q(h[0], h[1], h[2]), b = q(d[0], d[1], d[2]), f = de(g, b), y = Pe(o) ? 3 : 4.5;
4103
- if (f < y) {
4104
- const I = Math.round(f * 100) / 100, x = ce(h), $ = ce(d);
4140
+ if (!o || n.has(o) || (n.add(o), gi.has(o.tagName))) continue;
4141
+ const s = o.tagName;
4142
+ if (s === "BODY" || s === "HTML" || xi(o) || bi(o) || fi(o, t) || yi(o)) continue;
4143
+ const l = w(o);
4144
+ if (parseFloat(l.opacity) === 0 || wi(o) < 0.1) continue;
4145
+ const h = l.textShadow;
4146
+ if (h && h !== "none" && h !== "initial" || Ai(o)) continue;
4147
+ const c = N(l.color);
4148
+ if (!c) continue;
4149
+ const u = l.color.match(/rgba\(.+?,\s*([\d.]+)\s*\)/) || l.color.match(/rgba?\(.+?\/\s*([\d.]+%?)\s*\)/);
4150
+ if (u && (u[1].endsWith("%") ? parseFloat(u[1]) / 100 : parseFloat(u[1])) === 0 || _e(o)) continue;
4151
+ const p = Be(o);
4152
+ if (!p) continue;
4153
+ const b = R(c[0], c[1], c[2]), f = R(p[0], p[1], p[2]), y = me(b, f), I = Ve(o) ? 3 : 4.5;
4154
+ if (y < I) {
4155
+ const x = Math.round(y * 100) / 100, M = ue(c), ye = ue(p);
4105
4156
  a.push({
4106
4157
  ruleId: "color-contrast",
4107
4158
  selector: m(o),
4108
- html: u(o),
4159
+ html: d(o),
4109
4160
  impact: "serious",
4110
- message: `Insufficient color contrast ratio of ${I}:1 (required ${y}:1).`,
4111
- context: `foreground: ${x} rgb(${h.join(", ")}), background: ${$} rgb(${d.join(", ")}), ratio: ${I}:1, required: ${y}:1`
4161
+ message: `Insufficient color contrast ratio of ${x}:1 (required ${I}:1).`,
4162
+ context: `foreground: ${M} rgb(${c.join(", ")}), background: ${ye} rgb(${p.join(", ")}), ratio: ${x}:1, required: ${I}:1`
4112
4163
  });
4113
4164
  }
4114
4165
  }
4115
4166
  return a;
4116
4167
  }
4117
- }, pe = [
4168
+ }, ge = [
4118
4169
  // Document Structure
4119
- Kt,
4120
- Jt,
4121
4170
  Qt,
4122
4171
  Zt,
4123
4172
  ea,
4173
+ ta,
4124
4174
  aa,
4125
- ia,
4175
+ na,
4126
4176
  ra,
4127
4177
  sa,
4178
+ ca,
4128
4179
  // Images
4129
- je,
4130
4180
  ze,
4131
- Ue,
4132
4181
  Ge,
4133
4182
  Ye,
4134
- Ke,
4183
+ Xe,
4184
+ Je,
4135
4185
  Qe,
4136
- Ze,
4137
- it,
4186
+ et,
4187
+ tt,
4188
+ rt,
4138
4189
  // Forms
4139
- lt,
4140
- ct,
4141
4190
  ut,
4142
4191
  dt,
4143
- vt,
4144
- yt,
4192
+ mt,
4193
+ ht,
4145
4194
  wt,
4146
- // Keyboard
4195
+ At,
4147
4196
  xt,
4197
+ // Keyboard
4148
4198
  kt,
4149
- Rt,
4150
- Nt,
4199
+ Tt,
4151
4200
  $t,
4152
- // Structure
4153
4201
  Mt,
4154
- ta,
4155
- la,
4156
4202
  Ht,
4203
+ // Structure
4157
4204
  Dt,
4205
+ ia,
4206
+ ua,
4158
4207
  Ot,
4159
- Ft,
4160
4208
  Bt,
4209
+ Ft,
4161
4210
  Wt,
4162
4211
  _t,
4163
4212
  Pt,
4164
4213
  jt,
4165
4214
  Vt,
4215
+ zt,
4166
4216
  Ut,
4167
- Gt,
4168
4217
  Yt,
4218
+ Xt,
4219
+ Jt,
4169
4220
  // ARIA
4170
- ca,
4171
- ua,
4172
4221
  da,
4222
+ ma,
4173
4223
  ha,
4174
- va,
4175
- Aa,
4224
+ ga,
4225
+ wa,
4176
4226
  Sa,
4177
- ka,
4178
- Ea,
4179
- Ca,
4227
+ Ia,
4228
+ Ta,
4180
4229
  La,
4181
4230
  qa,
4182
4231
  Ra,
@@ -4186,42 +4235,44 @@ const vi = {
4186
4235
  Ha,
4187
4236
  Da,
4188
4237
  Oa,
4189
- Wa,
4190
- ga,
4191
- _a,
4192
- // Links
4238
+ Ba,
4239
+ Fa,
4240
+ Pa,
4241
+ fa,
4193
4242
  ja,
4194
- Va,
4195
- Ja,
4243
+ // Links
4244
+ za,
4245
+ Ua,
4246
+ Za,
4196
4247
  // Language
4197
- Qa,
4198
- ai,
4199
- ii,
4248
+ ei,
4200
4249
  ni,
4201
- // Tables
4202
4250
  ri,
4203
4251
  oi,
4252
+ // Tables
4204
4253
  si,
4205
4254
  li,
4206
4255
  ci,
4207
- // Parsing
4208
4256
  ui,
4209
- // Media
4210
4257
  di,
4258
+ // Parsing
4211
4259
  mi,
4260
+ // Media
4261
+ hi,
4262
+ pi,
4212
4263
  // Color
4213
- vi
4264
+ Si
4214
4265
  ];
4215
- let U = [], ge = /* @__PURE__ */ new Set();
4216
- function xi(t) {
4217
- t.additionalRules && (U = t.additionalRules), t.disabledRules && (ge = new Set(t.disabledRules));
4266
+ let G = [], be = /* @__PURE__ */ new Set();
4267
+ function Ei(t) {
4268
+ t.additionalRules && (G = t.additionalRules), t.disabledRules && (be = new Set(t.disabledRules));
4218
4269
  }
4219
- function be() {
4220
- return pe.filter((a) => !ge.has(a.id)).concat(U);
4270
+ function fe() {
4271
+ return ge.filter((a) => !be.has(a.id)).concat(G);
4221
4272
  }
4222
- function Si(t) {
4223
- fe();
4224
- const a = be(), e = [];
4273
+ function Ci(t) {
4274
+ ve();
4275
+ const a = fe(), e = [];
4225
4276
  let i = 0;
4226
4277
  return {
4227
4278
  processChunk(n) {
@@ -4240,13 +4291,13 @@ function Si(t) {
4240
4291
  }
4241
4292
  };
4242
4293
  }
4243
- function fe() {
4244
- Se(), ve(), ye(), He(), Me(), Ie();
4294
+ function ve() {
4295
+ Ie(), we(), Ae(), Oe(), De(), Ee();
4245
4296
  }
4246
- function ki(t) {
4297
+ function Li(t) {
4247
4298
  var i;
4248
- fe();
4249
- const a = be(), e = [];
4299
+ ve();
4300
+ const a = fe(), e = [];
4250
4301
  for (const n of a)
4251
4302
  try {
4252
4303
  e.push(...n.run(t));
@@ -4259,32 +4310,32 @@ function ki(t) {
4259
4310
  ruleCount: a.length
4260
4311
  };
4261
4312
  }
4262
- const yi = new Map(pe.map((t) => [t.id, t]));
4263
- function Ii(t) {
4264
- const a = yi.get(t);
4265
- return a || U.find((e) => e.id === t);
4313
+ const ki = new Map(ge.map((t) => [t.id, t]));
4314
+ function qi(t) {
4315
+ const a = ki.get(t);
4316
+ return a || G.find((e) => e.id === t);
4266
4317
  }
4267
4318
  export {
4268
- fe as clearAllCaches,
4269
- Me as clearAriaAttrAuditCache,
4270
- Se as clearAriaHiddenCache,
4271
- He as clearColorCaches,
4272
- ve as clearComputedRoleCache,
4319
+ ve as clearAllCaches,
4320
+ De as clearAriaAttrAuditCache,
4321
+ Ie as clearAriaHiddenCache,
4322
+ Oe as clearColorCaches,
4323
+ we as clearComputedRoleCache,
4273
4324
  k as compileDeclarativeRule,
4274
- xi as configureRules,
4275
- Si as createChunkedAudit,
4325
+ Ei as configureRules,
4326
+ Ci as createChunkedAudit,
4276
4327
  v as getAccessibleName,
4277
- w as getAccessibleTextContent,
4278
- be as getActiveRules,
4279
- L as getComputedRole,
4280
- u as getHtmlSnippet,
4281
- ue as getImplicitRole,
4282
- Ii as getRuleById,
4328
+ A as getAccessibleTextContent,
4329
+ fe as getActiveRules,
4330
+ q as getComputedRole,
4331
+ d as getHtmlSnippet,
4332
+ de as getImplicitRole,
4333
+ qi as getRuleById,
4283
4334
  m as getSelector,
4284
- p as isAriaHidden,
4285
- xe as isValidRole,
4286
- wi as querySelectorShadowAware,
4287
- pe as rules,
4288
- ki as runAudit,
4289
- Ai as validateDeclarativeRule
4335
+ g as isAriaHidden,
4336
+ ke as isValidRole,
4337
+ Ii as querySelectorShadowAware,
4338
+ ge as rules,
4339
+ Li as runAudit,
4340
+ Ti as validateDeclarativeRule
4290
4341
  };