@wcag-checkr/ci 1.0.22 → 1.0.24

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.
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ai-usage-log-HdIilbbf.js","assets/crash-reporter-DAZnNefT.js","assets/scheduled-audit-runner-DO-z335b.js","assets/preload-helper-D7HrI6pR.js","assets/diff-CECbooHD.js"])))=>i.map(i=>d[i]);
2
- import{_ as $}from"./preload-helper-D7HrI6pR.js";import{at as U,au as v,b as J,z as Z,av as ee,aw as te,ax as re,ay as ae,az as ne,aA as oe,aB as se,aC as ie,aD as ce,aE as le,aF as de,aG as ue,aH as fe,an as ge,aI as pe,aJ as he,aK as Ee,aL as Se,aM as me,aN as Te,q as C,aO as k,aP as ye,aQ as Re,aR as K,aS as Ie,aT as Ae,aU as we,aV as Ce,aW as _e}from"./scheduled-audit-runner-DO-z335b.js";import{m as M,b as S,r as be}from"./diff-CECbooHD.js";import{w as Pe,r as ke,a as Oe}from"./tier-config-client-D1GMRTQW.js";import{w as Ue,r as ve,a as Ne}from"./rubric-config-client-Ck8nJHda.js";import{o as g,m as xe,n as Le,c as h,e as _,i as De,p as Fe,f as B,k as $e}from"./crash-reporter-DAZnNefT.js";import{z as w,C as Me}from"./ai-usage-log-HdIilbbf.js";const Ge=h("support-messenger"),Ve="https://api.wcagcheckr.com/v1/products/wcagcheckr/support",O="support:rate-window",He=5,We=10*60*1e3,Qe=2,Ke="wcagcheckr",G="storybook:lastDetected";async function Be(e){if(!e)return;const t=await chrome.runtime.getPlatformInfo(),a=(await chrome.storage.local.get(G))[G];return{extensionVersion:chrome.runtime.getManifest().version,platform:t,storybookDetected:a!=null&&a.detected?a.version??"detected":"none",licenseTier:await S(),logTail:xe(Le())}}async function je(e=Date.now()){const r=((await chrome.storage.local.get(O))[O]??[]).filter(a=>e-a<We);return r.length>=He?!1:(r.push(e),await chrome.storage.local.set({[O]:r}),!0)}async function j(e,t=0){try{const r=await fetch(Ve,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok)throw new Error(`http ${r.status}`);const a=await r.json();if(!a.success)throw new Error(a.error??"server returned success=false");return{ticketRef:a.ticketRef??""}}catch(r){if(t<Qe){const a=(t+1)*1e3;return await new Promise(n=>setTimeout(n,a)),j(e,t+1)}throw r}}function qe(){return g("SUPPORT_MESSAGE_REQUEST",async e=>{if(!await je())return{type:"SUPPORT_MESSAGE_RESPONSE",success:!1,error:M("NETWORK","Rate limit reached. Try again in 10 minutes.",!0)};try{const t=await Be(e.includeContext);return{type:"SUPPORT_MESSAGE_RESPONSE",success:!0,ticketRef:(await j({productSlug:Ke,subject:e.subject,body:e.body,replyEmail:e.replyEmail,context:t,extensionVersion:chrome.runtime.getManifest().version,timestamp:new Date().toISOString()})).ticketRef}}catch(t){Ge.error("send failed",t);const r=t instanceof Error?t.message:String(t);return{type:"SUPPORT_MESSAGE_RESPONSE",success:!1,error:M("NETWORK",r,!0)}}})}const q=h("ai-color-suggester");async function Xe(e,t,r=[]){if(!t.enabled||e.length===0)return{results:[],totalCostUsd:0,capExceeded:!1};const a=U(t);if(!a.ok)return{results:[],totalCostUsd:0,capExceeded:!1};const n=a.client,o=v(t.costCapUsd),i=[];for(const c of e){if(!o.canCharge())break;try{const d=await n.suggestColorFix({foreground:c.foreground,background:c.background,fontSize:c.fontSize,fontWeight:c.fontWeight,targetLevel:c.targetLevel,paletteHints:r});o.recordCharge(d.costUsd),d.verdict==="suggested"&&d.candidates.length>0&&i.push({matchKey:c.matchKey,suggestions:d.candidates,reasoning:d.reasoning,costUsd:d.costUsd})}catch(d){q.warn(`color-fix suggestion failed for ${c.matchKey}`,d)}}return{results:i,totalCostUsd:o.state.spentUsd,capExceeded:o.state.exceeded}}async function ze(){const e=await chrome.storage.local.get("aiConfig");return w(e.aiConfig)}function Ye(){return g("AI_COLOR_SUGGEST_REQUEST",async e=>{const t=await S();if(!_(t,"aiColorFix"))return{type:"AI_COLOR_SUGGEST_RESPONSE",results:[],totalCostUsd:0,capExceeded:!1,unavailableReason:"AI color-fix suggester is not available on your current plan."};const r=await ze();if(!r.enabled)return{type:"AI_COLOR_SUGGEST_RESPONSE",results:[],totalCostUsd:0,capExceeded:!1,unavailableReason:"AI augmentation is disabled in Settings → AI augmentation."};if(!r.apiKey)return{type:"AI_COLOR_SUGGEST_RESPONSE",results:[],totalCostUsd:0,capExceeded:!1,unavailableReason:"No AI API key configured. Add one in Settings → AI augmentation."};try{const{results:a,totalCostUsd:n,capExceeded:o}=await Xe(e.inputs,r,e.paletteHints);return{type:"AI_COLOR_SUGGEST_RESPONSE",results:a,totalCostUsd:n,capExceeded:o}}catch(a){return q.warn("color-suggest handler failed",a),{type:"AI_COLOR_SUGGEST_RESPONSE",results:[],totalCostUsd:0,capExceeded:!1,unavailableReason:a instanceof Error?a.message:String(a)}}})}function V(e){if(!e)return null;const t=e.match(/rgba?\(\s*([0-9.]+)\s*,?\s*([0-9.]+)\s*,?\s*([0-9.]+)(?:\s*[,/]\s*([0-9.]+))?\s*\)/i);return t?{r:Math.round(parseFloat(t[1])),g:Math.round(parseFloat(t[2])),b:Math.round(parseFloat(t[3])),a:t[4]!==void 0?parseFloat(t[4]):1}:null}function H(e){const t=r=>{const a=r/255;return a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4)};return .2126*t(e.r)+.7152*t(e.g)+.0722*t(e.b)}function Je(e,t){const r=H(e),a=H(t),n=Math.max(r,a),o=Math.min(r,a);return(n+.05)/(o+.05)}function Ze(e,t){const r=Math.max(0,Math.min(1,e.a));return{r:Math.round(e.r*r+t.r*(1-r)),g:Math.round(e.g*r+t.g*(1-r)),b:Math.round(e.b*r+t.b*(1-r))}}function et(e,t){var F;if(e!=="color-contrast"&&e!=="color-contrast-enhanced")return null;const r=t.styles;if(!r)return null;const a=((F=r.effectiveBackground)==null?void 0:F.color)??r.background,n=r.foreground;if(!n||!a)return null;const o=V(n),i=V(a);if(!o||!i||i.a<.999)return null;const c=o.a<.999?Ze(o,i):{r:o.r,g:o.g,b:o.b},d=Je(c,i),l=r.fontSize??16,s=r.fontWeight??400,u=l>=24||l>=18.5&&s>=700,y=e==="color-contrast-enhanced"?u?4.5:7:u?3:4.5,L=d>=y?"pass":"fail",D=P=>`rgb(${P.r}, ${P.g}, ${P.b})`,Y=`Deterministic WCAG contrast measurement (no AI guessing, no pixel sampling). Foreground ${D(c)}${o.a<.999?` (originally rgba with alpha=${o.a}, composited over background)`:""} against background ${D(i)} yields contrast ratio ${d.toFixed(2)}:1. Text is ${l}px at font-weight ${s}; ${u?"qualifies as large text (threshold 3:1 for AA)":"normal text (threshold 4.5:1 for AA)"}. ${L==="pass"?`Passes AA at ${y}:1.`:`Falls below the ${y}:1 threshold.`}`;return{verdict:L,ratio:d,threshold:y,reasoning:Y}}async function tt(e,t,r){var c,d,l,s,u;const a=JSON.stringify({ruleId:e,selector:t,styles:{fg:((c=r.styles)==null?void 0:c.foreground)??null,bg:((d=r.styles)==null?void 0:d.background)??null,fs:((l=r.styles)==null?void 0:l.fontSize)??null,fw:((s=r.styles)==null?void 0:s.fontWeight)??null,ts:((u=r.styles)==null?void 0:u.textSample)??null},failureSummary:r.failureSummary??null}),n=new TextEncoder().encode(a),o=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(o)).map(T=>T.toString(16).padStart(2,"0")).join("")}const A=h("ai-incomplete-resolver");function W(e,t){if(!e)return t;const r=e.toLowerCase(),a=/verdict\s+corrected\s+to\s+pass|verdict:\s*pass\s+\(corrected\)/i,n=/verdict\s+corrected\s+to\s+fail|verdict:\s*fail\s+\(corrected\)/i,o=R(r,a),i=R(r,n);if(o>i&&o>=0)return"pass";if(i>o&&i>=0)return"fail";const c=/actually\s+passes|in\s+fact\s+passes|passes\s+AA/gi,d=/actually\s+fails|in\s+fact\s+fails|fails\s+AA/gi,l=R(r,c),s=R(r,d);return l<0&&s<0?t:l>s&&l/r.length>=.5?"pass":s>l&&s/r.length>=.5?"fail":t}function R(e,t){let r=-1;const a=t.flags.includes("g")?t.flags:t.flags+"g",n=new RegExp(t.source,a);let o;for(;(o=n.exec(e))!==null;)r=o.index,o.index===n.lastIndex&&n.lastIndex++;return r}async function rt(){const e=await chrome.storage.local.get("aiConfig");return w(e.aiConfig)}async function at(e){if(!e.aiConfig.enabled||e.elements.length===0)return{resolutions:[],totalCostUsd:0};const t=U(e.aiConfig);if(!t.ok)return{resolutions:[],totalCostUsd:0};const r=t.client,a=v(e.aiConfig.costCapUsd),n=[],o=await J(e.pageUrl),i=new Map;for(const c of o)i.set(`${c.ruleId}::${c.selector}`,c);for(const c of e.elements){if(!a.canCharge())break;const d=await tt(e.ruleId,c.selector,c),l=i.get(`${e.ruleId}::${c.selector}`),s=et(e.ruleId,c);if(s){A.info(`Deterministic verdict for ${e.ruleId} on ${c.selector}: ${s.verdict} (${s.ratio.toFixed(2)}:1 vs ${s.threshold}:1) — math overrides cache + AI`),n.push({pageUrl:e.pageUrl,ruleId:e.ruleId,selector:c.selector,verdict:s.verdict,reasoning:s.reasoning,resolvedAt:new Date().toISOString(),costUsd:0,wcagCriterion:e.wcagCriterion,inputHash:d});continue}if(l&&l.inputHash===d&&l.verdict!=="uncertain"){A.info(`Reusing cached resolution for ${e.ruleId} on ${c.selector} (hash match, verdict=${l.verdict})`);const u=W(l.reasoning,l.verdict);n.push({...l,verdict:u,resolvedAt:new Date().toISOString(),costUsd:0,inputHash:d});continue}try{const u=await r.resolveAxeIncomplete({ruleId:e.ruleId,element:c,pageUrl:e.pageUrl,targetLevel:e.targetLevel});a.recordCharge(u.costUsd);const T=W(u.reasoning,u.verdict);n.push({pageUrl:e.pageUrl,ruleId:e.ruleId,selector:c.selector,verdict:T,reasoning:u.reasoning,resolvedAt:new Date().toISOString(),costUsd:u.costUsd,wcagCriterion:e.wcagCriterion,inputHash:d})}catch(u){A.warn(`resolveAxeIncomplete failed for ${c.selector}`,u)}}return n.length>0&&await Z(n),{resolutions:n,totalCostUsd:a.state.spentUsd}}function nt(){return g("AI_RESOLVE_INCOMPLETE_REQUEST",async e=>{const t=await S();if(!_(t,"aiIncompleteResolver"))return{type:"AI_RESOLVE_INCOMPLETE_RESPONSE",resolutions:[],totalCostUsd:0,unavailableReason:"AI resolver for axe-incomplete elements is not available on your current plan."};const r=await rt();if(!r.enabled)return{type:"AI_RESOLVE_INCOMPLETE_RESPONSE",resolutions:[],totalCostUsd:0,unavailableReason:"AI augmentation is disabled in Settings → AI augmentation."};if(!r.apiKey)return{type:"AI_RESOLVE_INCOMPLETE_RESPONSE",resolutions:[],totalCostUsd:0,unavailableReason:"No AI API key configured. Add one in Settings → AI augmentation."};try{const{resolutions:a,totalCostUsd:n}=await at({ruleId:e.ruleId,pageUrl:e.pageUrl,wcagCriterion:e.wcagCriterion,elements:e.elements,targetLevel:e.targetLevel,aiConfig:r});return{type:"AI_RESOLVE_INCOMPLETE_RESPONSE",resolutions:a,totalCostUsd:n}}catch(a){return A.warn("ai-incomplete-resolver failed",a),{type:"AI_RESOLVE_INCOMPLETE_RESPONSE",resolutions:[],totalCostUsd:0,unavailableReason:a instanceof Error?a.message:"Unknown error during AI resolution."}}})}function ot(){return g("INTERACTIVE_AUDIT_REQUEST",async e=>{try{switch(e.criterionId){case"2.4.3":{const t=await oe({tabId:e.tabId,componentId:e.componentId,pageUrl:e.pageUrl});return t.ok?{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!0,result:t.result}:{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:t.error}}case"2.1.2":{const t=await ne({tabId:e.tabId,componentId:e.componentId,pageUrl:e.pageUrl});return t.ok?{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!0,result:t.result}:{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:t.error}}case"2.4.7":{const t=await ae({tabId:e.tabId,componentId:e.componentId,pageUrl:e.pageUrl});return t.ok?{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!0,result:t.result}:{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:t.error}}case"1.4.11":{const t=await chrome.storage.local.get("sidePanel:lastAudit"),r=t==null?void 0:t["sidePanel:lastAudit"],a=(r==null?void 0:r.results)??[];if(a.length===0)return{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:"No audit results available. Run an audit first; 1.4.11 needs the page screenshot."};const n=await re({componentId:e.componentId,pageUrl:e.pageUrl,results:a});return n.ok?{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!0,result:n.result}:{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:n.error}}case"1.3.2":{const t=await chrome.storage.local.get("sidePanel:lastAudit"),r=t==null?void 0:t["sidePanel:lastAudit"],a=(r==null?void 0:r.results)??[];if(a.length===0)return{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:"No audit results available. Run an audit first, then the 1.3.2 walkthrough can judge its reading-order findings."};const n=await te({componentId:e.componentId,pageUrl:e.pageUrl,results:a});return n.ok?{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!0,result:n.result}:{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:n.error}}case"2.5.3":{const t=await chrome.storage.local.get("sidePanel:lastAudit"),r=t==null?void 0:t["sidePanel:lastAudit"],a=await ee({tabId:e.tabId,componentId:e.componentId,pageUrl:e.pageUrl,results:r==null?void 0:r.results});return a.ok?{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!0,result:a.result}:{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:a.error}}default:return{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:`Interactive audit for criterion ${e.criterionId} not yet implemented.`}}}catch(t){return{type:"INTERACTIVE_AUDIT_RESPONSE",ok:!1,error:t instanceof Error?t.message:String(t)}}})}async function st(){var t;if(typeof chrome>"u"||!((t=chrome.storage)!=null&&t.local))return w(void 0);const e=await chrome.storage.local.get("aiConfig");return w(e.aiConfig)}async function it(e){const t=await st();if(!t.enabled)return{findings:[],totalCostUsd:0,capExceeded:!1,errors:[],skipReason:"disabled"};if(!t.apiKey)return{findings:[],totalCostUsd:0,capExceeded:!1,errors:[],skipReason:"no-key"};const r=U(t);if(!r.ok)return{findings:[],totalCostUsd:0,capExceeded:!1,errors:[`AI client unavailable: ${r.reason}`],skipReason:"client-error"};const a=r.client,n=v(t.costCapUsd),o=[],i=[],c=Math.max(1,t.maxCandidatesPerCheck??10);if(t.enabledChecks.altText){const d=e.figureAltTexts.slice(0,c);for(const l of d){if(!n.canCharge())break;try{const s=await a.judgeGenericLinkText({linkText:l.alt,surroundingText:`(This is an alt text on a PDF Figure tag, page ${l.pageNum}.)`});n.recordCharge(s.costUsd),s.verdict==="fail"&&s.confidence>=.6&&o.push({ruleId:"pdf-alt-text-not-descriptive",impact:"moderate",wcagCriterion:"1.1.1",description:`Figure on page ${l.pageNum} has alt text "${l.alt}" that doesn't describe the figure's content. ${s.reasoning} A screen-reader user hears the literal alt and gets no useful information about what the figure shows.`,failureSummary:'Replace generic alt text with a description of what the figure actually shows. For data charts: include the key data point. For decorative images: use alt="" so the screen reader skips them. PDF/UA-1 §7.4 / WCAG 1.1.1.'})}catch(s){i.push(`alt-text page ${l.pageNum}: ${s instanceof Error?s.message:String(s)}`)}}}else i.push("altText AI check disabled in user settings");if(t.enabledChecks.altText&&e.formLabels&&e.formLabels.length>0){const d=s=>{switch(s){case"Tx":return"text input";case"Btn":return"button / checkbox / radio";case"Ch":return"choice / dropdown";case"Sig":return"signature field";default:return s||"unknown"}},l=e.formLabels.slice(0,c);for(const s of l){if(!n.canCharge())break;try{const u=await a.judgeGenericLinkText({linkText:s.tooltip,surroundingText:`(This is the screen-reader tooltip for a PDF form field on page ${s.pageNum}. Field type: ${d(s.fieldType)}. Internal field name: "${s.fieldName||"(none)"}".)`});n.recordCharge(u.costUsd),u.verdict==="fail"&&u.confidence>=.6&&o.push({ruleId:"pdf-form-label-not-descriptive",impact:"serious",wcagCriterion:"3.3.2",description:`Form field on page ${s.pageNum} (${d(s.fieldType)}) has tooltip "${s.tooltip}" that doesn't convey what the user should enter. ${u.reasoning} Screen-reader users hear the tooltip as the field's accessible name; generic tooltips fail to identify the field's purpose.`,failureSummary:'Replace the generic tooltip with one that names what the field is for. "Field 1" → "Mailing address." "Text input" → "Email address." In Acrobat: Tools → Prepare Form → right-click field → Properties → General → Tooltip. WCAG 3.3.2 (Labels or Instructions) requires labels that describe purpose, not just type.'})}catch(u){i.push(`form-label page ${s.pageNum}: ${u instanceof Error?u.message:String(u)}`)}}}if(t.enabledChecks.headings&&e.headings&&e.headings.length>0){const d=e.headings.slice(0,c);for(const l of d){if(!n.canCharge())break;try{const s=await a.judgeHeading({headingText:l.headingText,sectionContent:l.sectionContent});n.recordCharge(s.costUsd),s.verdict==="fail"&&s.confidence>=.6&&o.push({ruleId:"pdf-heading-not-descriptive",impact:"moderate",wcagCriterion:"2.4.6",description:`Heading on page ${l.pageNum} "${l.headingText}" doesn't describe the content of its section. ${s.reasoning} Screen-reader users navigating by heading hear titles that don't help them locate the section they want.`,failureSummary:`Rewrite the heading to describe what the section is about. "Section 1" → "Q3 financial summary." "More info" → "How to apply for benefits." Generic, recycled, or placeholder heading text wastes the SR user's heading-navigation feature.`})}catch(s){i.push(`heading page ${l.pageNum}: ${s instanceof Error?s.message:String(s)}`)}}}return{findings:o,totalCostUsd:n.state.spentUsd,capExceeded:n.state.exceeded,errors:i}}function ct(e){return g("PDF_AUDIT_REQUEST",async t=>{const r=await e();if(!_(r,"pdfAudit"))return{type:"PDF_AUDIT_RESPONSE",ok:!1,source:t.url,findings:[],pageCount:null,fatalError:`PDF accessibility audit is not enabled on the ${r} tier. Upgrade or contact your admin to enable the pdfAudit feature.`};try{const a=await se(t.url,{maxBytes:t.maxBytes});let n=[];if(a.aiCandidates)try{const o=await it(a.aiCandidates);if(n=o.findings,o.skipReason&&(a.aiCandidates.figureAltTexts.length>0||a.aiCandidates.headings.length>0||a.aiCandidates.formLabels.length>0)){const i=o.skipReason==="no-key"?"No Anthropic API key configured. AI quality checks (alt-text descriptiveness, heading clarity, form-label match) did NOT run on this PDF.":o.skipReason==="disabled"?"AI augmentation is disabled in Settings → AI. AI quality checks did NOT run on this PDF.":"AI client could not be constructed. AI quality checks did NOT run on this PDF.";n=[...n,{ruleId:"pdf-ai-quality-skipped",impact:"minor",wcagCriterion:"1.1.1",description:i+` (${a.aiCandidates.figureAltTexts.length} figure alts, ${a.aiCandidates.headings.length} headings, ${a.aiCandidates.formLabels.length} form labels would have been judged.)`,failureSummary:"Configure an Anthropic API key in Settings → AI augmentation to enable PDF semantic-quality checks. The structural audit ran normally; this informational finding is dismissible."}]}}catch{}return{type:"PDF_AUDIT_RESPONSE",ok:a.ok,source:a.source,findings:[...a.findings,...n],pageCount:a.pageCount,...a.fatalError?{fatalError:a.fatalError}:{},...a._perPageContrast?{_perPageContrast:a._perPageContrast}:{},...a.aiCandidates?{aiCandidates:a.aiCandidates}:{}}}catch(a){return{type:"PDF_AUDIT_RESPONSE",ok:!1,source:t.url,findings:[],pageCount:null,fatalError:`PDF audit handler threw: ${a instanceof Error?a.message:String(a)}`}}})}const lt=h("ax-tree-snapshot"),dt="1.3";function ut(e){var r,a,n;const t=[];for(const o of e.properties??[]){const i=(r=o.value)==null?void 0:r.value;i!==void 0&&(typeof i=="string"||typeof i=="number"||typeof i=="boolean"||i===null)&&t.push({name:o.name,value:i})}return{nodeId:e.nodeId,parentId:e.parentId,childIds:e.childIds??[],role:typeof((a=e.role)==null?void 0:a.value)=="string"?e.role.value:"unknown",name:typeof((n=e.name)==null?void 0:n.value)=="string"?e.name.value:"",ignored:!!e.ignored,properties:t,backendDomNodeId:e.backendDOMNodeId}}async function ft(e){let t=!1;try{try{await chrome.debugger.attach({tabId:e},dt),t=!0}catch(n){if(!(n instanceof Error?n.message:String(n)).includes("Another debugger"))throw lt.warn("chrome.debugger.attach failed",n),n}await chrome.debugger.sendCommand({tabId:e},"Accessibility.enable");const r=await chrome.debugger.sendCommand({tabId:e},"Accessibility.getFullAXTree");return((r==null?void 0:r.nodes)??[]).map(ut)}finally{if(t)try{await chrome.debugger.detach({tabId:e})}catch{}}}const X=h("perf-throttle"),gt="1.3",pt={none:{label:"No throttling",network:null,cpuRate:1},"3g-slow":{label:"Slow 3G",network:{offline:!1,latency:400,downloadThroughput:500*1024/8,uploadThroughput:500*1024/8},cpuRate:6},"3g-fast":{label:"Fast 3G",network:{offline:!1,latency:150,downloadThroughput:1.5*1024*1024/8,uploadThroughput:750*1024/8},cpuRate:4},"4g":{label:"4G LTE",network:{offline:!1,latency:20,downloadThroughput:4*1024*1024/8,uploadThroughput:3*1024*1024/8},cpuRate:2},"cpu-2x":{label:"CPU 2× slowdown (no network throttle)",network:null,cpuRate:2},"cpu-4x":{label:"CPU 4× slowdown (no network throttle)",network:null,cpuRate:4}};async function ht(e){try{return await chrome.debugger.attach({tabId:e},gt),!0}catch(t){if((t instanceof Error?t.message:String(t)).includes("Another debugger"))return!1;throw t}}async function Et(e,t){const r=pt[t];await ht(e),await chrome.debugger.sendCommand({tabId:e},"Network.enable"),r.network?await chrome.debugger.sendCommand({tabId:e},"Network.emulateNetworkConditions",r.network):await chrome.debugger.sendCommand({tabId:e},"Network.emulateNetworkConditions",{offline:!1,latency:0,downloadThroughput:-1,uploadThroughput:-1}),await chrome.debugger.sendCommand({tabId:e},"Emulation.setCPUThrottlingRate",{rate:r.cpuRate}),X.info(`applied ${t} (label="${r.label}", cpu×${r.cpuRate})`)}async function St(e){try{await chrome.debugger.sendCommand({tabId:e},"Network.emulateNetworkConditions",{offline:!1,latency:0,downloadThroughput:-1,uploadThroughput:-1}),await chrome.debugger.sendCommand({tabId:e},"Emulation.setCPUThrottlingRate",{rate:1})}catch(t){X.debug("throttle reset commands failed (debugger may not be attached)",t)}}const f=h("service-worker");De("service-worker");ie();var I,Q;(Q=(I=chrome.sidePanel)==null?void 0:I.setPanelBehavior)==null||Q.call(I,{openPanelOnActionClick:!0}).catch(e=>f.warn("setPanelBehavior failed",e));ce();le();be();de().catch(e=>f.warn("initial cloud pull failed",e));(async()=>(await Me(),await Pe(),ke(),await Ue(),ve(),ue(),fe(),ge()))();chrome.alarms.onAlarm.addListener(e=>{const t=pe(e.name);t!==null&&he(t).catch(r=>f.warn(`scheduled audit ${t} threw at top level`,r))});Oe();Ne();Ee();Se();qe();Ye();me();nt();ot();ct(S);self.addEventListener("unhandledrejection",e=>{const t=e.reason;Fe(t instanceof Error?t:new Error(String(t)))});let E=!1;chrome.runtime.onConnect.addListener(e=>{if(e.name==="audit-keepalive"){f.debug("keepalive connected"),e.onDisconnect.addListener(async()=>{f.debug("keepalive disconnected"),await Te()});return}if(e.name==="sidepanel-tracker"){E=!0,f.debug("chrome.sidePanel opened"),e.onDisconnect.addListener(async()=>{E=!1,f.debug("chrome.sidePanel closed — restoring in-page overlay"),await b()});return}});let N=!1;const p={isCanceled:()=>N};async function x(){const e=await C();if(e)try{await B(e,{type:"SIDEBAR_HIDE_REQUEST"})}catch(t){f.warn("sidebar hide failed",t)}}async function b(){const e=await C();if(e)try{await B(e,{type:"SIDEBAR_SHOW_REQUEST"})}catch(t){f.warn("sidebar show failed",t)}}g("START_AUDIT",async e=>{N=!1,await x();const t=await C();let r;const a={verifyFixesOnly:e.verifyFixesOnly,recordForensic:e.recordForensic};if(e.mode==="single-element"){if(!e.scope)throw new Error("START_AUDIT single-element requires scope");r=k(e.scope,p,e.frameId,e.matrixOverride,a)}else if(e.mode==="full-page")r=k("html",p,0,e.matrixOverride,a);else if(e.mode==="quick-scan"){const{QUICK_SCAN_MATRIX_SETTINGS:n}=await $(async()=>{const{QUICK_SCAN_MATRIX_SETTINGS:o}=await import("./ai-usage-log-HdIilbbf.js").then(i=>i.Q);return{QUICK_SCAN_MATRIX_SETTINGS:o}},__vite__mapDeps([0,1]));r=k(e.scope??"html",p,e.frameId??0,n,a)}else if(e.mode==="all-frames")r=ye(p);else if(e.mode==="parallel-scan"){const{runParallelScan:n}=await $(async()=>{const{runParallelScan:o}=await import("./scheduled-audit-runner-DO-z335b.js").then(i=>i.b9);return{runParallelScan:o}},__vite__mapDeps([2,3,1,4,0]));r=n(p)}else r=Re(p);r.catch(n=>{f.error("audit failed",n);const o=n instanceof Error?n.message:String(n),i=/no audit target tab/i.test(o);$e({type:"AUDIT_FAILED_EVENT",error:{code:i?"RESTRICTED_URL":"UNKNOWN",message:i?"No audit target tab found. Open a regular http(s) page (not chrome:// or about:blank) and try again.":`Audit failed: ${o}`,recoverable:!0}})}).finally(()=>{t!=null&&K(t).catch(n=>f.debug("post-audit debugger release failed (best-effort)",n)),E||b()})});g("CANCEL_AUDIT",async()=>{N=!0,f.info("cancel requested")});let m=!1;const z={isCanceled:()=>m};g("START_SITE_CRAWL",async e=>{m=!1,await x();const t=await C();Ie(e.startUrl,{maxPages:e.maxPages,includeRegex:e.includeRegex,excludeRegex:e.excludeRegex,verifyFixesOnly:e.verifyFixesOnly,urls:e.urls,recordForensic:e.recordForensic},z).catch(r=>f.error("site crawl failed",r)).finally(()=>{t!=null&&K(t).catch(r=>f.debug("post-crawl debugger release failed (best-effort)",r)),E||b()})});g("CANCEL_SITE_CRAWL",async()=>{m=!0,f.info("site crawl cancel requested")});g("START_CRAWL_DISCOVERY",async e=>{m=!1,await x(),Ae(e.startUrl,{maxPages:e.maxPages,includeRegex:e.includeRegex,excludeRegex:e.excludeRegex},z).catch(t=>f.error("crawl discovery failed",t)).finally(()=>{E||b()})});g("CANCEL_CRAWL_DISCOVERY",async()=>{m=!0,f.info("crawl discovery cancel requested")});g("REGRADE_SITE_CRAWL",async()=>{try{const e=await we();return{type:"REGRADE_SITE_CRAWL_RESPONSE",ok:e.ok,...e.reason?{reason:e.reason}:{}}}catch(e){return{type:"REGRADE_SITE_CRAWL_RESPONSE",ok:!1,reason:e instanceof Error?e.message:String(e)}}});g("OPEN_SETTINGS",()=>{chrome.runtime.openOptionsPage()});g("PERF_THROTTLE_APPLY_REQUEST",async e=>{try{return await Et(e.tabId,e.profile),{type:"PERF_THROTTLE_APPLY_RESPONSE",ok:!0}}catch(t){return{type:"PERF_THROTTLE_APPLY_RESPONSE",ok:!1,error:t instanceof Error?t.message:String(t)}}});g("PERF_THROTTLE_CLEAR_REQUEST",async e=>{try{return await St(e.tabId),{type:"PERF_THROTTLE_CLEAR_RESPONSE",ok:!0}}catch(t){return{type:"PERF_THROTTLE_CLEAR_RESPONSE",ok:!1,error:t instanceof Error?t.message:String(t)}}});g("SITE_CLAIM_GET_REQUEST",async e=>({type:"SITE_CLAIM_GET_RESPONSE",claim:await Ce(e.domain)}));g("SITE_CLAIM_LIST_REQUEST",async()=>({type:"SITE_CLAIM_LIST_RESPONSE",claims:await _e()}));g("AX_TREE_SNAPSHOT_REQUEST",async e=>{const t=await S();if(!_(t,"axTreeViewer"))return{type:"AX_TREE_SNAPSHOT_RESPONSE",ok:!1,error:"AX-tree viewer is not available on your current plan."};try{return{type:"AX_TREE_SNAPSHOT_RESPONSE",ok:!0,nodes:await ft(e.tabId)}}catch(r){return f.warn("ax-tree snapshot failed",r),{type:"AX_TREE_SNAPSHOT_RESPONSE",ok:!1,error:r instanceof Error?r.message:String(r)}}});f.info("service worker ready");