/**
* Anti-Pattern Browser Detector for Impeccable
* Copyright (c) 2026 Paul Bakaus
*
* GENERATED -- do not edit. Source: crates/core/src/browser (rules, WASM) +
* browser-bundle/*.js (DOM probe, overlay UI).
* Rebuild: cargo xtask bundle
*
* Usage:
* Re-scan: window.impeccableScan()
*/
(function () {
if (typeof window === 'undefined') return;
// --- browser-bundle/10-probe.js ---
// The DOM probe the WASM rule core calls back into. Pure measurement: one
// function per DOM API the rules read (see crates/core/src/browser/dom.rs for
// the contract). Elements travel as handles (indexes into a registry; 0 is
// null). Nothing in here decides anything about a design.
const __els = [null];
let __ids = new WeakMap();
const __csCache = [null];
// Drop every handle (a new scan re-interns what it touches; JS keeps
// Elements, never handles, across calls).
function __resetRegistry() {
__els.length = 1;
__csCache.length = 1;
__ids = new WeakMap();
}
function __intern(el) {
if (!el) return 0;
let id = __ids.get(el);
if (id === undefined) {
id = __els.length;
__els.push(el);
__csCache.push(null);
__ids.set(el, id);
}
return id;
}
function __el(id) {
return __els[id] || null;
}
function __cs(id) {
let cs = __csCache[id];
if (!cs) {
cs = getComputedStyle(__els[id]);
__csCache[id] = cs;
}
return cs;
}
function __ids_of(list) {
const out = new Array(list.length);
for (let i = 0; i < list.length; i++) out[i] = __intern(list[i]);
return out;
}
const __SEL_ERR = 0xFFFFFFFF;
function __rectArray(r) {
return [r.x, r.y, r.width, r.height, r.top, r.right, r.bottom, r.left];
}
const __impeccableDom = {
document_element() { return __intern(document.documentElement); },
body() { return __intern(document.body); },
query_all(root, selector) {
try {
const scope = root ? __el(root) : document;
return __ids_of(scope.querySelectorAll(selector));
} catch { return [__SEL_ERR]; }
},
query_one(root, selector) {
try {
const scope = root ? __el(root) : document;
return __intern(scope.querySelector(selector));
} catch { return __SEL_ERR; }
},
inner_width() { return window.innerWidth; },
inner_height() { return window.innerHeight; },
scroll_x() { return window.scrollX; },
scroll_y() { return window.scrollY; },
hostname() { return location.hostname; },
element_from_point(x, y) { return __intern(document.elementFromPoint(x, y)); },
elements_from_point(x, y) {
return typeof document.elementsFromPoint === 'function' ? __ids_of(document.elementsFromPoint(x, y)) : [];
},
css_escape(s) { return CSS.escape(s); },
// JSON `[[["prop","value"],...], ...]` of the first @keyframes rule named
// `name` (document.styleSheets order, nested rules walked breadth-first
// exactly like keyframesToggleVisibilityDOM); undefined when none.
keyframes(name) {
if (!name) return undefined;
for (const sheet of document.styleSheets) {
let rules;
try { rules = sheet.cssRules || sheet.rules; } catch { continue; }
if (!rules) continue;
const stack = [...rules];
while (stack.length) {
const rule = stack.shift();
if (rule.cssRules && rule.type !== 7) { stack.push(...rule.cssRules); continue; }
if (rule.type !== 7 || rule.name !== name) continue;
const frames = [];
for (const frame of rule.cssRules || []) {
const fs = frame.style;
if (!fs) continue;
const decls = [];
for (let i = 0; i < fs.length; i++) {
const prop = fs[i];
decls.push([prop, fs.getPropertyValue(prop)]);
}
frames.push(decls);
}
return JSON.stringify(frames);
}
}
return undefined;
},
linked_stylesheet_text() {
// The CSSOM walk lives in 15-snapshot.js so the standalone snapshot
// producer carries it too; both routes read the same corpus.
return __snapLinkedStylesheetText();
},
document_html_for_patterns() {
const docClone = document.documentElement.cloneNode(true);
for (const node of docClone.querySelectorAll('[id^="impeccable-live-"]')) node.remove();
return docClone.outerHTML;
},
tag_name(el) { return __el(el).tagName; },
namespace_uri(el) { return __el(el).namespaceURI || ''; },
parent(el) { return __intern(__el(el).parentElement); },
children(el) { return __ids_of(__el(el).children); },
previous_element_sibling(el) { return __intern(__el(el).previousElementSibling); },
next_element_sibling(el) { return __intern(__el(el).nextElementSibling); },
contains(a, b) { return __el(a).contains(__el(b)); },
matches(el, selector) {
try { return __el(el).matches(selector) ? 1 : 0; } catch { return __SEL_ERR; }
},
closest(el, selector) {
try { return __intern(__el(el).closest(selector)); } catch { return __SEL_ERR; }
},
attr(el, name) {
const v = __el(el).getAttribute(name);
return v == null ? undefined : v;
},
id_prop(el) {
const v = __el(el).id;
return typeof v === 'string' ? v : undefined;
},
class_name_prop(el) {
const v = __el(el).className;
return typeof v === 'string' ? v : undefined;
},
text_content(el) { return __el(el).textContent || ''; },
inner_text(el) {
const v = __el(el).innerText;
return typeof v === 'string' && v ? v : undefined;
},
direct_text_nodes(el) {
const out = [];
for (const n of __el(el).childNodes) {
if (n.nodeType === 3) out.push(n.textContent || '');
}
return out;
},
is_content_editable(el) { return !!__el(el).isContentEditable; },
hidden_prop(el) { return !!__el(el).hidden; },
style(el, prop) {
const v = __cs(el)[prop];
return v == null ? '' : String(v);
},
pseudo_style(el, pseudo, prop) {
let ps;
try { ps = getComputedStyle(__el(el), pseudo); } catch { return undefined; }
if (!ps) return undefined;
const v = ps[prop];
return v == null ? '' : String(v);
},
rect(el) {
const node = __el(el);
if (typeof node.getBoundingClientRect !== 'function') return [];
return __rectArray(node.getBoundingClientRect());
},
client_width(el) { return __el(el).clientWidth; },
client_height(el) { return __el(el).clientHeight; },
client_left(el) { return __el(el).clientLeft; },
scroll_width(el) { return __el(el).scrollWidth; },
scroll_left(el) { return __el(el).scrollLeft; },
offset_width(el) { return __el(el).offsetWidth; },
offset_height(el) { return __el(el).offsetHeight; },
check_visibility(el) {
const node = __el(el);
if (typeof node.checkVisibility !== 'function') return -1;
return node.checkVisibility({ checkOpacity: false, checkVisibilityCSS: true }) ? 1 : 0;
},
// getDirectTextRect(el) from the JS driver: union of the client rects of
// the element's non-blank direct text nodes.
direct_text_rect(el) {
const node = __el(el);
const rects = [];
for (const child of node.childNodes) {
if (child.nodeType !== 3 || !(child.textContent || '').trim()) continue;
const range = document.createRange();
range.selectNodeContents(child);
for (const rect of range.getClientRects()) {
if (rect.width >= 1 && rect.height >= 1) rects.push(rect);
}
range.detach?.();
}
if (rects.length === 0) return [];
const left = Math.min(...rects.map(r => r.left));
const top = Math.min(...rects.map(r => r.top));
const right = Math.max(...rects.map(r => r.right));
const bottom = Math.max(...rects.map(r => r.bottom));
return [left, top, right - left, bottom - top, top, right, bottom, left];
},
};
// --- browser-bundle/15-snapshot.js ---
// The page snapshot producer and the live-page IO the rules cannot do from
// a snapshot. Pure measurement: what the probe in 10-probe.js reads on
// demand, this reads once and serializes, so the WASM core can run where
// the page's Content-Security-Policy keeps WebAssembly out (the extension's
// offscreen document; see crates/core/src/browser/snapshot.rs for the
// consumer and the field contract). Nothing in here decides anything about
// a design: no thresholds, no rule names, no snippet strings.
//
// Exposed as `__impeccableSnapshot`:
// capture(options) -> { json, elements, stats } | { error }
// answer(needs, elements) -> facts for the core (`hitTests` -> `hits`)
// idOf(el, elements) -> the element's snapshot id (0 when absent)
// visualIO(elements) -> the IO half of the visual-contrast pass
// (image loads, canvas pixel reads) over live
// Elements, keyed by snapshot id
// STYLE_PROPS / PSEUDO_PROPS / STATE_PSEUDOS (the capture contract)
// Computed-style properties the rules read. Mirrors STYLE_PROPS in
// crates/core/src/browser/snapshot.rs (cargo xtask bundle checks the two
// lists agree).
const __SNAP_STYLE_PROPS = [
"animationIterationCount", "animationName", "animationTimingFunction",
"backdropFilter", "background", "backgroundClip", "backgroundColor",
"backgroundImage", "backgroundPosition", "backgroundSize", "blockSize",
"borderBottomColor", "borderBottomWidth", "borderBottomStyle",
"borderLeftColor", "borderLeftWidth", "borderLeftStyle", "borderRadius",
"borderRightColor", "borderRightWidth", "borderRightStyle",
"borderTopColor", "borderTopWidth", "borderTopStyle", "bottom", "boxShadow",
"clip", "clip-path", "clipPath", "color", "content", "contentVisibility",
"cssFloat", "display", "filter", "float", "fontFamily", "fontSize",
"fontStyle", "fontVariant", "fontVariantCaps", "fontWeight", "height",
"hyphens", "inlineSize", "inset", "insetBlock", "insetBlockEnd",
"insetBlockStart", "insetInline", "insetInlineEnd", "insetInlineStart",
"left", "letterSpacing", "lineHeight", "marginBottom", "marginLeft",
"marginRight", "marginTop", "maxHeight", "maxWidth", "minHeight", "minWidth",
"mixBlendMode", "objectFit", "objectPosition", "opacity", "outline",
"outlineColor", "outlineOffset", "outlineStyle", "outlineWidth", "overflow",
"overflowX", "overflowY", "paddingBottom", "paddingLeft", "paddingRight",
"paddingTop", "pointerEvents", "position", "right", "textAlign",
"textDecoration", "textDecorationLine", "textIndent", "textOverflow",
"textShadow", "textTransform", "top", "transform", "transitionDuration",
"transitionProperty", "transitionTimingFunction", "verticalAlign",
"visibility", "webkitBackgroundClip", "webkitClipPath", "webkitHyphens",
"webkitTextFillColor", "whiteSpace", "width", "wordBreak", "zIndex",
];
// `::before` / `::after` properties, recorded where `content` is set.
const __SNAP_PSEUDO_PROPS = [
"content", "position", "opacity", "display", "width", "height", "top",
"right", "bottom", "left", "backgroundColor", "backgroundImage",
"background", "borderRadius", "transform", "visibility",
];
// Pseudo-class states recorded per element (`el.matches(':name')`), so the
// snapshot selector engine can answer `:checked` / `:disabled` / ... the way
// the live DOM would. Mirrors STATE_PSEUDOS in crates/core/src/browser/selector.rs.
const __SNAP_STATE_PSEUDOS = [
"hover", "active", "focus", "focus-within", "focus-visible", "target",
"target-within", "checked", "indeterminate", "disabled", "required",
"invalid", "user-invalid", "user-valid", "in-range", "out-of-range",
"placeholder-shown", "default", "open", "autofill", "-webkit-autofill",
"popover-open", "modal", "fullscreen", "-webkit-full-screen",
"picture-in-picture", "playing", "buffering", "seeking", "muted",
"volume-locked",
];
const __SNAP_NS = { "http://www.w3.org/1999/xhtml": 0, "http://www.w3.org/2000/svg": 1, "http://www.w3.org/1998/Math/MathML": 2 };
const __SNAP_DEFAULT_MAX_ELEMENTS = 30000;
const __SNAP_DEFAULT_MAX_BYTES = 48 * 1024 * 1024;
function __snapRect4(r) { return [r.x, r.y, r.width, r.height]; }
function __snapNum(v) { return typeof v === 'number' ? v : null; }
// getDirectTextRect(el): union of the client rects of the element's
// non-blank direct text nodes (same measure as 10-probe.js).
function __snapDirectTextRect(node) {
const rects = [];
for (const child of node.childNodes) {
if (child.nodeType !== 3 || !(child.textContent || '').trim()) continue;
const range = document.createRange();
range.selectNodeContents(child);
for (const rect of range.getClientRects()) {
if (rect.width >= 1 && rect.height >= 1) rects.push(rect);
}
range.detach?.();
}
if (rects.length === 0) return null;
const left = Math.min(...rects.map(r => r.left));
const top = Math.min(...rects.map(r => r.top));
const right = Math.max(...rects.map(r => r.right));
const bottom = Math.max(...rects.map(r => r.bottom));
return [left, top, right - left, bottom - top];
}
// ─── Linked stylesheet corpus (JS: injected/index.mjs #709) ────────────────
// JS: injected/index.mjs#pseudoElementHostSelector
function __snapPseudoElementHostSelector(selector) {
const raw = String(selector || '');
const legacyNames = new Set(['before', 'after', 'first-letter', 'first-line']);
const isNameChar = char => /[a-zA-Z0-9_-]/.test(char || '');
const consumeFunction = (start) => {
let depth = 0;
let quote = '';
for (let i = start; i < raw.length; i += 1) {
const char = raw[i];
if (char === '\\') { i += 1; continue; }
if (quote) { if (char === quote) quote = ''; continue; }
if (char === '"' || char === "'") { quote = char; continue; }
if (char === '(') depth += 1;
if (char === ')' && --depth === 0) return i + 1;
}
return raw.length;
};
let output = '';
let found = false;
for (let i = 0; i < raw.length;) {
const char = raw[i];
if (char === '\\') {
output += raw.slice(i, Math.min(raw.length, i + 2));
i += 2;
continue;
}
if (char === '"' || char === "'") {
const quote = char;
const start = i;
i += 1;
while (i < raw.length) {
if (raw[i] === '\\') { i += 2; continue; }
const value = raw[i];
i += 1;
if (value === quote) break;
}
output += raw.slice(start, i);
continue;
}
if (char !== ':') { output += char; i += 1; continue; }
let end = i + 1;
let isPseudoElement = false;
if (raw[end] === ':') {
end += 1;
const nameStart = end;
while (isNameChar(raw[end])) end += 1;
isPseudoElement = end > nameStart;
} else {
const nameStart = end;
while (isNameChar(raw[end])) end += 1;
isPseudoElement = legacyNames.has(raw.slice(nameStart, end).toLowerCase());
}
if (!isPseudoElement) { output += char; i += 1; continue; }
if (raw[end] === '(') end = consumeFunction(end);
found = true;
if (!output || /[\s>+~,]/.test(output[output.length - 1])) output += '*';
i = end;
}
if (!found) return null;
return output.trim().replace(/,\s*(?=,|$)/g, '');
}
// JS: injected/index.mjs#selectorNodesForLiveDom
function __snapSelectorNodesForLiveDom(root, selector) {
const raw = String(selector || '').trim();
if (!raw) return null;
const fallback = __snapPseudoElementHostSelector(raw);
if (fallback == null) {
// An empty result from a valid full selector is authoritative. In
// particular, do not broaden inactive :hover/:focus/:not() rules to
// their host element by stripping pseudo-classes.
try { return Array.from(root.querySelectorAll(raw)); }
catch { return null; }
}
// Resolve pseudo-elements to their originating live elements. An attached
// pseudo-element (`.card::before`) belongs to the element before it, while
// a hostless pseudo-element after a combinator (`main > ::before`) belongs
// to a matching element at that position (`main > *`).
if (!fallback || /^[,\s]*$/.test(fallback)) return null;
try { return Array.from(root.querySelectorAll(fallback)); }
catch { return null; }
}
let __snapContainerProbeSequence = 0;
function __snapIsContainerCssRule(rule) {
return rule?.constructor?.name === 'CSSContainerRule'
|| /^\s*@container\b/i.test(rule?.cssText || '');
}
function __snapStyleRuleAppliesToLiveMatches(rule, matches) {
const style = rule?.style;
if (!style || !matches?.length || typeof getComputedStyle !== 'function') return false;
const sequence = ++__snapContainerProbeSequence;
const property = `--impeccable-container-probe-${sequence}-${Math.random().toString(36).slice(2)}`;
const value = `impeccable-container-active-${sequence}`;
const previousValue = style.getPropertyValue(property);
const previousPriority = style.getPropertyPriority(property);
try { style.setProperty(property, value, 'important'); }
catch { return false; }
const pseudoElements = [...new Set(
String(rule.selectorText || '').match(/::[a-zA-Z-]+(?:\([^)]*\))?/g) || [],
)];
try {
return matches.some(el => [null, ...pseudoElements].some(pseudo => {
try {
const computed = pseudo ? getComputedStyle(el, pseudo) : getComputedStyle(el);
return computed.getPropertyValue(property).trim() === value;
} catch { return false; }
}));
} finally {
if (previousValue) style.setProperty(property, previousValue, previousPriority);
else style.removeProperty(property);
}
}
function __snapConditionalCssRuleIsActive(rule) {
const type = Number(rule?.type);
const constructorName = rule?.constructor?.name || '';
if (constructorName === 'CSSMediaRule' || type === 4) {
const condition = rule.conditionText || rule.media?.mediaText || '';
if (!condition || typeof window.matchMedia !== 'function') return true;
try { return window.matchMedia(condition).matches; }
catch { return true; }
}
if (constructorName === 'CSSSupportsRule' || type === 12) {
const condition = rule.conditionText || '';
if (!condition || typeof CSS === 'undefined' || typeof CSS.supports !== 'function') return true;
try { return CSS.supports(condition); }
catch { return true; }
}
return true;
}
function __snapSplitCssCommaList(value) {
const parts = [];
let current = '';
let quote = '';
let escaped = false;
for (const char of String(value || '')) {
if (escaped) { current += char; escaped = false; continue; }
if (char === '\\') { current += char; escaped = true; continue; }
if (quote) { current += char; if (char === quote) quote = ''; continue; }
if (char === '"' || char === "'") { quote = char; current += char; continue; }
if (char === ',') { parts.push(current); current = ''; continue; }
current += char;
}
parts.push(current);
return parts;
}
function __snapNormalizeAnimationName(value) {
const name = String(value || '').trim();
if (name.length >= 2 && name[0] === name[name.length - 1] && (name[0] === '"' || name[0] === "'")) {
return name.slice(1, -1);
}
return name;
}
function __snapAnimationNamesDeclaredByRule(rule) {
const style = rule?.style;
if (!style) return [];
let value = '';
try {
value = style.animationName
|| style.getPropertyValue?.('animation-name')
|| style.webkitAnimationName
|| style.getPropertyValue?.('-webkit-animation-name')
|| '';
} catch { return []; }
return __snapSplitCssCommaList(value)
.map(__snapNormalizeAnimationName)
.filter(name => name && name.toLowerCase() !== 'none');
}
function __snapKeyframesRuleName(rule, cssText) {
const constructorName = rule?.constructor?.name || '';
const type = Number(rule?.type);
const isKeyframes = constructorName === 'CSSKeyframesRule'
|| constructorName === 'WebKitCSSKeyframesRule'
|| type === 7
|| /^\s*@(?:-webkit-)?keyframes\b/i.test(cssText);
if (!isKeyframes) return '';
const match = String(cssText || '').match(/^\s*@(?:-webkit-)?keyframes\s+([^\s{]+)/i);
return __snapNormalizeAnimationName(rule?.name || match?.[1] || '');
}
function __snapCssPropertyName(property) {
if (property.startsWith('--')) return property;
return property.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);
}
function __snapResolvedAnimationKeyframes(candidateNames) {
if (typeof document.getAnimations !== 'function') return null;
let animations;
try { animations = document.getAnimations(); }
catch { return null; }
const resolved = new Map();
const metadata = new Set(['offset', 'computedOffset', 'easing', 'composite']);
for (const animation of animations) {
const name = __snapNormalizeAnimationName(animation?.animationName || '');
if (!name || !candidateNames.has(name) || resolved.has(name)) continue;
let frames;
try { frames = animation.effect?.getKeyframes?.() || []; }
catch { continue; }
const blocks = [];
for (const frame of frames) {
const rawOffset = Number.isFinite(frame.computedOffset) ? frame.computedOffset : frame.offset;
if (!Number.isFinite(rawOffset)) continue;
const offset = Math.round(rawOffset * 1000000) / 10000;
const declarations = Object.entries(frame)
.filter(([property, value]) => !metadata.has(property) && value != null && value !== '')
.map(([property, value]) => `${__snapCssPropertyName(property)}: ${value};`);
const easing = String(frame.easing || '').trim();
if (easing && easing.toLowerCase() !== 'linear') {
declarations.push(`animation-timing-function: ${easing};`);
}
if (declarations.length === 0) continue;
blocks.push(`${offset}% { ${declarations.join(' ')} }`);
}
if (blocks.length > 0) resolved.set(name, `@keyframes ${name} { ${blocks.join(' ')} }`);
}
return resolved;
}
// Read CSS that is absent from document.outerHTML. Inline