@webability/core 1.19.0 → 1.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dom.cjs +22 -20
- package/dist/dom.d.cts +1 -1
- package/dist/dom.d.ts +1 -1
- package/dist/dom.js +22 -20
- package/dist/engine.cjs +8 -6
- package/dist/engine.d.cts +1 -1
- package/dist/engine.d.ts +1 -1
- package/dist/engine.js +8 -6
- package/dist/index.cjs +13 -11
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -11
- package/dist/playwright.cjs +3 -1
- package/dist/playwright.d.cts +1 -1
- package/dist/playwright.d.ts +1 -1
- package/dist/playwright.js +3 -1
- package/dist/{types-BoA8VqsC.d.cts → types-B_q8lTmv.d.cts} +5 -0
- package/dist/{types-BoA8VqsC.d.ts → types-B_q8lTmv.d.ts} +5 -0
- package/package.json +1 -1
package/dist/playwright.cjs
CHANGED
|
@@ -829,6 +829,8 @@ impact: moderate
|
|
|
829
829
|
evidence: heading
|
|
830
830
|
where: linkTitle=false
|
|
831
831
|
vision: false
|
|
832
|
+
status: below-bar
|
|
833
|
+
note: Opt-in (Sid, 2026-11-11). Live sweep 2026-11-10/11 (16 control sites, alibaba/qwen3.8-flash, 3 runs): new weak_heading findings on 5 sites, mostly false positives (slogans, sr-only headings, card titles). Runs only when named in \`aspects\` or \`judge.rubrics\`.
|
|
832
834
|
---
|
|
833
835
|
## Aspect
|
|
834
836
|
A heading must describe the topic or purpose of the content it introduces (WCAG 2.4.6 Headings and Labels).
|
|
@@ -1015,7 +1017,7 @@ Rules:
|
|
|
1015
1017
|
Respond with ONLY a JSON array, one object per item, same ids:
|
|
1016
1018
|
[{"id": "...", "verdict": "pass" | "violation", "reason": "one sentence", "fix": {"attribute": "...", "value": "..."}}]
|
|
1017
1019
|
Omit "fix" for passes.`;Ln=f=>Math.round(f*100)/100;iO=[1,.6,.35];});var kb={};pr(kb,{dismissModals:()=>cO});async function cO(f){await f.evaluate(d=>{for(let h of d){let m=document.querySelectorAll(h);for(let p of m)if(p.offsetParent!==null){p.click();return}}},uO),await new Promise(d=>setTimeout(d,500));}var uO,Cb=Fe(()=>{uO=['[class*="cookie"] button[class*="accept"]','[class*="cookie"] button[class*="agree"]','[class*="consent"] button[class*="accept"]','[class*="consent"] button[class*="agree"]','[id*="cookie"] button','[id*="consent"] button',".cc-dismiss",".cc-allow",".cc-btn",'[class*="gdpr"] button[class*="accept"]','[aria-label*="cookie" i] button','[aria-label*="consent" i] button','button[class*="close-banner"]','[class*="popup"] [class*="close"]','[class*="overlay"] [class*="close"]','[class*="modal"] [class*="close"]','[class*="notification"] [class*="close"]','button[aria-label="Close"]','button[aria-label="Dismiss"]'];});var ns={};pr(ns,{focusOnlyObscuredIndexes:()=>hO,resetInteractionState:()=>dO,restoreInteractionState:()=>pO,snapshotInteractionState:()=>fO});async function dO(f){try{await f.evaluate(()=>{try{document.activeElement?.blur?.();}catch{}try{window.scrollTo({left:0,top:0,behavior:"instant"});}catch{}});}catch{}}async function fO(f){try{await f.evaluate(()=>{let d=window;d.__waCallerState={el:document.activeElement,x:window.scrollX,y:window.scrollY};});}catch{}}async function pO(f){try{await f.evaluate(()=>{let d=window,h=d.__waCallerState;if(delete d.__waCallerState,!h)return;let m=h.el;if(m&&m!==document.body&&m!==document.documentElement&&m.isConnected)try{m.focus({preventScroll:!0});}catch{}try{window.scrollTo({left:h.x,top:h.y,behavior:"instant"});}catch{}});}catch{}}function mO(f){if(typeof f=="string")return f;if(!Array.isArray(f))return null;let d=f.flat(1/0).filter(h=>typeof h=="string");return d.length===1?d[0]:null}async function hO(f,d){let h=d.map(_=>{let E=[..._.any??[],..._.none??[]].flatMap(A=>A.relatedNodes??[]);if(!E.length)return null;let C=E.map(A=>mO(A.target));return C.every(A=>!!A)?C:null}),m=Array.from(new Set(h.flatMap(_=>_??[])));if(!m.length)return new Set;let p={};try{p=await f.evaluate(({sels:_,own:w})=>{let E=A=>{let y=A.getBoundingClientRect(),x=getComputedStyle(A);return !!((y.width<=1||y.height<=1)&&(x.overflow==="hidden"||x.position==="absolute"||x.position==="fixed")||/^rect\(\s*0(px)?[\s,]+0(px)?[\s,]+0(px)?[\s,]+0(px)?\s*\)$/.test(x.clip||"")||/inset\(\s*50%/.test(x.clipPath||""))},C={};for(let A of _){let y=null;try{y=document.querySelector(A);}catch{y=null;}if(!y){C[A]=!1;continue}let x=y.closest(w);if(x&&x!==document.body&&x!==document.documentElement){C[A]=!0;continue}if(y===document.activeElement){try{y.blur();}catch{}C[A]=E(y);continue}C[A]=E(y);}return C},{sels:m,own:ua});}catch{return new Set}let v=new Set;return h.forEach((_,w)=>{_&&_.length&&_.every(E=>p[E]===true)&&v.add(w);}),v}var as=Fe(()=>{xr();});var On={};pr(On,{dedupeByElementIdentity:()=>wO,deduplicateIssues:()=>gO});function gO(f){let d=new Map,h=[...f].sort((m,p)=>{let v={webability:0,"axe-core":1,"deep-analysis":2},_=v[m.source]??3,w=v[p.source]??3;return _-w});for(let m of h){let p=vO(m);d.has(p)?!d.get(p).fix?.suggestedValue&&m.fix?.suggestedValue&&d.set(p,m):d.set(p,m);}return Array.from(d.values())}function vO(f){let d=f.selector.replace(/:focus-visible$/,"").replace(/:focus$/,"").replace(/\[data-[^\]]+\]/g,"").trim(),h=f.wcag||"";return d&&h?`${d}::${h}`:`${f.type}::${d||f.id}`}async function wO(f,d){if(d.length<2)return d;let h=Array.from(new Set(d.map(A=>A.selector).filter(Boolean))),m;try{m=await f.evaluate(A=>{let y=Array.from(document.querySelectorAll("*")),x=new Map;y.forEach((F,O)=>x.set(F,O));let D={};for(let F of A){let O=null;try{O=document.querySelector(F);}catch{}if(!O){let H=F.replace(/:(?:focus-visible|focus-within|focus|hover|active)$/,"");if(H!==F)try{O=document.querySelector(H);}catch{}}if(O){let H=O.closest("table");D[F]={el:x.get(O),table:H?x.get(H):-1,doc:O===document.documentElement||O===document.body};}}return D},h);}catch{return d}let p={webability:0,"axe-core":1,"deep-analysis":2},v=A=>{let y=m[A.selector];if(!y)return null;let x=A.wcag||A.type;return y.doc?{key:yO.has(A.wcag||"")?`doc::${x}`:`doc::${x}::${A.type}`,owner:true}:y.table>=0&&bO.test(A.type)?{key:`${y.table}::${x}::table-headers`,owner:y.el===y.table}:is.has(A.type)?{key:`${y.el}::accessible-name`,owner:true}:{key:`${y.el}::${x}`,owner:true}},_=[...d].sort((A,y)=>{let x=v(A),D=v(y),F=x?.owner?0:1,O=D?.owner?0:1,H=is.has(A.type)&&is.has(y.type),R=H&&A.confidence==="needs_review"?1:0,$=H&&y.confidence==="needs_review"?1:0,I=H?Tb(A.type)-Tb(y.type):0;return F-O||R-$||(p[A.source]??3)-(p[y.source]??3)||I}),w=new Map,E=[];for(let A of _){let y=v(A);if(!y){E.push(A);continue}let x=w.get(y.key);x?!is.has(x.type)&&!x.fix?.suggestedValue&&A.fix?.suggestedValue&&(v(x)?.owner??true)===y.owner&&w.set(y.key,A):w.set(y.key,A);}let C=new Set([...w.values(),...E]);return d.filter(A=>C.has(A))}var bO,yO,is,Sb,Tb,Nn=Fe(()=>{bO=/^missing_table_header$|^td-has-header$|^th-has-data-cells$|^h43|^h63/,yO=new Set(["2.4.1","3.1.1","2.4.2"]),is=new Set(["missing_label","label","select-name","aria-input-field-name","empty_link","link-name","missing_alt","image-alt","background_image_unlabeled","unlabeled_button","button-name","input-button-name","svg_missing_name","svg-img-alt","role-img-alt"]),Sb=["background_image_unlabeled","unlabeled_button","missing_label","empty_link","missing_alt","svg_missing_name"],Tb=f=>{let d=Sb.indexOf(f);return d<0?Sb.length:d};});var Ib={};pr(Ib,{parseGif:()=>Rb,playsOverFiveSeconds:()=>Fb,verifyAnimatedGifs:()=>xO});function Rb(f){if(String.fromCharCode(f[0]??0,f[1]??0,f[2]??0)!=="GIF")return null;let h=13,m=f[10]??0;m&128&&(h+=3*(1<<(m&7)+1));let p=0,v=0,_=0,w=null,E=()=>{for(;h<f.length;){let C=f[h++];if(C===0)return;h+=C;}};for(;h<f.length;){let C=f[h++];if(C===59)break;if(C===33){let A=f[h++];if(A===249)_=(f[h+2]??0)|(f[h+3]??0)<<8,h+=1+(f[h]??4),E();else if(A===255){let y=f[h]??0,x=String.fromCharCode(...Array.from(f.subarray(h+1,h+1+y)));h+=1+y,(x==="NETSCAPE2.0"||x==="ANIMEXTS1.0")&&f[h]===3&&f[h+1]===1&&(w=(f[h+2]??0)|(f[h+3]??0)<<8),E();}else E();}else if(C===44){let A=f[h+8]??0;h+=9,A&128&&(h+=3*(1<<(A&7)+1)),h+=1,E(),p++,v+=_<2?10:_,_=0;}else break}return {frames:p,seconds:v/100,loops:w}}function Fb(f){if(f.frames<2)return false;if(f.loops===0)return true;let d=f.loops===null?1:f.loops+1;return f.seconds*d>5}async function xO(f,d){let h=d.filter(v=>v.type==="animated_gif_no_pause");if(!h.length)return d;let m=Array.from(new Set(h.map(v=>v.selector))),p={};try{p=await f.evaluate(async({sels:v,parserSrc:_})=>{let w=new Function("var __name = function (f) { return f }; return ("+_+")")(),E={};return await Promise.all(v.map(async C=>{E[C]=null;try{let A=document.querySelector(C),y=A&&(A.currentSrc||A.src);if(!y)return;let x=new AbortController,D=setTimeout(()=>x.abort(),5e3);try{let F=await fetch(y,{signal:x.signal,credentials:"same-origin"});if(!F.ok||Number(F.headers.get("content-length")||"0")>2e7)return;E[C]=w(new Uint8Array(await F.arrayBuffer()));}finally{clearTimeout(D);}}catch{}})),E},{sels:m,parserSrc:Rb.toString()});}catch{p={};}return d.flatMap(v=>{if(v.type!=="animated_gif_no_pause")return [v];let _=p[v.selector];if(!_)return [{...v,message:`${v.message} \u2014 the GIF file could not be read from the page (cross-origin or blocked), so its frame count and duration were not measured`}];if(!Fb(_))return [];let w=_.loops===0?"loops forever":`plays for ${(_.seconds*(_.loops===null?1:_.loops+1)).toFixed(1)}s`;return [{...v,message:`animated GIF (${_.frames} frames, ${w}) starts automatically with no pause control \u2014 replace it with a video that has controls or a static image, or add a pause button (WCAG 2.2.2)`}]})}var Mb=Fe(()=>{});var gi={};pr(gi,{scopeIssuesToRoot:()=>AO});async function AO(f,d,h){let m=Array.from(new Set(d.map(v=>v.selector).filter(Boolean))),p;try{p=await f.evaluate(({rootSel:v,sels:_})=>{let w=A=>{try{let x=document.querySelector(A);if(x)return x}catch{}let y=A.replace(/:(?:focus-visible|focus-within|focus|hover|active)$/,"");if(y!==A)try{return document.querySelector(y)}catch{return null}return null},E=null;try{E=document.querySelector(v);}catch{return {invalid:!0,matched:!1,within:{}}}if(!E)return {invalid:!1,matched:!1,within:{}};let C={};for(let A of _){let y=w(A);C[A]=y?y===E||E.contains(y):!0;}return {invalid:!1,matched:!0,within:C}},{rootSel:h,sels:m});}catch{return {issues:d,warning:`scope:evaluate-failed (${h}) \u2014 results unfiltered`}}return p.invalid?{issues:d,warning:`scope:invalid-selector (${h}) \u2014 results unfiltered`}:p.matched?{issues:d.filter(v=>v.selector?p.within[v.selector]===true:true)}:{issues:[],warning:`scope:root-miss (${h} matched nothing \u2014 empty result)`}}var vi=Fe(()=>{});function DO(f){let{kinds:d,max:h,caps:m,own:p}=f,v=globalThis,_=new Set(d),w={},E={},C=(P,z)=>{let Y=(P||"").replace(/\s+/g," ").trim();return Y.length>z?Y.slice(0,z-1)+"\u2026":Y},A=P=>{try{if(P.closest(p)||typeof v.isWidget=="function"&&v.isWidget(P))return !0}catch{}return false},y=P=>{if(P===document.documentElement)return "html";try{if(typeof v.uniqueSel=="function")return v.uniqueSel(P)}catch{}let z=[];for(let Y=P;Y&&Y!==document.documentElement;Y=Y.parentElement){let K=Y.parentElement,J=K?Array.from(K.children).filter(ie=>ie.tagName===Y.tagName):[];z.unshift(Y.tagName.toLowerCase()+(J.length>1?`:nth-of-type(${J.indexOf(Y)+1})`:""));}return z.join(" > ")},x=window.scrollX||0,D=window.scrollY||0,F=P=>{let z=P.getBoundingClientRect();return {x:z.left+x,y:z.top+D,w:z.width,h:z.height}},O=P=>C(P.outerHTML||"",300),H=P=>getComputedStyle(P),R=P=>!!P.closest('[aria-hidden="true"]'),$=P=>{if(P.closest?.("[hidden]"))return false;let z=P;if(typeof z.checkVisibility=="function")return z.checkVisibility({visibilityProperty:true});let Y=H(P);return Y.display!=="none"&&Y.visibility!=="hidden"},I=P=>{if(!$(P))return false;let z=F(P);return z.w>1&&z.h>1&&z.x+z.w>0&&z.y+z.h>0},B=P=>{let z=H(P),Y=P.getBoundingClientRect();return /inset\(\s*(50|100)%/.test(z.clipPath||"")||/rect\(\s*0(px)?[\s,]+0(px)?[\s,]+0(px)?[\s,]+0(px)?\s*\)/.test(z.clip||"")?true:(Y.width<=1||Y.height<=1)&&z.overflow==="hidden"},ee=P=>{let z=Qe=>parseFloat(Qe||"0")||0,Y=(Qe,We)=>{if(We.display==="none"||We.visibility==="hidden"||parseFloat(We.opacity||"1")===0||z(We.fontSize)===0||B(Qe))return true;if(We.position==="absolute"||We.position==="fixed"){let Mt=Qe.getBoundingClientRect();if(z(We.left)<=-999||z(We.top)<=-999||Mt.right<=0||Mt.bottom<=-(window.scrollY||0))return true}return false},K=[],J=document.createTreeWalker(P,NodeFilter.SHOW_TEXT);for(let Qe=J.nextNode();Qe;Qe=J.nextNode()){let We=Qe.parentElement,Mt=(Qe.textContent||"").replace(/\s+/g," ").trim();if(!We||!Mt||!/[\p{L}\p{N}]/u.test(Mt))continue;let qn=false,dt=false;for(let Zt=We;Zt;Zt=Zt===P?null:Zt.parentElement)if(Zt.tagName==="KBD"&&(dt=true),/^(NOSCRIPT|SCRIPT|STYLE|TEMPLATE)$/.test(Zt.tagName)||Y(Zt,H(Zt))){qn=true;break}qn||K.push({text:Mt,raw:Qe.textContent||"",kbd:dt,p:We});}let ie=0,be=K.length;for(;ie<be&&K[ie].kbd;)ie++;for(;be>ie&&K[be-1].kbd;)be--;let Pe=ie<be?K.slice(ie,be):K,Re="h1, h2, h3, h4, h5, h6, [role=heading]",pe=Pe.map(Qe=>{let We=H(Qe.p);return {size:z(We.fontSize),weight:parseInt(We.fontWeight||"400",10)||400,head:!!Qe.p.closest(Re)&&P.contains(Qe.p.closest(Re))}}),Be=Qe=>{for(let We=Qe;We&&We!==P;We=We.parentElement)if(!/^inline(?!-block)|^contents$/.test(H(We).display||""))return We;return P},at=Pe.map(Qe=>Be(Qe.p)),ze=pe.map(Qe=>Qe.size).filter(Qe=>Qe>0),ft=ze.length?Math.max(...ze):0,It=ze.length?Math.min(...ze):0,Se=pe.length?Math.min(...pe.map(Qe=>Qe.weight)):400,At=0;pe.forEach(Qe=>{!Qe.head&&Qe.weight<600&&Qe.size>At&&(At=Qe.size);});let _t=Qe=>Pe.some((We,Mt)=>at[Mt]===at[Qe]&&pe[Mt].weight<600&&!pe[Mt].head),Ct=Pe.map((Qe,We)=>pe[We].head||ft>It&&pe[We].size>=ft||pe[We].weight>=600&&Se<600&&pe[We].size>=At&&!_t(We)),Pt=Ct.every(Boolean);return Pe.map((Qe,We)=>({text:Qe.text,raw:Qe.raw,block:at[We],prominent:!Pt&&Ct[We]}))},N=P=>{for(let z=P.parentElement;z;z=z.parentElement){let Y=(z.getAttribute("role")||"").trim().toLowerCase();if(/^(banner|contentinfo|navigation|main|complementary)$/.test(Y))return Y;let K=z.tagName;if(K==="MAIN")return "main";if(K==="NAV")return "navigation";if(K==="ASIDE")return "complementary";if(K==="HEADER"||K==="FOOTER"){if(z.parentElement?.closest("article, aside, main, nav, section"))continue;return K==="HEADER"?"banner":"contentinfo"}}return ""},T=(P,z)=>{if(!z||z.tagName!=="A")return false;let Y=(z.getAttribute("href")||"").trim(),K=/^\/(index\.\w+)?([?#].*)?$/.test(Y);if(!K)try{let ie=new URL(Y,location.href);K=ie.origin===location.origin&&/^\/(index\.\w+)?$/.test(ie.pathname);}catch{}return K?!z.innerText.replace(/\s+/g,"")&&z.querySelectorAll("img, svg, [role=img]").length>=1&&z.contains(P):false},S=P=>(P||"").split(/\s+/).filter(Boolean).map(z=>document.getElementById(z)).filter(Boolean).map(z=>C(z.textContent||"",200)).join(" ").trim(),M=P=>{let z="";for(let Y of Array.from(P.childNodes))if(Y.nodeType===3)z+=Y.textContent;else if(Y.nodeType===1){let K=Y;if(/^(script|style|template)$/i.test(K.tagName))continue;K.tagName==="IMG"?z+=" "+(K.getAttribute("alt")||"")+" ":z+=" "+M(K)+" ";}return z},q=P=>{let z=S(P.getAttribute("aria-labelledby"));if(z)return z;let Y=(P.getAttribute("aria-label")||"").trim();if(Y)return Y;let K=P.tagName.toLowerCase();if(K==="img"||K==="area"||K==="input"&&P.type==="image"){let J=P.getAttribute("alt");if(J!==null)return J.trim()}if(/^(input|select|textarea)$/.test(K)){let ie=Array.from(P.labels||[]).map(be=>C(be.textContent||"",120)).join(" ").trim();if(ie)return ie}if(K==="svg"){let J=P.querySelector(":scope > title");if(J&&(J.textContent||"").trim())return C(J.textContent||"",120)}if(K==="object")return (P.getAttribute("title")||"").trim();if(P.matches("a, button, [role=link], [role=button], [role=heading], h1, h2, h3, h4, h5, h6, summary, [role=menuitem], [role=tab], [role=option]")){let J=C(M(P),200);if(J)return J}return (P.getAttribute("title")||"").trim()},j=P=>(P.getAttribute("role")||"").trim().toLowerCase().split(/\s+/)[0]||"",W=(P,z)=>{let Y=P.parentElement?.closest("p, li, figure, td, th, dd, blockquote, section, article, div, body");return Y?C(Y.innerText||Y.textContent||"",z):""},Z=P=>{let z=P.previousElementSibling;return z?C(z.innerText||z.textContent||"",160):""},ne=(P,z)=>{let Y=w[P]||=[];Y.length<(m[P]??h)?Y.push(z):E[P]=(E[P]||0)+1;};if(_.has("image")){let P=new Set,z=Array.from(document.querySelectorAll("img, svg, canvas, input[type=image], object, embed, [role=img]")).filter(pe=>!(pe.tagName.toLowerCase()==="svg"&&pe.parentElement?.closest("svg"))),Y=[],K=document.body?Array.from(document.body.querySelectorAll("*")).slice(0,3e3):[];for(let pe of K)/url\(/i.test(H(pe).backgroundImage||"")&&!z.includes(pe)&&Y.push(pe);let J=[],ie=new Map;for(let pe of [...z,...Y]){if(P.has(pe)||A(pe))continue;P.add(pe);let Be=pe.tagName.toLowerCase(),at=j(pe),ze=Y.includes(pe),ft=q(pe),It=R(pe),Se=at==="none"||at==="presentation",At=$(pe)&&!It&&!Se;Be==="img"&&pe.getAttribute("alt")===""&&!pe.getAttribute("aria-label")&&!pe.getAttribute("aria-labelledby")&&!pe.getAttribute("title")&&(At=false),(Be==="svg"||Be==="canvas"||ze)&&at!=="img"&&!ft&&(At=false),ze&&at!=="img"&&(At=false);let _t=true;if(Be==="img"){let Mt=pe;_t=!(Mt.complete&&(Mt.naturalWidth===0||Mt.naturalWidth<=1&&Mt.naturalHeight<=1));}let Ct=pe.parentElement?.closest("a[href], button, [role=button], [role=link]")||null,Pt=!!Ct&&!!((Ct.getAttribute("aria-label")||"").trim()||Ct.getAttribute("aria-labelledby")),Qe=ze?(H(pe).backgroundImage.match(/url\(["']?([^"')]+)/)||[])[1]||"":pe.currentSrc||pe.getAttribute("src")||pe.getAttribute("data")||pe.querySelector("image")?.getAttribute("href")||"",We={selector:y(pe),html:O(pe),rect:F(pe),tag:Be,role:at,name:ft,alt:pe.getAttribute("alt"),ariaHidden:It,inTree:At,hasName:!!ft,rendered:I(pe)&&_t,cssBackground:ze,svgText:Be==="svg"&&!!pe.querySelector("text"),ownText:ze?C(ee(pe).map(Mt=>Mt.text).join(" "),160):"",src:/^data:/i.test(Qe)?Qe.slice(0,60):C(Qe,200),insideNamedControl:Pt,controlName:Ct?C(q(Ct),120):"",landmark:N(pe),homeLink:T(pe,Ct),nearbyText:C([Z(pe),W(pe,200)].filter(Boolean).join(" | "),260)};J.push(We),ie.set(We,pe);}J.sort((pe,Be)=>+!!Be.rendered-+!!pe.rendered);let be=window.scrollX,Pe=window.scrollY;for(let pe of J.slice(0,m.image??h)){if(pe.covered=false,!pe.rendered)continue;let Be=ie.get(pe);if(Be)try{Be.scrollIntoView({block:"center",inline:"center"});let at=Be.getBoundingClientRect(),ze=document.elementFromPoint(at.left+at.width/2,at.top+at.height/2);pe.covered=!!ze&&ze!==Be&&!Be.contains(ze)&&!ze.contains(Be)&&!(Be.tagName.toLowerCase()==="svg"&&Be.contains(ze));}catch{}}window.scrollTo(be,Pe);let Re=m.image??h;J.forEach((pe,Be)=>{Be<Re?ne("image",pe):pe.rendered&&!pe.svgText&&(E.image=(E.image||0)+1);});}if(_.has("link"))for(let P of Array.from(document.querySelectorAll("a[href], area[href], [role=link]"))){if(A(P))continue;let z=j(P);if(z&&z!=="link"||!$(P)||R(P))continue;let Y=q(P);if(!Y)continue;let K=[];for(let Be=P.closest("li");Be;Be=Be.parentElement?.closest("li")||null){let at="";for(let ze of Array.from(Be.childNodes))(ze.nodeType===3||ze.nodeType===1&&!/^(ul|ol)$/i.test(ze.tagName))&&(at+=" "+(ze.innerText??ze.textContent??""));K.push(C(at,160));}let J=P.closest("td, th"),ie=[];if(J){let Be=J.parentElement,at=J.closest("table"),ze=Array.from(Be?.children||[]).indexOf(J);for(let ft of (J.getAttribute("headers")||"").split(/\s+/).filter(Boolean)){let It=document.getElementById(ft);It&&ie.push(C(It.textContent||"",80));}if(at&&ze>=0){for(let It of Array.from(at.querySelectorAll("tr"))){let Se=It.children[ze];Se&&Se!==J&&Se.tagName==="TH"&&ie.push(C(Se.textContent||"",80));let At=It.children[0];It===Be&&At&&At!==J&&At.tagName==="TH"&&ie.push(C(At.textContent||"",80));}let ft=at.querySelector("tr > th[colspan]");ft&&ft!==J&&!ie.length&&ie.push(C(ft.textContent||"",80));}}let be=P.closest("p"),Pe=be||K.length||J?null:P.parentElement,Re=P.getAttribute("href")||"",pe=Re.startsWith("#")&&Re.length>1?document.getElementById(decodeURIComponent(Re.slice(1))):null;ne("link",{selector:y(P),html:O(P),rect:F(P),name:C(Y,160),href:C(Re,200),describedBy:S(P.getAttribute("aria-describedby")),context:{paragraph:be?C(be.innerText||be.textContent||"",300):"",listItems:K,cell:J?C(J.innerText||"",160):"",headers:ie},siblingText:C([Z(P.closest("ul, ol, table, p")||P),Pe&&Pe!==document.body?Pe.innerText:""].filter(Boolean).join(" | "),240),target:pe?C(pe.innerText||pe.textContent||"",160):""});}let le=P=>{let z=P.tagName.match(/^H([1-6])$/);return z?Number(z[1]):j(P)==="heading"?Number(P.getAttribute("aria-level"))||2:0},fe=()=>Array.from(document.querySelectorAll("h1, h2, h3, h4, h5, h6, [role=heading]")).filter(P=>$(P)&&!R(P)&&!A(P));if(_.has("heading"))for(let P of fe()){let z=le(P),Y=C(q(P),160);if(!Y)continue;let K=(P.textContent||"").trim().length,J=document.body;for(let pe=P.parentElement;pe&&pe!==document.body;pe=pe.parentElement)if((pe.textContent||"").trim().length-K>=40){J=pe;break}let ie="",be=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);be.currentNode=P;for(let pe=be.nextNode();pe&&ie.length<400&&J.contains(pe);pe=be.nextNode()){let Be=pe.parentElement;if(!Be||P.contains(Be)||/^(script|style|noscript|template)$/i.test(Be.tagName)||R(Be)||!$(Be))continue;let at=Be.closest("h1, h2, h3, h4, h5, h6, [role=heading]");if(at&&at!==P&&le(at)<=z)break;at||(ie+=" "+(pe.textContent||""));}let Pe=Array.from(P.querySelectorAll("a[href]")),Re=Pe.length===1&&(Pe[0].textContent||"").replace(/\s+/g," ").trim()===(P.textContent||"").replace(/\s+/g," ").trim();ne("heading",{selector:y(P),html:O(P),rect:F(P),level:z,text:Y,visible:I(P)&&!B(P),section:C(ie,400),linkTitle:Re});}if(_.has("formField")){let P=Array.from(document.querySelectorAll("input, select, textarea, [role=textbox], [role=combobox], [role=searchbox], [role=spinbutton], [role=listbox]")).filter(K=>!/^(hidden|submit|button|reset|image)$/i.test(K.type||"")&&!A(K)),z=K=>C(Array.from(K.labels||[]).map(J=>J.textContent||"").join(" ")||S(K.getAttribute("aria-labelledby")),60),Y=fe();for(let K of P){let J=[...Array.from(K.labels||[])];for(let pe of (K.getAttribute("aria-labelledby")||"").split(/\s+/).filter(Boolean)){let Be=document.getElementById(pe);Be&&J.push(Be);}if(/^(none|presentation)$/.test(j(K)))continue;let ie=J.map(pe=>({text:C(pe.textContent||"",120),visible:I(pe)&&!B(pe),inTree:$(pe)&&!R(pe)})).filter(pe=>pe.visible);if(!ie.length)continue;let be=K.closest("fieldset")?.querySelector("legend"),Pe=Y.filter(pe=>pe.compareDocumentPosition(K)&Node.DOCUMENT_POSITION_FOLLOWING).pop(),Re=be||Pe||null;ne("formField",{selector:y(K),html:O(K),rect:F(K),type:K.type||K.tagName.toLowerCase(),role:j(K),nameAttr:K.getAttribute("name")||"",rendered:I(K),disabled:K.disabled===true,labels:ie,groupHeading:Re?{text:C(Re.textContent||"",100),visible:I(Re)}:null,otherLabels:P.filter(pe=>pe!==K).map(z).filter(Boolean).slice(0,10)});}}if(_.has("control")){let P="button, a[href], [role=button], [role=link], [role=checkbox], [role=menuitem], [role=menuitemcheckbox], [role=menuitemradio], [role=option], [role=radio], [role=switch], [role=tab], [role=treeitem], [role=gridcell]";for(let z of Array.from(document.querySelectorAll(P))){if(A(z)||!$(z)||R(z)||!z.hasAttribute("aria-label")&&!z.hasAttribute("aria-labelledby"))continue;let Y=ee(z),K=C(Y.map((ie,be)=>(be&&Y[be-1].block!==ie.block?" ":"")+ie.raw).join(""),200);if(!K)continue;let J=C(Y.filter(ie=>ie.prominent).map(ie=>ie.text).join(" "),200);ne("control",{selector:y(z),html:O(z),rect:F(z),role:j(z)||z.tagName.toLowerCase(),name:C(q(z),200),visibleText:K,titleText:J,fontFamily:C(H(z).fontFamily,80)});}}let me=P=>{let z=(P||"").trim().split("-")[0].toLowerCase();if(!/^[a-z]{2,3}$/.test(z))return false;try{let K=new Intl.DisplayNames(["en"],{type:"language"}).of(z);return !!K&&K.toLowerCase()!==z}catch{return z.length===2}},oe=P=>{let z="",Y=[],K=P===document.documentElement&&document.body||P;if(!K)return {text:z,names:Y};let J=document.createTreeWalker(K,NodeFilter.SHOW_TEXT);for(let ie=J.nextNode();ie&&z.length<600;ie=J.nextNode()){let be=ie.parentElement;!be||/^(script|style|title)$/i.test(be.tagName)||be.closest("[lang]")===P&&(!$(be)||R(be)||(z+=" "+(ie.textContent||"")));}for(let ie of Array.from(K.querySelectorAll("[alt], [aria-label], [aria-labelledby]"))){if(ie.closest("[lang]")!==P||R(ie))continue;let be=C(q(ie),120);if(be&&Y.push(be),Y.length>=8)break}return {text:C(z,600),names:Y}};if(_.has("page")&&document.documentElement.namespaceURI==="http://www.w3.org/1999/xhtml"){let P=document.documentElement,z=P.getAttribute("lang")||"",Y=oe(P);ne("page",{selector:"html",html:C(`<html lang="${z}"><title>${document.title}</title>`,300),title:C(document.title||"",200),hasTitle:!!(document.title||"").trim(),lang:z,hasLang:me(z)&&!!(Y.text||Y.names.length),headings:fe().slice(0,10).map(K=>`h${le(K)} ${C(q(K),80)}`),text:C(document.body?.innerText||"",500),ownText:Y.text,ownNames:Y.names});}if(_.has("langElement"))for(let P of Array.from(document.querySelectorAll("body [lang], body[lang]"))){if(A(P))continue;let z=P.getAttribute("lang")||"";if(!me(z))continue;let Y=oe(P);!Y.text&&!Y.names.length||ne("langElement",{selector:y(P),html:O(P),rect:F(P),lang:z,ownText:Y.text,ownNames:Y.names});}if(_.has("form"))for(let P of Array.from(document.querySelectorAll("form"))){if(A(P))continue;let Y=Array.from(P.querySelectorAll("input, select, textarea")).filter(J=>!/^(hidden|submit|button|reset|image)$/i.test(J.type||"")).slice(0,15).map(J=>{let ie=J;return {label:C(q(J),80),type:ie.type||J.tagName.toLowerCase(),value:C(ie.value||"",40),required:ie.required===true,ariaInvalid:J.getAttribute("aria-invalid")||"",valid:typeof ie.checkValidity=="function"?ie.checkValidity():true,describedBy:S(J.getAttribute("aria-describedby")||J.getAttribute("aria-errormessage"))}}),K=[];for(let J of Array.from(P.querySelectorAll("*")))if(!(/^(label|legend|button|option|script|style|input|select|textarea)$/i.test(J.tagName)||J.closest("label, legend, button")||!Array.from(J.childNodes).filter(be=>be.nodeType===3).map(be=>be.textContent||"").join(" ").trim())&&(K.push({text:C(J.textContent||"",200),visible:I(J),ariaHidden:R(J)}),K.length>=10))break;ne("form",{selector:y(P),html:O(P),rect:F(P),hasMessages:K.length>0,fields:Y,messages:K});}if(_.has("iframeGroup")){let P=[],z=(K,J,ie,be)=>{if(!(be>3)){for(let Pe of Array.from(K.querySelectorAll("*")))if(Pe.shadowRoot&&z(Pe.shadowRoot,"shadow",ie||Pe,be+1),Pe.tagName==="IFRAME"){P.push({el:Pe,scope:J,host:ie||Pe});try{let Re=Pe.contentDocument;Re&&z(Re,"nested-frame",ie||Pe,be+1);}catch{}}}};z(document,"top",null,0);let Y=new Map;for(let K of P){if(A(K.host)||!$(K.el)||R(K.el))continue;let J=C(q(K.el),120).toLowerCase();J&&(Y.get(J)||Y.set(J,[]).get(J)).push(K);}for(let[K,J]of Y)J.length<2||ne("iframeGroup",{selector:y(J[0].host),html:O(J[0].el),rect:F(J[0].host),name:K,frames:J.slice(0,6).map(ie=>{let be="",Pe="";try{let Re=ie.el.contentDocument;be=C(Re?.title||"",100),Pe=C(Re?.body?.innerText||Re?.body?.textContent||"",300);}catch{}return {selector:y(ie.el),scope:ie.scope,src:C(ie.el.getAttribute("src")||(ie.el.hasAttribute("srcdoc")?"srcdoc":""),200),docTitle:be,text:Pe,inTree:$(ie.el)&&!R(ie.el)}})});}if(_.has("textBlocks")){let P=[];for(let J of fe().slice(0,12))P.push(`heading h${le(J)}: ${C(q(J),60)}`);let z=Array.from(document.querySelectorAll("nav, main, aside, header, footer, [role=navigation], [role=main], [role=complementary], [role=banner], [role=contentinfo], [role=region], [role=search]")).filter(J=>$(J));for(let J of z.slice(0,10))P.push(`landmark ${j(J)||J.tagName.toLowerCase()}${J.getAttribute("aria-label")||J.getAttribute("aria-labelledby")?` named "${C(q(J)||S(J.getAttribute("aria-labelledby")),40)}"`:" (unnamed)"}`);for(let J of Array.from(document.querySelectorAll("button, a[href], [role=button]")).filter(ie=>$(ie)).slice(0,15))P.push(`${J.tagName.toLowerCase()==="a"?"link":"button"}: ${C(q(J),50)}`);for(let J of Array.from(document.querySelectorAll("iframe")).slice(0,4)){let ie="";try{let be=J.contentDocument;ie=be?Array.from(be.querySelectorAll("h1, h2, h3, h4, h5, h6")).map(Pe=>C(Pe.textContent||"",40)).join("; "):"";}catch{}P.push(`iframe title "${C(J.getAttribute("title")||"",40)}" headings inside: ${ie||"none"}`);}let Y=P.join(`
|
|
1018
|
-
`),K=Array.from(document.querySelectorAll("p, li, td, th, dd, dt, label, figcaption, blockquote, caption, div, span")).filter(J=>!A(J)&&Array.from(J.childNodes).some(ie=>ie.nodeType===3&&(ie.textContent||"").trim().length>2));for(let J of K){if(J.parentElement&&K.includes(J.parentElement))continue;let ie=I(J)&&!B(J);!$(J)||!ie&&R(J)||ne("textBlocks",{selector:y(J),html:O(J),rect:F(J),text:C(J.textContent||"",220),visible:ie,ariaHidden:R(J),outline:Y});}}return {...w,cut:E}}async function Ob(f,d,h=Pb){if(!d.length)return {};try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");}catch{}try{return await f.evaluate(DO,{kinds:d,max:h,caps:{...Lb,...h<Pb?Object.fromEntries(Object.keys(Lb).map(m=>[m,h])):{}},own:ua})}catch{return {}}}var Pb,_O,Lb,Nb=Fe(()=>{xr();Pb=40,_O=400,Lb={control:_O};});function qb(f){let d=f;for(let h="";h!==d;)h=d,d=d.replace(kO," ");return d=d.toLowerCase().normalize("NFKD").replace(EO," ").trim(),d?d.split(/\s+/):[]}function CO(f){let d=qb(f);return d.length===1&&[...d[0].replace(/\p{M}/gu,"")].length===1&&/^\p{L}/u.test(d[0])?[]:d}function Bb(f,d){let h=CO(f);if(!h.length)return true;let m=qb(d);for(let p=0;p+h.length<=m.length;p++){let v=true;for(let _=0;_<h.length&&v;_++)v=m[p+_]===h[_];if(v)return true}return false}var EO,kO,Hb=Fe(()=>{EO=/[^\p{L}\p{N}\p{M}]+/gu,kO=/\([^()]*\)/g;});var jb={};pr(jb,{RUBRIC_BATCH_SIZE:()=>Vb,parseRubricVerdicts:()=>pi,rubricPromptHash:()=>mi,rubricSystemPrompt:()=>fa,rubricTransport:()=>$b,runRubrics:()=>MO});function $b(f){return f.transport?f.transport:f.apiKey?cc({apiKey:f.apiKey,baseUrl:f.baseUrl,visionModel:f.visionModel,textModel:f.textModel}):f.apiUrl?dc({apiUrl:f.apiUrl,token:f.apiToken,internalSecret:f.internalSecret}):null}function RO(f,d){if(f.evidence==="control"){let h=d;if(h.visibleText.trim()&&Bb(h.visibleText,h.name))return {aspect:f.id,selector:h.selector,verdict:"passed",reason:"the ACT label-in-name algorithm finds the visible label in the accessible name",by:"rule"}}return null}function IO(f){let{selector:d,html:h,rect:m,outline:p,...v}=f;return v}async function MO(f,d){let h={findings:[],verdicts:[],inapplicable:[],undecided:0,undecidedWcag:[],calls:0,errors:[]},m=$b(d.judge);if(!m)return h;let p=d.level??d.judge.level??"AA",v=db.filter(R=>(d.aspects?d.aspects.includes(R.id):R.status!=="below-bar")&&Qr([{wcag:R.sc.join(","),level:R.level}],p).length>0);if(!v.length)return h;let _=Date.now()+(d.timeoutMs??d.judge.timeoutMs??SO),w=d.warnings??[];await ju(f,w);let E=[...new Set(v.map(R=>R.evidence))],C=globalThis.process?.env?.WA_STRICT_STATE==="1",A=await Vu(f,"rubric-evidence",w,()=>Ob(f,E),{strict:C,bugs:d.bugs});if(d.rootSelector){let{scopeIssuesToRoot:R}=await Promise.resolve().then(()=>(vi(),gi));for(let $ of E){let I=A[$]||[];if(!I.length)continue;let B=new Set((await R(f,I,d.rootSelector)).issues);A[$]=I.filter(ee=>B.has(ee));}}let y=d.judge.vision!==false&&typeof f.screenshot=="function",x=d.batchSize??Vb,D=fc(d.judge),F=async R=>{let $=(A[R.evidence]||[]).filter(T=>FO(R,T)),I=[];for(let T of $){let S=RO(R,T);S?h.verdicts.push(S):I.push(T);}let B=A.cut?.[R.evidence]??0,ee=T=>{T<=0||(h.undecided+=T,h.undecidedWcag.includes(R.sc[0])||h.undecidedWcag.push(R.sc[0]));};if(B&&(ee(B),h.errors.push(`${R.id}: ${B} candidates over the evidence cap`)),!$.length){B||h.inapplicable.push(R.id);return}let N=0;for(let T=0;T<I.length;T+=x){let S=_-Date.now();if(S<=0){ee(I.length-T),h.errors.push(`${R.id}: deadline`);return}let M=I.slice(T,T+x),q=[];for(let[me,oe]of M.entries()){let P;if(R.vision&&y&&N<TO&&oe.rect){let z=await pc(f,{rect:oe.rect,hidden:false,tag:String(oe.tag||"")},D);N++,P=z?.data;}q.push({id:`${R.id}#${T+me}`,type:R.issueType,wcag:R.sc[0],message:R.title,selector:String(oe.selector),html:String(oe.html||""),context:IO(oe),...P?{screenshot:P}:{}});}let j=M.find(me=>typeof me.outline=="string")?.outline,W=new AbortController,Z=setTimeout(()=>W.abort(),S),ne=null,le=false;h.calls++;try{let me=await Promise.race([m({url:d.url,level:p,vision:R.vision&&y,items:q,system:fa(R),rubric:{id:R.id,hash:mi(R)},...j?{page:{outline:j}}:{}},W.signal),new Promise((oe,P)=>W.signal.addEventListener("abort",()=>P(new Error("rubric deadline"))))]);ne=pi(me),ne||h.errors.push(`${R.id}: malformed output`);}catch(me){h.errors.push(`${R.id}: ${me.message.slice(0,80)}`),le=me instanceof bn;}finally{clearTimeout(Z);}let fe=new Map(q.map((me,oe)=>[me.id,M[oe]]));for(let me of ne||[]){let oe=fe.get(me.id);if(!oe||me.verdict==="cantTell")continue;fe.delete(me.id);let P=uc(me.reason);h.verdicts.push({aspect:R.id,selector:String(oe.selector),verdict:me.verdict,reason:P,by:"model"}),me.verdict==="failed"&&h.findings.push({id:`rubric-${R.id}-${Mn(String(oe.selector))}`,source:"webability",type:R.issueType,wcag:R.sc[0],level:R.level,impact:R.impact,message:`${R.title}: ${P||"failed the rubric"}`,selector:String(oe.selector),html:String(oe.html||"")});}if(ee(fe.size),le){ee(I.length-T-M.length);return}}},O=[...v],H=Array.from({length:Math.max(1,d.concurrency??3)},async()=>{for(let R=O.shift();R;R=O.shift())await F(R);});return await Promise.all(H),h.findings=await $u(f,h.findings,d.bugs),h}var Vb,SO,TO,FO,zb=Fe(()=>{da();mc();xr();zu();nc();ac();Nb();Hb();Vb=8,SO=45e3,TO=12;FO=(f,d)=>f.where.every(h=>d[h.field]===h.value);});var Yo={mobile:{width:375,height:667},tablet:{width:768,height:1024},desktop:{width:1280,height:720}};zu();var qv="1.19.0";da();Zu();async function Wv(f,d){return Ju("axe",f,()=>pL(f,d))}async function pL(f,d){try{let{AxeBuilder:h}=await import('@axe-core/playwright'),m=typeof f.mainFrame=="function"?f:f.axePage?.()??f,p=await new h({page:m}).options({rules:Wu(d)}).withTags(d).analyze();return await gL(f,p)}catch{return mL(f,d)}}async function mL(f,d){let h=await Promise.resolve().then(()=>BM(Gv())),m=h.source??h.default?.source;if(!m)throw new Error("axe-core source unavailable");try{await f.evaluate(m);}catch{let{inject:v}=await Promise.resolve().then(()=>(xr(),vn));await v(f,{tool:"axe",content:m});}return await f.evaluate(({wcagTags:v,rules:_})=>new Promise((w,E)=>{let C=window;if(!C.axe)return E(new Error("axe-core not loaded"));C.axe.run(document,{runOnly:{type:"tag",values:v},rules:_,resultTypes:["violations","incomplete"]}).then(w).catch(E);}),{wcagTags:d,rules:Wu(d)})}function hL(f,d){if(f=f.toLowerCase().replace(/^www\./,""),d=d.toLowerCase().replace(/^www\./,""),!f||!d)return false;if(f===d||f.endsWith("."+d)||d.endsWith("."+f))return true;let h=m=>{let p=m.split(".");if(p.length<=2)return m;let v=p[p.length-1],_=p[p.length-2],w=v.length===2&&["co","com","net","org","ac","gov","edu"].includes(_)?3:2;return p.slice(-w).join(".")};return h(f)===h(d)}async function gL(f,d){let h=new Set,m=C=>!Array.isArray(C)||C.length<2?null:JSON.stringify(C[0]);for(let C of [d.violations,d.incomplete])for(let A of C??[])for(let y of A.nodes??[]){let x=m(y.target);x&&h.add(x);}if(!h.size)return d;let p;try{p=await f.evaluate(C=>{let A={};for(let y of C){A[y]=null;try{let x=JSON.parse(y),D=Array.isArray(x)?x:[x],F=document,O=null;for(let I=0;I<D.length&&(O=F.querySelector(D[I]),!(!O||(I<D.length-1&&(F=O.shadowRoot),!F)));I++);if(!O||O.tagName!=="IFRAME"&&O.tagName!=="FRAME"||O.hasAttribute("srcdoc"))continue;let H=I=>I&&/^https?:/i.test(I)?I:"",R="",$=!1;try{R=H(O.contentWindow.location.href);}catch{$=!0;}if(R||(R=H(O.src)||H(O.getAttribute("data-src"))||H(O.getAttribute("data-lazy-src"))),!R){$&&(A[y]={frame:"",page:location.hostname});continue}A[y]={frame:new URL(R).hostname,page:location.hostname};}catch{}}return A},[...h]);}catch{return d}let v=C=>{let A=m(C),y=A?p[A]:null;return !y||y.frame&&hL(y.frame,y.page)?null:{insideFrameFrom:y.frame||"a cross-origin frame whose address cannot be read",pageHost:y.page,thirdPartyDocument:true}},_=[],w=(d.violations??[]).flatMap(C=>{let A=C.nodes??[],y=A.filter(D=>!v(D.target)),x=A.filter(D=>v(D.target)).map(D=>({...D,waEvidence:v(D.target)}));return x.length&&_.push({...C,nodes:x}),x.length?y.length?[{...C,nodes:y}]:[]:[C]}),E=(d.incomplete??[]).map(C=>C.nodes?.some(A=>v(A.target))?{...C,nodes:C.nodes.map(A=>v(A.target)?{...A,waEvidence:v(A.target)}:A)}:C);return {...d,violations:w,incomplete:[...E,..._]}}function Qu(f){let d=[],h=[];for(let m of f)m.confidence==="needs_review"||bL(m)?h.push(m):d.push(vL(m));return {verdicts:d,undecided:h}}function vL(f){if(f.confidence===void 0&&f.reviewReason===void 0&&f.evidence===void 0)return f;let{confidence:d,reviewReason:h,evidence:m,...p}=f;return p}function bL(f){let d=(f.type||"").toLowerCase(),h=f.wcag||"",m=f.html||"",p=(f.message||"").toLowerCase();if((d==="contrast_insufficient"||d==="color-contrast"||h==="1.4.3"||h==="1.4.11")&&yL(m))return "background uses gradient or image";if(d==="image_of_text"||h==="1.4.5"){let v=Uv(m,"src").toLowerCase();v.startsWith("data:")&&(v=v.split(",")[0]);let _=Uv(m,"alt").toLowerCase();if(/\b(logo|brand|wordmark|hero|banner|footer|marketing|promo|cover)\b/.test(v))return "brand imagery";if(_.length>0&&/\b(logo|brand|product screenshot|dashboard)\b/.test(_))return "branded imagery"}return (d==="inconsistent_navigation"||p.includes("inconsistent navigation"))&&(/<footer/i.test(m)||/<aside/i.test(m))?"footer/aside nav":""}function yL(f){return /background(-image)?\s*:\s*(?:linear-gradient|radial-gradient|conic-gradient|url\()/i.test(f)}function Uv(f,d){let h=new RegExp(`\\b${d}\\s*=\\s*"([^"]*)"`,"i"),m=f.match(h);return m?m[1]:""}tc();mc();async function oO(f){let d=F=>({verdict:"drop",why:F}),h=null;try{h=document.querySelector(f.selector);}catch{return d("bad selector")}if(!h||h.tagName!=="VIDEO")return d("not a video");let m=getComputedStyle(h),p=h.getBoundingClientRect();if(m.display==="none"||m.visibility==="hidden"||h.closest("[hidden]")||p.width<100||p.height<50)return d("not visible/large enough");if(h.error)return d("failed load");let v=h.currentSrc||h.getAttribute("src")||h.querySelector("source")?.getAttribute("src")||"";if(!v||/^(blob|data|about|javascript):/i.test(v)||/\.(m3u8|mpd)(\?|$)/i.test(v))return d("no direct src / MSE");let _=h.hasAttribute("muted")||h.muted,w=h.hasAttribute("controls"),E=h.hasAttribute("autoplay")||h.autoplay,C=h.hasAttribute("loop")||h.loop,A=w||E&&!_;if(!A){let F=/play|pause|mute|unmute|sound|volume/i;for(let O=h.parentElement,H=0;O&&H<3&&!A;O=O.parentElement,H++)A=Array.from(O.querySelectorAll('button, [role="button"]')).some(R=>F.test((R.getAttribute("aria-label")||"")+" "+(R.getAttribute("title")||"")+" "+(R.textContent||"")));}if(!A)return d("not user-playable");if(_&&C&&!w)return d("decorative loop");if(h.hasAttribute("muted")&&!w&&!E)return d("muted");if(Number.isFinite(h.duration)&&h.duration>0&&h.duration<5)return d("under 5s");await new Promise(F=>setTimeout(F,2e3));for(let F of Array.from(h.querySelectorAll("track"))){let O=(F.getAttribute("kind")||"subtitles").toLowerCase();if((O==="captions"||O==="subtitles")&&F.getAttribute("src"))return d("has caption track")}let y=h.textTracks;for(let F=0;y&&F<y.length;F++)if(y[F].kind==="captions"||y[F].kind==="subtitles")return d("has text track");let x=h,D=null;if(typeof x.mozHasAudio=="boolean"?D=x.mozHasAudio:x.audioTracks&&typeof x.audioTracks.length=="number"&&(D=x.audioTracks.length>0?true:null),D===null&&typeof x.webkitAudioDecodedByteCount=="number"&&x.webkitAudioDecodedByteCount>0&&(D=true),D===null)try{let F=new AbortController,O=setTimeout(()=>F.abort(),f.fetchMs),H=await fetch(v,{headers:{Range:"bytes=0-"+(f.rangeBytes-1)},signal:F.signal}),R=new Uint8Array(f.rangeBytes),$=0,I=H.body?H.body.getReader():null;if(I)try{for(;$<f.rangeBytes;){let{done:N,value:T}=await I.read();if(N||!T)break;let S=Math.min(T.length,f.rangeBytes-$);R.set(T.subarray(0,S),$),$+=S;}}finally{try{await I.cancel();}catch{}}clearTimeout(O);let B=(N,T=0)=>{e:for(let S=T;S<=$-N.length;S++){for(let M=0;M<N.length;M++)if(R[S+M]!==N[M])continue e;return S}return -1},ee=N=>Array.from(N).map(T=>T.charCodeAt(0));B(ee("ftyp"))>=0&&B(ee("moov"))>=0?D=B(ee("hdlr"))>=0&&B(ee("soun"))>=0:R[0]===26&&R[1]===69&&R[2]===223&&R[3]===163&&B([22,84,174,107])>=0&&(D=B([131,129,2])>=0);}catch{D=null;}return D!==true?d(D===false?"silent":"audio unknowable"):{verdict:"violation"}}async function xb(f,d){let h=d.filter(v=>v.type==="missing_captions"&&/^<video\b/i.test(v.html??"")&&v.selector).slice(0,10);if(h.length===0)return [];let m=[],p=Date.now()+1e4;try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");for(let v of h){if(Date.now()>p)break;let _=p-Date.now(),w,E=await Promise.race([f.evaluate(oO,{selector:v.selector,rangeBytes:1048576,fetchMs:4e3}),new Promise(C=>{w=setTimeout(()=>C(null),_);})]).finally(()=>w&&clearTimeout(w));if(!E)break;if(E.verdict==="violation"){let{confidence:C,reviewReason:A,evidence:y,...x}=v;m.push({...x,id:v.id.replace("axe-incomplete-","axe-"),message:"video has an audio track, can be played by the user, and has no captions or subtitles track (WCAG 1.2.2)"});}}}catch{}return m}function Db(){let f=p=>{let v=p.getBoundingClientRect();if(v.width===0||v.height===0)return false;let _=window.getComputedStyle(p);return _.visibility!=="hidden"&&_.display!=="none"&&_.opacity!=="0"},d=Array.from(document.querySelectorAll('input[type="password"]')),h=Array.from(document.querySelectorAll('button, input[type="submit"], a[role="button"]')).filter(f).map(p=>(p.value||p.textContent||"").trim().toLowerCase()).filter(p=>p.length>0&&p.length<40),m=Array.from(document.querySelectorAll("button, a")).filter(f).filter(p=>/sign in with|continue with|log in with/i.test(p.textContent||"")).length;return {passwordFields:d.length,visiblePasswordFields:d.filter(f).length,submitLabels:h,oauthButtons:m,formCount:document.querySelectorAll("form").length,bodyTextLength:(document.body?.innerText||"").trim().length,headingText:(document.querySelector("h1, h2")?.textContent||"").trim().slice(0,120).toLowerCase()}}var sO=/\b(log ?in|sign ?in|sign ?on|authenticate)\b/,lO=/\b(log ?in|sign ?in|sign ?on|authentication|welcome back|access denied|unauthori[sz]ed)\b/;function Ab(f){try{let d=new URL(f).pathname.toLowerCase();return /(^|\/)(login|signin|sign-in|log-in|auth|sso|session\/new|users\/sign_in)(\/|$)/.test(d)}catch{return false}}function Eb(f,d,h){if(Ab(d))return null;let m=_b(d)!==_b(h),p=f.submitLabels.some(y=>sO.test(y)),v=lO.test(f.headingText),_=Ab(h),w=[];_&&w.push("url"),p&&w.push("submit"),v&&w.push("heading"),m&&w.push("redirected");let E=f.visiblePasswordFields>0,C=f.oauthButtons>0&&f.bodyTextLength<600&&f.formCount<=1;if(!E&&!C||w.length<2)return null;let A=`${E?"password-field":"oauth-only"}+${w.join("+")}`;return {reason:`Scan did not reach the requested page \u2014 it landed on a sign-in page at ${h}. The findings would describe the login screen, not the intended page. Configure site authentication for this site, or scan a page that does not require a session.`,signal:A,finalUrl:h}}function _b(f){try{let d=new URL(f);return `${d.origin}${d.pathname.replace(/\/+$/,"")}`.toLowerCase()}catch{return f.toLowerCase()}}da();async function PO(f){try{return await f.evaluate(()=>{let d=(document.title||"").toLowerCase(),h=[["just a moment","Cloudflare"],["attention required","Cloudflare"],["checking your browser","Cloudflare"],["access to this page has been denied","PerimeterX/HUMAN"],["please verify you are a human","PerimeterX/HUMAN"],["verify you are human","bot-challenge"],["are you a robot","bot-challenge"],["you have been blocked","bot-challenge"],["request unsuccessful","Imperva/Incapsula"],["human verification","bot-challenge"],["additional security check is required","bot-challenge"]];for(let[v,_]of h)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!1};let m=[["#cf-chl-widget","Cloudflare"],["#challenge-running","Cloudflare"],["#cf-challenge-running","Cloudflare"],[".cf-browser-verification","Cloudflare"],["#cf-please-wait","Cloudflare"],["div.cf-error-details","Cloudflare"],["#px-captcha","PerimeterX/HUMAN"],["#distilCaptchaForm","Distil"],["form#challenge-form","bot-challenge"]];for(let[v,_]of m)if(document.querySelector(v))return {vendor:_,signal:`marker:${v}`,needsCorroboration:!1};if(window._cf_chl_opt)return {vendor:"Cloudflare",signal:"marker:window._cf_chl_opt",needsCorroboration:!1};let p=[["please wait...","Cloudflare"],["access denied","bot-challenge"]];for(let[v,_]of p)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!0};return null})}catch{return null}}async function LO(f){try{return await f.evaluate(()=>{let d=document.querySelectorAll("body *").length;if(d>250)return null;let h=['[id*="captcha" i]','[class*="captcha" i]','img[src*="captcha" i]','iframe[src*="recaptcha" i]','iframe[src*="hcaptcha" i]','iframe[src*="turnstile" i]','[name*="captcha" i]'];for(let p of h)try{if(document.querySelector(p))return {signal:`marker:${p}`,elements:d}}catch{}let m=(document.title||"").toLowerCase();return m.includes("captcha")||m.includes("security check")||m.includes("bot verification")?{signal:`title:"${document.title}"`,elements:d}:null})}catch{return null}}async function OO(f,d){let h=await PO(f),m=typeof d=="number"&&d>=400,p=h&&(!h.needsCorroboration||m)?h:null;if(!p&&!m)return null;let v=[];return p&&v.push(`served a ${p.vendor} bot-challenge / interstitial page`),m&&v.push(`main document returned HTTP ${d}`),{reason:`Scan did not reach the real page \u2014 the target ${v.join(" and ")}. The returned issue list reflects the challenge/error page, not the intended site.`,...p?{vendor:p.vendor}:{},...typeof d=="number"?{status:d}:{},...p?{signal:p.signal}:m?{signal:`status:${d}`}:{}}}async function bi(f,d){let h=typeof f=="string",m={wcagTags:Gu,includeAxe:true,deep:false,dismissModals:h,...d},p,v,_,w;if(h){_=f.startsWith("http")?f:`https://${f}`;let E=typeof m.viewport=="string"?Yo[m.viewport]??Yo.desktop:m.viewport??Yo.desktop;v=await(await import('playwright')).chromium.launch({headless:m.browser?.headless??true}),p=await(await v.newContext({viewport:E})).newPage();let y=await p.goto(_,{waitUntil:"domcontentloaded",timeout:m.browser?.timeout??3e4});w=typeof y?.status=="function"?y.status():void 0;}else p=f,_=p.url(),w=m.mainStatus;if(m.dismissModals)try{let{dismissModals:E}=await Promise.resolve().then(()=>(Cb(),kb));await E(p);}catch{}if(m.settle!==false)try{let{waitForRenderSettle:E}=await Promise.resolve().then(()=>(oa(),li));await E(p,typeof m.settle=="number"?m.settle:void 0);}catch{}if(!v){let{snapshotInteractionState:E}=await Promise.resolve().then(()=>(as(),ns));await E(p);}try{let E=await p.evaluate(()=>performance.timeOrigin);try{let P=await p.evaluate(Db),z=Eb(P,_,typeof p.url=="function"?p.url():_);if(z)return {url:_,timestamp:new Date().toISOString(),blocked:{reason:z.reason,signal:`auth-wall:${z.signal}`,...typeof w=="number"?{status:w}:{}},issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}}}catch{}let C=await OO(p,w);if(C)return {url:_,timestamp:new Date().toISOString(),blocked:C,issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}};let A=[],y=new Map,x=[],D=[],F=[],{guardDetectorState:O,dropToolingFindings:H}=await Promise.resolve().then(()=>(xr(),vn)),R=await LO(p);R&&D.push(`challenge:suspected-interstitial (${R.signal}; ${R.elements} elements) \u2014 this looks like a bot-challenge/CAPTCHA page, not the real site; results may be invalid`),await(await Promise.resolve().then(()=>(xr(),vn))).startProvenance(p);let{trackPageActivity:$,waitForInteractionSettle:I}=await Promise.resolve().then(()=>(oa(),li));m.settle!==!1&&await $(p);let{takeTurn:B}=await Promise.resolve().then(()=>(Zu(),jv)),ee=await B("detectors",p,()=>Nv(p,x,D,{internalBugs:F,extraSerialDetectors:m.extraSerialDetectors,experimental:m.experimental}));A.push(...ee.map(Vv));let{resetInteractionState:N,focusOnlyObscuredIndexes:T}=await Promise.resolve().then(()=>(as(),ns));if(await N(p),m.settle!==!1&&await I(p),m.includeAxe)try{let P=await O(p,"axe",D,()=>Wv(p,Bv(m.wcagTags??Gu,m.level)),{bugs:F});for(let z of P.violations){let Y=z.id==="target-size"?await T(p,z.nodes):new Set;for(let[K,J]of z.nodes.entries()){if(Y.has(K)){F.push({tool:"axe",kind:"finding-dropped",detail:"target-size obscured only by a focus-only element (scanner focus state)",selector:ca(J.target)});continue}A.push({id:`axe-${z.id}-${Mn(ca(J.target))}`,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(J.target),html:J.html?.slice(0,300)});}}for(let z of P.incomplete??[])for(let Y of z.nodes){let K=`axe-incomplete-${z.id}-${Mn(ca(Y.target))}`,J=Y.any?.[0]?.data?.messageKey;J&&y.set(K,J),A.push({id:K,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(Y.target),html:Y.html?.slice(0,300),confidence:"needs_review",...Y.waEvidence?{reviewReason:"this node is inside a frame served by another site; decide whether the page owner is responsible for it",evidence:Y.waEvidence}:{reviewReason:"axe-core flagged this as needing human review"}});}}catch(P){F.push({tool:"axe",kind:"engine-failed",detail:`axe-core threw, its findings are absent: ${P?.message??String(P)}`});}let{deduplicateIssues:S}=await Promise.resolve().then(()=>(Nn(),On)),M=Qu(A),q=S(M.verdicts);try{let{pruneInvisibleContrast:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{pruneHiddenIframeIssues:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));q=await P(p,q);}catch{}try{q=await H(p,q,F);}catch{}try{let{verifyAnimatedGifs:P}=await Promise.resolve().then(()=>(Mb(),Ib));q=await P(p,q);}catch{}if(m.deep&&m.deepApiKey)try{let P=await NO(_,q,m);q.push(...P);}catch{}if(m.rootSelector)try{let{scopeIssuesToRoot:P}=await Promise.resolve().then(()=>(vi(),gi)),z=await P(p,q,m.rootSelector);q=z.issues,z.warning&&D.push(z.warning);}catch{}q=Qr(q,m.level??"AA");let j=Qu(q),W=j.verdicts,Z=[],ne=[],le=new Set;try{if(ne=[...M.undecided,...j.undecided],m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));ne=(await J(p,ne,m.rootSelector)).issues;}let P=new Map;await N(p);let z=await O(p,"contrast-pixels",D,()=>nb(p,ne,y,P),{bugs:F}),Y=await xb(p,ne),K=[...z,...Y];if(le=new Set(K.map(J=>`${J.selector}|${J.wcag}`)),K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}{let J=ne.filter(be=>!le.has(`${be.selector}|${be.wcag}`)),ie=await wb(p,J,{...m.judge,url:_,level:m.judge?.level??m.level??"AA",measured:P});if(globalThis.process?.env?.WA_DEBUG_JUDGE&&console.error(`ai judge: ${J.length} undecided before judge, ${ie.promoted.length} promoted, ${ie.judged.filter(be=>be.verdict==="pass").length} passed`),Z=ie.judged,ie.promoted.length){let{deduplicateIssues:be}=await Promise.resolve().then(()=>(Nn(),On));W=be([...W,...Qr(ie.promoted,m.level??"AA")]);}}}catch{}let fe={count:0,wcag:[]};if(m.judge)try{let{runRubrics:P,rubricTransport:z}=await Promise.resolve().then(()=>(zb(),jb));if(z(m.judge)){await N(p);let Y=await P(p,{url:_,judge:m.judge,level:m.level??"AA",timeoutMs:m.judge.timeoutMs,bugs:F,warnings:D,rootSelector:m.rootSelector});fe={count:Y.undecided,wcag:Y.undecidedWcag};for(let J of Y.errors)D.push(`rubric ${J}`);let K=Qr(Y.findings,m.level??"AA");if(K.length&&m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));K=(await J(p,K,m.rootSelector)).issues;}if(K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}}}catch{}let me;{let P=new Set(Z.map(K=>K.id)),z=Qr(ne,m.level??"AA").filter(K=>!le.has(`${K.selector}|${K.wcag}`)&&!P.has(K.id.replace("axe-incomplete-","axe-"))),Y=z.length+fe.count;Y&&(me={count:Y,wcag:[...new Set([...z.map(K=>K.wcag),...fe.wcag])].sort()});}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));W=await P(p,W);}catch{}try{W=await H(p,W,F);}catch{}if(await p.evaluate(()=>performance.timeOrigin)!==E)throw new Error(`the page's document was replaced during the scan (navigation to ${p.url()}); the findings mix two documents`);{let{attachMutations:P,stopProvenance:z}=await Promise.resolve().then(()=>(xr(),vn));P(F,await z(p));}let oe={url:_,timestamp:new Date().toISOString(),engine:qv,issues:W,internal_bugs:F,incomplete:[],...Z.length?{judged:Z}:{},...x.length?{truncated:x}:{},...D.length?{engineWarnings:D}:{},...me?{unsettled:me}:{},...m.keepDetected?{detected:ee}:{},summary:Xu(W)};if(m.review!==!1&&m.deepApiKey)try{oe=await qO(oe,m);}catch{}return oe}finally{let{stopProvenance:E}=await Promise.resolve().then(()=>(xr(),vn));if(await E(p),v)await v.close();else {let{restoreInteractionState:C}=await Promise.resolve().then(()=>(as(),ns));await C(p);}}}async function NO(f,d,h){let m=h.deepApiUrl||"https://api.webability.io",p=await fetch(`${m}/cli/deep-scan`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${h.deepApiKey}`},body:JSON.stringify({url:f,standardIssues:d.slice(0,30).map(({source:_,...w})=>w)})});return p.ok?((await p.json()).issues??[]).map((_,w)=>({id:`deep-${w}-${Mn(_.selector||_.element||"")}`,source:"deep-analysis",type:`wcag-${_.wcag}`,wcag:_.wcag,level:"AA",impact:_.severity==="High"?"critical":_.severity==="Medium"?"serious":"moderate",message:_.message,selector:_.selector||_.element||""})):[]}function Gb(f){let d=f.fix?.attribute??"";return !!f.fix?.needsManualReview&&d!=="style"&&!d.startsWith("data-")}async function qO(f,d){let h=d.deepApiUrl||"https://api.webability.io",m=f.issues.filter(Gb);if(m.length===0)return f;try{let p=await fetch(`${h}/review-findings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d.deepApiKey}`},body:JSON.stringify({url:f.url,issues:m.slice(0,30).map(({source:E,...C})=>C)})});if(!p.ok)return f;let v=await p.json();if(!v.confirmed_ids)return f;let _=new Set(v.confirmed_ids),w=f.issues.filter(E=>!Gb(E)||_.has(E.id));return {...f,issues:w,summary:Xu(w)}}catch{return f}}function Ub(f){return {...f,issues:f.issues.map(({source:d,...h})=>h)}}async function BO(f,d){return Ub(await bi(f,{...d,dismissModals:false}))}var Wb=class{page;options;issues=new Map;observer=false;merged={};running=null;queued=false;constructor(d,h){this.page=d,this.options=h??{};}async analyze(d){return BO(this.page,{...this.options,...d})}record(d){for(let h of d.issues)this.issues.set(h.id,h);}onMutation(){return this.observer?this.running?(this.queued=true,this.running):(this.running=(async()=>{do{this.queued=false;try{this.record(await bi(this.page,{...this.merged,dismissModals:!1}));}catch{}}while(this.queued&&this.observer)})().finally(()=>{this.running=null;}),this.running):Promise.resolve()}async start(d){this.issues=new Map,this.observer=true,this.merged={...this.options,...d},this.record(await bi(this.page,{...this.merged,dismissModals:false})),await this.page.exposeFunction("__webabilityOnMutation",()=>this.onMutation()),await this.page.evaluate(()=>{let h=new MutationObserver(()=>{window.__webabilityOnMutation?.();});h.observe(document.body,{childList:true,subtree:true}),window.__webabilityObserver=h;});}async stop(){this.observer=false,await this.page.evaluate(()=>{window.__webabilityObserver?.disconnect();}).catch(()=>{}),await this.running?.catch(()=>{});let d=await bi(this.page,{...this.options,dismissModals:false});this.record(d);let h=Array.from(this.issues.values()),m={url:d.url,timestamp:d.timestamp,issues:h,incomplete:[],summary:{total:h.length,critical:h.filter(p=>p.impact==="critical").length,serious:h.filter(p=>p.impact==="serious").length,moderate:h.filter(p=>p.impact==="moderate").length,minor:h.filter(p=>p.impact==="minor").length,incomplete:0}};return this.issues=new Map,Ub(m)}};/*! Bundled license information:
|
|
1020
|
+
`),K=Array.from(document.querySelectorAll("p, li, td, th, dd, dt, label, figcaption, blockquote, caption, div, span")).filter(J=>!A(J)&&Array.from(J.childNodes).some(ie=>ie.nodeType===3&&(ie.textContent||"").trim().length>2));for(let J of K){if(J.parentElement&&K.includes(J.parentElement))continue;let ie=I(J)&&!B(J);!$(J)||!ie&&R(J)||ne("textBlocks",{selector:y(J),html:O(J),rect:F(J),text:C(J.textContent||"",220),visible:ie,ariaHidden:R(J),outline:Y});}}return {...w,cut:E}}async function Ob(f,d,h=Pb){if(!d.length)return {};try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");}catch{}try{return await f.evaluate(DO,{kinds:d,max:h,caps:{...Lb,...h<Pb?Object.fromEntries(Object.keys(Lb).map(m=>[m,h])):{}},own:ua})}catch{return {}}}var Pb,_O,Lb,Nb=Fe(()=>{xr();Pb=40,_O=400,Lb={control:_O};});function qb(f){let d=f;for(let h="";h!==d;)h=d,d=d.replace(kO," ");return d=d.toLowerCase().normalize("NFKD").replace(EO," ").trim(),d?d.split(/\s+/):[]}function CO(f){let d=qb(f);return d.length===1&&[...d[0].replace(/\p{M}/gu,"")].length===1&&/^\p{L}/u.test(d[0])?[]:d}function Bb(f,d){let h=CO(f);if(!h.length)return true;let m=qb(d);for(let p=0;p+h.length<=m.length;p++){let v=true;for(let _=0;_<h.length&&v;_++)v=m[p+_]===h[_];if(v)return true}return false}var EO,kO,Hb=Fe(()=>{EO=/[^\p{L}\p{N}\p{M}]+/gu,kO=/\([^()]*\)/g;});var jb={};pr(jb,{RUBRIC_BATCH_SIZE:()=>Vb,parseRubricVerdicts:()=>pi,rubricPromptHash:()=>mi,rubricSystemPrompt:()=>fa,rubricTransport:()=>$b,runRubrics:()=>MO});function $b(f){return f.transport?f.transport:f.apiKey?cc({apiKey:f.apiKey,baseUrl:f.baseUrl,visionModel:f.visionModel,textModel:f.textModel}):f.apiUrl?dc({apiUrl:f.apiUrl,token:f.apiToken,internalSecret:f.internalSecret}):null}function RO(f,d){if(f.evidence==="control"){let h=d;if(h.visibleText.trim()&&Bb(h.visibleText,h.name))return {aspect:f.id,selector:h.selector,verdict:"passed",reason:"the ACT label-in-name algorithm finds the visible label in the accessible name",by:"rule"}}return null}function IO(f){let{selector:d,html:h,rect:m,outline:p,...v}=f;return v}async function MO(f,d){let h={findings:[],verdicts:[],inapplicable:[],undecided:0,undecidedWcag:[],calls:0,errors:[]},m=$b(d.judge);if(!m)return h;let p=d.level??d.judge.level??"AA",v=db.filter(R=>(d.aspects?d.aspects.includes(R.id):R.status!=="below-bar"||!!d.judge.rubrics?.includes(R.id))&&Qr([{wcag:R.sc.join(","),level:R.level}],p).length>0);if(!v.length)return h;let _=Date.now()+(d.timeoutMs??d.judge.timeoutMs??SO),w=d.warnings??[];await ju(f,w);let E=[...new Set(v.map(R=>R.evidence))],C=globalThis.process?.env?.WA_STRICT_STATE==="1",A=await Vu(f,"rubric-evidence",w,()=>Ob(f,E),{strict:C,bugs:d.bugs});if(d.rootSelector){let{scopeIssuesToRoot:R}=await Promise.resolve().then(()=>(vi(),gi));for(let $ of E){let I=A[$]||[];if(!I.length)continue;let B=new Set((await R(f,I,d.rootSelector)).issues);A[$]=I.filter(ee=>B.has(ee));}}let y=d.judge.vision!==false&&typeof f.screenshot=="function",x=d.batchSize??Vb,D=fc(d.judge),F=async R=>{let $=(A[R.evidence]||[]).filter(T=>FO(R,T)),I=[];for(let T of $){let S=RO(R,T);S?h.verdicts.push(S):I.push(T);}let B=A.cut?.[R.evidence]??0,ee=T=>{T<=0||(h.undecided+=T,h.undecidedWcag.includes(R.sc[0])||h.undecidedWcag.push(R.sc[0]));};if(B&&(ee(B),h.errors.push(`${R.id}: ${B} candidates over the evidence cap`)),!$.length){B||h.inapplicable.push(R.id);return}let N=0;for(let T=0;T<I.length;T+=x){let S=_-Date.now();if(S<=0){ee(I.length-T),h.errors.push(`${R.id}: deadline`);return}let M=I.slice(T,T+x),q=[];for(let[me,oe]of M.entries()){let P;if(R.vision&&y&&N<TO&&oe.rect){let z=await pc(f,{rect:oe.rect,hidden:false,tag:String(oe.tag||"")},D);N++,P=z?.data;}q.push({id:`${R.id}#${T+me}`,type:R.issueType,wcag:R.sc[0],message:R.title,selector:String(oe.selector),html:String(oe.html||""),context:IO(oe),...P?{screenshot:P}:{}});}let j=M.find(me=>typeof me.outline=="string")?.outline,W=new AbortController,Z=setTimeout(()=>W.abort(),S),ne=null,le=false;h.calls++;try{let me=await Promise.race([m({url:d.url,level:p,vision:R.vision&&y,items:q,system:fa(R),rubric:{id:R.id,hash:mi(R)},...j?{page:{outline:j}}:{}},W.signal),new Promise((oe,P)=>W.signal.addEventListener("abort",()=>P(new Error("rubric deadline"))))]);ne=pi(me),ne||h.errors.push(`${R.id}: malformed output`);}catch(me){h.errors.push(`${R.id}: ${me.message.slice(0,80)}`),le=me instanceof bn;}finally{clearTimeout(Z);}let fe=new Map(q.map((me,oe)=>[me.id,M[oe]]));for(let me of ne||[]){let oe=fe.get(me.id);if(!oe||me.verdict==="cantTell")continue;fe.delete(me.id);let P=uc(me.reason);h.verdicts.push({aspect:R.id,selector:String(oe.selector),verdict:me.verdict,reason:P,by:"model"}),me.verdict==="failed"&&h.findings.push({id:`rubric-${R.id}-${Mn(String(oe.selector))}`,source:"webability",type:R.issueType,wcag:R.sc[0],level:R.level,impact:R.impact,message:`${R.title}: ${P||"failed the rubric"}`,selector:String(oe.selector),html:String(oe.html||"")});}if(ee(fe.size),le){ee(I.length-T-M.length);return}}},O=[...v],H=Array.from({length:Math.max(1,d.concurrency??3)},async()=>{for(let R=O.shift();R;R=O.shift())await F(R);});return await Promise.all(H),h.findings=await $u(f,h.findings,d.bugs),h}var Vb,SO,TO,FO,zb=Fe(()=>{da();mc();xr();zu();nc();ac();Nb();Hb();Vb=8,SO=45e3,TO=12;FO=(f,d)=>f.where.every(h=>d[h.field]===h.value);});var Yo={mobile:{width:375,height:667},tablet:{width:768,height:1024},desktop:{width:1280,height:720}};zu();var qv="1.19.1";da();Zu();async function Wv(f,d){return Ju("axe",f,()=>pL(f,d))}async function pL(f,d){try{let{AxeBuilder:h}=await import('@axe-core/playwright'),m=typeof f.mainFrame=="function"?f:f.axePage?.()??f,p=await new h({page:m}).options({rules:Wu(d)}).withTags(d).analyze();return await gL(f,p)}catch{return mL(f,d)}}async function mL(f,d){let h=await Promise.resolve().then(()=>BM(Gv())),m=h.source??h.default?.source;if(!m)throw new Error("axe-core source unavailable");try{await f.evaluate(m);}catch{let{inject:v}=await Promise.resolve().then(()=>(xr(),vn));await v(f,{tool:"axe",content:m});}return await f.evaluate(({wcagTags:v,rules:_})=>new Promise((w,E)=>{let C=window;if(!C.axe)return E(new Error("axe-core not loaded"));C.axe.run(document,{runOnly:{type:"tag",values:v},rules:_,resultTypes:["violations","incomplete"]}).then(w).catch(E);}),{wcagTags:d,rules:Wu(d)})}function hL(f,d){if(f=f.toLowerCase().replace(/^www\./,""),d=d.toLowerCase().replace(/^www\./,""),!f||!d)return false;if(f===d||f.endsWith("."+d)||d.endsWith("."+f))return true;let h=m=>{let p=m.split(".");if(p.length<=2)return m;let v=p[p.length-1],_=p[p.length-2],w=v.length===2&&["co","com","net","org","ac","gov","edu"].includes(_)?3:2;return p.slice(-w).join(".")};return h(f)===h(d)}async function gL(f,d){let h=new Set,m=C=>!Array.isArray(C)||C.length<2?null:JSON.stringify(C[0]);for(let C of [d.violations,d.incomplete])for(let A of C??[])for(let y of A.nodes??[]){let x=m(y.target);x&&h.add(x);}if(!h.size)return d;let p;try{p=await f.evaluate(C=>{let A={};for(let y of C){A[y]=null;try{let x=JSON.parse(y),D=Array.isArray(x)?x:[x],F=document,O=null;for(let I=0;I<D.length&&(O=F.querySelector(D[I]),!(!O||(I<D.length-1&&(F=O.shadowRoot),!F)));I++);if(!O||O.tagName!=="IFRAME"&&O.tagName!=="FRAME"||O.hasAttribute("srcdoc"))continue;let H=I=>I&&/^https?:/i.test(I)?I:"",R="",$=!1;try{R=H(O.contentWindow.location.href);}catch{$=!0;}if(R||(R=H(O.src)||H(O.getAttribute("data-src"))||H(O.getAttribute("data-lazy-src"))),!R){$&&(A[y]={frame:"",page:location.hostname});continue}A[y]={frame:new URL(R).hostname,page:location.hostname};}catch{}}return A},[...h]);}catch{return d}let v=C=>{let A=m(C),y=A?p[A]:null;return !y||y.frame&&hL(y.frame,y.page)?null:{insideFrameFrom:y.frame||"a cross-origin frame whose address cannot be read",pageHost:y.page,thirdPartyDocument:true}},_=[],w=(d.violations??[]).flatMap(C=>{let A=C.nodes??[],y=A.filter(D=>!v(D.target)),x=A.filter(D=>v(D.target)).map(D=>({...D,waEvidence:v(D.target)}));return x.length&&_.push({...C,nodes:x}),x.length?y.length?[{...C,nodes:y}]:[]:[C]}),E=(d.incomplete??[]).map(C=>C.nodes?.some(A=>v(A.target))?{...C,nodes:C.nodes.map(A=>v(A.target)?{...A,waEvidence:v(A.target)}:A)}:C);return {...d,violations:w,incomplete:[...E,..._]}}function Qu(f){let d=[],h=[];for(let m of f)m.confidence==="needs_review"||bL(m)?h.push(m):d.push(vL(m));return {verdicts:d,undecided:h}}function vL(f){if(f.confidence===void 0&&f.reviewReason===void 0&&f.evidence===void 0)return f;let{confidence:d,reviewReason:h,evidence:m,...p}=f;return p}function bL(f){let d=(f.type||"").toLowerCase(),h=f.wcag||"",m=f.html||"",p=(f.message||"").toLowerCase();if((d==="contrast_insufficient"||d==="color-contrast"||h==="1.4.3"||h==="1.4.11")&&yL(m))return "background uses gradient or image";if(d==="image_of_text"||h==="1.4.5"){let v=Uv(m,"src").toLowerCase();v.startsWith("data:")&&(v=v.split(",")[0]);let _=Uv(m,"alt").toLowerCase();if(/\b(logo|brand|wordmark|hero|banner|footer|marketing|promo|cover)\b/.test(v))return "brand imagery";if(_.length>0&&/\b(logo|brand|product screenshot|dashboard)\b/.test(_))return "branded imagery"}return (d==="inconsistent_navigation"||p.includes("inconsistent navigation"))&&(/<footer/i.test(m)||/<aside/i.test(m))?"footer/aside nav":""}function yL(f){return /background(-image)?\s*:\s*(?:linear-gradient|radial-gradient|conic-gradient|url\()/i.test(f)}function Uv(f,d){let h=new RegExp(`\\b${d}\\s*=\\s*"([^"]*)"`,"i"),m=f.match(h);return m?m[1]:""}tc();mc();async function oO(f){let d=F=>({verdict:"drop",why:F}),h=null;try{h=document.querySelector(f.selector);}catch{return d("bad selector")}if(!h||h.tagName!=="VIDEO")return d("not a video");let m=getComputedStyle(h),p=h.getBoundingClientRect();if(m.display==="none"||m.visibility==="hidden"||h.closest("[hidden]")||p.width<100||p.height<50)return d("not visible/large enough");if(h.error)return d("failed load");let v=h.currentSrc||h.getAttribute("src")||h.querySelector("source")?.getAttribute("src")||"";if(!v||/^(blob|data|about|javascript):/i.test(v)||/\.(m3u8|mpd)(\?|$)/i.test(v))return d("no direct src / MSE");let _=h.hasAttribute("muted")||h.muted,w=h.hasAttribute("controls"),E=h.hasAttribute("autoplay")||h.autoplay,C=h.hasAttribute("loop")||h.loop,A=w||E&&!_;if(!A){let F=/play|pause|mute|unmute|sound|volume/i;for(let O=h.parentElement,H=0;O&&H<3&&!A;O=O.parentElement,H++)A=Array.from(O.querySelectorAll('button, [role="button"]')).some(R=>F.test((R.getAttribute("aria-label")||"")+" "+(R.getAttribute("title")||"")+" "+(R.textContent||"")));}if(!A)return d("not user-playable");if(_&&C&&!w)return d("decorative loop");if(h.hasAttribute("muted")&&!w&&!E)return d("muted");if(Number.isFinite(h.duration)&&h.duration>0&&h.duration<5)return d("under 5s");await new Promise(F=>setTimeout(F,2e3));for(let F of Array.from(h.querySelectorAll("track"))){let O=(F.getAttribute("kind")||"subtitles").toLowerCase();if((O==="captions"||O==="subtitles")&&F.getAttribute("src"))return d("has caption track")}let y=h.textTracks;for(let F=0;y&&F<y.length;F++)if(y[F].kind==="captions"||y[F].kind==="subtitles")return d("has text track");let x=h,D=null;if(typeof x.mozHasAudio=="boolean"?D=x.mozHasAudio:x.audioTracks&&typeof x.audioTracks.length=="number"&&(D=x.audioTracks.length>0?true:null),D===null&&typeof x.webkitAudioDecodedByteCount=="number"&&x.webkitAudioDecodedByteCount>0&&(D=true),D===null)try{let F=new AbortController,O=setTimeout(()=>F.abort(),f.fetchMs),H=await fetch(v,{headers:{Range:"bytes=0-"+(f.rangeBytes-1)},signal:F.signal}),R=new Uint8Array(f.rangeBytes),$=0,I=H.body?H.body.getReader():null;if(I)try{for(;$<f.rangeBytes;){let{done:N,value:T}=await I.read();if(N||!T)break;let S=Math.min(T.length,f.rangeBytes-$);R.set(T.subarray(0,S),$),$+=S;}}finally{try{await I.cancel();}catch{}}clearTimeout(O);let B=(N,T=0)=>{e:for(let S=T;S<=$-N.length;S++){for(let M=0;M<N.length;M++)if(R[S+M]!==N[M])continue e;return S}return -1},ee=N=>Array.from(N).map(T=>T.charCodeAt(0));B(ee("ftyp"))>=0&&B(ee("moov"))>=0?D=B(ee("hdlr"))>=0&&B(ee("soun"))>=0:R[0]===26&&R[1]===69&&R[2]===223&&R[3]===163&&B([22,84,174,107])>=0&&(D=B([131,129,2])>=0);}catch{D=null;}return D!==true?d(D===false?"silent":"audio unknowable"):{verdict:"violation"}}async function xb(f,d){let h=d.filter(v=>v.type==="missing_captions"&&/^<video\b/i.test(v.html??"")&&v.selector).slice(0,10);if(h.length===0)return [];let m=[],p=Date.now()+1e4;try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");for(let v of h){if(Date.now()>p)break;let _=p-Date.now(),w,E=await Promise.race([f.evaluate(oO,{selector:v.selector,rangeBytes:1048576,fetchMs:4e3}),new Promise(C=>{w=setTimeout(()=>C(null),_);})]).finally(()=>w&&clearTimeout(w));if(!E)break;if(E.verdict==="violation"){let{confidence:C,reviewReason:A,evidence:y,...x}=v;m.push({...x,id:v.id.replace("axe-incomplete-","axe-"),message:"video has an audio track, can be played by the user, and has no captions or subtitles track (WCAG 1.2.2)"});}}}catch{}return m}function Db(){let f=p=>{let v=p.getBoundingClientRect();if(v.width===0||v.height===0)return false;let _=window.getComputedStyle(p);return _.visibility!=="hidden"&&_.display!=="none"&&_.opacity!=="0"},d=Array.from(document.querySelectorAll('input[type="password"]')),h=Array.from(document.querySelectorAll('button, input[type="submit"], a[role="button"]')).filter(f).map(p=>(p.value||p.textContent||"").trim().toLowerCase()).filter(p=>p.length>0&&p.length<40),m=Array.from(document.querySelectorAll("button, a")).filter(f).filter(p=>/sign in with|continue with|log in with/i.test(p.textContent||"")).length;return {passwordFields:d.length,visiblePasswordFields:d.filter(f).length,submitLabels:h,oauthButtons:m,formCount:document.querySelectorAll("form").length,bodyTextLength:(document.body?.innerText||"").trim().length,headingText:(document.querySelector("h1, h2")?.textContent||"").trim().slice(0,120).toLowerCase()}}var sO=/\b(log ?in|sign ?in|sign ?on|authenticate)\b/,lO=/\b(log ?in|sign ?in|sign ?on|authentication|welcome back|access denied|unauthori[sz]ed)\b/;function Ab(f){try{let d=new URL(f).pathname.toLowerCase();return /(^|\/)(login|signin|sign-in|log-in|auth|sso|session\/new|users\/sign_in)(\/|$)/.test(d)}catch{return false}}function Eb(f,d,h){if(Ab(d))return null;let m=_b(d)!==_b(h),p=f.submitLabels.some(y=>sO.test(y)),v=lO.test(f.headingText),_=Ab(h),w=[];_&&w.push("url"),p&&w.push("submit"),v&&w.push("heading"),m&&w.push("redirected");let E=f.visiblePasswordFields>0,C=f.oauthButtons>0&&f.bodyTextLength<600&&f.formCount<=1;if(!E&&!C||w.length<2)return null;let A=`${E?"password-field":"oauth-only"}+${w.join("+")}`;return {reason:`Scan did not reach the requested page \u2014 it landed on a sign-in page at ${h}. The findings would describe the login screen, not the intended page. Configure site authentication for this site, or scan a page that does not require a session.`,signal:A,finalUrl:h}}function _b(f){try{let d=new URL(f);return `${d.origin}${d.pathname.replace(/\/+$/,"")}`.toLowerCase()}catch{return f.toLowerCase()}}da();async function PO(f){try{return await f.evaluate(()=>{let d=(document.title||"").toLowerCase(),h=[["just a moment","Cloudflare"],["attention required","Cloudflare"],["checking your browser","Cloudflare"],["access to this page has been denied","PerimeterX/HUMAN"],["please verify you are a human","PerimeterX/HUMAN"],["verify you are human","bot-challenge"],["are you a robot","bot-challenge"],["you have been blocked","bot-challenge"],["request unsuccessful","Imperva/Incapsula"],["human verification","bot-challenge"],["additional security check is required","bot-challenge"]];for(let[v,_]of h)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!1};let m=[["#cf-chl-widget","Cloudflare"],["#challenge-running","Cloudflare"],["#cf-challenge-running","Cloudflare"],[".cf-browser-verification","Cloudflare"],["#cf-please-wait","Cloudflare"],["div.cf-error-details","Cloudflare"],["#px-captcha","PerimeterX/HUMAN"],["#distilCaptchaForm","Distil"],["form#challenge-form","bot-challenge"]];for(let[v,_]of m)if(document.querySelector(v))return {vendor:_,signal:`marker:${v}`,needsCorroboration:!1};if(window._cf_chl_opt)return {vendor:"Cloudflare",signal:"marker:window._cf_chl_opt",needsCorroboration:!1};let p=[["please wait...","Cloudflare"],["access denied","bot-challenge"]];for(let[v,_]of p)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!0};return null})}catch{return null}}async function LO(f){try{return await f.evaluate(()=>{let d=document.querySelectorAll("body *").length;if(d>250)return null;let h=['[id*="captcha" i]','[class*="captcha" i]','img[src*="captcha" i]','iframe[src*="recaptcha" i]','iframe[src*="hcaptcha" i]','iframe[src*="turnstile" i]','[name*="captcha" i]'];for(let p of h)try{if(document.querySelector(p))return {signal:`marker:${p}`,elements:d}}catch{}let m=(document.title||"").toLowerCase();return m.includes("captcha")||m.includes("security check")||m.includes("bot verification")?{signal:`title:"${document.title}"`,elements:d}:null})}catch{return null}}async function OO(f,d){let h=await PO(f),m=typeof d=="number"&&d>=400,p=h&&(!h.needsCorroboration||m)?h:null;if(!p&&!m)return null;let v=[];return p&&v.push(`served a ${p.vendor} bot-challenge / interstitial page`),m&&v.push(`main document returned HTTP ${d}`),{reason:`Scan did not reach the real page \u2014 the target ${v.join(" and ")}. The returned issue list reflects the challenge/error page, not the intended site.`,...p?{vendor:p.vendor}:{},...typeof d=="number"?{status:d}:{},...p?{signal:p.signal}:m?{signal:`status:${d}`}:{}}}async function bi(f,d){let h=typeof f=="string",m={wcagTags:Gu,includeAxe:true,deep:false,dismissModals:h,...d},p,v,_,w;if(h){_=f.startsWith("http")?f:`https://${f}`;let E=typeof m.viewport=="string"?Yo[m.viewport]??Yo.desktop:m.viewport??Yo.desktop;v=await(await import('playwright')).chromium.launch({headless:m.browser?.headless??true}),p=await(await v.newContext({viewport:E})).newPage();let y=await p.goto(_,{waitUntil:"domcontentloaded",timeout:m.browser?.timeout??3e4});w=typeof y?.status=="function"?y.status():void 0;}else p=f,_=p.url(),w=m.mainStatus;if(m.dismissModals)try{let{dismissModals:E}=await Promise.resolve().then(()=>(Cb(),kb));await E(p);}catch{}if(m.settle!==false)try{let{waitForRenderSettle:E}=await Promise.resolve().then(()=>(oa(),li));await E(p,typeof m.settle=="number"?m.settle:void 0);}catch{}if(!v){let{snapshotInteractionState:E}=await Promise.resolve().then(()=>(as(),ns));await E(p);}try{let E=await p.evaluate(()=>performance.timeOrigin);try{let P=await p.evaluate(Db),z=Eb(P,_,typeof p.url=="function"?p.url():_);if(z)return {url:_,timestamp:new Date().toISOString(),blocked:{reason:z.reason,signal:`auth-wall:${z.signal}`,...typeof w=="number"?{status:w}:{}},issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}}}catch{}let C=await OO(p,w);if(C)return {url:_,timestamp:new Date().toISOString(),blocked:C,issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}};let A=[],y=new Map,x=[],D=[],F=[],{guardDetectorState:O,dropToolingFindings:H}=await Promise.resolve().then(()=>(xr(),vn)),R=await LO(p);R&&D.push(`challenge:suspected-interstitial (${R.signal}; ${R.elements} elements) \u2014 this looks like a bot-challenge/CAPTCHA page, not the real site; results may be invalid`),await(await Promise.resolve().then(()=>(xr(),vn))).startProvenance(p);let{trackPageActivity:$,waitForInteractionSettle:I}=await Promise.resolve().then(()=>(oa(),li));m.settle!==!1&&await $(p);let{takeTurn:B}=await Promise.resolve().then(()=>(Zu(),jv)),ee=await B("detectors",p,()=>Nv(p,x,D,{internalBugs:F,extraSerialDetectors:m.extraSerialDetectors,experimental:m.experimental}));A.push(...ee.map(Vv));let{resetInteractionState:N,focusOnlyObscuredIndexes:T}=await Promise.resolve().then(()=>(as(),ns));if(await N(p),m.settle!==!1&&await I(p),m.includeAxe)try{let P=await O(p,"axe",D,()=>Wv(p,Bv(m.wcagTags??Gu,m.level)),{bugs:F});for(let z of P.violations){let Y=z.id==="target-size"?await T(p,z.nodes):new Set;for(let[K,J]of z.nodes.entries()){if(Y.has(K)){F.push({tool:"axe",kind:"finding-dropped",detail:"target-size obscured only by a focus-only element (scanner focus state)",selector:ca(J.target)});continue}A.push({id:`axe-${z.id}-${Mn(ca(J.target))}`,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(J.target),html:J.html?.slice(0,300)});}}for(let z of P.incomplete??[])for(let Y of z.nodes){let K=`axe-incomplete-${z.id}-${Mn(ca(Y.target))}`,J=Y.any?.[0]?.data?.messageKey;J&&y.set(K,J),A.push({id:K,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(Y.target),html:Y.html?.slice(0,300),confidence:"needs_review",...Y.waEvidence?{reviewReason:"this node is inside a frame served by another site; decide whether the page owner is responsible for it",evidence:Y.waEvidence}:{reviewReason:"axe-core flagged this as needing human review"}});}}catch(P){F.push({tool:"axe",kind:"engine-failed",detail:`axe-core threw, its findings are absent: ${P?.message??String(P)}`});}let{deduplicateIssues:S}=await Promise.resolve().then(()=>(Nn(),On)),M=Qu(A),q=S(M.verdicts);try{let{pruneInvisibleContrast:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{pruneHiddenIframeIssues:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));q=await P(p,q);}catch{}try{q=await H(p,q,F);}catch{}try{let{verifyAnimatedGifs:P}=await Promise.resolve().then(()=>(Mb(),Ib));q=await P(p,q);}catch{}if(m.deep&&m.deepApiKey)try{let P=await NO(_,q,m);q.push(...P);}catch{}if(m.rootSelector)try{let{scopeIssuesToRoot:P}=await Promise.resolve().then(()=>(vi(),gi)),z=await P(p,q,m.rootSelector);q=z.issues,z.warning&&D.push(z.warning);}catch{}q=Qr(q,m.level??"AA");let j=Qu(q),W=j.verdicts,Z=[],ne=[],le=new Set;try{if(ne=[...M.undecided,...j.undecided],m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));ne=(await J(p,ne,m.rootSelector)).issues;}let P=new Map;await N(p);let z=await O(p,"contrast-pixels",D,()=>nb(p,ne,y,P),{bugs:F}),Y=await xb(p,ne),K=[...z,...Y];if(le=new Set(K.map(J=>`${J.selector}|${J.wcag}`)),K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}{let J=ne.filter(be=>!le.has(`${be.selector}|${be.wcag}`)),ie=await wb(p,J,{...m.judge,url:_,level:m.judge?.level??m.level??"AA",measured:P});if(globalThis.process?.env?.WA_DEBUG_JUDGE&&console.error(`ai judge: ${J.length} undecided before judge, ${ie.promoted.length} promoted, ${ie.judged.filter(be=>be.verdict==="pass").length} passed`),Z=ie.judged,ie.promoted.length){let{deduplicateIssues:be}=await Promise.resolve().then(()=>(Nn(),On));W=be([...W,...Qr(ie.promoted,m.level??"AA")]);}}}catch{}let fe={count:0,wcag:[]};if(m.judge)try{let{runRubrics:P,rubricTransport:z}=await Promise.resolve().then(()=>(zb(),jb));if(z(m.judge)){await N(p);let Y=await P(p,{url:_,judge:m.judge,level:m.level??"AA",timeoutMs:m.judge.timeoutMs,bugs:F,warnings:D,rootSelector:m.rootSelector});fe={count:Y.undecided,wcag:Y.undecidedWcag};for(let J of Y.errors)D.push(`rubric ${J}`);let K=Qr(Y.findings,m.level??"AA");if(K.length&&m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));K=(await J(p,K,m.rootSelector)).issues;}if(K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}}}catch{}let me;{let P=new Set(Z.map(K=>K.id)),z=Qr(ne,m.level??"AA").filter(K=>!le.has(`${K.selector}|${K.wcag}`)&&!P.has(K.id.replace("axe-incomplete-","axe-"))),Y=z.length+fe.count;Y&&(me={count:Y,wcag:[...new Set([...z.map(K=>K.wcag),...fe.wcag])].sort()});}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));W=await P(p,W);}catch{}try{W=await H(p,W,F);}catch{}if(await p.evaluate(()=>performance.timeOrigin)!==E)throw new Error(`the page's document was replaced during the scan (navigation to ${p.url()}); the findings mix two documents`);{let{attachMutations:P,stopProvenance:z}=await Promise.resolve().then(()=>(xr(),vn));P(F,await z(p));}let oe={url:_,timestamp:new Date().toISOString(),engine:qv,issues:W,internal_bugs:F,incomplete:[],...Z.length?{judged:Z}:{},...x.length?{truncated:x}:{},...D.length?{engineWarnings:D}:{},...me?{unsettled:me}:{},...m.keepDetected?{detected:ee}:{},summary:Xu(W)};if(m.review!==!1&&m.deepApiKey)try{oe=await qO(oe,m);}catch{}return oe}finally{let{stopProvenance:E}=await Promise.resolve().then(()=>(xr(),vn));if(await E(p),v)await v.close();else {let{restoreInteractionState:C}=await Promise.resolve().then(()=>(as(),ns));await C(p);}}}async function NO(f,d,h){let m=h.deepApiUrl||"https://api.webability.io",p=await fetch(`${m}/cli/deep-scan`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${h.deepApiKey}`},body:JSON.stringify({url:f,standardIssues:d.slice(0,30).map(({source:_,...w})=>w)})});return p.ok?((await p.json()).issues??[]).map((_,w)=>({id:`deep-${w}-${Mn(_.selector||_.element||"")}`,source:"deep-analysis",type:`wcag-${_.wcag}`,wcag:_.wcag,level:"AA",impact:_.severity==="High"?"critical":_.severity==="Medium"?"serious":"moderate",message:_.message,selector:_.selector||_.element||""})):[]}function Gb(f){let d=f.fix?.attribute??"";return !!f.fix?.needsManualReview&&d!=="style"&&!d.startsWith("data-")}async function qO(f,d){let h=d.deepApiUrl||"https://api.webability.io",m=f.issues.filter(Gb);if(m.length===0)return f;try{let p=await fetch(`${h}/review-findings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d.deepApiKey}`},body:JSON.stringify({url:f.url,issues:m.slice(0,30).map(({source:E,...C})=>C)})});if(!p.ok)return f;let v=await p.json();if(!v.confirmed_ids)return f;let _=new Set(v.confirmed_ids),w=f.issues.filter(E=>!Gb(E)||_.has(E.id));return {...f,issues:w,summary:Xu(w)}}catch{return f}}function Ub(f){return {...f,issues:f.issues.map(({source:d,...h})=>h)}}async function BO(f,d){return Ub(await bi(f,{...d,dismissModals:false}))}var Wb=class{page;options;issues=new Map;observer=false;merged={};running=null;queued=false;constructor(d,h){this.page=d,this.options=h??{};}async analyze(d){return BO(this.page,{...this.options,...d})}record(d){for(let h of d.issues)this.issues.set(h.id,h);}onMutation(){return this.observer?this.running?(this.queued=true,this.running):(this.running=(async()=>{do{this.queued=false;try{this.record(await bi(this.page,{...this.merged,dismissModals:!1}));}catch{}}while(this.queued&&this.observer)})().finally(()=>{this.running=null;}),this.running):Promise.resolve()}async start(d){this.issues=new Map,this.observer=true,this.merged={...this.options,...d},this.record(await bi(this.page,{...this.merged,dismissModals:false})),await this.page.exposeFunction("__webabilityOnMutation",()=>this.onMutation()),await this.page.evaluate(()=>{let h=new MutationObserver(()=>{window.__webabilityOnMutation?.();});h.observe(document.body,{childList:true,subtree:true}),window.__webabilityObserver=h;});}async stop(){this.observer=false,await this.page.evaluate(()=>{window.__webabilityObserver?.disconnect();}).catch(()=>{}),await this.running?.catch(()=>{});let d=await bi(this.page,{...this.options,dismissModals:false});this.record(d);let h=Array.from(this.issues.values()),m={url:d.url,timestamp:d.timestamp,issues:h,incomplete:[],summary:{total:h.length,critical:h.filter(p=>p.impact==="critical").length,serious:h.filter(p=>p.impact==="serious").length,moderate:h.filter(p=>p.impact==="moderate").length,minor:h.filter(p=>p.impact==="minor").length,incomplete:0}};return this.issues=new Map,Ub(m)}};/*! Bundled license information:
|
|
1019
1021
|
|
|
1020
1022
|
axe-core/axe.js:
|
|
1021
1023
|
(*! axe v4.11.3
|
package/dist/playwright.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Page } from 'playwright';
|
|
2
|
-
import { S as ScanOptions, b as ScanIssue, a as ScanResult } from './types-
|
|
2
|
+
import { S as ScanOptions, b as ScanIssue, a as ScanResult } from './types-B_q8lTmv.cjs';
|
|
3
3
|
|
|
4
4
|
interface A11yCheckOptions extends Omit<ScanOptions, 'browser' | 'dismissModals'> {
|
|
5
5
|
}
|
package/dist/playwright.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Page } from 'playwright';
|
|
2
|
-
import { S as ScanOptions, b as ScanIssue, a as ScanResult } from './types-
|
|
2
|
+
import { S as ScanOptions, b as ScanIssue, a as ScanResult } from './types-B_q8lTmv.js';
|
|
3
3
|
|
|
4
4
|
interface A11yCheckOptions extends Omit<ScanOptions, 'browser' | 'dismissModals'> {
|
|
5
5
|
}
|
package/dist/playwright.js
CHANGED
|
@@ -829,6 +829,8 @@ impact: moderate
|
|
|
829
829
|
evidence: heading
|
|
830
830
|
where: linkTitle=false
|
|
831
831
|
vision: false
|
|
832
|
+
status: below-bar
|
|
833
|
+
note: Opt-in (Sid, 2026-11-11). Live sweep 2026-11-10/11 (16 control sites, alibaba/qwen3.8-flash, 3 runs): new weak_heading findings on 5 sites, mostly false positives (slogans, sr-only headings, card titles). Runs only when named in \`aspects\` or \`judge.rubrics\`.
|
|
832
834
|
---
|
|
833
835
|
## Aspect
|
|
834
836
|
A heading must describe the topic or purpose of the content it introduces (WCAG 2.4.6 Headings and Labels).
|
|
@@ -1015,7 +1017,7 @@ Rules:
|
|
|
1015
1017
|
Respond with ONLY a JSON array, one object per item, same ids:
|
|
1016
1018
|
[{"id": "...", "verdict": "pass" | "violation", "reason": "one sentence", "fix": {"attribute": "...", "value": "..."}}]
|
|
1017
1019
|
Omit "fix" for passes.`;Ln=f=>Math.round(f*100)/100;iO=[1,.6,.35];});var kb={};pr(kb,{dismissModals:()=>cO});async function cO(f){await f.evaluate(d=>{for(let h of d){let m=document.querySelectorAll(h);for(let p of m)if(p.offsetParent!==null){p.click();return}}},uO),await new Promise(d=>setTimeout(d,500));}var uO,Cb=Fe(()=>{uO=['[class*="cookie"] button[class*="accept"]','[class*="cookie"] button[class*="agree"]','[class*="consent"] button[class*="accept"]','[class*="consent"] button[class*="agree"]','[id*="cookie"] button','[id*="consent"] button',".cc-dismiss",".cc-allow",".cc-btn",'[class*="gdpr"] button[class*="accept"]','[aria-label*="cookie" i] button','[aria-label*="consent" i] button','button[class*="close-banner"]','[class*="popup"] [class*="close"]','[class*="overlay"] [class*="close"]','[class*="modal"] [class*="close"]','[class*="notification"] [class*="close"]','button[aria-label="Close"]','button[aria-label="Dismiss"]'];});var ns={};pr(ns,{focusOnlyObscuredIndexes:()=>hO,resetInteractionState:()=>dO,restoreInteractionState:()=>pO,snapshotInteractionState:()=>fO});async function dO(f){try{await f.evaluate(()=>{try{document.activeElement?.blur?.();}catch{}try{window.scrollTo({left:0,top:0,behavior:"instant"});}catch{}});}catch{}}async function fO(f){try{await f.evaluate(()=>{let d=window;d.__waCallerState={el:document.activeElement,x:window.scrollX,y:window.scrollY};});}catch{}}async function pO(f){try{await f.evaluate(()=>{let d=window,h=d.__waCallerState;if(delete d.__waCallerState,!h)return;let m=h.el;if(m&&m!==document.body&&m!==document.documentElement&&m.isConnected)try{m.focus({preventScroll:!0});}catch{}try{window.scrollTo({left:h.x,top:h.y,behavior:"instant"});}catch{}});}catch{}}function mO(f){if(typeof f=="string")return f;if(!Array.isArray(f))return null;let d=f.flat(1/0).filter(h=>typeof h=="string");return d.length===1?d[0]:null}async function hO(f,d){let h=d.map(_=>{let E=[..._.any??[],..._.none??[]].flatMap(A=>A.relatedNodes??[]);if(!E.length)return null;let C=E.map(A=>mO(A.target));return C.every(A=>!!A)?C:null}),m=Array.from(new Set(h.flatMap(_=>_??[])));if(!m.length)return new Set;let p={};try{p=await f.evaluate(({sels:_,own:w})=>{let E=A=>{let y=A.getBoundingClientRect(),x=getComputedStyle(A);return !!((y.width<=1||y.height<=1)&&(x.overflow==="hidden"||x.position==="absolute"||x.position==="fixed")||/^rect\(\s*0(px)?[\s,]+0(px)?[\s,]+0(px)?[\s,]+0(px)?\s*\)$/.test(x.clip||"")||/inset\(\s*50%/.test(x.clipPath||""))},C={};for(let A of _){let y=null;try{y=document.querySelector(A);}catch{y=null;}if(!y){C[A]=!1;continue}let x=y.closest(w);if(x&&x!==document.body&&x!==document.documentElement){C[A]=!0;continue}if(y===document.activeElement){try{y.blur();}catch{}C[A]=E(y);continue}C[A]=E(y);}return C},{sels:m,own:ua});}catch{return new Set}let v=new Set;return h.forEach((_,w)=>{_&&_.length&&_.every(E=>p[E]===true)&&v.add(w);}),v}var as=Fe(()=>{xr();});var On={};pr(On,{dedupeByElementIdentity:()=>wO,deduplicateIssues:()=>gO});function gO(f){let d=new Map,h=[...f].sort((m,p)=>{let v={webability:0,"axe-core":1,"deep-analysis":2},_=v[m.source]??3,w=v[p.source]??3;return _-w});for(let m of h){let p=vO(m);d.has(p)?!d.get(p).fix?.suggestedValue&&m.fix?.suggestedValue&&d.set(p,m):d.set(p,m);}return Array.from(d.values())}function vO(f){let d=f.selector.replace(/:focus-visible$/,"").replace(/:focus$/,"").replace(/\[data-[^\]]+\]/g,"").trim(),h=f.wcag||"";return d&&h?`${d}::${h}`:`${f.type}::${d||f.id}`}async function wO(f,d){if(d.length<2)return d;let h=Array.from(new Set(d.map(A=>A.selector).filter(Boolean))),m;try{m=await f.evaluate(A=>{let y=Array.from(document.querySelectorAll("*")),x=new Map;y.forEach((F,O)=>x.set(F,O));let D={};for(let F of A){let O=null;try{O=document.querySelector(F);}catch{}if(!O){let H=F.replace(/:(?:focus-visible|focus-within|focus|hover|active)$/,"");if(H!==F)try{O=document.querySelector(H);}catch{}}if(O){let H=O.closest("table");D[F]={el:x.get(O),table:H?x.get(H):-1,doc:O===document.documentElement||O===document.body};}}return D},h);}catch{return d}let p={webability:0,"axe-core":1,"deep-analysis":2},v=A=>{let y=m[A.selector];if(!y)return null;let x=A.wcag||A.type;return y.doc?{key:yO.has(A.wcag||"")?`doc::${x}`:`doc::${x}::${A.type}`,owner:true}:y.table>=0&&bO.test(A.type)?{key:`${y.table}::${x}::table-headers`,owner:y.el===y.table}:is.has(A.type)?{key:`${y.el}::accessible-name`,owner:true}:{key:`${y.el}::${x}`,owner:true}},_=[...d].sort((A,y)=>{let x=v(A),D=v(y),F=x?.owner?0:1,O=D?.owner?0:1,H=is.has(A.type)&&is.has(y.type),R=H&&A.confidence==="needs_review"?1:0,$=H&&y.confidence==="needs_review"?1:0,I=H?Tb(A.type)-Tb(y.type):0;return F-O||R-$||(p[A.source]??3)-(p[y.source]??3)||I}),w=new Map,E=[];for(let A of _){let y=v(A);if(!y){E.push(A);continue}let x=w.get(y.key);x?!is.has(x.type)&&!x.fix?.suggestedValue&&A.fix?.suggestedValue&&(v(x)?.owner??true)===y.owner&&w.set(y.key,A):w.set(y.key,A);}let C=new Set([...w.values(),...E]);return d.filter(A=>C.has(A))}var bO,yO,is,Sb,Tb,Nn=Fe(()=>{bO=/^missing_table_header$|^td-has-header$|^th-has-data-cells$|^h43|^h63/,yO=new Set(["2.4.1","3.1.1","2.4.2"]),is=new Set(["missing_label","label","select-name","aria-input-field-name","empty_link","link-name","missing_alt","image-alt","background_image_unlabeled","unlabeled_button","button-name","input-button-name","svg_missing_name","svg-img-alt","role-img-alt"]),Sb=["background_image_unlabeled","unlabeled_button","missing_label","empty_link","missing_alt","svg_missing_name"],Tb=f=>{let d=Sb.indexOf(f);return d<0?Sb.length:d};});var Ib={};pr(Ib,{parseGif:()=>Rb,playsOverFiveSeconds:()=>Fb,verifyAnimatedGifs:()=>xO});function Rb(f){if(String.fromCharCode(f[0]??0,f[1]??0,f[2]??0)!=="GIF")return null;let h=13,m=f[10]??0;m&128&&(h+=3*(1<<(m&7)+1));let p=0,v=0,_=0,w=null,E=()=>{for(;h<f.length;){let C=f[h++];if(C===0)return;h+=C;}};for(;h<f.length;){let C=f[h++];if(C===59)break;if(C===33){let A=f[h++];if(A===249)_=(f[h+2]??0)|(f[h+3]??0)<<8,h+=1+(f[h]??4),E();else if(A===255){let y=f[h]??0,x=String.fromCharCode(...Array.from(f.subarray(h+1,h+1+y)));h+=1+y,(x==="NETSCAPE2.0"||x==="ANIMEXTS1.0")&&f[h]===3&&f[h+1]===1&&(w=(f[h+2]??0)|(f[h+3]??0)<<8),E();}else E();}else if(C===44){let A=f[h+8]??0;h+=9,A&128&&(h+=3*(1<<(A&7)+1)),h+=1,E(),p++,v+=_<2?10:_,_=0;}else break}return {frames:p,seconds:v/100,loops:w}}function Fb(f){if(f.frames<2)return false;if(f.loops===0)return true;let d=f.loops===null?1:f.loops+1;return f.seconds*d>5}async function xO(f,d){let h=d.filter(v=>v.type==="animated_gif_no_pause");if(!h.length)return d;let m=Array.from(new Set(h.map(v=>v.selector))),p={};try{p=await f.evaluate(async({sels:v,parserSrc:_})=>{let w=new Function("var __name = function (f) { return f }; return ("+_+")")(),E={};return await Promise.all(v.map(async C=>{E[C]=null;try{let A=document.querySelector(C),y=A&&(A.currentSrc||A.src);if(!y)return;let x=new AbortController,D=setTimeout(()=>x.abort(),5e3);try{let F=await fetch(y,{signal:x.signal,credentials:"same-origin"});if(!F.ok||Number(F.headers.get("content-length")||"0")>2e7)return;E[C]=w(new Uint8Array(await F.arrayBuffer()));}finally{clearTimeout(D);}}catch{}})),E},{sels:m,parserSrc:Rb.toString()});}catch{p={};}return d.flatMap(v=>{if(v.type!=="animated_gif_no_pause")return [v];let _=p[v.selector];if(!_)return [{...v,message:`${v.message} \u2014 the GIF file could not be read from the page (cross-origin or blocked), so its frame count and duration were not measured`}];if(!Fb(_))return [];let w=_.loops===0?"loops forever":`plays for ${(_.seconds*(_.loops===null?1:_.loops+1)).toFixed(1)}s`;return [{...v,message:`animated GIF (${_.frames} frames, ${w}) starts automatically with no pause control \u2014 replace it with a video that has controls or a static image, or add a pause button (WCAG 2.2.2)`}]})}var Mb=Fe(()=>{});var gi={};pr(gi,{scopeIssuesToRoot:()=>AO});async function AO(f,d,h){let m=Array.from(new Set(d.map(v=>v.selector).filter(Boolean))),p;try{p=await f.evaluate(({rootSel:v,sels:_})=>{let w=A=>{try{let x=document.querySelector(A);if(x)return x}catch{}let y=A.replace(/:(?:focus-visible|focus-within|focus|hover|active)$/,"");if(y!==A)try{return document.querySelector(y)}catch{return null}return null},E=null;try{E=document.querySelector(v);}catch{return {invalid:!0,matched:!1,within:{}}}if(!E)return {invalid:!1,matched:!1,within:{}};let C={};for(let A of _){let y=w(A);C[A]=y?y===E||E.contains(y):!0;}return {invalid:!1,matched:!0,within:C}},{rootSel:h,sels:m});}catch{return {issues:d,warning:`scope:evaluate-failed (${h}) \u2014 results unfiltered`}}return p.invalid?{issues:d,warning:`scope:invalid-selector (${h}) \u2014 results unfiltered`}:p.matched?{issues:d.filter(v=>v.selector?p.within[v.selector]===true:true)}:{issues:[],warning:`scope:root-miss (${h} matched nothing \u2014 empty result)`}}var vi=Fe(()=>{});function DO(f){let{kinds:d,max:h,caps:m,own:p}=f,v=globalThis,_=new Set(d),w={},E={},C=(P,z)=>{let Y=(P||"").replace(/\s+/g," ").trim();return Y.length>z?Y.slice(0,z-1)+"\u2026":Y},A=P=>{try{if(P.closest(p)||typeof v.isWidget=="function"&&v.isWidget(P))return !0}catch{}return false},y=P=>{if(P===document.documentElement)return "html";try{if(typeof v.uniqueSel=="function")return v.uniqueSel(P)}catch{}let z=[];for(let Y=P;Y&&Y!==document.documentElement;Y=Y.parentElement){let K=Y.parentElement,J=K?Array.from(K.children).filter(ie=>ie.tagName===Y.tagName):[];z.unshift(Y.tagName.toLowerCase()+(J.length>1?`:nth-of-type(${J.indexOf(Y)+1})`:""));}return z.join(" > ")},x=window.scrollX||0,D=window.scrollY||0,F=P=>{let z=P.getBoundingClientRect();return {x:z.left+x,y:z.top+D,w:z.width,h:z.height}},O=P=>C(P.outerHTML||"",300),H=P=>getComputedStyle(P),R=P=>!!P.closest('[aria-hidden="true"]'),$=P=>{if(P.closest?.("[hidden]"))return false;let z=P;if(typeof z.checkVisibility=="function")return z.checkVisibility({visibilityProperty:true});let Y=H(P);return Y.display!=="none"&&Y.visibility!=="hidden"},I=P=>{if(!$(P))return false;let z=F(P);return z.w>1&&z.h>1&&z.x+z.w>0&&z.y+z.h>0},B=P=>{let z=H(P),Y=P.getBoundingClientRect();return /inset\(\s*(50|100)%/.test(z.clipPath||"")||/rect\(\s*0(px)?[\s,]+0(px)?[\s,]+0(px)?[\s,]+0(px)?\s*\)/.test(z.clip||"")?true:(Y.width<=1||Y.height<=1)&&z.overflow==="hidden"},ee=P=>{let z=Qe=>parseFloat(Qe||"0")||0,Y=(Qe,We)=>{if(We.display==="none"||We.visibility==="hidden"||parseFloat(We.opacity||"1")===0||z(We.fontSize)===0||B(Qe))return true;if(We.position==="absolute"||We.position==="fixed"){let Mt=Qe.getBoundingClientRect();if(z(We.left)<=-999||z(We.top)<=-999||Mt.right<=0||Mt.bottom<=-(window.scrollY||0))return true}return false},K=[],J=document.createTreeWalker(P,NodeFilter.SHOW_TEXT);for(let Qe=J.nextNode();Qe;Qe=J.nextNode()){let We=Qe.parentElement,Mt=(Qe.textContent||"").replace(/\s+/g," ").trim();if(!We||!Mt||!/[\p{L}\p{N}]/u.test(Mt))continue;let qn=false,dt=false;for(let Zt=We;Zt;Zt=Zt===P?null:Zt.parentElement)if(Zt.tagName==="KBD"&&(dt=true),/^(NOSCRIPT|SCRIPT|STYLE|TEMPLATE)$/.test(Zt.tagName)||Y(Zt,H(Zt))){qn=true;break}qn||K.push({text:Mt,raw:Qe.textContent||"",kbd:dt,p:We});}let ie=0,be=K.length;for(;ie<be&&K[ie].kbd;)ie++;for(;be>ie&&K[be-1].kbd;)be--;let Pe=ie<be?K.slice(ie,be):K,Re="h1, h2, h3, h4, h5, h6, [role=heading]",pe=Pe.map(Qe=>{let We=H(Qe.p);return {size:z(We.fontSize),weight:parseInt(We.fontWeight||"400",10)||400,head:!!Qe.p.closest(Re)&&P.contains(Qe.p.closest(Re))}}),Be=Qe=>{for(let We=Qe;We&&We!==P;We=We.parentElement)if(!/^inline(?!-block)|^contents$/.test(H(We).display||""))return We;return P},at=Pe.map(Qe=>Be(Qe.p)),ze=pe.map(Qe=>Qe.size).filter(Qe=>Qe>0),ft=ze.length?Math.max(...ze):0,It=ze.length?Math.min(...ze):0,Se=pe.length?Math.min(...pe.map(Qe=>Qe.weight)):400,At=0;pe.forEach(Qe=>{!Qe.head&&Qe.weight<600&&Qe.size>At&&(At=Qe.size);});let _t=Qe=>Pe.some((We,Mt)=>at[Mt]===at[Qe]&&pe[Mt].weight<600&&!pe[Mt].head),Ct=Pe.map((Qe,We)=>pe[We].head||ft>It&&pe[We].size>=ft||pe[We].weight>=600&&Se<600&&pe[We].size>=At&&!_t(We)),Pt=Ct.every(Boolean);return Pe.map((Qe,We)=>({text:Qe.text,raw:Qe.raw,block:at[We],prominent:!Pt&&Ct[We]}))},N=P=>{for(let z=P.parentElement;z;z=z.parentElement){let Y=(z.getAttribute("role")||"").trim().toLowerCase();if(/^(banner|contentinfo|navigation|main|complementary)$/.test(Y))return Y;let K=z.tagName;if(K==="MAIN")return "main";if(K==="NAV")return "navigation";if(K==="ASIDE")return "complementary";if(K==="HEADER"||K==="FOOTER"){if(z.parentElement?.closest("article, aside, main, nav, section"))continue;return K==="HEADER"?"banner":"contentinfo"}}return ""},T=(P,z)=>{if(!z||z.tagName!=="A")return false;let Y=(z.getAttribute("href")||"").trim(),K=/^\/(index\.\w+)?([?#].*)?$/.test(Y);if(!K)try{let ie=new URL(Y,location.href);K=ie.origin===location.origin&&/^\/(index\.\w+)?$/.test(ie.pathname);}catch{}return K?!z.innerText.replace(/\s+/g,"")&&z.querySelectorAll("img, svg, [role=img]").length>=1&&z.contains(P):false},S=P=>(P||"").split(/\s+/).filter(Boolean).map(z=>document.getElementById(z)).filter(Boolean).map(z=>C(z.textContent||"",200)).join(" ").trim(),M=P=>{let z="";for(let Y of Array.from(P.childNodes))if(Y.nodeType===3)z+=Y.textContent;else if(Y.nodeType===1){let K=Y;if(/^(script|style|template)$/i.test(K.tagName))continue;K.tagName==="IMG"?z+=" "+(K.getAttribute("alt")||"")+" ":z+=" "+M(K)+" ";}return z},q=P=>{let z=S(P.getAttribute("aria-labelledby"));if(z)return z;let Y=(P.getAttribute("aria-label")||"").trim();if(Y)return Y;let K=P.tagName.toLowerCase();if(K==="img"||K==="area"||K==="input"&&P.type==="image"){let J=P.getAttribute("alt");if(J!==null)return J.trim()}if(/^(input|select|textarea)$/.test(K)){let ie=Array.from(P.labels||[]).map(be=>C(be.textContent||"",120)).join(" ").trim();if(ie)return ie}if(K==="svg"){let J=P.querySelector(":scope > title");if(J&&(J.textContent||"").trim())return C(J.textContent||"",120)}if(K==="object")return (P.getAttribute("title")||"").trim();if(P.matches("a, button, [role=link], [role=button], [role=heading], h1, h2, h3, h4, h5, h6, summary, [role=menuitem], [role=tab], [role=option]")){let J=C(M(P),200);if(J)return J}return (P.getAttribute("title")||"").trim()},j=P=>(P.getAttribute("role")||"").trim().toLowerCase().split(/\s+/)[0]||"",W=(P,z)=>{let Y=P.parentElement?.closest("p, li, figure, td, th, dd, blockquote, section, article, div, body");return Y?C(Y.innerText||Y.textContent||"",z):""},Z=P=>{let z=P.previousElementSibling;return z?C(z.innerText||z.textContent||"",160):""},ne=(P,z)=>{let Y=w[P]||=[];Y.length<(m[P]??h)?Y.push(z):E[P]=(E[P]||0)+1;};if(_.has("image")){let P=new Set,z=Array.from(document.querySelectorAll("img, svg, canvas, input[type=image], object, embed, [role=img]")).filter(pe=>!(pe.tagName.toLowerCase()==="svg"&&pe.parentElement?.closest("svg"))),Y=[],K=document.body?Array.from(document.body.querySelectorAll("*")).slice(0,3e3):[];for(let pe of K)/url\(/i.test(H(pe).backgroundImage||"")&&!z.includes(pe)&&Y.push(pe);let J=[],ie=new Map;for(let pe of [...z,...Y]){if(P.has(pe)||A(pe))continue;P.add(pe);let Be=pe.tagName.toLowerCase(),at=j(pe),ze=Y.includes(pe),ft=q(pe),It=R(pe),Se=at==="none"||at==="presentation",At=$(pe)&&!It&&!Se;Be==="img"&&pe.getAttribute("alt")===""&&!pe.getAttribute("aria-label")&&!pe.getAttribute("aria-labelledby")&&!pe.getAttribute("title")&&(At=false),(Be==="svg"||Be==="canvas"||ze)&&at!=="img"&&!ft&&(At=false),ze&&at!=="img"&&(At=false);let _t=true;if(Be==="img"){let Mt=pe;_t=!(Mt.complete&&(Mt.naturalWidth===0||Mt.naturalWidth<=1&&Mt.naturalHeight<=1));}let Ct=pe.parentElement?.closest("a[href], button, [role=button], [role=link]")||null,Pt=!!Ct&&!!((Ct.getAttribute("aria-label")||"").trim()||Ct.getAttribute("aria-labelledby")),Qe=ze?(H(pe).backgroundImage.match(/url\(["']?([^"')]+)/)||[])[1]||"":pe.currentSrc||pe.getAttribute("src")||pe.getAttribute("data")||pe.querySelector("image")?.getAttribute("href")||"",We={selector:y(pe),html:O(pe),rect:F(pe),tag:Be,role:at,name:ft,alt:pe.getAttribute("alt"),ariaHidden:It,inTree:At,hasName:!!ft,rendered:I(pe)&&_t,cssBackground:ze,svgText:Be==="svg"&&!!pe.querySelector("text"),ownText:ze?C(ee(pe).map(Mt=>Mt.text).join(" "),160):"",src:/^data:/i.test(Qe)?Qe.slice(0,60):C(Qe,200),insideNamedControl:Pt,controlName:Ct?C(q(Ct),120):"",landmark:N(pe),homeLink:T(pe,Ct),nearbyText:C([Z(pe),W(pe,200)].filter(Boolean).join(" | "),260)};J.push(We),ie.set(We,pe);}J.sort((pe,Be)=>+!!Be.rendered-+!!pe.rendered);let be=window.scrollX,Pe=window.scrollY;for(let pe of J.slice(0,m.image??h)){if(pe.covered=false,!pe.rendered)continue;let Be=ie.get(pe);if(Be)try{Be.scrollIntoView({block:"center",inline:"center"});let at=Be.getBoundingClientRect(),ze=document.elementFromPoint(at.left+at.width/2,at.top+at.height/2);pe.covered=!!ze&&ze!==Be&&!Be.contains(ze)&&!ze.contains(Be)&&!(Be.tagName.toLowerCase()==="svg"&&Be.contains(ze));}catch{}}window.scrollTo(be,Pe);let Re=m.image??h;J.forEach((pe,Be)=>{Be<Re?ne("image",pe):pe.rendered&&!pe.svgText&&(E.image=(E.image||0)+1);});}if(_.has("link"))for(let P of Array.from(document.querySelectorAll("a[href], area[href], [role=link]"))){if(A(P))continue;let z=j(P);if(z&&z!=="link"||!$(P)||R(P))continue;let Y=q(P);if(!Y)continue;let K=[];for(let Be=P.closest("li");Be;Be=Be.parentElement?.closest("li")||null){let at="";for(let ze of Array.from(Be.childNodes))(ze.nodeType===3||ze.nodeType===1&&!/^(ul|ol)$/i.test(ze.tagName))&&(at+=" "+(ze.innerText??ze.textContent??""));K.push(C(at,160));}let J=P.closest("td, th"),ie=[];if(J){let Be=J.parentElement,at=J.closest("table"),ze=Array.from(Be?.children||[]).indexOf(J);for(let ft of (J.getAttribute("headers")||"").split(/\s+/).filter(Boolean)){let It=document.getElementById(ft);It&&ie.push(C(It.textContent||"",80));}if(at&&ze>=0){for(let It of Array.from(at.querySelectorAll("tr"))){let Se=It.children[ze];Se&&Se!==J&&Se.tagName==="TH"&&ie.push(C(Se.textContent||"",80));let At=It.children[0];It===Be&&At&&At!==J&&At.tagName==="TH"&&ie.push(C(At.textContent||"",80));}let ft=at.querySelector("tr > th[colspan]");ft&&ft!==J&&!ie.length&&ie.push(C(ft.textContent||"",80));}}let be=P.closest("p"),Pe=be||K.length||J?null:P.parentElement,Re=P.getAttribute("href")||"",pe=Re.startsWith("#")&&Re.length>1?document.getElementById(decodeURIComponent(Re.slice(1))):null;ne("link",{selector:y(P),html:O(P),rect:F(P),name:C(Y,160),href:C(Re,200),describedBy:S(P.getAttribute("aria-describedby")),context:{paragraph:be?C(be.innerText||be.textContent||"",300):"",listItems:K,cell:J?C(J.innerText||"",160):"",headers:ie},siblingText:C([Z(P.closest("ul, ol, table, p")||P),Pe&&Pe!==document.body?Pe.innerText:""].filter(Boolean).join(" | "),240),target:pe?C(pe.innerText||pe.textContent||"",160):""});}let le=P=>{let z=P.tagName.match(/^H([1-6])$/);return z?Number(z[1]):j(P)==="heading"?Number(P.getAttribute("aria-level"))||2:0},fe=()=>Array.from(document.querySelectorAll("h1, h2, h3, h4, h5, h6, [role=heading]")).filter(P=>$(P)&&!R(P)&&!A(P));if(_.has("heading"))for(let P of fe()){let z=le(P),Y=C(q(P),160);if(!Y)continue;let K=(P.textContent||"").trim().length,J=document.body;for(let pe=P.parentElement;pe&&pe!==document.body;pe=pe.parentElement)if((pe.textContent||"").trim().length-K>=40){J=pe;break}let ie="",be=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);be.currentNode=P;for(let pe=be.nextNode();pe&&ie.length<400&&J.contains(pe);pe=be.nextNode()){let Be=pe.parentElement;if(!Be||P.contains(Be)||/^(script|style|noscript|template)$/i.test(Be.tagName)||R(Be)||!$(Be))continue;let at=Be.closest("h1, h2, h3, h4, h5, h6, [role=heading]");if(at&&at!==P&&le(at)<=z)break;at||(ie+=" "+(pe.textContent||""));}let Pe=Array.from(P.querySelectorAll("a[href]")),Re=Pe.length===1&&(Pe[0].textContent||"").replace(/\s+/g," ").trim()===(P.textContent||"").replace(/\s+/g," ").trim();ne("heading",{selector:y(P),html:O(P),rect:F(P),level:z,text:Y,visible:I(P)&&!B(P),section:C(ie,400),linkTitle:Re});}if(_.has("formField")){let P=Array.from(document.querySelectorAll("input, select, textarea, [role=textbox], [role=combobox], [role=searchbox], [role=spinbutton], [role=listbox]")).filter(K=>!/^(hidden|submit|button|reset|image)$/i.test(K.type||"")&&!A(K)),z=K=>C(Array.from(K.labels||[]).map(J=>J.textContent||"").join(" ")||S(K.getAttribute("aria-labelledby")),60),Y=fe();for(let K of P){let J=[...Array.from(K.labels||[])];for(let pe of (K.getAttribute("aria-labelledby")||"").split(/\s+/).filter(Boolean)){let Be=document.getElementById(pe);Be&&J.push(Be);}if(/^(none|presentation)$/.test(j(K)))continue;let ie=J.map(pe=>({text:C(pe.textContent||"",120),visible:I(pe)&&!B(pe),inTree:$(pe)&&!R(pe)})).filter(pe=>pe.visible);if(!ie.length)continue;let be=K.closest("fieldset")?.querySelector("legend"),Pe=Y.filter(pe=>pe.compareDocumentPosition(K)&Node.DOCUMENT_POSITION_FOLLOWING).pop(),Re=be||Pe||null;ne("formField",{selector:y(K),html:O(K),rect:F(K),type:K.type||K.tagName.toLowerCase(),role:j(K),nameAttr:K.getAttribute("name")||"",rendered:I(K),disabled:K.disabled===true,labels:ie,groupHeading:Re?{text:C(Re.textContent||"",100),visible:I(Re)}:null,otherLabels:P.filter(pe=>pe!==K).map(z).filter(Boolean).slice(0,10)});}}if(_.has("control")){let P="button, a[href], [role=button], [role=link], [role=checkbox], [role=menuitem], [role=menuitemcheckbox], [role=menuitemradio], [role=option], [role=radio], [role=switch], [role=tab], [role=treeitem], [role=gridcell]";for(let z of Array.from(document.querySelectorAll(P))){if(A(z)||!$(z)||R(z)||!z.hasAttribute("aria-label")&&!z.hasAttribute("aria-labelledby"))continue;let Y=ee(z),K=C(Y.map((ie,be)=>(be&&Y[be-1].block!==ie.block?" ":"")+ie.raw).join(""),200);if(!K)continue;let J=C(Y.filter(ie=>ie.prominent).map(ie=>ie.text).join(" "),200);ne("control",{selector:y(z),html:O(z),rect:F(z),role:j(z)||z.tagName.toLowerCase(),name:C(q(z),200),visibleText:K,titleText:J,fontFamily:C(H(z).fontFamily,80)});}}let me=P=>{let z=(P||"").trim().split("-")[0].toLowerCase();if(!/^[a-z]{2,3}$/.test(z))return false;try{let K=new Intl.DisplayNames(["en"],{type:"language"}).of(z);return !!K&&K.toLowerCase()!==z}catch{return z.length===2}},oe=P=>{let z="",Y=[],K=P===document.documentElement&&document.body||P;if(!K)return {text:z,names:Y};let J=document.createTreeWalker(K,NodeFilter.SHOW_TEXT);for(let ie=J.nextNode();ie&&z.length<600;ie=J.nextNode()){let be=ie.parentElement;!be||/^(script|style|title)$/i.test(be.tagName)||be.closest("[lang]")===P&&(!$(be)||R(be)||(z+=" "+(ie.textContent||"")));}for(let ie of Array.from(K.querySelectorAll("[alt], [aria-label], [aria-labelledby]"))){if(ie.closest("[lang]")!==P||R(ie))continue;let be=C(q(ie),120);if(be&&Y.push(be),Y.length>=8)break}return {text:C(z,600),names:Y}};if(_.has("page")&&document.documentElement.namespaceURI==="http://www.w3.org/1999/xhtml"){let P=document.documentElement,z=P.getAttribute("lang")||"",Y=oe(P);ne("page",{selector:"html",html:C(`<html lang="${z}"><title>${document.title}</title>`,300),title:C(document.title||"",200),hasTitle:!!(document.title||"").trim(),lang:z,hasLang:me(z)&&!!(Y.text||Y.names.length),headings:fe().slice(0,10).map(K=>`h${le(K)} ${C(q(K),80)}`),text:C(document.body?.innerText||"",500),ownText:Y.text,ownNames:Y.names});}if(_.has("langElement"))for(let P of Array.from(document.querySelectorAll("body [lang], body[lang]"))){if(A(P))continue;let z=P.getAttribute("lang")||"";if(!me(z))continue;let Y=oe(P);!Y.text&&!Y.names.length||ne("langElement",{selector:y(P),html:O(P),rect:F(P),lang:z,ownText:Y.text,ownNames:Y.names});}if(_.has("form"))for(let P of Array.from(document.querySelectorAll("form"))){if(A(P))continue;let Y=Array.from(P.querySelectorAll("input, select, textarea")).filter(J=>!/^(hidden|submit|button|reset|image)$/i.test(J.type||"")).slice(0,15).map(J=>{let ie=J;return {label:C(q(J),80),type:ie.type||J.tagName.toLowerCase(),value:C(ie.value||"",40),required:ie.required===true,ariaInvalid:J.getAttribute("aria-invalid")||"",valid:typeof ie.checkValidity=="function"?ie.checkValidity():true,describedBy:S(J.getAttribute("aria-describedby")||J.getAttribute("aria-errormessage"))}}),K=[];for(let J of Array.from(P.querySelectorAll("*")))if(!(/^(label|legend|button|option|script|style|input|select|textarea)$/i.test(J.tagName)||J.closest("label, legend, button")||!Array.from(J.childNodes).filter(be=>be.nodeType===3).map(be=>be.textContent||"").join(" ").trim())&&(K.push({text:C(J.textContent||"",200),visible:I(J),ariaHidden:R(J)}),K.length>=10))break;ne("form",{selector:y(P),html:O(P),rect:F(P),hasMessages:K.length>0,fields:Y,messages:K});}if(_.has("iframeGroup")){let P=[],z=(K,J,ie,be)=>{if(!(be>3)){for(let Pe of Array.from(K.querySelectorAll("*")))if(Pe.shadowRoot&&z(Pe.shadowRoot,"shadow",ie||Pe,be+1),Pe.tagName==="IFRAME"){P.push({el:Pe,scope:J,host:ie||Pe});try{let Re=Pe.contentDocument;Re&&z(Re,"nested-frame",ie||Pe,be+1);}catch{}}}};z(document,"top",null,0);let Y=new Map;for(let K of P){if(A(K.host)||!$(K.el)||R(K.el))continue;let J=C(q(K.el),120).toLowerCase();J&&(Y.get(J)||Y.set(J,[]).get(J)).push(K);}for(let[K,J]of Y)J.length<2||ne("iframeGroup",{selector:y(J[0].host),html:O(J[0].el),rect:F(J[0].host),name:K,frames:J.slice(0,6).map(ie=>{let be="",Pe="";try{let Re=ie.el.contentDocument;be=C(Re?.title||"",100),Pe=C(Re?.body?.innerText||Re?.body?.textContent||"",300);}catch{}return {selector:y(ie.el),scope:ie.scope,src:C(ie.el.getAttribute("src")||(ie.el.hasAttribute("srcdoc")?"srcdoc":""),200),docTitle:be,text:Pe,inTree:$(ie.el)&&!R(ie.el)}})});}if(_.has("textBlocks")){let P=[];for(let J of fe().slice(0,12))P.push(`heading h${le(J)}: ${C(q(J),60)}`);let z=Array.from(document.querySelectorAll("nav, main, aside, header, footer, [role=navigation], [role=main], [role=complementary], [role=banner], [role=contentinfo], [role=region], [role=search]")).filter(J=>$(J));for(let J of z.slice(0,10))P.push(`landmark ${j(J)||J.tagName.toLowerCase()}${J.getAttribute("aria-label")||J.getAttribute("aria-labelledby")?` named "${C(q(J)||S(J.getAttribute("aria-labelledby")),40)}"`:" (unnamed)"}`);for(let J of Array.from(document.querySelectorAll("button, a[href], [role=button]")).filter(ie=>$(ie)).slice(0,15))P.push(`${J.tagName.toLowerCase()==="a"?"link":"button"}: ${C(q(J),50)}`);for(let J of Array.from(document.querySelectorAll("iframe")).slice(0,4)){let ie="";try{let be=J.contentDocument;ie=be?Array.from(be.querySelectorAll("h1, h2, h3, h4, h5, h6")).map(Pe=>C(Pe.textContent||"",40)).join("; "):"";}catch{}P.push(`iframe title "${C(J.getAttribute("title")||"",40)}" headings inside: ${ie||"none"}`);}let Y=P.join(`
|
|
1018
|
-
`),K=Array.from(document.querySelectorAll("p, li, td, th, dd, dt, label, figcaption, blockquote, caption, div, span")).filter(J=>!A(J)&&Array.from(J.childNodes).some(ie=>ie.nodeType===3&&(ie.textContent||"").trim().length>2));for(let J of K){if(J.parentElement&&K.includes(J.parentElement))continue;let ie=I(J)&&!B(J);!$(J)||!ie&&R(J)||ne("textBlocks",{selector:y(J),html:O(J),rect:F(J),text:C(J.textContent||"",220),visible:ie,ariaHidden:R(J),outline:Y});}}return {...w,cut:E}}async function Ob(f,d,h=Pb){if(!d.length)return {};try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");}catch{}try{return await f.evaluate(DO,{kinds:d,max:h,caps:{...Lb,...h<Pb?Object.fromEntries(Object.keys(Lb).map(m=>[m,h])):{}},own:ua})}catch{return {}}}var Pb,_O,Lb,Nb=Fe(()=>{xr();Pb=40,_O=400,Lb={control:_O};});function qb(f){let d=f;for(let h="";h!==d;)h=d,d=d.replace(kO," ");return d=d.toLowerCase().normalize("NFKD").replace(EO," ").trim(),d?d.split(/\s+/):[]}function CO(f){let d=qb(f);return d.length===1&&[...d[0].replace(/\p{M}/gu,"")].length===1&&/^\p{L}/u.test(d[0])?[]:d}function Bb(f,d){let h=CO(f);if(!h.length)return true;let m=qb(d);for(let p=0;p+h.length<=m.length;p++){let v=true;for(let _=0;_<h.length&&v;_++)v=m[p+_]===h[_];if(v)return true}return false}var EO,kO,Hb=Fe(()=>{EO=/[^\p{L}\p{N}\p{M}]+/gu,kO=/\([^()]*\)/g;});var jb={};pr(jb,{RUBRIC_BATCH_SIZE:()=>Vb,parseRubricVerdicts:()=>pi,rubricPromptHash:()=>mi,rubricSystemPrompt:()=>fa,rubricTransport:()=>$b,runRubrics:()=>MO});function $b(f){return f.transport?f.transport:f.apiKey?cc({apiKey:f.apiKey,baseUrl:f.baseUrl,visionModel:f.visionModel,textModel:f.textModel}):f.apiUrl?dc({apiUrl:f.apiUrl,token:f.apiToken,internalSecret:f.internalSecret}):null}function RO(f,d){if(f.evidence==="control"){let h=d;if(h.visibleText.trim()&&Bb(h.visibleText,h.name))return {aspect:f.id,selector:h.selector,verdict:"passed",reason:"the ACT label-in-name algorithm finds the visible label in the accessible name",by:"rule"}}return null}function IO(f){let{selector:d,html:h,rect:m,outline:p,...v}=f;return v}async function MO(f,d){let h={findings:[],verdicts:[],inapplicable:[],undecided:0,undecidedWcag:[],calls:0,errors:[]},m=$b(d.judge);if(!m)return h;let p=d.level??d.judge.level??"AA",v=db.filter(R=>(d.aspects?d.aspects.includes(R.id):R.status!=="below-bar")&&Qr([{wcag:R.sc.join(","),level:R.level}],p).length>0);if(!v.length)return h;let _=Date.now()+(d.timeoutMs??d.judge.timeoutMs??SO),w=d.warnings??[];await ju(f,w);let E=[...new Set(v.map(R=>R.evidence))],C=globalThis.process?.env?.WA_STRICT_STATE==="1",A=await Vu(f,"rubric-evidence",w,()=>Ob(f,E),{strict:C,bugs:d.bugs});if(d.rootSelector){let{scopeIssuesToRoot:R}=await Promise.resolve().then(()=>(vi(),gi));for(let $ of E){let I=A[$]||[];if(!I.length)continue;let B=new Set((await R(f,I,d.rootSelector)).issues);A[$]=I.filter(ee=>B.has(ee));}}let y=d.judge.vision!==false&&typeof f.screenshot=="function",x=d.batchSize??Vb,D=fc(d.judge),F=async R=>{let $=(A[R.evidence]||[]).filter(T=>FO(R,T)),I=[];for(let T of $){let S=RO(R,T);S?h.verdicts.push(S):I.push(T);}let B=A.cut?.[R.evidence]??0,ee=T=>{T<=0||(h.undecided+=T,h.undecidedWcag.includes(R.sc[0])||h.undecidedWcag.push(R.sc[0]));};if(B&&(ee(B),h.errors.push(`${R.id}: ${B} candidates over the evidence cap`)),!$.length){B||h.inapplicable.push(R.id);return}let N=0;for(let T=0;T<I.length;T+=x){let S=_-Date.now();if(S<=0){ee(I.length-T),h.errors.push(`${R.id}: deadline`);return}let M=I.slice(T,T+x),q=[];for(let[me,oe]of M.entries()){let P;if(R.vision&&y&&N<TO&&oe.rect){let z=await pc(f,{rect:oe.rect,hidden:false,tag:String(oe.tag||"")},D);N++,P=z?.data;}q.push({id:`${R.id}#${T+me}`,type:R.issueType,wcag:R.sc[0],message:R.title,selector:String(oe.selector),html:String(oe.html||""),context:IO(oe),...P?{screenshot:P}:{}});}let j=M.find(me=>typeof me.outline=="string")?.outline,W=new AbortController,Z=setTimeout(()=>W.abort(),S),ne=null,le=false;h.calls++;try{let me=await Promise.race([m({url:d.url,level:p,vision:R.vision&&y,items:q,system:fa(R),rubric:{id:R.id,hash:mi(R)},...j?{page:{outline:j}}:{}},W.signal),new Promise((oe,P)=>W.signal.addEventListener("abort",()=>P(new Error("rubric deadline"))))]);ne=pi(me),ne||h.errors.push(`${R.id}: malformed output`);}catch(me){h.errors.push(`${R.id}: ${me.message.slice(0,80)}`),le=me instanceof bn;}finally{clearTimeout(Z);}let fe=new Map(q.map((me,oe)=>[me.id,M[oe]]));for(let me of ne||[]){let oe=fe.get(me.id);if(!oe||me.verdict==="cantTell")continue;fe.delete(me.id);let P=uc(me.reason);h.verdicts.push({aspect:R.id,selector:String(oe.selector),verdict:me.verdict,reason:P,by:"model"}),me.verdict==="failed"&&h.findings.push({id:`rubric-${R.id}-${Mn(String(oe.selector))}`,source:"webability",type:R.issueType,wcag:R.sc[0],level:R.level,impact:R.impact,message:`${R.title}: ${P||"failed the rubric"}`,selector:String(oe.selector),html:String(oe.html||"")});}if(ee(fe.size),le){ee(I.length-T-M.length);return}}},O=[...v],H=Array.from({length:Math.max(1,d.concurrency??3)},async()=>{for(let R=O.shift();R;R=O.shift())await F(R);});return await Promise.all(H),h.findings=await $u(f,h.findings,d.bugs),h}var Vb,SO,TO,FO,zb=Fe(()=>{da();mc();xr();zu();nc();ac();Nb();Hb();Vb=8,SO=45e3,TO=12;FO=(f,d)=>f.where.every(h=>d[h.field]===h.value);});var Yo={mobile:{width:375,height:667},tablet:{width:768,height:1024},desktop:{width:1280,height:720}};zu();var qv="1.19.0";da();Zu();async function Wv(f,d){return Ju("axe",f,()=>pL(f,d))}async function pL(f,d){try{let{AxeBuilder:h}=await import('@axe-core/playwright'),m=typeof f.mainFrame=="function"?f:f.axePage?.()??f,p=await new h({page:m}).options({rules:Wu(d)}).withTags(d).analyze();return await gL(f,p)}catch{return mL(f,d)}}async function mL(f,d){let h=await Promise.resolve().then(()=>BM(Gv())),m=h.source??h.default?.source;if(!m)throw new Error("axe-core source unavailable");try{await f.evaluate(m);}catch{let{inject:v}=await Promise.resolve().then(()=>(xr(),vn));await v(f,{tool:"axe",content:m});}return await f.evaluate(({wcagTags:v,rules:_})=>new Promise((w,E)=>{let C=window;if(!C.axe)return E(new Error("axe-core not loaded"));C.axe.run(document,{runOnly:{type:"tag",values:v},rules:_,resultTypes:["violations","incomplete"]}).then(w).catch(E);}),{wcagTags:d,rules:Wu(d)})}function hL(f,d){if(f=f.toLowerCase().replace(/^www\./,""),d=d.toLowerCase().replace(/^www\./,""),!f||!d)return false;if(f===d||f.endsWith("."+d)||d.endsWith("."+f))return true;let h=m=>{let p=m.split(".");if(p.length<=2)return m;let v=p[p.length-1],_=p[p.length-2],w=v.length===2&&["co","com","net","org","ac","gov","edu"].includes(_)?3:2;return p.slice(-w).join(".")};return h(f)===h(d)}async function gL(f,d){let h=new Set,m=C=>!Array.isArray(C)||C.length<2?null:JSON.stringify(C[0]);for(let C of [d.violations,d.incomplete])for(let A of C??[])for(let y of A.nodes??[]){let x=m(y.target);x&&h.add(x);}if(!h.size)return d;let p;try{p=await f.evaluate(C=>{let A={};for(let y of C){A[y]=null;try{let x=JSON.parse(y),D=Array.isArray(x)?x:[x],F=document,O=null;for(let I=0;I<D.length&&(O=F.querySelector(D[I]),!(!O||(I<D.length-1&&(F=O.shadowRoot),!F)));I++);if(!O||O.tagName!=="IFRAME"&&O.tagName!=="FRAME"||O.hasAttribute("srcdoc"))continue;let H=I=>I&&/^https?:/i.test(I)?I:"",R="",$=!1;try{R=H(O.contentWindow.location.href);}catch{$=!0;}if(R||(R=H(O.src)||H(O.getAttribute("data-src"))||H(O.getAttribute("data-lazy-src"))),!R){$&&(A[y]={frame:"",page:location.hostname});continue}A[y]={frame:new URL(R).hostname,page:location.hostname};}catch{}}return A},[...h]);}catch{return d}let v=C=>{let A=m(C),y=A?p[A]:null;return !y||y.frame&&hL(y.frame,y.page)?null:{insideFrameFrom:y.frame||"a cross-origin frame whose address cannot be read",pageHost:y.page,thirdPartyDocument:true}},_=[],w=(d.violations??[]).flatMap(C=>{let A=C.nodes??[],y=A.filter(D=>!v(D.target)),x=A.filter(D=>v(D.target)).map(D=>({...D,waEvidence:v(D.target)}));return x.length&&_.push({...C,nodes:x}),x.length?y.length?[{...C,nodes:y}]:[]:[C]}),E=(d.incomplete??[]).map(C=>C.nodes?.some(A=>v(A.target))?{...C,nodes:C.nodes.map(A=>v(A.target)?{...A,waEvidence:v(A.target)}:A)}:C);return {...d,violations:w,incomplete:[...E,..._]}}function Qu(f){let d=[],h=[];for(let m of f)m.confidence==="needs_review"||bL(m)?h.push(m):d.push(vL(m));return {verdicts:d,undecided:h}}function vL(f){if(f.confidence===void 0&&f.reviewReason===void 0&&f.evidence===void 0)return f;let{confidence:d,reviewReason:h,evidence:m,...p}=f;return p}function bL(f){let d=(f.type||"").toLowerCase(),h=f.wcag||"",m=f.html||"",p=(f.message||"").toLowerCase();if((d==="contrast_insufficient"||d==="color-contrast"||h==="1.4.3"||h==="1.4.11")&&yL(m))return "background uses gradient or image";if(d==="image_of_text"||h==="1.4.5"){let v=Uv(m,"src").toLowerCase();v.startsWith("data:")&&(v=v.split(",")[0]);let _=Uv(m,"alt").toLowerCase();if(/\b(logo|brand|wordmark|hero|banner|footer|marketing|promo|cover)\b/.test(v))return "brand imagery";if(_.length>0&&/\b(logo|brand|product screenshot|dashboard)\b/.test(_))return "branded imagery"}return (d==="inconsistent_navigation"||p.includes("inconsistent navigation"))&&(/<footer/i.test(m)||/<aside/i.test(m))?"footer/aside nav":""}function yL(f){return /background(-image)?\s*:\s*(?:linear-gradient|radial-gradient|conic-gradient|url\()/i.test(f)}function Uv(f,d){let h=new RegExp(`\\b${d}\\s*=\\s*"([^"]*)"`,"i"),m=f.match(h);return m?m[1]:""}tc();mc();async function oO(f){let d=F=>({verdict:"drop",why:F}),h=null;try{h=document.querySelector(f.selector);}catch{return d("bad selector")}if(!h||h.tagName!=="VIDEO")return d("not a video");let m=getComputedStyle(h),p=h.getBoundingClientRect();if(m.display==="none"||m.visibility==="hidden"||h.closest("[hidden]")||p.width<100||p.height<50)return d("not visible/large enough");if(h.error)return d("failed load");let v=h.currentSrc||h.getAttribute("src")||h.querySelector("source")?.getAttribute("src")||"";if(!v||/^(blob|data|about|javascript):/i.test(v)||/\.(m3u8|mpd)(\?|$)/i.test(v))return d("no direct src / MSE");let _=h.hasAttribute("muted")||h.muted,w=h.hasAttribute("controls"),E=h.hasAttribute("autoplay")||h.autoplay,C=h.hasAttribute("loop")||h.loop,A=w||E&&!_;if(!A){let F=/play|pause|mute|unmute|sound|volume/i;for(let O=h.parentElement,H=0;O&&H<3&&!A;O=O.parentElement,H++)A=Array.from(O.querySelectorAll('button, [role="button"]')).some(R=>F.test((R.getAttribute("aria-label")||"")+" "+(R.getAttribute("title")||"")+" "+(R.textContent||"")));}if(!A)return d("not user-playable");if(_&&C&&!w)return d("decorative loop");if(h.hasAttribute("muted")&&!w&&!E)return d("muted");if(Number.isFinite(h.duration)&&h.duration>0&&h.duration<5)return d("under 5s");await new Promise(F=>setTimeout(F,2e3));for(let F of Array.from(h.querySelectorAll("track"))){let O=(F.getAttribute("kind")||"subtitles").toLowerCase();if((O==="captions"||O==="subtitles")&&F.getAttribute("src"))return d("has caption track")}let y=h.textTracks;for(let F=0;y&&F<y.length;F++)if(y[F].kind==="captions"||y[F].kind==="subtitles")return d("has text track");let x=h,D=null;if(typeof x.mozHasAudio=="boolean"?D=x.mozHasAudio:x.audioTracks&&typeof x.audioTracks.length=="number"&&(D=x.audioTracks.length>0?true:null),D===null&&typeof x.webkitAudioDecodedByteCount=="number"&&x.webkitAudioDecodedByteCount>0&&(D=true),D===null)try{let F=new AbortController,O=setTimeout(()=>F.abort(),f.fetchMs),H=await fetch(v,{headers:{Range:"bytes=0-"+(f.rangeBytes-1)},signal:F.signal}),R=new Uint8Array(f.rangeBytes),$=0,I=H.body?H.body.getReader():null;if(I)try{for(;$<f.rangeBytes;){let{done:N,value:T}=await I.read();if(N||!T)break;let S=Math.min(T.length,f.rangeBytes-$);R.set(T.subarray(0,S),$),$+=S;}}finally{try{await I.cancel();}catch{}}clearTimeout(O);let B=(N,T=0)=>{e:for(let S=T;S<=$-N.length;S++){for(let M=0;M<N.length;M++)if(R[S+M]!==N[M])continue e;return S}return -1},ee=N=>Array.from(N).map(T=>T.charCodeAt(0));B(ee("ftyp"))>=0&&B(ee("moov"))>=0?D=B(ee("hdlr"))>=0&&B(ee("soun"))>=0:R[0]===26&&R[1]===69&&R[2]===223&&R[3]===163&&B([22,84,174,107])>=0&&(D=B([131,129,2])>=0);}catch{D=null;}return D!==true?d(D===false?"silent":"audio unknowable"):{verdict:"violation"}}async function xb(f,d){let h=d.filter(v=>v.type==="missing_captions"&&/^<video\b/i.test(v.html??"")&&v.selector).slice(0,10);if(h.length===0)return [];let m=[],p=Date.now()+1e4;try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");for(let v of h){if(Date.now()>p)break;let _=p-Date.now(),w,E=await Promise.race([f.evaluate(oO,{selector:v.selector,rangeBytes:1048576,fetchMs:4e3}),new Promise(C=>{w=setTimeout(()=>C(null),_);})]).finally(()=>w&&clearTimeout(w));if(!E)break;if(E.verdict==="violation"){let{confidence:C,reviewReason:A,evidence:y,...x}=v;m.push({...x,id:v.id.replace("axe-incomplete-","axe-"),message:"video has an audio track, can be played by the user, and has no captions or subtitles track (WCAG 1.2.2)"});}}}catch{}return m}function Db(){let f=p=>{let v=p.getBoundingClientRect();if(v.width===0||v.height===0)return false;let _=window.getComputedStyle(p);return _.visibility!=="hidden"&&_.display!=="none"&&_.opacity!=="0"},d=Array.from(document.querySelectorAll('input[type="password"]')),h=Array.from(document.querySelectorAll('button, input[type="submit"], a[role="button"]')).filter(f).map(p=>(p.value||p.textContent||"").trim().toLowerCase()).filter(p=>p.length>0&&p.length<40),m=Array.from(document.querySelectorAll("button, a")).filter(f).filter(p=>/sign in with|continue with|log in with/i.test(p.textContent||"")).length;return {passwordFields:d.length,visiblePasswordFields:d.filter(f).length,submitLabels:h,oauthButtons:m,formCount:document.querySelectorAll("form").length,bodyTextLength:(document.body?.innerText||"").trim().length,headingText:(document.querySelector("h1, h2")?.textContent||"").trim().slice(0,120).toLowerCase()}}var sO=/\b(log ?in|sign ?in|sign ?on|authenticate)\b/,lO=/\b(log ?in|sign ?in|sign ?on|authentication|welcome back|access denied|unauthori[sz]ed)\b/;function Ab(f){try{let d=new URL(f).pathname.toLowerCase();return /(^|\/)(login|signin|sign-in|log-in|auth|sso|session\/new|users\/sign_in)(\/|$)/.test(d)}catch{return false}}function Eb(f,d,h){if(Ab(d))return null;let m=_b(d)!==_b(h),p=f.submitLabels.some(y=>sO.test(y)),v=lO.test(f.headingText),_=Ab(h),w=[];_&&w.push("url"),p&&w.push("submit"),v&&w.push("heading"),m&&w.push("redirected");let E=f.visiblePasswordFields>0,C=f.oauthButtons>0&&f.bodyTextLength<600&&f.formCount<=1;if(!E&&!C||w.length<2)return null;let A=`${E?"password-field":"oauth-only"}+${w.join("+")}`;return {reason:`Scan did not reach the requested page \u2014 it landed on a sign-in page at ${h}. The findings would describe the login screen, not the intended page. Configure site authentication for this site, or scan a page that does not require a session.`,signal:A,finalUrl:h}}function _b(f){try{let d=new URL(f);return `${d.origin}${d.pathname.replace(/\/+$/,"")}`.toLowerCase()}catch{return f.toLowerCase()}}da();async function PO(f){try{return await f.evaluate(()=>{let d=(document.title||"").toLowerCase(),h=[["just a moment","Cloudflare"],["attention required","Cloudflare"],["checking your browser","Cloudflare"],["access to this page has been denied","PerimeterX/HUMAN"],["please verify you are a human","PerimeterX/HUMAN"],["verify you are human","bot-challenge"],["are you a robot","bot-challenge"],["you have been blocked","bot-challenge"],["request unsuccessful","Imperva/Incapsula"],["human verification","bot-challenge"],["additional security check is required","bot-challenge"]];for(let[v,_]of h)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!1};let m=[["#cf-chl-widget","Cloudflare"],["#challenge-running","Cloudflare"],["#cf-challenge-running","Cloudflare"],[".cf-browser-verification","Cloudflare"],["#cf-please-wait","Cloudflare"],["div.cf-error-details","Cloudflare"],["#px-captcha","PerimeterX/HUMAN"],["#distilCaptchaForm","Distil"],["form#challenge-form","bot-challenge"]];for(let[v,_]of m)if(document.querySelector(v))return {vendor:_,signal:`marker:${v}`,needsCorroboration:!1};if(window._cf_chl_opt)return {vendor:"Cloudflare",signal:"marker:window._cf_chl_opt",needsCorroboration:!1};let p=[["please wait...","Cloudflare"],["access denied","bot-challenge"]];for(let[v,_]of p)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!0};return null})}catch{return null}}async function LO(f){try{return await f.evaluate(()=>{let d=document.querySelectorAll("body *").length;if(d>250)return null;let h=['[id*="captcha" i]','[class*="captcha" i]','img[src*="captcha" i]','iframe[src*="recaptcha" i]','iframe[src*="hcaptcha" i]','iframe[src*="turnstile" i]','[name*="captcha" i]'];for(let p of h)try{if(document.querySelector(p))return {signal:`marker:${p}`,elements:d}}catch{}let m=(document.title||"").toLowerCase();return m.includes("captcha")||m.includes("security check")||m.includes("bot verification")?{signal:`title:"${document.title}"`,elements:d}:null})}catch{return null}}async function OO(f,d){let h=await PO(f),m=typeof d=="number"&&d>=400,p=h&&(!h.needsCorroboration||m)?h:null;if(!p&&!m)return null;let v=[];return p&&v.push(`served a ${p.vendor} bot-challenge / interstitial page`),m&&v.push(`main document returned HTTP ${d}`),{reason:`Scan did not reach the real page \u2014 the target ${v.join(" and ")}. The returned issue list reflects the challenge/error page, not the intended site.`,...p?{vendor:p.vendor}:{},...typeof d=="number"?{status:d}:{},...p?{signal:p.signal}:m?{signal:`status:${d}`}:{}}}async function bi(f,d){let h=typeof f=="string",m={wcagTags:Gu,includeAxe:true,deep:false,dismissModals:h,...d},p,v,_,w;if(h){_=f.startsWith("http")?f:`https://${f}`;let E=typeof m.viewport=="string"?Yo[m.viewport]??Yo.desktop:m.viewport??Yo.desktop;v=await(await import('playwright')).chromium.launch({headless:m.browser?.headless??true}),p=await(await v.newContext({viewport:E})).newPage();let y=await p.goto(_,{waitUntil:"domcontentloaded",timeout:m.browser?.timeout??3e4});w=typeof y?.status=="function"?y.status():void 0;}else p=f,_=p.url(),w=m.mainStatus;if(m.dismissModals)try{let{dismissModals:E}=await Promise.resolve().then(()=>(Cb(),kb));await E(p);}catch{}if(m.settle!==false)try{let{waitForRenderSettle:E}=await Promise.resolve().then(()=>(oa(),li));await E(p,typeof m.settle=="number"?m.settle:void 0);}catch{}if(!v){let{snapshotInteractionState:E}=await Promise.resolve().then(()=>(as(),ns));await E(p);}try{let E=await p.evaluate(()=>performance.timeOrigin);try{let P=await p.evaluate(Db),z=Eb(P,_,typeof p.url=="function"?p.url():_);if(z)return {url:_,timestamp:new Date().toISOString(),blocked:{reason:z.reason,signal:`auth-wall:${z.signal}`,...typeof w=="number"?{status:w}:{}},issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}}}catch{}let C=await OO(p,w);if(C)return {url:_,timestamp:new Date().toISOString(),blocked:C,issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}};let A=[],y=new Map,x=[],D=[],F=[],{guardDetectorState:O,dropToolingFindings:H}=await Promise.resolve().then(()=>(xr(),vn)),R=await LO(p);R&&D.push(`challenge:suspected-interstitial (${R.signal}; ${R.elements} elements) \u2014 this looks like a bot-challenge/CAPTCHA page, not the real site; results may be invalid`),await(await Promise.resolve().then(()=>(xr(),vn))).startProvenance(p);let{trackPageActivity:$,waitForInteractionSettle:I}=await Promise.resolve().then(()=>(oa(),li));m.settle!==!1&&await $(p);let{takeTurn:B}=await Promise.resolve().then(()=>(Zu(),jv)),ee=await B("detectors",p,()=>Nv(p,x,D,{internalBugs:F,extraSerialDetectors:m.extraSerialDetectors,experimental:m.experimental}));A.push(...ee.map(Vv));let{resetInteractionState:N,focusOnlyObscuredIndexes:T}=await Promise.resolve().then(()=>(as(),ns));if(await N(p),m.settle!==!1&&await I(p),m.includeAxe)try{let P=await O(p,"axe",D,()=>Wv(p,Bv(m.wcagTags??Gu,m.level)),{bugs:F});for(let z of P.violations){let Y=z.id==="target-size"?await T(p,z.nodes):new Set;for(let[K,J]of z.nodes.entries()){if(Y.has(K)){F.push({tool:"axe",kind:"finding-dropped",detail:"target-size obscured only by a focus-only element (scanner focus state)",selector:ca(J.target)});continue}A.push({id:`axe-${z.id}-${Mn(ca(J.target))}`,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(J.target),html:J.html?.slice(0,300)});}}for(let z of P.incomplete??[])for(let Y of z.nodes){let K=`axe-incomplete-${z.id}-${Mn(ca(Y.target))}`,J=Y.any?.[0]?.data?.messageKey;J&&y.set(K,J),A.push({id:K,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(Y.target),html:Y.html?.slice(0,300),confidence:"needs_review",...Y.waEvidence?{reviewReason:"this node is inside a frame served by another site; decide whether the page owner is responsible for it",evidence:Y.waEvidence}:{reviewReason:"axe-core flagged this as needing human review"}});}}catch(P){F.push({tool:"axe",kind:"engine-failed",detail:`axe-core threw, its findings are absent: ${P?.message??String(P)}`});}let{deduplicateIssues:S}=await Promise.resolve().then(()=>(Nn(),On)),M=Qu(A),q=S(M.verdicts);try{let{pruneInvisibleContrast:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{pruneHiddenIframeIssues:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));q=await P(p,q);}catch{}try{q=await H(p,q,F);}catch{}try{let{verifyAnimatedGifs:P}=await Promise.resolve().then(()=>(Mb(),Ib));q=await P(p,q);}catch{}if(m.deep&&m.deepApiKey)try{let P=await NO(_,q,m);q.push(...P);}catch{}if(m.rootSelector)try{let{scopeIssuesToRoot:P}=await Promise.resolve().then(()=>(vi(),gi)),z=await P(p,q,m.rootSelector);q=z.issues,z.warning&&D.push(z.warning);}catch{}q=Qr(q,m.level??"AA");let j=Qu(q),W=j.verdicts,Z=[],ne=[],le=new Set;try{if(ne=[...M.undecided,...j.undecided],m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));ne=(await J(p,ne,m.rootSelector)).issues;}let P=new Map;await N(p);let z=await O(p,"contrast-pixels",D,()=>nb(p,ne,y,P),{bugs:F}),Y=await xb(p,ne),K=[...z,...Y];if(le=new Set(K.map(J=>`${J.selector}|${J.wcag}`)),K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}{let J=ne.filter(be=>!le.has(`${be.selector}|${be.wcag}`)),ie=await wb(p,J,{...m.judge,url:_,level:m.judge?.level??m.level??"AA",measured:P});if(globalThis.process?.env?.WA_DEBUG_JUDGE&&console.error(`ai judge: ${J.length} undecided before judge, ${ie.promoted.length} promoted, ${ie.judged.filter(be=>be.verdict==="pass").length} passed`),Z=ie.judged,ie.promoted.length){let{deduplicateIssues:be}=await Promise.resolve().then(()=>(Nn(),On));W=be([...W,...Qr(ie.promoted,m.level??"AA")]);}}}catch{}let fe={count:0,wcag:[]};if(m.judge)try{let{runRubrics:P,rubricTransport:z}=await Promise.resolve().then(()=>(zb(),jb));if(z(m.judge)){await N(p);let Y=await P(p,{url:_,judge:m.judge,level:m.level??"AA",timeoutMs:m.judge.timeoutMs,bugs:F,warnings:D,rootSelector:m.rootSelector});fe={count:Y.undecided,wcag:Y.undecidedWcag};for(let J of Y.errors)D.push(`rubric ${J}`);let K=Qr(Y.findings,m.level??"AA");if(K.length&&m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));K=(await J(p,K,m.rootSelector)).issues;}if(K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}}}catch{}let me;{let P=new Set(Z.map(K=>K.id)),z=Qr(ne,m.level??"AA").filter(K=>!le.has(`${K.selector}|${K.wcag}`)&&!P.has(K.id.replace("axe-incomplete-","axe-"))),Y=z.length+fe.count;Y&&(me={count:Y,wcag:[...new Set([...z.map(K=>K.wcag),...fe.wcag])].sort()});}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));W=await P(p,W);}catch{}try{W=await H(p,W,F);}catch{}if(await p.evaluate(()=>performance.timeOrigin)!==E)throw new Error(`the page's document was replaced during the scan (navigation to ${p.url()}); the findings mix two documents`);{let{attachMutations:P,stopProvenance:z}=await Promise.resolve().then(()=>(xr(),vn));P(F,await z(p));}let oe={url:_,timestamp:new Date().toISOString(),engine:qv,issues:W,internal_bugs:F,incomplete:[],...Z.length?{judged:Z}:{},...x.length?{truncated:x}:{},...D.length?{engineWarnings:D}:{},...me?{unsettled:me}:{},...m.keepDetected?{detected:ee}:{},summary:Xu(W)};if(m.review!==!1&&m.deepApiKey)try{oe=await qO(oe,m);}catch{}return oe}finally{let{stopProvenance:E}=await Promise.resolve().then(()=>(xr(),vn));if(await E(p),v)await v.close();else {let{restoreInteractionState:C}=await Promise.resolve().then(()=>(as(),ns));await C(p);}}}async function NO(f,d,h){let m=h.deepApiUrl||"https://api.webability.io",p=await fetch(`${m}/cli/deep-scan`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${h.deepApiKey}`},body:JSON.stringify({url:f,standardIssues:d.slice(0,30).map(({source:_,...w})=>w)})});return p.ok?((await p.json()).issues??[]).map((_,w)=>({id:`deep-${w}-${Mn(_.selector||_.element||"")}`,source:"deep-analysis",type:`wcag-${_.wcag}`,wcag:_.wcag,level:"AA",impact:_.severity==="High"?"critical":_.severity==="Medium"?"serious":"moderate",message:_.message,selector:_.selector||_.element||""})):[]}function Gb(f){let d=f.fix?.attribute??"";return !!f.fix?.needsManualReview&&d!=="style"&&!d.startsWith("data-")}async function qO(f,d){let h=d.deepApiUrl||"https://api.webability.io",m=f.issues.filter(Gb);if(m.length===0)return f;try{let p=await fetch(`${h}/review-findings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d.deepApiKey}`},body:JSON.stringify({url:f.url,issues:m.slice(0,30).map(({source:E,...C})=>C)})});if(!p.ok)return f;let v=await p.json();if(!v.confirmed_ids)return f;let _=new Set(v.confirmed_ids),w=f.issues.filter(E=>!Gb(E)||_.has(E.id));return {...f,issues:w,summary:Xu(w)}}catch{return f}}function Ub(f){return {...f,issues:f.issues.map(({source:d,...h})=>h)}}async function BO(f,d){return Ub(await bi(f,{...d,dismissModals:false}))}var Wb=class{page;options;issues=new Map;observer=false;merged={};running=null;queued=false;constructor(d,h){this.page=d,this.options=h??{};}async analyze(d){return BO(this.page,{...this.options,...d})}record(d){for(let h of d.issues)this.issues.set(h.id,h);}onMutation(){return this.observer?this.running?(this.queued=true,this.running):(this.running=(async()=>{do{this.queued=false;try{this.record(await bi(this.page,{...this.merged,dismissModals:!1}));}catch{}}while(this.queued&&this.observer)})().finally(()=>{this.running=null;}),this.running):Promise.resolve()}async start(d){this.issues=new Map,this.observer=true,this.merged={...this.options,...d},this.record(await bi(this.page,{...this.merged,dismissModals:false})),await this.page.exposeFunction("__webabilityOnMutation",()=>this.onMutation()),await this.page.evaluate(()=>{let h=new MutationObserver(()=>{window.__webabilityOnMutation?.();});h.observe(document.body,{childList:true,subtree:true}),window.__webabilityObserver=h;});}async stop(){this.observer=false,await this.page.evaluate(()=>{window.__webabilityObserver?.disconnect();}).catch(()=>{}),await this.running?.catch(()=>{});let d=await bi(this.page,{...this.options,dismissModals:false});this.record(d);let h=Array.from(this.issues.values()),m={url:d.url,timestamp:d.timestamp,issues:h,incomplete:[],summary:{total:h.length,critical:h.filter(p=>p.impact==="critical").length,serious:h.filter(p=>p.impact==="serious").length,moderate:h.filter(p=>p.impact==="moderate").length,minor:h.filter(p=>p.impact==="minor").length,incomplete:0}};return this.issues=new Map,Ub(m)}};/*! Bundled license information:
|
|
1020
|
+
`),K=Array.from(document.querySelectorAll("p, li, td, th, dd, dt, label, figcaption, blockquote, caption, div, span")).filter(J=>!A(J)&&Array.from(J.childNodes).some(ie=>ie.nodeType===3&&(ie.textContent||"").trim().length>2));for(let J of K){if(J.parentElement&&K.includes(J.parentElement))continue;let ie=I(J)&&!B(J);!$(J)||!ie&&R(J)||ne("textBlocks",{selector:y(J),html:O(J),rect:F(J),text:C(J.textContent||"",220),visible:ie,ariaHidden:R(J),outline:Y});}}return {...w,cut:E}}async function Ob(f,d,h=Pb){if(!d.length)return {};try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");}catch{}try{return await f.evaluate(DO,{kinds:d,max:h,caps:{...Lb,...h<Pb?Object.fromEntries(Object.keys(Lb).map(m=>[m,h])):{}},own:ua})}catch{return {}}}var Pb,_O,Lb,Nb=Fe(()=>{xr();Pb=40,_O=400,Lb={control:_O};});function qb(f){let d=f;for(let h="";h!==d;)h=d,d=d.replace(kO," ");return d=d.toLowerCase().normalize("NFKD").replace(EO," ").trim(),d?d.split(/\s+/):[]}function CO(f){let d=qb(f);return d.length===1&&[...d[0].replace(/\p{M}/gu,"")].length===1&&/^\p{L}/u.test(d[0])?[]:d}function Bb(f,d){let h=CO(f);if(!h.length)return true;let m=qb(d);for(let p=0;p+h.length<=m.length;p++){let v=true;for(let _=0;_<h.length&&v;_++)v=m[p+_]===h[_];if(v)return true}return false}var EO,kO,Hb=Fe(()=>{EO=/[^\p{L}\p{N}\p{M}]+/gu,kO=/\([^()]*\)/g;});var jb={};pr(jb,{RUBRIC_BATCH_SIZE:()=>Vb,parseRubricVerdicts:()=>pi,rubricPromptHash:()=>mi,rubricSystemPrompt:()=>fa,rubricTransport:()=>$b,runRubrics:()=>MO});function $b(f){return f.transport?f.transport:f.apiKey?cc({apiKey:f.apiKey,baseUrl:f.baseUrl,visionModel:f.visionModel,textModel:f.textModel}):f.apiUrl?dc({apiUrl:f.apiUrl,token:f.apiToken,internalSecret:f.internalSecret}):null}function RO(f,d){if(f.evidence==="control"){let h=d;if(h.visibleText.trim()&&Bb(h.visibleText,h.name))return {aspect:f.id,selector:h.selector,verdict:"passed",reason:"the ACT label-in-name algorithm finds the visible label in the accessible name",by:"rule"}}return null}function IO(f){let{selector:d,html:h,rect:m,outline:p,...v}=f;return v}async function MO(f,d){let h={findings:[],verdicts:[],inapplicable:[],undecided:0,undecidedWcag:[],calls:0,errors:[]},m=$b(d.judge);if(!m)return h;let p=d.level??d.judge.level??"AA",v=db.filter(R=>(d.aspects?d.aspects.includes(R.id):R.status!=="below-bar"||!!d.judge.rubrics?.includes(R.id))&&Qr([{wcag:R.sc.join(","),level:R.level}],p).length>0);if(!v.length)return h;let _=Date.now()+(d.timeoutMs??d.judge.timeoutMs??SO),w=d.warnings??[];await ju(f,w);let E=[...new Set(v.map(R=>R.evidence))],C=globalThis.process?.env?.WA_STRICT_STATE==="1",A=await Vu(f,"rubric-evidence",w,()=>Ob(f,E),{strict:C,bugs:d.bugs});if(d.rootSelector){let{scopeIssuesToRoot:R}=await Promise.resolve().then(()=>(vi(),gi));for(let $ of E){let I=A[$]||[];if(!I.length)continue;let B=new Set((await R(f,I,d.rootSelector)).issues);A[$]=I.filter(ee=>B.has(ee));}}let y=d.judge.vision!==false&&typeof f.screenshot=="function",x=d.batchSize??Vb,D=fc(d.judge),F=async R=>{let $=(A[R.evidence]||[]).filter(T=>FO(R,T)),I=[];for(let T of $){let S=RO(R,T);S?h.verdicts.push(S):I.push(T);}let B=A.cut?.[R.evidence]??0,ee=T=>{T<=0||(h.undecided+=T,h.undecidedWcag.includes(R.sc[0])||h.undecidedWcag.push(R.sc[0]));};if(B&&(ee(B),h.errors.push(`${R.id}: ${B} candidates over the evidence cap`)),!$.length){B||h.inapplicable.push(R.id);return}let N=0;for(let T=0;T<I.length;T+=x){let S=_-Date.now();if(S<=0){ee(I.length-T),h.errors.push(`${R.id}: deadline`);return}let M=I.slice(T,T+x),q=[];for(let[me,oe]of M.entries()){let P;if(R.vision&&y&&N<TO&&oe.rect){let z=await pc(f,{rect:oe.rect,hidden:false,tag:String(oe.tag||"")},D);N++,P=z?.data;}q.push({id:`${R.id}#${T+me}`,type:R.issueType,wcag:R.sc[0],message:R.title,selector:String(oe.selector),html:String(oe.html||""),context:IO(oe),...P?{screenshot:P}:{}});}let j=M.find(me=>typeof me.outline=="string")?.outline,W=new AbortController,Z=setTimeout(()=>W.abort(),S),ne=null,le=false;h.calls++;try{let me=await Promise.race([m({url:d.url,level:p,vision:R.vision&&y,items:q,system:fa(R),rubric:{id:R.id,hash:mi(R)},...j?{page:{outline:j}}:{}},W.signal),new Promise((oe,P)=>W.signal.addEventListener("abort",()=>P(new Error("rubric deadline"))))]);ne=pi(me),ne||h.errors.push(`${R.id}: malformed output`);}catch(me){h.errors.push(`${R.id}: ${me.message.slice(0,80)}`),le=me instanceof bn;}finally{clearTimeout(Z);}let fe=new Map(q.map((me,oe)=>[me.id,M[oe]]));for(let me of ne||[]){let oe=fe.get(me.id);if(!oe||me.verdict==="cantTell")continue;fe.delete(me.id);let P=uc(me.reason);h.verdicts.push({aspect:R.id,selector:String(oe.selector),verdict:me.verdict,reason:P,by:"model"}),me.verdict==="failed"&&h.findings.push({id:`rubric-${R.id}-${Mn(String(oe.selector))}`,source:"webability",type:R.issueType,wcag:R.sc[0],level:R.level,impact:R.impact,message:`${R.title}: ${P||"failed the rubric"}`,selector:String(oe.selector),html:String(oe.html||"")});}if(ee(fe.size),le){ee(I.length-T-M.length);return}}},O=[...v],H=Array.from({length:Math.max(1,d.concurrency??3)},async()=>{for(let R=O.shift();R;R=O.shift())await F(R);});return await Promise.all(H),h.findings=await $u(f,h.findings,d.bugs),h}var Vb,SO,TO,FO,zb=Fe(()=>{da();mc();xr();zu();nc();ac();Nb();Hb();Vb=8,SO=45e3,TO=12;FO=(f,d)=>f.where.every(h=>d[h.field]===h.value);});var Yo={mobile:{width:375,height:667},tablet:{width:768,height:1024},desktop:{width:1280,height:720}};zu();var qv="1.19.1";da();Zu();async function Wv(f,d){return Ju("axe",f,()=>pL(f,d))}async function pL(f,d){try{let{AxeBuilder:h}=await import('@axe-core/playwright'),m=typeof f.mainFrame=="function"?f:f.axePage?.()??f,p=await new h({page:m}).options({rules:Wu(d)}).withTags(d).analyze();return await gL(f,p)}catch{return mL(f,d)}}async function mL(f,d){let h=await Promise.resolve().then(()=>BM(Gv())),m=h.source??h.default?.source;if(!m)throw new Error("axe-core source unavailable");try{await f.evaluate(m);}catch{let{inject:v}=await Promise.resolve().then(()=>(xr(),vn));await v(f,{tool:"axe",content:m});}return await f.evaluate(({wcagTags:v,rules:_})=>new Promise((w,E)=>{let C=window;if(!C.axe)return E(new Error("axe-core not loaded"));C.axe.run(document,{runOnly:{type:"tag",values:v},rules:_,resultTypes:["violations","incomplete"]}).then(w).catch(E);}),{wcagTags:d,rules:Wu(d)})}function hL(f,d){if(f=f.toLowerCase().replace(/^www\./,""),d=d.toLowerCase().replace(/^www\./,""),!f||!d)return false;if(f===d||f.endsWith("."+d)||d.endsWith("."+f))return true;let h=m=>{let p=m.split(".");if(p.length<=2)return m;let v=p[p.length-1],_=p[p.length-2],w=v.length===2&&["co","com","net","org","ac","gov","edu"].includes(_)?3:2;return p.slice(-w).join(".")};return h(f)===h(d)}async function gL(f,d){let h=new Set,m=C=>!Array.isArray(C)||C.length<2?null:JSON.stringify(C[0]);for(let C of [d.violations,d.incomplete])for(let A of C??[])for(let y of A.nodes??[]){let x=m(y.target);x&&h.add(x);}if(!h.size)return d;let p;try{p=await f.evaluate(C=>{let A={};for(let y of C){A[y]=null;try{let x=JSON.parse(y),D=Array.isArray(x)?x:[x],F=document,O=null;for(let I=0;I<D.length&&(O=F.querySelector(D[I]),!(!O||(I<D.length-1&&(F=O.shadowRoot),!F)));I++);if(!O||O.tagName!=="IFRAME"&&O.tagName!=="FRAME"||O.hasAttribute("srcdoc"))continue;let H=I=>I&&/^https?:/i.test(I)?I:"",R="",$=!1;try{R=H(O.contentWindow.location.href);}catch{$=!0;}if(R||(R=H(O.src)||H(O.getAttribute("data-src"))||H(O.getAttribute("data-lazy-src"))),!R){$&&(A[y]={frame:"",page:location.hostname});continue}A[y]={frame:new URL(R).hostname,page:location.hostname};}catch{}}return A},[...h]);}catch{return d}let v=C=>{let A=m(C),y=A?p[A]:null;return !y||y.frame&&hL(y.frame,y.page)?null:{insideFrameFrom:y.frame||"a cross-origin frame whose address cannot be read",pageHost:y.page,thirdPartyDocument:true}},_=[],w=(d.violations??[]).flatMap(C=>{let A=C.nodes??[],y=A.filter(D=>!v(D.target)),x=A.filter(D=>v(D.target)).map(D=>({...D,waEvidence:v(D.target)}));return x.length&&_.push({...C,nodes:x}),x.length?y.length?[{...C,nodes:y}]:[]:[C]}),E=(d.incomplete??[]).map(C=>C.nodes?.some(A=>v(A.target))?{...C,nodes:C.nodes.map(A=>v(A.target)?{...A,waEvidence:v(A.target)}:A)}:C);return {...d,violations:w,incomplete:[...E,..._]}}function Qu(f){let d=[],h=[];for(let m of f)m.confidence==="needs_review"||bL(m)?h.push(m):d.push(vL(m));return {verdicts:d,undecided:h}}function vL(f){if(f.confidence===void 0&&f.reviewReason===void 0&&f.evidence===void 0)return f;let{confidence:d,reviewReason:h,evidence:m,...p}=f;return p}function bL(f){let d=(f.type||"").toLowerCase(),h=f.wcag||"",m=f.html||"",p=(f.message||"").toLowerCase();if((d==="contrast_insufficient"||d==="color-contrast"||h==="1.4.3"||h==="1.4.11")&&yL(m))return "background uses gradient or image";if(d==="image_of_text"||h==="1.4.5"){let v=Uv(m,"src").toLowerCase();v.startsWith("data:")&&(v=v.split(",")[0]);let _=Uv(m,"alt").toLowerCase();if(/\b(logo|brand|wordmark|hero|banner|footer|marketing|promo|cover)\b/.test(v))return "brand imagery";if(_.length>0&&/\b(logo|brand|product screenshot|dashboard)\b/.test(_))return "branded imagery"}return (d==="inconsistent_navigation"||p.includes("inconsistent navigation"))&&(/<footer/i.test(m)||/<aside/i.test(m))?"footer/aside nav":""}function yL(f){return /background(-image)?\s*:\s*(?:linear-gradient|radial-gradient|conic-gradient|url\()/i.test(f)}function Uv(f,d){let h=new RegExp(`\\b${d}\\s*=\\s*"([^"]*)"`,"i"),m=f.match(h);return m?m[1]:""}tc();mc();async function oO(f){let d=F=>({verdict:"drop",why:F}),h=null;try{h=document.querySelector(f.selector);}catch{return d("bad selector")}if(!h||h.tagName!=="VIDEO")return d("not a video");let m=getComputedStyle(h),p=h.getBoundingClientRect();if(m.display==="none"||m.visibility==="hidden"||h.closest("[hidden]")||p.width<100||p.height<50)return d("not visible/large enough");if(h.error)return d("failed load");let v=h.currentSrc||h.getAttribute("src")||h.querySelector("source")?.getAttribute("src")||"";if(!v||/^(blob|data|about|javascript):/i.test(v)||/\.(m3u8|mpd)(\?|$)/i.test(v))return d("no direct src / MSE");let _=h.hasAttribute("muted")||h.muted,w=h.hasAttribute("controls"),E=h.hasAttribute("autoplay")||h.autoplay,C=h.hasAttribute("loop")||h.loop,A=w||E&&!_;if(!A){let F=/play|pause|mute|unmute|sound|volume/i;for(let O=h.parentElement,H=0;O&&H<3&&!A;O=O.parentElement,H++)A=Array.from(O.querySelectorAll('button, [role="button"]')).some(R=>F.test((R.getAttribute("aria-label")||"")+" "+(R.getAttribute("title")||"")+" "+(R.textContent||"")));}if(!A)return d("not user-playable");if(_&&C&&!w)return d("decorative loop");if(h.hasAttribute("muted")&&!w&&!E)return d("muted");if(Number.isFinite(h.duration)&&h.duration>0&&h.duration<5)return d("under 5s");await new Promise(F=>setTimeout(F,2e3));for(let F of Array.from(h.querySelectorAll("track"))){let O=(F.getAttribute("kind")||"subtitles").toLowerCase();if((O==="captions"||O==="subtitles")&&F.getAttribute("src"))return d("has caption track")}let y=h.textTracks;for(let F=0;y&&F<y.length;F++)if(y[F].kind==="captions"||y[F].kind==="subtitles")return d("has text track");let x=h,D=null;if(typeof x.mozHasAudio=="boolean"?D=x.mozHasAudio:x.audioTracks&&typeof x.audioTracks.length=="number"&&(D=x.audioTracks.length>0?true:null),D===null&&typeof x.webkitAudioDecodedByteCount=="number"&&x.webkitAudioDecodedByteCount>0&&(D=true),D===null)try{let F=new AbortController,O=setTimeout(()=>F.abort(),f.fetchMs),H=await fetch(v,{headers:{Range:"bytes=0-"+(f.rangeBytes-1)},signal:F.signal}),R=new Uint8Array(f.rangeBytes),$=0,I=H.body?H.body.getReader():null;if(I)try{for(;$<f.rangeBytes;){let{done:N,value:T}=await I.read();if(N||!T)break;let S=Math.min(T.length,f.rangeBytes-$);R.set(T.subarray(0,S),$),$+=S;}}finally{try{await I.cancel();}catch{}}clearTimeout(O);let B=(N,T=0)=>{e:for(let S=T;S<=$-N.length;S++){for(let M=0;M<N.length;M++)if(R[S+M]!==N[M])continue e;return S}return -1},ee=N=>Array.from(N).map(T=>T.charCodeAt(0));B(ee("ftyp"))>=0&&B(ee("moov"))>=0?D=B(ee("hdlr"))>=0&&B(ee("soun"))>=0:R[0]===26&&R[1]===69&&R[2]===223&&R[3]===163&&B([22,84,174,107])>=0&&(D=B([131,129,2])>=0);}catch{D=null;}return D!==true?d(D===false?"silent":"audio unknowable"):{verdict:"violation"}}async function xb(f,d){let h=d.filter(v=>v.type==="missing_captions"&&/^<video\b/i.test(v.html??"")&&v.selector).slice(0,10);if(h.length===0)return [];let m=[],p=Date.now()+1e4;try{await f.evaluate("if(typeof globalThis.__name==='undefined'){globalThis.__name=function(t){return t}}");for(let v of h){if(Date.now()>p)break;let _=p-Date.now(),w,E=await Promise.race([f.evaluate(oO,{selector:v.selector,rangeBytes:1048576,fetchMs:4e3}),new Promise(C=>{w=setTimeout(()=>C(null),_);})]).finally(()=>w&&clearTimeout(w));if(!E)break;if(E.verdict==="violation"){let{confidence:C,reviewReason:A,evidence:y,...x}=v;m.push({...x,id:v.id.replace("axe-incomplete-","axe-"),message:"video has an audio track, can be played by the user, and has no captions or subtitles track (WCAG 1.2.2)"});}}}catch{}return m}function Db(){let f=p=>{let v=p.getBoundingClientRect();if(v.width===0||v.height===0)return false;let _=window.getComputedStyle(p);return _.visibility!=="hidden"&&_.display!=="none"&&_.opacity!=="0"},d=Array.from(document.querySelectorAll('input[type="password"]')),h=Array.from(document.querySelectorAll('button, input[type="submit"], a[role="button"]')).filter(f).map(p=>(p.value||p.textContent||"").trim().toLowerCase()).filter(p=>p.length>0&&p.length<40),m=Array.from(document.querySelectorAll("button, a")).filter(f).filter(p=>/sign in with|continue with|log in with/i.test(p.textContent||"")).length;return {passwordFields:d.length,visiblePasswordFields:d.filter(f).length,submitLabels:h,oauthButtons:m,formCount:document.querySelectorAll("form").length,bodyTextLength:(document.body?.innerText||"").trim().length,headingText:(document.querySelector("h1, h2")?.textContent||"").trim().slice(0,120).toLowerCase()}}var sO=/\b(log ?in|sign ?in|sign ?on|authenticate)\b/,lO=/\b(log ?in|sign ?in|sign ?on|authentication|welcome back|access denied|unauthori[sz]ed)\b/;function Ab(f){try{let d=new URL(f).pathname.toLowerCase();return /(^|\/)(login|signin|sign-in|log-in|auth|sso|session\/new|users\/sign_in)(\/|$)/.test(d)}catch{return false}}function Eb(f,d,h){if(Ab(d))return null;let m=_b(d)!==_b(h),p=f.submitLabels.some(y=>sO.test(y)),v=lO.test(f.headingText),_=Ab(h),w=[];_&&w.push("url"),p&&w.push("submit"),v&&w.push("heading"),m&&w.push("redirected");let E=f.visiblePasswordFields>0,C=f.oauthButtons>0&&f.bodyTextLength<600&&f.formCount<=1;if(!E&&!C||w.length<2)return null;let A=`${E?"password-field":"oauth-only"}+${w.join("+")}`;return {reason:`Scan did not reach the requested page \u2014 it landed on a sign-in page at ${h}. The findings would describe the login screen, not the intended page. Configure site authentication for this site, or scan a page that does not require a session.`,signal:A,finalUrl:h}}function _b(f){try{let d=new URL(f);return `${d.origin}${d.pathname.replace(/\/+$/,"")}`.toLowerCase()}catch{return f.toLowerCase()}}da();async function PO(f){try{return await f.evaluate(()=>{let d=(document.title||"").toLowerCase(),h=[["just a moment","Cloudflare"],["attention required","Cloudflare"],["checking your browser","Cloudflare"],["access to this page has been denied","PerimeterX/HUMAN"],["please verify you are a human","PerimeterX/HUMAN"],["verify you are human","bot-challenge"],["are you a robot","bot-challenge"],["you have been blocked","bot-challenge"],["request unsuccessful","Imperva/Incapsula"],["human verification","bot-challenge"],["additional security check is required","bot-challenge"]];for(let[v,_]of h)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!1};let m=[["#cf-chl-widget","Cloudflare"],["#challenge-running","Cloudflare"],["#cf-challenge-running","Cloudflare"],[".cf-browser-verification","Cloudflare"],["#cf-please-wait","Cloudflare"],["div.cf-error-details","Cloudflare"],["#px-captcha","PerimeterX/HUMAN"],["#distilCaptchaForm","Distil"],["form#challenge-form","bot-challenge"]];for(let[v,_]of m)if(document.querySelector(v))return {vendor:_,signal:`marker:${v}`,needsCorroboration:!1};if(window._cf_chl_opt)return {vendor:"Cloudflare",signal:"marker:window._cf_chl_opt",needsCorroboration:!1};let p=[["please wait...","Cloudflare"],["access denied","bot-challenge"]];for(let[v,_]of p)if(d.includes(v))return {vendor:_,signal:`title:"${document.title}"`,needsCorroboration:!0};return null})}catch{return null}}async function LO(f){try{return await f.evaluate(()=>{let d=document.querySelectorAll("body *").length;if(d>250)return null;let h=['[id*="captcha" i]','[class*="captcha" i]','img[src*="captcha" i]','iframe[src*="recaptcha" i]','iframe[src*="hcaptcha" i]','iframe[src*="turnstile" i]','[name*="captcha" i]'];for(let p of h)try{if(document.querySelector(p))return {signal:`marker:${p}`,elements:d}}catch{}let m=(document.title||"").toLowerCase();return m.includes("captcha")||m.includes("security check")||m.includes("bot verification")?{signal:`title:"${document.title}"`,elements:d}:null})}catch{return null}}async function OO(f,d){let h=await PO(f),m=typeof d=="number"&&d>=400,p=h&&(!h.needsCorroboration||m)?h:null;if(!p&&!m)return null;let v=[];return p&&v.push(`served a ${p.vendor} bot-challenge / interstitial page`),m&&v.push(`main document returned HTTP ${d}`),{reason:`Scan did not reach the real page \u2014 the target ${v.join(" and ")}. The returned issue list reflects the challenge/error page, not the intended site.`,...p?{vendor:p.vendor}:{},...typeof d=="number"?{status:d}:{},...p?{signal:p.signal}:m?{signal:`status:${d}`}:{}}}async function bi(f,d){let h=typeof f=="string",m={wcagTags:Gu,includeAxe:true,deep:false,dismissModals:h,...d},p,v,_,w;if(h){_=f.startsWith("http")?f:`https://${f}`;let E=typeof m.viewport=="string"?Yo[m.viewport]??Yo.desktop:m.viewport??Yo.desktop;v=await(await import('playwright')).chromium.launch({headless:m.browser?.headless??true}),p=await(await v.newContext({viewport:E})).newPage();let y=await p.goto(_,{waitUntil:"domcontentloaded",timeout:m.browser?.timeout??3e4});w=typeof y?.status=="function"?y.status():void 0;}else p=f,_=p.url(),w=m.mainStatus;if(m.dismissModals)try{let{dismissModals:E}=await Promise.resolve().then(()=>(Cb(),kb));await E(p);}catch{}if(m.settle!==false)try{let{waitForRenderSettle:E}=await Promise.resolve().then(()=>(oa(),li));await E(p,typeof m.settle=="number"?m.settle:void 0);}catch{}if(!v){let{snapshotInteractionState:E}=await Promise.resolve().then(()=>(as(),ns));await E(p);}try{let E=await p.evaluate(()=>performance.timeOrigin);try{let P=await p.evaluate(Db),z=Eb(P,_,typeof p.url=="function"?p.url():_);if(z)return {url:_,timestamp:new Date().toISOString(),blocked:{reason:z.reason,signal:`auth-wall:${z.signal}`,...typeof w=="number"?{status:w}:{}},issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}}}catch{}let C=await OO(p,w);if(C)return {url:_,timestamp:new Date().toISOString(),blocked:C,issues:[],incomplete:[],internal_bugs:[],summary:{total:0,critical:0,serious:0,moderate:0,minor:0,incomplete:0}};let A=[],y=new Map,x=[],D=[],F=[],{guardDetectorState:O,dropToolingFindings:H}=await Promise.resolve().then(()=>(xr(),vn)),R=await LO(p);R&&D.push(`challenge:suspected-interstitial (${R.signal}; ${R.elements} elements) \u2014 this looks like a bot-challenge/CAPTCHA page, not the real site; results may be invalid`),await(await Promise.resolve().then(()=>(xr(),vn))).startProvenance(p);let{trackPageActivity:$,waitForInteractionSettle:I}=await Promise.resolve().then(()=>(oa(),li));m.settle!==!1&&await $(p);let{takeTurn:B}=await Promise.resolve().then(()=>(Zu(),jv)),ee=await B("detectors",p,()=>Nv(p,x,D,{internalBugs:F,extraSerialDetectors:m.extraSerialDetectors,experimental:m.experimental}));A.push(...ee.map(Vv));let{resetInteractionState:N,focusOnlyObscuredIndexes:T}=await Promise.resolve().then(()=>(as(),ns));if(await N(p),m.settle!==!1&&await I(p),m.includeAxe)try{let P=await O(p,"axe",D,()=>Wv(p,Bv(m.wcagTags??Gu,m.level)),{bugs:F});for(let z of P.violations){let Y=z.id==="target-size"?await T(p,z.nodes):new Set;for(let[K,J]of z.nodes.entries()){if(Y.has(K)){F.push({tool:"axe",kind:"finding-dropped",detail:"target-size obscured only by a focus-only element (scanner focus state)",selector:ca(J.target)});continue}A.push({id:`axe-${z.id}-${Mn(ca(J.target))}`,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(J.target),html:J.html?.slice(0,300)});}}for(let z of P.incomplete??[])for(let Y of z.nodes){let K=`axe-incomplete-${z.id}-${Mn(ca(Y.target))}`,J=Y.any?.[0]?.data?.messageKey;J&&y.set(K,J),A.push({id:K,source:"axe-core",type:z.id,wcag:Ku(z.tags),level:Yu(z.tags),impact:Uu(z.impact),message:z.help,selector:ca(Y.target),html:Y.html?.slice(0,300),confidence:"needs_review",...Y.waEvidence?{reviewReason:"this node is inside a frame served by another site; decide whether the page owner is responsible for it",evidence:Y.waEvidence}:{reviewReason:"axe-core flagged this as needing human review"}});}}catch(P){F.push({tool:"axe",kind:"engine-failed",detail:`axe-core threw, its findings are absent: ${P?.message??String(P)}`});}let{deduplicateIssues:S}=await Promise.resolve().then(()=>(Nn(),On)),M=Qu(A),q=S(M.verdicts);try{let{pruneInvisibleContrast:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{pruneHiddenIframeIssues:P}=await Promise.resolve().then(()=>(oa(),li));q=await P(p,q);}catch{}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));q=await P(p,q);}catch{}try{q=await H(p,q,F);}catch{}try{let{verifyAnimatedGifs:P}=await Promise.resolve().then(()=>(Mb(),Ib));q=await P(p,q);}catch{}if(m.deep&&m.deepApiKey)try{let P=await NO(_,q,m);q.push(...P);}catch{}if(m.rootSelector)try{let{scopeIssuesToRoot:P}=await Promise.resolve().then(()=>(vi(),gi)),z=await P(p,q,m.rootSelector);q=z.issues,z.warning&&D.push(z.warning);}catch{}q=Qr(q,m.level??"AA");let j=Qu(q),W=j.verdicts,Z=[],ne=[],le=new Set;try{if(ne=[...M.undecided,...j.undecided],m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));ne=(await J(p,ne,m.rootSelector)).issues;}let P=new Map;await N(p);let z=await O(p,"contrast-pixels",D,()=>nb(p,ne,y,P),{bugs:F}),Y=await xb(p,ne),K=[...z,...Y];if(le=new Set(K.map(J=>`${J.selector}|${J.wcag}`)),K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}{let J=ne.filter(be=>!le.has(`${be.selector}|${be.wcag}`)),ie=await wb(p,J,{...m.judge,url:_,level:m.judge?.level??m.level??"AA",measured:P});if(globalThis.process?.env?.WA_DEBUG_JUDGE&&console.error(`ai judge: ${J.length} undecided before judge, ${ie.promoted.length} promoted, ${ie.judged.filter(be=>be.verdict==="pass").length} passed`),Z=ie.judged,ie.promoted.length){let{deduplicateIssues:be}=await Promise.resolve().then(()=>(Nn(),On));W=be([...W,...Qr(ie.promoted,m.level??"AA")]);}}}catch{}let fe={count:0,wcag:[]};if(m.judge)try{let{runRubrics:P,rubricTransport:z}=await Promise.resolve().then(()=>(zb(),jb));if(z(m.judge)){await N(p);let Y=await P(p,{url:_,judge:m.judge,level:m.level??"AA",timeoutMs:m.judge.timeoutMs,bugs:F,warnings:D,rootSelector:m.rootSelector});fe={count:Y.undecided,wcag:Y.undecidedWcag};for(let J of Y.errors)D.push(`rubric ${J}`);let K=Qr(Y.findings,m.level??"AA");if(K.length&&m.rootSelector){let{scopeIssuesToRoot:J}=await Promise.resolve().then(()=>(vi(),gi));K=(await J(p,K,m.rootSelector)).issues;}if(K.length){let{deduplicateIssues:J}=await Promise.resolve().then(()=>(Nn(),On));W=J([...W,...K]);}}}catch{}let me;{let P=new Set(Z.map(K=>K.id)),z=Qr(ne,m.level??"AA").filter(K=>!le.has(`${K.selector}|${K.wcag}`)&&!P.has(K.id.replace("axe-incomplete-","axe-"))),Y=z.length+fe.count;Y&&(me={count:Y,wcag:[...new Set([...z.map(K=>K.wcag),...fe.wcag])].sort()});}try{let{dedupeByElementIdentity:P}=await Promise.resolve().then(()=>(Nn(),On));W=await P(p,W);}catch{}try{W=await H(p,W,F);}catch{}if(await p.evaluate(()=>performance.timeOrigin)!==E)throw new Error(`the page's document was replaced during the scan (navigation to ${p.url()}); the findings mix two documents`);{let{attachMutations:P,stopProvenance:z}=await Promise.resolve().then(()=>(xr(),vn));P(F,await z(p));}let oe={url:_,timestamp:new Date().toISOString(),engine:qv,issues:W,internal_bugs:F,incomplete:[],...Z.length?{judged:Z}:{},...x.length?{truncated:x}:{},...D.length?{engineWarnings:D}:{},...me?{unsettled:me}:{},...m.keepDetected?{detected:ee}:{},summary:Xu(W)};if(m.review!==!1&&m.deepApiKey)try{oe=await qO(oe,m);}catch{}return oe}finally{let{stopProvenance:E}=await Promise.resolve().then(()=>(xr(),vn));if(await E(p),v)await v.close();else {let{restoreInteractionState:C}=await Promise.resolve().then(()=>(as(),ns));await C(p);}}}async function NO(f,d,h){let m=h.deepApiUrl||"https://api.webability.io",p=await fetch(`${m}/cli/deep-scan`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${h.deepApiKey}`},body:JSON.stringify({url:f,standardIssues:d.slice(0,30).map(({source:_,...w})=>w)})});return p.ok?((await p.json()).issues??[]).map((_,w)=>({id:`deep-${w}-${Mn(_.selector||_.element||"")}`,source:"deep-analysis",type:`wcag-${_.wcag}`,wcag:_.wcag,level:"AA",impact:_.severity==="High"?"critical":_.severity==="Medium"?"serious":"moderate",message:_.message,selector:_.selector||_.element||""})):[]}function Gb(f){let d=f.fix?.attribute??"";return !!f.fix?.needsManualReview&&d!=="style"&&!d.startsWith("data-")}async function qO(f,d){let h=d.deepApiUrl||"https://api.webability.io",m=f.issues.filter(Gb);if(m.length===0)return f;try{let p=await fetch(`${h}/review-findings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${d.deepApiKey}`},body:JSON.stringify({url:f.url,issues:m.slice(0,30).map(({source:E,...C})=>C)})});if(!p.ok)return f;let v=await p.json();if(!v.confirmed_ids)return f;let _=new Set(v.confirmed_ids),w=f.issues.filter(E=>!Gb(E)||_.has(E.id));return {...f,issues:w,summary:Xu(w)}}catch{return f}}function Ub(f){return {...f,issues:f.issues.map(({source:d,...h})=>h)}}async function BO(f,d){return Ub(await bi(f,{...d,dismissModals:false}))}var Wb=class{page;options;issues=new Map;observer=false;merged={};running=null;queued=false;constructor(d,h){this.page=d,this.options=h??{};}async analyze(d){return BO(this.page,{...this.options,...d})}record(d){for(let h of d.issues)this.issues.set(h.id,h);}onMutation(){return this.observer?this.running?(this.queued=true,this.running):(this.running=(async()=>{do{this.queued=false;try{this.record(await bi(this.page,{...this.merged,dismissModals:!1}));}catch{}}while(this.queued&&this.observer)})().finally(()=>{this.running=null;}),this.running):Promise.resolve()}async start(d){this.issues=new Map,this.observer=true,this.merged={...this.options,...d},this.record(await bi(this.page,{...this.merged,dismissModals:false})),await this.page.exposeFunction("__webabilityOnMutation",()=>this.onMutation()),await this.page.evaluate(()=>{let h=new MutationObserver(()=>{window.__webabilityOnMutation?.();});h.observe(document.body,{childList:true,subtree:true}),window.__webabilityObserver=h;});}async stop(){this.observer=false,await this.page.evaluate(()=>{window.__webabilityObserver?.disconnect();}).catch(()=>{}),await this.running?.catch(()=>{});let d=await bi(this.page,{...this.options,dismissModals:false});this.record(d);let h=Array.from(this.issues.values()),m={url:d.url,timestamp:d.timestamp,issues:h,incomplete:[],summary:{total:h.length,critical:h.filter(p=>p.impact==="critical").length,serious:h.filter(p=>p.impact==="serious").length,moderate:h.filter(p=>p.impact==="moderate").length,minor:h.filter(p=>p.impact==="minor").length,incomplete:0}};return this.issues=new Map,Ub(m)}};/*! Bundled license information:
|
|
1019
1021
|
|
|
1020
1022
|
axe-core/axe.js:
|
|
1021
1023
|
(*! axe v4.11.3
|
|
@@ -165,6 +165,11 @@ interface JudgeOptions {
|
|
|
165
165
|
* the hosted path (the endpoint answers 413 above it, PNG only), none elsewhere.
|
|
166
166
|
*/
|
|
167
167
|
maxCropChars?: number;
|
|
168
|
+
/**
|
|
169
|
+
* Opt-in rubric aspects (status: below-bar) to run as well as the default
|
|
170
|
+
* ones, by rubric id, e.g. ['heading-descriptive'].
|
|
171
|
+
*/
|
|
172
|
+
rubrics?: string[];
|
|
168
173
|
}
|
|
169
174
|
interface JudgeRunOptions extends JudgeOptions {
|
|
170
175
|
url: string;
|
|
@@ -165,6 +165,11 @@ interface JudgeOptions {
|
|
|
165
165
|
* the hosted path (the endpoint answers 413 above it, PNG only), none elsewhere.
|
|
166
166
|
*/
|
|
167
167
|
maxCropChars?: number;
|
|
168
|
+
/**
|
|
169
|
+
* Opt-in rubric aspects (status: below-bar) to run as well as the default
|
|
170
|
+
* ones, by rubric id, e.g. ['heading-descriptive'].
|
|
171
|
+
*/
|
|
172
|
+
rubrics?: string[];
|
|
168
173
|
}
|
|
169
174
|
interface JudgeRunOptions extends JudgeOptions {
|
|
170
175
|
url: string;
|