@treelocator/runtime 0.3.2 → 0.4.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/browserApi.d.ts +45 -0
- package/dist/browserApi.js +23 -1
- package/dist/components/RecordingOutline.d.ts +5 -0
- package/dist/components/RecordingOutline.js +53 -0
- package/dist/components/RecordingResults.d.ts +25 -0
- package/dist/components/RecordingResults.js +272 -0
- package/dist/components/Runtime.js +505 -70
- package/dist/dejitter/recorder.d.ts +91 -0
- package/dist/dejitter/recorder.js +904 -0
- package/dist/functions/enrichAncestrySourceMaps.js +9 -2
- package/dist/output.css +13 -0
- package/package.json +2 -2
- package/src/browserApi.ts +74 -1
- package/src/components/RecordingOutline.tsx +66 -0
- package/src/components/RecordingResults.tsx +287 -0
- package/src/components/Runtime.tsx +534 -80
- package/src/dejitter/recorder.ts +934 -0
- package/src/functions/enrichAncestrySourceMaps.ts +9 -2
- package/.turbo/turbo-build.log +0 -32
- package/.turbo/turbo-dev.log +0 -32
- package/.turbo/turbo-test.log +0 -14
- package/.turbo/turbo-ts.log +0 -4
- package/LICENSE +0 -22
package/dist/browserApi.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { AdapterId } from "./consts";
|
|
2
2
|
import { AncestryItem } from "./functions/formatAncestryChain";
|
|
3
|
+
import type { DejitterFinding, DejitterSummary } from "./dejitter/recorder";
|
|
4
|
+
import type { InteractionEvent } from "./components/RecordingResults";
|
|
3
5
|
export interface LocatorJSAPI {
|
|
4
6
|
/**
|
|
5
7
|
* Get formatted ancestry path for an element.
|
|
@@ -98,6 +100,49 @@ export interface LocatorJSAPI {
|
|
|
98
100
|
* console.log(help);
|
|
99
101
|
*/
|
|
100
102
|
help(): string;
|
|
103
|
+
/**
|
|
104
|
+
* Replay the last recorded interaction sequence.
|
|
105
|
+
* Dispatches the recorded clicks at the original positions and timing.
|
|
106
|
+
* Must have a completed recording with interactions to replay.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* // In browser console
|
|
110
|
+
* window.__treelocator__.replay();
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* // In Playwright
|
|
114
|
+
* await page.evaluate(() => window.__treelocator__.replay());
|
|
115
|
+
*/
|
|
116
|
+
replay(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Replay the last recorded interaction sequence while recording an element's property changes.
|
|
119
|
+
* Combines replay and dejitter recording: plays back stored clicks at original timing while
|
|
120
|
+
* tracking visual changes (opacity, transform, position, size) on the target element.
|
|
121
|
+
* Returns the dejitter analysis results when replay completes.
|
|
122
|
+
*
|
|
123
|
+
* @param elementOrSelector - HTMLElement or CSS selector for the element to record during replay
|
|
124
|
+
* @returns Promise resolving to recording results with findings, summary, and interaction log
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* // Record the sliding panel while replaying user clicks
|
|
128
|
+
* const results = await window.__treelocator__.replayWithRecord('[data-locatorjs-id="SlidingPanel"]');
|
|
129
|
+
* console.log(results.findings); // anomaly analysis
|
|
130
|
+
* console.log(results.path); // component ancestry
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* // In Playwright - automated regression test
|
|
134
|
+
* const results = await page.evaluate(async () => {
|
|
135
|
+
* return await window.__treelocator__.replayWithRecord('.my-panel');
|
|
136
|
+
* });
|
|
137
|
+
* expect(results.findings.filter(f => f.severity === 'high')).toHaveLength(0);
|
|
138
|
+
*/
|
|
139
|
+
replayWithRecord(elementOrSelector: HTMLElement | string): Promise<{
|
|
140
|
+
path: string;
|
|
141
|
+
findings: DejitterFinding[];
|
|
142
|
+
summary: DejitterSummary | null;
|
|
143
|
+
data: any;
|
|
144
|
+
interactions: InteractionEvent[];
|
|
145
|
+
} | null>;
|
|
101
146
|
}
|
|
102
147
|
export declare function createBrowserAPI(adapterIdParam?: AdapterId): LocatorJSAPI;
|
|
103
148
|
export declare function installBrowserAPI(adapterIdParam?: AdapterId): void;
|
package/dist/browserApi.js
CHANGED
|
@@ -63,7 +63,22 @@ METHODS:
|
|
|
63
63
|
console.log(data.path) // formatted string
|
|
64
64
|
console.log(data.ancestry) // structured array
|
|
65
65
|
|
|
66
|
-
4.
|
|
66
|
+
4. replay()
|
|
67
|
+
Replays the last recorded interaction sequence as a macro.
|
|
68
|
+
|
|
69
|
+
Usage:
|
|
70
|
+
window.__treelocator__.replay()
|
|
71
|
+
|
|
72
|
+
5. replayWithRecord(elementOrSelector)
|
|
73
|
+
Replays stored interactions while recording element changes.
|
|
74
|
+
Returns dejitter analysis when replay completes.
|
|
75
|
+
|
|
76
|
+
Usage:
|
|
77
|
+
const results = await window.__treelocator__.replayWithRecord('[data-locatorjs-id="SlidingPanel"]')
|
|
78
|
+
console.log(results.findings) // anomaly analysis
|
|
79
|
+
console.log(results.path) // component ancestry
|
|
80
|
+
|
|
81
|
+
6. help()
|
|
67
82
|
Displays this help message.
|
|
68
83
|
|
|
69
84
|
PLAYWRIGHT EXAMPLES:
|
|
@@ -148,6 +163,13 @@ export function createBrowserAPI(adapterIdParam) {
|
|
|
148
163
|
},
|
|
149
164
|
help() {
|
|
150
165
|
return HELP_TEXT;
|
|
166
|
+
},
|
|
167
|
+
replay() {
|
|
168
|
+
// Replaced by Runtime component once mounted
|
|
169
|
+
},
|
|
170
|
+
replayWithRecord() {
|
|
171
|
+
// Replaced by Runtime component once mounted
|
|
172
|
+
return Promise.resolve(null);
|
|
151
173
|
}
|
|
152
174
|
};
|
|
153
175
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { template as _$template } from "solid-js/web";
|
|
2
|
+
import { effect as _$effect } from "solid-js/web";
|
|
3
|
+
import { setStyleProperty as _$setStyleProperty } from "solid-js/web";
|
|
4
|
+
var _tmpl$ = /*#__PURE__*/_$template(`<div style=z-index:2;border-radius:2px;pointer-events:none><div style="align-items:center;border-radius:4px;font-size:10px;font-family:system-ui, sans-serif;font-weight:600;letter-spacing:0.5px;white-space:nowrap"><div style=border-radius:50%></div>REC`);
|
|
5
|
+
import { createSignal, onCleanup, onMount } from "solid-js";
|
|
6
|
+
export function RecordingOutline(props) {
|
|
7
|
+
const [box, setBox] = createSignal(props.element.getBoundingClientRect());
|
|
8
|
+
let rafId;
|
|
9
|
+
const updateBox = () => {
|
|
10
|
+
setBox(props.element.getBoundingClientRect());
|
|
11
|
+
rafId = requestAnimationFrame(updateBox);
|
|
12
|
+
};
|
|
13
|
+
onMount(() => {
|
|
14
|
+
rafId = requestAnimationFrame(updateBox);
|
|
15
|
+
});
|
|
16
|
+
onCleanup(() => cancelAnimationFrame(rafId));
|
|
17
|
+
return (() => {
|
|
18
|
+
var _el$ = _tmpl$(),
|
|
19
|
+
_el$2 = _el$.firstChild,
|
|
20
|
+
_el$3 = _el$2.firstChild;
|
|
21
|
+
_$setStyleProperty(_el$, "position", "fixed");
|
|
22
|
+
_$setStyleProperty(_el$, "border", "2px dashed #ef4444");
|
|
23
|
+
_$setStyleProperty(_el$2, "position", "absolute");
|
|
24
|
+
_$setStyleProperty(_el$2, "top", "-22px");
|
|
25
|
+
_$setStyleProperty(_el$2, "left", "4px");
|
|
26
|
+
_$setStyleProperty(_el$2, "display", "flex");
|
|
27
|
+
_$setStyleProperty(_el$2, "gap", "4px");
|
|
28
|
+
_$setStyleProperty(_el$2, "padding", "2px 8px");
|
|
29
|
+
_$setStyleProperty(_el$2, "background", "rgba(239, 68, 68, 0.9)");
|
|
30
|
+
_$setStyleProperty(_el$2, "color", "#fff");
|
|
31
|
+
_$setStyleProperty(_el$3, "width", "6px");
|
|
32
|
+
_$setStyleProperty(_el$3, "height", "6px");
|
|
33
|
+
_$setStyleProperty(_el$3, "background", "#fff");
|
|
34
|
+
_$setStyleProperty(_el$3, "animation", "treelocator-rec-pulse 1s ease-in-out infinite");
|
|
35
|
+
_$effect(_p$ => {
|
|
36
|
+
var _v$ = box().x + "px",
|
|
37
|
+
_v$2 = box().y + "px",
|
|
38
|
+
_v$3 = box().width + "px",
|
|
39
|
+
_v$4 = box().height + "px";
|
|
40
|
+
_v$ !== _p$.e && _$setStyleProperty(_el$, "left", _p$.e = _v$);
|
|
41
|
+
_v$2 !== _p$.t && _$setStyleProperty(_el$, "top", _p$.t = _v$2);
|
|
42
|
+
_v$3 !== _p$.a && _$setStyleProperty(_el$, "width", _p$.a = _v$3);
|
|
43
|
+
_v$4 !== _p$.o && _$setStyleProperty(_el$, "height", _p$.o = _v$4);
|
|
44
|
+
return _p$;
|
|
45
|
+
}, {
|
|
46
|
+
e: undefined,
|
|
47
|
+
t: undefined,
|
|
48
|
+
a: undefined,
|
|
49
|
+
o: undefined
|
|
50
|
+
});
|
|
51
|
+
return _el$;
|
|
52
|
+
})();
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DejitterFinding, DejitterSummary } from "../dejitter/recorder";
|
|
2
|
+
export type InteractionEvent = {
|
|
3
|
+
t: number;
|
|
4
|
+
type: string;
|
|
5
|
+
target: string;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
};
|
|
9
|
+
type RecordingResultsProps = {
|
|
10
|
+
findings: DejitterFinding[];
|
|
11
|
+
summary: DejitterSummary | null;
|
|
12
|
+
data: any;
|
|
13
|
+
elementPath: string;
|
|
14
|
+
interactions: InteractionEvent[];
|
|
15
|
+
onDismiss: () => void;
|
|
16
|
+
onReplay?: () => void;
|
|
17
|
+
replaying?: boolean;
|
|
18
|
+
onToast?: (msg: string) => void;
|
|
19
|
+
hasPrevious?: boolean;
|
|
20
|
+
onLoadPrevious?: () => void;
|
|
21
|
+
hasNext?: boolean;
|
|
22
|
+
onLoadNext?: () => void;
|
|
23
|
+
};
|
|
24
|
+
export declare function RecordingResults(props: RecordingResultsProps): import("solid-js").JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { template as _$template } from "solid-js/web";
|
|
2
|
+
import { delegateEvents as _$delegateEvents } from "solid-js/web";
|
|
3
|
+
import { style as _$style } from "solid-js/web";
|
|
4
|
+
import { effect as _$effect } from "solid-js/web";
|
|
5
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
6
|
+
import { addEventListener as _$addEventListener } from "solid-js/web";
|
|
7
|
+
import { memo as _$memo } from "solid-js/web";
|
|
8
|
+
import { insert as _$insert } from "solid-js/web";
|
|
9
|
+
import { setStyleProperty as _$setStyleProperty } from "solid-js/web";
|
|
10
|
+
var _tmpl$ = /*#__PURE__*/_$template(`<div style=margin-bottom:4px;font-size:11px;text-transform:uppercase;letter-spacing:0.5px>Findings (<!>)`),
|
|
11
|
+
_tmpl$2 = /*#__PURE__*/_$template(`<div style="border-top:1px solid rgba(255, 255, 255, 0.08)"><div style=margin-bottom:4px;font-size:11px;text-transform:uppercase;letter-spacing:0.5px>Interactions (<!>)`),
|
|
12
|
+
_tmpl$3 = /*#__PURE__*/_$template(`<div style="z-index:2147483646;max-height:400px;overflow-y:auto;backdrop-filter:blur(12px);border-radius:12px;box-shadow:0 8px 32px rgba(0, 0, 0, 0.4);font-family:system-ui, -apple-system, sans-serif;font-size:12px;pointer-events:auto"><div style="align-items:center;justify-content:space-between;border-bottom:1px solid rgba(255, 255, 255, 0.08)"><div><div style=font-weight:600;font-size:13px>Recording Results</div><div style=margin-top:2px>ms · <!> frames</div></div><div style=align-items:center><div>Copy</div><div style=border-radius:4px;font-size:16px;line-height:1>×</div></div></div><div>`),
|
|
13
|
+
_tmpl$4 = /*#__PURE__*/_$template(`<div>`),
|
|
14
|
+
_tmpl$5 = /*#__PURE__*/_$template(`<div>Prev`),
|
|
15
|
+
_tmpl$6 = /*#__PURE__*/_$template(`<div>Next`),
|
|
16
|
+
_tmpl$7 = /*#__PURE__*/_$template(`<div style=align-items:center><span style=font-size:14px>✓</span>No anomalies detected`),
|
|
17
|
+
_tmpl$8 = /*#__PURE__*/_$template(`<div style="align-items:flex-start;border-bottom:1px solid rgba(255, 255, 255, 0.05)"><div style=border-radius:50%;flex-shrink:0;margin-top:3px></div><div style=min-width:0><div style=align-items:center><span style=font-weight:600></span><span style=font-size:11px></span></div><div style=margin-top:2px;line-height:1.4;word-break:break-word>`),
|
|
18
|
+
_tmpl$9 = /*#__PURE__*/_$template(`<div style=font-family:monospace;font-size:11px><span>ms</span> <span></span> <span>`);
|
|
19
|
+
import { For, Show } from "solid-js";
|
|
20
|
+
const SEVERITY_COLORS = {
|
|
21
|
+
high: "#ef4444",
|
|
22
|
+
medium: "#f59e0b",
|
|
23
|
+
low: "#eab308",
|
|
24
|
+
info: "#9ca3af"
|
|
25
|
+
};
|
|
26
|
+
function formatDataForClipboard(data, elementPath, summary, findings, interactions) {
|
|
27
|
+
const lines = [];
|
|
28
|
+
|
|
29
|
+
// Element ancestry path from treelocator
|
|
30
|
+
if (elementPath) {
|
|
31
|
+
lines.push(`Element: ${elementPath}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Header
|
|
35
|
+
lines.push(`Recording: ${Math.round(summary?.duration ?? 0)}ms, ${summary?.rawFrameCount ?? 0} frames`);
|
|
36
|
+
lines.push('');
|
|
37
|
+
|
|
38
|
+
// Property changes
|
|
39
|
+
if (data?.propStats?.props && data.propStats.props.length > 0) {
|
|
40
|
+
lines.push('Changed properties:');
|
|
41
|
+
for (const p of data.propStats.props) {
|
|
42
|
+
if (p.raw === 0) continue;
|
|
43
|
+
lines.push(` ${p.prop}: ${p.raw} changes (${p.mode})`);
|
|
44
|
+
}
|
|
45
|
+
lines.push('');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Samples with actual values — replace dejitter element IDs with the ancestry path
|
|
49
|
+
if (data?.samples && data.samples.length > 0) {
|
|
50
|
+
lines.push('Timeline:');
|
|
51
|
+
for (const frame of data.samples) {
|
|
52
|
+
for (const change of frame.changes) {
|
|
53
|
+
const {
|
|
54
|
+
id,
|
|
55
|
+
...props
|
|
56
|
+
} = change;
|
|
57
|
+
const propEntries = Object.entries(props);
|
|
58
|
+
if (propEntries.length > 0) {
|
|
59
|
+
const vals = propEntries.map(([k, v]) => `${k}=${v}`).join(', ');
|
|
60
|
+
lines.push(` ${frame.t}ms: ${vals}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
lines.push('');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Findings — replace dejitter element IDs in descriptions
|
|
68
|
+
if (findings.length > 0) {
|
|
69
|
+
lines.push('Anomalies:');
|
|
70
|
+
for (const f of findings) {
|
|
71
|
+
lines.push(` [${f.severity}] ${f.type}: ${f.description}`);
|
|
72
|
+
}
|
|
73
|
+
lines.push('');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Interactions
|
|
77
|
+
if (interactions.length > 0) {
|
|
78
|
+
lines.push('User interactions:');
|
|
79
|
+
for (const evt of interactions) {
|
|
80
|
+
lines.push(` ${evt.t}ms ${evt.type} ${evt.target} (${evt.x},${evt.y})`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return lines.join('\n');
|
|
84
|
+
}
|
|
85
|
+
const buttonStyle = active => ({
|
|
86
|
+
cursor: "pointer",
|
|
87
|
+
padding: "4px 10px",
|
|
88
|
+
"border-radius": "4px",
|
|
89
|
+
background: active ? "rgba(59, 130, 246, 0.2)" : "rgba(255, 255, 255, 0.08)",
|
|
90
|
+
color: active ? "#60a5fa" : "#9ca3af",
|
|
91
|
+
"font-size": "11px",
|
|
92
|
+
"font-weight": "600",
|
|
93
|
+
"line-height": "1.4",
|
|
94
|
+
transition: "background 0.15s, color 0.15s"
|
|
95
|
+
});
|
|
96
|
+
export function RecordingResults(props) {
|
|
97
|
+
const duration = () => props.summary?.duration ?? 0;
|
|
98
|
+
const frameCount = () => props.summary?.rawFrameCount ?? 0;
|
|
99
|
+
function handleCopy() {
|
|
100
|
+
const text = formatDataForClipboard(props.data, props.elementPath, props.summary, props.findings, props.interactions);
|
|
101
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
102
|
+
props.onToast?.("Copied to clipboard");
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return (() => {
|
|
106
|
+
var _el$ = _tmpl$3(),
|
|
107
|
+
_el$2 = _el$.firstChild,
|
|
108
|
+
_el$3 = _el$2.firstChild,
|
|
109
|
+
_el$4 = _el$3.firstChild,
|
|
110
|
+
_el$5 = _el$4.nextSibling,
|
|
111
|
+
_el$6 = _el$5.firstChild,
|
|
112
|
+
_el$8 = _el$6.nextSibling,
|
|
113
|
+
_el$7 = _el$8.nextSibling,
|
|
114
|
+
_el$9 = _el$3.nextSibling,
|
|
115
|
+
_el$0 = _el$9.firstChild,
|
|
116
|
+
_el$1 = _el$0.nextSibling,
|
|
117
|
+
_el$10 = _el$2.nextSibling;
|
|
118
|
+
_$setStyleProperty(_el$, "position", "fixed");
|
|
119
|
+
_$setStyleProperty(_el$, "bottom", "84px");
|
|
120
|
+
_$setStyleProperty(_el$, "right", "20px");
|
|
121
|
+
_$setStyleProperty(_el$, "width", "340px");
|
|
122
|
+
_$setStyleProperty(_el$, "background", "rgba(15, 15, 15, 0.92)");
|
|
123
|
+
_$setStyleProperty(_el$, "border", "1px solid rgba(255, 255, 255, 0.1)");
|
|
124
|
+
_$setStyleProperty(_el$, "color", "#e5e5e5");
|
|
125
|
+
_$setStyleProperty(_el$2, "display", "flex");
|
|
126
|
+
_$setStyleProperty(_el$2, "padding", "12px 14px 8px");
|
|
127
|
+
_$setStyleProperty(_el$4, "color", "#fff");
|
|
128
|
+
_$setStyleProperty(_el$5, "color", "#9ca3af");
|
|
129
|
+
_$insert(_el$5, () => Math.round(duration()), _el$6);
|
|
130
|
+
_$insert(_el$5, frameCount, _el$8);
|
|
131
|
+
_$setStyleProperty(_el$9, "display", "flex");
|
|
132
|
+
_$setStyleProperty(_el$9, "gap", "4px");
|
|
133
|
+
_el$0.$$click = handleCopy;
|
|
134
|
+
_$insert(_el$9, (() => {
|
|
135
|
+
var _c$ = _$memo(() => !!props.onReplay);
|
|
136
|
+
return () => _c$() && (() => {
|
|
137
|
+
var _el$20 = _tmpl$4();
|
|
138
|
+
_$addEventListener(_el$20, "click", props.onReplay, true);
|
|
139
|
+
_$insert(_el$20, () => props.replaying ? "Replaying..." : "Replay");
|
|
140
|
+
_$effect(_$p => _$style(_el$20, buttonStyle(props.replaying), _$p));
|
|
141
|
+
return _el$20;
|
|
142
|
+
})();
|
|
143
|
+
})(), _el$1);
|
|
144
|
+
_$insert(_el$9, (() => {
|
|
145
|
+
var _c$2 = _$memo(() => !!(props.hasPrevious && props.onLoadPrevious));
|
|
146
|
+
return () => _c$2() && (() => {
|
|
147
|
+
var _el$21 = _tmpl$5();
|
|
148
|
+
_$addEventListener(_el$21, "click", props.onLoadPrevious, true);
|
|
149
|
+
_$effect(_$p => _$style(_el$21, buttonStyle(), _$p));
|
|
150
|
+
return _el$21;
|
|
151
|
+
})();
|
|
152
|
+
})(), _el$1);
|
|
153
|
+
_$insert(_el$9, (() => {
|
|
154
|
+
var _c$3 = _$memo(() => !!(props.hasNext && props.onLoadNext));
|
|
155
|
+
return () => _c$3() && (() => {
|
|
156
|
+
var _el$22 = _tmpl$6();
|
|
157
|
+
_$addEventListener(_el$22, "click", props.onLoadNext, true);
|
|
158
|
+
_$effect(_$p => _$style(_el$22, buttonStyle(), _$p));
|
|
159
|
+
return _el$22;
|
|
160
|
+
})();
|
|
161
|
+
})(), _el$1);
|
|
162
|
+
_$addEventListener(_el$1, "click", props.onDismiss, true);
|
|
163
|
+
_$setStyleProperty(_el$1, "cursor", "pointer");
|
|
164
|
+
_$setStyleProperty(_el$1, "padding", "4px 8px");
|
|
165
|
+
_$setStyleProperty(_el$1, "color", "#9ca3af");
|
|
166
|
+
_$setStyleProperty(_el$10, "padding", "8px 14px");
|
|
167
|
+
_$insert(_el$10, _$createComponent(Show, {
|
|
168
|
+
get when() {
|
|
169
|
+
return props.findings.length > 0;
|
|
170
|
+
},
|
|
171
|
+
get fallback() {
|
|
172
|
+
return (() => {
|
|
173
|
+
var _el$23 = _tmpl$7(),
|
|
174
|
+
_el$24 = _el$23.firstChild;
|
|
175
|
+
_$setStyleProperty(_el$23, "display", "flex");
|
|
176
|
+
_$setStyleProperty(_el$23, "gap", "6px");
|
|
177
|
+
_$setStyleProperty(_el$23, "padding", "8px 0");
|
|
178
|
+
_$setStyleProperty(_el$23, "color", "#4ade80");
|
|
179
|
+
return _el$23;
|
|
180
|
+
})();
|
|
181
|
+
},
|
|
182
|
+
get children() {
|
|
183
|
+
return [(() => {
|
|
184
|
+
var _el$11 = _tmpl$(),
|
|
185
|
+
_el$12 = _el$11.firstChild,
|
|
186
|
+
_el$14 = _el$12.nextSibling,
|
|
187
|
+
_el$13 = _el$14.nextSibling;
|
|
188
|
+
_$setStyleProperty(_el$11, "color", "#9ca3af");
|
|
189
|
+
_$insert(_el$11, () => props.findings.length, _el$14);
|
|
190
|
+
return _el$11;
|
|
191
|
+
})(), _$createComponent(For, {
|
|
192
|
+
get each() {
|
|
193
|
+
return props.findings;
|
|
194
|
+
},
|
|
195
|
+
children: finding => (() => {
|
|
196
|
+
var _el$25 = _tmpl$8(),
|
|
197
|
+
_el$26 = _el$25.firstChild,
|
|
198
|
+
_el$27 = _el$26.nextSibling,
|
|
199
|
+
_el$28 = _el$27.firstChild,
|
|
200
|
+
_el$29 = _el$28.firstChild,
|
|
201
|
+
_el$30 = _el$29.nextSibling,
|
|
202
|
+
_el$31 = _el$28.nextSibling;
|
|
203
|
+
_$setStyleProperty(_el$25, "display", "flex");
|
|
204
|
+
_$setStyleProperty(_el$25, "gap", "8px");
|
|
205
|
+
_$setStyleProperty(_el$25, "padding", "6px 0");
|
|
206
|
+
_$setStyleProperty(_el$26, "width", "8px");
|
|
207
|
+
_$setStyleProperty(_el$26, "height", "8px");
|
|
208
|
+
_$setStyleProperty(_el$28, "display", "flex");
|
|
209
|
+
_$setStyleProperty(_el$28, "gap", "6px");
|
|
210
|
+
_$setStyleProperty(_el$29, "color", "#fff");
|
|
211
|
+
_$insert(_el$29, () => finding.type);
|
|
212
|
+
_$insert(_el$30, () => finding.severity);
|
|
213
|
+
_$setStyleProperty(_el$31, "color", "#a1a1aa");
|
|
214
|
+
_$insert(_el$31, () => finding.description);
|
|
215
|
+
_$effect(_p$ => {
|
|
216
|
+
var _v$ = SEVERITY_COLORS[finding.severity] || "#9ca3af",
|
|
217
|
+
_v$2 = SEVERITY_COLORS[finding.severity];
|
|
218
|
+
_v$ !== _p$.e && _$setStyleProperty(_el$26, "background", _p$.e = _v$);
|
|
219
|
+
_v$2 !== _p$.t && _$setStyleProperty(_el$30, "color", _p$.t = _v$2);
|
|
220
|
+
return _p$;
|
|
221
|
+
}, {
|
|
222
|
+
e: undefined,
|
|
223
|
+
t: undefined
|
|
224
|
+
});
|
|
225
|
+
return _el$25;
|
|
226
|
+
})()
|
|
227
|
+
})];
|
|
228
|
+
}
|
|
229
|
+
}));
|
|
230
|
+
_$insert(_el$, _$createComponent(Show, {
|
|
231
|
+
get when() {
|
|
232
|
+
return props.interactions.length > 0;
|
|
233
|
+
},
|
|
234
|
+
get children() {
|
|
235
|
+
var _el$15 = _tmpl$2(),
|
|
236
|
+
_el$16 = _el$15.firstChild,
|
|
237
|
+
_el$17 = _el$16.firstChild,
|
|
238
|
+
_el$19 = _el$17.nextSibling,
|
|
239
|
+
_el$18 = _el$19.nextSibling;
|
|
240
|
+
_$setStyleProperty(_el$15, "padding", "8px 14px 12px");
|
|
241
|
+
_$setStyleProperty(_el$16, "color", "#9ca3af");
|
|
242
|
+
_$insert(_el$16, () => props.interactions.length, _el$19);
|
|
243
|
+
_$insert(_el$15, _$createComponent(For, {
|
|
244
|
+
get each() {
|
|
245
|
+
return props.interactions;
|
|
246
|
+
},
|
|
247
|
+
children: evt => (() => {
|
|
248
|
+
var _el$32 = _tmpl$9(),
|
|
249
|
+
_el$33 = _el$32.firstChild,
|
|
250
|
+
_el$34 = _el$33.firstChild,
|
|
251
|
+
_el$35 = _el$33.nextSibling,
|
|
252
|
+
_el$36 = _el$35.nextSibling,
|
|
253
|
+
_el$37 = _el$36.nextSibling,
|
|
254
|
+
_el$38 = _el$37.nextSibling;
|
|
255
|
+
_$setStyleProperty(_el$32, "padding", "3px 0");
|
|
256
|
+
_$setStyleProperty(_el$32, "color", "#a1a1aa");
|
|
257
|
+
_$setStyleProperty(_el$33, "color", "#9ca3af");
|
|
258
|
+
_$insert(_el$33, () => evt.t, _el$34);
|
|
259
|
+
_$setStyleProperty(_el$36, "color", "#60a5fa");
|
|
260
|
+
_$insert(_el$36, () => evt.type);
|
|
261
|
+
_$insert(_el$38, () => evt.target);
|
|
262
|
+
return _el$32;
|
|
263
|
+
})()
|
|
264
|
+
}), null);
|
|
265
|
+
return _el$15;
|
|
266
|
+
}
|
|
267
|
+
}), null);
|
|
268
|
+
_$effect(_$p => _$style(_el$0, buttonStyle(), _$p));
|
|
269
|
+
return _el$;
|
|
270
|
+
})();
|
|
271
|
+
}
|
|
272
|
+
_$delegateEvents(["click"]);
|