@wenathlan/extension 1.1.47 → 1.1.49

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]);
@@ -1147,6 +1331,212 @@ function expireprofilerecords(input) {
1147
1331
  };
1148
1332
  }
1149
1333
 
1334
+ // sessions.ts
1335
+ var sessionkinds = ["persiststate", "capturesession", "restoresession", "namedsessions", "diffsessions", "searchsessions", "exportsessions", "importsessions"];
1336
+ var sessionfileversion = 1;
1337
+ var snapshotsections = ["tabs", "scroll", "forms", "storage", "cookies"];
1338
+ var searchfields = ["urls", "titles", "names", "text"];
1339
+ function checksumtext(payload) {
1340
+ let hash = 2166136261;
1341
+ for (let index = 0; index < payload.length; index += 1) {
1342
+ hash ^= payload.charCodeAt(index);
1343
+ hash = Math.imul(hash, 16777619) >>> 0;
1344
+ }
1345
+ return hash.toString(16).padStart(8, "0");
1346
+ }
1347
+ function taskstatechecksum(runid, stepcursor, outputs) {
1348
+ return checksumtext(`${runid}:${stepcursor}:${outputs.length}:${outputs.map((output) => `${output.stepid}:${output.ok}:${output.summary.length}`).join("|")}`);
1349
+ }
1350
+ function taskstateof(input) {
1351
+ return { runid: input.runid, stepcursor: input.stepcursor, outputs: input.outputs, checkpointat: input.checkpointat, checksum: taskstatechecksum(input.runid, input.stepcursor, input.outputs) };
1352
+ }
1353
+ function taskstatevalid(state) {
1354
+ if (!state || typeof state.runid !== "string" || !state.runid.trim()) return false;
1355
+ if (typeof state.stepcursor !== "number" || !Number.isInteger(state.stepcursor) || state.stepcursor < 0) return false;
1356
+ if (typeof state.checkpointat !== "number" || !Number.isFinite(state.checkpointat)) return false;
1357
+ if (!Array.isArray(state.outputs)) return false;
1358
+ return state.checksum === taskstatechecksum(state.runid, state.stepcursor, state.outputs);
1359
+ }
1360
+ function sessiontabof(value) {
1361
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1362
+ const candidate = value;
1363
+ if (typeof candidate.url !== "string" || !candidate.url.trim()) return void 0;
1364
+ if (typeof candidate.title !== "string") return void 0;
1365
+ if (typeof candidate.index !== "number" || !Number.isInteger(candidate.index) || candidate.index < 0) return void 0;
1366
+ const scrollx = typeof candidate.scrollx === "number" && Number.isFinite(candidate.scrollx) ? candidate.scrollx : 0;
1367
+ const scrolly = typeof candidate.scrolly === "number" && Number.isFinite(candidate.scrolly) ? candidate.scrolly : 0;
1368
+ const forms = Array.isArray(candidate.forms) ? candidate.forms.flatMap((entry) => {
1369
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
1370
+ const form = entry;
1371
+ if (typeof form.selector !== "string" || !form.selector.trim()) return [];
1372
+ return [{ selector: form.selector, value: typeof form.value === "string" ? form.value : "" }];
1373
+ }) : [];
1374
+ return { url: candidate.url, title: candidate.title, index: candidate.index, scrollx, scrolly, forms };
1375
+ }
1376
+ function autointervalof(value) {
1377
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1378
+ const candidate = value;
1379
+ if (typeof candidate.period !== "number" || !Number.isFinite(candidate.period) || candidate.period <= 0) return void 0;
1380
+ if (typeof candidate.maxsnapshots !== "number" || !Number.isInteger(candidate.maxsnapshots) || candidate.maxsnapshots < 1) return void 0;
1381
+ if (typeof candidate.expiry !== "number" || !Number.isFinite(candidate.expiry) || candidate.expiry < 0) return void 0;
1382
+ return { period: candidate.period, maxsnapshots: candidate.maxsnapshots, expiry: candidate.expiry };
1383
+ }
1384
+ function snapshotplanof(value) {
1385
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1386
+ const candidate = value;
1387
+ if (candidate.scope !== "tab" && candidate.scope !== "run" && candidate.scope !== "all") return void 0;
1388
+ const sections = Array.isArray(candidate.sections) ? candidate.sections.flatMap((section) => typeof section === "string" && snapshotsections.includes(section) ? [section] : []) : [];
1389
+ if (sections.length === 0) return void 0;
1390
+ if (typeof candidate.captures !== "boolean") return void 0;
1391
+ const auto = candidate.auto === void 0 ? void 0 : autointervalof(candidate.auto);
1392
+ if (candidate.auto !== void 0 && auto === void 0) return void 0;
1393
+ return { scope: candidate.scope, sections, captures: candidate.captures, ...auto !== void 0 ? { auto } : {} };
1394
+ }
1395
+ function restoreplanof(value) {
1396
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1397
+ const candidate = value;
1398
+ if (candidate.tabpolicy !== "reopen" && candidate.tabpolicy !== "skip") return void 0;
1399
+ if (candidate.formpolicy !== "restore" && candidate.formpolicy !== "skip") return void 0;
1400
+ if (candidate.capturepolicy !== "link" && candidate.capturepolicy !== "skip") return void 0;
1401
+ return { tabpolicy: candidate.tabpolicy, formpolicy: candidate.formpolicy, capturepolicy: candidate.capturepolicy };
1402
+ }
1403
+ function searchqueryof(value) {
1404
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1405
+ const candidate = value;
1406
+ const terms = Array.isArray(candidate.terms) ? candidate.terms.flatMap((term) => typeof term === "string" && term.trim() ? [term.trim()] : []) : [];
1407
+ if (terms.length === 0) return void 0;
1408
+ const fields = Array.isArray(candidate.fields) ? candidate.fields.flatMap((field) => typeof field === "string" && searchfields.includes(field) ? [field] : []) : [...searchfields];
1409
+ if (fields.length === 0) return void 0;
1410
+ const from = typeof candidate.from === "number" && Number.isFinite(candidate.from) ? candidate.from : void 0;
1411
+ const to = typeof candidate.to === "number" && Number.isFinite(candidate.to) ? candidate.to : void 0;
1412
+ if (from !== void 0 && to !== void 0 && from > to) return void 0;
1413
+ return { terms, fields, ...from !== void 0 ? { from } : {}, ...to !== void 0 ? { to } : {} };
1414
+ }
1415
+ function sessionfolderof(value) {
1416
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1417
+ const candidate = value;
1418
+ if (typeof candidate.name !== "string" || !candidate.name.trim()) return void 0;
1419
+ const parent = typeof candidate.parent === "string" && candidate.parent.trim() ? candidate.parent : void 0;
1420
+ const tags = Array.isArray(candidate.tags) ? candidate.tags.flatMap((tag) => typeof tag === "string" && tag.trim() ? [tag] : []) : [];
1421
+ return { name: candidate.name, ...parent !== void 0 ? { parent } : {}, tags };
1422
+ }
1423
+ function newsessionrecord(input) {
1424
+ return { id: input.id, name: input.name, createdat: input.createdat, tabs: input.tabs, captures: input.captures, storage: input.storage, cookies: input.cookies, ...input.folder !== void 0 ? { folder: input.folder } : {}, tags: input.tags ?? [], ...input.auto === true ? { auto: true } : {} };
1425
+ }
1426
+ function diffsessionrecords(left, right) {
1427
+ const changes = [];
1428
+ const leftbyindex = new Map(left.tabs.map((tab) => [tab.index, tab]));
1429
+ const rightbyindex = new Map(right.tabs.map((tab) => [tab.index, tab]));
1430
+ for (const tab of right.tabs) {
1431
+ const prior = leftbyindex.get(tab.index);
1432
+ if (!prior) {
1433
+ changes.push({ class: "added", subject: "tab", detail: `Tab ${tab.index} added: ${tab.url}` });
1434
+ continue;
1435
+ }
1436
+ if (prior.url !== tab.url) changes.push({ class: "changed", subject: "url", detail: `Tab ${tab.index} moved from ${prior.url} to ${tab.url}` });
1437
+ if (prior.title !== tab.title) changes.push({ class: "changed", subject: "tab", detail: `Tab ${tab.index} title changed from "${prior.title}" to "${tab.title}"` });
1438
+ const priorforms = new Map(prior.forms.map((form) => [form.selector, form.value]));
1439
+ for (const form of tab.forms) {
1440
+ const before = priorforms.get(form.selector);
1441
+ if (before === void 0) {
1442
+ changes.push({ class: "added", subject: "form", detail: `Form field ${form.selector} of tab ${tab.index} added with a value` });
1443
+ continue;
1444
+ }
1445
+ if (before !== form.value) changes.push({ class: "changed", subject: "form", detail: `Form field ${form.selector} of tab ${tab.index} changed its captured value` });
1446
+ }
1447
+ for (const form of prior.forms) if (!tab.forms.some((entry) => entry.selector === form.selector)) changes.push({ class: "removed", subject: "form", detail: `Form field ${form.selector} of tab ${tab.index} removed` });
1448
+ }
1449
+ for (const tab of left.tabs) if (!rightbyindex.has(tab.index)) changes.push({ class: "removed", subject: "tab", detail: `Tab ${tab.index} removed: ${tab.url}` });
1450
+ const leftstorage = new Map(left.storage.map((entry) => [entry.origin, entry]));
1451
+ for (const entry of right.storage) {
1452
+ const prior = leftstorage.get(entry.origin);
1453
+ if (!prior) {
1454
+ changes.push({ class: "added", subject: "storage", detail: `Local storage of ${entry.origin} captured with ${entry.keys.length} keys` });
1455
+ continue;
1456
+ }
1457
+ if (prior.keys.join("|") !== entry.keys.join("|") || prior.values.join("|") !== entry.values.join("|")) changes.push({ class: "changed", subject: "storage", detail: `Local storage of ${entry.origin} changed its captured keys or values` });
1458
+ }
1459
+ for (const entry of left.storage) if (!right.storage.some((candidate) => candidate.origin === entry.origin)) changes.push({ class: "removed", subject: "storage", detail: `Local storage of ${entry.origin} left the capture` });
1460
+ return changes;
1461
+ }
1462
+ function newsessiondiff(input) {
1463
+ return { id: input.id, leftid: input.left.id, rightid: input.right.id, changes: diffsessionrecords(input.left, input.right), at: input.at };
1464
+ }
1465
+ function searchsessionrecords(query, records) {
1466
+ const matches = [];
1467
+ for (const record2 of records) {
1468
+ if (query.from !== void 0 && record2.createdat < query.from) continue;
1469
+ if (query.to !== void 0 && record2.createdat > query.to) continue;
1470
+ const haystacks = [
1471
+ { field: "urls", text: record2.tabs.map((tab) => tab.url).join(" ") },
1472
+ { field: "titles", text: record2.tabs.map((tab) => tab.title).join(" ") },
1473
+ { field: "names", text: [record2.name, record2.folder ?? "", ...record2.tags].join(" ") },
1474
+ { field: "text", text: record2.tabs.flatMap((tab) => tab.forms.map((form) => form.value)).join(" ") }
1475
+ ];
1476
+ for (const haystack of haystacks) {
1477
+ if (!query.fields.includes(haystack.field)) continue;
1478
+ const lower = haystack.text.toLowerCase();
1479
+ for (const term of query.terms) {
1480
+ const at = lower.indexOf(term.toLowerCase());
1481
+ if (at < 0) continue;
1482
+ const start = Math.max(0, at - 30);
1483
+ matches.push({ sessionid: record2.id, field: haystack.field, term, at: record2.createdat, excerpt: haystack.text.slice(start, start + 80).trim() });
1484
+ }
1485
+ }
1486
+ }
1487
+ return matches;
1488
+ }
1489
+ function exportsessionfile(records, now) {
1490
+ const recordids = records.map((record2) => record2.id);
1491
+ const payload = JSON.stringify(records);
1492
+ return { formatversion: sessionfileversion, records, recordids, bytesize: payload.length, checksum: checksumtext(`${sessionfileversion}:${recordids.join(",")}:${payload.length}`), exportedat: now };
1493
+ }
1494
+ function importsessionfile(value) {
1495
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
1496
+ const candidate = value;
1497
+ if (candidate.formatversion !== sessionfileversion) return void 0;
1498
+ const records = Array.isArray(candidate.records) ? candidate.records.flatMap((record2) => sessionrecordvalid(record2) ? [record2] : []) : [];
1499
+ if (records.length === 0) return void 0;
1500
+ if (!Array.isArray(candidate.recordids) || candidate.recordids.length !== records.length || !candidate.recordids.every((id, index) => id === records[index]?.id)) return void 0;
1501
+ const bytesize = typeof candidate.bytesize === "number" && Number.isFinite(candidate.bytesize) ? candidate.bytesize : -1;
1502
+ if (bytesize < 0) return void 0;
1503
+ const checksum = typeof candidate.checksum === "string" ? candidate.checksum : "";
1504
+ if (checksum !== checksumtext(`${sessionfileversion}:${candidate.recordids.join(",")}:${bytesize}`)) return void 0;
1505
+ return { formatversion: sessionfileversion, records, recordids: candidate.recordids, bytesize, checksum, exportedat: typeof candidate.exportedat === "number" && Number.isFinite(candidate.exportedat) ? candidate.exportedat : 0 };
1506
+ }
1507
+ function sessionrecordvalid(value) {
1508
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1509
+ const candidate = value;
1510
+ if (typeof candidate.id !== "string" || !candidate.id.trim()) return false;
1511
+ if (typeof candidate.name !== "string" || !candidate.name.trim()) return false;
1512
+ if (typeof candidate.createdat !== "number" || !Number.isFinite(candidate.createdat)) return false;
1513
+ if (!Array.isArray(candidate.tabs) || !candidate.tabs.every((tab) => sessiontabof(tab) !== void 0)) return false;
1514
+ if (!Array.isArray(candidate.captures) || !candidate.captures.every((id) => typeof id === "string")) return false;
1515
+ if (!Array.isArray(candidate.tags) || !candidate.tags.every((tag) => typeof tag === "string")) return false;
1516
+ return true;
1517
+ }
1518
+ function expiresessions(records, retention, now) {
1519
+ if (retention === void 0 || !Number.isFinite(retention)) return records;
1520
+ return records.map((record2) => {
1521
+ if (record2.sectionsexpired || now - record2.createdat < retention) return record2;
1522
+ return { id: record2.id, name: record2.name, createdat: record2.createdat, tabs: [], captures: record2.captures, storage: [], cookies: [], ...record2.folder !== void 0 ? { folder: record2.folder } : {}, tags: record2.tags, ...record2.auto === true ? { auto: true } : {}, ...record2.restoredat !== void 0 ? { restoredat: record2.restoredat } : {}, sectionsexpired: true };
1523
+ });
1524
+ }
1525
+ function filteredsessions(records, filter) {
1526
+ return records.filter((record2) => {
1527
+ if (filter.name !== void 0 && !record2.name.toLowerCase().includes(filter.name.toLowerCase())) return false;
1528
+ if (filter.folder !== void 0 && record2.folder !== filter.folder) return false;
1529
+ if (filter.from !== void 0 && record2.createdat < filter.from) return false;
1530
+ if (filter.to !== void 0 && record2.createdat > filter.to) return false;
1531
+ return true;
1532
+ });
1533
+ }
1534
+ function crashinterrupted(state, plansteps, now) {
1535
+ if (!state) return void 0;
1536
+ if (state.stepcursor >= plansteps) return state;
1537
+ return { ...state, interrupted: true, crashat: state.crashat ?? now };
1538
+ }
1539
+
1150
1540
  // memory.ts
