@flemo/devtools 0.2.1 → 0.3.0
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/README.md +7 -9
- package/dist/__tests__/domProtocol.test.d.ts +1 -0
- package/dist/__tests__/overridesRegistry.test.d.ts +1 -0
- package/dist/anomalies.d.ts +0 -4
- package/dist/domProtocol.d.ts +22 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +424 -390
- package/dist/noop.d.ts +1 -1
- package/dist/noop.mjs +147 -100
- package/dist/overrides.d.ts +39 -7
- package/dist/types.d.ts +0 -14
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -11,7 +11,7 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
11
11
|
return d.holdReassertedAtMs !== null && n.push(`hold re-asserted ${d.holdReassertedAtMs}ms into the flight, after it had already released (an interleaved commit wrote the stale paused hold attribute over a running flight — the flemo 2026-08-18 release-race signature; the motion pauses while every timing metric stays clean)`), d.pausedAfterRelease && n.push("compiled animation reported playState=paused after its release (the flight was posed and then stopped mid-motion, not merely starved of frames)"), d.longestStallMs >= 48 && n.push(`motion stalled ${d.longestStallMs}ms mid-flight (${d.stalledFrames}/${d.sampledFrames} released frames advanced neither the animation clock nor the pose — freeze, or freeze-then-leap if the flight still landed on time)`), d.sampledFrames === 0 && e.releasedAtMs !== null && n.push("no released frames were sampled (the flight ended at or before its own hold release — the visible motion, if any, was never observed)"), f.completedUnheld > 0 && n.push(`${f.completedUnheld} image(s) finished loading mid-flight without a hold (${f.completedDuringFlight} completed, ${f.heldDuringFlight} held; ${f.loadingAtStart} were loading at t0, ${f.addedDuringFlight} arrived mid-flight) — each decode rasters on the moving layer and costs a present; this is the warm-side image-hold regression`), l.orphanedHolds.length > 0 && n.push(`hold markers left on the page at rest: ${l.orphanedHolds.join("; ")} (whatever they hide has no owner left to reveal it — the permanently-blank-avatar class)`), l.residualInlineTransforms.length > 0 && n.push(`residual inline style after COMPLETED: ${l.residualInlineTransforms.join("; ")} (landing cleanup failure — the landed scope belongs to the compiled rest rules)`), l.offViewportAtRest && n.push("screen resting at from-pose while COMPLETED+active (blank-viewport signature — the flemo PR #259 class: a residual pose left the landed screen parked off-viewport)"), l.stuckStatuses.length > 0 && n.push(`transitional status stuck >${t / 1e3}s: ${l.stuckStatuses.join(", ")} (navigation queue lock or missed animationend — later navigations will be swallowed)`), i === "unknown" && n.push("driver could not be classified (no running flemo-* CSSAnimation and no player inline-style signature observed — zero-duration flight, or the sampler attached after motion ended)"), n;
|
|
12
12
|
}, o = (e) => {
|
|
13
13
|
let n = [];
|
|
14
|
-
if (e.
|
|
14
|
+
if (e.emulationSuspected) {
|
|
15
15
|
let t = /Win/i.test(e.platform) ? " (Windows touch hardware makes this signal ambiguous — confirm the DevTools device toolbar state)" : "";
|
|
16
16
|
n.push("DevTools device emulation suspected — the page composites to a rescaled surface, so visual reports from this session are untrustworthy; judge motion in a plain window or on a real device" + t);
|
|
17
17
|
}
|
|
@@ -21,24 +21,33 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
21
21
|
"Display-hardware effects: local dimming, backlight modulation, and panel overdrive alter perceived motion and are invisible to every web API.",
|
|
22
22
|
"Compositor-internal present skips: a frame can be produced on time (clean rAF, clean player gaps) yet dropped or delayed inside the compositor's present queue; only platform tools (about:tracing, Instruments) see that layer.",
|
|
23
23
|
"DevTools device emulation composites the page to a rescaled surface: every in-page instrument reads the pre-scale surface and reports clean while the eye watches the post-scale one, so emulated sessions grow shimmer/flash artifacts that do not exist in a plain window or on a real device."
|
|
24
|
-
], c =
|
|
24
|
+
], c = "data-flemo-screen", l = "data-flemo-status", u = "data-flemo-active", d = "data-flemo-anim-hold", f = "data-flemo-img-hold", p = "data-flemo-held-arrival", ee = "data-flemo-part-name", m = "data-flemo-decorator", h = "data-flemo-bar", g = "data-flemo-devtools-panel", _ = [
|
|
25
|
+
"PUSHING",
|
|
26
|
+
"POPPING",
|
|
27
|
+
"REPLACING"
|
|
28
|
+
], v = [
|
|
29
|
+
"true",
|
|
30
|
+
"park",
|
|
31
|
+
"park-under",
|
|
32
|
+
"park-over"
|
|
33
|
+
], y = (e) => `[${e}]`, te = (e, t) => `[${e}="${t}"]`, b = () => {
|
|
25
34
|
if (typeof navigator > "u") return null;
|
|
26
35
|
let e = navigator.userAgentData;
|
|
27
36
|
return !e || !Array.isArray(e.brands) ? null : e.brands.map((e) => ({
|
|
28
37
|
brand: String(e.brand ?? ""),
|
|
29
38
|
version: String(e.version ?? "")
|
|
30
39
|
}));
|
|
31
|
-
},
|
|
40
|
+
}, x = () => {
|
|
32
41
|
if (typeof navigator > "u") return "unknown";
|
|
33
|
-
let e =
|
|
42
|
+
let e = b();
|
|
34
43
|
if (e?.some((e) => /Chromium/i.test(e.brand))) return "blink";
|
|
35
44
|
let t = navigator.userAgent ?? "";
|
|
36
45
|
return /Firefox|FxiOS/i.test(t) ? "gecko" : e || /AppleWebKit/i.test(t) && !/Chrome|Chromium|Android/i.test(t) ? "webkit" : /Android/i.test(t) ? "blink" : "unknown";
|
|
37
|
-
},
|
|
38
|
-
if (typeof navigator > "u" ||
|
|
46
|
+
}, S = () => {
|
|
47
|
+
if (typeof navigator > "u" || x() !== "blink") return !1;
|
|
39
48
|
let e = navigator.platform ?? "";
|
|
40
49
|
return /Mac|Win|Linux/i.test(e) ? /Android/i.test(navigator.userAgent ?? "") && !/Mac|Win/i.test(e) ? /Linux (x86_64|i686)/i.test(e) : (navigator.maxTouchPoints ?? 0) > 0 : !1;
|
|
41
|
-
},
|
|
50
|
+
}, ne = (e = 20) => new Promise((t) => {
|
|
42
51
|
let n = Number.isFinite(e) ? Math.max(1, Math.floor(e)) : 20;
|
|
43
52
|
if (typeof requestAnimationFrame != "function" || typeof performance > "u") {
|
|
44
53
|
t({
|
|
@@ -60,13 +69,13 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
60
69
|
requestAnimationFrame(a);
|
|
61
70
|
};
|
|
62
71
|
requestAnimationFrame(a);
|
|
63
|
-
}),
|
|
72
|
+
}), C = () => {
|
|
64
73
|
try {
|
|
65
74
|
return typeof PerformanceObserver < "u" && Array.isArray(PerformanceObserver.supportedEntryTypes) && PerformanceObserver.supportedEntryTypes.includes("longtask");
|
|
66
75
|
} catch {
|
|
67
76
|
return !1;
|
|
68
77
|
}
|
|
69
|
-
},
|
|
78
|
+
}, w = (e) => {
|
|
70
79
|
let t = typeof navigator < "u" ? navigator : null, n = typeof window < "u" ? window : null, r = !1;
|
|
71
80
|
try {
|
|
72
81
|
r = n?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? !1;
|
|
@@ -75,8 +84,8 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
75
84
|
}
|
|
76
85
|
return {
|
|
77
86
|
userAgent: t?.userAgent ?? "",
|
|
78
|
-
uaBrands:
|
|
79
|
-
engine:
|
|
87
|
+
uaBrands: b(),
|
|
88
|
+
engine: x(),
|
|
80
89
|
platform: t?.platform ?? "",
|
|
81
90
|
maxTouchPoints: t?.maxTouchPoints ?? 0,
|
|
82
91
|
devicePixelRatio: n?.devicePixelRatio ?? 1,
|
|
@@ -91,175 +100,226 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
91
100
|
visualViewportScale: n?.visualViewport?.scale ?? null,
|
|
92
101
|
rafCadence: e,
|
|
93
102
|
reducedMotion: r,
|
|
94
|
-
emulationSuspected:
|
|
103
|
+
emulationSuspected: S(),
|
|
95
104
|
observation: {
|
|
96
|
-
longTasks:
|
|
105
|
+
longTasks: C(),
|
|
97
106
|
elementAnimations: typeof Element < "u" && typeof Element.prototype.getAnimations == "function",
|
|
98
107
|
playerGapMirror: Array.isArray(n?.__flemoPlayerGaps)
|
|
99
108
|
}
|
|
100
109
|
};
|
|
101
|
-
},
|
|
110
|
+
}, T = [
|
|
102
111
|
"DevTools must be CLOSED while judging motion. An open inspector serializes requests and repaints its own panels on the same machine; the 2026-08 campaign's entire residual 'stutter' was this, and it is invisible to every in-page metric.",
|
|
103
112
|
"No screen recording or display capture while judging. A capture client forces WindowServer to composite every vsync, which SUPPRESSES the symptom — a capture that looks smooth proves nothing about the uncaptured session.",
|
|
104
113
|
"Judge with real input (a finger, a mouse). Synthetic dispatch — evaluate().click() and friends — never fires pointerdown, so it bypasses the swipe/gesture machinery that a real navigation goes through.",
|
|
105
114
|
"Establish the viewing configuration before believing any verdict: device emulation off, which physical display, its refresh rate and HiDPI scaling, Low Power Mode. Ask for a photo of the setup if it is not certain."
|
|
106
|
-
],
|
|
115
|
+
], E = "flemo:devtools-panel-height", D = [{
|
|
116
|
+
key: "flemo:devtools",
|
|
117
|
+
storage: "session",
|
|
118
|
+
kind: "opt-in-diagnostic",
|
|
119
|
+
values: "\"on\" / \"off\"",
|
|
120
|
+
fallback: "off",
|
|
121
|
+
effect: "arms this flight recorder in the playground (?devtools=on)"
|
|
122
|
+
}, {
|
|
123
|
+
key: E,
|
|
124
|
+
storage: "session",
|
|
125
|
+
kind: "production-state",
|
|
126
|
+
values: "a pixel height",
|
|
127
|
+
fallback: "(the panel's default height)",
|
|
128
|
+
effect: "the drawer height this panel was last dragged to"
|
|
129
|
+
}], O = [
|
|
107
130
|
{
|
|
108
|
-
key: "flemo:
|
|
109
|
-
storage: "
|
|
131
|
+
key: "flemo:sixty",
|
|
132
|
+
storage: "session",
|
|
110
133
|
kind: "production-state",
|
|
111
|
-
|
|
134
|
+
values: "\"high\" / a streak count",
|
|
135
|
+
fallback: "(learned)",
|
|
136
|
+
effect: "steady-60 desktop verdict seed — owned by steadySixtyCadence.ts"
|
|
112
137
|
},
|
|
113
138
|
{
|
|
114
|
-
key: "flemo:
|
|
139
|
+
key: "flemo:settle-gate",
|
|
115
140
|
storage: "session",
|
|
116
|
-
kind: "
|
|
117
|
-
|
|
141
|
+
kind: "production-default-with-override",
|
|
142
|
+
values: "\"on\" / \"off\"",
|
|
143
|
+
fallback: "touch WebKit + touch Blink + desktop macOS WebKit + steady-60 desktop",
|
|
144
|
+
effect: "render-settle entry gate, shared by the engine's routing and the binding"
|
|
118
145
|
},
|
|
119
146
|
{
|
|
120
|
-
key: "flemo:
|
|
147
|
+
key: "flemo:arrivalhold",
|
|
121
148
|
storage: "session",
|
|
122
|
-
kind: "production-
|
|
123
|
-
|
|
149
|
+
kind: "production-default-with-override",
|
|
150
|
+
values: "\"off\"",
|
|
151
|
+
fallback: "on",
|
|
152
|
+
effect: "the whole in-flight hold set (arrival, response, invisible animations, images)"
|
|
124
153
|
},
|
|
125
154
|
{
|
|
126
|
-
key: "flemo:
|
|
155
|
+
key: "flemo:deskflip",
|
|
127
156
|
storage: "session",
|
|
128
|
-
kind: "production-
|
|
129
|
-
|
|
157
|
+
kind: "production-default-with-override",
|
|
158
|
+
values: "\"on\" / \"off\"",
|
|
159
|
+
fallback: "desktop macOS WebKit",
|
|
160
|
+
effect: "atomic release flip: the hold attribute flips on the DOM inside the readiness rAF"
|
|
130
161
|
},
|
|
131
162
|
{
|
|
132
|
-
key: "flemo:
|
|
163
|
+
key: "flemo:deskhead",
|
|
133
164
|
storage: "session",
|
|
134
|
-
kind: "production-
|
|
135
|
-
|
|
165
|
+
kind: "production-default-with-override",
|
|
166
|
+
values: "\"on\" / \"off\"",
|
|
167
|
+
fallback: "desktop macOS WebKit",
|
|
168
|
+
effect: "desktop flat-head keyframes; arming it retires the desktop birth anchor"
|
|
136
169
|
},
|
|
137
170
|
{
|
|
138
|
-
key: "flemo:
|
|
171
|
+
key: "flemo:creep",
|
|
139
172
|
storage: "session",
|
|
140
|
-
kind: "
|
|
141
|
-
|
|
173
|
+
kind: "production-default-with-override",
|
|
174
|
+
values: "\"on\" / \"off\"",
|
|
175
|
+
fallback: "touch WebKit",
|
|
176
|
+
effect: "creep head: its end keyframe carries a hair of motion, so the compositor is already carrying the animation at the boundary"
|
|
142
177
|
},
|
|
143
178
|
{
|
|
144
|
-
key: "flemo:
|
|
179
|
+
key: "flemo:relcommit",
|
|
145
180
|
storage: "session",
|
|
146
|
-
kind: "
|
|
147
|
-
|
|
181
|
+
kind: "production-default-with-override",
|
|
182
|
+
values: "\"defer\" / \"sync\"",
|
|
183
|
+
fallback: "touch WebKit",
|
|
184
|
+
effect: "the release's reconcile lands next frame instead of synchronously"
|
|
148
185
|
},
|
|
149
186
|
{
|
|
150
|
-
key: "flemo:
|
|
187
|
+
key: "flemo:imgoffload",
|
|
151
188
|
storage: "session",
|
|
152
189
|
kind: "production-default-with-override",
|
|
153
|
-
|
|
190
|
+
values: "\"on\" / \"off\"",
|
|
191
|
+
fallback: "on — the offloader decides per image, from the source's own size",
|
|
192
|
+
effect: "image decode offloader: an oversized source is fetched and downscaled in a worker so its decode never lands in a paint"
|
|
154
193
|
},
|
|
155
194
|
{
|
|
156
|
-
key: "flemo:
|
|
195
|
+
key: "flemo:governed",
|
|
157
196
|
storage: "session",
|
|
158
|
-
kind: "
|
|
159
|
-
|
|
197
|
+
kind: "production-default-with-override",
|
|
198
|
+
values: "\"on\" / \"off\"",
|
|
199
|
+
fallback: "legacy Android Blink (an old browser, not a slow device)",
|
|
200
|
+
effect: "the governed head kit on touch Blink — a flat head covering a compiled flight's opening. The auto-detection reads browser AGE, so a modern-but-weak phone falls through it; this is how such a device gets measured"
|
|
160
201
|
},
|
|
161
202
|
{
|
|
162
|
-
key: "flemo:
|
|
203
|
+
key: "flemo:imghold",
|
|
163
204
|
storage: "session",
|
|
164
205
|
kind: "opt-in-diagnostic",
|
|
165
|
-
|
|
206
|
+
values: "\"on\" / \"off\"",
|
|
207
|
+
fallback: "off",
|
|
208
|
+
effect: "flight-scoped <img> reveal hold"
|
|
166
209
|
},
|
|
167
210
|
{
|
|
168
|
-
key: "flemo:
|
|
211
|
+
key: "flemo:preraster",
|
|
169
212
|
storage: "session",
|
|
170
213
|
kind: "opt-in-diagnostic",
|
|
171
|
-
|
|
214
|
+
values: "\"on\"",
|
|
215
|
+
fallback: "off",
|
|
216
|
+
effect: "REST-time scope promotion, and the park-over hold variant. Flight-time promotion is the engine's own stamp and needs no flag"
|
|
172
217
|
},
|
|
173
218
|
{
|
|
174
|
-
key: "flemo:
|
|
219
|
+
key: "flemo:layers",
|
|
175
220
|
storage: "session",
|
|
176
|
-
kind: "
|
|
177
|
-
|
|
221
|
+
kind: "opt-in-diagnostic",
|
|
222
|
+
values: "\"resident\" / \"off\"",
|
|
223
|
+
fallback: "off",
|
|
224
|
+
effect: "keep screen layers resident at rest — a resident layer is a PERMANENT stacking context over the consumer's screen"
|
|
178
225
|
},
|
|
179
226
|
{
|
|
180
|
-
key: "flemo:
|
|
227
|
+
key: "flemo:freeze",
|
|
181
228
|
storage: "session",
|
|
182
229
|
kind: "opt-in-diagnostic",
|
|
183
|
-
|
|
230
|
+
values: "\"shallow\"",
|
|
231
|
+
fallback: "off",
|
|
232
|
+
effect: "keep the direct prev screen live instead of freezing it"
|
|
233
|
+
}
|
|
234
|
+
], k = [...O, ...D], A = [
|
|
235
|
+
{
|
|
236
|
+
key: "flemo:motion-driver",
|
|
237
|
+
storage: "local",
|
|
238
|
+
retiredWith: "the per-origin driver demotion ledger (2026-08-19)"
|
|
184
239
|
},
|
|
185
240
|
{
|
|
186
|
-
key: "flemo:
|
|
241
|
+
key: "flemo:motion-driver-force",
|
|
187
242
|
storage: "session",
|
|
188
|
-
|
|
189
|
-
description: "resident screen layers at rest"
|
|
243
|
+
retiredWith: "the hard driver pin, with the rAF player (2026-08-22)"
|
|
190
244
|
},
|
|
191
245
|
{
|
|
192
|
-
key: "flemo:
|
|
246
|
+
key: "flemo:landing-snap",
|
|
193
247
|
storage: "session",
|
|
194
|
-
|
|
195
|
-
description: "keep the direct prev screen live"
|
|
248
|
+
retiredWith: "the integer-device-pixel landing snap, falsified on device (2026-08-22)"
|
|
196
249
|
},
|
|
197
250
|
{
|
|
198
|
-
key: "flemo:
|
|
251
|
+
key: "flemo:handoff",
|
|
199
252
|
storage: "session",
|
|
200
|
-
|
|
201
|
-
description: "promote the entering content layer through the hold"
|
|
253
|
+
retiredWith: "the player's anchored-opening handoff (2026-08-22)"
|
|
202
254
|
},
|
|
203
255
|
{
|
|
204
|
-
key: "flemo:
|
|
256
|
+
key: "flemo:handoffms",
|
|
205
257
|
storage: "session",
|
|
206
|
-
|
|
207
|
-
description: "image decode offloader override"
|
|
258
|
+
retiredWith: "the player's anchored-opening handoff (2026-08-22)"
|
|
208
259
|
},
|
|
209
260
|
{
|
|
210
|
-
key: "flemo:
|
|
261
|
+
key: "flemo:apply",
|
|
211
262
|
storage: "session",
|
|
212
|
-
|
|
213
|
-
|
|
263
|
+
retiredWith: "the scrub-WAAPI value-application tier (2026-08-22)"
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
key: "flemo:snap",
|
|
267
|
+
storage: "session",
|
|
268
|
+
retiredWith: "the player's device-pixel snap policy (2026-08-22)"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
key: "flemo:snapband",
|
|
272
|
+
storage: "session",
|
|
273
|
+
retiredWith: "the player's device-pixel snap policy (2026-08-22)"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
key: "flemo:lat",
|
|
277
|
+
storage: "session",
|
|
278
|
+
retiredWith: "the Low Power Mode release-latency probe (2026-08-22)"
|
|
214
279
|
}
|
|
215
|
-
],
|
|
280
|
+
], j = "(retired — the library no longer reads this)", M = (e) => {
|
|
216
281
|
try {
|
|
217
282
|
let t = e === "session" ? sessionStorage : localStorage;
|
|
218
283
|
return t.length, t;
|
|
219
284
|
} catch {
|
|
220
285
|
return null;
|
|
221
286
|
}
|
|
222
|
-
},
|
|
287
|
+
}, N = (e, t) => {
|
|
223
288
|
try {
|
|
224
289
|
return e ? e.getItem(t) : null;
|
|
225
290
|
} catch {
|
|
226
291
|
return null;
|
|
227
292
|
}
|
|
228
|
-
},
|
|
229
|
-
let e = {}, t =
|
|
230
|
-
for (let r of
|
|
231
|
-
let i =
|
|
293
|
+
}, re = new Set(k.map((e) => e.key)), ie = new Set(A.map((e) => e.key)), P = new Set(D.map((e) => e.key)), F = () => {
|
|
294
|
+
let e = {}, t = M("session"), n = M("local");
|
|
295
|
+
for (let r of k) {
|
|
296
|
+
let i = N(r.storage === "session" ? t : n, r.key);
|
|
232
297
|
i !== null && (e[r.key] = i);
|
|
233
298
|
}
|
|
234
|
-
let r
|
|
235
|
-
|
|
299
|
+
for (let r of A) for (let [i, a] of [[t, "sessionStorage"], [n, "localStorage"]]) {
|
|
300
|
+
let t = N(i, r.key);
|
|
301
|
+
t !== null && (e[`${r.key} (${a}) ${j}`] = t);
|
|
302
|
+
}
|
|
236
303
|
for (let [r, i] of [[t, "sessionStorage"], [n, "localStorage"]]) if (r) try {
|
|
237
304
|
for (let t = 0; t < r.length; t += 1) {
|
|
238
305
|
let n = r.key(t);
|
|
239
|
-
!n || !n.startsWith("flemo:") ||
|
|
306
|
+
!n || !n.startsWith("flemo:") || re.has(n) || ie.has(n) || (e[`${n} (${i}, unknown key)`] = r.getItem(n) ?? "");
|
|
240
307
|
}
|
|
241
308
|
} catch {}
|
|
242
309
|
return e;
|
|
243
|
-
},
|
|
310
|
+
}, ae = (e) => {
|
|
244
311
|
let t = [];
|
|
245
312
|
for (let [n, r] of Object.entries(e)) {
|
|
246
|
-
if (n
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
if (n === _) {
|
|
251
|
-
t.push(`${n}=${r} — legacy localStorage driver pin present. The library removes it on sight and never honors it, but its existence means an old A/B session left residue on this profile.`);
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
if (n.startsWith(`${g} `)) {
|
|
255
|
-
t.push(`${n}=${r} — a driver force pin was observed this session (see marker in the key). Even a since-cleared pin may have shaped early driver decisions; treat this session's routing as suspect.`);
|
|
313
|
+
if (n.includes("(retired — the library no longer reads this)")) {
|
|
314
|
+
let e = n.slice(0, n.indexOf(" (")), i = A.find((t) => t.key === e);
|
|
315
|
+
t.push(`${n}=${r} — RETIRED residue: this key went with ${i?.retiredWith ?? "a removed feature"}. The library never reads it, so it cannot explain anything you are seeing. Safe to delete; it is listed only so it does not read as an unexplained lead.`);
|
|
256
316
|
continue;
|
|
257
317
|
}
|
|
258
|
-
let e =
|
|
259
|
-
!e || e.key
|
|
318
|
+
let e = k.find((e) => n === e.key || n.startsWith(`${e.key} `));
|
|
319
|
+
!e || P.has(e.key) || (e.kind === "opt-in-diagnostic" ? t.push(`${n}=${r} — opt-in diagnostic active (${e.effect}); behavior differs from stock. Possible left-over A/B toggle from an earlier debugging session.`) : e.kind === "production-default-with-override" && t.push(`${n}=${r} — production default overridden for this session (${e.effect}). Stock behavior here is ${e.fallback}.`));
|
|
260
320
|
}
|
|
261
321
|
return t;
|
|
262
|
-
},
|
|
322
|
+
}, I = (e) => Math.round(e * 10) / 10, L = (e) => {
|
|
263
323
|
if (e.length === 0) return {
|
|
264
324
|
count: 0,
|
|
265
325
|
medianGapMs: 0,
|
|
@@ -269,11 +329,11 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
269
329
|
let t = [...e].sort((e, t) => e - t);
|
|
270
330
|
return {
|
|
271
331
|
count: e.length,
|
|
272
|
-
medianGapMs:
|
|
273
|
-
maxGapMs:
|
|
332
|
+
medianGapMs: I(t[Math.floor(t.length / 2)]),
|
|
333
|
+
maxGapMs: I(t[t.length - 1]),
|
|
274
334
|
over30Count: e.filter((e) => e >= 30).length
|
|
275
335
|
};
|
|
276
|
-
},
|
|
336
|
+
}, R = (e, t = []) => {
|
|
277
337
|
let n = [...e, ...t];
|
|
278
338
|
return {
|
|
279
339
|
...n.length === 0 ? {
|
|
@@ -284,21 +344,21 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
284
344
|
let e = [...n].sort((e, t) => e - t);
|
|
285
345
|
return {
|
|
286
346
|
count: n.length,
|
|
287
|
-
medianGapMs:
|
|
288
|
-
maxGapMs:
|
|
347
|
+
medianGapMs: I(e[Math.floor(e.length / 2)]),
|
|
348
|
+
maxGapMs: I(e[e.length - 1])
|
|
289
349
|
};
|
|
290
350
|
})(),
|
|
291
|
-
longGaps: n.filter((e) => e >= 30).map(
|
|
292
|
-
held:
|
|
293
|
-
released:
|
|
351
|
+
longGaps: n.filter((e) => e >= 30).map(I),
|
|
352
|
+
held: L(e),
|
|
353
|
+
released: L(t)
|
|
294
354
|
};
|
|
295
|
-
},
|
|
296
|
-
maxMs:
|
|
355
|
+
}, oe = (e) => e.length === 0 ? null : {
|
|
356
|
+
maxMs: I(Math.max(...e)),
|
|
297
357
|
over30Count: e.filter((e) => e >= 30).length
|
|
298
|
-
},
|
|
358
|
+
}, z = (e) => {
|
|
299
359
|
let t = e.playerSuppression || e.playerAdvance;
|
|
300
360
|
return t && e.compiledAnimation ? "mixed" : t ? "player" : e.compiledAnimation ? "compiled" : "unknown";
|
|
301
|
-
},
|
|
361
|
+
}, se = (e) => e === "PUSHING" ? "PUSH" : e === "POPPING" ? "POP" : e === "REPLACING" ? "REPLACE" : null, ce = (e) => {
|
|
302
362
|
let t = /^matrix3d\(([^)]+)\)$/.exec(e.trim());
|
|
303
363
|
if (t) {
|
|
304
364
|
let e = t[1].split(",").map((e) => Number(e.trim()));
|
|
@@ -310,23 +370,14 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
310
370
|
return e.length === 6 && Number.isFinite(e[4]) ? e[4] : null;
|
|
311
371
|
}
|
|
312
372
|
return null;
|
|
313
|
-
},
|
|
314
|
-
|
|
315
|
-
"POPPING",
|
|
316
|
-
"REPLACING"
|
|
317
|
-
]), j = /* @__PURE__ */ new Set([
|
|
318
|
-
"true",
|
|
319
|
-
"park",
|
|
320
|
-
"park-under",
|
|
321
|
-
"park-over"
|
|
322
|
-
]), M = "[data-flemo-screen]", N = "data-flemo-status", te = "data-flemo-active", P = "data-flemo-anim-hold", F = 2, I = 2e3, L = "data-flemo-img-hold", ne = "data-flemo-held-arrival", re = 2, R = 200, ie = 1e3, z = (e) => Math.round(e * 10) / 10, B = null, V = () => window, ae = (e = {}) => {
|
|
323
|
-
if (B) return B;
|
|
373
|
+
}, le = "2", B = new Set(_), V = new Set(v), ue = y(c), H = d, de = 2, fe = 2e3, pe = 2, me = 200, he = 1e3, U = (e) => Math.round(e * 10) / 10, ge = null, _e = () => window, ve = (e = {}) => {
|
|
374
|
+
if (ge) return ge;
|
|
324
375
|
if (typeof window > "u" || typeof document > "u") return {
|
|
325
376
|
detach: () => {},
|
|
326
377
|
report: () => ({
|
|
327
378
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
328
379
|
version: "2",
|
|
329
|
-
environment:
|
|
380
|
+
environment: w({
|
|
330
381
|
medianGapMs: null,
|
|
331
382
|
sampleCount: 0
|
|
332
383
|
}),
|
|
@@ -334,51 +385,47 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
334
385
|
active: {},
|
|
335
386
|
warnings: ["no DOM available — recorder ran inert"]
|
|
336
387
|
},
|
|
337
|
-
driverPolicy: {
|
|
338
|
-
demotion: null,
|
|
339
|
-
forcePin: null
|
|
340
|
-
},
|
|
341
388
|
flights: [],
|
|
342
389
|
anomalies: [],
|
|
343
390
|
blindSpots: [...s],
|
|
344
|
-
judgingProtocol: [...
|
|
391
|
+
judgingProtocol: [...T]
|
|
345
392
|
})
|
|
346
393
|
};
|
|
347
|
-
let n = e.maxFlights ?? 50, r = e.log ?? !1, i = e.installGlobal ?? !0, c =
|
|
394
|
+
let n = e.maxFlights ?? 50, r = e.log ?? !1, i = e.installGlobal ?? !0, c = F(), d = {
|
|
348
395
|
medianGapMs: null,
|
|
349
396
|
sampleCount: 0
|
|
350
397
|
};
|
|
351
|
-
|
|
352
|
-
|
|
398
|
+
ne().then((e) => {
|
|
399
|
+
d = e;
|
|
353
400
|
});
|
|
354
|
-
let
|
|
401
|
+
let g = [], _ = null;
|
|
355
402
|
try {
|
|
356
|
-
typeof PerformanceObserver < "u" && PerformanceObserver.supportedEntryTypes?.includes("longtask") && (
|
|
357
|
-
for (let t of e.getEntries())
|
|
358
|
-
startMs:
|
|
359
|
-
durationMs:
|
|
403
|
+
typeof PerformanceObserver < "u" && PerformanceObserver.supportedEntryTypes?.includes("longtask") && (_ = new PerformanceObserver((e) => {
|
|
404
|
+
for (let t of e.getEntries()) g.push({
|
|
405
|
+
startMs: U(t.startTime),
|
|
406
|
+
durationMs: U(t.duration)
|
|
360
407
|
});
|
|
361
|
-
|
|
362
|
-
}),
|
|
408
|
+
g.length > he && g.splice(0, g.length - he);
|
|
409
|
+
}), _.observe({
|
|
363
410
|
type: "longtask",
|
|
364
411
|
buffered: !0
|
|
365
412
|
}));
|
|
366
413
|
} catch {
|
|
367
|
-
|
|
414
|
+
_ = null;
|
|
368
415
|
}
|
|
369
|
-
let
|
|
370
|
-
let t = Array.from(document.querySelectorAll(
|
|
416
|
+
let v = [], te = 0, b = null, x = [], S = !1, C = !1, E = () => Array.from(document.querySelectorAll(ue)).filter((e) => B.has(e.getAttribute("data-flemo-status") ?? "")), D = (e) => {
|
|
417
|
+
let t = Array.from(document.querySelectorAll(y(h))).filter((e) => B.has(e.getAttribute("data-flemo-bar-status") ?? "") || e.getAttribute("data-flemo-bar-riding") === "true").length, n = Array.from(document.querySelectorAll(y(m))).filter((e) => B.has(e.getAttribute("data-flemo-status") ?? "")).length, r = Array.from(document.querySelectorAll(y(ee))).filter((e) => B.has(e.getAttribute("data-flemo-status") ?? "")).length;
|
|
371
418
|
return {
|
|
372
419
|
screens: e.length,
|
|
373
420
|
bars: t,
|
|
374
421
|
decorators: n,
|
|
375
422
|
parts: r
|
|
376
423
|
};
|
|
377
|
-
},
|
|
424
|
+
}, O = (e) => {
|
|
378
425
|
let t = [];
|
|
379
426
|
for (let n of e) for (let e of Array.from(n.querySelectorAll("img"))) t.push(e);
|
|
380
427
|
return t;
|
|
381
|
-
},
|
|
428
|
+
}, k = (e) => {
|
|
382
429
|
let t = 0, n = 0;
|
|
383
430
|
for (let r of e.imagesTracked) r.complete && (t += 1, e.imagesHeld.has(r) || (n += 1));
|
|
384
431
|
return {
|
|
@@ -388,20 +435,20 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
388
435
|
heldDuringFlight: e.imagesHeld.size,
|
|
389
436
|
completedUnheld: n
|
|
390
437
|
};
|
|
391
|
-
},
|
|
392
|
-
let t =
|
|
393
|
-
if (!(!t || t.imagesTracked.size >=
|
|
438
|
+
}, A = (e) => {
|
|
439
|
+
let t = b;
|
|
440
|
+
if (!(!t || t.imagesTracked.size >= me)) for (let n of Array.from(e)) {
|
|
394
441
|
if (!(n instanceof Element) || !t.elements.some((e) => e === n || e.contains(n))) continue;
|
|
395
442
|
let e = n instanceof HTMLImageElement ? [n] : Array.from(n.querySelectorAll("img"));
|
|
396
443
|
for (let n of e) if (!(n.complete || t.imagesTracked.has(n))) {
|
|
397
|
-
if (t.imagesTracked.size >=
|
|
444
|
+
if (t.imagesTracked.size >= me) return;
|
|
398
445
|
t.imagesTracked.add(n), t.imagesAddedDuringFlight += 1;
|
|
399
446
|
}
|
|
400
447
|
}
|
|
401
|
-
},
|
|
402
|
-
for (let t of e.elements) for (let n of Array.from(t.querySelectorAll(`img[${
|
|
403
|
-
for (let t of e.imagesTracked) t.hasAttribute(
|
|
404
|
-
},
|
|
448
|
+
}, j = (e) => {
|
|
449
|
+
for (let t of e.elements) for (let n of Array.from(t.querySelectorAll(`img[${f}]`))) e.imagesHeld.add(n);
|
|
450
|
+
for (let t of e.imagesTracked) t.hasAttribute("data-flemo-img-hold") && e.imagesHeld.add(t);
|
|
451
|
+
}, M = (e, t) => {
|
|
405
452
|
e.releasedFrames += 1;
|
|
406
453
|
let n = !1, r = !1;
|
|
407
454
|
for (let t of e.elements) {
|
|
@@ -420,7 +467,7 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
420
467
|
e.lastPose.get(t) !== r && (n = !0);
|
|
421
468
|
}
|
|
422
469
|
}
|
|
423
|
-
if (!(e.releasedFrames <
|
|
470
|
+
if (!(e.releasedFrames < pe)) {
|
|
424
471
|
if (n) {
|
|
425
472
|
e.stallRunMs = 0;
|
|
426
473
|
return;
|
|
@@ -431,7 +478,7 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
431
478
|
}
|
|
432
479
|
e.stalledFrames += 1, e.stallRunMs += t, e.stallRunMs > e.longestStallMs && (e.longestStallMs = e.stallRunMs);
|
|
433
480
|
}
|
|
434
|
-
},
|
|
481
|
+
}, N = (e) => {
|
|
435
482
|
for (let t of e.elements) {
|
|
436
483
|
let n = t.style, r = t.getAnimations, i = e.clocks.get(t);
|
|
437
484
|
if (i !== void 0 && i.playState !== "finished") {
|
|
@@ -454,51 +501,51 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
454
501
|
i !== void 0 && i !== r && (e.evidence.playerAdvance = !0), e.lastPose.set(t, r);
|
|
455
502
|
}
|
|
456
503
|
}
|
|
457
|
-
},
|
|
458
|
-
let t = e.getAttribute(
|
|
459
|
-
return t !== null &&
|
|
460
|
-
}),
|
|
461
|
-
let e =
|
|
462
|
-
if (!e ||
|
|
504
|
+
}, re = (e) => e.elements.some((e) => {
|
|
505
|
+
let t = e.getAttribute(H);
|
|
506
|
+
return t !== null && V.has(t);
|
|
507
|
+
}), ie = () => {
|
|
508
|
+
let e = b;
|
|
509
|
+
if (!e || S) return;
|
|
463
510
|
let t = performance.now();
|
|
464
|
-
if (e.lastFrameAt !== null && e.heldGaps.length + e.releasedGaps.length <
|
|
465
|
-
let n = t - e.lastFrameAt, r =
|
|
466
|
-
(r ? e.heldGaps : e.releasedGaps).push(n), r || (
|
|
511
|
+
if (e.lastFrameAt !== null && e.heldGaps.length + e.releasedGaps.length < fe) {
|
|
512
|
+
let n = t - e.lastFrameAt, r = re(e);
|
|
513
|
+
(r ? e.heldGaps : e.releasedGaps).push(n), r || (M(e, n), e.releasedFrames === 1 && j(e));
|
|
467
514
|
}
|
|
468
|
-
if (e.lastFrameAt = t,
|
|
469
|
-
|
|
515
|
+
if (e.lastFrameAt = t, N(e), t - e.t0Ms > 1e4) {
|
|
516
|
+
x = [...e.elements], ye(t, P(e));
|
|
470
517
|
return;
|
|
471
518
|
}
|
|
472
|
-
e.rafId = requestAnimationFrame(
|
|
473
|
-
},
|
|
519
|
+
e.rafId = requestAnimationFrame(ie);
|
|
520
|
+
}, P = (e) => {
|
|
474
521
|
let t = /* @__PURE__ */ new Set();
|
|
475
522
|
for (let n of e.elements) {
|
|
476
|
-
let e = n.getAttribute(
|
|
477
|
-
|
|
523
|
+
let e = n.getAttribute("data-flemo-status") ?? "";
|
|
524
|
+
B.has(e) && t.add(e);
|
|
478
525
|
}
|
|
479
526
|
return [...t];
|
|
480
|
-
},
|
|
527
|
+
}, I = (e) => {
|
|
481
528
|
let t = performance.now();
|
|
482
|
-
|
|
483
|
-
let n = e.find((e) => e.getAttribute(
|
|
529
|
+
te += 1;
|
|
530
|
+
let n = e.find((e) => e.getAttribute("data-flemo-active") === "true") ?? e[0], r = se(n.getAttribute("data-flemo-status") ?? "") ?? "PUSH", i = null;
|
|
484
531
|
for (let t of e) {
|
|
485
|
-
let e = t.getAttribute(
|
|
486
|
-
if (e !== null &&
|
|
532
|
+
let e = t.getAttribute(H);
|
|
533
|
+
if (e !== null && V.has(e)) {
|
|
487
534
|
i = e;
|
|
488
535
|
break;
|
|
489
536
|
}
|
|
490
537
|
}
|
|
491
|
-
|
|
492
|
-
id: `flight-${
|
|
538
|
+
b = {
|
|
539
|
+
id: `flight-${te}`,
|
|
493
540
|
kind: r,
|
|
494
541
|
routerId: n.getAttribute("data-flemo-router") ?? void 0,
|
|
495
542
|
t0Ms: t,
|
|
496
543
|
t0Iso: (/* @__PURE__ */ new Date()).toISOString(),
|
|
497
544
|
elements: [...e],
|
|
498
|
-
participants:
|
|
545
|
+
participants: D(e),
|
|
499
546
|
holdKind: i,
|
|
500
547
|
holdReleasedAtMs: null,
|
|
501
|
-
playerGapStartIndex:
|
|
548
|
+
playerGapStartIndex: _e().__flemoPlayerGaps?.length ?? 0,
|
|
502
549
|
heldGaps: [],
|
|
503
550
|
releasedGaps: [],
|
|
504
551
|
lastFrameAt: null,
|
|
@@ -517,32 +564,32 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
517
564
|
longestStallMs: 0,
|
|
518
565
|
pausedAfterRelease: !1,
|
|
519
566
|
holdReassertedAtMs: null,
|
|
520
|
-
imagesTracked: new Set(
|
|
567
|
+
imagesTracked: new Set(O(e).filter((e) => !e.complete)),
|
|
521
568
|
imagesLoadingAtStart: 0,
|
|
522
569
|
imagesAddedDuringFlight: 0,
|
|
523
570
|
imagesHeld: /* @__PURE__ */ new Set(),
|
|
524
571
|
rafId: null
|
|
525
|
-
},
|
|
526
|
-
},
|
|
527
|
-
let n =
|
|
528
|
-
if (!
|
|
572
|
+
}, b.imagesLoadingAtStart = b.imagesTracked.size, N(b), b.rafId = requestAnimationFrame(ie);
|
|
573
|
+
}, L = (e, t) => {
|
|
574
|
+
let n = de, r = () => {
|
|
575
|
+
if (!S) {
|
|
529
576
|
if (--n, n > 0) {
|
|
530
577
|
requestAnimationFrame(r);
|
|
531
578
|
return;
|
|
532
579
|
}
|
|
533
|
-
|
|
580
|
+
ve(e, t);
|
|
534
581
|
}
|
|
535
582
|
};
|
|
536
583
|
requestAnimationFrame(r);
|
|
537
|
-
},
|
|
538
|
-
if (
|
|
584
|
+
}, le = () => {
|
|
585
|
+
if (b !== null || E().length > 0) return [];
|
|
539
586
|
let e = [];
|
|
540
|
-
for (let [t, n] of [[
|
|
587
|
+
for (let [t, n] of [[f, "image reveal hold"], [p, "arrival hold"]]) {
|
|
541
588
|
let r = document.querySelectorAll(`[${t}]`).length;
|
|
542
589
|
r > 0 && e.push(`${r} × ${n} (${t}) still marked at rest`);
|
|
543
590
|
}
|
|
544
591
|
return e;
|
|
545
|
-
},
|
|
592
|
+
}, ve = (e, t) => {
|
|
546
593
|
let n = [], r = !1, i = window.visualViewport?.width ?? window.innerWidth ?? 0;
|
|
547
594
|
t.forEach((e, t) => {
|
|
548
595
|
if (!(e instanceof HTMLElement) || !e.isConnected) return;
|
|
@@ -552,45 +599,45 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
552
599
|
a = t.transform ?? "", o = t.display ?? "";
|
|
553
600
|
} catch {}
|
|
554
601
|
if (o === "none") return;
|
|
555
|
-
let s = e.getAttribute(
|
|
556
|
-
if (e.style.transform !== "" && e.style.transform !== "none" && n.push(`${c} transform=${e.style.transform}`), e.style.opacity !== "" && e.style.opacity !== "1" && n.push(`${c} opacity=${e.style.opacity}`), s && e.getAttribute(
|
|
557
|
-
let e =
|
|
602
|
+
let s = e.getAttribute(u) === "true", c = `screen[${t}]${s ? " (active)" : ""}`;
|
|
603
|
+
if (e.style.transform !== "" && e.style.transform !== "none" && n.push(`${c} transform=${e.style.transform}`), e.style.opacity !== "" && e.style.opacity !== "1" && n.push(`${c} opacity=${e.style.opacity}`), s && e.getAttribute("data-flemo-status") === "COMPLETED" && i > 0) {
|
|
604
|
+
let e = ce(a);
|
|
558
605
|
e !== null && Math.abs(e) >= i * .5 && (r = !0);
|
|
559
606
|
}
|
|
560
|
-
}), e.landing.residualInlineTransforms = n, e.landing.offViewportAtRest = r, e.landing.orphanedHolds =
|
|
561
|
-
},
|
|
562
|
-
let i =
|
|
607
|
+
}), e.landing.residualInlineTransforms = n, e.landing.offViewportAtRest = r, e.landing.orphanedHolds = le();
|
|
608
|
+
}, ye = (e, t) => {
|
|
609
|
+
let i = b;
|
|
563
610
|
if (!i) return;
|
|
564
|
-
|
|
565
|
-
let a =
|
|
611
|
+
j(i), b = null, i.rafId !== null && cancelAnimationFrame(i.rafId);
|
|
612
|
+
let a = oe((_e().__flemoPlayerGaps ?? []).slice(i.playerGapStartIndex)), o = {
|
|
566
613
|
id: i.id,
|
|
567
614
|
...i.routerId === void 0 ? {} : { routerId: i.routerId },
|
|
568
615
|
kind: i.kind,
|
|
569
616
|
t0: {
|
|
570
|
-
ms:
|
|
617
|
+
ms: U(i.t0Ms),
|
|
571
618
|
iso: i.t0Iso
|
|
572
619
|
},
|
|
573
620
|
t1: {
|
|
574
|
-
ms:
|
|
621
|
+
ms: U(e),
|
|
575
622
|
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
576
623
|
},
|
|
577
|
-
durationMs:
|
|
578
|
-
driver:
|
|
624
|
+
durationMs: U(e - i.t0Ms),
|
|
625
|
+
driver: z(i.evidence),
|
|
579
626
|
participants: i.participants,
|
|
580
627
|
holds: {
|
|
581
628
|
kind: i.holdKind,
|
|
582
629
|
releasedAtMs: i.holdReleasedAtMs
|
|
583
630
|
},
|
|
584
|
-
frameSamples:
|
|
631
|
+
frameSamples: R(i.heldGaps, i.releasedGaps),
|
|
585
632
|
motion: {
|
|
586
633
|
sampledFrames: i.releasedFrames,
|
|
587
634
|
stalledFrames: i.stalledFrames,
|
|
588
|
-
longestStallMs:
|
|
635
|
+
longestStallMs: U(i.longestStallMs),
|
|
589
636
|
pausedAfterRelease: i.pausedAfterRelease,
|
|
590
637
|
holdReassertedAtMs: i.holdReassertedAtMs,
|
|
591
638
|
tailFrames: i.tailFrames
|
|
592
639
|
},
|
|
593
|
-
images:
|
|
640
|
+
images: k(i),
|
|
594
641
|
...a ? { playerGaps: a } : {},
|
|
595
642
|
longTasks: [],
|
|
596
643
|
holdLongTasks: [],
|
|
@@ -602,34 +649,34 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
602
649
|
},
|
|
603
650
|
anomalies: []
|
|
604
651
|
};
|
|
605
|
-
|
|
606
|
-
},
|
|
607
|
-
let t =
|
|
652
|
+
v.push(o), v.length > n && v.splice(0, v.length - n), t.length === 0 && L(o, i.elements), r && console.info(`[flemo devtools] ${o.id} ${o.kind} driver=${o.driver} ${o.durationMs}ms screens=${o.participants.screens}`);
|
|
653
|
+
}, W = (e) => {
|
|
654
|
+
let t = b;
|
|
608
655
|
if (!t || !(e.target instanceof Element)) return;
|
|
609
|
-
let n = e.target.getAttribute(
|
|
610
|
-
n !== null &&
|
|
611
|
-
},
|
|
612
|
-
let e =
|
|
613
|
-
if (
|
|
614
|
-
if (e.some((e) =>
|
|
615
|
-
|
|
656
|
+
let n = e.target.getAttribute(H);
|
|
657
|
+
n !== null && V.has(n) && t.holdKind === null && (t.holdKind = n), n !== null && V.has(n) && t.holdReleasedAtMs !== null && t.holdReassertedAtMs === null && (t.holdReassertedAtMs = U(performance.now() - t.t0Ms)), (n === "false" || n === null) && e.oldValue !== null && V.has(e.oldValue) && t.holdReleasedAtMs === null && !re(t) && (t.holdReleasedAtMs = U(performance.now() - t.t0Ms));
|
|
658
|
+
}, be = () => {
|
|
659
|
+
let e = E();
|
|
660
|
+
if (x.length > 0) {
|
|
661
|
+
if (e.some((e) => x.includes(e))) return;
|
|
662
|
+
x = [];
|
|
616
663
|
}
|
|
617
|
-
if (!
|
|
618
|
-
|
|
664
|
+
if (!b && e.length > 0) {
|
|
665
|
+
I(e);
|
|
619
666
|
return;
|
|
620
667
|
}
|
|
621
|
-
if (
|
|
622
|
-
|
|
668
|
+
if (b && e.length === 0) {
|
|
669
|
+
ye(performance.now(), []);
|
|
623
670
|
return;
|
|
624
671
|
}
|
|
625
|
-
if (
|
|
626
|
-
},
|
|
672
|
+
if (b) for (let t of e) b.elements.includes(t) || (b.elements.push(t), A(t.querySelectorAll("img")), b.participants = D(b.elements));
|
|
673
|
+
}, G = null, K = null, q = () => {
|
|
627
674
|
let e = document.documentElement;
|
|
628
675
|
if (!e) return !1;
|
|
629
676
|
let t = new MutationObserver((e) => {
|
|
630
|
-
if (!
|
|
631
|
-
for (let t of e) t.type === "attributes" && t.attributeName ===
|
|
632
|
-
|
|
677
|
+
if (!S) {
|
|
678
|
+
for (let t of e) t.type === "attributes" && t.attributeName === H ? W(t) : t.type === "childList" && t.addedNodes.length > 0 && A(t.addedNodes);
|
|
679
|
+
be();
|
|
633
680
|
}
|
|
634
681
|
});
|
|
635
682
|
try {
|
|
@@ -639,31 +686,31 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
639
686
|
attributes: !0,
|
|
640
687
|
attributeOldValue: !0,
|
|
641
688
|
attributeFilter: [
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
689
|
+
l,
|
|
690
|
+
u,
|
|
691
|
+
H
|
|
645
692
|
]
|
|
646
693
|
});
|
|
647
694
|
} catch {
|
|
648
695
|
return !1;
|
|
649
696
|
}
|
|
650
|
-
return
|
|
697
|
+
return G = t, be(), !0;
|
|
651
698
|
};
|
|
652
|
-
if (
|
|
699
|
+
if (!q()) {
|
|
653
700
|
let e = () => {
|
|
654
|
-
|
|
701
|
+
K = null, S || q();
|
|
655
702
|
};
|
|
656
|
-
|
|
703
|
+
K = e, document.addEventListener("DOMContentLoaded", e, { once: !0 });
|
|
657
704
|
}
|
|
658
|
-
let
|
|
659
|
-
let t =
|
|
705
|
+
let J = (e) => {
|
|
706
|
+
let t = g.filter((t) => t.startMs + t.durationMs >= e.t0.ms - 120 && t.startMs <= e.t1.ms), n = e.holds.kind === null ? e.t0.ms : e.holds.releasedAtMs === null ? e.t1.ms : e.t0.ms + e.holds.releasedAtMs;
|
|
660
707
|
return {
|
|
661
708
|
released: t.filter((e) => e.startMs + e.durationMs > n),
|
|
662
709
|
held: t.filter((e) => e.startMs + e.durationMs <= n)
|
|
663
710
|
};
|
|
664
|
-
},
|
|
665
|
-
let e = performance.now(), n =
|
|
666
|
-
let t =
|
|
711
|
+
}, Y = () => {
|
|
712
|
+
let e = performance.now(), n = v.map((e) => {
|
|
713
|
+
let t = J(e), n = {
|
|
667
714
|
...e,
|
|
668
715
|
longTasks: t.released,
|
|
669
716
|
holdLongTasks: t.held,
|
|
@@ -687,47 +734,47 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
687
734
|
motion: n.motion,
|
|
688
735
|
images: n.images
|
|
689
736
|
}), n;
|
|
690
|
-
}), r =
|
|
737
|
+
}), r = b;
|
|
691
738
|
if (!r) return n;
|
|
692
739
|
let i = e - r.t0Ms > t, o = {
|
|
693
740
|
id: `${r.id} (in flight)`,
|
|
694
741
|
...r.routerId === void 0 ? {} : { routerId: r.routerId },
|
|
695
742
|
kind: r.kind,
|
|
696
743
|
t0: {
|
|
697
|
-
ms:
|
|
744
|
+
ms: U(r.t0Ms),
|
|
698
745
|
iso: r.t0Iso
|
|
699
746
|
},
|
|
700
747
|
t1: {
|
|
701
|
-
ms:
|
|
748
|
+
ms: U(e),
|
|
702
749
|
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
703
750
|
},
|
|
704
|
-
durationMs:
|
|
705
|
-
driver:
|
|
751
|
+
durationMs: U(e - r.t0Ms),
|
|
752
|
+
driver: z(r.evidence),
|
|
706
753
|
participants: r.participants,
|
|
707
754
|
holds: {
|
|
708
755
|
kind: r.holdKind,
|
|
709
756
|
releasedAtMs: r.holdReleasedAtMs
|
|
710
757
|
},
|
|
711
|
-
frameSamples:
|
|
758
|
+
frameSamples: R(r.heldGaps, r.releasedGaps),
|
|
712
759
|
motion: {
|
|
713
760
|
sampledFrames: r.releasedFrames,
|
|
714
761
|
stalledFrames: r.stalledFrames,
|
|
715
|
-
longestStallMs:
|
|
762
|
+
longestStallMs: U(r.longestStallMs),
|
|
716
763
|
pausedAfterRelease: r.pausedAfterRelease,
|
|
717
764
|
holdReassertedAtMs: r.holdReassertedAtMs,
|
|
718
765
|
tailFrames: r.tailFrames
|
|
719
766
|
},
|
|
720
|
-
images:
|
|
767
|
+
images: k(r),
|
|
721
768
|
longTasks: [],
|
|
722
769
|
holdLongTasks: [],
|
|
723
770
|
landing: {
|
|
724
771
|
residualInlineTransforms: [],
|
|
725
772
|
offViewportAtRest: !1,
|
|
726
|
-
stuckStatuses: i ?
|
|
773
|
+
stuckStatuses: i ? P(r) : [],
|
|
727
774
|
orphanedHolds: []
|
|
728
775
|
},
|
|
729
776
|
anomalies: []
|
|
730
|
-
}, s =
|
|
777
|
+
}, s = J(o);
|
|
731
778
|
return o.longTasks = s.released, o.holdLongTasks = s.held, o.anomalies = a({
|
|
732
779
|
t0Ms: o.t0.ms,
|
|
733
780
|
t1Ms: o.t1.ms,
|
|
@@ -741,16 +788,10 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
741
788
|
motion: o.motion,
|
|
742
789
|
images: o.images
|
|
743
790
|
}), [...n, o];
|
|
744
|
-
},
|
|
745
|
-
|
|
746
|
-
return (e === "session" ? sessionStorage : localStorage).getItem(t);
|
|
747
|
-
} catch {
|
|
748
|
-
return null;
|
|
749
|
-
}
|
|
750
|
-
}, he = () => {
|
|
751
|
-
let e = x(), t = { ...e };
|
|
791
|
+
}, X = () => {
|
|
792
|
+
let e = F(), t = { ...e };
|
|
752
793
|
for (let [n, r] of Object.entries(c)) n in e || (t[`${n} (at attach, since cleared)`] = r);
|
|
753
|
-
let n =
|
|
794
|
+
let n = ae(t), r = w(d), i = Y(), a = b;
|
|
754
795
|
return {
|
|
755
796
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
756
797
|
version: "2",
|
|
@@ -759,57 +800,50 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
759
800
|
active: t,
|
|
760
801
|
warnings: n
|
|
761
802
|
},
|
|
762
|
-
|
|
763
|
-
demotion: me("local", "flemo:motion-driver"),
|
|
764
|
-
forcePin: i
|
|
765
|
-
},
|
|
766
|
-
flights: u,
|
|
803
|
+
flights: i,
|
|
767
804
|
anomalies: o({
|
|
768
|
-
forcePin: i,
|
|
769
|
-
legacyLocalForcePin: t[_] ?? null,
|
|
770
|
-
clearedForcePin: a,
|
|
771
805
|
emulationSuspected: r.emulationSuspected,
|
|
772
806
|
platform: r.platform,
|
|
773
|
-
stuckFlightOpen:
|
|
774
|
-
flightAnomalies:
|
|
807
|
+
stuckFlightOpen: a !== null && performance.now() - a.t0Ms > 1e4,
|
|
808
|
+
flightAnomalies: i.map((e) => e.anomalies)
|
|
775
809
|
}),
|
|
776
810
|
blindSpots: [...s],
|
|
777
|
-
judgingProtocol: [...
|
|
811
|
+
judgingProtocol: [...T]
|
|
778
812
|
};
|
|
779
|
-
},
|
|
780
|
-
if (!
|
|
781
|
-
if (
|
|
782
|
-
let e =
|
|
813
|
+
}, xe = () => {
|
|
814
|
+
if (!S) {
|
|
815
|
+
if (S = !0, G?.disconnect(), K !== null && (document.removeEventListener("DOMContentLoaded", K), K = null), _?.disconnect(), b?.rafId != null && cancelAnimationFrame(b.rafId), b = null, C) {
|
|
816
|
+
let e = _e();
|
|
783
817
|
e.flemo?.__flemoDevtools === !0 && delete e.flemo;
|
|
784
818
|
}
|
|
785
|
-
|
|
819
|
+
ge = null;
|
|
786
820
|
}
|
|
787
|
-
},
|
|
788
|
-
detach:
|
|
789
|
-
report:
|
|
821
|
+
}, Se = {
|
|
822
|
+
detach: xe,
|
|
823
|
+
report: X
|
|
790
824
|
};
|
|
791
825
|
if (i) {
|
|
792
|
-
let e =
|
|
826
|
+
let e = _e(), t = e.flemo;
|
|
793
827
|
(t === void 0 || t?.__flemoDevtools === !0) && (e.flemo = {
|
|
794
828
|
__flemoDevtools: !0,
|
|
795
|
-
report:
|
|
796
|
-
flights:
|
|
797
|
-
detach:
|
|
829
|
+
report: X,
|
|
830
|
+
flights: Y,
|
|
831
|
+
detach: xe
|
|
798
832
|
}, C = !0);
|
|
799
833
|
}
|
|
800
|
-
return
|
|
801
|
-
},
|
|
834
|
+
return ge = Se, Se;
|
|
835
|
+
}, ye = "http://www.w3.org/2000/svg", W = (e, t, n) => {
|
|
802
836
|
let r = document.createElement(e);
|
|
803
837
|
return t !== void 0 && (r.className = t), n !== void 0 && (r.textContent = n), r;
|
|
804
|
-
},
|
|
805
|
-
let n = document.createElementNS(
|
|
838
|
+
}, be = (e, t) => {
|
|
839
|
+
let n = document.createElementNS(ye, e);
|
|
806
840
|
for (let [e, r] of Object.entries(t)) n.setAttribute(e, r);
|
|
807
841
|
return n;
|
|
808
842
|
}, G = (e) => {
|
|
809
843
|
for (; e.firstChild !== null;) e.removeChild(e.firstChild);
|
|
810
844
|
}, K = (e, t) => {
|
|
811
845
|
e.textContent !== t && (e.textContent = t);
|
|
812
|
-
}, q = (e) => e == null || e === "" ? "—" : String(e), J = (e) => typeof e == "number" && Number.isFinite(e) ? `${Math.round(e)}ms` : "—", Y = (e) => typeof e == "number" && Number.isFinite(e) ? `${Math.round(e * 10) / 10}ms` : "—", X = (e) => typeof e == "number" && Number.isFinite(e) ? String(e) : "—",
|
|
846
|
+
}, q = (e) => e == null || e === "" ? "—" : String(e), J = (e) => typeof e == "number" && Number.isFinite(e) ? `${Math.round(e)}ms` : "—", Y = (e) => typeof e == "number" && Number.isFinite(e) ? `${Math.round(e * 10) / 10}ms` : "—", X = (e) => typeof e == "number" && Number.isFinite(e) ? String(e) : "—", xe = (e) => e === !0 ? "yes" : e === !1 ? "no" : "—", Se = (e) => {
|
|
813
847
|
let t = e?.environment;
|
|
814
848
|
if (!t) return "—";
|
|
815
849
|
let n = t.viewport, r = n && typeof n.width == "number" && typeof n.height == "number" ? `${Math.round(n.width)}×${Math.round(n.height)}` : "—";
|
|
@@ -819,36 +853,36 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
819
853
|
r,
|
|
820
854
|
`rAF ${Y(t.rafCadence?.medianGapMs)}`
|
|
821
855
|
].join(" · ");
|
|
822
|
-
},
|
|
856
|
+
}, Ce = (e, t) => `${t ?? ""}#${e.map((e) => `${e?.id ?? ""}|${e?.kind ?? ""}|${e?.driver ?? ""}|${Math.round(e?.durationMs ?? 0)}|${e?.participants?.screens ?? 0}|${e?.anomalies?.length ?? 0}`).join(",")}`, we = (e) => {
|
|
823
857
|
let t = e?.released?.gaps;
|
|
824
858
|
if (!Array.isArray(t)) return null;
|
|
825
859
|
let n = t.filter((e) => typeof e == "number" && Number.isFinite(e));
|
|
826
860
|
return n.length >= 2 ? n : null;
|
|
827
|
-
},
|
|
828
|
-
let i =
|
|
829
|
-
i.appendChild(
|
|
861
|
+
}, Te = "\n:host {\n all: initial;\n color-scheme: dark;\n}\n* { box-sizing: border-box; }\n.root {\n --bg: #14161a;\n --bg-soft: #1b1e24;\n --line: #2b3038;\n --fg: #e6e9ef;\n --fg-dim: #99a1b0;\n --accent: #7cc4ff;\n --warn: #ffb454;\n --bad: #ff6b6b;\n font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n color: var(--fg);\n}\n@media (prefers-color-scheme: light) {\n .root {\n --bg: #ffffff;\n --bg-soft: #f4f6f9;\n --line: #dde1e8;\n --fg: #1a1d22;\n --fg-dim: #5c6472;\n --accent: #0b6bcb;\n --warn: #a35a00;\n --bad: #c2261f;\n }\n}\n.toggle {\n position: fixed;\n bottom: 12px;\n z-index: 2147483000;\n display: flex;\n align-items: center;\n gap: 6px;\n margin: 0;\n padding: 6px 10px;\n border: 1px solid var(--line);\n border-radius: 999px;\n background: var(--bg);\n color: var(--fg);\n font: inherit;\n cursor: pointer;\n}\n.toggle:hover { background: var(--bg-soft); }\n.toggle[data-corner=\"bottom-right\"] { right: 12px; }\n.toggle[data-corner=\"bottom-left\"] { left: 12px; }\n.mark { font-weight: 700; letter-spacing: 0.04em; }\n.count {\n padding: 0 6px;\n border-radius: 999px;\n background: var(--bg-soft);\n color: var(--fg-dim);\n}\n.dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--bad);\n}\n.dot[hidden] { display: none; }\n.panel {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 2147482999;\n display: flex;\n flex-direction: column;\n max-width: 100%;\n border-top: 1px solid var(--line);\n background: var(--bg);\n overflow: hidden;\n}\n.panel[hidden] { display: none; }\n.grip {\n flex: 0 0 6px;\n height: 6px;\n background: var(--line);\n cursor: ns-resize;\n touch-action: none;\n}\n.head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-bottom: 1px solid var(--line);\n}\n.env { color: var(--fg-dim); }\n.spacer { flex: 1 1 auto; }\n.act {\n padding: 4px 8px;\n border: 1px solid var(--line);\n border-radius: 4px;\n background: var(--bg-soft);\n color: var(--fg);\n font: inherit;\n cursor: pointer;\n}\n.chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1 1 100%;\n}\n.chips:empty { display: none; }\n.chip {\n padding: 2px 8px;\n border: 1px solid var(--line);\n border-radius: 999px;\n background: var(--bg-soft);\n color: var(--fg-dim);\n max-width: 100%;\n overflow-wrap: anywhere;\n}\n.chip.warn { border-color: var(--warn); color: var(--warn); }\n.chip.bad { border-color: var(--bad); color: var(--bad); }\n.body {\n display: flex;\n flex: 1 1 auto;\n min-height: 0;\n}\n.list {\n flex: 0 0 40%;\n max-width: 340px;\n min-width: 180px;\n overflow: auto;\n border-right: 1px solid var(--line);\n}\n.row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-bottom: 1px solid var(--line);\n background: none;\n color: var(--fg);\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n.row[aria-selected=\"true\"] { background: var(--bg-soft); }\n.row .kind { font-weight: 700; }\n.row .driver { color: var(--accent); }\n.row .dur, .row .screens { color: var(--fg-dim); }\n.row .n {\n margin-left: auto;\n padding: 0 6px;\n border-radius: 999px;\n background: var(--bg-soft);\n color: var(--fg-dim);\n}\n.row .n.bad { background: var(--bad); color: #fff; }\n.detail { flex: 1 1 auto; overflow: auto; padding: 8px 10px; }\n.section { margin: 0 0 10px; }\n.section > h2 {\n margin: 0 0 4px;\n font: inherit;\n font-weight: 700;\n color: var(--fg-dim);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n.kv { display: flex; gap: 8px; }\n.kv > .k { flex: 0 0 34%; max-width: 180px; color: var(--fg-dim); }\n.kv > .v { flex: 1 1 auto; overflow-wrap: anywhere; }\n/* A value that IS the finding — a stall, a re-asserted hold, an orphan. */\n.kv > .v.bad { color: var(--bad); }\n.li { overflow-wrap: anywhere; }\n.li.bad { color: var(--bad); }\n.dim { color: var(--fg-dim); }\n.spark { display: block; width: 100%; height: 28px; }\n.foot { border-top: 1px solid var(--line); padding: 6px 10px; color: var(--fg-dim); }\n.foot summary { cursor: pointer; }\n.foot .li { margin-top: 4px; }\n", Ee = 48, Z = (e, t, n, r) => {
|
|
862
|
+
let i = W("div", "kv");
|
|
863
|
+
i.appendChild(W("span", "k", t)), i.appendChild(W("span", r ? `v ${r}` : "v", n)), e.appendChild(i);
|
|
830
864
|
}, Q = (e, t) => {
|
|
831
|
-
let n =
|
|
832
|
-
return n.appendChild(
|
|
865
|
+
let n = W("section", "section");
|
|
866
|
+
return n.appendChild(W("h2", void 0, t)), e.appendChild(n), n;
|
|
833
867
|
}, $ = (e, t, n = "li") => {
|
|
834
|
-
e.appendChild(
|
|
835
|
-
},
|
|
868
|
+
e.appendChild(W("div", n, t));
|
|
869
|
+
}, De = (e, t) => {
|
|
836
870
|
G(e);
|
|
837
|
-
for (let n of t?.overrides?.warnings ?? []) e.appendChild(
|
|
838
|
-
for (let n of t?.anomalies ?? []) e.appendChild(
|
|
839
|
-
for (let [n, r] of Object.entries(t?.overrides?.active ?? {})) e.appendChild(
|
|
840
|
-
},
|
|
871
|
+
for (let n of t?.overrides?.warnings ?? []) e.appendChild(W("span", "chip warn", q(n)));
|
|
872
|
+
for (let n of t?.anomalies ?? []) e.appendChild(W("span", "chip bad", q(n)));
|
|
873
|
+
for (let [n, r] of Object.entries(t?.overrides?.active ?? {})) e.appendChild(W("span", "chip", `${n}=${String(r)}`));
|
|
874
|
+
}, Oe = (e, t, n, r) => {
|
|
841
875
|
if (G(e), t.length === 0) {
|
|
842
876
|
$(e, "no flights recorded yet — navigate once", "li dim");
|
|
843
877
|
return;
|
|
844
878
|
}
|
|
845
879
|
for (let i = t.length - 1; i >= 0; --i) {
|
|
846
|
-
let a = t[i], o = q(a?.id), s =
|
|
847
|
-
s.type = "button", s.setAttribute("data-flight-id", o), s.setAttribute("aria-selected", String(o === n)), s.appendChild(
|
|
880
|
+
let a = t[i], o = q(a?.id), s = W("button", "row");
|
|
881
|
+
s.type = "button", s.setAttribute("data-flight-id", o), s.setAttribute("aria-selected", String(o === n)), s.appendChild(W("span", "kind", q(a?.kind))), s.appendChild(W("span", "driver", q(a?.driver))), s.appendChild(W("span", "dur", J(a?.durationMs))), s.appendChild(W("span", "screens", `${X(a?.participants?.screens)} scr`));
|
|
848
882
|
let c = a?.anomalies?.length ?? 0;
|
|
849
|
-
s.appendChild(
|
|
883
|
+
s.appendChild(W("span", c > 0 ? "n bad" : "n", String(c))), s.addEventListener("click", () => r(o)), e.appendChild(s);
|
|
850
884
|
}
|
|
851
|
-
},
|
|
885
|
+
}, ke = (e, t, n) => {
|
|
852
886
|
if (!n) {
|
|
853
887
|
Z(e, t, "—");
|
|
854
888
|
return;
|
|
@@ -859,21 +893,21 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
859
893
|
`max ${Y(n.maxGapMs)}`
|
|
860
894
|
];
|
|
861
895
|
typeof n.over30Count == "number" && r.push(`>30ms ×${n.over30Count}`), Z(e, t, r.join(" · "));
|
|
862
|
-
},
|
|
863
|
-
let t = Math.max(...e), n = t > 0 ? t : 1, r = 100 / (e.length - 1), i = e.map((e, t) => `${Math.round(t * r * 10) / 10},${Math.round((27 - e / n * 26) * 10) / 10}`).join(" "), a =
|
|
896
|
+
}, Ae = (e) => {
|
|
897
|
+
let t = Math.max(...e), n = t > 0 ? t : 1, r = 100 / (e.length - 1), i = e.map((e, t) => `${Math.round(t * r * 10) / 10},${Math.round((27 - e / n * 26) * 10) / 10}`).join(" "), a = be("svg", {
|
|
864
898
|
class: "spark",
|
|
865
899
|
viewBox: "0 0 100 28",
|
|
866
900
|
preserveAspectRatio: "none",
|
|
867
901
|
"aria-hidden": "true"
|
|
868
902
|
});
|
|
869
|
-
return a.appendChild(
|
|
903
|
+
return a.appendChild(be("polyline", {
|
|
870
904
|
points: i,
|
|
871
905
|
fill: "none",
|
|
872
906
|
stroke: "currentColor",
|
|
873
907
|
"stroke-width": "1",
|
|
874
908
|
"vector-effect": "non-scaling-stroke"
|
|
875
909
|
})), a;
|
|
876
|
-
},
|
|
910
|
+
}, je = (e, t) => {
|
|
877
911
|
let n = t.longTasks ?? [], r = t.holdLongTasks ?? [];
|
|
878
912
|
if (n.length === 0 && r.length === 0) {
|
|
879
913
|
$(e, "none", "li dim");
|
|
@@ -882,7 +916,7 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
882
916
|
let i = (e) => `${J(e?.startMs)} + ${J(e?.durationMs)}`;
|
|
883
917
|
for (let t of n) $(e, i(t), "li bad");
|
|
884
918
|
for (let t of r) $(e, `${i(t)} (absorbed by hold)`, "li dim");
|
|
885
|
-
},
|
|
919
|
+
}, Me = (e, t) => {
|
|
886
920
|
if (G(e), !t) {
|
|
887
921
|
$(e, "select a flight", "li dim");
|
|
888
922
|
return;
|
|
@@ -890,174 +924,174 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = (e) => {
|
|
|
890
924
|
let n = Q(e, "timing");
|
|
891
925
|
Z(n, "id", q(t.id)), Z(n, "kind / driver", `${q(t.kind)} · ${q(t.driver)}`), Z(n, "router", q(t.routerId)), Z(n, "t0", q(t.t0?.iso)), Z(n, "duration", J(t.durationMs)), Z(n, "participants", `${X(t.participants?.screens)} screens · ${X(t.participants?.bars)} bars · ${X(t.participants?.decorators)} decorators · ${X(t.participants?.parts)} parts`), Z(n, "hold", `${q(t.holds?.kind)} · released ${J(t.holds?.releasedAtMs)}`);
|
|
892
926
|
let r = Q(e, "frames");
|
|
893
|
-
|
|
894
|
-
let i =
|
|
895
|
-
i && r.appendChild(
|
|
927
|
+
ke(r, "held (absorbed)", t.frameSamples?.held), ke(r, "released (visible)", t.frameSamples?.released), t.playerGaps && Z(r, "player mirror", `max ${Y(t.playerGaps.maxMs)} · >30ms ×${X(t.playerGaps.over30Count)}`);
|
|
928
|
+
let i = we(t.frameSamples);
|
|
929
|
+
i && r.appendChild(Ae(i));
|
|
896
930
|
let a = Q(e, "motion (did it move)"), o = t.motion?.longestStallMs, s = t.motion?.holdReassertedAtMs;
|
|
897
|
-
Z(a, "released frames", X(t.motion?.sampledFrames)), Z(a, "stalled frames", X(t.motion?.stalledFrames), (t.motion?.stalledFrames ?? 0) > 0 ? "bad" : void 0), Z(a, "longest stall", J(o), (o ?? 0) >=
|
|
931
|
+
Z(a, "released frames", X(t.motion?.sampledFrames)), Z(a, "stalled frames", X(t.motion?.stalledFrames), (t.motion?.stalledFrames ?? 0) > 0 ? "bad" : void 0), Z(a, "longest stall", J(o), (o ?? 0) >= Ee ? "bad" : void 0), Z(a, "paused after release", xe(t.motion?.pausedAfterRelease), t.motion?.pausedAfterRelease === !0 ? "bad" : void 0), Z(a, "hold re-asserted", s == null ? "no" : J(s), typeof s == "number" ? "bad" : void 0);
|
|
898
932
|
let c = Q(e, "images"), l = t.images?.completedDuringFlight ?? 0, u = t.images?.heldDuringFlight ?? 0, d = t.images?.completedUnheld, f = typeof d == "number" ? d > 0 : l > u;
|
|
899
|
-
Z(c, "loading at t0", X(t.images?.loadingAtStart)), Z(c, "added mid-flight", X(t.images?.addedDuringFlight)), Z(c, "completed mid-flight", X(t.images?.completedDuringFlight), f ? "bad" : void 0), Z(c, "held by the engine", X(t.images?.heldDuringFlight)), Z(c, "completed without hold", X(d), f ? "bad" : void 0),
|
|
900
|
-
let p = Q(e, "landing"),
|
|
901
|
-
if (
|
|
902
|
-
else for (let e of
|
|
903
|
-
Z(p, "off-viewport at rest",
|
|
904
|
-
let
|
|
905
|
-
Z(p, "stuck statuses",
|
|
906
|
-
let
|
|
907
|
-
if (
|
|
908
|
-
else for (let e of
|
|
909
|
-
let
|
|
910
|
-
if (
|
|
911
|
-
$(
|
|
933
|
+
Z(c, "loading at t0", X(t.images?.loadingAtStart)), Z(c, "added mid-flight", X(t.images?.addedDuringFlight)), Z(c, "completed mid-flight", X(t.images?.completedDuringFlight), f ? "bad" : void 0), Z(c, "held by the engine", X(t.images?.heldDuringFlight)), Z(c, "completed without hold", X(d), f ? "bad" : void 0), je(Q(e, "long tasks"), t);
|
|
934
|
+
let p = Q(e, "landing"), ee = t.landing?.residualInlineTransforms ?? [];
|
|
935
|
+
if (ee.length === 0) Z(p, "inline residue", "clean");
|
|
936
|
+
else for (let e of ee) Z(p, "inline residue", q(e));
|
|
937
|
+
Z(p, "off-viewport at rest", xe(t.landing?.offViewportAtRest));
|
|
938
|
+
let m = t.landing?.stuckStatuses ?? [];
|
|
939
|
+
Z(p, "stuck statuses", m.length === 0 ? "none" : m.join(", "));
|
|
940
|
+
let h = t.landing?.orphanedHolds ?? [];
|
|
941
|
+
if (h.length === 0) Z(p, "orphaned holds", "none");
|
|
942
|
+
else for (let e of h) Z(p, "orphaned holds", q(e), "bad");
|
|
943
|
+
let g = Q(e, "anomalies"), _ = t.anomalies ?? [];
|
|
944
|
+
if (_.length === 0) {
|
|
945
|
+
$(g, "none", "li dim");
|
|
912
946
|
return;
|
|
913
947
|
}
|
|
914
|
-
for (let e of
|
|
915
|
-
},
|
|
948
|
+
for (let e of _) $(g, q(e), "li bad");
|
|
949
|
+
}, Ne = (e, t) => {
|
|
916
950
|
G(e);
|
|
917
951
|
for (let n of t ?? []) $(e, q(n));
|
|
918
|
-
},
|
|
919
|
-
if (
|
|
920
|
-
if (typeof document > "u") return { detach:
|
|
952
|
+
}, Pe = _.map((e) => y(c) + te(l, e)).join(","), Fe = 320, Ie = 2e3, Le = 120, Re = "Copy report JSON", ze = () => {}, Be = null, Ve = (e = {}) => {
|
|
953
|
+
if (Be) return Be;
|
|
954
|
+
if (typeof document > "u") return { detach: ze };
|
|
921
955
|
let t = !1, n, r = window.flemo;
|
|
922
956
|
e.recorder ? n = e.recorder : r?.__flemoDevtools === !0 && typeof r.report == "function" ? n = {
|
|
923
957
|
report: r.report,
|
|
924
|
-
detach:
|
|
925
|
-
} : (n =
|
|
926
|
-
let i =
|
|
927
|
-
i.setAttribute(
|
|
928
|
-
let a = i.attachShadow({ mode: "open" }), o =
|
|
929
|
-
o.textContent =
|
|
930
|
-
let s =
|
|
958
|
+
detach: ze
|
|
959
|
+
} : (n = ve(), t = !0);
|
|
960
|
+
let i = W("div");
|
|
961
|
+
i.setAttribute(g, ""), i.style.position = "fixed", i.style.top = "0", i.style.left = "0", i.style.width = "0", i.style.height = "0", i.style.zIndex = "2147483000";
|
|
962
|
+
let a = i.attachShadow({ mode: "open" }), o = W("style");
|
|
963
|
+
o.textContent = Te, a.appendChild(o);
|
|
964
|
+
let s = W("div", "root");
|
|
931
965
|
a.appendChild(s);
|
|
932
|
-
let c =
|
|
966
|
+
let c = W("button", "toggle");
|
|
933
967
|
c.type = "button", c.setAttribute("data-corner", e.position ?? "bottom-right"), c.setAttribute("aria-label", "flemo devtools");
|
|
934
|
-
let l =
|
|
935
|
-
u.hidden = !0, c.appendChild(
|
|
936
|
-
let d =
|
|
968
|
+
let l = W("span", "count", "0"), u = W("span", "dot");
|
|
969
|
+
u.hidden = !0, c.appendChild(W("span", "mark", "flemo")), c.appendChild(l), c.appendChild(u);
|
|
970
|
+
let d = W("section", "panel");
|
|
937
971
|
d.hidden = !0;
|
|
938
|
-
let f =
|
|
972
|
+
let f = W("div", "grip");
|
|
939
973
|
f.setAttribute("role", "separator"), f.setAttribute("aria-label", "Resize flemo devtools panel");
|
|
940
|
-
let p =
|
|
974
|
+
let p = W("header", "head"), ee = W("div", "env", "—"), m = W("button", "act", Re);
|
|
975
|
+
m.type = "button";
|
|
976
|
+
let h = W("button", "act", "Close");
|
|
941
977
|
h.type = "button";
|
|
942
|
-
let
|
|
943
|
-
g.type = "button";
|
|
944
|
-
let _ = U("button", "act", "Detach");
|
|
978
|
+
let _ = W("button", "act", "Detach");
|
|
945
979
|
_.type = "button";
|
|
946
|
-
let v =
|
|
947
|
-
p.appendChild(
|
|
948
|
-
let y =
|
|
949
|
-
y.appendChild(
|
|
950
|
-
let
|
|
951
|
-
|
|
952
|
-
let
|
|
953
|
-
|
|
954
|
-
let
|
|
980
|
+
let v = W("div", "chips");
|
|
981
|
+
p.appendChild(ee), p.appendChild(W("div", "spacer")), p.appendChild(m), p.appendChild(h), p.appendChild(_), p.appendChild(v);
|
|
982
|
+
let y = W("div", "body"), te = W("div", "list"), b = W("div", "detail");
|
|
983
|
+
y.appendChild(te), y.appendChild(b);
|
|
984
|
+
let x = W("div", "foot"), S = W("details");
|
|
985
|
+
S.appendChild(W("summary", void 0, "What this cannot see"));
|
|
986
|
+
let ne = W("div");
|
|
987
|
+
S.appendChild(ne), x.appendChild(S), d.appendChild(f), d.appendChild(p), d.appendChild(y), d.appendChild(x), s.appendChild(c), s.appendChild(d);
|
|
988
|
+
let C = !1, w = e.initialOpen === !0, T = null, D = "", O = "", k = "", A = !1, j = 0, M = 0, N = (e) => Math.min(Math.max(e, Le), Math.max(Le, window.innerHeight * .9)), re = () => {
|
|
955
989
|
try {
|
|
956
|
-
let e = sessionStorage.getItem(
|
|
990
|
+
let e = sessionStorage.getItem(E);
|
|
957
991
|
if (e === null) return null;
|
|
958
992
|
let t = Number.parseFloat(e);
|
|
959
993
|
return Number.isFinite(t) ? t : null;
|
|
960
994
|
} catch {
|
|
961
995
|
return null;
|
|
962
996
|
}
|
|
963
|
-
},
|
|
997
|
+
}, ie = (e) => {
|
|
964
998
|
try {
|
|
965
|
-
sessionStorage.setItem(
|
|
999
|
+
sessionStorage.setItem(E, String(Math.round(e)));
|
|
966
1000
|
} catch {}
|
|
967
|
-
},
|
|
968
|
-
d.style.height = `${Math.round(
|
|
969
|
-
let
|
|
1001
|
+
}, P = N(re() ?? window.innerHeight * .4);
|
|
1002
|
+
d.style.height = `${Math.round(P)}px`;
|
|
1003
|
+
let F = () => document.querySelector(Pe) !== null, ae = () => {
|
|
970
1004
|
try {
|
|
971
1005
|
return n.report();
|
|
972
1006
|
} catch {
|
|
973
1007
|
return null;
|
|
974
1008
|
}
|
|
975
|
-
},
|
|
976
|
-
e !==
|
|
977
|
-
},
|
|
978
|
-
let e =
|
|
1009
|
+
}, I = (e) => {
|
|
1010
|
+
e !== T && (T = e, R());
|
|
1011
|
+
}, L = () => {
|
|
1012
|
+
let e = ae(), t = e?.flights ?? [];
|
|
979
1013
|
K(l, String(t.length));
|
|
980
1014
|
let n = t.some((e) => (e?.anomalies?.length ?? 0) > 0);
|
|
981
|
-
if (u.hidden = !n, d.hidden = !
|
|
982
|
-
K(
|
|
1015
|
+
if (u.hidden = !n, d.hidden = !w, !w) return;
|
|
1016
|
+
K(ee, Se(e));
|
|
983
1017
|
let r = JSON.stringify([
|
|
984
1018
|
e?.overrides?.warnings ?? [],
|
|
985
1019
|
e?.anomalies ?? [],
|
|
986
1020
|
e?.overrides?.active ?? {}
|
|
987
1021
|
]);
|
|
988
|
-
r !== k && (k = r,
|
|
989
|
-
let i =
|
|
990
|
-
i !==
|
|
991
|
-
let a = t.find((e) => e?.id ===
|
|
992
|
-
o !==
|
|
1022
|
+
r !== k && (k = r, De(v, e)), T === null && t.length > 0 && (T = t[t.length - 1]?.id ?? null);
|
|
1023
|
+
let i = Ce(t, T);
|
|
1024
|
+
i !== D && (D = i, Oe(te, t, T, I));
|
|
1025
|
+
let a = t.find((e) => e?.id === T) ?? null, o = JSON.stringify(a);
|
|
1026
|
+
o !== O && (O = o, Me(b, a)), A || (A = !0, Ne(ne, e?.blindSpots));
|
|
993
1027
|
};
|
|
994
1028
|
function R() {
|
|
995
|
-
|
|
1029
|
+
C || F() || L();
|
|
996
1030
|
}
|
|
997
|
-
function
|
|
1031
|
+
function oe() {
|
|
998
1032
|
j = 0, R(), z();
|
|
999
1033
|
}
|
|
1000
1034
|
function z() {
|
|
1001
|
-
j = window.setTimeout(
|
|
1035
|
+
j = window.setTimeout(oe, w ? Fe : Ie);
|
|
1002
1036
|
}
|
|
1003
|
-
let
|
|
1037
|
+
let se = () => {
|
|
1004
1038
|
window.clearTimeout(j), z();
|
|
1005
|
-
},
|
|
1006
|
-
|
|
1039
|
+
}, ce = (e) => {
|
|
1040
|
+
w = e, se(), R();
|
|
1007
1041
|
};
|
|
1008
|
-
c.addEventListener("click", () =>
|
|
1009
|
-
let
|
|
1010
|
-
if (!
|
|
1011
|
-
if (
|
|
1012
|
-
window.clearTimeout(M), M = window.setTimeout(
|
|
1042
|
+
c.addEventListener("click", () => ce(!w)), h.addEventListener("click", () => ce(!1)), _.addEventListener("click", () => de());
|
|
1043
|
+
let le = () => {
|
|
1044
|
+
if (!C) {
|
|
1045
|
+
if (F()) {
|
|
1046
|
+
window.clearTimeout(M), M = window.setTimeout(le, Fe);
|
|
1013
1047
|
return;
|
|
1014
1048
|
}
|
|
1015
|
-
K(
|
|
1049
|
+
K(m, "Copied ✓"), window.clearTimeout(M), M = window.setTimeout(B, 1200);
|
|
1016
1050
|
}
|
|
1017
1051
|
};
|
|
1018
|
-
function
|
|
1019
|
-
if (
|
|
1020
|
-
M = window.setTimeout(
|
|
1052
|
+
function B() {
|
|
1053
|
+
if (F()) {
|
|
1054
|
+
M = window.setTimeout(B, Fe);
|
|
1021
1055
|
return;
|
|
1022
1056
|
}
|
|
1023
|
-
M = 0, K(
|
|
1057
|
+
M = 0, K(m, Re);
|
|
1024
1058
|
}
|
|
1025
|
-
let
|
|
1026
|
-
if (
|
|
1027
|
-
if (
|
|
1028
|
-
window.clearTimeout(M), M = window.setTimeout(() =>
|
|
1059
|
+
let V = (e) => {
|
|
1060
|
+
if (C) return;
|
|
1061
|
+
if (F()) {
|
|
1062
|
+
window.clearTimeout(M), M = window.setTimeout(() => V(e), Fe);
|
|
1029
1063
|
return;
|
|
1030
1064
|
}
|
|
1031
|
-
let t =
|
|
1065
|
+
let t = W("textarea");
|
|
1032
1066
|
t.value = e, t.setAttribute("aria-hidden", "true"), t.style.position = "fixed", t.style.opacity = "0", t.style.pointerEvents = "none", document.body.appendChild(t), t.select();
|
|
1033
1067
|
let n = document;
|
|
1034
1068
|
try {
|
|
1035
1069
|
n.execCommand?.("copy");
|
|
1036
1070
|
} catch {}
|
|
1037
|
-
t.remove(),
|
|
1071
|
+
t.remove(), le();
|
|
1038
1072
|
};
|
|
1039
|
-
|
|
1040
|
-
let e = JSON.stringify(
|
|
1073
|
+
m.addEventListener("click", () => {
|
|
1074
|
+
let e = JSON.stringify(ae(), null, 2), t = navigator.clipboard;
|
|
1041
1075
|
if (t && typeof t.writeText == "function") {
|
|
1042
|
-
t.writeText(e).then(
|
|
1076
|
+
t.writeText(e).then(le, () => V(e));
|
|
1043
1077
|
return;
|
|
1044
1078
|
}
|
|
1045
|
-
|
|
1079
|
+
V(e);
|
|
1046
1080
|
});
|
|
1047
|
-
let
|
|
1048
|
-
|
|
1049
|
-
},
|
|
1050
|
-
window.removeEventListener("pointermove",
|
|
1081
|
+
let ue = (e) => {
|
|
1082
|
+
P = N(window.innerHeight - e.clientY), d.style.height = `${Math.round(P)}px`;
|
|
1083
|
+
}, H = () => {
|
|
1084
|
+
window.removeEventListener("pointermove", ue), window.removeEventListener("pointerup", H), ie(P);
|
|
1051
1085
|
};
|
|
1052
1086
|
f.addEventListener("pointerdown", (e) => {
|
|
1053
|
-
e.preventDefault(), window.addEventListener("pointermove",
|
|
1087
|
+
e.preventDefault(), window.addEventListener("pointermove", ue), window.addEventListener("pointerup", H);
|
|
1054
1088
|
});
|
|
1055
|
-
function
|
|
1056
|
-
|
|
1089
|
+
function de() {
|
|
1090
|
+
C || (C = !0, window.clearTimeout(j), j = 0, window.clearTimeout(M), M = 0, window.removeEventListener("pointermove", ue), window.removeEventListener("pointerup", H), i.remove(), t && n.detach(), Be = null);
|
|
1057
1091
|
}
|
|
1058
1092
|
document.body.appendChild(i), R(), z();
|
|
1059
|
-
let
|
|
1060
|
-
return
|
|
1093
|
+
let fe = { detach: de };
|
|
1094
|
+
return Be = fe, fe;
|
|
1061
1095
|
};
|
|
1062
1096
|
//#endregion
|
|
1063
|
-
export { s as BLIND_SPOTS,
|
|
1097
|
+
export { s as BLIND_SPOTS, O as CORE_FLAGS, D as DEVTOOLS_OWNED_FLAGS, k as FLAG_REGISTRY, e as LONG_GAP_MS, i as MID_FLIGHT_TASK_MS, n as OPENING_WINDOW_LEAD_MS, r as OPENING_WINDOW_TAIL_MS, E as PANEL_HEIGHT_KEY, le as REPORT_SCHEMA_VERSION, A as RETIRED_FLAGS, j as RETIRED_MARKER, t as STUCK_STATUS_MS, Ve as attachDevtoolsPanel, ve as attachFlightRecorder, w as captureEnvironment, z as classifyDriver, R as computeFrameStats, L as computePhaseStats, oe as computePlayerGapStats, a as deriveFlightAnomalies, ae as deriveOverrideWarnings, o as deriveReportAnomalies, x as detectEngine, S as isEmulationSuspected, se as kindFromStatus, ce as parseTranslateX, ne as sampleRafCadence, F as snapshotOverrides };
|