@wenathlan/extension 1.1.46 → 1.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -333,6 +333,190 @@ function teardowncdpsession(input) {
333
333
  };
334
334
  }
335
335
 
336
+ // emulation.ts
337
+ var emulationkinds = ["emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "blackboxscripts"];
338
+ var browserpermissions = ["geolocation", "notifications", "camera", "microphone", "clipboard-read", "clipboard-write", "midi", "persistent-storage"];
339
+ var permissionstates = ["granted", "denied", "prompt"];
340
+ function familyofkind(kind) {
341
+ if (kind === "emulatedevice") return "device";
342
+ if (kind === "emulatenetwork") return "network";
343
+ if (kind === "emulatelocate") return "location";
344
+ if (kind === "setuseragent") return "agent";
345
+ if (kind === "overridepermission") return "permission";
346
+ if (kind === "blackboxscripts") return "blackbox";
347
+ return void 0;
348
+ }
349
+ function devicepresetof(value) {
350
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
351
+ const entry = value;
352
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
353
+ const width = typeof entry.width === "number" && Number.isInteger(entry.width) && entry.width > 0 ? entry.width : void 0;
354
+ const height = typeof entry.height === "number" && Number.isInteger(entry.height) && entry.height > 0 ? entry.height : void 0;
355
+ const pixelratio = typeof entry.pixelratio === "number" && Number.isFinite(entry.pixelratio) && entry.pixelratio > 0 ? entry.pixelratio : void 0;
356
+ if (name === void 0 || width === void 0 || height === void 0 || pixelratio === void 0) return void 0;
357
+ return { name, width, height, pixelratio, mobile: entry.mobile === true };
358
+ }
359
+ function networkpresetof(value) {
360
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
361
+ const entry = value;
362
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
363
+ const latency = typeof entry.latency === "number" && Number.isFinite(entry.latency) && entry.latency >= 0 ? entry.latency : void 0;
364
+ const download = typeof entry.download === "number" && Number.isFinite(entry.download) && entry.download >= 0 ? entry.download : void 0;
365
+ const upload = typeof entry.upload === "number" && Number.isFinite(entry.upload) && entry.upload >= 0 ? entry.upload : void 0;
366
+ if (name === void 0 || latency === void 0 || download === void 0 || upload === void 0) return void 0;
367
+ return { name, latency, download, upload, offline: entry.offline === true };
368
+ }
369
+ function locationpresetof(value) {
370
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
371
+ const entry = value;
372
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
373
+ const latitude = typeof entry.latitude === "number" && Number.isFinite(entry.latitude) ? entry.latitude : void 0;
374
+ const longitude = typeof entry.longitude === "number" && Number.isFinite(entry.longitude) ? entry.longitude : void 0;
375
+ const accuracy = typeof entry.accuracy === "number" && Number.isFinite(entry.accuracy) && entry.accuracy >= 0 ? entry.accuracy : void 0;
376
+ if (name === void 0 || latitude === void 0 || longitude === void 0 || accuracy === void 0) return void 0;
377
+ if (!locationrangevalid(latitude, longitude)) return void 0;
378
+ return { name, latitude, longitude, accuracy };
379
+ }
380
+ function agentpresetof(value) {
381
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
382
+ const entry = value;
383
+ const name = typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : void 0;
384
+ const useragent = typeof entry.useragent === "string" ? entry.useragent : void 0;
385
+ const platform = typeof entry.platform === "string" && entry.platform.trim() ? entry.platform.trim() : void 0;
386
+ const brands = Array.isArray(entry.brands) ? entry.brands.filter((brand) => typeof brand === "string" && brand.trim().length > 0) : [];
387
+ if (name === void 0 || useragent === void 0 || platform === void 0 || brands.length === 0) return void 0;
388
+ if (!agentgrammarvalid(useragent)) return void 0;
389
+ return { name, useragent, platform, brands: [...new Set(brands)] };
390
+ }
391
+ function permissiongrantof(value) {
392
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
393
+ const entry = value;
394
+ const name = typeof entry.name === "string" && browserpermissions.includes(entry.name) ? entry.name : void 0;
395
+ const state = typeof entry.state === "string" && permissionstates.includes(entry.state) ? entry.state : void 0;
396
+ if (name === void 0 || state === void 0) return void 0;
397
+ return { name, state, runscope: entry.runscope !== false };
398
+ }
399
+ function blackboxruleof(value) {
400
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
401
+ const entry = value;
402
+ const urlpatterns = Array.isArray(entry.urlpatterns) ? entry.urlpatterns.filter((pattern) => typeof pattern === "string" && /^https:\/\//.test(pattern)) : [];
403
+ const tracescope = entry.tracescope;
404
+ if (urlpatterns.length === 0) return void 0;
405
+ if (tracescope !== "profiles" && tracescope !== "traces" && tracescope !== "both") return void 0;
406
+ return { urlpatterns: [...new Set(urlpatterns)], tracescope };
407
+ }
408
+ function revertplanof(value) {
409
+ const steps = Array.isArray(value) ? value.filter((step) => typeof step === "string" && step.trim().length > 0) : [];
410
+ return steps.length > 0 ? steps : void 0;
411
+ }
412
+ function newlayer(input) {
413
+ return { id: input.id, runid: input.runid, stepid: input.stepid, family: input.family, name: input.name, originscope: input.originscope, appliedat: input.at, ...input.prior !== void 0 ? { prior: input.prior } : {}, revertplan: [...input.revertplan] };
414
+ }
415
+ function emulationstateof(input) {
416
+ return { runid: input.runid, tabid: input.tabid, origin: input.origin, layers: [], updatedat: input.now };
417
+ }
418
+ function applylayer(state, layer, at) {
419
+ const layers = [...state.layers.filter((item) => item.id !== layer.id), layer];
420
+ return { ...state, layers, updatedat: at };
421
+ }
422
+ function revertlayer(state, layerid, at) {
423
+ const layers = state.layers.map((layer) => layer.id === layerid && layer.revertedat === void 0 ? { ...layer, revertedat: at } : layer);
424
+ return { ...state, layers, updatedat: at };
425
+ }
426
+ function revertalllayers(state, at) {
427
+ const reverted = [...state.layers].reverse().filter((layer) => layer.revertedat === void 0);
428
+ const layers = state.layers.map((layer) => layer.revertedat === void 0 ? { ...layer, revertedat: at } : layer);
429
+ return { state: { ...state, layers, updatedat: at }, reverted };
430
+ }
431
+ function activelayers(state) {
432
+ return state ? state.layers.filter((layer) => layer.revertedat === void 0) : [];
433
+ }
434
+ function layernames(state) {
435
+ return activelayers(state).map((layer) => layer.name);
436
+ }
437
+ function stackedcount(state) {
438
+ return activelayers(state).length;
439
+ }
440
+ function locationrangevalid(latitude, longitude) {
441
+ return Number.isFinite(latitude) && Number.isFinite(longitude) && latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180;
442
+ }
443
+ function agentgrammarvalid(useragent) {
444
+ const text2 = useragent.trim();
445
+ if (text2.length === 0 || text2.length > 512) return false;
446
+ if (/[\r\n]/.test(text2)) return false;
447
+ if (!/^[A-Za-z0-9][A-Za-z0-9._+\-()/:; ,]*$/.test(text2)) return false;
448
+ return /\/\d/.test(text2) || /\d+\.\d+/.test(text2);
449
+ }
450
+ function permissiongrade(name) {
451
+ return name === "geolocation" || name === "camera" || name === "microphone" || name === "notifications" ? "powerful" : "standard";
452
+ }
453
+ function blackboxmatches(urlpattern, url) {
454
+ const patternmatch = /^(https:\/\/[^/]+)(\/.*)?$/.exec(urlpattern);
455
+ const urlmatch = /^(https:\/\/[^/]+)(\/.*)?$/.exec(url);
456
+ if (!patternmatch || !urlmatch) return false;
457
+ if (patternmatch[1] !== urlmatch[1]) return false;
458
+ const patternpath = (patternmatch[2] ?? "/").split("/").filter((segment) => segment.length > 0);
459
+ const urlpath = (urlmatch[2] ?? "/").split("/").filter((segment) => segment.length > 0);
460
+ const walk = (patternindex, urlindex) => {
461
+ if (patternindex >= patternpath.length) return urlindex >= urlpath.length;
462
+ const segment = patternpath[patternindex];
463
+ if (segment === void 0) return false;
464
+ if (segment === "**") return walk(patternindex + 1, urlindex) || urlindex < urlpath.length && walk(patternindex, urlindex + 1);
465
+ if (urlindex >= urlpath.length) return false;
466
+ if (segment !== "*" && segment !== urlpath[urlindex]) return false;
467
+ return walk(patternindex + 1, urlindex + 1);
468
+ };
469
+ return walk(0, 0);
470
+ }
471
+ function hideblackboxedframes(rules, frames) {
472
+ const patterns = rules.filter((rule) => rule.tracescope === "traces" || rule.tracescope === "both").flatMap((rule) => rule.urlpatterns);
473
+ if (patterns.length === 0) return frames;
474
+ return frames.filter((frame) => !patterns.some((pattern) => blackboxmatches(pattern, frame.url)));
475
+ }
476
+ function blackboxedurls(rules, urls) {
477
+ const patterns = rules.flatMap((rule) => rule.urlpatterns);
478
+ return urls.filter((url) => patterns.some((pattern) => blackboxmatches(pattern, url)));
479
+ }
480
+ function expirelayers(state, retention, now) {
481
+ if (retention === void 0) return state;
482
+ const layers = state.layers.map((layer) => {
483
+ if (layer.revertedat === void 0 || layer.prior === void 0 || layer.priorexpired === true) return layer;
484
+ if (now - layer.revertedat <= retention) return layer;
485
+ const { prior, ...metadata } = layer;
486
+ void prior;
487
+ return { ...metadata, priorexpired: true };
488
+ });
489
+ return { ...state, layers, updatedat: now };
490
+ }
491
+ function exportpresetlibrary(input) {
492
+ return { version: 1, devices: [...input.devices], networks: [...input.networks], locations: [...input.locations], agents: [...input.agents], exportedat: input.now };
493
+ }
494
+ function importpresetlibrary(value) {
495
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
496
+ const entry = value;
497
+ const devices = (Array.isArray(entry.devices) ? entry.devices : []).flatMap((preset) => {
498
+ const parsed = devicepresetof(preset);
499
+ return parsed !== void 0 ? [parsed] : [];
500
+ });
501
+ const networks = (Array.isArray(entry.networks) ? entry.networks : []).flatMap((preset) => {
502
+ const parsed = networkpresetof(preset);
503
+ return parsed !== void 0 ? [parsed] : [];
504
+ });
505
+ const locations = (Array.isArray(entry.locations) ? entry.locations : []).flatMap((preset) => {
506
+ const parsed = locationpresetof(preset);
507
+ return parsed !== void 0 ? [parsed] : [];
508
+ });
509
+ const agents = (Array.isArray(entry.agents) ? entry.agents : []).flatMap((preset) => {
510
+ const parsed = agentpresetof(preset);
511
+ return parsed !== void 0 ? [parsed] : [];
512
+ });
513
+ if (devices.length + networks.length + locations.length + agents.length === 0) return void 0;
514
+ return { version: typeof entry.version === "number" && Number.isInteger(entry.version) && entry.version >= 1 ? entry.version : 1, devices, networks, locations, agents, exportedat: typeof entry.exportedat === "number" ? entry.exportedat : Date.now() };
515
+ }
516
+ function locationconsentcovers(origin, latitude, longitude, consents) {
517
+ return consents.some((consent) => consent.origin === origin && consent.approved === true && consent.revokedat === void 0 && consent.latitude === latitude && consent.longitude === longitude);
518
+ }
519
+
336
520
  // httpclient.ts
337
521
  var httpkinds = ["fetchurl", "parsejson", "parsehtml", "callrest", "callgraphql"];
338
522
  var redirectstatuses = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
@@ -921,6 +1105,232 @@ function streamsummaries(raw) {
921
1105
  });
922
1106
  }
