@emailens/engine 0.10.2 → 0.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -208,6 +208,19 @@ declare const COMPOUND_VALUE_FEATURES: readonly ["::after", "::before", "::first
208
208
  /** CSS function features (e.g., "linear-gradient"). */
209
209
  declare const CSS_FUNCTION_FEATURES: readonly ["calc", "clamp", "conic-gradient", "fit-content", "linear-gradient", "max", "min", "radial-gradient"];
210
210
 
211
+ /**
212
+ * caniemail's page for each feature, for a diagnostic's `codeDescription`.
213
+ *
214
+ * 250 of 255 features. The rest have no caniemail entry of
215
+ * their own and get no link, which is the honest outcome — a link to a 404
216
+ * is worse than none.
217
+ *
218
+ * DO NOT EDIT — regenerate with: bun run sync:feature-urls
219
+ */
220
+ declare const FEATURE_URLS: Record<string, string>;
221
+ /** Where to read about a rule, when there is somewhere. */
222
+ declare function featureUrl(code: string): string | undefined;
223
+
211
224
  /**
212
225
  * Properties whose "partial" rating is value-level: the property usually
213
226
  * renders fine and only specific values hit the caveat. For these the warning
@@ -562,4 +575,4 @@ declare function alphaBlend(fg: RGBA, bgR: number, bgG: number, bgB: number): [n
562
575
  */
563
576
  declare function downlevelCSS(html: string): string;
564
577
 
565
- export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkOverflow, checkSize, checkTemplateVariables, checkVisual, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
578
+ export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, FEATURE_URLS, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkOverflow, checkSize, checkTemplateVariables, checkVisual, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, featureUrl, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
package/dist/index.d.ts CHANGED
@@ -208,6 +208,19 @@ declare const COMPOUND_VALUE_FEATURES: readonly ["::after", "::before", "::first
208
208
  /** CSS function features (e.g., "linear-gradient"). */
209
209
  declare const CSS_FUNCTION_FEATURES: readonly ["calc", "clamp", "conic-gradient", "fit-content", "linear-gradient", "max", "min", "radial-gradient"];
210
210
 
211
+ /**
212
+ * caniemail's page for each feature, for a diagnostic's `codeDescription`.
213
+ *
214
+ * 250 of 255 features. The rest have no caniemail entry of
215
+ * their own and get no link, which is the honest outcome — a link to a 404
216
+ * is worse than none.
217
+ *
218
+ * DO NOT EDIT — regenerate with: bun run sync:feature-urls
219
+ */
220
+ declare const FEATURE_URLS: Record<string, string>;
221
+ /** Where to read about a rule, when there is somewhere. */
222
+ declare function featureUrl(code: string): string | undefined;
223
+
211
224
  /**
212
225
  * Properties whose "partial" rating is value-level: the property usually
213
226
  * renders fine and only specific values hit the caveat. For these the warning
@@ -562,4 +575,4 @@ declare function alphaBlend(fg: RGBA, bgR: number, bgG: number, bgB: number): [n
562
575
  */
563
576
  declare function downlevelCSS(html: string): string;
564
577
 
565
- export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkOverflow, checkSize, checkTemplateVariables, checkVisual, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
578
+ export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, FEATURE_URLS, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkOverflow, checkSize, checkTemplateVariables, checkVisual, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, featureUrl, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
package/dist/index.js CHANGED
@@ -10915,6 +10915,54 @@ function locOfAttr(el, attr) {
10915
10915
  const attrLoc = (_d = (_a = raw.attrs) == null ? void 0 : _a[attr]) != null ? _d : (_c = (_b = raw.startTag) == null ? void 0 : _b.attrs) == null ? void 0 : _c[attr];
10916
10916
  return attrLoc ? toLoc(attrLoc) : locOfElement(el);
10917
10917
  }
10918
+ function locInAttr(attrLoc, source, property, occurrence = 0) {
10919
+ if (!attrLoc || !source) return void 0;
10920
+ const raw = source.slice(attrLoc.offset, attrLoc.offset + attrLoc.length);
10921
+ const open = raw.search(/["']/);
10922
+ const close = raw.lastIndexOf(raw[open]);
10923
+ if (open === -1 || close <= open) return void 0;
10924
+ const found = declarationsIn(raw.slice(open + 1, close), property);
10925
+ const hit = found[occurrence];
10926
+ if (!hit) return void 0;
10927
+ const start = attrLoc.offset + open + 1 + hit.start;
10928
+ const end = attrLoc.offset + open + 1 + hit.end;
10929
+ const from = positionOf(source, start);
10930
+ const to = positionOf(source, end);
10931
+ return {
10932
+ line: from.line,
10933
+ column: from.column,
10934
+ endLine: to.line,
10935
+ endColumn: to.column,
10936
+ offset: start,
10937
+ length: end - start
10938
+ };
10939
+ }
10940
+ function declarationsIn(value, property) {
10941
+ const wanted = property.toLowerCase();
10942
+ const found = [];
10943
+ let depth = 0;
10944
+ let start = 0;
10945
+ const consider = (from, to) => {
10946
+ const text = value.slice(from, to);
10947
+ const colon = text.indexOf(":");
10948
+ if (colon === -1) return;
10949
+ if (text.slice(0, colon).trim().toLowerCase() !== wanted) return;
10950
+ const lead = text.length - text.trimStart().length;
10951
+ const trail = text.length - text.trimEnd().length;
10952
+ if (from + lead < to - trail) found.push({ start: from + lead, end: to - trail });
10953
+ };
10954
+ for (let i = 0; i < value.length; i++) {
10955
+ const c = value[i];
10956
+ if (c === "(") depth++;
10957
+ else if (c === ")") depth = Math.max(0, depth - 1);
10958
+ else if (c === ";" && depth === 0) {
10959
+ consider(start, i);
10960
+ start = i + 1;
10961
+ }
10962
+ }
10963
+ consider(start, value.length);
10964
+ return found;
10965
+ }
10918
10966
  function locOfFirst($, selector) {
10919
10967
  const el = $(selector).first()[0];
10920
10968
  return el ? locOfElement(el) : void 0;
@@ -11180,7 +11228,7 @@ function describeSelector($, el) {
11180
11228
  if (cls) return `${tag}.${cls.split(/\s+/)[0]}`;
11181
11229
  return tag;
11182
11230
  }
11183
- function checkDarkModeFromDom($) {
11231
+ function checkDarkModeFromDom($, source) {
11184
11232
  var _a, _b;
11185
11233
  const darkBlock = collectDarkBlocks($);
11186
11234
  if (!darkBlock) return [];
@@ -11207,7 +11255,7 @@ function checkDarkModeFromDom($) {
11207
11255
  const coveredByAny = matchedElements($, darkBlock.any);
11208
11256
  let uncovered = 0;
11209
11257
  $("[bgcolor], [style]").each((_, el) => {
11210
- var _a2;
11258
+ var _a2, _b2;
11211
11259
  if (uncovered >= MAX_UNCOVERED_ELEMENTS) return false;
11212
11260
  const $el = $(el);
11213
11261
  const style = parseInlineStyle($el.attr("style") || "");
@@ -11217,7 +11265,8 @@ function checkDarkModeFromDom($) {
11217
11265
  if (inline ? coveredByImportant.has(el) : coveredByAny.has(el)) return;
11218
11266
  uncovered++;
11219
11267
  const selector = describeSelector($, el);
11220
- const loc = locOfAttr(el, inline ? "style" : "bgcolor");
11268
+ const attrLoc = locOfAttr(el, inline ? "style" : "bgcolor");
11269
+ const loc = inline ? (_b2 = locInAttr(attrLoc, source, style.get("background-color") !== void 0 ? "background-color" : "background")) != null ? _b2 : attrLoc : attrLoc;
11221
11270
  for (const clientId of PREFERS_COLOR_SCHEME_CLIENTS) {
11222
11271
  warnings.push(__spreadValues({
11223
11272
  severity: "warning",
@@ -11482,18 +11531,37 @@ function analyzeEmailFromDom($, framework, source) {
11482
11531
  const style = $(el).attr("style") || "";
11483
11532
  const props = parseStyleProperties(style);
11484
11533
  const selector = describeSelector2(el);
11485
- const locs = elementLocs(locOfAttr(el, "style"));
11534
+ const attrLoc = locOfAttr(el, "style");
11535
+ const declarationLocs = (prop, occurrence = 0) => {
11536
+ var _a;
11537
+ return (_a = elementLocs(locInAttr(attrLoc, source, prop, occurrence))) != null ? _a : elementLocs(attrLoc);
11538
+ };
11539
+ const locs = elementLocs(attrLoc);
11486
11540
  for (const prop of props) {
11487
11541
  for (const det of COMPOUND_DETECTORS) {
11488
11542
  if (prop === det.property) {
11489
11543
  const value2 = getStyleValue(style, prop);
11490
11544
  if (value2 == null ? void 0 : value2.toLowerCase().includes(det.valueIncludes)) {
11491
- checkPropertySupport(det.key, addWarning, framework, selector, void 0, void 0, locs);
11545
+ checkPropertySupport(
11546
+ det.key,
11547
+ addWarning,
11548
+ framework,
11549
+ selector,
11550
+ void 0,
11551
+ void 0,
11552
+ declarationLocs(prop)
11553
+ );
11492
11554
  }
11493
11555
  }
11494
11556
  }
11495
11557
  if (cssPropertiesToCheck.includes(prop)) {
11496
11558
  const declared = getStyleValues(style, prop);
11559
+ const placed = [];
11560
+ declared.forEach((value2, i) => {
11561
+ const at = locInAttr(attrLoc, source, prop, i);
11562
+ if (at) placed.push({ value: value2, loc: at });
11563
+ });
11564
+ const occurrences = placed.length === declared.length && placed.length > 0 ? { locs: placed.map((p) => p.loc), values: placed.map((p) => p.value) } : locs;
11497
11565
  checkPropertySupport(
11498
11566
  prop,
11499
11567
  addWarning,
@@ -11501,14 +11569,22 @@ function analyzeEmailFromDom($, framework, source) {
11501
11569
  selector,
11502
11570
  void 0,
11503
11571
  declared.length ? declared : void 0,
11504
- locs
11572
+ occurrences
11505
11573
  );
11506
11574
  }
11507
11575
  const value = getStyleValue(style, prop);
11508
11576
  if (value) {
11509
11577
  for (const fn of CSS_FUNCTION_DETECTORS) {
11510
11578
  if (value.includes(fn.pattern)) {
11511
- checkPropertySupport(fn.key, addWarning, framework, selector, void 0, void 0, locs);
11579
+ checkPropertySupport(
11580
+ fn.key,
11581
+ addWarning,
11582
+ framework,
11583
+ selector,
11584
+ void 0,
11585
+ void 0,
11586
+ declarationLocs(prop)
11587
+ );
11512
11588
  }
11513
11589
  }
11514
11590
  }
@@ -11547,7 +11623,7 @@ function analyzeEmailFromDom($, framework, source) {
11547
11623
  for (const fn of detectedCssFunctions) {
11548
11624
  checkPropertySupport(fn, addWarning, framework, void 0, propertyLines.get(fn), void 0, propertyLocs.get(fn));
11549
11625
  }
11550
- for (const w of checkDarkModeFromDom($)) addWarning(w);
11626
+ for (const w of checkDarkModeFromDom($, source)) addWarning(w);
11551
11627
  const severityOrder = { error: 0, warning: 1, info: 2 };
11552
11628
  warnings.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
11553
11629
  return warnings;
@@ -11977,6 +12053,263 @@ function extractCode(response) {
11977
12053
  return response.trim();
11978
12054
  }
11979
12055
 
12056
+ // src/rules/feature-urls.ts
12057
+ var FEATURE_URLS = {
12058
+ "!important": "https://www.caniemail.com/features/css-important/",
12059
+ "::after": "https://www.caniemail.com/features/css-pseudo-element-after/",
12060
+ "::before": "https://www.caniemail.com/features/css-pseudo-element-before/",
12061
+ "::first-letter": "https://www.caniemail.com/features/css-pseudo-element-first-letter/",
12062
+ "::first-line": "https://www.caniemail.com/features/css-pseudo-element-first-line/",
12063
+ "::marker": "https://www.caniemail.com/features/css-pseudo-element-marker/",
12064
+ "::placeholder": "https://www.caniemail.com/features/css-pseudo-element-placeholder/",
12065
+ ":adjacent-sibling": "https://www.caniemail.com/features/css-selector-adjacent-sibling/",
12066
+ ":attribute-selector": "https://www.caniemail.com/features/css-selector-attribute/",
12067
+ ":chaining": "https://www.caniemail.com/features/css-selector-chaining/",
12068
+ ":checked": "https://www.caniemail.com/features/css-pseudo-class-checked/",
12069
+ ":child-combinator": "https://www.caniemail.com/features/css-selector-child/",
12070
+ ":class-selector": "https://www.caniemail.com/features/css-selector-class/",
12071
+ ":descendant-combinator": "https://www.caniemail.com/features/css-selector-descendant/",
12072
+ ":first-child": "https://www.caniemail.com/features/css-pseudo-class-first-child/",
12073
+ ":first-of-type": "https://www.caniemail.com/features/css-pseudo-class-first-of-type/",
12074
+ ":focus": "https://www.caniemail.com/features/css-pseudo-class-focus/",
12075
+ ":focus-visible": "https://www.caniemail.com/features/css-pseudo-class-focus-visible/",
12076
+ ":focus-within": "https://www.caniemail.com/features/css-pseudo-class-focus-within/",
12077
+ ":general-sibling": "https://www.caniemail.com/features/css-selector-general-sibling/",
12078
+ ":grouping": "https://www.caniemail.com/features/css-selector-grouping/",
12079
+ ":has": "https://www.caniemail.com/features/css-pseudo-class-has/",
12080
+ ":hover": "https://www.caniemail.com/features/css-pseudo-class-hover/",
12081
+ ":id-selector": "https://www.caniemail.com/features/css-selector-id/",
12082
+ ":lang": "https://www.caniemail.com/features/css-pseudo-class-lang/",
12083
+ ":last-child": "https://www.caniemail.com/features/css-pseudo-class-last-child/",
12084
+ ":last-of-type": "https://www.caniemail.com/features/css-pseudo-class-last-of-type/",
12085
+ ":link": "https://www.caniemail.com/features/css-pseudo-class-link/",
12086
+ ":not": "https://www.caniemail.com/features/css-pseudo-class-not/",
12087
+ ":nth-child": "https://www.caniemail.com/features/css-pseudo-class-nth-child/",
12088
+ ":nth-last-child": "https://www.caniemail.com/features/css-pseudo-class-nth-last-child/",
12089
+ ":nth-of-type": "https://www.caniemail.com/features/css-pseudo-class-nth-of-type/",
12090
+ ":only-child": "https://www.caniemail.com/features/css-pseudo-class-only-child/",
12091
+ ":only-of-type": "https://www.caniemail.com/features/css-pseudo-class-only-of-type/",
12092
+ ":target": "https://www.caniemail.com/features/css-pseudo-class-target/",
12093
+ ":type-selector": "https://www.caniemail.com/features/css-selector-type/",
12094
+ ":universal-selector": "https://www.caniemail.com/features/css-selector-universal/",
12095
+ ":visited": "https://www.caniemail.com/features/css-pseudo-class-visited/",
12096
+ "<abbr>": "https://www.caniemail.com/features/html-abbr/",
12097
+ "<acronym>": "https://www.caniemail.com/features/html-acronym/",
12098
+ "<address>": "https://www.caniemail.com/features/html-address/",
12099
+ "<audio>": "https://www.caniemail.com/features/html-audio/",
12100
+ "<base>": "https://www.caniemail.com/features/html-base/",
12101
+ "<bdi>": "https://www.caniemail.com/features/html-bdi/",
12102
+ "<blockquote>": "https://www.caniemail.com/features/html-blockquote/",
12103
+ "<body>": "https://www.caniemail.com/features/html-body/",
12104
+ "<code>": "https://www.caniemail.com/features/html-code/",
12105
+ "<del>": "https://www.caniemail.com/features/html-del/",
12106
+ "<dfn>": "https://www.caniemail.com/features/html-dfn/",
12107
+ "<dialog>": "https://www.caniemail.com/features/html-dialog/",
12108
+ "<div>": "https://www.caniemail.com/features/html-div/",
12109
+ "<form>": "https://www.caniemail.com/features/html-form/",
12110
+ "<h1>": "https://www.caniemail.com/features/html-h1-h6/",
12111
+ "<hr>": "https://www.caniemail.com/features/html-hr/",
12112
+ "<img>": "https://www.caniemail.com/features/html-img/",
12113
+ "<link>": "https://www.caniemail.com/features/html-link/",
12114
+ "<marquee>": "https://www.caniemail.com/features/html-marquee/",
12115
+ "<meter>": "https://www.caniemail.com/features/html-meter/",
12116
+ "<object>": "https://www.caniemail.com/features/html-object/",
12117
+ "<p>": "https://www.caniemail.com/features/html-p/",
12118
+ "<picture>": "https://www.caniemail.com/features/html-picture/",
12119
+ "<pre>": "https://www.caniemail.com/features/html-pre/",
12120
+ "<progress>": "https://www.caniemail.com/features/html-progress/",
12121
+ "<rp>": "https://www.caniemail.com/features/html-rp/",
12122
+ "<rt>": "https://www.caniemail.com/features/html-rt/",
12123
+ "<ruby>": "https://www.caniemail.com/features/html-ruby/",
12124
+ "<select>": "https://www.caniemail.com/features/html-select/",
12125
+ "<small>": "https://www.caniemail.com/features/html-small/",
12126
+ "<span>": "https://www.caniemail.com/features/html-span/",
12127
+ "<strike>": "https://www.caniemail.com/features/html-strike/",
12128
+ "<strong>": "https://www.caniemail.com/features/html-strong/",
12129
+ "<style>": "https://www.caniemail.com/features/html-style/",
12130
+ "<svg>": "https://www.caniemail.com/features/html-svg/",
12131
+ "<table>": "https://www.caniemail.com/features/html-table/",
12132
+ "<textarea>": "https://www.caniemail.com/features/html-textarea/",
12133
+ "<ul>": "https://www.caniemail.com/features/html-lists/",
12134
+ "<video>": "https://www.caniemail.com/features/html-video/",
12135
+ "<wbr>": "https://www.caniemail.com/features/html-wbr/",
12136
+ "@font-face": "https://www.caniemail.com/features/css-at-font-face/",
12137
+ "@import": "https://www.caniemail.com/features/css-at-import/",
12138
+ "@keyframes": "https://www.caniemail.com/features/css-at-keyframes/",
12139
+ "@media": "https://www.caniemail.com/features/css-at-media/",
12140
+ "@supports": "https://www.caniemail.com/features/css-at-supports/",
12141
+ "accent-color": "https://www.caniemail.com/features/css-accent-color/",
12142
+ "align-items": "https://www.caniemail.com/features/css-align-items/",
12143
+ "animation": "https://www.caniemail.com/features/css-animation/",
12144
+ "aspect-ratio": "https://www.caniemail.com/features/css-aspect-ratio/",
12145
+ "backdrop-filter": "https://www.caniemail.com/features/css-backdrop-filter/",
12146
+ "background": "https://www.caniemail.com/features/css-background/",
12147
+ "background-blend-mode": "https://www.caniemail.com/features/css-background-blend-mode/",
12148
+ "background-clip": "https://www.caniemail.com/features/css-background-clip/",
12149
+ "background-color": "https://www.caniemail.com/features/css-background-color/",
12150
+ "background-image": "https://www.caniemail.com/features/css-background-image/",
12151
+ "background-origin": "https://www.caniemail.com/features/css-background-origin/",
12152
+ "background-position": "https://www.caniemail.com/features/css-background-position/",
12153
+ "background-repeat": "https://www.caniemail.com/features/css-background-repeat/",
12154
+ "background-size": "https://www.caniemail.com/features/css-background-size/",
12155
+ "bimi": "https://www.caniemail.com/features/bimi/",
12156
+ "block-size": "https://www.caniemail.com/features/css-block-inline-size/",
12157
+ "border": "https://www.caniemail.com/features/css-border/",
12158
+ "border-collapse": "https://www.caniemail.com/features/css-border-collapse/",
12159
+ "border-image": "https://www.caniemail.com/features/css-border-image/",
12160
+ "border-inline": "https://www.caniemail.com/features/css-border-inline-block/",
12161
+ "border-inline-individual": "https://www.caniemail.com/features/css-border-inline-block-individual/",
12162
+ "border-inline-longhand": "https://www.caniemail.com/features/css-border-inline-block-longhand/",
12163
+ "border-radius": "https://www.caniemail.com/features/css-border-radius/",
12164
+ "border-radius-logical": "https://www.caniemail.com/features/css-border-radius-logical/",
12165
+ "border-spacing": "https://www.caniemail.com/features/css-border-spacing/",
12166
+ "box-shadow": "https://www.caniemail.com/features/css-box-shadow/",
12167
+ "box-sizing": "https://www.caniemail.com/features/css-box-sizing/",
12168
+ "calc": "https://www.caniemail.com/features/css-unit-calc/",
12169
+ "caption-side": "https://www.caniemail.com/features/css-caption-side/",
12170
+ "clamp": "https://www.caniemail.com/features/css-function-clamp/",
12171
+ "clear": "https://www.caniemail.com/features/css-clear/",
12172
+ "clip-path": "https://www.caniemail.com/features/css-clip-path/",
12173
+ "color-scheme": "https://www.caniemail.com/features/css-color-scheme/",
12174
+ "column-count": "https://www.caniemail.com/features/css-column-count/",
12175
+ "columns": "https://www.caniemail.com/features/css-column-layout-properties/",
12176
+ "conic-gradient": "https://www.caniemail.com/features/css-conic-gradient/",
12177
+ "css-comments": "https://www.caniemail.com/features/css-comments/",
12178
+ "cursor": "https://www.caniemail.com/features/css-cursor/",
12179
+ "custom-properties": "https://www.caniemail.com/features/css-variables/",
12180
+ "direction": "https://www.caniemail.com/features/css-direction/",
12181
+ "display": "https://www.caniemail.com/features/css-display/",
12182
+ "display:flex": "https://www.caniemail.com/features/css-display-flex/",
12183
+ "display:grid": "https://www.caniemail.com/features/css-display-grid/",
12184
+ "display:none": "https://www.caniemail.com/features/css-display-none/",
12185
+ "empty-cells": "https://www.caniemail.com/features/css-empty-cells/",
12186
+ "filter": "https://www.caniemail.com/features/css-filter/",
12187
+ "fit-content": "https://www.caniemail.com/features/css-intrinsic-size/",
12188
+ "flex-direction": "https://www.caniemail.com/features/css-flex-direction/",
12189
+ "flex-wrap": "https://www.caniemail.com/features/css-flex-wrap/",
12190
+ "float": "https://www.caniemail.com/features/css-float/",
12191
+ "font": "https://www.caniemail.com/features/css-font/",
12192
+ "font-kerning": "https://www.caniemail.com/features/css-font-kerning/",
12193
+ "font-size": "https://www.caniemail.com/features/css-font-size/",
12194
+ "font-size-adjust": "https://www.caniemail.com/features/css-font-size-adjust/",
12195
+ "font-stretch": "https://www.caniemail.com/features/css-font-stretch/",
12196
+ "font-weight": "https://www.caniemail.com/features/css-font-weight/",
12197
+ "gap": "https://www.caniemail.com/features/css-gap/",
12198
+ "grid-template-columns": "https://www.caniemail.com/features/css-grid-template/",
12199
+ "height": "https://www.caniemail.com/features/css-height/",
12200
+ "hyphenate-character": "https://www.caniemail.com/features/css-hyphenate-character/",
12201
+ "hyphenate-limit-chars": "https://www.caniemail.com/features/css-hyphenate-limit-chars/",
12202
+ "hyphens": "https://www.caniemail.com/features/css-hyphens/",
12203
+ "inert": "https://www.caniemail.com/features/css-inert-attribute/",
12204
+ "inline-size": "https://www.caniemail.com/features/css-inline-size/",
12205
+ "inset": "https://www.caniemail.com/features/css-inset/",
12206
+ "justify-content": "https://www.caniemail.com/features/css-justify-content/",
12207
+ "left": "https://www.caniemail.com/features/css-left-right-top-bottom/",
12208
+ "letter-spacing": "https://www.caniemail.com/features/css-letter-spacing/",
12209
+ "light-dark": "https://www.caniemail.com/features/css-function-light-dark/",
12210
+ "line-height": "https://www.caniemail.com/features/css-line-height/",
12211
+ "linear-gradient": "https://www.caniemail.com/features/css-linear-gradient/",
12212
+ "list-style": "https://www.caniemail.com/features/css-list-style/",
12213
+ "list-style-image": "https://www.caniemail.com/features/css-list-style-image/",
12214
+ "list-style-position": "https://www.caniemail.com/features/css-list-style-position/",
12215
+ "list-style-type": "https://www.caniemail.com/features/css-list-style-type/",
12216
+ "margin": "https://www.caniemail.com/features/css-margin/",
12217
+ "margin-block-start-end": "https://www.caniemail.com/features/css-margin-block-start-end/",
12218
+ "margin-inline-block": "https://www.caniemail.com/features/css-margin-inline-block/",
12219
+ "margin-inline-start-end": "https://www.caniemail.com/features/css-margin-inline-start-end/",
12220
+ "mask-image": "https://www.caniemail.com/features/css-mask-image/",
12221
+ "max": "https://www.caniemail.com/features/css-function-max/",
12222
+ "max-block-size": "https://www.caniemail.com/features/css-max-block-size/",
12223
+ "max-height": "https://www.caniemail.com/features/css-max-height/",
12224
+ "max-inline-size": "https://www.caniemail.com/features/css-max-inline-size/",
12225
+ "max-width": "https://www.caniemail.com/features/css-max-width/",
12226
+ "min": "https://www.caniemail.com/features/css-function-min/",
12227
+ "min-block-size": "https://www.caniemail.com/features/css-min-block-size/",
12228
+ "min-height": "https://www.caniemail.com/features/css-min-height/",
12229
+ "min-inline-size": "https://www.caniemail.com/features/css-min-inline-size/",
12230
+ "min-width": "https://www.caniemail.com/features/css-min-width/",
12231
+ "mix-blend-mode": "https://www.caniemail.com/features/css-mix-blend-mode/",
12232
+ "modern-color": "https://www.caniemail.com/features/css-modern-color/",
12233
+ "nesting": "https://www.caniemail.com/features/css-nesting/",
12234
+ "object-fit": "https://www.caniemail.com/features/css-object-fit/",
12235
+ "object-position": "https://www.caniemail.com/features/css-object-position/",
12236
+ "opacity": "https://www.caniemail.com/features/css-opacity/",
12237
+ "orphans": "https://www.caniemail.com/features/css-orphans/",
12238
+ "outline": "https://www.caniemail.com/features/css-outline/",
12239
+ "outline-offset": "https://www.caniemail.com/features/css-outline-offset/",
12240
+ "overflow": "https://www.caniemail.com/features/css-overflow/",
12241
+ "overflow-wrap": "https://www.caniemail.com/features/css-word-wrap/",
12242
+ "padding": "https://www.caniemail.com/features/css-padding/",
12243
+ "padding-block-start-end": "https://www.caniemail.com/features/css-padding-block-start-end/",
12244
+ "padding-inline-block": "https://www.caniemail.com/features/css-padding-inline-block/",
12245
+ "padding-inline-start-end": "https://www.caniemail.com/features/css-padding-inline-start-end/",
12246
+ "position": "https://www.caniemail.com/features/css-position/",
12247
+ "pseudo-class-active": "https://www.caniemail.com/features/css-pseudo-class-active/",
12248
+ "pseudo-class-default": "https://www.caniemail.com/features/css-pseudo-class-default/",
12249
+ "pseudo-class-nth-last-of-type": "https://www.caniemail.com/features/css-pseudo-class-nth-last-of-type/",
12250
+ "radial-gradient": "https://www.caniemail.com/features/css-radial-gradient/",
12251
+ "resize": "https://www.caniemail.com/features/css-resize/",
12252
+ "rgb": "https://www.caniemail.com/features/css-rgb/",
12253
+ "rgba": "https://www.caniemail.com/features/css-rgba/",
12254
+ "scroll-snap": "https://www.caniemail.com/features/css-scroll-snap/",
12255
+ "shape-margin": "https://www.caniemail.com/features/css-shape-margin/",
12256
+ "shape-outside": "https://www.caniemail.com/features/css-shape-outside/",
12257
+ "system-ui": "https://www.caniemail.com/features/css-sytem-ui/",
12258
+ "tab-size": "https://www.caniemail.com/features/css-tab-size/",
12259
+ "table-layout": "https://www.caniemail.com/features/css-table-layout/",
12260
+ "text-align": "https://www.caniemail.com/features/css-text-align/",
12261
+ "text-align-last": "https://www.caniemail.com/features/css-text-align-last/",
12262
+ "text-decoration": "https://www.caniemail.com/features/css-text-decoration/",
12263
+ "text-decoration-color": "https://www.caniemail.com/features/css-text-decoration-color/",
12264
+ "text-decoration-line": "https://www.caniemail.com/features/css-text-decoration-line/",
12265
+ "text-decoration-skip-ink": "https://www.caniemail.com/features/css-text-decoration-skip-ink/",
12266
+ "text-decoration-style": "https://www.caniemail.com/features/css-text-decoration-style/",
12267
+ "text-decoration-thickness": "https://www.caniemail.com/features/css-text-decoration-thickness/",
12268
+ "text-emphasis": "https://www.caniemail.com/features/css-text-emphasis/",
12269
+ "text-emphasis-position": "https://www.caniemail.com/features/css-text-emphasis-position/",
12270
+ "text-indent": "https://www.caniemail.com/features/css-text-indent/",
12271
+ "text-justify": "https://www.caniemail.com/features/css-text-justify/",
12272
+ "text-orientation": "https://www.caniemail.com/features/css-text-orientation/",
12273
+ "text-overflow": "https://www.caniemail.com/features/css-text-overflow/",
12274
+ "text-shadow": "https://www.caniemail.com/features/css-text-shadow/",
12275
+ "text-transform": "https://www.caniemail.com/features/css-text-transform/",
12276
+ "text-underline-offset": "https://www.caniemail.com/features/css-text-underline-offset/",
12277
+ "text-underline-position": "https://www.caniemail.com/features/css-text-underline-position/",
12278
+ "text-wrap": "https://www.caniemail.com/features/css-text-wrap/",
12279
+ "transform": "https://www.caniemail.com/features/css-transform/",
12280
+ "transition": "https://www.caniemail.com/features/css-transition/",
12281
+ "unit-ch": "https://www.caniemail.com/features/css-unit-ch/",
12282
+ "unit-cm": "https://www.caniemail.com/features/css-unit-cm/",
12283
+ "unit-em": "https://www.caniemail.com/features/css-unit-em/",
12284
+ "unit-ex": "https://www.caniemail.com/features/css-unit-ex/",
12285
+ "unit-in": "https://www.caniemail.com/features/css-unit-in/",
12286
+ "unit-initial": "https://www.caniemail.com/features/css-unit-initial/",
12287
+ "unit-mm": "https://www.caniemail.com/features/css-unit-mm/",
12288
+ "unit-pc": "https://www.caniemail.com/features/css-unit-pc/",
12289
+ "unit-percent": "https://www.caniemail.com/features/css-unit-percent/",
12290
+ "unit-pt": "https://www.caniemail.com/features/css-unit-pt/",
12291
+ "unit-px": "https://www.caniemail.com/features/css-unit-px/",
12292
+ "unit-rem": "https://www.caniemail.com/features/css-unit-rem/",
12293
+ "unit-vh": "https://www.caniemail.com/features/css-unit-vh/",
12294
+ "unit-vmax": "https://www.caniemail.com/features/css-unit-vmax/",
12295
+ "unit-vmin": "https://www.caniemail.com/features/css-unit-vmin/",
12296
+ "unit-vw": "https://www.caniemail.com/features/css-unit-vw/",
12297
+ "user-select": "https://www.caniemail.com/features/css-user-select/",
12298
+ "vertical-align": "https://www.caniemail.com/features/css-vertical-align/",
12299
+ "visibility": "https://www.caniemail.com/features/css-visibility/",
12300
+ "white-space": "https://www.caniemail.com/features/css-white-space/",
12301
+ "white-space-collapse": "https://www.caniemail.com/features/css-white-space-collapse/",
12302
+ "widows": "https://www.caniemail.com/features/css-widows/",
12303
+ "width": "https://www.caniemail.com/features/css-width/",
12304
+ "word-break": "https://www.caniemail.com/features/css-word-break/",
12305
+ "word-spacing": "https://www.caniemail.com/features/css-word-spacing/",
12306
+ "writing-mode": "https://www.caniemail.com/features/css-writing-mode/",
12307
+ "z-index": "https://www.caniemail.com/features/css-z-index/"
12308
+ };
12309
+ function featureUrl(code) {
12310
+ return FEATURE_URLS[code];
12311
+ }
12312
+
11980
12313
  // src/spam-scorer.ts
11981
12314
  var SPAM_TRIGGER_PHRASES = [
11982
12315
  "act now",
@@ -13941,6 +14274,7 @@ export {
13941
14274
  CompileError,
13942
14275
  EMAIL_CLIENTS,
13943
14276
  EMPTY_DELIVERABILITY,
14277
+ FEATURE_URLS,
13944
14278
  GENERIC_LINK_TEXT,
13945
14279
  HTML_ELEMENT_FEATURES,
13946
14280
  MAX_HTML_SIZE,
@@ -13965,6 +14299,7 @@ export {
13965
14299
  errorWarnings,
13966
14300
  estimateAiFixTokens,
13967
14301
  extractInboxPreview,
14302
+ featureUrl,
13968
14303
  formatRgb,
13969
14304
  generateAiFix,
13970
14305
  generateCompatibilityScore,