1151
1541
  var sessionmemory = class {
1152
1542
  constructor(adapter) {
@@ -2517,6 +2907,169 @@ var sessionmemory = class {
2517
2907
  await this.adapter.set("sourcemapconsents", updated);
2518
2908
  return revoked;
2519
2909
  }
2910
+ /** 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. */
2911
+ async setemulationstate(state) {
2912
+ const retention = (await this.getsettings())?.emulationretention;
2913
+ await this.adapter.set(`emulationstate${state.runid}`, expirelayers(state, retention, Date.now()));
2914
+ }
2915
+ /** Returns the persisted emulation state of one run so the layers survive service worker restarts. */
2916
+ async getemulationstate(runid) {
2917
+ return this.adapter.get(`emulationstate${runid}`);
2918
+ }
2919
+ /** Returns the active and past layers of one run, newest last in apply order; the listlayers accessor of the emulation memory. */
2920
+ async listlayers(runid) {
2921
+ const state = await this.getemulationstate(runid);
2922
+ return state?.layers ?? [];
2923
+ }
2924
+ /** Stores one user curated device preset by its name so the preset library stays user data instead of a hardcoded list. */
2925
+ async setdevicepreset(preset) {
2926
+ const records = (await this.adapter.get("devicepresets") ?? []).filter((item) => item.name !== preset.name);
2927
+ await this.adapter.set("devicepresets", [...records, preset]);
2928
+ }
2929
+ /** Returns every user curated device preset. */
2930
+ async getdevicepresets() {
2931
+ return await this.adapter.get("devicepresets") ?? [];
2932
+ }
2933
+ /** Stores one user curated network preset by its name with editable values. */
2934
+ async setnetworkpreset(preset) {
2935
+ const records = (await this.adapter.get("networkpresets") ?? []).filter((item) => item.name !== preset.name);
2936
+ await this.adapter.set("networkpresets", [...records, preset]);
2937
+ }
2938
+ /** Returns every user curated network preset. */
2939
+ async getnetworkpresets() {
2940
+ return await this.adapter.get("networkpresets") ?? [];
2941
+ }
2942
+ /** Stores one user curated location preset by its name. */
2943
+ async setlocationpreset(preset) {
2944
+ const records = (await this.adapter.get("locationpresets") ?? []).filter((item) => item.name !== preset.name);
2945
+ await this.adapter.set("locationpresets", [...records, preset]);
2946
+ }
2947
+ /** Returns every user curated location preset. */
2948
+ async getlocationpresets() {
2949
+ return await this.adapter.get("locationpresets") ?? [];
2950
+ }
2951
+ /** Stores one user curated agent preset by its name. */
2952
+ async setagentpreset(preset) {
2953
+ const records = (await this.adapter.get("agentpresets") ?? []).filter((item) => item.name !== preset.name);
2954
+ await this.adapter.set("agentpresets", [...records, preset]);
2955
+ }
2956
+ /** Returns every user curated agent preset. */
2957
+ async getagentpresets() {
2958
+ return await this.adapter.get("agentpresets") ?? [];
2959
+ }
2960
+ /** Replaces the blackbox rule set of one origin so third party script blackboxing stays scoped per origin. */
2961
+ async setblackboxrules(origin, rules) {
2962
+ const records = (await this.adapter.get("blackboxrules") ?? []).filter((item) => item.origin !== origin);
2963
+ await this.adapter.set("blackboxrules", [...records, { origin, rules }]);
2964
+ }
2965
+ /** Returns every stored blackbox rule set with its origin. */
2966
+ async getblackboxrules() {
2967
+ return await this.adapter.get("blackboxrules") ?? [];
2968
+ }
2969
+ /** Records one permission override of a run with its prior state captured for the exact restore. */
2970
+ async addpermissionoverride(record2) {
2971
+ const records = (await this.adapter.get("permissionoverrides") ?? []).filter((item) => item.id !== record2.id);
2972
+ await this.adapter.set("permissionoverrides", [record2, ...records]);
2973
+ }
2974
+ /** Returns the permission override history with restore states, newest first. */
2975
+ async getpermissionoverrides() {
2976
+ return await this.adapter.get("permissionoverrides") ?? [];
2977
+ }
2978
+ /** Stores one location consent decision per origin, replacing the previous decision of its id. */
2979
+ async setlocationconsent(consent) {
2980
+ const records = (await this.adapter.get("locationconsents") ?? []).filter((item) => item.id !== consent.id);
2981
+ await this.adapter.set("locationconsents", [consent, ...records]);
2982
+ }
2983
+ /** Returns every location consent decision, newest first. */
2984
+ async getlocationconsents() {
2985
+ return await this.adapter.get("locationconsents") ?? [];
2986
+ }
2987
+ /** Returns the persisted task state checkpoint of one run so the run resumes after a service worker restart. */
2988
+ async gettaskstate(runid) {
2989
+ return this.adapter.get(`taskstate${runid}`);
2990
+ }
2991
+ /** Persists one task state checkpoint per run with its corruption checksum. */
2992
+ async settaskstate(state) {
2993
+ return this.adapter.set(`taskstate${state.runid}`, state);
2994
+ }
2995
+ /** Returns the session event history with timestamps, newest first. */
2996
+ async getsessionevents() {
2997
+ return await this.adapter.get("sessionevents") ?? [];
2998
+ }
2999
+ /** Records one session event of the run with its timestamp and detail. */
3000
+ async addsessionevent(event) {
3001
+ const records = await this.getsessionevents();
3002
+ await this.adapter.set("sessionevents", [event, ...records]);
3003
+ }
3004
+ /** Returns every saved session record with its sections, newest first. */
3005
+ async getsessionrecords() {
3006
+ return await this.adapter.get("sessionrecords") ?? [];
3007
+ }
3008
+ /** Adds one saved session record to the library. */
3009
+ async addsessionrecord(record2) {
3010
+ const records = await this.getsessionrecords();
3011
+ await this.adapter.set("sessionrecords", [record2, ...records]);
3012
+ }
3013
+ /** Replaces one saved session record by its id after a filing or restore touches it. */
3014
+ async updatesessionrecord(record2) {
3015
+ const records = await this.getsessionrecords();
3016
+ await this.adapter.set("sessionrecords", records.map((item) => item.id === record2.id ? record2 : item));
3017
+ }
3018
+ /** Lists saved sessions filtered by name substring, folder and time window; the filter stays a user choice with no result cap. */
3019
+ async listsessions(filter) {
3020
+ return filteredsessions(await this.getsessionrecords(), filter);
3021
+ }
3022
+ /** Returns one saved session with every section; an expired record carries its metadata only. */
3023
+ async getsessionrecord(id) {
3024
+ return (await this.getsessionrecords()).find((record2) => record2.id === id);
3025
+ }
3026
+ /** Runs the reviewed search query across every stored session and returns the matches with their session ids and time windows. */
3027
+ async searchmemory(query) {
3028
+ return searchsessionrecords(query, await this.getsessionrecords());
3029
+ }
3030
+ /** Returns the folder tree of the session library. */
3031
+ async getsessionfolders() {
3032
+ return await this.adapter.get("sessionfolders") ?? [];
3033
+ }
3034
+ /** Replaces the folder tree after a reviewed filing adds or moves one folder. */
3035
+ async setsessionfolders(folders) {
3036
+ return this.adapter.set("sessionfolders", folders);
3037
+ }
3038
+ /** Returns every stored session diff result, newest first. */
3039
+ async getsessiondiffs() {
3040
+ return await this.adapter.get("sessiondiffs") ?? [];
3041
+ }
3042
+ /** Stores one session diff result for later review. */
3043
+ async addsessiondiff(diff) {
3044
+ const records = await this.getsessiondiffs();
3045
+ await this.adapter.set("sessiondiffs", [diff, ...records]);
3046
+ }
3047
+ /** Returns the persisted auto snapshot state with the reviewed interval, the last snapshot time and the snapshot count. */
3048
+ async getautosnapshot() {
3049
+ return await this.adapter.get("autosnapshot") ?? void 0;
3050
+ }
3051
+ /** Stores the auto snapshot state of the reviewed interval. */
3052
+ async setautosnapshot(state) {
3053
+ return this.adapter.set("autosnapshot", state);
3054
+ }
3055
+ /** Clears the auto snapshot interval so on demand captures stay the only source of records. */
3056
+ async clearautosnapshot() {
3057
+ return this.adapter.set("autosnapshot", null);
3058
+ }
3059
+ /** Expires the heavy sections of saved sessions after the reviewed retention window while the record metadata survives. */
3060
+ async applysessionexpiry(retention, now) {
3061
+ const records = expiresessions(await this.getsessionrecords(), retention, now);
3062
+ await this.adapter.set("sessionrecords", records);
3063
+ return records;
3064
+ }
3065
+ /** Returns the crash marker of a run interrupted by a browser restart. */
3066
+ async getcrashflag() {
3067
+ return await this.adapter.get("crashed") ?? false;
3068
+ }
3069
+ /** Sets the crash marker so the sessions view offers the crash restore inside the consent model. */
3070
+ async setcrashflag(value) {
3071
+ return this.adapter.set("crashed", value);
3072
+ }
2520
3073
  };
2521
3074
  function mediakindof(record2) {
2522
3075
  if ("pages" in record2) return "pdf";
@@ -3463,9 +4016,9 @@ function polldecision(input) {
3463
4016
  }
3464
4017
 
3465
4018
  // policy.ts
3466
- 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"]);
4019
+ 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", "restoresession", "exportsessions", "importsessions"]);
3467
4020
  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"]);
3468
- 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"]);
4021
+ 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", "persiststate", "capturesession", "namedsessions", "diffsessions", "searchsessions"]);
3469
4022
  var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
3470
4023
  var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
3471
4024
  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"]);
@@ -3484,6 +4037,8 @@ var controlactions = /* @__PURE__ */ new Set(["blockrequest", "mockresponse", "r
3484
4037
  var debugactions = /* @__PURE__ */ new Set(["watchconsole", "watcherrors", "watchtasks"]);
3485
4038
  var cdpactions = /* @__PURE__ */ new Set(["attachcdp", "detachcdp", "cdpcmd", "watchcdp", "setbreakpoint", "stepcode", "watchexpr", "overridescript"]);
3486
4039
  var profileractions = /* @__PURE__ */ new Set(["measureflow", "heapshot", "trackmemory", "profilecpu", "watchshifts", "traceload", "annotatetrace", "replaytrace", "capturesourcemaps"]);
4040
+ var emulationactions = /* @__PURE__ */ new Set(["emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "blackboxscripts"]);
4041
+ var sessionactions = /* @__PURE__ */ new Set(["persiststate", "capturesession", "restoresession", "namedsessions", "diffsessions", "searchsessions", "exportsessions", "importsessions"]);
3487
4042
  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"]);
3488
4043
  var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
3489
4044
  var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
@@ -3499,6 +4054,9 @@ function hostpattern(origin) {
3499
4054
  if (parsed.protocol !== "https:") throw new Error("Only HTTPS origins can be granted.");
3500
4055
  return `${parsed.origin}/*`;
3501
4056
  }
4057
+ function issessionkind(kind) {
4058
+ return sessionactions.has(kind);
4059
+ }
3502
4060
  function iswatchkind(kind) {
3503
4061
  return watchactions.has(kind);
3504
4062
  }
@@ -3511,6 +4069,9 @@ function iscdpkind(kind) {
3511
4069
  function isprofilekind(kind) {
3512
4070
  return profileractions.has(kind);
3513
4071
  }
4072
+ function isemulationkind(kind) {
4073
+ return emulationactions.has(kind);
4074
+ }
3514
4075
  function observationmodeof(kind) {
3515
4076
  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";
3516
4077
  if (kind === "diffsnapshots") return "diffing";
@@ -4795,6 +5356,176 @@ function pauseretentionwindow(settings) {
4795
5356
  function breakpointceilingof(settings) {
4796
5357
  return settings?.breakpointceiling;
4797
5358
  }
5359
+ function emugate(input) {
5360
+ const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now: input.now, action: "emulate the run tab" });
5361
+ if (!gate.allowed) return gate;
5362
+ if (!input.plan || input.plan.state !== "approved") return { allowed: false, reason: "Emulation layers need an approved plan before they apply." };
5363
+ let options = {};
5364
+ try {
5365
+ options = parseoptions(input.step);
5366
+ } catch {
5367
+ options = {};
5368
+ }
5369
+ if (options.reviewed !== true) return { allowed: false, reason: `The ${input.step.kind} layer needs the explicit reviewed flag before any mask applies.` };
5370
+ 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.` };
5371
+ return { allowed: true };
5372
+ }
5373
+ function emulationstackallowed(plan, kind, active) {
5374
+ if (!plan) return { allowed: false, reason: "Layer stacking needs the reviewed plan first." };
5375
+ const listed = plan.steps.filter((step) => step.kind === kind).length;
5376
+ 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.` };
5377
+ return { allowed: true };
5378
+ }
5379
+ function locationconsentgate(origin, latitude, longitude, consents) {
5380
+ 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.` };
5381
+ if (locationconsentcovers(origin, latitude, longitude, consents)) return { allowed: true };
5382
+ 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.` };
5383
+ }
5384
+ function emulationretentionwindow(settings) {
5385
+ return settings?.emulationretention;
5386
+ }
5387
+ function validateemulationgrammar(step, options) {
5388
+ const kind = step.kind;
5389
+ if (revertplanof(options.revertplan) === void 0) return { allowed: false, reason: `Every ${kind} layer needs a reviewed revert plan before any mask applies.` };
5390
+ if (kind === "emulatedevice") {
5391
+ const preset = devicepresetof(options.device);
5392
+ 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." };
5393
+ 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." };
5394
+ return { allowed: true };
5395
+ }
5396
+ if (kind === "emulatenetwork") {
5397
+ const preset = networkpresetof(options.network);
5398
+ 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." };
5399
+ 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." };
5400
+ return { allowed: true };
5401
+ }
5402
+ if (kind === "emulatelocate") {
5403
+ const preset = locationpresetof(options.location);
5404
+ 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." };
5405
+ 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." };
5406
+ return { allowed: true };
5407
+ }
5408
+ if (kind === "setuseragent") {
5409
+ const preset = agentpresetof(options.agent);
5410
+ 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." };
5411
+ 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." };
5412
+ return { allowed: true };
5413
+ }
5414
+ if (kind === "overridepermission") {
5415
+ const grant = permissiongrantof(options.permission);
5416
+ 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(", ")}.` };
5417
+ void permissiongrade(grant.name);
5418
+ return { allowed: true };
5419
+ }
5420
+ if (kind === "blackboxscripts") {
5421
+ const rules = Array.isArray(options.rules) ? options.rules.flatMap((rule) => {
5422
+ const parsed = blackboxruleof(rule);
5423
+ return parsed !== void 0 ? [parsed] : [];
5424
+ }) : [];
5425
+ 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." };
5426
+ return { allowed: true };
5427
+ }
5428
+ return { allowed: true };
5429
+ }
5430
+ function permissionnamevalid(name) {
5431
+ if (!browserpermissions.includes(name)) return { allowed: false, reason: `The permission ${name} stays outside the reviewed browser permission set: ${browserpermissions.join(", ")}.` };
5432
+ return { allowed: true };
5433
+ }
5434
+ function validatesessiongrammar(step, options) {
5435
+ const kind = step.kind;
5436
+ if (kind === "persiststate") {
5437
+ if (options.resume !== void 0 && typeof options.resume !== "boolean") return { allowed: false, reason: "The reviewed resume flag must be a boolean." };
5438
+ return { allowed: true };
5439
+ }
5440
+ if (kind === "capturesession") {
5441
+ const plan = snapshotplanof(options.snapshot);
5442
+ if (!plan) return { allowed: false, reason: "The session capture needs a reviewed snapshot plan with its scope, a non-empty section list of the reviewed grammar (tabs, scroll, forms, storage, cookies) and the capture link flag." };
5443
+ if (plan.auto !== void 0) {
5444
+ const interval = autointervalof(options.snapshot.auto);
5445
+ if (interval === void 0) return { allowed: false, reason: "The reviewed auto snapshot interval needs a positive period, a positive maximum snapshot count and a zero or positive expiry window with no code ceiling." };
5446
+ }
5447
+ return { allowed: true };
5448
+ }
5449
+ if (kind === "restoresession") {
5450
+ if (typeof options.sessionid !== "string" || !options.sessionid.trim()) return { allowed: false, reason: "The session restore needs the reviewed session id of the saved record." };
5451
+ if (restoreplanof(options.restore) === void 0) return { allowed: false, reason: "The session restore needs a reviewed restore plan with its tab, form and capture policies." };
5452
+ if (options.reviewed !== true) return { allowed: false, reason: "Every session restore needs the explicit restore review with its tabs, form state and captures listed before it reopens anything." };
5453
+ return { allowed: true };
5454
+ }
5455
+ if (kind === "namedsessions") {
5456
+ if (typeof options.sessionid !== "string" || !options.sessionid.trim()) return { allowed: false, reason: "The session filing needs the reviewed session id of the saved record." };
5457
+ if (typeof options.name !== "string" || !options.name.trim()) return { allowed: false, reason: "The session filing needs a reviewed non-empty session name." };
5458
+ if (options.folder !== void 0 && (typeof options.folder !== "string" || !options.folder.trim())) return { allowed: false, reason: "The reviewed folder name must be a non-empty string." };
5459
+ if (options.tags !== void 0 && (!Array.isArray(options.tags) || !options.tags.every((tag) => typeof tag === "string" && tag.trim()))) return { allowed: false, reason: "The reviewed tag list must be a list of non-empty strings." };
5460
+ return { allowed: true };
5461
+ }
5462
+ if (kind === "diffsessions") {
5463
+ if (typeof options.left !== "string" || !options.left.trim() || typeof options.right !== "string" || !options.right.trim()) return { allowed: false, reason: "The session diff needs the reviewed ids of both saved sessions." };
5464
+ return { allowed: true };
5465
+ }
5466
+ if (kind === "searchsessions") {
5467
+ if (searchqueryof(options.query) === void 0) return { allowed: false, reason: "The session search needs a reviewed query with a non-empty term list, fields of the reviewed grammar (urls, titles, names, text) and an optional time window." };
5468
+ return { allowed: true };
5469
+ }
5470
+ if (kind === "exportsessions") {
5471
+ if (options.reviewed !== true) return { allowed: false, reason: "Session exports need the explicit export review before any session file leaves the device." };
5472
+ if (options.ids !== void 0 && (!Array.isArray(options.ids) || options.ids.length === 0 || !options.ids.every((id) => typeof id === "string" && id.trim()))) return { allowed: false, reason: "The reviewed export id list must be a non-empty list of saved session ids." };
5473
+ return { allowed: true };
5474
+ }
5475
+ if (kind === "importsessions") {
5476
+ if (options.reviewed !== true) return { allowed: false, reason: "Session imports need the explicit full record review before any record joins the library." };
5477
+ if (importsessionfile(options.file) === void 0) return { allowed: false, reason: "The session import needs a reviewed file of the known format version with an intact checksum." };
5478
+ return { allowed: true };
5479
+ }
5480
+ return { allowed: true };
5481
+ }
5482
+ function restorereviewgranted(step) {
5483
+ let options = {};
5484
+ try {
5485
+ options = parseoptions(step);
5486
+ } catch {
5487
+ options = {};
5488
+ }
5489
+ if (restoreplanof(options.restore) === void 0) return { allowed: false, reason: "Every session restore needs a reviewed restore plan with its tab, form and capture policies." };
5490
+ if (options.reviewed !== true) return { allowed: false, reason: "The session restore needs the explicit restore review of its tabs, form state and captures before it reopens anything." };
5491
+ return { allowed: true };
5492
+ }
5493
+ function sessionrestoregate(input) {
5494
+ const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now: input.now, action: "run the session memory step" });
5495
+ if (!gate.allowed) return gate;
5496
+ if (!input.plan || input.plan.state !== "approved") return { allowed: false, reason: "Session memory steps need an approved plan before they run." };
5497
+ if (input.step.kind === "restoresession") return restorereviewgranted(input.step);
5498
+ return { allowed: true };
5499
+ }
5500
+ function restoreoriginsgranted(urls, grants) {
5501
+ const covered = new Set(grants);
5502
+ const skippedorigins = [];
5503
+ for (const url of urls) {
5504
+ let origin = "";
5505
+ try {
5506
+ origin = new URL(url).origin;
5507
+ } catch {
5508
+ origin = "";
5509
+ }
5510
+ if (!origin || !covered.has(origin)) skippedorigins.push(origin || url);
5511
+ }
5512
+ return { allowed: skippedorigins.length === 0, skippedorigins: [...new Set(skippedorigins)] };
5513
+ }
5514
+ function sessionnameunique(name, records, recordid) {
5515
+ if (records.some((record2) => record2.name === name && record2.id !== recordid)) return { allowed: false, reason: `The session name ${name} already exists in the library; review a unique name.` };
5516
+ return { allowed: true };
5517
+ }
5518
+ function sessionfolderunique(name, folders) {
5519
+ if (folders.some((folder) => folder.name === name)) return { allowed: false, reason: `The folder name ${name} already exists in the library; review a unique folder name.` };
5520
+ return { allowed: true };
5521
+ }
5522
+ function snapshotretentionwindow(settings) {
5523
+ return settings?.sessionretention;
5524
+ }
5525
+ function permissionstatevalid(state) {
5526
+ if (!permissionstates.includes(state)) return { allowed: false, reason: `The reviewed permission state must be one of ${permissionstates.join(", ")}.` };
5527
+ return { allowed: true };
5528
+ }
4798
5529
  function validatecdpgrammar(step, options) {
4799
5530
  const kind = step.kind;
4800
5531
  if (kind === "attachcdp") {
@@ -5352,6 +6083,14 @@ function validatestep(step, origin) {
5352
6083
  const profilecheck = validateprofilegrammar(step, options);
5353
6084
  if (!profilecheck.allowed) return profilecheck;
5354
6085
  }
6086
+ if (isemulationkind(step.kind)) {
6087
+ const emulationcheck = validateemulationgrammar(step, options);
6088
+ if (!emulationcheck.allowed) return emulationcheck;
6089
+ }
6090
+ if (issessionkind(step.kind)) {
6091
+ const sessioncheck = validatesessiongrammar(step, options);
6092
+ if (!sessioncheck.allowed) return sessioncheck;
6093
+ }
5355
6094
  if (step.kind === "tabcreate") {
5356
6095
  if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
5357
6096
  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." };
@@ -5521,6 +6260,27 @@ function canexecute(input) {
5521
6260
  }
5522
6261
  }
5523
6262
  }
6263
+ if (isemulationkind(input.step.kind)) {
6264
+ const emugatecheck = emugate({ session: input.session, plan: input.plan, step: input.step, tabid: input.tabid, origin: input.origin, now });
6265
+ if (!emugatecheck.allowed) return emugatecheck;
6266
+ }
6267
+ if (issessionkind(input.step.kind)) {
6268
+ const sessiongatecheck = sessionrestoregate({ session: input.session, plan: input.plan, step: input.step, tabid: input.tabid, origin: input.origin, now });
6269
+ if (!sessiongatecheck.allowed) return sessiongatecheck;
6270
+ if (input.step.kind === "restoresession") {
6271
+ let restoreoptions = {};
6272
+ try {
6273
+ restoreoptions = parseoptions(input.step);
6274
+ } catch {
6275
+ restoreoptions = {};
6276
+ }
6277
+ for (const url of Array.isArray(restoreoptions.origins) ? restoreoptions.origins : []) {
6278
+ if (typeof url !== "string" || !url) continue;
6279
+ const origingate = origincheck(input.session, url);
6280
+ if (!origingate.allowed) return { allowed: false, reason: `The session restore reopens ${url} outside the session origin grants; review the restore record or grant the origin.` };
6281
+ }
6282
+ }
6283
+ }
5524
6284
  if (iscontrolkind(input.step.kind)) {
5525
6285
  const controlgate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: "control the network" });
5526
6286
  if (!controlgate.allowed) return controlgate;
@@ -5604,7 +6364,7 @@ function canexecute(input) {
5604
6364
  }
5605
6365
 
5606
6366
  // version.ts
5607
- var packageversion = "1.1.47";
6367
+ var packageversion = "1.1.49";
5608
6368
 
5609
6369
  // types.ts
5610
6370
  var protocolversion = packageversion;
@@ -5776,6 +6536,50 @@ function parseproposal(value, origin, grants) {
5776
6536
  }
5777
6537
  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.");
5778
6538
  }
6539
+ if (isemulationkind(step.kind)) {
6540
+ const granted = covered.some((pattern) => {
6541
+ try {
6542
+ return new URL(origin).origin === new URL(pattern).origin;
6543
+ } catch {
6544
+ return false;
6545
+ }
6546
+ });
6547
+ if (!granted) throw new Error(`The ${step.kind} step of ${origin} targets an origin outside the grants.`);
6548
+ let emulationoptions = {};
6549
+ try {
6550
+ emulationoptions = parseoptions(step);
6551
+ } catch {
6552
+ emulationoptions = {};
6553
+ }
6554
+ if (revertplanof(emulationoptions.revertplan) === void 0) throw new Error("Emulation steps without a reviewed revert plan are refused.");
6555
+ if (step.kind === "emulatelocate") {
6556
+ const preset = locationpresetof(emulationoptions.location);
6557
+ if (preset === void 0) throw new Error("Location emulation needs a reviewed preset with coordinates inside the latitude and longitude ranges.");
6558
+ }
6559
+ if (step.kind === "overridepermission" && permissiongrantof(emulationoptions.permission) === void 0) throw new Error("Permission overrides of unknown permission names are refused.");
6560
+ }
6561
+ if (issessionkind(step.kind)) {
6562
+ let sessionoptions = {};
6563
+ try {
6564
+ sessionoptions = parseoptions(step);
6565
+ } catch {
6566
+ sessionoptions = {};
6567
+ }
6568
+ if (step.kind === "restoresession") {
6569
+ for (const url of Array.isArray(sessionoptions.origins) ? sessionoptions.origins : []) {
6570
+ if (typeof url !== "string" || !url) continue;
6571
+ const granted = covered.some((pattern) => {
6572
+ try {
6573
+ return new URL(url).origin === new URL(pattern).origin;
6574
+ } catch {
6575
+ return false;
6576
+ }
6577
+ });
6578
+ if (!granted) throw new Error(`The session restore reopens ${url} outside the grants.`);
6579
+ }
6580
+ }
6581
+ if (step.kind === "importsessions" && importsessionfile(sessionoptions.file) === void 0) throw new Error("Session import files of unknown format versions are refused.");
6582
+ }
5779
6583
  const evaluation = validatestep(step, origin);
5780
6584
  if (!evaluation.allowed) throw new Error(evaluation.reason);
5781
6585
  const target = outboundtarget(step);
@@ -5850,7 +6654,7 @@ function requestbody(input) {
5850
6654
  return JSON.stringify({ version: protocolversion, objective: input.objective, session: input.session, observation: input.observation, capabilities: input.capabilities });
5851
6655
  }
5852
6656
  function outcomeresponse(input) {
5853
- 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 } : {} });
6657
+ 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 } : {}, ...input.session ? { session: input.session } : {} });
5854
6658
  }
5855
6659
  function mapresponse(input) {
5856
6660
  return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, map: input.map });
@@ -5988,7 +6792,21 @@ function profilereport(input) {
5988
6792
  });
5989
6793
  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 };
5990
6794
  }
6795
+ function emulationreport(input) {
6796
+ const consents = input.consents.map((consent) => {
6797
+ const { prompt, ...metadata } = consent;
6798
+ void prompt;
6799
+ return metadata;
6800
+ });
6801
+ 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 };
6802
+ }
6803
+ function sessionreport(input) {
6804
+ return { version: protocolversion, records: input.records, events: input.events, folders: input.folders, diffs: input.diffs, ...input.auto !== void 0 ? { auto: input.auto } : {}, ...input.crashed === true ? { crashed: true } : {} };
6805
+ }
5991
6806
  export {
6807
+ activelayers,
6808
+ agentgrammarvalid,
6809
+ agentpresetof,
5992
6810
  allowlistcovers,
5993
6811
  annotatetrace,
5994
6812
  annotationof,
@@ -5997,6 +6815,7 @@ export {
5997
6815
  apikeyconsentgranted,
5998
6816
  apireplayspecof,
5999
6817
  applyheaderules,
6818
+ applylayer,
6000
6819
  argkind,
6001
6820
  assetentries,
6002
6821
  attachcdpsession,
@@ -6005,6 +6824,10 @@ export {
6005
6824
  authconsentgranted,
6006
6825
  authorizeurl,
6007
6826
  authreport,
6827
+ autointervalof,
6828
+ blackboxedurls,
6829
+ blackboxmatches,
6830
+ blackboxruleof,
6008
6831
  blendrows,
6009
6832
  blockgate,
6010
6833
  blockingduration,
@@ -6014,6 +6837,7 @@ export {
6014
6837
  breakpointbudgetallowed,
6015
6838
  breakpointceilingof,
6016
6839
  breakpointinputof,
6840
+ browserpermissions,
6017
6841
  buildname,
6018
6842
  buildpdf,
6019
6843
  buildsheet,
@@ -6059,6 +6883,7 @@ export {
6059
6883
  cookierecordof,
6060
6884
  correlationid,
6061
6885
  cpusnap,
6886
+ crashinterrupted,
6062
6887
  croprect,
6063
6888
  crossesviewport,
6064
6889
  cursorfrom,
@@ -6069,19 +6894,33 @@ export {
6069
6894
  dedupeimages,
6070
6895
  actionrisk as deriveactionrisk,
6071
6896
  detachcdpsession,
6897
+ devicepresetof,
6072
6898
  diffresponse,
6073
6899
  diffreviewgrade,
6900
+ diffsessionrecords,
6074
6901
  downloadreport,
6902
+ emugate,
6903
+ emulationkinds,
6904
+ emulationreport,
6905
+ emulationretentionwindow,
6906
+ emulationstackallowed,
6907
+ emulationstateof,
6075
6908
  errorcapture,
6076
6909
  errorreportresponse,
6077
6910
  eventresponse,
6078
6911
  exchangesreport,
6912
+ expirelayers,
6079
6913
  expireprofilerecords,
6914
+ expiresessions,
6915
+ exportpresetlibrary,
6916
+ exportsessionfile,
6080
6917
  extractionreport,
6081
6918
  extractvalues,
6082
6919
  failureclass,
6920
+ familyofkind,
6083
6921
  fetchoptionsof,
6084
6922
  fetchrequestof,
6923
+ filteredsessions,
6085
6924
  filterentries,
6086
6925
  filterexchanges,
6087
6926
  finishrecording,
@@ -6101,25 +6940,35 @@ export {
6101
6940
  heapintervalallowed,
6102
6941
  heapsnap,
6103
6942
  heldkeysreport,
6943
+ hideblackboxedframes,
6104
6944
  hostpattern,
6105
6945
  htmlqueriesof,
6106
6946
  httpkinds,
6107
6947
  imagefilterof,
6108
6948
  imagematches,
6109
6949
  imagenames,
6950
+ importpresetlibrary,
6951
+ importsessionfile,
6110
6952
  iscdpkind,
6111
6953
  iscontrolkind,
6112
6954
  isdebugkind,
6955
+ isemulationkind,
6113
6956
  isformkind,
6114
6957
  isnetwatchkind,
6115
6958
  isprofilekind,
6959
+ issessionkind,
6116
6960
  issocketkind,
6117
6961
  iswatchkind,
6118
6962
  jsonpathrulesof,
6119
6963
  lapseframes,
6120
6964
  lapseplanof,
6965
+ layernames,
6121
6966
  layoutreport,
6122
6967
  levelrank,
6968
+ locationconsentcovers,
6969
+ locationconsentgate,
6970
+ locationpresetof,
6971
+ locationrangevalid,
6123
6972
  loglevels,
6124
6973
  longtaskcapture,
6125
6974
  mapresponse,
@@ -6140,12 +6989,16 @@ export {
6140
6989
  netfailureentryof,
6141
6990
  netlogreport,
6142
6991
  netwatchkinds,
6992
+ networkpresetof,
6143
6993
  newblockrule,
6144
6994
  newchannel,
6145
6995
  newexchange,
6146
6996
  newheaderule,
6997
+ newlayer,
6147
6998
  newmockspec,
6148
6999
  newrecording,
7000
+ newsessiondiff,
7001
+ newsessionrecord,
6149
7002
  normalizeendpoint,
6150
7003
  oauthflowof,
6151
7004
  observationmodeof,
@@ -6170,6 +7023,11 @@ export {
6170
7023
  pdfpagesize,
6171
7024
  pdfsegments,
6172
7025
  pdftextlayout,
7026
+ permissiongrade,
7027
+ permissiongrantof,
7028
+ permissionnamevalid,
7029
+ permissionstates,
7030
+ permissionstatevalid,
6173
7031
  planallowlist,
6174
7032
  pollcursorof,
6175
7033
  polldecision,
@@ -6206,7 +7064,13 @@ export {
6206
7064
  resolutionverdict,
6207
7065
  resolvedrisk,
6208
7066
  resourcefacts,
7067
+ restoreoriginsgranted,
7068
+ restoreplanof,
7069
+ restorereviewgranted,
6209
7070
  retryafterof,
7071
+ revertalllayers,
7072
+ revertlayer,
7073
+ revertplanof,
6210
7074
  revertrule,
6211
7075
  revocationruleof,
6212
7076
  rewritesourcelocation,
@@ -6215,21 +7079,36 @@ export {
6215
7079
  safetyresponse,
6216
7080
  scaledrect,
6217
7081
  seamweights,
7082
+ searchfields,
7083
+ searchqueryof,
7084
+ searchsessionrecords,
6218
7085
  selectorresponse,
6219
7086
  sendcdpcommand,
6220
7087
  sendfetch,
6221
7088
  sequenceintegrity,
6222
7089
  serializearg,
6223
7090
  serializecdpcommand,
7091
+ sessionfileversion,
7092
+ sessionfolderof,
7093
+ sessionfolderunique,
7094
+ sessionkinds,
6224
7095
  sessionmemory,
7096
+ sessionnameunique,
7097
+ sessionreport,
7098
+ sessionrestoregate,
7099
+ sessiontabof,
6225
7100
  shiftentryof,
6226
7101
  signalsreport,
7102
+ snapshotplanof,
7103
+ snapshotretentionwindow,
7104
+ snapshotsections,
6227
7105
  socketgate,
6228
7106
  socketkinds,
6229
7107
  sourcemapconsentcovers,
6230
7108
  spamdetect,
6231
7109
  spamruleof,
6232
7110
  sserequestheaders,
7111
+ stackedcount,
6233
7112
  stackframes,
6234
7113
  stackgate,
6235
7114
  statusclassof,
@@ -6241,6 +7120,9 @@ export {
6241
7120
  subscriptionoptionsof,
6242
7121
  tabreportresponse,
6243
7122
  targetgate,
7123
+ taskstatechecksum,
7124
+ taskstateof,
7125
+ taskstatevalid,
6244
7126
  teardowncdpsession,
6245
7127
  teardownplanof,
6246
7128
  templateurl,