923
1107
 
1108
+ // profilers.ts
1109
+ var profilerkinds = ["measureflow", "heapshot", "trackmemory", "profilecpu", "watchshifts", "traceload", "annotatetrace", "replaytrace", "capturesourcemaps"];
1110
+ var flowmetricnames = ["navigation", "paint", "lcp", "fid", "interaction", "blocking"];
1111
+ var tracecategories = ["navigation", "scripting", "rendering", "painting", "loading", "network"];
1112
+ function attachtargetof(value) {
1113
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1114
+ const entry = value;
1115
+ const kinds = ["page", "iframe", "worker", "serviceworker"];
1116
+ const kind = typeof entry.kind === "string" && kinds.includes(entry.kind) ? entry.kind : void 0;
1117
+ const url = typeof entry.url === "string" && entry.url.trim() ? entry.url.trim() : void 0;
1118
+ if (kind === void 0 || url === void 0) return void 0;
1119
+ if (kind !== "page" && !/^https:\/\//.test(url)) return void 0;
1120
+ return { kind, url };
1121
+ }
1122
+ function flowspecof(value) {
1123
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1124
+ const entry = value;
1125
+ const prefix = typeof entry.prefix === "string" && entry.prefix.trim() ? entry.prefix.trim() : void 0;
1126
+ const steps = Array.isArray(entry.steps) ? entry.steps.filter((step) => typeof step === "string" && step.trim().length > 0) : [];
1127
+ const metrics = Array.isArray(entry.metrics) ? entry.metrics.filter((metric) => typeof metric === "string" && flowmetricnames.includes(metric)) : [];
1128
+ if (prefix === void 0 || steps.length === 0 || metrics.length === 0) return void 0;
1129
+ return { prefix, steps, metrics };
1130
+ }
1131
+ function stepwindows(spec, marks) {
1132
+ const windows = [];
1133
+ for (const stepid of spec.steps) {
1134
+ const start = marks.find((mark) => mark.type === "mark" && mark.name === `${spec.prefix}:${stepid}:start`);
1135
+ const end = marks.find((mark) => mark.type === "mark" && mark.name === `${spec.prefix}:${stepid}:end`);
1136
+ if (start === void 0 || end === void 0) continue;
1137
+ windows.push({ stepid, start: start.start, end: Math.max(end.start, start.start) });
1138
+ }
1139
+ return windows;
1140
+ }
1141
+ function measure(input) {
1142
+ const metrics = [];
1143
+ const windows = stepwindows(input.spec, input.entries.filter((entry) => entry.type === "mark"));
1144
+ const stepsof = (start, end) => windows.filter((window) => window.end >= start && window.start <= end).map((window) => window.stepid);
1145
+ const push = (name, start, end, steps) => {
1146
+ if (!input.spec.metrics.includes(name)) return;
1147
+ metrics.push({ id: `${input.runid}-${input.stepid}-${name}-${metrics.length}`, runid: input.runid, stepid: input.stepid, name, start, end, duration: Math.max(0, end - start), steps, at: input.now });
1148
+ };
1149
+ const navigation = input.entries.find((entry) => entry.type === "navigation");
1150
+ if (navigation !== void 0) push("navigation", navigation.start, navigation.start + navigation.duration, stepsof(navigation.start, navigation.start + navigation.duration));
1151
+ for (const paint of input.entries.filter((entry) => entry.type === "paint")) {
1152
+ if (!input.spec.metrics.includes("paint")) break;
1153
+ push("paint", paint.start, paint.start + paint.duration, stepsof(paint.start, paint.start + paint.duration));
1154
+ }
1155
+ const lcps = input.entries.filter((entry) => entry.type === "largest-contentful-paint");
1156
+ const lcp = lcps.length > 0 ? lcps.reduce((largest, entry) => entry.start > largest.start ? entry : largest) : void 0;
1157
+ if (lcp !== void 0) push("lcp", lcp.start, lcp.start + lcp.duration, stepsof(lcp.start, lcp.start + lcp.duration));
1158
+ const firstinput = input.entries.find((entry) => entry.type === "first-input");
1159
+ if (firstinput !== void 0) push("fid", firstinput.start, firstinput.start + firstinput.duration, stepsof(firstinput.start, firstinput.start + firstinput.duration));
1160
+ const interactions = input.entries.filter((entry) => entry.type === "event");
1161
+ if (interactions.length > 0) {
1162
+ const start = interactions.reduce((earliest, entry) => entry.start < earliest.start ? entry : earliest).start;
1163
+ const end = interactions.reduce((latest, entry) => entry.start + entry.duration > latest ? entry.start + entry.duration : latest, start);
1164
+ push("interaction", start, end, stepsof(start, end));
1165
+ }
1166
+ for (const window of windows) {
1167
+ if (!input.spec.metrics.includes("blocking")) break;
1168
+ const blocking = input.entries.filter((entry) => entry.type === "longtask" && entry.start >= window.start && entry.start <= window.end).reduce((total, entry) => total + Math.max(0, entry.duration - 50), 0);
1169
+ metrics.push({ id: `${input.runid}-${input.stepid}-blocking-${window.stepid}`, runid: input.runid, stepid: input.stepid, name: "blocking", start: window.start, end: window.end, duration: blocking, steps: [window.stepid], at: input.now });
1170
+ }
1171
+ return metrics;
1172
+ }
1173
+ function heapintervalallowed(lastcapturedat, interval, now) {
1174
+ if (interval === void 0 || lastcapturedat === void 0) return true;
1175
+ return now - lastcapturedat >= interval;
1176
+ }
1177
+ function heapsnap(input) {
1178
+ return { id: input.id, runid: input.runid, stepid: input.stepid, origin: input.origin, bytesize: input.usedbytes, nodecount: input.nodecount, capturedat: input.now };
1179
+ }
1180
+ function growsampleof(input) {
1181
+ return { id: input.id, runid: input.runid, stepid: input.stepid, usedbytes: input.usedbytes, limitbytes: input.limitbytes, at: input.now };
1182
+ }
1183
+ function growthtrend(input) {
1184
+ const ordered = [...input.samples].sort((left, right) => left.at - right.at);
1185
+ const first = ordered[0];
1186
+ const last = ordered[ordered.length - 1];
1187
+ const computed = first !== void 0 && last !== void 0 && last.at > first.at ? (last.usedbytes - first.usedbytes) / (last.at - first.at) : 0;
1188
+ const flaggedsteps = [];
1189
+ for (let index = 1; index < ordered.length; index += 1) {
1190
+ const previous = ordered[index - 1];
1191
+ const current = ordered[index];
1192
+ if (previous === void 0 || current === void 0) continue;
1193
+ const growth = current.at > previous.at ? (current.usedbytes - previous.usedbytes) / (current.at - previous.at) : 0;
1194
+ if (growth > input.slope && !flaggedsteps.includes(current.stepid)) flaggedsteps.push(current.stepid);
1195
+ }
1196
+ return { runid: input.runid, slope: computed, samples: ordered.length, flaggedsteps, at: input.now };
1197
+ }
1198
+ function cpusnap(input) {
1199
+ const ranked = /* @__PURE__ */ new Map();
1200
+ for (const sample of input.samples) ranked.set(sample.name, (ranked.get(sample.name) ?? 0) + sample.time);
1201
+ const hotfunctions = [...ranked.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0])).map((entry) => entry[0]);
1202
+ return { id: input.id, runid: input.runid, stepid: input.stepid, origin: input.origin, duration: input.duration, samplecount: input.samples.length, hotfunctions, at: input.now };
1203
+ }
1204
+ function shiftentryof(value) {
1205
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1206
+ const entry = value;
1207
+ const score = typeof entry.score === "number" && Number.isFinite(entry.score) && entry.score >= 0 ? entry.score : void 0;
1208
+ const starttime = typeof entry.starttime === "number" && Number.isFinite(entry.starttime) ? entry.starttime : void 0;
1209
+ if (score === void 0 || starttime === void 0) return void 0;
1210
+ const selectors = Array.isArray(entry.selectors) ? entry.selectors.filter((selector) => typeof selector === "string" && selector.trim().length > 0) : [];
1211
+ return { id: typeof entry.id === "string" ? entry.id : "", runid: typeof entry.runid === "string" ? entry.runid : "", stepid: typeof entry.stepid === "string" ? entry.stepid : "", score, starttime, selectors, at: typeof entry.at === "number" ? entry.at : starttime };
1212
+ }
1213
+ function tracestart(input) {
1214
+ return { id: input.id, runid: input.runid, stepid: input.stepid, origin: input.origin, categories: [...new Set(input.categories)], bytesize: 0, events: 0, annotations: [], startedat: input.now, endedat: input.now };
1215
+ }
1216
+ function tracetofile(trace, events) {
1217
+ const payload = { devthinktrace: "1.1.47", runid: trace.runid, origin: trace.origin, categories: trace.categories, startedat: trace.startedat, endedat: trace.endedat, annotations: trace.annotations, traceevents: events.map((event) => ({ name: event.name, cat: event.category, offset: event.offset })) };
1218
+ const content = JSON.stringify(payload);
1219
+ return { content, bytesize: content.length, events: events.length };
1220
+ }
1221
+ function annotationof(value) {
1222
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1223
+ const entry = value;
1224
+ const stepid = typeof entry.stepid === "string" && entry.stepid.trim() ? entry.stepid.trim() : void 0;
1225
+ const label = typeof entry.label === "string" && entry.label.trim() ? entry.label.trim() : void 0;
1226
+ if (stepid === void 0 || label === void 0) return void 0;
1227
+ const offset = typeof entry.offset === "number" && Number.isFinite(entry.offset) && entry.offset >= 0 ? entry.offset : 0;
1228
+ return { stepid, label, offset };
1229
+ }
1230
+ function annotatetrace(input) {
1231
+ const aligned = input.annotations.map((annotation) => {
1232
+ const entry = input.timeline.find((item) => item.stepid === annotation.stepid);
1233
+ if (entry === void 0) return annotation;
1234
+ return { ...annotation, offset: Math.max(0, entry.time - input.trace.startedat) };
1235
+ });
1236
+ return { ...input.trace, annotations: aligned, endedat: Math.max(input.trace.endedat, input.now) };
1237
+ }
1238
+ function replaytrace(content) {
1239
+ let parsed;
1240
+ try {
1241
+ parsed = JSON.parse(content);
1242
+ } catch {
1243
+ throw new Error("The trace file is not valid json.");
1244
+ }
1245
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("The trace file is not a json object.");
1246
+ const record2 = parsed;
1247
+ const runid = typeof record2.runid === "string" ? record2.runid : "";
1248
+ const annotations = Array.isArray(record2.annotations) ? record2.annotations.flatMap((item) => {
1249
+ const annotation = annotationof(item);
1250
+ return annotation !== void 0 ? [annotation] : [];
1251
+ }) : [];
1252
+ const rawevents = Array.isArray(record2.traceevents) ? record2.traceevents : [];
1253
+ const categories = {};
1254
+ const events = rawevents.flatMap((item) => {
1255
+ if (!item || typeof item !== "object") return [];
1256
+ const entry = item;
1257
+ if (typeof entry.name !== "string" || typeof entry.cat !== "string" || typeof entry.offset !== "number") return [];
1258
+ const offset = entry.offset;
1259
+ categories[entry.cat] = (categories[entry.cat] ?? 0) + 1;
1260
+ const annotation = annotations.find((candidate) => Math.abs(candidate.offset - offset) < 1);
1261
+ return [{ name: entry.name, category: entry.cat, offset, ...annotation !== void 0 ? { stepid: annotation.stepid } : {} }];
1262
+ });
1263
+ return { traceid: typeof record2.id === "string" ? record2.id : "", runid, categories, events, annotations };
1264
+ }
1265
+ function mapurlof(scripturl, source) {
1266
+ const match = /[#@]\s*sourceMappingURL=(\S+)/.exec(source);
1267
+ if (match === null || match[1] === void 0) return void 0;
1268
+ try {
1269
+ return new URL(match[1], scripturl).toString();
1270
+ } catch {
1271
+ return void 0;
1272
+ }
1273
+ }
1274
+ function capturesourcemaps(input) {
1275
+ return input.scripts.flatMap((script) => {
1276
+ const mapurl = mapurlof(script.url, script.source);
1277
+ if (mapurl === void 0) return [];
1278
+ return [{ id: `${input.runid}-${script.url}`, runid: input.runid, stepid: input.stepid, origin: input.origin, scripturl: script.url, mapurl, parsed: false, at: input.now }];
1279
+ });
1280
+ }
1281
+ function decodevlq(segment) {
1282
+ const values = [];
1283
+ let shift = 0;
1284
+ let value = 0;
1285
+ for (const character of segment) {
1286
+ const digit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(character);
1287
+ if (digit < 0) return void 0;
1288
+ value += (digit & 31) << shift;
1289
+ shift += 5;
1290
+ if ((digit & 32) === 0) {
1291
+ const negative = (value & 1) === 1;
1292
+ values.push(negative ? -(value >>> 1) : value >>> 1);
1293
+ value = 0;
1294
+ shift = 0;
1295
+ }
1296
+ }
1297
+ return values.length > 0 ? values : void 0;
1298
+ }
1299
+ function rewritesourcelocation(input, map) {
1300
+ const sources = Array.isArray(map.sources) ? map.sources.filter((source2) => typeof source2 === "string") : [];
1301
+ if (sources.length === 0 || typeof map.mappings !== "string" || map.mappings.length === 0) return void 0;
1302
+ const lines = map.mappings.split(";");
1303
+ if (input.line >= lines.length) return void 0;
1304
+ let sourceindex = 0;
1305
+ let sourceline = 0;
1306
+ for (let line = 0; line <= input.line; line += 1) {
1307
+ const linemappings = lines[line];
1308
+ if (linemappings === void 0) continue;
1309
+ const first = linemappings.split(",")[0] ?? "";
1310
+ if (first.length === 0) continue;
1311
+ const values = decodevlq(first);
1312
+ if (values === void 0 || values.length < 4) continue;
1313
+ sourceindex = Math.max(0, sourceindex + (values[1] ?? 0));
1314
+ sourceline = Math.max(0, sourceline + (values[2] ?? 0));
1315
+ }
1316
+ const targetmappings = lines[input.line];
1317
+ const target = targetmappings !== void 0 ? targetmappings.split(",")[0] ?? "" : "";
1318
+ if (target.length === 0) return void 0;
1319
+ const source = sources[Math.min(sources.length - 1, sourceindex)];
1320
+ if (source === void 0) return void 0;
1321
+ return { url: source, line: sourceline };
1322
+ }
1323
+ function expireprofilerecords(input) {
1324
+ const retention = input.retention;
1325
+ if (retention === void 0) return { heaps: input.heaps, profiles: input.profiles, traces: input.traces };
1326
+ const expired = (at) => input.now - at > retention;
1327
+ return {
1328
+ heaps: input.heaps.map((heap) => expired(heap.capturedat) && heap.bytesexpired !== true ? { ...heap, bytesexpired: true } : heap),
1329
+ profiles: input.profiles.map((profile) => expired(profile.at) && profile.samplesexpired !== true ? { ...profile, samplesexpired: true } : profile),
1330
+ traces: input.traces.map((trace) => expired(trace.endedat) && trace.bytesexpired !== true ? { ...trace, bytesexpired: true } : trace)
1331
+ };
1332
+ }
1333
+
924
1334
  // memory.ts
925
1335
  var sessionmemory = class {
926
1336
  constructor(adapter) {
@@ -2164,6 +2574,210 @@ var sessionmemory = class {
2164
2574
  async getlevelsummaries() {
2165
2575
  return await this.adapter.get("levelsummaries") ?? [];
2166
2576
  }
2577
+ /** Stores one measured flow metric of the run beside its step span; the flow series stays per run. */
2578
+ async addflowmetric(metric) {
2579
+ const records = await this.getflowmetrics();
2580
+ await this.adapter.set("flowmetrics", [metric, ...records]);
2581
+ }
2582
+ /** Returns every stored flow metric, newest first. */
2583
+ async getflowmetrics() {
2584
+ return await this.adapter.get("flowmetrics") ?? [];
2585
+ }
2586
+ /** Returns the flow metrics of one run, newest first. */
2587
+ async listflowmetrics(runid) {
2588
+ const records = await this.getflowmetrics();
2589
+ return records.filter((metric) => metric.runid === runid);
2590
+ }
2591
+ /** Stores one heap snapshot record with its byte and node counts; the user configured profile retention window expires the heavy snapshot bytes while the counts survive. */
2592
+ async setheaprecord(heap) {
2593
+ const records = (await this.adapter.get("heaprecords") ?? []).filter((item) => item.id !== heap.id);
2594
+ const retention = (await this.getsettings())?.profileretention;
2595
+ const { heaps } = expireprofilerecords({ heaps: [heap, ...records], profiles: [], traces: [], retention, now: Date.now() });
2596
+ await this.adapter.set("heaprecords", heaps);
2597
+ }
2598
+ /** Returns every stored heap snapshot record, newest first. */
2599
+ async getheaprecords() {
2600
+ return await this.adapter.get("heaprecords") ?? [];
2601
+ }
2602
+ /** Stores one heap growth sample taken beside a step. */
2603
+ async addgrowsample(sample) {
2604
+ const records = await this.adapter.get("growsamples") ?? [];
2605
+ await this.adapter.set("growsamples", [sample, ...records]);
2606
+ }
2607
+ /** Returns every stored heap growth sample, newest first. */
2608
+ async getgrowsamples() {
2609
+ return await this.adapter.get("growsamples") ?? [];
2610
+ }
2611
+ /** Returns the heap growth samples of one run, newest first. */
2612
+ async listgrowsamples(runid) {
2613
+ const records = await this.getgrowsamples();
2614
+ return records.filter((sample) => sample.runid === runid);
2615
+ }
2616
+ /** Stores one computed heap growth trend of a run with its slope and flagged steps, replacing the previous trend of the run. */
2617
+ async settrend(trend) {
2618
+ const records = await this.adapter.get("memorytrends") ?? [];
2619
+ await this.adapter.set("memorytrends", [trend, ...records.filter((item) => item.runid !== trend.runid)]);
2620
+ }
2621
+ /** Returns every stored heap growth trend, newest first. */
2622
+ async gettrends() {
2623
+ return await this.adapter.get("memorytrends") ?? [];
2624
+ }
2625
+ /** Stores one cpu profile record with its sample count and hot function list; the profile retention window expires the heavy sample payload while the counts and hot functions survive. */
2626
+ async setcpuprofile(profile) {
2627
+ const records = (await this.adapter.get("cpuprofiles") ?? []).filter((item) => item.id !== profile.id);
2628
+ const retention = (await this.getsettings())?.profileretention;
2629
+ const { profiles } = expireprofilerecords({ heaps: [], profiles: [profile, ...records], traces: [], retention, now: Date.now() });
2630
+ await this.adapter.set("cpuprofiles", profiles);
2631
+ }
2632
+ /** Returns every stored cpu profile record, newest first. */
2633
+ async getcpuprofiles() {
2634
+ return await this.adapter.get("cpuprofiles") ?? [];
2635
+ }
2636
+ /** Stores one layout shift entry with its score and impacted selectors. */
2637
+ async addshiftentry(entry) {
2638
+ const records = await this.adapter.get("shiftentries") ?? [];
2639
+ await this.adapter.set("shiftentries", [entry, ...records]);
2640
+ }
2641
+ /** Returns every stored layout shift entry, newest first. */
2642
+ async getshiftentries() {
2643
+ return await this.adapter.get("shiftentries") ?? [];
2644
+ }
2645
+ /** Stores one trace record with its category list, byte size and step annotations; the profile retention window expires the heavy trace bytes while the metadata and annotations survive. */
2646
+ async settracerecord(trace) {
2647
+ const records = (await this.adapter.get("tracerecords") ?? []).filter((item) => item.id !== trace.id);
2648
+ const retention = (await this.getsettings())?.profileretention;
2649
+ const { traces } = expireprofilerecords({ heaps: [], profiles: [], traces: [trace, ...records], retention, now: Date.now() });
2650
+ await this.adapter.set("tracerecords", traces);
2651
+ }
2652
+ /** Returns every stored trace record, newest first. */
2653
+ async gettracerecords() {
2654
+ return await this.adapter.get("tracerecords") ?? [];
2655
+ }
2656
+ /** Returns the trace records filtered by run and applied categories. */
2657
+ async listtraces(filter) {
2658
+ const records = await this.gettracerecords();
2659
+ return records.filter((trace) => (filter.runid === void 0 || trace.runid === filter.runid) && (filter.categories === void 0 || filter.categories.every((category) => trace.categories.includes(category))));
2660
+ }
2661
+ /** Stores the exported file content of one trace beside its record; the retention window drops the file bytes of expired traces while the record survives. */
2662
+ async settracefile(traceid, content) {
2663
+ const records = (await this.adapter.get("tracefiles") ?? []).filter((item) => item.traceid !== traceid);
2664
+ const trace = (await this.gettracerecords()).find((item) => item.id === traceid);
2665
+ const retention = (await this.getsettings())?.profileretention;
2666
+ const kept = retention === void 0 || trace === void 0 || Date.now() - trace.endedat <= retention ? [{ traceid, content, savedat: Date.now() }, ...records] : records;
2667
+ await this.adapter.set("tracefiles", kept);
2668
+ }
2669
+ /** Returns the exported file content of one trace, or undefined when the retention window dropped the bytes. */
2670
+ async gettracefile(traceid) {
2671
+ const records = await this.adapter.get("tracefiles") ?? [];
2672
+ return records.find((item) => item.traceid === traceid)?.content;
2673
+ }
2674
+ /** Stores one source map reference of a run with its script url, map url and parsed state. */
2675
+ async setsourcemapref(ref) {
2676
+ const records = (await this.adapter.get("sourcemaprefs") ?? []).filter((item) => item.id !== ref.id);
2677
+ await this.adapter.set("sourcemaprefs", [ref, ...records]);
2678
+ }
2679
+ /** Returns every stored source map reference, newest first. */
2680
+ async getsourcemaps() {
2681
+ return await this.adapter.get("sourcemaprefs") ?? [];
2682
+ }
2683
+ /** Stores one source map capture consent decision per origin, replacing the previous decision of its id. */
2684
+ async setsourcemapconsent(consent) {
2685
+ const records = (await this.adapter.get("sourcemapconsents") ?? []).filter((item) => item.id !== consent.id);
2686
+ await this.adapter.set("sourcemapconsents", [consent, ...records]);
2687
+ }
2688
+ /** Returns every source map capture consent decision, newest first. */
2689
+ async getsourcemapconsents() {
2690
+ return await this.adapter.get("sourcemapconsents") ?? [];
2691
+ }
2692
+ /** Revokes every approved source map consent of one origin so the next capture needs a new reviewed prompt. */
2693
+ async revokesourcemapconsents(origin, at) {
2694
+ const records = await this.getsourcemapconsents();
2695
+ let revoked = 0;
2696
+ const updated = records.map((consent) => {
2697
+ if (consent.origin !== origin || consent.revokedat !== void 0) return consent;
2698
+ revoked += 1;
2699
+ return { ...consent, revokedat: at };
2700
+ });
2701
+ await this.adapter.set("sourcemapconsents", updated);
2702
+ return revoked;
2703
+ }
2704
+ /** Stores the emulation state of one run keyed by its run id; the reverted layer prior states expire after the user configured retention window while the layer history always survives. */
2705
+ async setemulationstate(state) {
2706
+ const retention = (await this.getsettings())?.emulationretention;
2707
+ await this.adapter.set(`emulationstate${state.runid}`, expirelayers(state, retention, Date.now()));
2708
+ }
2709
+ /** Returns the persisted emulation state of one run so the layers survive service worker restarts. */
2710
+ async getemulationstate(runid) {
2711
+ return this.adapter.get(`emulationstate${runid}`);
2712
+ }
2713
+ /** Returns the active and past layers of one run, newest last in apply order; the listlayers accessor of the emulation memory. */
2714
+ async listlayers(runid) {
2715
+ const state = await this.getemulationstate(runid);
2716
+ return state?.layers ?? [];
2717
+ }
2718
+ /** Stores one user curated device preset by its name so the preset library stays user data instead of a hardcoded list. */
2719
+ async setdevicepreset(preset) {
2720
+ const records = (await this.adapter.get("devicepresets") ?? []).filter((item) => item.name !== preset.name);
2721
+ await this.adapter.set("devicepresets", [...records, preset]);
2722
+ }
2723
+ /** Returns every user curated device preset. */
2724
+ async getdevicepresets() {
2725
+ return await this.adapter.get("devicepresets") ?? [];
2726
+ }
2727
+ /** Stores one user curated network preset by its name with editable values. */
2728
+ async setnetworkpreset(preset) {
2729
+ const records = (await this.adapter.get("networkpresets") ?? []).filter((item) => item.name !== preset.name);
2730
+ await this.adapter.set("networkpresets", [...records, preset]);
2731
+ }
2732
+ /** Returns every user curated network preset. */
2733
+ async getnetworkpresets() {
2734
+ return await this.adapter.get("networkpresets") ?? [];
2735
+ }
2736
+ /** Stores one user curated location preset by its name. */
2737
+ async setlocationpreset(preset) {
2738
+ const records = (await this.adapter.get("locationpresets") ?? []).filter((item) => item.name !== preset.name);
2739
+ await this.adapter.set("locationpresets", [...records, preset]);
2740
+ }
2741
+ /** Returns every user curated location preset. */
2742
+ async getlocationpresets() {
2743
+ return await this.adapter.get("locationpresets") ?? [];
2744
+ }
2745
+ /** Stores one user curated agent preset by its name. */
2746
+ async setagentpreset(preset) {
2747
+ const records = (await this.adapter.get("agentpresets") ?? []).filter((item) => item.name !== preset.name);
2748
+ await this.adapter.set("agentpresets", [...records, preset]);
2749
+ }
2750
+ /** Returns every user curated agent preset. */
2751
+ async getagentpresets() {
2752
+ return await this.adapter.get("agentpresets") ?? [];
2753
+ }
2754
+ /** Replaces the blackbox rule set of one origin so third party script blackboxing stays scoped per origin. */
2755
+ async setblackboxrules(origin, rules) {
2756
+ const records = (await this.adapter.get("blackboxrules") ?? []).filter((item) => item.origin !== origin);
2757
+ await this.adapter.set("blackboxrules", [...records, { origin, rules }]);
2758
+ }
2759
+ /** Returns every stored blackbox rule set with its origin. */
2760
+ async getblackboxrules() {
2761
+ return await this.adapter.get("blackboxrules") ?? [];
2762
+ }
2763
+ /** Records one permission override of a run with its prior state captured for the exact restore. */
2764
+ async addpermissionoverride(record2) {
2765
+ const records = (await this.adapter.get("permissionoverrides") ?? []).filter((item) => item.id !== record2.id);
2766
+ await this.adapter.set("permissionoverrides", [record2, ...records]);
2767
+ }
2768
+ /** Returns the permission override history with restore states, newest first. */
2769
+ async getpermissionoverrides() {
2770
+ return await this.adapter.get("permissionoverrides") ?? [];
2771
+ }
2772
+ /** Stores one location consent decision per origin, replacing the previous decision of its id. */
2773
+ async setlocationconsent(consent) {
2774
+ const records = (await this.adapter.get("locationconsents") ?? []).filter((item) => item.id !== consent.id);
2775
+ await this.adapter.set("locationconsents", [consent, ...records]);
2776
+ }
2777
+ /** Returns every location consent decision, newest first. */
2778
+ async getlocationconsents() {
2779
+ return await this.adapter.get("locationconsents") ?? [];
2780
+ }
2167
2781
  };
2168
2782
  function mediakindof(record2) {
2169
2783
  if ("pages" in record2) return "pdf";
@@ -3110,9 +3724,9 @@ function polldecision(input) {
3110
3724
  }
3111
3725
 
3112
3726
  // policy.ts
3113
- var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles", "attachcdp", "detachcdp", "cdpcmd", "overridescript"]);
3727
+ var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles", "attachcdp", "detachcdp", "cdpcmd", "overridescript", "heapshot", "profilecpu", "capturesourcemaps", "emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission"]);
3114
3728
  var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction", "capturebodies", "setbreakpoint", "stepcode", "watchexpr"]);
3115
- var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks", "watchcdp"]);
3729
+ var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace", "blackboxscripts"]);
3116
3730
  var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
3117
3731
  var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
3118
3732
  var targetactions = /* @__PURE__ */ new Set(["inspect", "focus", "click", "type", "scroll", "select", "hover", "clickdeep", "rightclick", "doubleclick", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "highlight", "setattribute", "removeattribute", "waitfor", "shiftclick", "typetime", "appendtext", "setvalue", "typeedit", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "expanddetails", "verifyvisible", "verifyenabled", "pierceshadow", "deriveselector", "fingerprintsection", "submitform", "retryform", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword", "scrapetable", "paginateextract", "shotelement", "captureframe", "shotcanvas"]);
@@ -3130,6 +3744,8 @@ var netwatchactions = /* @__PURE__ */ new Set(["watchrequests", "readheaders", "
3130
3744
  var controlactions = /* @__PURE__ */ new Set(["blockrequest", "mockresponse", "rewriteheaders", "setcookies", "readcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles"]);
3131
3745
  var debugactions = /* @__PURE__ */ new Set(["watchconsole", "watcherrors", "watchtasks"]);
3132
3746
  var cdpactions = /* @__PURE__ */ new Set(["attachcdp", "detachcdp", "cdpcmd", "watchcdp", "setbreakpoint", "stepcode", "watchexpr", "overridescript"]);
3747
+ var profileractions = /* @__PURE__ */ new Set(["measureflow", "heapshot", "trackmemory", "profilecpu", "watchshifts", "traceload", "annotatetrace", "replaytrace", "capturesourcemaps"]);
3748
+ var emulationactions = /* @__PURE__ */ new Set(["emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "blackboxscripts"]);
3133
3749
  var credentialheaders = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2", "set-cookie", "api-key", "x-api-key", "x-auth-token", "x-session-token", "proxy-authorization"]);
3134
3750
  var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
3135
3751
  var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
@@ -3154,8 +3770,14 @@ function isdebugkind(kind) {
3154
3770
  function iscdpkind(kind) {
3155
3771
  return cdpactions.has(kind);
3156
3772
  }
3773
+ function isprofilekind(kind) {
3774
+ return profileractions.has(kind);
3775
+ }
3776
+ function isemulationkind(kind) {
3777
+ return emulationactions.has(kind);
3778
+ }
3157
3779
  function observationmodeof(kind) {
3158
- if (watchactions.has(kind) || debugactions.has(kind) || cdpactions.has(kind) && kind === "watchcdp" || kind === "waitquiet") return "watching";
3780
+ if (watchactions.has(kind) || debugactions.has(kind) || profileractions.has(kind) && kind !== "heapshot" && kind !== "replaytrace" && kind !== "annotatetrace" && kind !== "capturesourcemaps" && kind !== "profilecpu" || cdpactions.has(kind) && kind === "watchcdp" || kind === "waitquiet") return "watching";
3159
3781
  if (kind === "diffsnapshots") return "diffing";
3160
3782
  return "passive";
3161
3783
  }
@@ -4384,6 +5006,31 @@ function debuggerconsentcovers(origin, domains, grants) {
4384
5006
  if (grants.some((grant) => grant.origin === origin && grant.revokedat !== void 0)) return { allowed: false, reason: `The debugger consent on ${origin} was revoked; approve a new prompt before the devtools protocol runs again.` };
4385
5007
  return { allowed: false, reason: `The devtools protocol on ${origin} needs the reviewed debugger consent for ${needed.join(", ")} first; approve the prompt with the domain allowlist shown in the review panel.` };
4386
5008
  }
5009
+ function targetgate(input) {
5010
+ const base = debuggate(input.session, input.tabid, input.origin, input.now);
5011
+ if (!base.allowed) return base;
5012
+ for (const target of input.targets) {
5013
+ if (target.kind === "page") continue;
5014
+ const origincheckresult = origincheck(input.session, target.url);
5015
+ if (!origincheckresult.allowed) return { allowed: false, reason: `The ${target.kind} target ${target.url} stays outside the granted origins; profiling refuses to attach.` };
5016
+ }
5017
+ if (input.grants === void 0) return { allowed: true };
5018
+ const consent = debuggerconsentcovers(input.origin, [], input.grants);
5019
+ if (!consent.allowed) return { allowed: false, reason: `The profiling step on ${input.origin} needs the reviewed debugger grant of the origin first; approve the prompt with the profiling derivation shown in the review panel.` };
5020
+ return { allowed: true };
5021
+ }
5022
+ function sourcemapconsentcovers(origin, consents) {
5023
+ const covering = consents.find((consent) => consent.origin === origin && consent.approved === true && consent.revokedat === void 0);
5024
+ if (covering) return { allowed: true };
5025
+ if (consents.some((consent) => consent.origin === origin && consent.revokedat !== void 0)) return { allowed: false, reason: `The source map capture consent on ${origin} was revoked; approve a new prompt before another map file is fetched.` };
5026
+ return { allowed: false, reason: `The source map capture on ${origin} needs the reviewed per origin consent first; approve the prompt shown in the review panel.` };
5027
+ }
5028
+ function profileretentionwindow(settings) {
5029
+ return settings?.profileretention;
5030
+ }
5031
+ function traceceilingof(settings) {
5032
+ return settings?.traceceiling;
5033
+ }
4387
5034
  function validatebreakpointcondition(condition) {
4388
5035
  const expression = condition.trim();
4389
5036
  if (expression.length === 0) return { allowed: false, reason: "The breakpoint condition must not be empty." };
@@ -4413,6 +5060,85 @@ function pauseretentionwindow(settings) {
4413
5060
  function breakpointceilingof(settings) {
4414
5061
  return settings?.breakpointceiling;
4415
5062
  }
5063
+ function emugate(input) {
5064
+ const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now: input.now, action: "emulate the run tab" });
5065
+ if (!gate.allowed) return gate;
5066
+ if (!input.plan || input.plan.state !== "approved") return { allowed: false, reason: "Emulation layers need an approved plan before they apply." };
5067
+ let options = {};
5068
+ try {
5069
+ options = parseoptions(input.step);
5070
+ } catch {
5071
+ options = {};
5072
+ }
5073
+ if (options.reviewed !== true) return { allowed: false, reason: `The ${input.step.kind} layer needs the explicit reviewed flag before any mask applies.` };
5074
+ if (revertplanof(options.revertplan) === void 0) return { allowed: false, reason: `Every ${input.step.kind} layer needs a reviewed revert plan beside it before any mask applies.` };
5075
+ return { allowed: true };
5076
+ }
5077
+ function emulationstackallowed(plan, kind, active) {
5078
+ if (!plan) return { allowed: false, reason: "Layer stacking needs the reviewed plan first." };
5079
+ const listed = plan.steps.filter((step) => step.kind === kind).length;
5080
+ if (active >= listed) return { allowed: false, reason: `The plan lists ${listed} reviewed ${kind} step${listed === 1 ? "" : "s"} and ${active} layer${active === 1 ? "" : "s"} of that family are already active; stacking beyond the reviewed plan is refused.` };
5081
+ return { allowed: true };
5082
+ }
5083
+ function locationconsentgate(origin, latitude, longitude, consents) {
5084
+ if (consents.some((consent) => consent.origin === origin && consent.revokedat !== void 0)) return { allowed: false, reason: `The location consent on ${origin} was revoked; approve a new prompt before the location override runs again.` };
5085
+ if (locationconsentcovers(origin, latitude, longitude, consents)) return { allowed: true };
5086
+ return { allowed: false, reason: `The location override of ${latitude}, ${longitude} on ${origin} needs the reviewed location consent first; approve the prompt with the coordinates shown in the review panel.` };
5087
+ }
5088
+ function emulationretentionwindow(settings) {
5089
+ return settings?.emulationretention;
5090
+ }
5091
+ function validateemulationgrammar(step, options) {
5092
+ const kind = step.kind;
5093
+ if (revertplanof(options.revertplan) === void 0) return { allowed: false, reason: `Every ${kind} layer needs a reviewed revert plan before any mask applies.` };
5094
+ if (kind === "emulatedevice") {
5095
+ const preset = devicepresetof(options.device);
5096
+ if (!preset) return { allowed: false, reason: "The device layer needs a reviewed preset with a name, positive integer width and height and a positive pixel ratio." };
5097
+ if (options.reload !== void 0 && typeof options.reload !== "boolean") return { allowed: false, reason: "The reviewed reload flag must be a boolean; the page reloads only when the reviewed plan asks." };
5098
+ return { allowed: true };
5099
+ }
5100
+ if (kind === "emulatenetwork") {
5101
+ const preset = networkpresetof(options.network);
5102
+ if (!preset) return { allowed: false, reason: "The network layer needs a reviewed preset with a name and zero or positive latency, download and upload bounds." };
5103
+ if (options.window !== void 0 && (typeof options.window !== "number" || !Number.isFinite(options.window) || options.window < 0)) return { allowed: false, reason: "The reviewed offline window must be zero or a positive number of milliseconds with no code ceiling." };
5104
+ return { allowed: true };
5105
+ }
5106
+ if (kind === "emulatelocate") {
5107
+ const preset = locationpresetof(options.location);
5108
+ if (!preset) return { allowed: false, reason: "The location layer needs a reviewed preset with a name, a latitude inside -90 and 90, a longitude inside -180 and 180 and a zero or positive accuracy radius." };
5109
+ if (!locationrangevalid(preset.latitude, preset.longitude)) return { allowed: false, reason: "The reviewed latitude must stay inside -90 and 90 degrees and the longitude inside -180 and 180 degrees." };
5110
+ return { allowed: true };
5111
+ }
5112
+ if (kind === "setuseragent") {
5113
+ const preset = agentpresetof(options.agent);
5114
+ if (!preset) return { allowed: false, reason: "The agent layer needs a reviewed preset with a user agent string of the reviewed grammar, a platform and a non-empty brand list." };
5115
+ if (!agentgrammarvalid(preset.useragent)) return { allowed: false, reason: "The reviewed user agent string must use the reviewed grammar of tokens, separators and version marks without line breaks." };
5116
+ return { allowed: true };
5117
+ }
5118
+ if (kind === "overridepermission") {
5119
+ const grant = permissiongrantof(options.permission);
5120
+ if (!grant) return { allowed: false, reason: `The permission override needs a reviewed name of the browser permission set (${browserpermissions.join(", ")}) and a state of ${permissionstates.join(", ")}.` };
5121
+ void permissiongrade(grant.name);
5122
+ return { allowed: true };
5123
+ }
5124
+ if (kind === "blackboxscripts") {
5125
+ const rules = Array.isArray(options.rules) ? options.rules.flatMap((rule) => {
5126
+ const parsed = blackboxruleof(rule);
5127
+ return parsed !== void 0 ? [parsed] : [];
5128
+ }) : [];
5129
+ if (rules.length === 0) return { allowed: false, reason: "The blackbox layer needs a reviewed non-empty rule list where every pattern names its origin explicitly and carries a trace scope." };
5130
+ return { allowed: true };
5131
+ }
5132
+ return { allowed: true };
5133
+ }
5134
+ function permissionnamevalid(name) {
5135
+ if (!browserpermissions.includes(name)) return { allowed: false, reason: `The permission ${name} stays outside the reviewed browser permission set: ${browserpermissions.join(", ")}.` };
5136
+ return { allowed: true };
5137
+ }
5138
+ function permissionstatevalid(state) {
5139
+ if (!permissionstates.includes(state)) return { allowed: false, reason: `The reviewed permission state must be one of ${permissionstates.join(", ")}.` };
5140
+ return { allowed: true };
5141
+ }
4416
5142
  function validatecdpgrammar(step, options) {
4417
5143
  const kind = step.kind;
4418
5144
  if (kind === "attachcdp") {
@@ -4479,6 +5205,66 @@ function validatecdpgrammar(step, options) {
4479
5205
  }
4480
5206
  return { allowed: true };
4481
5207
  }
5208
+ function validateprofilegrammar(step, options) {
5209
+ const kind = step.kind;
5210
+ if (kind === "measureflow") {
5211
+ if (flowspecof(options.flow) === void 0) return { allowed: false, reason: `The flow measurement needs a reviewed flow spec with its mark prefix, step window and metric list of the reviewed metric set: navigation, paint, lcp, fid, interaction, blocking.` };
5212
+ const watch = options.watch && typeof options.watch === "object" && !Array.isArray(options.watch) ? options.watch : {};
5213
+ if (typeof watch.window !== "number" || !Number.isFinite(watch.window) || watch.window < 0) return { allowed: false, reason: "The flow measurement needs a reviewed watch window of zero or more milliseconds." };
5214
+ const budgetcheck = debugwaitbudgetallowed(watch.window, typeof options.wait === "number" ? options.wait : void 0);
5215
+ if (!budgetcheck.allowed) return budgetcheck;
5216
+ return { allowed: true };
5217
+ }
5218
+ if (kind === "heapshot") {
5219
+ const heap = options.heap && typeof options.heap === "object" && !Array.isArray(options.heap) ? options.heap : {};
5220
+ if (heap.interval !== void 0 && (typeof heap.interval !== "number" || !Number.isFinite(heap.interval) || heap.interval < 0)) return { allowed: false, reason: "The reviewed heap snapshot interval must be zero or a positive number of milliseconds and stays a user choice with no code ceiling." };
5221
+ return { allowed: true };
5222
+ }
5223
+ if (kind === "trackmemory") {
5224
+ const growth = options.growth && typeof options.growth === "object" && !Array.isArray(options.growth) ? options.growth : void 0;
5225
+ if (!growth || typeof growth.slope !== "number" || !Number.isFinite(growth.slope) || growth.slope < 0) return { allowed: false, reason: "Memory growth tracking needs the reviewed slope in bytes per millisecond before any sample is flagged." };
5226
+ if (growth.interval !== void 0 && (typeof growth.interval !== "number" || !Number.isFinite(growth.interval) || growth.interval < 0)) return { allowed: false, reason: "The reviewed sampling interval must be zero or a positive number of milliseconds and stays a user choice with no code ceiling." };
5227
+ return { allowed: true };
5228
+ }
5229
+ if (kind === "profilecpu") {
5230
+ const profile = options.profile && typeof options.profile === "object" && !Array.isArray(options.profile) ? options.profile : void 0;
5231
+ if (!profile || typeof profile.duration !== "number" || !Number.isFinite(profile.duration) || profile.duration < 0) return { allowed: false, reason: "The cpu profile needs a reviewed duration of zero or more milliseconds." };
5232
+ const budgetcheck = debugwaitbudgetallowed(profile.duration, typeof options.wait === "number" ? options.wait : void 0);
5233
+ if (!budgetcheck.allowed) return budgetcheck;
5234
+ return { allowed: true };
5235
+ }
5236
+ if (kind === "watchshifts") {
5237
+ const watch = options.watch && typeof options.watch === "object" && !Array.isArray(options.watch) ? options.watch : {};
5238
+ if (typeof watch.window !== "number" || !Number.isFinite(watch.window) || watch.window < 0) return { allowed: false, reason: "The layout shift watch needs a reviewed observation window of zero or more milliseconds; the window stays a user choice with no code ceiling." };
5239
+ if (options.threshold !== void 0 && (typeof options.threshold !== "number" || !Number.isFinite(options.threshold) || options.threshold < 0)) return { allowed: false, reason: "The reviewed shift score threshold must be zero or a positive number." };
5240
+ const budgetcheck = debugwaitbudgetallowed(watch.window, typeof options.wait === "number" ? options.wait : void 0);
5241
+ if (!budgetcheck.allowed) return budgetcheck;
5242
+ return { allowed: true };
5243
+ }
5244
+ if (kind === "traceload") {
5245
+ const trace = options.trace && typeof options.trace === "object" && !Array.isArray(options.trace) ? options.trace : void 0;
5246
+ if (!trace || !Array.isArray(trace.categories) || trace.categories.length === 0 || !trace.categories.every((category) => typeof category === "string" && tracecategories.includes(category))) return { allowed: false, reason: `The trace record needs a non-empty reviewed category list of the reviewed category grammar: ${tracecategories.join(", ")}.` };
5247
+ if (typeof trace.window !== "number" || !Number.isFinite(trace.window) || trace.window < 0) return { allowed: false, reason: "The trace record needs a reviewed window of zero or more milliseconds and stops at the reviewed window end." };
5248
+ if (trace.exporttarget !== void 0 && trace.exporttarget !== "memory" && trace.exporttarget !== "download") return { allowed: false, reason: "The trace export target must be memory or download." };
5249
+ const budgetcheck = debugwaitbudgetallowed(trace.window, typeof options.wait === "number" ? options.wait : void 0);
5250
+ if (!budgetcheck.allowed) return budgetcheck;
5251
+ return { allowed: true };
5252
+ }
5253
+ if (kind === "annotatetrace" || kind === "replaytrace") {
5254
+ const trace = options.trace && typeof options.trace === "object" && !Array.isArray(options.trace) ? options.trace : void 0;
5255
+ if (!trace || typeof trace.traceid !== "string" || !trace.traceid.trim()) return { allowed: false, reason: `The ${kind === "annotatetrace" ? "trace annotation" : "trace replay"} needs the stored trace id of a recorded trace.` };
5256
+ if (kind === "replaytrace") return { allowed: true };
5257
+ if (!Array.isArray(options.annotations) || options.annotations.length === 0 || !options.annotations.every((annotation) => annotationof(annotation) !== void 0)) return { allowed: false, reason: "Exported traces carry their step annotations: every annotation needs a step id, a label and an optional offset from the trace start." };
5258
+ return { allowed: true };
5259
+ }
5260
+ if (kind === "capturesourcemaps") {
5261
+ if (options.scripts !== void 0) {
5262
+ if (!Array.isArray(options.scripts) || options.scripts.length === 0 || !options.scripts.every((url) => typeof url === "string" && ishttpsurl(url))) return { allowed: false, reason: "The source map capture scripts must be a non-empty list of reviewed HTTPS urls." };
5263
+ }
5264
+ return { allowed: true };
5265
+ }
5266
+ return { allowed: true };
5267
+ }
4482
5268
  function planallowlist(steps) {
4483
5269
  const attach = steps.find((step) => step.kind === "attachcdp");
4484
5270
  if (!attach) return void 0;
@@ -4906,6 +5692,14 @@ function validatestep(step, origin) {
4906
5692
  const cdpcheck = validatecdpgrammar(step, options);
4907
5693
  if (!cdpcheck.allowed) return cdpcheck;
4908
5694
  }
5695
+ if (isprofilekind(step.kind)) {
5696
+ const profilecheck = validateprofilegrammar(step, options);
5697
+ if (!profilecheck.allowed) return profilecheck;
5698
+ }
5699
+ if (isemulationkind(step.kind)) {
5700
+ const emulationcheck = validateemulationgrammar(step, options);
5701
+ if (!emulationcheck.allowed) return emulationcheck;
5702
+ }
4909
5703
  if (step.kind === "tabcreate") {
4910
5704
  if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
4911
5705
  if (options.window !== void 0 && (typeof options.window !== "number" || !Number.isInteger(options.window) || options.window < 0)) return { allowed: false, reason: "The reviewed target window id must be a non-negative integer." };
@@ -5039,18 +5833,46 @@ function canexecute(input) {
5039
5833
  if (input.step.kind === "setbreakpoint") {
5040
5834
  const breakpoint = breakpointinputof(cdpoptions.breakpoint);
5041
5835
  if (breakpoint) {
5042
- const targetgate = origincheck(input.session, breakpoint.url);
5043
- if (!targetgate.allowed) return targetgate;
5836
+ const targetgate2 = origincheck(input.session, breakpoint.url);
5837
+ if (!targetgate2.allowed) return targetgate2;
5044
5838
  }
5045
5839
  }
5046
5840
  if (input.step.kind === "overridescript") {
5047
5841
  const override = overrideinputof(cdpoptions.override);
5048
5842
  if (override) {
5049
- const targetgate = origincheck(input.session, override.urlpattern);
5050
- if (!targetgate.allowed) return targetgate;
5843
+ const targetgate2 = origincheck(input.session, override.urlpattern);
5844
+ if (!targetgate2.allowed) return targetgate2;
5845
+ }
5846
+ }
5847
+ }
5848
+ if (isprofilekind(input.step.kind)) {
5849
+ let profileoptions = {};
5850
+ try {
5851
+ profileoptions = parseoptions(input.step);
5852
+ } catch {
5853
+ profileoptions = {};
5854
+ }
5855
+ const targets = [
5856
+ ...attachtargetof(profileoptions.target) !== void 0 ? [attachtargetof(profileoptions.target)] : [],
5857
+ ...Array.isArray(profileoptions.attachtargets) ? profileoptions.attachtargets.flatMap((target) => {
5858
+ const parsed = attachtargetof(target);
5859
+ return parsed !== void 0 ? [parsed] : [];
5860
+ }) : []
5861
+ ];
5862
+ const targetgatecheck = targetgate({ session: input.session, tabid: input.tabid, origin: input.origin, targets, grants: void 0, now });
5863
+ if (!targetgatecheck.allowed) return targetgatecheck;
5864
+ if (input.step.kind === "capturesourcemaps") {
5865
+ for (const url of Array.isArray(profileoptions.scripts) ? profileoptions.scripts : []) {
5866
+ if (typeof url !== "string") continue;
5867
+ const scriptgate = origincheck(input.session, url);
5868
+ if (!scriptgate.allowed) return scriptgate;
5051
5869
  }
5052
5870
  }
5053
5871
  }
5872
+ if (isemulationkind(input.step.kind)) {
5873
+ const emugatecheck = emugate({ session: input.session, plan: input.plan, step: input.step, tabid: input.tabid, origin: input.origin, now });
5874
+ if (!emugatecheck.allowed) return emugatecheck;
5875
+ }
5054
5876
  if (iscontrolkind(input.step.kind)) {
5055
5877
  const controlgate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: "control the network" });
5056
5878
  if (!controlgate.allowed) return controlgate;
@@ -5096,8 +5918,8 @@ function canexecute(input) {
5096
5918
  }
5097
5919
  const target = controltarget(input.step);
5098
5920
  if (target !== void 0) {
5099
- const targetgate = origincheck(input.session, target);
5100
- if (!targetgate.allowed) return targetgate;
5921
+ const targetgate2 = origincheck(input.session, target);
5922
+ if (!targetgate2.allowed) return targetgate2;
5101
5923
  }
5102
5924
  }
5103
5925
  if (input.step.kind === "extractapi") {
@@ -5134,7 +5956,7 @@ function canexecute(input) {
5134
5956
  }
5135
5957
 
5136
5958
  // version.ts
5137
- var packageversion = "1.1.46";
5959
+ var packageversion = "1.1.48";
5138
5960
 
5139
5961
  // types.ts
5140
5962
  var protocolversion = packageversion;
@@ -5253,6 +6075,81 @@ function parseproposal(value, origin, grants) {
5253
6075
  if (!allowlistcovers(planallowlist2, method)) throw new Error(`The raw command ${method} stays outside the enabled domain allowlist of the plan attach.`);
5254
6076
  }
5255
6077
  }
6078
+ if (isprofilekind(step.kind)) {
6079
+ const granted = covered.some((pattern) => {
6080
+ try {
6081
+ return new URL(origin).origin === new URL(pattern).origin;
6082
+ } catch {
6083
+ return false;
6084
+ }
6085
+ });
6086
+ if (!granted) throw new Error(`The ${step.kind} step of ${origin} targets an origin outside the grants.`);
6087
+ let profileoptions = {};
6088
+ try {
6089
+ profileoptions = parseoptions(step);
6090
+ } catch {
6091
+ profileoptions = {};
6092
+ }
6093
+ const targets = [
6094
+ ...attachtargetof(profileoptions.target) !== void 0 ? [attachtargetof(profileoptions.target)] : [],
6095
+ ...Array.isArray(profileoptions.attachtargets) ? profileoptions.attachtargets.flatMap((target2) => {
6096
+ const parsed = attachtargetof(target2);
6097
+ return parsed !== void 0 ? [parsed] : [];
6098
+ }) : []
6099
+ ];
6100
+ for (const target2 of targets) {
6101
+ if (target2.kind === "page") continue;
6102
+ const targetgranted = covered.some((pattern) => {
6103
+ try {
6104
+ return new URL(target2.url).origin === new URL(pattern).origin;
6105
+ } catch {
6106
+ return false;
6107
+ }
6108
+ });
6109
+ if (!targetgranted) throw new Error(`The ${target2.kind} target ${target2.url} of the ${step.kind} step stays outside the granted origins.`);
6110
+ }
6111
+ if (step.kind === "traceload") {
6112
+ const trace = profileoptions.trace && typeof profileoptions.trace === "object" && !Array.isArray(profileoptions.trace) ? profileoptions.trace : void 0;
6113
+ const categories = trace !== void 0 && Array.isArray(trace.categories) ? trace.categories : [];
6114
+ if (categories.some((category) => typeof category !== "string" || !tracecategories.includes(category))) throw new Error(`Trace categories outside the reviewed list are refused: ${tracecategories.join(", ")}.`);
6115
+ }
6116
+ if (step.kind === "capturesourcemaps") {
6117
+ for (const url of Array.isArray(profileoptions.scripts) ? profileoptions.scripts : []) {
6118
+ if (typeof url !== "string") continue;
6119
+ const scriptgranted = covered.some((pattern) => {
6120
+ try {
6121
+ return new URL(url).origin === new URL(pattern).origin;
6122
+ } catch {
6123
+ return false;
6124
+ }
6125
+ });
6126
+ if (!scriptgranted) throw new Error(`The source map capture of ${url} targets an origin outside the grants.`);
6127
+ }
6128
+ }
6129
+ if (step.kind === "annotatetrace" && (!Array.isArray(profileoptions.annotations) || profileoptions.annotations.length === 0 || !profileoptions.annotations.every((annotation) => annotationof(annotation) !== void 0))) throw new Error("Trace annotation steps without reviewed step annotations are refused.");
6130
+ }
6131
+ if (isemulationkind(step.kind)) {
6132
+ const granted = covered.some((pattern) => {
6133
+ try {
6134
+ return new URL(origin).origin === new URL(pattern).origin;
6135
+ } catch {
6136
+ return false;
6137
+ }
6138
+ });
6139
+ if (!granted) throw new Error(`The ${step.kind} step of ${origin} targets an origin outside the grants.`);
6140
+ let emulationoptions = {};
6141
+ try {
6142
+ emulationoptions = parseoptions(step);
6143
+ } catch {
6144
+ emulationoptions = {};
6145
+ }
6146
+ if (revertplanof(emulationoptions.revertplan) === void 0) throw new Error("Emulation steps without a reviewed revert plan are refused.");
6147
+ if (step.kind === "emulatelocate") {
6148
+ const preset = locationpresetof(emulationoptions.location);
6149
+ if (preset === void 0) throw new Error("Location emulation needs a reviewed preset with coordinates inside the latitude and longitude ranges.");
6150
+ }
6151
+ if (step.kind === "overridepermission" && permissiongrantof(emulationoptions.permission) === void 0) throw new Error("Permission overrides of unknown permission names are refused.");
6152
+ }
5256
6153
  const evaluation = validatestep(step, origin);
5257
6154
  if (!evaluation.allowed) throw new Error(evaluation.reason);
5258
6155
  const target = outboundtarget(step);
@@ -5327,7 +6224,7 @@ function requestbody(input) {
5327
6224
  return JSON.stringify({ version: protocolversion, objective: input.objective, session: input.session, observation: input.observation, capabilities: input.capabilities });
5328
6225
  }
5329
6226
  function outcomeresponse(input) {
5330
- return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {}, ...input.cdp ? { cdp: input.cdp } : {} });
6227
+ return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {}, ...input.cdp ? { cdp: input.cdp } : {}, ...input.profile ? { profile: input.profile } : {}, ...input.emulation ? { emulation: input.emulation } : {} });
5331
6228
  }
5332
6229
  function mapresponse(input) {
5333
6230
  return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, map: input.map });
@@ -5457,20 +6354,46 @@ function cdpreport(input) {
5457
6354
  });
5458
6355
  return { version: protocolversion, sessions: input.sessions, commands: input.commands, events: input.events, breakpoints: input.breakpoints, pauses: input.pauses, watches: input.watches, overrides, grants };
5459
6356
  }
6357
+ function profilereport(input) {
6358
+ const consents = input.consents.map((consent) => {
6359
+ const { prompt, ...metadata } = consent;
6360
+ void prompt;
6361
+ return metadata;
6362
+ });
6363
+ return { version: protocolversion, flows: input.flows, heaps: input.heaps, samples: input.samples, trends: input.trends, profiles: input.profiles, shifts: input.shifts, traces: input.traces, sourcemaps: input.sourcemaps, consents };
6364
+ }
6365
+ function emulationreport(input) {
6366
+ const consents = input.consents.map((consent) => {
6367
+ const { prompt, ...metadata } = consent;
6368
+ void prompt;
6369
+ return metadata;
6370
+ });
6371
+ return { version: protocolversion, ...input.state !== void 0 ? { state: input.state } : {}, layers: input.state?.layers ?? [], devices: input.devices, networks: input.networks, locations: input.locations, agents: input.agents, blackbox: input.blackbox, permissions: input.permissions, consents };
6372
+ }
5460
6373
  export {
6374
+ activelayers,
6375
+ agentgrammarvalid,
6376
+ agentpresetof,
5461
6377
  allowlistcovers,
6378
+ annotatetrace,
6379
+ annotationof,
5462
6380
  annotationplanof,
5463
6381
  apientries,
5464
6382
  apikeyconsentgranted,
5465
6383
  apireplayspecof,
5466
6384
  applyheaderules,
6385
+ applylayer,
5467
6386
  argkind,
5468
6387
  assetentries,
5469
6388
  attachcdpsession,
6389
+ attachtargetof,
5470
6390
  attachtimeline,
5471
6391
  authconsentgranted,
5472
6392
  authorizeurl,
5473
6393
  authreport,
6394
+ blackboxedurls,
6395
+ blackboxmatches,
6396
+ blackboxruleof,
5474
6397
  blendrows,
5475
6398
  blockgate,
5476
6399
  blockingduration,
@@ -5480,6 +6403,7 @@ export {
5480
6403
  breakpointbudgetallowed,
5481
6404
  breakpointceilingof,
5482
6405
  breakpointinputof,
6406
+ browserpermissions,
5483
6407
  buildname,
5484
6408
  buildpdf,
5485
6409
  buildsheet,
@@ -5498,6 +6422,7 @@ export {
5498
6422
  capturepause,
5499
6423
  captureregion,
5500
6424
  capturereport,
6425
+ capturesourcemaps,
5501
6426
  capturestates,
5502
6427
  capturestitched,
5503
6428
  capturetargets,
@@ -5523,6 +6448,7 @@ export {
5523
6448
  cookiegate,
5524
6449
  cookierecordof,
5525
6450
  correlationid,
6451
+ cpusnap,
5526
6452
  croprect,
5527
6453
  crossesviewport,
5528
6454
  cursorfrom,
@@ -5533,54 +6459,82 @@ export {
5533
6459
  dedupeimages,
5534
6460
  actionrisk as deriveactionrisk,
5535
6461
  detachcdpsession,
6462
+ devicepresetof,
5536
6463
  diffresponse,
5537
6464
  diffreviewgrade,
5538
6465
  downloadreport,
6466
+ emugate,
6467
+ emulationkinds,
6468
+ emulationreport,
6469
+ emulationretentionwindow,
6470
+ emulationstackallowed,
6471
+ emulationstateof,
5539
6472
  errorcapture,
5540
6473
  errorreportresponse,
5541
6474
  eventresponse,
5542
6475
  exchangesreport,
6476
+ expirelayers,
6477
+ expireprofilerecords,
6478
+ exportpresetlibrary,
5543
6479
  extractionreport,
5544
6480
  extractvalues,
5545
6481
  failureclass,
6482
+ familyofkind,
5546
6483
  fetchoptionsof,
5547
6484
  fetchrequestof,
5548
6485
  filterentries,
5549
6486
  filterexchanges,
5550
6487
  finishrecording,
5551
6488
  fixedheadermatch,
6489
+ flowmetricnames,
6490
+ flowspecof,
5552
6491
  formpayloadof,
5553
6492
  formreportresponse,
5554
6493
  frameinterval,
5555
6494
  generatedvalueallowed,
5556
6495
  graphqlopenvelope,
5557
6496
  graphqlrequestof,
6497
+ growsampleof,
6498
+ growthtrend,
5558
6499
  headerfilterof,
5559
6500
  headeruleof,
6501
+ heapintervalallowed,
6502
+ heapsnap,
5560
6503
  heldkeysreport,
6504
+ hideblackboxedframes,
5561
6505
  hostpattern,
5562
6506
  htmlqueriesof,
5563
6507
  httpkinds,
5564
6508
  imagefilterof,
5565
6509
  imagematches,
5566
6510
  imagenames,
6511
+ importpresetlibrary,
5567
6512
  iscdpkind,
5568
6513
  iscontrolkind,
5569
6514
  isdebugkind,
6515
+ isemulationkind,
5570
6516
  isformkind,
5571
6517
  isnetwatchkind,
6518
+ isprofilekind,
5572
6519
  issocketkind,
5573
6520
  iswatchkind,
5574
6521
  jsonpathrulesof,
5575
6522
  lapseframes,
5576
6523
  lapseplanof,
6524
+ layernames,
5577
6525
  layoutreport,
5578
6526
  levelrank,
6527
+ locationconsentcovers,
6528
+ locationconsentgate,
6529
+ locationpresetof,
6530
+ locationrangevalid,
5579
6531
  loglevels,
5580
6532
  longtaskcapture,
5581
6533
  mapresponse,
6534
+ mapurlof,
5582
6535
  matchmessage,
5583
6536
  matchurlpattern,
6537
+ measure,
5584
6538
  mediaentries,
5585
6539
  mediakinds,
5586
6540
  mediareport,
@@ -5594,10 +6548,12 @@ export {
5594
6548
  netfailureentryof,
5595
6549
  netlogreport,
5596
6550
  netwatchkinds,
6551
+ networkpresetof,
5597
6552
  newblockrule,
5598
6553
  newchannel,
5599
6554
  newexchange,
5600
6555
  newheaderule,
6556
+ newlayer,
5601
6557
  newmockspec,
5602
6558
  newrecording,
5603
6559
  normalizeendpoint,
@@ -5624,12 +6580,20 @@ export {
5624
6580
  pdfpagesize,
5625
6581
  pdfsegments,
5626
6582
  pdftextlayout,
6583
+ permissiongrade,
6584
+ permissiongrantof,
6585
+ permissionnamevalid,
6586
+ permissionstates,
6587
+ permissionstatevalid,
5627
6588
  planallowlist,
5628
6589
  pollcursorof,
5629
6590
  polldecision,
5630
6591
  pollurl,
5631
6592
  privatemime,
5632
6593
  profilegrantgranted,
6594
+ profilereport,
6595
+ profileretentionwindow,
6596
+ profilerkinds,
5633
6597
  protocolversion,
5634
6598
  provenancereport,
5635
6599
  proxygate,
@@ -5651,14 +6615,19 @@ export {
5651
6615
  redactedcookies,
5652
6616
  regionsteps,
5653
6617
  rejectioncapture,
6618
+ replaytrace,
5654
6619
  replayurl,
5655
6620
  requestbody,
5656
6621
  resolutionverdict,
5657
6622
  resolvedrisk,
5658
6623
  resourcefacts,
5659
6624
  retryafterof,
6625
+ revertalllayers,
6626
+ revertlayer,
6627
+ revertplanof,
5660
6628
  revertrule,
5661
6629
  revocationruleof,
6630
+ rewritesourcelocation,
5662
6631
  rotatelogs,
5663
6632
  rotationruleof,
5664
6633
  safetyresponse,
@@ -5671,21 +6640,26 @@ export {
5671
6640
  serializearg,
5672
6641
  serializecdpcommand,
5673
6642
  sessionmemory,
6643
+ shiftentryof,
5674
6644
  signalsreport,
5675
6645
  socketgate,
5676
6646
  socketkinds,
6647
+ sourcemapconsentcovers,
5677
6648
  spamdetect,
5678
6649
  spamruleof,
5679
6650
  sserequestheaders,
6651
+ stackedcount,
5680
6652
  stackframes,
5681
6653
  stackgate,
5682
6654
  statusclassof,
5683
6655
  stepmodeof,
6656
+ stepwindows,
5684
6657
  streamsummaries,
5685
6658
  streamwindowof,
5686
6659
  submitreviewgranted,
5687
6660
  subscriptionoptionsof,
5688
6661
  tabreportresponse,
6662
+ targetgate,
5689
6663
  teardowncdpsession,
5690
6664
  teardownplanof,
5691
6665
  templateurl,
@@ -5698,6 +6672,10 @@ export {
5698
6672
  timelineretentionwindow,
5699
6673
  timelinesources,
5700
6674
  tokenrequest,
6675
+ tracecategories,
6676
+ traceceilingof,
6677
+ tracestart,
6678
+ tracetofile,
5701
6679
  trailreport,
5702
6680
  transformgrammar,
5703
6681
  unwrapgraphql,