@ng-prism/plugin-visual-regression 22.2.0-beta.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.
Files changed (55) hide show
  1. package/README.md +106 -0
  2. package/dist/asset-url.d.ts +14 -0
  3. package/dist/asset-url.d.ts.map +1 -0
  4. package/dist/asset-url.js +25 -0
  5. package/dist/index.browser.d.ts +7 -0
  6. package/dist/index.browser.d.ts.map +1 -0
  7. package/dist/index.browser.js +8 -0
  8. package/dist/index.d.ts +7 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +5 -0
  11. package/dist/report-reader.d.ts +18 -0
  12. package/dist/report-reader.d.ts.map +1 -0
  13. package/dist/report-reader.js +55 -0
  14. package/dist/schematics/ng-add/index.d.ts +4 -0
  15. package/dist/schematics/ng-add/index.d.ts.map +1 -0
  16. package/dist/schematics/ng-add/index.js +25 -0
  17. package/dist/schematics/ng-add/schema.d.ts +4 -0
  18. package/dist/schematics/ng-add/schema.d.ts.map +1 -0
  19. package/dist/schematics/ng-add/schema.js +1 -0
  20. package/dist/thresholds.d.ts +16 -0
  21. package/dist/thresholds.d.ts.map +1 -0
  22. package/dist/thresholds.js +20 -0
  23. package/dist/visual-regression-header-badge.component.d.ts +14 -0
  24. package/dist/visual-regression-header-badge.component.d.ts.map +1 -0
  25. package/dist/visual-regression-header-badge.component.js +73 -0
  26. package/dist/visual-regression-panel.component.d.ts +22 -0
  27. package/dist/visual-regression-panel.component.d.ts.map +1 -0
  28. package/dist/visual-regression-panel.component.js +191 -0
  29. package/dist/visual-regression-plugin.browser.d.ts +11 -0
  30. package/dist/visual-regression-plugin.browser.d.ts.map +1 -0
  31. package/dist/visual-regression-plugin.browser.js +34 -0
  32. package/dist/visual-regression-plugin.d.ts +11 -0
  33. package/dist/visual-regression-plugin.d.ts.map +1 -0
  34. package/dist/visual-regression-plugin.js +67 -0
  35. package/dist/visual-regression.types.d.ts +97 -0
  36. package/dist/visual-regression.types.d.ts.map +1 -0
  37. package/dist/visual-regression.types.js +1 -0
  38. package/dist/vrt-bg.d.ts +37 -0
  39. package/dist/vrt-bg.d.ts.map +1 -0
  40. package/dist/vrt-bg.js +53 -0
  41. package/dist/vrt-compare.component.d.ts +70 -0
  42. package/dist/vrt-compare.component.d.ts.map +1 -0
  43. package/dist/vrt-compare.component.js +602 -0
  44. package/dist/vrt-summarize.d.ts +48 -0
  45. package/dist/vrt-summarize.d.ts.map +1 -0
  46. package/dist/vrt-summarize.js +97 -0
  47. package/dist/vrt-summary.component.d.ts +17 -0
  48. package/dist/vrt-summary.component.d.ts.map +1 -0
  49. package/dist/vrt-summary.component.js +67 -0
  50. package/dist/vrt-zoom.d.ts +36 -0
  51. package/dist/vrt-zoom.d.ts.map +1 -0
  52. package/dist/vrt-zoom.js +48 -0
  53. package/package.json +54 -0
  54. package/schematics/collection.json +10 -0
  55. package/schematics/ng-add/schema.json +16 -0
