@templatical/editor 0.21.0 → 0.21.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/{AiFeatureMenu-CPdNpHpZ.js → AiFeatureMenu-CcqQDHzJ.js} +1 -1
- package/dist/{CloudEditor-3a7mqMhe.js → CloudEditor-Dnww6og-.js} +5 -5
- package/dist/{CollaboratorBar-Ds0YZWzV.js → CollaboratorBar-Bj4NZiie.js} +1 -1
- package/dist/CountdownBlock-J_Q9JRQM.js +91 -0
- package/dist/{ParagraphEditor-CkwBirNl.js → ParagraphEditor--_zWfxps.js} +1 -1
- package/dist/{SaveBlockDialog-Cc5BSUBx.js → SaveBlockDialog-CYIEHABH.js} +3 -3
- package/dist/{SavedBlockPreviewCanvas-ubttfmKr.js → SavedBlockPreviewCanvas-2-mzAnZE.js} +1 -1
- package/dist/{SavedBlocksBrowserModal-LkY_U3lY.js → SavedBlocksBrowserModal-D5V5yF_3.js} +4 -4
- package/dist/{SavedBlocksPanels-CET0zvH6.js → SavedBlocksPanels-Dff38YXu.js} +1 -1
- package/dist/{SavedBlocksPickBar-poGS4PoI.js → SavedBlocksPickBar-rB6iyji6.js} +1 -1
- package/dist/{SnapshotHistory-BvF5IXn1.js → SnapshotHistory-FtzDq8f0.js} +1 -1
- package/dist/{TestEmailModal-BRaM_eko.js → TestEmailModal-DL2O1H8M.js} +2 -2
- package/dist/{TitleEditor-Bhgzh-iQ.js → TitleEditor-CPda5lh-.js} +1 -1
- package/dist/{TplModal-BA-Zsg0O.js → TplModal-C7Koj5gM.js} +1 -1
- package/dist/{blockTypeIcons-B1-Yzp-a.js → blockTypeIcons-CgwECCut.js} +1 -1
- package/dist/bundle-stats.json +8 -8
- package/dist/cdn/chunks/AiChatSidebar-A1CuWGY0.js +203 -0
- package/dist/cdn/chunks/AiChatSidebar-A1CuWGY0.js.map +1 -0
- package/dist/cdn/chunks/{AiFeatureMenu--PdArSnv.js → AiFeatureMenu-Duwg413F.js} +9 -5
- package/dist/cdn/chunks/{AiFeatureMenu--PdArSnv.js.map → AiFeatureMenu-Duwg413F.js.map} +1 -1
- package/dist/cdn/chunks/{BlockIssueBadge-DMSd0SIl.js → BlockIssueBadge-Da4yR-mh.js} +7 -5
- package/dist/cdn/chunks/{BlockIssueBadge-DMSd0SIl.js.map → BlockIssueBadge-Da4yR-mh.js.map} +1 -1
- package/dist/cdn/chunks/{CloudEditor-DnTfI5GU.js → CloudEditor-B3hqbwfP.js} +179 -170
- package/dist/cdn/chunks/{CloudEditor-DnTfI5GU.js.map → CloudEditor-B3hqbwfP.js.map} +1 -1
- package/dist/cdn/chunks/{CollaboratorBar-CBqd7ldq.js → CollaboratorBar-BS3rJy6-.js} +7 -6
- package/dist/cdn/chunks/{CollaboratorBar-CBqd7ldq.js.map → CollaboratorBar-BS3rJy6-.js.map} +1 -1
- package/dist/cdn/chunks/{ColorPicker-DCdWP8YB.js → ColorPicker-DZSzZ5ZP.js} +107 -103
- package/dist/cdn/chunks/{ColorPicker-DCdWP8YB.js.map → ColorPicker-DZSzZ5ZP.js.map} +1 -1
- package/dist/cdn/chunks/CommentsSidebar-DHdRiGPX.js +412 -0
- package/dist/cdn/chunks/CommentsSidebar-DHdRiGPX.js.map +1 -0
- package/dist/cdn/chunks/CountdownBlock-Bffpoppw.js +93 -0
- package/dist/cdn/chunks/{CountdownBlock-BDnWMAME.js.map → CountdownBlock-Bffpoppw.js.map} +1 -1
- package/dist/cdn/chunks/{CountdownToolbar-BbLoo22S.js → CountdownToolbar-DAnmIZjq.js} +4 -4
- package/dist/cdn/chunks/{CountdownToolbar-BbLoo22S.js.map → CountdownToolbar-DAnmIZjq.js.map} +1 -1
- package/dist/cdn/chunks/DesignReferenceSidebar-Dre99DTH.js +223 -0
- package/dist/cdn/chunks/DesignReferenceSidebar-Dre99DTH.js.map +1 -0
- package/dist/cdn/chunks/{IssuesPanel-CfudrI3T.js → IssuesPanel-D80JedOj.js} +11 -10
- package/dist/cdn/chunks/{IssuesPanel-CfudrI3T.js.map → IssuesPanel-D80JedOj.js.map} +1 -1
- package/dist/cdn/chunks/LoadingTrack-D-CW2tUa.js +12 -0
- package/dist/cdn/chunks/LoadingTrack-D-CW2tUa.js.map +1 -0
- package/dist/cdn/chunks/{NumberWithSuffix-BmMx9_n_.js → NumberWithSuffix-CjlVNIEe.js} +2 -2
- package/dist/cdn/chunks/{NumberWithSuffix-BmMx9_n_.js.map → NumberWithSuffix-CjlVNIEe.js.map} +1 -1
- package/dist/cdn/chunks/{ParagraphEditor-DPCUSXpx.js → ParagraphEditor-CtaRa1vr.js} +73 -68
- package/dist/cdn/chunks/{ParagraphEditor-DPCUSXpx.js.map → ParagraphEditor-CtaRa1vr.js.map} +1 -1
- package/dist/cdn/chunks/{RichTextEditorContent-B8dOiv_D.js → RichTextEditorContent-BbdgJqWM.js} +9 -6
- package/dist/cdn/chunks/{RichTextEditorContent-B8dOiv_D.js.map → RichTextEditorContent-BbdgJqWM.js.map} +1 -1
- package/dist/cdn/chunks/{SaveBlockDialog-BY3SMnNV.js → SaveBlockDialog-Bb3fdUEZ.js} +30 -26
- package/dist/cdn/chunks/{SaveBlockDialog-BY3SMnNV.js.map → SaveBlockDialog-Bb3fdUEZ.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlockPreviewCanvas-LpaOcusq.js → SavedBlockPreviewCanvas-DZOMgNsz.js} +33 -32
- package/dist/cdn/chunks/{SavedBlockPreviewCanvas-LpaOcusq.js.map → SavedBlockPreviewCanvas-DZOMgNsz.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksBrowserModal-CfIcmyzF.js → SavedBlocksBrowserModal-CeUWcPv0.js} +14 -10
- package/dist/cdn/chunks/{SavedBlocksBrowserModal-CfIcmyzF.js.map → SavedBlocksBrowserModal-CeUWcPv0.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksPanels-kIowCfh_.js → SavedBlocksPanels-D-pA_wfk.js} +2 -2
- package/dist/cdn/chunks/{SavedBlocksPanels-kIowCfh_.js.map → SavedBlocksPanels-D-pA_wfk.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksPickBar-WSGe1GiZ.js → SavedBlocksPickBar-1rf1KpqS.js} +6 -4
- package/dist/cdn/chunks/{SavedBlocksPickBar-WSGe1GiZ.js.map → SavedBlocksPickBar-1rf1KpqS.js.map} +1 -1
- package/dist/cdn/chunks/SnapshotHistory-Bf1uovti.js +121 -0
- package/dist/cdn/chunks/SnapshotHistory-Bf1uovti.js.map +1 -0
- package/dist/cdn/chunks/TemplateScoringPanel-CTk8WwxU.js +231 -0
- package/dist/cdn/chunks/TemplateScoringPanel-CTk8WwxU.js.map +1 -0
- package/dist/cdn/chunks/TestEmailModal-BJTDxFHh.js +96 -0
- package/dist/cdn/chunks/TestEmailModal-BJTDxFHh.js.map +1 -0
- package/dist/cdn/chunks/{TitleEditor-iwd-O9sO.js → TitleEditor-BJ7LFykI.js} +15 -12
- package/dist/cdn/chunks/{TitleEditor-iwd-O9sO.js.map → TitleEditor-BJ7LFykI.js.map} +1 -1
- package/dist/cdn/chunks/TplModal-CH9RzKF7.js +50 -0
- package/dist/cdn/chunks/TplModal-CH9RzKF7.js.map +1 -0
- package/dist/cdn/chunks/_plugin-vue_export-helper-B3ysoDQm.js +8 -0
- package/dist/cdn/chunks/blockTypeIcons-etMMQoVv.js +21 -0
- package/dist/cdn/chunks/{blockTypeIcons-BYz0fgLz.js.map → blockTypeIcons-etMMQoVv.js.map} +1 -1
- package/dist/cdn/chunks/cloud-BJlbXGTJ.js +1787 -0
- package/dist/cdn/chunks/cloud-BJlbXGTJ.js.map +1 -0
- package/dist/cdn/chunks/dist-CiBEt0VR.js +163 -0
- package/dist/cdn/chunks/dist-CiBEt0VR.js.map +1 -0
- package/dist/cdn/chunks/dist-CxTt8FRE.js +403 -0
- package/dist/cdn/chunks/dist-CxTt8FRE.js.map +1 -0
- package/dist/cdn/chunks/{extensions-DeJh3E9b.js → extensions-ZX2oarW6.js} +17 -15
- package/dist/cdn/chunks/{extensions-DeJh3E9b.js.map → extensions-ZX2oarW6.js.map} +1 -1
- package/dist/cdn/chunks/formatRelativeTime-CtUU-QZ8.js +12 -0
- package/dist/cdn/chunks/formatRelativeTime-CtUU-QZ8.js.map +1 -0
- package/dist/cdn/chunks/htmlparser-CZa2V5cF.js +1008 -0
- package/dist/cdn/chunks/htmlparser-CZa2V5cF.js.map +1 -0
- package/dist/cdn/chunks/icons-CYWw8Xfp.js +1190 -0
- package/dist/cdn/chunks/icons-CYWw8Xfp.js.map +1 -0
- package/dist/cdn/chunks/keys-D7kUmfpE.js +12 -0
- package/dist/cdn/chunks/keys-D7kUmfpE.js.map +1 -0
- package/dist/cdn/chunks/src-BKI1x1k7.js +546 -0
- package/dist/cdn/chunks/src-BKI1x1k7.js.map +1 -0
- package/dist/cdn/chunks/src-CM0gCvAS.js +1176 -0
- package/dist/cdn/chunks/src-CM0gCvAS.js.map +1 -0
- package/dist/cdn/chunks/{media-library-mCCZieYO.js → src-D6F_3XkE.js} +1782 -1280
- package/dist/cdn/chunks/src-D6F_3XkE.js.map +1 -0
- package/dist/cdn/chunks/{renderer-Yg1XhsBN.js → src-DYji-wXB.js} +118 -134
- package/dist/cdn/chunks/src-DYji-wXB.js.map +1 -0
- package/dist/cdn/chunks/{styles-Bp5Jsu9J.js → styles-DMOEiSX9.js} +867 -859
- package/dist/cdn/chunks/styles-DMOEiSX9.js.map +1 -0
- package/dist/cdn/chunks/timeouts-Bmi_yePw.js +6 -0
- package/dist/cdn/chunks/timeouts-Bmi_yePw.js.map +1 -0
- package/dist/cdn/chunks/useAliveFlag-aanU8uqB.js +12 -0
- package/dist/cdn/chunks/useAliveFlag-aanU8uqB.js.map +1 -0
- package/dist/cdn/chunks/useCloudI18n-BjNENqkM.js +25 -0
- package/dist/cdn/chunks/useCloudI18n-BjNENqkM.js.map +1 -0
- package/dist/cdn/chunks/useEditorCore-BA6mspzD.js +3019 -0
- package/dist/cdn/chunks/useEditorCore-BA6mspzD.js.map +1 -0
- package/dist/cdn/chunks/useI18n-8Wd7G-cq.js +19 -0
- package/dist/cdn/chunks/useI18n-8Wd7G-cq.js.map +1 -0
- package/dist/cdn/chunks/useMergeTag-C7G31KV-.js +46 -0
- package/dist/cdn/chunks/useMergeTag-C7G31KV-.js.map +1 -0
- package/dist/cdn/chunks/usePopoverPosition-Bx0QewTv.js +61 -0
- package/dist/cdn/chunks/usePopoverPosition-Bx0QewTv.js.map +1 -0
- package/dist/cdn/editor.css +1 -1
- package/dist/cdn/editor.js +72 -69
- package/dist/cdn/editor.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/{styles-DIDAJdkj.js → styles-PcOPXvLO.js} +547 -549
- package/dist/templatical-editor.js +5 -5
- package/dist/{useEditorCore-Bd9CA4L_.js → useEditorCore-CT1slufs.js} +3 -3
- package/package.json +7 -7
- package/dist/CountdownBlock-BUHYIAe9.js +0 -92
- package/dist/cdn/chunks/CountdownBlock-BDnWMAME.js +0 -93
- package/dist/cdn/chunks/blockTypeIcons-BYz0fgLz.js +0 -22
- package/dist/cdn/chunks/features-pLfGJWIB.js +0 -7813
- package/dist/cdn/chunks/features-pLfGJWIB.js.map +0 -1
- package/dist/cdn/chunks/icons-FLemooQz.js +0 -690
- package/dist/cdn/chunks/icons-FLemooQz.js.map +0 -1
- package/dist/cdn/chunks/media-library-mCCZieYO.js.map +0 -1
- package/dist/cdn/chunks/quality-BRbHtAk1.js +0 -2180
- package/dist/cdn/chunks/quality-BRbHtAk1.js.map +0 -1
- package/dist/cdn/chunks/renderer-Yg1XhsBN.js.map +0 -1
- package/dist/cdn/chunks/src-BDJeYiVE.js +0 -509
- package/dist/cdn/chunks/src-BDJeYiVE.js.map +0 -1
- package/dist/cdn/chunks/styles-Bp5Jsu9J.js.map +0 -1
|
@@ -0,0 +1,1176 @@
|
|
|
1
|
+
import { n as e } from "./rolldown-runtime-Dqa2HsxW.js";
|
|
2
|
+
import { B as t, G as n, H as r, J as i, K as a, L as o, P as s, R as c, V as l, W as ee, z as u } from "./src-BKI1x1k7.js";
|
|
3
|
+
import { t as d } from "./htmlparser-CZa2V5cF.js";
|
|
4
|
+
//#region ../quality/src/types.ts
|
|
5
|
+
var f = {
|
|
6
|
+
altMaxLength: 125,
|
|
7
|
+
minFontSize: 14,
|
|
8
|
+
allCapsMinLength: 20,
|
|
9
|
+
minTouchTargetPx: 44
|
|
10
|
+
}, te = [
|
|
11
|
+
"localhost",
|
|
12
|
+
"127.0.0.1",
|
|
13
|
+
"0.0.0.0",
|
|
14
|
+
"*.local",
|
|
15
|
+
"*.staging.*",
|
|
16
|
+
"*.dev.*"
|
|
17
|
+
];
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region ../quality/src/contrast.ts
|
|
20
|
+
function p(e, t) {
|
|
21
|
+
let n = g(e), r = g(t);
|
|
22
|
+
if (!n || !r) return NaN;
|
|
23
|
+
let i = v(n), a = v(r), o = Math.max(i, a), s = Math.min(i, a);
|
|
24
|
+
return (o + .05) / (s + .05);
|
|
25
|
+
}
|
|
26
|
+
var ne = /^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i, m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i, h = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
|
|
27
|
+
function g(e) {
|
|
28
|
+
if (typeof e != "string") return null;
|
|
29
|
+
let t = e.trim(), n = h.exec(t);
|
|
30
|
+
if (n) return n[4].toLowerCase() === "ff" ? {
|
|
31
|
+
r: parseInt(n[1], 16),
|
|
32
|
+
g: parseInt(n[2], 16),
|
|
33
|
+
b: parseInt(n[3], 16)
|
|
34
|
+
} : null;
|
|
35
|
+
let r = m.exec(t);
|
|
36
|
+
if (r) return {
|
|
37
|
+
r: parseInt(r[1], 16),
|
|
38
|
+
g: parseInt(r[2], 16),
|
|
39
|
+
b: parseInt(r[3], 16)
|
|
40
|
+
};
|
|
41
|
+
let i = ne.exec(t);
|
|
42
|
+
return i ? {
|
|
43
|
+
r: parseInt(i[1] + i[1], 16),
|
|
44
|
+
g: parseInt(i[2] + i[2], 16),
|
|
45
|
+
b: parseInt(i[3] + i[3], 16)
|
|
46
|
+
} : null;
|
|
47
|
+
}
|
|
48
|
+
function _(e) {
|
|
49
|
+
return g(e ?? "") !== null;
|
|
50
|
+
}
|
|
51
|
+
function v({ r: e, g: t, b: n }) {
|
|
52
|
+
let r = y(e / 255), i = y(t / 255), a = y(n / 255);
|
|
53
|
+
return .2126 * r + .7152 * i + .0722 * a;
|
|
54
|
+
}
|
|
55
|
+
function y(e) {
|
|
56
|
+
return e <= .03928 ? e / 12.92 : ((e + .055) / 1.055) ** 2.4;
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region ../quality/src/walk.ts
|
|
60
|
+
var b = "#ffffff", x = "#1a1a1a";
|
|
61
|
+
function S(e, t) {
|
|
62
|
+
let n = _(e.settings.backgroundColor) ? e.settings.backgroundColor.toLowerCase() : b, r = _(e.settings.textColor) ? e.settings.textColor.toLowerCase() : x, i = (e, n) => {
|
|
63
|
+
let r = e.styles?.backgroundColor, a = _(r) ? r.toLowerCase() : n.resolvedBackgroundColor;
|
|
64
|
+
t(e, a === n.resolvedBackgroundColor ? n : {
|
|
65
|
+
...n,
|
|
66
|
+
resolvedBackgroundColor: a
|
|
67
|
+
}), l(e) && e.children.forEach((t, r) => {
|
|
68
|
+
t.forEach((t) => i(t, {
|
|
69
|
+
parent: e,
|
|
70
|
+
section: e,
|
|
71
|
+
columnIndex: r,
|
|
72
|
+
depth: n.depth + 1,
|
|
73
|
+
resolvedBackgroundColor: a,
|
|
74
|
+
resolvedTextColor: n.resolvedTextColor
|
|
75
|
+
}));
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
for (let t of e.blocks) i(t, {
|
|
79
|
+
parent: null,
|
|
80
|
+
section: null,
|
|
81
|
+
columnIndex: null,
|
|
82
|
+
depth: 0,
|
|
83
|
+
resolvedBackgroundColor: n,
|
|
84
|
+
resolvedTextColor: r
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region ../quality/src/run-rules.ts
|
|
89
|
+
function C(e, t, n, r) {
|
|
90
|
+
let i = [];
|
|
91
|
+
function a(e, t, i) {
|
|
92
|
+
return {
|
|
93
|
+
blockId: i.blockId,
|
|
94
|
+
ruleId: e,
|
|
95
|
+
severity: t,
|
|
96
|
+
message: r(n.locale, e, i.params),
|
|
97
|
+
fix: i.fix
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
S(e, (e, r) => {
|
|
101
|
+
for (let o of t) {
|
|
102
|
+
let t = n.severity(o.meta.id);
|
|
103
|
+
if (t === "off" || !o.block) continue;
|
|
104
|
+
let s = o.block(e, r, n);
|
|
105
|
+
s !== null && i.push(a(o.meta.id, t, s));
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
for (let r of t) {
|
|
109
|
+
let t = n.severity(r.meta.id);
|
|
110
|
+
if (t === "off" || !r.template) continue;
|
|
111
|
+
let o = r.template(e, n);
|
|
112
|
+
for (let e of o) i.push(a(r.meta.id, t, e));
|
|
113
|
+
}
|
|
114
|
+
return i;
|
|
115
|
+
}
|
|
116
|
+
function w(e) {
|
|
117
|
+
let t = e.overrides ?? {}, n = {
|
|
118
|
+
...f,
|
|
119
|
+
...e.thresholds ?? {}
|
|
120
|
+
}, r = { nonProductionHosts: e.nonProductionHosts ?? te }, i = e.locale ?? "en", a = e.rules;
|
|
121
|
+
return {
|
|
122
|
+
locale: i,
|
|
123
|
+
rules: t,
|
|
124
|
+
thresholds: n,
|
|
125
|
+
links: r,
|
|
126
|
+
severity: (e) => {
|
|
127
|
+
let n = t[e];
|
|
128
|
+
return n === void 0 ? a.find((t) => t.meta.id === e)?.meta.severity ?? "warning" : n;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function re(e, t, n) {
|
|
133
|
+
return w({
|
|
134
|
+
locale: e,
|
|
135
|
+
rules: n,
|
|
136
|
+
overrides: t.rules,
|
|
137
|
+
thresholds: t.thresholds,
|
|
138
|
+
nonProductionHosts: void 0
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function ie(e, t, n) {
|
|
142
|
+
return w({
|
|
143
|
+
locale: e,
|
|
144
|
+
rules: n,
|
|
145
|
+
overrides: t.rules,
|
|
146
|
+
thresholds: void 0,
|
|
147
|
+
nonProductionHosts: void 0
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function ae(e, t, n) {
|
|
151
|
+
return w({
|
|
152
|
+
locale: e,
|
|
153
|
+
rules: n,
|
|
154
|
+
overrides: t.rules,
|
|
155
|
+
thresholds: void 0,
|
|
156
|
+
nonProductionHosts: t.nonProductionHosts
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region ../quality/src/accessibility/messages/de.ts
|
|
161
|
+
var oe = /* @__PURE__ */ e({ default: () => se }), se = {
|
|
162
|
+
"a11y.img-missing-alt": "Bild ohne Alt-Text. Füge eine kurze Beschreibung hinzu oder markiere das Bild als dekorativ.",
|
|
163
|
+
"a11y.img-alt-is-filename": "Alt-Text sieht wie ein Dateiname aus (\"{alt}\"). Beschreibe stattdessen kurz, was das Bild zeigt.",
|
|
164
|
+
"a11y.img-alt-too-long": "Alt-Text ist {length} Zeichen lang; bleibe unter {max}.",
|
|
165
|
+
"a11y.img-decorative-needs-empty-alt": "Dekoratives Bild hat Alt-Text. Entferne den Alt-Text oder hebe die Markierung als dekorativ auf.",
|
|
166
|
+
"a11y.img-linked-no-context": "Verlinktes Bild beschreibt nur das Motiv, nicht das Linkziel. Nenne das Ziel (z. B. „Frühlingssale ansehen“).",
|
|
167
|
+
"a11y.heading-empty": "Überschrift ist leer. Füge Text hinzu oder entferne den Block.",
|
|
168
|
+
"a11y.heading-skip-level": "Überschrift springt von H{from} auf H{to}. Eine Ebene pro Schritt.",
|
|
169
|
+
"a11y.heading-multiple-h1": "E-Mail enthält mehr als eine H1. Verwende H1 nur einmal für die Hauptüberschrift.",
|
|
170
|
+
"a11y.link-empty": "Ein Link in diesem Block hat keinen Text und kein beschriebenes Bild.",
|
|
171
|
+
"a11y.link-vague-text": "Link-Text „{text}“ ist unspezifisch. Beschreibe stattdessen das Ziel.",
|
|
172
|
+
"a11y.link-href-empty": "Ein Link in diesem Block hat ein leeres oder „#“-href.",
|
|
173
|
+
"a11y.link-target-blank-no-rel": "Link öffnet in neuem Tab, aber rel=\"noopener\" fehlt – ergänze es, damit das Ziel nicht auf window.opener zugreifen kann.",
|
|
174
|
+
"a11y.link-nested-anchor": "Ein Link liegt innerhalb eines anderen Links. Verschachtelte Anker sind ungültiges HTML und werden von E-Mail-Clients unterschiedlich gerendert – flache einen einzigen Anker daraus.",
|
|
175
|
+
"a11y.text-all-caps": "Längere Texte in Großbuchstaben sind schwerer lesbar. Verwende Groß- und Kleinschreibung.",
|
|
176
|
+
"a11y.text-low-contrast": "Überschriftskontrast beträgt {ratio}:1; WCAG AA verlangt mindestens {required}:1.",
|
|
177
|
+
"a11y.text-too-small": "Text ist {size}px; mindestens {min}px verwenden.",
|
|
178
|
+
"a11y.button-vague-label": "Button-Beschriftung „{text}“ ist unspezifisch. Beschreibe die Aktion.",
|
|
179
|
+
"a11y.button-touch-target": "Button ist etwa {height}px hoch; mindestens {min}px verwenden, um Fehltipper auf Mobilgeräten zu vermeiden.",
|
|
180
|
+
"a11y.button-low-contrast": "Buttontextkontrast beträgt {ratio}:1; WCAG AA verlangt mindestens {required}:1.",
|
|
181
|
+
"a11y.missing-preheader": "Kein Preheader-Text gesetzt. Postfächer zeigen sonst Bruchstücke des ersten Blocks an."
|
|
182
|
+
}, ce = /* @__PURE__ */ e({ default: () => T }), T = {
|
|
183
|
+
"a11y.img-missing-alt": "Image is missing alt text. Add a short description, or mark the image as decorative.",
|
|
184
|
+
"a11y.img-alt-is-filename": "Alt text looks like a filename (\"{alt}\"). Replace with a short description of what the image conveys.",
|
|
185
|
+
"a11y.img-alt-too-long": "Alt text is {length} characters; aim for under {max}.",
|
|
186
|
+
"a11y.img-decorative-needs-empty-alt": "Decorative image has alt text. Either clear the alt text or unmark the image as decorative.",
|
|
187
|
+
"a11y.img-linked-no-context": "Linked image alt describes the image but not the link destination. Include where the link goes (e.g. 'Buy spring sale').",
|
|
188
|
+
"a11y.heading-empty": "Heading is empty. Add text or remove the block.",
|
|
189
|
+
"a11y.heading-skip-level": "Heading jumps from H{from} to H{to}. Step one level at a time.",
|
|
190
|
+
"a11y.heading-multiple-h1": "Email has more than one H1. Use H1 once for the main heading.",
|
|
191
|
+
"a11y.link-empty": "A link in this block has no text and no described image.",
|
|
192
|
+
"a11y.link-vague-text": "Link text \"{text}\" is vague. Describe the destination instead.",
|
|
193
|
+
"a11y.link-href-empty": "A link in this block has an empty or '#' href.",
|
|
194
|
+
"a11y.link-target-blank-no-rel": "Link opens in a new tab but is missing rel=\"noopener\" — add it to prevent the destination from accessing window.opener.",
|
|
195
|
+
"a11y.link-nested-anchor": "A link is nested inside another link. Nested anchors are invalid HTML and clients render them inconsistently — flatten to a single anchor.",
|
|
196
|
+
"a11y.text-all-caps": "Long all-caps text is harder to read for everyone. Use sentence case.",
|
|
197
|
+
"a11y.text-low-contrast": "Heading contrast is {ratio}:1; WCAG AA requires at least {required}:1.",
|
|
198
|
+
"a11y.text-too-small": "Text is {size}px; aim for at least {min}px.",
|
|
199
|
+
"a11y.button-vague-label": "Button label \"{text}\" is vague. Describe the action.",
|
|
200
|
+
"a11y.button-touch-target": "Button is roughly {height}px tall; aim for at least {min}px to avoid mis-taps on mobile.",
|
|
201
|
+
"a11y.button-low-contrast": "Button text contrast is {ratio}:1; WCAG AA requires at least {required}:1.",
|
|
202
|
+
"a11y.missing-preheader": "No preheader text set. Inboxes will fall back to fragments of the first block."
|
|
203
|
+
}, E = /* #__PURE__ */ Object.assign({
|
|
204
|
+
"./de.ts": oe,
|
|
205
|
+
"./en.ts": ce
|
|
206
|
+
}), D = {};
|
|
207
|
+
for (let e in E) {
|
|
208
|
+
let t = /\.\/([^/]+)\.ts$/.exec(e);
|
|
209
|
+
if (!t) continue;
|
|
210
|
+
let n = t[1];
|
|
211
|
+
n !== "index" && (D[n] = E[e].default);
|
|
212
|
+
}
|
|
213
|
+
function le(e) {
|
|
214
|
+
return D[e.split("-")[0]?.toLowerCase() ?? "en"] ?? D.en ?? T;
|
|
215
|
+
}
|
|
216
|
+
function ue(e, t, n) {
|
|
217
|
+
let r = le(e)[t] ?? T[t];
|
|
218
|
+
return n ? r.replace(/\{(\w+)\}/g, (e, t) => {
|
|
219
|
+
let r = n[t];
|
|
220
|
+
return r === void 0 ? `{${t}}` : String(r);
|
|
221
|
+
}) : r;
|
|
222
|
+
}
|
|
223
|
+
var de = {
|
|
224
|
+
meta: {
|
|
225
|
+
id: "a11y.img-missing-alt",
|
|
226
|
+
severity: "error"
|
|
227
|
+
},
|
|
228
|
+
block(e) {
|
|
229
|
+
return !c(e) || e.decorative === !0 || (e.alt?.trim() ?? "") !== "" || (e.src ?? "").trim() === "" ? null : { blockId: e.id };
|
|
230
|
+
}
|
|
231
|
+
}, fe = {
|
|
232
|
+
id: "a11y.img-alt-is-filename",
|
|
233
|
+
severity: "warning"
|
|
234
|
+
}, pe = [
|
|
235
|
+
/\.(jpe?g|png|gif|webp|svg)$/i,
|
|
236
|
+
/^IMG[_-]?\d+/i,
|
|
237
|
+
/^Untitled/i,
|
|
238
|
+
/^Screen[\s_-]?Shot/i,
|
|
239
|
+
/^DSC[_-]?\d+/i
|
|
240
|
+
], me = {
|
|
241
|
+
meta: fe,
|
|
242
|
+
block(e) {
|
|
243
|
+
if (!c(e) || e.decorative === !0) return null;
|
|
244
|
+
let t = e.alt?.trim() ?? "";
|
|
245
|
+
return t === "" || !pe.some((e) => e.test(t)) ? null : {
|
|
246
|
+
blockId: e.id,
|
|
247
|
+
params: { alt: t }
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}, he = {
|
|
251
|
+
meta: {
|
|
252
|
+
id: "a11y.img-alt-too-long",
|
|
253
|
+
severity: "warning"
|
|
254
|
+
},
|
|
255
|
+
block(e, t, n) {
|
|
256
|
+
if (!c(e) || e.decorative === !0) return null;
|
|
257
|
+
let r = e.alt ?? "";
|
|
258
|
+
return r.length <= n.thresholds.altMaxLength ? null : {
|
|
259
|
+
blockId: e.id,
|
|
260
|
+
params: {
|
|
261
|
+
length: r.length,
|
|
262
|
+
max: n.thresholds.altMaxLength
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}, ge = {
|
|
267
|
+
meta: {
|
|
268
|
+
id: "a11y.img-decorative-needs-empty-alt",
|
|
269
|
+
severity: "info"
|
|
270
|
+
},
|
|
271
|
+
block(e) {
|
|
272
|
+
return !c(e) || e.decorative !== !0 || (e.alt ?? "").trim() === "" ? null : {
|
|
273
|
+
blockId: e.id,
|
|
274
|
+
fix: {
|
|
275
|
+
description: "Clear alt text",
|
|
276
|
+
apply: (t) => t.updateBlock(e.id, { alt: "" })
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}, _e = /* @__PURE__ */ e({ default: () => ve }), ve = {
|
|
281
|
+
vagueLinkText: [
|
|
282
|
+
"hier klicken",
|
|
283
|
+
"hier",
|
|
284
|
+
"mehr lesen",
|
|
285
|
+
"mehr",
|
|
286
|
+
"weiter",
|
|
287
|
+
"weiterlesen",
|
|
288
|
+
"siehe mehr",
|
|
289
|
+
"dies",
|
|
290
|
+
"dieser link",
|
|
291
|
+
"link",
|
|
292
|
+
"klick"
|
|
293
|
+
],
|
|
294
|
+
vagueButtonLabels: [
|
|
295
|
+
"hier klicken",
|
|
296
|
+
"klicken",
|
|
297
|
+
"senden",
|
|
298
|
+
"los",
|
|
299
|
+
"ok",
|
|
300
|
+
"okay",
|
|
301
|
+
"ja",
|
|
302
|
+
"nein"
|
|
303
|
+
],
|
|
304
|
+
linkedImageActionHints: [
|
|
305
|
+
"kaufen",
|
|
306
|
+
"shoppen",
|
|
307
|
+
"ansehen",
|
|
308
|
+
"lesen",
|
|
309
|
+
"lernen",
|
|
310
|
+
"öffnen",
|
|
311
|
+
"los",
|
|
312
|
+
"sehen",
|
|
313
|
+
"entdecken",
|
|
314
|
+
"erkunden",
|
|
315
|
+
"stöbern",
|
|
316
|
+
"herunterladen",
|
|
317
|
+
"holen",
|
|
318
|
+
"abholen",
|
|
319
|
+
"einlösen",
|
|
320
|
+
"anschauen",
|
|
321
|
+
"jetzt"
|
|
322
|
+
]
|
|
323
|
+
}, ye = /* @__PURE__ */ e({ default: () => O }), O = {
|
|
324
|
+
vagueLinkText: [
|
|
325
|
+
"click here",
|
|
326
|
+
"here",
|
|
327
|
+
"read more",
|
|
328
|
+
"more",
|
|
329
|
+
"learn more",
|
|
330
|
+
"see more",
|
|
331
|
+
"this",
|
|
332
|
+
"this link",
|
|
333
|
+
"link",
|
|
334
|
+
"click"
|
|
335
|
+
],
|
|
336
|
+
vagueButtonLabels: [
|
|
337
|
+
"click here",
|
|
338
|
+
"click",
|
|
339
|
+
"submit",
|
|
340
|
+
"go",
|
|
341
|
+
"ok",
|
|
342
|
+
"okay",
|
|
343
|
+
"yes",
|
|
344
|
+
"no"
|
|
345
|
+
],
|
|
346
|
+
linkedImageActionHints: [
|
|
347
|
+
"buy",
|
|
348
|
+
"shop",
|
|
349
|
+
"view",
|
|
350
|
+
"read",
|
|
351
|
+
"learn",
|
|
352
|
+
"open",
|
|
353
|
+
"go",
|
|
354
|
+
"see",
|
|
355
|
+
"explore",
|
|
356
|
+
"discover",
|
|
357
|
+
"browse",
|
|
358
|
+
"download",
|
|
359
|
+
"get",
|
|
360
|
+
"claim",
|
|
361
|
+
"redeem",
|
|
362
|
+
"watch"
|
|
363
|
+
]
|
|
364
|
+
}, k = /* #__PURE__ */ Object.assign({
|
|
365
|
+
"./de.ts": _e,
|
|
366
|
+
"./en.ts": ye
|
|
367
|
+
}), A = {};
|
|
368
|
+
for (let e in k) {
|
|
369
|
+
let t = /\.\/([^/]+)\.ts$/.exec(e);
|
|
370
|
+
if (!t) continue;
|
|
371
|
+
let n = t[1];
|
|
372
|
+
n !== "index" && (A[n] = k[e].default);
|
|
373
|
+
}
|
|
374
|
+
function j(e) {
|
|
375
|
+
return N;
|
|
376
|
+
}
|
|
377
|
+
function M(e) {
|
|
378
|
+
let t = /* @__PURE__ */ new Set();
|
|
379
|
+
for (let n of Object.values(A)) for (let r of e(n)) t.add(r);
|
|
380
|
+
return Array.from(t);
|
|
381
|
+
}
|
|
382
|
+
var N = {
|
|
383
|
+
vagueLinkText: M((e) => e.vagueLinkText),
|
|
384
|
+
vagueButtonLabels: M((e) => e.vagueButtonLabels),
|
|
385
|
+
linkedImageActionHints: M((e) => e.linkedImageActionHints)
|
|
386
|
+
};
|
|
387
|
+
function P(e) {
|
|
388
|
+
return e.toLowerCase().replace(/\s+/g, " ").replace(/^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu, "").trim();
|
|
389
|
+
}
|
|
390
|
+
var be = {
|
|
391
|
+
meta: {
|
|
392
|
+
id: "a11y.img-linked-no-context",
|
|
393
|
+
severity: "warning"
|
|
394
|
+
},
|
|
395
|
+
block(e, t, n) {
|
|
396
|
+
if (!c(e) || e.decorative === !0 || !e.linkUrl || e.linkUrl.trim() === "") return null;
|
|
397
|
+
let r = (e.alt ?? "").trim();
|
|
398
|
+
if (r === "") return null;
|
|
399
|
+
let i = r.toLocaleLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean), a = j(n.locale).linkedImageActionHints;
|
|
400
|
+
return i.some((e) => a.includes(e)) ? null : { blockId: e.id };
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
//#endregion
|
|
404
|
+
//#region ../quality/src/html-utils.ts
|
|
405
|
+
function F(e) {
|
|
406
|
+
let t = [], n = null, r = "", i = () => {
|
|
407
|
+
n !== null && (n.text = r.trim(), t.push(n), n = null, r = "");
|
|
408
|
+
}, a = new d({
|
|
409
|
+
onopentag(e, t) {
|
|
410
|
+
if (e === "a") {
|
|
411
|
+
i(), n = {
|
|
412
|
+
href: t.href ?? "",
|
|
413
|
+
text: "",
|
|
414
|
+
target: t.target ?? null,
|
|
415
|
+
rel: t.rel ?? null,
|
|
416
|
+
hasImageWithAlt: !1
|
|
417
|
+
};
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
e === "img" && n !== null && (t.alt ?? "").trim() !== "" && (n.hasImageWithAlt = !0);
|
|
421
|
+
},
|
|
422
|
+
ontext(e) {
|
|
423
|
+
n !== null && (r += e);
|
|
424
|
+
},
|
|
425
|
+
onclosetag(e) {
|
|
426
|
+
e === "a" && i();
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
return a.write(e), a.end(), i(), t;
|
|
430
|
+
}
|
|
431
|
+
function xe(e) {
|
|
432
|
+
let t = Se(e).matchAll(/<\/?a\b[^<>]*>/gi), n = 0;
|
|
433
|
+
for (let e of t) {
|
|
434
|
+
if (e[0].startsWith("</")) {
|
|
435
|
+
n > 0 && n--;
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
if (n > 0) return !0;
|
|
439
|
+
n++;
|
|
440
|
+
}
|
|
441
|
+
return !1;
|
|
442
|
+
}
|
|
443
|
+
function Se(e) {
|
|
444
|
+
let t = "", n = 0;
|
|
445
|
+
for (; n < e.length;) {
|
|
446
|
+
let r = e.indexOf("<!--", n);
|
|
447
|
+
if (r === -1) {
|
|
448
|
+
t += e.substring(n);
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
t += e.substring(n, r);
|
|
452
|
+
let i = e.indexOf("-->", r + 4);
|
|
453
|
+
if (i === -1) break;
|
|
454
|
+
n = i + 3;
|
|
455
|
+
}
|
|
456
|
+
return t;
|
|
457
|
+
}
|
|
458
|
+
function I(e) {
|
|
459
|
+
let t = "", n = new d({ ontext(e) {
|
|
460
|
+
t += e;
|
|
461
|
+
} });
|
|
462
|
+
return n.write(e), n.end(), t.trim();
|
|
463
|
+
}
|
|
464
|
+
var Ce = {
|
|
465
|
+
meta: {
|
|
466
|
+
id: "a11y.heading-empty",
|
|
467
|
+
severity: "error"
|
|
468
|
+
},
|
|
469
|
+
block(e) {
|
|
470
|
+
return !n(e) || I(e.content ?? "") !== "" ? null : { blockId: e.id };
|
|
471
|
+
}
|
|
472
|
+
}, we = {
|
|
473
|
+
id: "a11y.heading-skip-level",
|
|
474
|
+
severity: "error"
|
|
475
|
+
};
|
|
476
|
+
function L(e, t) {
|
|
477
|
+
for (let r of e) {
|
|
478
|
+
if (n(r)) {
|
|
479
|
+
t.push(r);
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
if (l(r)) for (let e of r.children) L(e, t);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
var Te = {
|
|
486
|
+
meta: we,
|
|
487
|
+
template(e) {
|
|
488
|
+
let t = [];
|
|
489
|
+
L(e.blocks, t);
|
|
490
|
+
let n = [], r = 0;
|
|
491
|
+
for (let e of t) r !== 0 && e.level > r + 1 && n.push({
|
|
492
|
+
blockId: e.id,
|
|
493
|
+
params: {
|
|
494
|
+
from: r,
|
|
495
|
+
to: e.level
|
|
496
|
+
}
|
|
497
|
+
}), r = e.level;
|
|
498
|
+
return n;
|
|
499
|
+
}
|
|
500
|
+
}, Ee = {
|
|
501
|
+
id: "a11y.heading-multiple-h1",
|
|
502
|
+
severity: "warning"
|
|
503
|
+
};
|
|
504
|
+
function R(e, t) {
|
|
505
|
+
for (let r of e) {
|
|
506
|
+
if (n(r)) {
|
|
507
|
+
t.push(r);
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
if (l(r)) for (let e of r.children) R(e, t);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
var De = {
|
|
514
|
+
meta: Ee,
|
|
515
|
+
template(e) {
|
|
516
|
+
let t = [];
|
|
517
|
+
R(e.blocks, t);
|
|
518
|
+
let n = t.filter((e) => e.level === 1);
|
|
519
|
+
return n.length <= 1 ? [] : n.slice(1).map((e) => ({ blockId: e.id }));
|
|
520
|
+
}
|
|
521
|
+
}, Oe = {
|
|
522
|
+
id: "a11y.link-empty",
|
|
523
|
+
severity: "error"
|
|
524
|
+
};
|
|
525
|
+
function ke(e) {
|
|
526
|
+
return t(e) || n(e) ? e.content : null;
|
|
527
|
+
}
|
|
528
|
+
var Ae = {
|
|
529
|
+
meta: Oe,
|
|
530
|
+
block(e) {
|
|
531
|
+
let t = ke(e);
|
|
532
|
+
return t === null || !F(t).find((e) => e.text === "" && !e.hasImageWithAlt) ? null : { blockId: e.id };
|
|
533
|
+
}
|
|
534
|
+
}, je = {
|
|
535
|
+
id: "a11y.link-vague-text",
|
|
536
|
+
severity: "warning"
|
|
537
|
+
};
|
|
538
|
+
function Me(e) {
|
|
539
|
+
return t(e) || n(e) ? e.content : null;
|
|
540
|
+
}
|
|
541
|
+
var Ne = {
|
|
542
|
+
meta: je,
|
|
543
|
+
block(e, t, n) {
|
|
544
|
+
let r = Me(e);
|
|
545
|
+
if (r === null) return null;
|
|
546
|
+
let i = j(n.locale).vagueLinkText, a = F(r).find((e) => {
|
|
547
|
+
let t = P(e.text);
|
|
548
|
+
return t !== "" && i.includes(t);
|
|
549
|
+
});
|
|
550
|
+
return a ? {
|
|
551
|
+
blockId: e.id,
|
|
552
|
+
params: { text: a.text }
|
|
553
|
+
} : null;
|
|
554
|
+
}
|
|
555
|
+
}, Pe = {
|
|
556
|
+
id: "a11y.link-href-empty",
|
|
557
|
+
severity: "error"
|
|
558
|
+
};
|
|
559
|
+
function Fe(e) {
|
|
560
|
+
return t(e) || n(e) ? e.content : null;
|
|
561
|
+
}
|
|
562
|
+
var Ie = {
|
|
563
|
+
meta: Pe,
|
|
564
|
+
block(e) {
|
|
565
|
+
let t = Fe(e);
|
|
566
|
+
return t === null || !F(t).find((e) => {
|
|
567
|
+
let t = e.href.trim();
|
|
568
|
+
return t === "" || t === "#";
|
|
569
|
+
}) ? null : { blockId: e.id };
|
|
570
|
+
}
|
|
571
|
+
}, Le = {
|
|
572
|
+
id: "a11y.link-target-blank-no-rel",
|
|
573
|
+
severity: "warning"
|
|
574
|
+
};
|
|
575
|
+
function Re(e) {
|
|
576
|
+
return t(e) || n(e) ? e.content : null;
|
|
577
|
+
}
|
|
578
|
+
function ze(e) {
|
|
579
|
+
if (e === null) return !1;
|
|
580
|
+
let t = e.toLowerCase().split(/\s+/);
|
|
581
|
+
return t.includes("noopener") || t.includes("noreferrer");
|
|
582
|
+
}
|
|
583
|
+
var Be = {
|
|
584
|
+
meta: Le,
|
|
585
|
+
block(e) {
|
|
586
|
+
let r = Re(e);
|
|
587
|
+
return r === null || !F(r).find((e) => e.target === "_blank" && !ze(e.rel)) ? null : {
|
|
588
|
+
blockId: e.id,
|
|
589
|
+
fix: {
|
|
590
|
+
description: "Add rel=\"noopener\"",
|
|
591
|
+
apply: (r) => {
|
|
592
|
+
if (!t(e) && !n(e)) return;
|
|
593
|
+
let i = Ue(e.content ?? "");
|
|
594
|
+
r.updateBlock(e.id, { content: i });
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
}, z = /([^\s"'>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
600
|
+
function Ve(e) {
|
|
601
|
+
let t = [], n = new RegExp(z.source, z.flags), r;
|
|
602
|
+
for (; (r = n.exec(e)) !== null;) t.push({
|
|
603
|
+
raw: r[0],
|
|
604
|
+
name: r[1],
|
|
605
|
+
value: r[2] ?? r[3] ?? r[4] ?? null,
|
|
606
|
+
start: r.index
|
|
607
|
+
});
|
|
608
|
+
return t;
|
|
609
|
+
}
|
|
610
|
+
function He(e) {
|
|
611
|
+
return e.some((e) => e.name.toLowerCase() === "target" && e.value !== null && e.value.toLowerCase() === "_blank");
|
|
612
|
+
}
|
|
613
|
+
function Ue(e) {
|
|
614
|
+
return e.replace(/<a\b([^>]*)>/gi, (e, t) => {
|
|
615
|
+
let n = Ve(t);
|
|
616
|
+
if (!He(n)) return e;
|
|
617
|
+
let r = n.find((e) => e.name.toLowerCase() === "rel");
|
|
618
|
+
if (r) {
|
|
619
|
+
let n = (r.value ?? "").toLowerCase().split(/\s+/);
|
|
620
|
+
if (n.includes("noopener") || n.includes("noreferrer")) return e;
|
|
621
|
+
let i = `${r.value ?? ""} noopener`.trim();
|
|
622
|
+
return `<a${t.slice(0, r.start)}rel="${i}"${t.slice(r.start + r.raw.length)}>`;
|
|
623
|
+
}
|
|
624
|
+
return `<a${t} rel="noopener">`;
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
//#endregion
|
|
628
|
+
//#region ../quality/src/accessibility/rules/link-nested-anchor.ts
|
|
629
|
+
var We = {
|
|
630
|
+
id: "a11y.link-nested-anchor",
|
|
631
|
+
severity: "error"
|
|
632
|
+
};
|
|
633
|
+
function Ge(e) {
|
|
634
|
+
return t(e) || n(e) ? e.content : null;
|
|
635
|
+
}
|
|
636
|
+
var Ke = {
|
|
637
|
+
meta: We,
|
|
638
|
+
block(e) {
|
|
639
|
+
let t = Ge(e);
|
|
640
|
+
return t === null || !xe(t) ? null : { blockId: e.id };
|
|
641
|
+
}
|
|
642
|
+
}, qe = {
|
|
643
|
+
meta: {
|
|
644
|
+
id: "a11y.text-all-caps",
|
|
645
|
+
severity: "warning"
|
|
646
|
+
},
|
|
647
|
+
block(e, r, i) {
|
|
648
|
+
if (!t(e) && !n(e)) return null;
|
|
649
|
+
let a = I(e.content ?? "").replace(/[^\p{L}]/gu, "");
|
|
650
|
+
return a.length < i.thresholds.allCapsMinLength || a !== a.toLocaleUpperCase() ? null : { blockId: e.id };
|
|
651
|
+
}
|
|
652
|
+
}, Je = {
|
|
653
|
+
meta: {
|
|
654
|
+
id: "a11y.text-low-contrast",
|
|
655
|
+
severity: "error"
|
|
656
|
+
},
|
|
657
|
+
block(e, t) {
|
|
658
|
+
if (!n(e)) return null;
|
|
659
|
+
let r = e.color ?? t.resolvedTextColor;
|
|
660
|
+
if (!_(r) || !_(t.resolvedBackgroundColor)) return null;
|
|
661
|
+
let a = i[e.level] >= 24 ? 3 : 4.5, o = p(r, t.resolvedBackgroundColor);
|
|
662
|
+
return Number.isNaN(o) || o >= a ? null : {
|
|
663
|
+
blockId: e.id,
|
|
664
|
+
params: {
|
|
665
|
+
ratio: o.toFixed(2),
|
|
666
|
+
required: a
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
}, Ye = {
|
|
671
|
+
id: "a11y.text-too-small",
|
|
672
|
+
severity: "warning"
|
|
673
|
+
};
|
|
674
|
+
function Xe(e) {
|
|
675
|
+
return u(e) || ee(e) ? e.fontSize : null;
|
|
676
|
+
}
|
|
677
|
+
//#endregion
|
|
678
|
+
//#region ../quality/src/accessibility/index.ts
|
|
679
|
+
var B = [
|
|
680
|
+
de,
|
|
681
|
+
me,
|
|
682
|
+
he,
|
|
683
|
+
ge,
|
|
684
|
+
be,
|
|
685
|
+
Ce,
|
|
686
|
+
Te,
|
|
687
|
+
De,
|
|
688
|
+
Ae,
|
|
689
|
+
Ne,
|
|
690
|
+
Ie,
|
|
691
|
+
Be,
|
|
692
|
+
Ke,
|
|
693
|
+
qe,
|
|
694
|
+
Je,
|
|
695
|
+
{
|
|
696
|
+
meta: Ye,
|
|
697
|
+
block(e, t, n) {
|
|
698
|
+
let r = Xe(e);
|
|
699
|
+
return r === null || r >= n.thresholds.minFontSize ? null : {
|
|
700
|
+
blockId: e.id,
|
|
701
|
+
params: {
|
|
702
|
+
size: r,
|
|
703
|
+
min: n.thresholds.minFontSize
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
meta: {
|
|
710
|
+
id: "a11y.button-vague-label",
|
|
711
|
+
severity: "warning"
|
|
712
|
+
},
|
|
713
|
+
block(e, t, n) {
|
|
714
|
+
if (!s(e)) return null;
|
|
715
|
+
let r = P(e.text ?? "");
|
|
716
|
+
return r === "" || !j(n.locale).vagueButtonLabels.includes(r) ? null : {
|
|
717
|
+
blockId: e.id,
|
|
718
|
+
params: { text: e.text }
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
meta: {
|
|
724
|
+
id: "a11y.button-touch-target",
|
|
725
|
+
severity: "warning"
|
|
726
|
+
},
|
|
727
|
+
block(e, t, n) {
|
|
728
|
+
if (!s(e)) return null;
|
|
729
|
+
let r = e.buttonPadding;
|
|
730
|
+
if (!r) return null;
|
|
731
|
+
let i = e.fontSize * 1.4 + r.top + r.bottom;
|
|
732
|
+
return i >= n.thresholds.minTouchTargetPx ? null : {
|
|
733
|
+
blockId: e.id,
|
|
734
|
+
params: {
|
|
735
|
+
height: Math.round(i),
|
|
736
|
+
min: n.thresholds.minTouchTargetPx
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
meta: {
|
|
743
|
+
id: "a11y.button-low-contrast",
|
|
744
|
+
severity: "error"
|
|
745
|
+
},
|
|
746
|
+
block(e) {
|
|
747
|
+
if (!s(e)) return null;
|
|
748
|
+
let t = p(e.textColor, e.backgroundColor);
|
|
749
|
+
if (Number.isNaN(t)) return null;
|
|
750
|
+
let n = e.fontSize >= 24 ? 3 : 4.5;
|
|
751
|
+
return t >= n ? null : {
|
|
752
|
+
blockId: e.id,
|
|
753
|
+
params: {
|
|
754
|
+
ratio: t.toFixed(2),
|
|
755
|
+
required: n
|
|
756
|
+
}
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
meta: {
|
|
762
|
+
id: "a11y.missing-preheader",
|
|
763
|
+
severity: "info"
|
|
764
|
+
},
|
|
765
|
+
template(e) {
|
|
766
|
+
return (e.settings.preheaderText?.trim() ?? "") === "" ? [{ blockId: null }] : [];
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
];
|
|
770
|
+
function Ze(e, t = {}) {
|
|
771
|
+
return t.disabled === !0 || t.accessibility === !1 ? [] : C(e, B, re(t.locale, t.accessibility ?? {}, B), (e, t, n) => ue(e, t, n));
|
|
772
|
+
}
|
|
773
|
+
//#endregion
|
|
774
|
+
//#region ../quality/src/structure/messages/de.ts
|
|
775
|
+
var Qe = /* @__PURE__ */ e({ default: () => $e }), $e = {
|
|
776
|
+
"structure.duplicate-block-id": "Block-ID erscheint {count}-mal im Baum. Jeder Block muss eine eindeutige ID haben.",
|
|
777
|
+
"structure.section-column-mismatch": "Sektion verwendet Layout „{layout}\" (erwartet {expected} Spalten), hat aber {actual}. Deutet auf beschädigten Zustand hin.",
|
|
778
|
+
"structure.nested-section": "Sektion ist in einer anderen Sektion verschachtelt. Sektionen können nicht verschachtelt werden – der Renderer wird sich falsch verhalten.",
|
|
779
|
+
"structure.empty-section": "Sektion enthält keine Blöcke. Entferne sie oder füge Inhalt hinzu.",
|
|
780
|
+
"structure.empty-column": "Spalte {columnIndex} dieser Sektion ist leer. Füge Inhalt hinzu oder reduziere die Spaltenanzahl."
|
|
781
|
+
}, et = /* @__PURE__ */ e({ default: () => V }), V = {
|
|
782
|
+
"structure.duplicate-block-id": "Block id appears {count} times in the tree. Each block must have a unique id.",
|
|
783
|
+
"structure.section-column-mismatch": "Section uses layout \"{layout}\" (expects {expected} columns) but has {actual}. Indicates corrupted state.",
|
|
784
|
+
"structure.nested-section": "Section is nested inside another section. Sections cannot nest — the renderer will misbehave.",
|
|
785
|
+
"structure.empty-section": "Section has no blocks. Remove it or add content.",
|
|
786
|
+
"structure.empty-column": "Column {columnIndex} of this section is empty. Add content or reduce the column count."
|
|
787
|
+
}, H = /* #__PURE__ */ Object.assign({
|
|
788
|
+
"./de.ts": Qe,
|
|
789
|
+
"./en.ts": et
|
|
790
|
+
}), U = {};
|
|
791
|
+
for (let e in H) {
|
|
792
|
+
let t = /\.\/([^/]+)\.ts$/.exec(e);
|
|
793
|
+
if (!t) continue;
|
|
794
|
+
let n = t[1];
|
|
795
|
+
n !== "index" && (U[n] = H[e].default);
|
|
796
|
+
}
|
|
797
|
+
function tt(e) {
|
|
798
|
+
return U[e.split("-")[0]?.toLowerCase() ?? "en"] ?? U.en ?? V;
|
|
799
|
+
}
|
|
800
|
+
function nt(e, t, n) {
|
|
801
|
+
let r = tt(e)[t] ?? V[t];
|
|
802
|
+
return n ? r.replace(/\{(\w+)\}/g, (e, t) => {
|
|
803
|
+
let r = n[t];
|
|
804
|
+
return r === void 0 ? `{${t}}` : String(r);
|
|
805
|
+
}) : r;
|
|
806
|
+
}
|
|
807
|
+
//#endregion
|
|
808
|
+
//#region ../quality/src/structure/rules/duplicate-block-id.ts
|
|
809
|
+
var rt = {
|
|
810
|
+
id: "structure.duplicate-block-id",
|
|
811
|
+
severity: "error"
|
|
812
|
+
};
|
|
813
|
+
function W(e, t) {
|
|
814
|
+
for (let n of e) if (t.set(n.id, (t.get(n.id) ?? 0) + 1), l(n)) for (let e of n.children) W(e, t);
|
|
815
|
+
}
|
|
816
|
+
var it = {
|
|
817
|
+
meta: rt,
|
|
818
|
+
template(e) {
|
|
819
|
+
let t = /* @__PURE__ */ new Map();
|
|
820
|
+
W(e.blocks, t);
|
|
821
|
+
let n = [];
|
|
822
|
+
for (let [e, r] of t) r > 1 && n.push({
|
|
823
|
+
blockId: e,
|
|
824
|
+
params: { count: r }
|
|
825
|
+
});
|
|
826
|
+
return n;
|
|
827
|
+
}
|
|
828
|
+
}, at = {
|
|
829
|
+
id: "structure.empty-column",
|
|
830
|
+
severity: "warning"
|
|
831
|
+
};
|
|
832
|
+
function G(e, t) {
|
|
833
|
+
for (let n of e) {
|
|
834
|
+
if (!l(n)) continue;
|
|
835
|
+
let e = n;
|
|
836
|
+
e.children.length > 1 && e.children.forEach((n, r) => {
|
|
837
|
+
n.length === 0 && t.push({
|
|
838
|
+
blockId: e.id,
|
|
839
|
+
params: { columnIndex: r + 1 }
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
for (let n of e.children) G(n, t);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
var ot = {
|
|
846
|
+
meta: at,
|
|
847
|
+
template(e) {
|
|
848
|
+
let t = [];
|
|
849
|
+
return G(e.blocks, t), t;
|
|
850
|
+
}
|
|
851
|
+
}, st = {
|
|
852
|
+
id: "structure.empty-section",
|
|
853
|
+
severity: "warning"
|
|
854
|
+
};
|
|
855
|
+
function ct(e) {
|
|
856
|
+
return e.children.length === 0 || e.children.every((e) => e.length === 0);
|
|
857
|
+
}
|
|
858
|
+
var lt = {
|
|
859
|
+
meta: st,
|
|
860
|
+
block(e) {
|
|
861
|
+
if (!l(e)) return null;
|
|
862
|
+
let t = e;
|
|
863
|
+
return ct(t) ? {
|
|
864
|
+
blockId: t.id,
|
|
865
|
+
fix: {
|
|
866
|
+
description: "Remove the empty section",
|
|
867
|
+
apply: (e) => {
|
|
868
|
+
e.removeBlock(t.id);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
} : null;
|
|
872
|
+
}
|
|
873
|
+
}, ut = {
|
|
874
|
+
meta: {
|
|
875
|
+
id: "structure.nested-section",
|
|
876
|
+
severity: "error"
|
|
877
|
+
},
|
|
878
|
+
block(e, t) {
|
|
879
|
+
return !l(e) || t.section === null ? null : {
|
|
880
|
+
blockId: e.id,
|
|
881
|
+
params: { parentId: t.section.id }
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
}, dt = {
|
|
885
|
+
id: "structure.section-column-mismatch",
|
|
886
|
+
severity: "error"
|
|
887
|
+
};
|
|
888
|
+
function ft(e) {
|
|
889
|
+
return e === "1" ? 1 : e === "3" ? 3 : 2;
|
|
890
|
+
}
|
|
891
|
+
//#endregion
|
|
892
|
+
//#region ../quality/src/structure/index.ts
|
|
893
|
+
var K = [
|
|
894
|
+
it,
|
|
895
|
+
lt,
|
|
896
|
+
ot,
|
|
897
|
+
ut,
|
|
898
|
+
{
|
|
899
|
+
meta: dt,
|
|
900
|
+
block(e) {
|
|
901
|
+
if (!l(e)) return null;
|
|
902
|
+
let t = e, n = ft(t.columns), r = t.children.length;
|
|
903
|
+
return r === n ? null : {
|
|
904
|
+
blockId: t.id,
|
|
905
|
+
params: {
|
|
906
|
+
layout: t.columns,
|
|
907
|
+
expected: n,
|
|
908
|
+
actual: r
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
];
|
|
914
|
+
function pt(e, t = {}) {
|
|
915
|
+
return t.disabled === !0 || t.structure === !1 ? [] : C(e, K, ie(t.locale, t.structure ?? {}, K), (e, t, n) => nt(e, t, n));
|
|
916
|
+
}
|
|
917
|
+
//#endregion
|
|
918
|
+
//#region ../quality/src/links/messages/de.ts
|
|
919
|
+
var mt = /* @__PURE__ */ e({ default: () => ht }), ht = {
|
|
920
|
+
"link.javascript-protocol": "Die URL verwendet das Protokoll „{protocol}:\", das beliebigen Skriptcode ausführen kann und aus Sicherheitsgründen beim Rendern entfernt wird. Ersetze sie durch eine echte URL oder entferne sie.",
|
|
921
|
+
"link.unsupported-protocol": "Die URL verwendet das Protokoll „{protocol}\", das von den meisten E-Mail-Clients nicht unterstützt wird. Verwende http, https, mailto, tel oder sms.",
|
|
922
|
+
"link.malformed-mailto": "Der mailto:-Link ist fehlerhaft. Erwartet wird eine einzelne Empfängeradresse vor einer eventuellen Querystring (z. B. mailto:hallo@example.com).",
|
|
923
|
+
"link.malformed-tel": "Der tel:-Link enthält Zeichen, die keine Ziffern, +, Leerzeichen, Bindestriche, Klammern oder Punkte sind.",
|
|
924
|
+
"link.localhost-or-staging": "Der URL-Host „{host}\" entspricht einem Nicht-Produktionsmuster. Ersetze ihn vor dem Versand durch die Produktions-URL."
|
|
925
|
+
}, gt = /* @__PURE__ */ e({ default: () => q }), q = {
|
|
926
|
+
"link.javascript-protocol": "URL uses the \"{protocol}:\" protocol, which can execute arbitrary script and is stripped at render time for safety. Replace it with a real link or remove the URL.",
|
|
927
|
+
"link.unsupported-protocol": "URL uses the \"{protocol}\" protocol, which most email clients do not support. Use http, https, mailto, tel, or sms.",
|
|
928
|
+
"link.malformed-mailto": "mailto: link is malformed. Expected a single recipient address before any query string (e.g. mailto:hello@example.com).",
|
|
929
|
+
"link.malformed-tel": "tel: link contains characters that are not digits, +, spaces, dashes, parentheses, or dots.",
|
|
930
|
+
"link.localhost-or-staging": "URL host \"{host}\" matches a non-production pattern. Replace with the production URL before sending."
|
|
931
|
+
}, J = /* #__PURE__ */ Object.assign({
|
|
932
|
+
"./de.ts": mt,
|
|
933
|
+
"./en.ts": gt
|
|
934
|
+
}), Y = {};
|
|
935
|
+
for (let e in J) {
|
|
936
|
+
let t = /\.\/([^/]+)\.ts$/.exec(e);
|
|
937
|
+
if (!t) continue;
|
|
938
|
+
let n = t[1];
|
|
939
|
+
n !== "index" && (Y[n] = J[e].default);
|
|
940
|
+
}
|
|
941
|
+
function _t(e) {
|
|
942
|
+
return Y[e.split("-")[0]?.toLowerCase() ?? "en"] ?? Y.en ?? q;
|
|
943
|
+
}
|
|
944
|
+
function vt(e, t, n) {
|
|
945
|
+
let r = _t(e)[t] ?? q[t];
|
|
946
|
+
return n ? r.replace(/\{(\w+)\}/g, (e, t) => {
|
|
947
|
+
let r = n[t];
|
|
948
|
+
return r === void 0 ? `{${t}}` : String(r);
|
|
949
|
+
}) : r;
|
|
950
|
+
}
|
|
951
|
+
//#endregion
|
|
952
|
+
//#region ../quality/src/url-walker.ts
|
|
953
|
+
function X(e) {
|
|
954
|
+
let i = [];
|
|
955
|
+
return S(e, (e) => {
|
|
956
|
+
if (n(e) || t(e) || o(e)) {
|
|
957
|
+
for (let t of F(e.content)) i.push({
|
|
958
|
+
url: t.href,
|
|
959
|
+
blockId: e.id,
|
|
960
|
+
source: "anchor",
|
|
961
|
+
label: t.text
|
|
962
|
+
});
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
if (s(e)) {
|
|
966
|
+
i.push({
|
|
967
|
+
url: e.url,
|
|
968
|
+
blockId: e.id,
|
|
969
|
+
source: "button",
|
|
970
|
+
label: e.text
|
|
971
|
+
});
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
if (c(e)) {
|
|
975
|
+
e.linkUrl && e.linkUrl !== "" && i.push({
|
|
976
|
+
url: e.linkUrl,
|
|
977
|
+
blockId: e.id,
|
|
978
|
+
source: "image-link",
|
|
979
|
+
label: e.alt || void 0
|
|
980
|
+
});
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
if (a(e)) {
|
|
984
|
+
i.push({
|
|
985
|
+
url: e.url,
|
|
986
|
+
blockId: e.id,
|
|
987
|
+
source: "video",
|
|
988
|
+
label: e.alt || void 0
|
|
989
|
+
});
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
if (u(e)) {
|
|
993
|
+
for (let t of e.items) i.push({
|
|
994
|
+
url: t.url,
|
|
995
|
+
blockId: e.id,
|
|
996
|
+
source: "menu-item",
|
|
997
|
+
label: t.text
|
|
998
|
+
});
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
if (r(e)) {
|
|
1002
|
+
for (let t of e.icons) i.push({
|
|
1003
|
+
url: t.url,
|
|
1004
|
+
blockId: e.id,
|
|
1005
|
+
source: "social-icon",
|
|
1006
|
+
label: t.platform
|
|
1007
|
+
});
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
}), i;
|
|
1011
|
+
}
|
|
1012
|
+
//#endregion
|
|
1013
|
+
//#region ../quality/src/links/rules/javascript-protocol.ts
|
|
1014
|
+
var yt = {
|
|
1015
|
+
id: "link.javascript-protocol",
|
|
1016
|
+
severity: "error"
|
|
1017
|
+
}, Z = [
|
|
1018
|
+
"javascript",
|
|
1019
|
+
"data",
|
|
1020
|
+
"vbscript"
|
|
1021
|
+
];
|
|
1022
|
+
function bt(e) {
|
|
1023
|
+
if (!e) return null;
|
|
1024
|
+
let t = e.replace(/\s+/g, "");
|
|
1025
|
+
for (let e of Z) if (RegExp(`^${e}:`, "i").test(t)) return e;
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
var xt = {
|
|
1029
|
+
meta: yt,
|
|
1030
|
+
template(e) {
|
|
1031
|
+
let t = [];
|
|
1032
|
+
for (let n of X(e)) {
|
|
1033
|
+
let e = bt(n.url);
|
|
1034
|
+
e !== null && t.push({
|
|
1035
|
+
blockId: n.blockId,
|
|
1036
|
+
params: { protocol: e }
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
return t;
|
|
1040
|
+
}
|
|
1041
|
+
}, St = {
|
|
1042
|
+
id: "link.unsupported-protocol",
|
|
1043
|
+
severity: "warning"
|
|
1044
|
+
}, Ct = /* @__PURE__ */ new Set([
|
|
1045
|
+
"http",
|
|
1046
|
+
"https",
|
|
1047
|
+
"mailto",
|
|
1048
|
+
"tel",
|
|
1049
|
+
"sms"
|
|
1050
|
+
]), wt = new Set(Z);
|
|
1051
|
+
function Tt(e) {
|
|
1052
|
+
if (!e) return null;
|
|
1053
|
+
let t = e.trim(), n = /^([a-z][a-z0-9+\-.]*):/i.exec(t);
|
|
1054
|
+
return n ? n[1].toLowerCase() : null;
|
|
1055
|
+
}
|
|
1056
|
+
var Et = {
|
|
1057
|
+
meta: St,
|
|
1058
|
+
template(e) {
|
|
1059
|
+
let t = [];
|
|
1060
|
+
for (let n of X(e)) {
|
|
1061
|
+
let e = Tt(n.url);
|
|
1062
|
+
e !== null && (wt.has(e) || Ct.has(e) || t.push({
|
|
1063
|
+
blockId: n.blockId,
|
|
1064
|
+
params: { protocol: e }
|
|
1065
|
+
}));
|
|
1066
|
+
}
|
|
1067
|
+
return t;
|
|
1068
|
+
}
|
|
1069
|
+
}, Dt = {
|
|
1070
|
+
id: "link.malformed-mailto",
|
|
1071
|
+
severity: "warning"
|
|
1072
|
+
};
|
|
1073
|
+
function Q(e) {
|
|
1074
|
+
let t = e.trim();
|
|
1075
|
+
if (!/^mailto:/i.test(t)) return !1;
|
|
1076
|
+
let [n] = t.slice(7).split("?", 2);
|
|
1077
|
+
if (n.trim() === "") return !0;
|
|
1078
|
+
let r = n.split(",").map((e) => e.trim());
|
|
1079
|
+
for (let e of r) {
|
|
1080
|
+
if (e === "") return !0;
|
|
1081
|
+
let t = e.split("@");
|
|
1082
|
+
if (t.length !== 2) return !0;
|
|
1083
|
+
let [n, r] = t;
|
|
1084
|
+
if (n === "" || r === "" || !r.includes(".")) return !0;
|
|
1085
|
+
}
|
|
1086
|
+
return !1;
|
|
1087
|
+
}
|
|
1088
|
+
var Ot = {
|
|
1089
|
+
meta: Dt,
|
|
1090
|
+
template(e) {
|
|
1091
|
+
let t = [];
|
|
1092
|
+
for (let n of X(e)) Q(n.url) && t.push({ blockId: n.blockId });
|
|
1093
|
+
return t;
|
|
1094
|
+
}
|
|
1095
|
+
}, kt = {
|
|
1096
|
+
id: "link.malformed-tel",
|
|
1097
|
+
severity: "warning"
|
|
1098
|
+
}, At = /^[+0-9\s().\-]+$/, jt = /^[A-Za-z0-9-]+(=[^;]+)?$/;
|
|
1099
|
+
function Mt(e) {
|
|
1100
|
+
let t = e.trim();
|
|
1101
|
+
if (!/^tel:/i.test(t)) return !1;
|
|
1102
|
+
let n = t.slice(4).trim();
|
|
1103
|
+
if (n === "") return !0;
|
|
1104
|
+
let [r, ...i] = n.split(";");
|
|
1105
|
+
return !At.test(r) || i.some((e) => !jt.test(e));
|
|
1106
|
+
}
|
|
1107
|
+
var Nt = {
|
|
1108
|
+
meta: kt,
|
|
1109
|
+
template(e) {
|
|
1110
|
+
let t = [];
|
|
1111
|
+
for (let n of X(e)) Mt(n.url) && t.push({ blockId: n.blockId });
|
|
1112
|
+
return t;
|
|
1113
|
+
}
|
|
1114
|
+
}, Pt = {
|
|
1115
|
+
id: "link.localhost-or-staging",
|
|
1116
|
+
severity: "warning"
|
|
1117
|
+
};
|
|
1118
|
+
function Ft(e) {
|
|
1119
|
+
let t = e.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
1120
|
+
return RegExp(`^${t}$`, "i");
|
|
1121
|
+
}
|
|
1122
|
+
function It(e) {
|
|
1123
|
+
if (!e) return null;
|
|
1124
|
+
let t = e.trim();
|
|
1125
|
+
if (!/^(https?|ftps?):\/\//i.test(t)) return null;
|
|
1126
|
+
try {
|
|
1127
|
+
return new URL(t).hostname.toLowerCase();
|
|
1128
|
+
} catch {
|
|
1129
|
+
return null;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
//#endregion
|
|
1133
|
+
//#region ../quality/src/links/index.ts
|
|
1134
|
+
var $ = [
|
|
1135
|
+
xt,
|
|
1136
|
+
Et,
|
|
1137
|
+
Ot,
|
|
1138
|
+
Nt,
|
|
1139
|
+
{
|
|
1140
|
+
meta: Pt,
|
|
1141
|
+
template(e, t) {
|
|
1142
|
+
let n = t.links.nonProductionHosts;
|
|
1143
|
+
if (n.length === 0) return [];
|
|
1144
|
+
let r = n.map(Ft), i = [];
|
|
1145
|
+
for (let t of X(e)) {
|
|
1146
|
+
let e = It(t.url);
|
|
1147
|
+
e !== null && r.some((t) => t.test(e)) && i.push({
|
|
1148
|
+
blockId: t.blockId,
|
|
1149
|
+
params: { host: e }
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
return i;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
];
|
|
1156
|
+
function Lt(e, t = {}) {
|
|
1157
|
+
return t.disabled === !0 || t.links === !1 ? [] : C(e, $, ae(t.locale, t.links ?? {}, $), (e, t, n) => vt(e, t, n));
|
|
1158
|
+
}
|
|
1159
|
+
//#endregion
|
|
1160
|
+
//#region ../quality/src/util.ts
|
|
1161
|
+
function Rt(e) {
|
|
1162
|
+
return e ? e.disabled === !0 || e.accessibility === !1 && e.structure === !1 && e.links === !1 : !1;
|
|
1163
|
+
}
|
|
1164
|
+
//#endregion
|
|
1165
|
+
//#region ../quality/src/lint-template.ts
|
|
1166
|
+
function zt(e, t = {}) {
|
|
1167
|
+
return Rt(t) ? [] : [
|
|
1168
|
+
...Ze(e, t),
|
|
1169
|
+
...pt(e, t),
|
|
1170
|
+
...Lt(e, t)
|
|
1171
|
+
];
|
|
1172
|
+
}
|
|
1173
|
+
//#endregion
|
|
1174
|
+
export { zt as lintTemplate };
|
|
1175
|
+
|
|
1176
|
+
//# sourceMappingURL=src-CM0gCvAS.js.map
|