@@ -0,0 +1,602 @@
1
+ import { ChangeDetectionStrategy, Component, computed, input, signal, } from '@angular/core';
2
+ import { resolveAssetUrl } from './asset-url.js';
3
+ import { bgChange, shotSurfaceStyle } from './vrt-bg.js';
4
+ import { formatPercent } from './vrt-summarize.js';
5
+ import { frameWidthStyle, ZOOMS } from './vrt-zoom.js';
6
+ import * as i0 from "@angular/core";
7
+ function VrtCompareComponent_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
8
+ const _r1 = i0.ɵɵgetCurrentView();
9
+ i0.ɵɵdomElementStart(0, "button", 10);
10
+ i0.ɵɵdomListener("click", function VrtCompareComponent_Conditional_1_For_3_Template_button_click_0_listener() { const mode_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.requestedMode.set(mode_r2)); });
11
+ i0.ɵɵtext(1);
12
+ i0.ɵɵdomElementEnd();
13
+ } if (rf & 2) {
14
+ const mode_r2 = ctx.$implicit;
15
+ const ctx_r2 = i0.ɵɵnextContext(2);
16
+ i0.ɵɵclassProp("vrt-cmp__mode--active", mode_r2 === ctx_r2.activeMode());
17
+ i0.ɵɵadvance();
18
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.MODE_LABEL[mode_r2], " ");
19
+ } }
20
+ function VrtCompareComponent_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
21
+ i0.ɵɵdomElementStart(0, "span");
22
+ i0.ɵɵtext(1);
23
+ i0.ɵɵdomElementEnd();
24
+ } if (rf & 2) {
25
+ const ctx_r2 = i0.ɵɵnextContext(2);
26
+ i0.ɵɵadvance();
27
+ i0.ɵɵtextInterpolate2("", ctx_r2.variant().width, "\u00D7", ctx_r2.variant().height);
28
+ } }
29
+ function VrtCompareComponent_Conditional_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵdomElementStart(0, "span");
31
+ i0.ɵɵtext(1);
32
+ i0.ɵɵdomElementEnd();
33
+ } if (rf & 2) {
34
+ const ctx_r2 = i0.ɵɵnextContext(2);
35
+ i0.ɵɵadvance();
36
+ i0.ɵɵtextInterpolate1("", ctx_r2.variant().diffPixels.toLocaleString(), " px");
37
+ } }
38
+ function VrtCompareComponent_Conditional_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
39
+ i0.ɵɵdomElementStart(0, "span", 7);
40
+ i0.ɵɵtext(1);
41
+ i0.ɵɵdomElementEnd();
42
+ } if (rf & 2) {
43
+ const ctx_r2 = i0.ɵɵnextContext(2);
44
+ i0.ɵɵattribute("data-hot", ctx_r2.variant().diffRatio > 0 ? "" : null);
45
+ i0.ɵɵadvance();
46
+ i0.ɵɵtextInterpolate(ctx_r2.percent(ctx_r2.variant().diffRatio));
47
+ } }
48
+ function VrtCompareComponent_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
49
+ i0.ɵɵdomElementStart(0, "span", 8);
50
+ i0.ɵɵtext(1);
51
+ i0.ɵɵdomElementEnd();
52
+ } if (rf & 2) {
53
+ i0.ɵɵadvance();
54
+ i0.ɵɵtextInterpolate1("on ", ctx);
55
+ } }
56
+ function VrtCompareComponent_Conditional_1_Conditional_10_For_2_Template(rf, ctx) { if (rf & 1) {
57
+ const _r4 = i0.ɵɵgetCurrentView();
58
+ i0.ɵɵdomElementStart(0, "button", 12);
59
+ i0.ɵɵdomListener("click", function VrtCompareComponent_Conditional_1_Conditional_10_For_2_Template_button_click_0_listener() { const z_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.zoom.set(z_r5)); });
60
+ i0.ɵɵtext(1);
61
+ i0.ɵɵdomElementEnd();
62
+ } if (rf & 2) {
63
+ const z_r5 = ctx.$implicit;
64
+ const ctx_r2 = i0.ɵɵnextContext(3);
65
+ i0.ɵɵclassProp("vrt-cmp__zoom--active", z_r5 === ctx_r2.zoom());
66
+ i0.ɵɵadvance();
67
+ i0.ɵɵtextInterpolate1(" ", z_r5 === "fit" ? "Fit" : z_r5 + "\u00D7", " ");
68
+ } }
69
+ function VrtCompareComponent_Conditional_1_Conditional_10_Template(rf, ctx) { if (rf & 1) {
70
+ i0.ɵɵdomElementStart(0, "div", 9);
71
+ i0.ɵɵrepeaterCreate(1, VrtCompareComponent_Conditional_1_Conditional_10_For_2_Template, 2, 3, "button", 11, i0.ɵɵrepeaterTrackByIdentity);
72
+ i0.ɵɵdomElementEnd();
73
+ } if (rf & 2) {
74
+ const ctx_r2 = i0.ɵɵnextContext(2);
75
+ i0.ɵɵadvance();
76
+ i0.ɵɵrepeater(ctx_r2.ZOOMS);
77
+ } }
78
+ function VrtCompareComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
79
+ i0.ɵɵdomElementStart(0, "div", 1)(1, "div", 3);
80
+ i0.ɵɵrepeaterCreate(2, VrtCompareComponent_Conditional_1_For_3_Template, 2, 3, "button", 4, i0.ɵɵrepeaterTrackByIdentity);
81
+ i0.ɵɵdomElementEnd();
82
+ i0.ɵɵdomElementStart(4, "div", 5)(5, "span", 6);
83
+ i0.ɵɵconditionalCreate(6, VrtCompareComponent_Conditional_1_Conditional_6_Template, 2, 2, "span");
84
+ i0.ɵɵconditionalCreate(7, VrtCompareComponent_Conditional_1_Conditional_7_Template, 2, 1, "span");
85
+ i0.ɵɵconditionalCreate(8, VrtCompareComponent_Conditional_1_Conditional_8_Template, 2, 2, "span", 7);
86
+ i0.ɵɵconditionalCreate(9, VrtCompareComponent_Conditional_1_Conditional_9_Template, 2, 1, "span", 8);
87
+ i0.ɵɵdomElementEnd();
88
+ i0.ɵɵconditionalCreate(10, VrtCompareComponent_Conditional_1_Conditional_10_Template, 3, 0, "div", 9);
89
+ i0.ɵɵdomElementEnd()();
90
+ } if (rf & 2) {
91
+ let tmp_5_0;
92
+ const ctx_r2 = i0.ɵɵnextContext();
93
+ i0.ɵɵadvance(2);
94
+ i0.ɵɵrepeater(ctx_r2.availableModes());
95
+ i0.ɵɵadvance(4);
96
+ i0.ɵɵconditional(ctx_r2.variant().width && ctx_r2.variant().height ? 6 : -1);
97
+ i0.ɵɵadvance();
98
+ i0.ɵɵconditional(ctx_r2.variant().diffPixels !== undefined ? 7 : -1);
99
+ i0.ɵɵadvance();
100
+ i0.ɵɵconditional(ctx_r2.variant().diffRatio !== undefined ? 8 : -1);
101
+ i0.ɵɵadvance();
102
+ i0.ɵɵconditional((tmp_5_0 = ctx_r2.variant().bg) ? 9 : -1, tmp_5_0);
103
+ i0.ɵɵadvance();
104
+ i0.ɵɵconditional(ctx_r2.canZoom() ? 10 : -1);
105
+ } }
106
+ function VrtCompareComponent_Conditional_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
107
+ i0.ɵɵtext(0);
108
+ } if (rf & 2) {
109
+ const ctx_r2 = i0.ɵɵnextContext(2);
110
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.variant().reason, " ");
111
+ } }
112
+ function VrtCompareComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
113
+ i0.ɵɵdomElementStart(0, "div", 2)(1, "b");
114
+ i0.ɵɵtext(2, "Excluded from visual regression.");
115
+ i0.ɵɵdomElementEnd();
116
+ i0.ɵɵdomElementStart(3, "span");
117
+ i0.ɵɵtext(4, " Nothing was captured for this variant.");
118
+ i0.ɵɵconditionalCreate(5, VrtCompareComponent_Conditional_2_Conditional_5_Template, 1, 1);
119
+ i0.ɵɵdomElementEnd()();
120
+ } if (rf & 2) {
121
+ const ctx_r2 = i0.ɵɵnextContext();
122
+ i0.ɵɵadvance(5);
123
+ i0.ɵɵconditional(ctx_r2.variant().reason ? 5 : -1);
124
+ } }
125
+ function VrtCompareComponent_Conditional_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
126
+ i0.ɵɵdomElementStart(0, "div", 13)(1, "b");
127
+ i0.ɵɵtext(2, "Background changed.");
128
+ i0.ɵɵdomElementEnd();
129
+ i0.ɵɵdomElementStart(3, "span");
130
+ i0.ɵɵtext(4, " The baseline was captured on ");
131
+ i0.ɵɵdomElementStart(5, "code");
132
+ i0.ɵɵtext(6);
133
+ i0.ɵɵdomElementEnd();
134
+ i0.ɵɵtext(7, ", this run on ");
135
+ i0.ɵɵdomElementStart(8, "code");
136
+ i0.ɵɵtext(9);
137
+ i0.ɵɵdomElementEnd();
138
+ i0.ɵɵtext(10, " \u2014 the difference is the surface, not necessarily the component. Re-record the baseline. ");
139
+ i0.ɵɵdomElementEnd()();
140
+ } if (rf & 2) {
141
+ const move_r6 = ctx;
142
+ i0.ɵɵadvance(6);
143
+ i0.ɵɵtextInterpolate(move_r6.from);
144
+ i0.ɵɵadvance(3);
145
+ i0.ɵɵtextInterpolate(move_r6.to);
146
+ } }
147
+ function VrtCompareComponent_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
148
+ i0.ɵɵdomElementStart(0, "div", 13)(1, "b");
149
+ i0.ɵɵtext(2, "Dimensions changed.");
150
+ i0.ɵɵdomElementEnd();
151
+ i0.ɵɵdomElementStart(3, "span");
152
+ i0.ɵɵtext(4, "No pixel comparison was possible \u2014 compare the images directly.");
153
+ i0.ɵɵdomElementEnd()();
154
+ } }
155
+ function VrtCompareComponent_Conditional_3_Conditional_2_Case_0_Template(rf, ctx) { if (rf & 1) {
156
+ const _r7 = i0.ɵɵgetCurrentView();
157
+ i0.ɵɵdomElementStart(0, "div", 14)(1, "div", 16)(2, "div", 17);
158
+ i0.ɵɵdomElement(3, "img", 18);
159
+ i0.ɵɵdomElementStart(4, "div", 19);
160
+ i0.ɵɵdomElement(5, "img", 18);
161
+ i0.ɵɵdomElementEnd();
162
+ i0.ɵɵdomElement(6, "div", 20);
163
+ i0.ɵɵdomElementEnd();
164
+ i0.ɵɵdomElementStart(7, "input", 21);
165
+ i0.ɵɵdomListener("input", function VrtCompareComponent_Conditional_3_Conditional_2_Case_0_Template_input_input_7_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.wipe.set(+$event.target.value)); });
166
+ i0.ɵɵdomElementEnd();
167
+ i0.ɵɵdomElementStart(8, "div", 22)(9, "span");
168
+ i0.ɵɵtext(10);
169
+ i0.ɵɵdomElementEnd();
170
+ i0.ɵɵdomElementStart(11, "span");
171
+ i0.ɵɵtext(12);
172
+ i0.ɵɵdomElementEnd()()()();
173
+ } if (rf & 2) {
174
+ const img_r8 = i0.ɵɵnextContext();
175
+ const ctx_r2 = i0.ɵɵnextContext(2);
176
+ i0.ɵɵadvance();
177
+ i0.ɵɵstyleMap(ctx_r2.frameStyle());
178
+ i0.ɵɵadvance();
179
+ i0.ɵɵstyleMap(ctx_r2.currentSurface());
180
+ i0.ɵɵadvance();
181
+ i0.ɵɵdomProperty("src", img_r8.left, i0.ɵɵsanitizeUrl)("alt", img_r8.leftLabel);
182
+ i0.ɵɵadvance();
183
+ i0.ɵɵstyleProp("clip-path", "inset(0 0 0 " + ctx_r2.wipe() + "%)");
184
+ i0.ɵɵadvance();
185
+ i0.ɵɵdomProperty("src", img_r8.right, i0.ɵɵsanitizeUrl)("alt", img_r8.rightLabel);
186
+ i0.ɵɵadvance();
187
+ i0.ɵɵstyleProp("left", ctx_r2.wipe(), "%");
188
+ i0.ɵɵadvance();
189
+ i0.ɵɵdomProperty("value", ctx_r2.wipe());
190
+ i0.ɵɵadvance(3);
191
+ i0.ɵɵtextInterpolate(img_r8.leftLabel);
192
+ i0.ɵɵadvance(2);
193
+ i0.ɵɵtextInterpolate(img_r8.rightLabel);
194
+ } }
195
+ function VrtCompareComponent_Conditional_3_Conditional_2_Case_1_Template(rf, ctx) { if (rf & 1) {
196
+ i0.ɵɵdomElementStart(0, "div", 15)(1, "figure", 16)(2, "figcaption");
197
+ i0.ɵɵtext(3);
198
+ i0.ɵɵdomElementEnd();
199
+ i0.ɵɵdomElementStart(4, "div", 23);
200
+ i0.ɵɵdomElement(5, "img", 18);
201
+ i0.ɵɵdomElementEnd()();
202
+ i0.ɵɵdomElementStart(6, "figure", 16)(7, "figcaption");
203
+ i0.ɵɵtext(8);
204
+ i0.ɵɵdomElementEnd();
205
+ i0.ɵɵdomElementStart(9, "div", 23);
206
+ i0.ɵɵdomElement(10, "img", 18);
207
+ i0.ɵɵdomElementEnd()()();
208
+ } if (rf & 2) {
209
+ const img_r8 = i0.ɵɵnextContext();
210
+ const ctx_r2 = i0.ɵɵnextContext(2);
211
+ i0.ɵɵadvance();
212
+ i0.ɵɵstyleMap(ctx_r2.frameStyle());
213
+ i0.ɵɵadvance(2);
214
+ i0.ɵɵtextInterpolate(img_r8.leftLabel);
215
+ i0.ɵɵadvance();
216
+ i0.ɵɵstyleMap(ctx_r2.baselineSurface());
217
+ i0.ɵɵadvance();
218
+ i0.ɵɵdomProperty("src", img_r8.left, i0.ɵɵsanitizeUrl)("alt", img_r8.leftLabel);
219
+ i0.ɵɵadvance();
220
+ i0.ɵɵstyleMap(ctx_r2.frameStyle());
221
+ i0.ɵɵadvance(2);
222
+ i0.ɵɵtextInterpolate(img_r8.rightLabel);
223
+ i0.ɵɵadvance();
224
+ i0.ɵɵstyleMap(ctx_r2.currentSurface());
225
+ i0.ɵɵadvance();
226
+ i0.ɵɵdomProperty("src", img_r8.right, i0.ɵɵsanitizeUrl)("alt", img_r8.rightLabel);
227
+ } }
228
+ function VrtCompareComponent_Conditional_3_Conditional_2_Case_2_Template(rf, ctx) { if (rf & 1) {
229
+ i0.ɵɵdomElementStart(0, "div", 14)(1, "div", 16)(2, "div", 23);
230
+ i0.ɵɵdomElement(3, "img", 24);
231
+ i0.ɵɵdomElementEnd()()();
232
+ } if (rf & 2) {
233
+ const ctx_r2 = i0.ɵɵnextContext(3);
234
+ i0.ɵɵadvance();
235
+ i0.ɵɵstyleMap(ctx_r2.frameStyle());
236
+ i0.ɵɵadvance();
237
+ i0.ɵɵstyleMap(ctx_r2.currentSurface());
238
+ i0.ɵɵadvance();
239
+ i0.ɵɵdomProperty("src", ctx_r2.diffUrl(), i0.ɵɵsanitizeUrl);
240
+ } }
241
+ function VrtCompareComponent_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
242
+ i0.ɵɵconditionalCreate(0, VrtCompareComponent_Conditional_3_Conditional_2_Case_0_Template, 13, 15, "div", 14)(1, VrtCompareComponent_Conditional_3_Conditional_2_Case_1_Template, 11, 14, "div", 15)(2, VrtCompareComponent_Conditional_3_Conditional_2_Case_2_Template, 4, 5, "div", 14);
243
+ } if (rf & 2) {
244
+ let tmp_3_0;
245
+ const ctx_r2 = i0.ɵɵnextContext(2);
246
+ i0.ɵɵconditional((tmp_3_0 = ctx_r2.activeMode()) === "wipe" ? 0 : tmp_3_0 === "side-by-side" ? 1 : tmp_3_0 === "diff" ? 2 : -1);
247
+ } }
248
+ function VrtCompareComponent_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
249
+ i0.ɵɵdomElementStart(0, "div", 2)(1, "b");
250
+ i0.ɵɵtext(2);
251
+ i0.ɵɵdomElementEnd();
252
+ i0.ɵɵdomElementStart(3, "span");
253
+ i0.ɵɵtext(4);
254
+ i0.ɵɵdomElementEnd()();
255
+ i0.ɵɵdomElementStart(5, "div", 14)(6, "div", 16)(7, "div", 23);
256
+ i0.ɵɵdomElement(8, "img", 18);
257
+ i0.ɵɵdomElementEnd()()();
258
+ } if (rf & 2) {
259
+ const single_r9 = ctx;
260
+ const ctx_r2 = i0.ɵɵnextContext(2);
261
+ i0.ɵɵadvance(2);
262
+ i0.ɵɵtextInterpolate(single_r9.title);
263
+ i0.ɵɵadvance(2);
264
+ i0.ɵɵtextInterpolate(single_r9.note);
265
+ i0.ɵɵadvance(2);
266
+ i0.ɵɵstyleMap(ctx_r2.frameStyle());
267
+ i0.ɵɵadvance();
268
+ i0.ɵɵstyleMap(single_r9.surface);
269
+ i0.ɵɵadvance();
270
+ i0.ɵɵdomProperty("src", single_r9.src, i0.ɵɵsanitizeUrl)("alt", single_r9.label);
271
+ } }
272
+ function VrtCompareComponent_Conditional_3_Conditional_4_Template(rf, ctx) { if (rf & 1) {
273
+ i0.ɵɵdomElementStart(0, "div", 2)(1, "b");
274
+ i0.ɵɵtext(2, "No images recorded.");
275
+ i0.ɵɵdomElementEnd();
276
+ i0.ɵɵdomElementStart(3, "span");
277
+ i0.ɵɵtext(4, " The report has a result for this variant but no file paths. ");
278
+ i0.ɵɵdomElementEnd()();
279
+ } }
280
+ function VrtCompareComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
281
+ i0.ɵɵconditionalCreate(0, VrtCompareComponent_Conditional_3_Conditional_0_Template, 11, 2, "div", 13);
282
+ i0.ɵɵconditionalCreate(1, VrtCompareComponent_Conditional_3_Conditional_1_Template, 5, 0, "div", 13);
283
+ i0.ɵɵconditionalCreate(2, VrtCompareComponent_Conditional_3_Conditional_2_Template, 3, 1)(3, VrtCompareComponent_Conditional_3_Conditional_3_Template, 9, 8)(4, VrtCompareComponent_Conditional_3_Conditional_4_Template, 5, 0, "div", 2);
284
+ } if (rf & 2) {
285
+ let tmp_1_0;
286
+ let tmp_3_0;
287
+ const ctx_r2 = i0.ɵɵnextContext();
288
+ i0.ɵɵconditional((tmp_1_0 = ctx_r2.bgMove()) ? 0 : -1, tmp_1_0);
289
+ i0.ɵɵadvance();
290
+ i0.ɵɵconditional(ctx_r2.variant().status === "size-mismatch" ? 1 : -1);
291
+ i0.ɵɵadvance();
292
+ i0.ɵɵconditional((tmp_3_0 = ctx_r2.images()) ? 2 : (tmp_3_0 = ctx_r2.singleImage()) ? 3 : 4, tmp_3_0);
293
+ } }
294
+ const MODE_LABEL = {
295
+ wipe: 'Wipe',
296
+ 'side-by-side': 'Side by side',
297
+ diff: 'Diff',
298
+ };
299
+ /**
300
+ * The comparison stage: toolbar, zoom, and the three ways to look at a variant.
301
+ *
302
+ * Owns its own URL resolution and mode state so the panel shell stays a shell.
303
+ * Everything it needs is in the one variant it is handed.
304
+ */
305
+ export class VrtCompareComponent {
306
+ variant = input.required(/* @ts-ignore */
307
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
308
+ assetBaseUrl = input('', /* @ts-ignore */
309
+ ...(ngDevMode ? [{ debugName: "assetBaseUrl" }] : /* istanbul ignore next */ []));
310
+ requestedMode = signal(null, /* @ts-ignore */
311
+ ...(ngDevMode ? [{ debugName: "requestedMode" }] : /* istanbul ignore next */ []));
312
+ zoom = signal('fit', /* @ts-ignore */
313
+ ...(ngDevMode ? [{ debugName: "zoom" }] : /* istanbul ignore next */ []));
314
+ wipe = signal(50, /* @ts-ignore */
315
+ ...(ngDevMode ? [{ debugName: "wipe" }] : /* istanbul ignore next */ []));
316
+ MODE_LABEL = MODE_LABEL;
317
+ ZOOMS = ZOOMS;
318
+ baselineUrl = computed(() => resolveAssetUrl(this.assetBaseUrl(), this.variant().baselinePath), /* @ts-ignore */
319
+ ...(ngDevMode ? [{ debugName: "baselineUrl" }] : /* istanbul ignore next */ []));
320
+ currentUrl = computed(() => resolveAssetUrl(this.assetBaseUrl(), this.variant().currentPath), /* @ts-ignore */
321
+ ...(ngDevMode ? [{ debugName: "currentUrl" }] : /* istanbul ignore next */ []));
322
+ diffUrl = computed(() => resolveAssetUrl(this.assetBaseUrl(), this.variant().diffPath), /* @ts-ignore */
323
+ ...(ngDevMode ? [{ debugName: "diffUrl" }] : /* istanbul ignore next */ []));
324
+ /**
325
+ * The two images to compare.
326
+ *
327
+ * `currentPath` is optional in the report, so the right-hand side falls back
328
+ * to the diff mask. Below that the viewer degrades to a single image.
329
+ */
330
+ images = computed(() => {
331
+ const left = this.baselineUrl();
332
+ const right = this.currentUrl() ?? this.diffUrl();
333
+ if (!left || !right)
334
+ return null;
335
+ return {
336
+ left,
337
+ leftLabel: 'Baseline',
338
+ right,
339
+ rightLabel: this.currentUrl() ? 'Current' : 'Diff',
340
+ };
341
+ }, /* @ts-ignore */
342
+ ...(ngDevMode ? [{ debugName: "images" }] : /* istanbul ignore next */ []));
343
+ /**
344
+ * The surface each capture sits on; see {@link shotSurfaceStyle}.
345
+ *
346
+ * The baseline falls back to this run's background: when it did not move the
347
+ * two are the same, and when it did, `baselineBg` is what records the move.
348
+ */
349
+ currentSurface = computed(() => shotSurfaceStyle(this.variant().bg), /* @ts-ignore */
350
+ ...(ngDevMode ? [{ debugName: "currentSurface" }] : /* istanbul ignore next */ []));
351
+ baselineSurface = computed(() => shotSurfaceStyle(this.variant().baselineBg ?? this.variant().bg), /* @ts-ignore */
352
+ ...(ngDevMode ? [{ debugName: "baselineSurface" }] : /* istanbul ignore next */ []));
353
+ /** A background move between baseline and this run; see {@link bgChange}. */
354
+ bgMove = computed(() => bgChange(this.variant()), /* @ts-ignore */
355
+ ...(ngDevMode ? [{ debugName: "bgMove" }] : /* istanbul ignore next */ []));
356
+ singleImage = computed(() => {
357
+ if (this.images())
358
+ return null;
359
+ const baseline = this.baselineUrl();
360
+ const only = baseline ?? this.currentUrl() ?? this.diffUrl();
361
+ if (!only)
362
+ return null;
363
+ const isNew = this.variant().status === 'new';
364
+ return {
365
+ src: only,
366
+ surface: baseline ? this.baselineSurface() : this.currentSurface(),
367
+ label: isNew ? 'Current' : 'Recorded image',
368
+ title: isNew ? 'No baseline yet.' : 'Only one image recorded.',
369
+ note: isNew
370
+ ? 'Nothing to compare against — this is what the runner captured.'
371
+ : 'The report recorded only one image for this variant.',
372
+ };
373
+ }, /* @ts-ignore */
374
+ ...(ngDevMode ? [{ debugName: "singleImage" }] : /* istanbul ignore next */ []));
375
+ availableModes = computed(() => {
376
+ if (this.variant().status === 'excluded')
377
+ return [];
378
+ if (!this.images())
379
+ return [];
380
+ // Wiping between two images of different sizes overlays pixels that do not
381
+ // correspond, so a resized variant leads with side-by-side. Wipe stays
382
+ // available — it is a poor comparison there, not a forbidden one.
383
+ const modes = this.variant().status === 'size-mismatch'
384
+ ? ['side-by-side', 'wipe']
385
+ : ['wipe', 'side-by-side'];
386
+ // Only a distinct diff mask earns its own tab; when it is already the
387
+ // right-hand image, a "Diff" button would just repeat the comparison.
388
+ if (this.diffUrl() && this.currentUrl())
389
+ modes.push('diff');
390
+ return modes;
391
+ }, /* @ts-ignore */
392
+ ...(ngDevMode ? [{ debugName: "availableModes" }] : /* istanbul ignore next */ []));
393
+ activeMode = computed(() => {
394
+ const available = this.availableModes();
395
+ const requested = this.requestedMode();
396
+ return requested && available.includes(requested)
397
+ ? requested
398
+ : available[0] ?? 'wipe';
399
+ }, /* @ts-ignore */
400
+ ...(ngDevMode ? [{ debugName: "activeMode" }] : /* istanbul ignore next */ []));
401
+ /** Fixed zoom steps need a natural width to multiply; `fit` does not. */
402
+ canZoom = computed(() => typeof this.variant().width === 'number', /* @ts-ignore */
403
+ ...(ngDevMode ? [{ debugName: "canZoom" }] : /* istanbul ignore next */ []));
404
+ /**
405
+ * An excluded variant has no modes, no measurements and nothing to zoom, so
406
+ * the bar would render as a bare rule above the note explaining why.
407
+ */
408
+ showToolbar = computed(() => {
409
+ const variant = this.variant();
410
+ return (this.availableModes().length > 0 ||
411
+ this.canZoom() ||
412
+ variant.diffPixels !== undefined ||
413
+ variant.diffRatio !== undefined);
414
+ }, /* @ts-ignore */
415
+ ...(ngDevMode ? [{ debugName: "showToolbar" }] : /* istanbul ignore next */ []));
416
+ /** Width declarations for the frame; see {@link frameWidthStyle}. */
417
+ frameStyle = computed(() => {
418
+ const { width, height } = this.variant();
419
+ return frameWidthStyle(width, height, this.zoom());
420
+ }, /* @ts-ignore */
421
+ ...(ngDevMode ? [{ debugName: "frameStyle" }] : /* istanbul ignore next */ []));
422
+ percent(ratio) {
423
+ return formatPercent(ratio);
424
+ }
425
+ static ɵfac = function VrtCompareComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || VrtCompareComponent)(); };
426
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: VrtCompareComponent, selectors: [["prism-vrt-compare"]], inputs: { variant: [1, "variant"], assetBaseUrl: [1, "assetBaseUrl"] }, decls: 4, vars: 2, consts: [[1, "vrt-cmp"], [1, "vrt-cmp__bar"], [1, "vrt-cmp__note"], [1, "vrt-cmp__modes"], ["type", "button", 1, "vrt-cmp__mode", 3, "vrt-cmp__mode--active"], [1, "vrt-cmp__right"], [1, "vrt-cmp__meta"], [1, "vrt-cmp__ratio"], ["title", "The canvas background this capture was taken on", 1, "vrt-cmp__bg"], [1, "vrt-cmp__zooms"], ["type", "button", 1, "vrt-cmp__mode", 3, "click"], ["type", "button", 1, "vrt-cmp__zoom", 3, "vrt-cmp__zoom--active"], ["type", "button", 1, "vrt-cmp__zoom", 3, "click"], [1, "vrt-cmp__note", "vrt-cmp__note--warn"], [1, "vrt-cmp__stage"], [1, "vrt-cmp__stage", "vrt-cmp__stage--split"], [1, "vrt-cmp__frame"], [1, "vrt-cmp__shot", "vrt-cmp__wipe"], [1, "vrt-cmp__img", 3, "src", "alt"], [1, "vrt-cmp__wipe-top"], [1, "vrt-cmp__wipe-handle"], ["type", "range", "min", "0", "max", "100", "aria-label", "Comparison position", 1, "vrt-cmp__slider", 3, "input", "value"], [1, "vrt-cmp__legend"], [1, "vrt-cmp__shot"], ["alt", "Pixel diff", 1, "vrt-cmp__img", 3, "src"]], template: function VrtCompareComponent_Template(rf, ctx) { if (rf & 1) {
427
+ i0.ɵɵdomElementStart(0, "div", 0);
428
+ i0.ɵɵconditionalCreate(1, VrtCompareComponent_Conditional_1_Template, 11, 5, "div", 1);
429
+ i0.ɵɵconditionalCreate(2, VrtCompareComponent_Conditional_2_Template, 6, 1, "div", 2)(3, VrtCompareComponent_Conditional_3_Template, 5, 3);
430
+ i0.ɵɵdomElementEnd();
431
+ } if (rf & 2) {
432
+ i0.ɵɵadvance();
433
+ i0.ɵɵconditional(ctx.showToolbar() ? 1 : -1);
434
+ i0.ɵɵadvance();
435
+ i0.ɵɵconditional(ctx.variant().status === "excluded" ? 2 : 3);
436
+ } }, styles: ["[_nghost-%COMP%] { display: block; min-width: 0; }\n\n .vrt-cmp[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 14px 16px;\n min-width: 0;\n }\n\n .vrt-cmp__bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n flex-wrap: wrap;\n border-bottom: 1px solid var(--prism-border);\n }\n\n .vrt-cmp__right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding-bottom: 7px;\n }\n\n \n\n .vrt-cmp__modes[_ngcontent-%COMP%] { display: flex; gap: 2px; }\n\n .vrt-cmp__mode[_ngcontent-%COMP%] {\n position: relative;\n padding: 6px 11px 8px;\n background: none;\n border: none;\n cursor: pointer;\n font-family: var(--font-sans);\n font-size: 12px;\n font-weight: 500;\n color: var(--prism-text-muted);\n transition: color var(--dur-fast);\n }\n .vrt-cmp__mode[_ngcontent-%COMP%]:hover { color: var(--prism-text-2); }\n .vrt-cmp__mode--active[_ngcontent-%COMP%] { color: var(--prism-text); }\n .vrt-cmp__mode--active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n left: 6px;\n right: 6px;\n bottom: -1px;\n height: 2px;\n border-radius: 1px;\n background: var(--prism-primary);\n }\n\n .vrt-cmp__meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--font-mono);\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n }\n .vrt-cmp__meta[_ngcontent-%COMP%] > span[_ngcontent-%COMP%] + span[_ngcontent-%COMP%]::before {\n content: '\u00B7';\n margin-right: 8px;\n color: var(--prism-text-ghost);\n }\n .vrt-cmp__ratio[_ngcontent-%COMP%] { color: var(--prism-success); }\n .vrt-cmp__ratio[data-hot][_ngcontent-%COMP%] { color: var(--prism-danger); }\n\n .vrt-cmp__zooms[_ngcontent-%COMP%] {\n display: flex;\n gap: 1px;\n padding: 2px;\n background: var(--prism-input-bg);\n border-radius: var(--radius-md);\n }\n .vrt-cmp__zoom[_ngcontent-%COMP%] {\n padding: 3px 8px;\n border: none;\n background: none;\n border-radius: var(--radius-sm);\n cursor: pointer;\n font-family: var(--font-mono);\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n transition: color var(--dur-fast), background var(--dur-fast);\n }\n .vrt-cmp__zoom[_ngcontent-%COMP%]:hover { color: var(--prism-text-2); }\n .vrt-cmp__zoom--active[_ngcontent-%COMP%] {\n background: var(--prism-bg-elevated);\n color: var(--prism-text);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);\n }\n\n .vrt-cmp__stage[_ngcontent-%COMP%] {\n display: flex;\n \n\n overflow: auto;\n padding: 14px;\n background: var(--prism-bg-surface);\n border: 1px solid var(--prism-border);\n border-radius: var(--radius-lg);\n min-width: 0;\n \n\n\n\n\n --vrt-gap: 16px;\n --vrt-fit-basis: 100%;\n }\n .vrt-cmp__stage--split[_ngcontent-%COMP%] {\n gap: var(--vrt-gap);\n --vrt-fit-basis: calc((100% - var(--vrt-gap)) / 2);\n }\n\n .vrt-cmp__frame[_ngcontent-%COMP%] {\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: none;\n }\n .vrt-cmp__stage--split[_ngcontent-%COMP%] .vrt-cmp__frame[_ngcontent-%COMP%] { margin: 0; }\n\n figure.vrt-cmp__frame[_ngcontent-%COMP%] figcaption[_ngcontent-%COMP%] {\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n }\n\n \n .vrt-cmp__shot[_ngcontent-%COMP%] {\n position: relative;\n border: 1px solid var(--prism-border);\n border-radius: var(--radius-sm);\n overflow: hidden;\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 12px 12px;\n background-position: 0 0, 0 6px, 6px -6px, -6px 0;\n }\n\n .vrt-cmp__img[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n height: auto;\n \n image-rendering: pixelated;\n }\n\n .vrt-cmp__wipe-top[_ngcontent-%COMP%] { position: absolute; inset: 0; }\n .vrt-cmp__wipe-handle[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n margin-left: -1px;\n background: var(--prism-primary);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--prism-void) 45%, transparent);\n pointer-events: none;\n }\n\n .vrt-cmp__slider[_ngcontent-%COMP%] {\n width: 100%;\n margin: 0;\n appearance: none;\n background: none;\n cursor: ew-resize;\n }\n .vrt-cmp__slider[_ngcontent-%COMP%]::-webkit-slider-runnable-track {\n height: 4px;\n border-radius: 2px;\n background: var(--prism-input-bg);\n }\n .vrt-cmp__slider[_ngcontent-%COMP%]::-moz-range-track {\n height: 4px;\n border-radius: 2px;\n background: var(--prism-input-bg);\n }\n .vrt-cmp__slider[_ngcontent-%COMP%]::-webkit-slider-thumb {\n appearance: none;\n width: 13px;\n height: 13px;\n margin-top: -4.5px;\n border-radius: 50%;\n background: var(--prism-primary);\n border: 2px solid var(--prism-bg-elevated);\n box-shadow: 0 0 0 1px var(--prism-border-strong);\n }\n .vrt-cmp__slider[_ngcontent-%COMP%]::-moz-range-thumb {\n width: 13px;\n height: 13px;\n border-radius: 50%;\n background: var(--prism-primary);\n border: 2px solid var(--prism-bg-elevated);\n box-shadow: 0 0 0 1px var(--prism-border-strong);\n }\n\n .vrt-cmp__legend[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n }\n\n .vrt-cmp__note[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 3px;\n padding: 10px 12px;\n background: var(--prism-bg-surface);\n border: 1px solid var(--prism-border);\n border-left: 3px solid var(--prism-text-muted);\n border-radius: var(--radius-md);\n font-size: var(--fs-md);\n }\n .vrt-cmp__note[_ngcontent-%COMP%] b[_ngcontent-%COMP%] { font-weight: 600; color: var(--prism-text); }\n .vrt-cmp__note[_ngcontent-%COMP%] span[_ngcontent-%COMP%] { color: var(--prism-text-muted); }\n .vrt-cmp__note--warn[_ngcontent-%COMP%] { border-left-color: var(--prism-warn); }\n \n\n .vrt-cmp__note[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n font-family: var(--font-mono);\n font-size: var(--fs-sm);\n padding: 1px 5px;\n border-radius: var(--radius-xs);\n background: var(--prism-input-bg);\n }"] });
437
+ }
438
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VrtCompareComponent, [{
439
+ type: Component,
440
+ args: [{ selector: 'prism-vrt-compare', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
441
+ <div class="vrt-cmp">
442
+ @if (showToolbar()) {
443
+ <div class="vrt-cmp__bar">
444
+ <div class="vrt-cmp__modes">
445
+ @for (mode of availableModes(); track mode) {
446
+ <button
447
+ type="button"
448
+ class="vrt-cmp__mode"
449
+ [class.vrt-cmp__mode--active]="mode === activeMode()"
450
+ (click)="requestedMode.set(mode)"
451
+ >
452
+ {{ MODE_LABEL[mode] }}
453
+ </button>
454
+ }
455
+ </div>
456
+
457
+ <div class="vrt-cmp__right">
458
+ <span class="vrt-cmp__meta">
459
+ @if (variant().width && variant().height) {
460
+ <span>{{ variant().width }}×{{ variant().height }}</span>
461
+ } @if (variant().diffPixels !== undefined) {
462
+ <span>{{ variant().diffPixels!.toLocaleString() }} px</span>
463
+ } @if (variant().diffRatio !== undefined) {
464
+ <span
465
+ class="vrt-cmp__ratio"
466
+ [attr.data-hot]="variant().diffRatio! > 0 ? '' : null"
467
+ >{{ percent(variant().diffRatio!) }}</span
468
+ >
469
+ } @if (variant().bg; as bg) {
470
+ <span
471
+ class="vrt-cmp__bg"
472
+ title="The canvas background this capture was taken on"
473
+ >on {{ bg }}</span
474
+ >
475
+ }
476
+ </span>
477
+
478
+ @if (canZoom()) {
479
+ <div class="vrt-cmp__zooms">
480
+ @for (z of ZOOMS; track z) {
481
+ <button
482
+ type="button"
483
+ class="vrt-cmp__zoom"
484
+ [class.vrt-cmp__zoom--active]="z === zoom()"
485
+ (click)="zoom.set(z)"
486
+ >
487
+ {{ z === 'fit' ? 'Fit' : z + '×' }}
488
+ </button>
489
+ }
490
+ </div>
491
+ }
492
+ </div>
493
+ </div>
494
+ } @if (variant().status === 'excluded') {
495
+ <div class="vrt-cmp__note">
496
+ <b>Excluded from visual regression.</b>
497
+ <span>
498
+ Nothing was captured for this variant.@if (variant().reason) {
499
+ {{ variant().reason }} }
500
+ </span>
501
+ </div>
502
+ } @else { @if (bgMove(); as move) {
503
+ <div class="vrt-cmp__note vrt-cmp__note--warn">
504
+ <b>Background changed.</b>
505
+ <span>
506
+ The baseline was captured on <code>{{ move.from }}</code
507
+ >, this run on <code>{{ move.to }}</code> — the difference is the
508
+ surface, not necessarily the component. Re-record the baseline.
509
+ </span>
510
+ </div>
511
+ } @if (variant().status === 'size-mismatch') {
512
+ <div class="vrt-cmp__note vrt-cmp__note--warn">
513
+ <b>Dimensions changed.</b>
514
+ <span
515
+ >No pixel comparison was possible — compare the images directly.</span
516
+ >
517
+ </div>
518
+ } @if (images(); as img) { @switch (activeMode()) { @case ('wipe') {
519
+ <div class="vrt-cmp__stage">
520
+ <div class="vrt-cmp__frame" [style]="frameStyle()">
521
+ <div class="vrt-cmp__shot vrt-cmp__wipe" [style]="currentSurface()">
522
+ <img class="vrt-cmp__img" [src]="img.left" [alt]="img.leftLabel" />
523
+ <div
524
+ class="vrt-cmp__wipe-top"
525
+ [style.clip-path]="'inset(0 0 0 ' + wipe() + '%)'"
526
+ >
527
+ <img
528
+ class="vrt-cmp__img"
529
+ [src]="img.right"
530
+ [alt]="img.rightLabel"
531
+ />
532
+ </div>
533
+ <div class="vrt-cmp__wipe-handle" [style.left.%]="wipe()"></div>
534
+ </div>
535
+ <!-- Inside the frame, so the slider travel always matches the image
536
+ it controls, at any zoom. -->
537
+ <input
538
+ class="vrt-cmp__slider"
539
+ type="range"
540
+ min="0"
541
+ max="100"
542
+ aria-label="Comparison position"
543
+ [value]="wipe()"
544
+ (input)="wipe.set(+$any($event.target).value)"
545
+ />
546
+ <div class="vrt-cmp__legend">
547
+ <span>{{ img.leftLabel }}</span>
548
+ <span>{{ img.rightLabel }}</span>
549
+ </div>
550
+ </div>
551
+ </div>
552
+ } @case ('side-by-side') {
553
+ <div class="vrt-cmp__stage vrt-cmp__stage--split">
554
+ <figure class="vrt-cmp__frame" [style]="frameStyle()">
555
+ <figcaption>{{ img.leftLabel }}</figcaption>
556
+ <div class="vrt-cmp__shot" [style]="baselineSurface()">
557
+ <img class="vrt-cmp__img" [src]="img.left" [alt]="img.leftLabel" />
558
+ </div>
559
+ </figure>
560
+ <figure class="vrt-cmp__frame" [style]="frameStyle()">
561
+ <figcaption>{{ img.rightLabel }}</figcaption>
562
+ <div class="vrt-cmp__shot" [style]="currentSurface()">
563
+ <img
564
+ class="vrt-cmp__img"
565
+ [src]="img.right"
566
+ [alt]="img.rightLabel"
567
+ />
568
+ </div>
569
+ </figure>
570
+ </div>
571
+ } @case ('diff') {
572
+ <div class="vrt-cmp__stage">
573
+ <div class="vrt-cmp__frame" [style]="frameStyle()">
574
+ <div class="vrt-cmp__shot" [style]="currentSurface()">
575
+ <img class="vrt-cmp__img" [src]="diffUrl()" alt="Pixel diff" />
576
+ </div>
577
+ </div>
578
+ </div>
579
+ } } } @else if (singleImage(); as single) {
580
+ <div class="vrt-cmp__note">
581
+ <b>{{ single.title }}</b>
582
+ <span>{{ single.note }}</span>
583
+ </div>
584
+ <div class="vrt-cmp__stage">
585
+ <div class="vrt-cmp__frame" [style]="frameStyle()">
586
+ <div class="vrt-cmp__shot" [style]="single.surface">
587
+ <img class="vrt-cmp__img" [src]="single.src" [alt]="single.label" />
588
+ </div>
589
+ </div>
590
+ </div>
591
+ } @else {
592
+ <div class="vrt-cmp__note">
593
+ <b>No images recorded.</b>
594
+ <span>
595
+ The report has a result for this variant but no file paths.
596
+ </span>
597
+ </div>
598
+ } }
599
+ </div>
600
+ `, styles: ["\n :host { display: block; min-width: 0; }\n\n .vrt-cmp {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 14px 16px;\n min-width: 0;\n }\n\n .vrt-cmp__bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n flex-wrap: wrap;\n border-bottom: 1px solid var(--prism-border);\n }\n\n .vrt-cmp__right {\n display: flex;\n align-items: center;\n gap: 12px;\n padding-bottom: 7px;\n }\n\n /* Mode switching is the same act as the a11y panel's sub-tabs, so it gets\n the same underline treatment rather than a third kind of button. */\n .vrt-cmp__modes { display: flex; gap: 2px; }\n\n .vrt-cmp__mode {\n position: relative;\n padding: 6px 11px 8px;\n background: none;\n border: none;\n cursor: pointer;\n font-family: var(--font-sans);\n font-size: 12px;\n font-weight: 500;\n color: var(--prism-text-muted);\n transition: color var(--dur-fast);\n }\n .vrt-cmp__mode:hover { color: var(--prism-text-2); }\n .vrt-cmp__mode--active { color: var(--prism-text); }\n .vrt-cmp__mode--active::after {\n content: '';\n position: absolute;\n left: 6px;\n right: 6px;\n bottom: -1px;\n height: 2px;\n border-radius: 1px;\n background: var(--prism-primary);\n }\n\n .vrt-cmp__meta {\n display: flex;\n align-items: center;\n gap: 8px;\n font-family: var(--font-mono);\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n }\n .vrt-cmp__meta > span + span::before {\n content: '\u00B7';\n margin-right: 8px;\n color: var(--prism-text-ghost);\n }\n .vrt-cmp__ratio { color: var(--prism-success); }\n .vrt-cmp__ratio[data-hot] { color: var(--prism-danger); }\n\n .vrt-cmp__zooms {\n display: flex;\n gap: 1px;\n padding: 2px;\n background: var(--prism-input-bg);\n border-radius: var(--radius-md);\n }\n .vrt-cmp__zoom {\n padding: 3px 8px;\n border: none;\n background: none;\n border-radius: var(--radius-sm);\n cursor: pointer;\n font-family: var(--font-mono);\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n transition: color var(--dur-fast), background var(--dur-fast);\n }\n .vrt-cmp__zoom:hover { color: var(--prism-text-2); }\n .vrt-cmp__zoom--active {\n background: var(--prism-bg-elevated);\n color: var(--prism-text);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);\n }\n\n .vrt-cmp__stage {\n display: flex;\n /* overflow-safe centring: justify-content would clip the left edge of an\n image wider than the stage, margin auto scrolls to it instead. */\n overflow: auto;\n padding: 14px;\n background: var(--prism-bg-surface);\n border: 1px solid var(--prism-border);\n border-radius: var(--radius-lg);\n min-width: 0;\n /* How wide one frame may grow under the fit zoom. Side by side there are\n two of them, so each gets half the stage minus the gap. This is an\n inherited custom property rather than flex-grow, because a growing\n flex item ignores its own width -- which is exactly what the explicit\n zoom steps set. */\n --vrt-gap: 16px;\n --vrt-fit-basis: 100%;\n }\n .vrt-cmp__stage--split {\n gap: var(--vrt-gap);\n --vrt-fit-basis: calc((100% - var(--vrt-gap)) / 2);\n }\n\n .vrt-cmp__frame {\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: none;\n }\n .vrt-cmp__stage--split .vrt-cmp__frame { margin: 0; }\n\n figure.vrt-cmp__frame figcaption {\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n }\n\n /* A checkerboard makes transparent regions of a PNG legible. */\n .vrt-cmp__shot {\n position: relative;\n border: 1px solid var(--prism-border);\n border-radius: var(--radius-sm);\n overflow: hidden;\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 12px 12px;\n background-position: 0 0, 0 6px, 6px -6px, -6px 0;\n }\n\n .vrt-cmp__img {\n display: block;\n width: 100%;\n height: auto;\n /* Zooming a diff is only useful if the pixels stay pixels. */\n image-rendering: pixelated;\n }\n\n .vrt-cmp__wipe-top { position: absolute; inset: 0; }\n .vrt-cmp__wipe-handle {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n margin-left: -1px;\n background: var(--prism-primary);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--prism-void) 45%, transparent);\n pointer-events: none;\n }\n\n .vrt-cmp__slider {\n width: 100%;\n margin: 0;\n appearance: none;\n background: none;\n cursor: ew-resize;\n }\n .vrt-cmp__slider::-webkit-slider-runnable-track {\n height: 4px;\n border-radius: 2px;\n background: var(--prism-input-bg);\n }\n .vrt-cmp__slider::-moz-range-track {\n height: 4px;\n border-radius: 2px;\n background: var(--prism-input-bg);\n }\n .vrt-cmp__slider::-webkit-slider-thumb {\n appearance: none;\n width: 13px;\n height: 13px;\n margin-top: -4.5px;\n border-radius: 50%;\n background: var(--prism-primary);\n border: 2px solid var(--prism-bg-elevated);\n box-shadow: 0 0 0 1px var(--prism-border-strong);\n }\n .vrt-cmp__slider::-moz-range-thumb {\n width: 13px;\n height: 13px;\n border-radius: 50%;\n background: var(--prism-primary);\n border: 2px solid var(--prism-bg-elevated);\n box-shadow: 0 0 0 1px var(--prism-border-strong);\n }\n\n .vrt-cmp__legend {\n display: flex;\n justify-content: space-between;\n font-size: var(--fs-sm);\n color: var(--prism-text-muted);\n }\n\n .vrt-cmp__note {\n display: flex;\n flex-direction: column;\n gap: 3px;\n padding: 10px 12px;\n background: var(--prism-bg-surface);\n border: 1px solid var(--prism-border);\n border-left: 3px solid var(--prism-text-muted);\n border-radius: var(--radius-md);\n font-size: var(--fs-md);\n }\n .vrt-cmp__note b { font-weight: 600; color: var(--prism-text); }\n .vrt-cmp__note span { color: var(--prism-text-muted); }\n .vrt-cmp__note--warn { border-left-color: var(--prism-warn); }\n /* Matches the panel shell's own inline code, so a background name reads\n the same wherever it appears. */\n .vrt-cmp__note code {\n font-family: var(--font-mono);\n font-size: var(--fs-sm);\n padding: 1px 5px;\n border-radius: var(--radius-xs);\n background: var(--prism-input-bg);\n }\n "] }]
601
+ }], null, { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: true }] }], assetBaseUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "assetBaseUrl", required: false }] }] }); })();
602
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VrtCompareComponent, { className: "VrtCompareComponent", filePath: "vrt-compare.component.ts", lineNumber: 430 }); })();