@wenathlan/extension 1.1.40 → 1.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +551 -5
- package/dist/index.js.map +4 -4
- package/dist/media.d.ts +96 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/memory.d.ts +24 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +12 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +18 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/types.d.ts +208 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +955 -11
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +194 -3
- package/extension/dist/pagebridge.js.map +3 -3
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +14 -2
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +253 -2
- package/extension/dist/sidepanel.js.map +3 -3
- package/extension/dist/style.css +2 -0
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -196,6 +196,308 @@ function annotationplanof(input) {
|
|
|
196
196
|
return plan;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
// media.ts
|
|
200
|
+
var mediakinds = ["capturepdf", "recordscreen", "captureaudio", "captureframe", "downloadimages", "shotcanvas", "probestream", "readmedia", "readassets", "timelapse", "convertimage", "makethumbs"];
|
|
201
|
+
var defaultpaperwidth = 8.5;
|
|
202
|
+
var defaultpaperheight = 11;
|
|
203
|
+
var defaultmargins = { top: 0.4, right: 0.4, bottom: 0.4, left: 0.4 };
|
|
204
|
+
var pdfpointsperinch = 72;
|
|
205
|
+
var basefontsize = 11;
|
|
206
|
+
function pdfoptionsof(value) {
|
|
207
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
208
|
+
const options = value;
|
|
209
|
+
const normalized = {};
|
|
210
|
+
if (typeof options.paperwidth === "number" && Number.isFinite(options.paperwidth)) normalized.paperwidth = options.paperwidth;
|
|
211
|
+
if (typeof options.paperheight === "number" && Number.isFinite(options.paperheight)) normalized.paperheight = options.paperheight;
|
|
212
|
+
if (options.margins && typeof options.margins === "object" && !Array.isArray(options.margins)) {
|
|
213
|
+
const margins = options.margins;
|
|
214
|
+
const top = typeof margins.top === "number" ? margins.top : defaultmargins.top;
|
|
215
|
+
const right = typeof margins.right === "number" ? margins.right : defaultmargins.right;
|
|
216
|
+
const bottom = typeof margins.bottom === "number" ? margins.bottom : defaultmargins.bottom;
|
|
217
|
+
const left = typeof margins.left === "number" ? margins.left : defaultmargins.left;
|
|
218
|
+
normalized.margins = { top, right, bottom, left };
|
|
219
|
+
}
|
|
220
|
+
if (typeof options.scale === "number" && Number.isFinite(options.scale)) normalized.scale = options.scale;
|
|
221
|
+
if (typeof options.landscape === "boolean") normalized.landscape = options.landscape;
|
|
222
|
+
if (typeof options.paginate === "boolean") normalized.paginate = options.paginate;
|
|
223
|
+
return normalized;
|
|
224
|
+
}
|
|
225
|
+
function pdfpagesize(options) {
|
|
226
|
+
const width = (options.paperwidth ?? defaultpaperwidth) * pdfpointsperinch;
|
|
227
|
+
const height = (options.paperheight ?? defaultpaperheight) * pdfpointsperinch;
|
|
228
|
+
return options.landscape === true ? { width: height, height: width } : { width, height };
|
|
229
|
+
}
|
|
230
|
+
function pdfmargins(options) {
|
|
231
|
+
const margins = options.margins ?? defaultmargins;
|
|
232
|
+
return { top: margins.top * pdfpointsperinch, right: margins.right * pdfpointsperinch, bottom: margins.bottom * pdfpointsperinch, left: margins.left * pdfpointsperinch };
|
|
233
|
+
}
|
|
234
|
+
function pdffontsize(options) {
|
|
235
|
+
return basefontsize * (options.scale ?? 1);
|
|
236
|
+
}
|
|
237
|
+
function pdftextlayout(text2, options) {
|
|
238
|
+
const size = pdfpagesize(options);
|
|
239
|
+
const margins = pdfmargins(options);
|
|
240
|
+
const fontsize = pdffontsize(options);
|
|
241
|
+
const leading = fontsize * 1.35;
|
|
242
|
+
const linesperpage = Math.max(1, Math.floor((size.height - margins.top - margins.bottom) / leading));
|
|
243
|
+
const columns = Math.max(1, Math.floor((size.width - margins.left - margins.right) / (fontsize * 0.5)));
|
|
244
|
+
const wrapped = [];
|
|
245
|
+
for (const paragraph of text2.split(/\r?\n/)) {
|
|
246
|
+
let line = "";
|
|
247
|
+
for (const word of paragraph.split(/\s+/).filter(Boolean)) {
|
|
248
|
+
const candidate = line ? `${line} ${word}` : word;
|
|
249
|
+
if (candidate.length <= columns) {
|
|
250
|
+
line = candidate;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (line) wrapped.push(line);
|
|
254
|
+
if (word.length <= columns) {
|
|
255
|
+
line = word;
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
for (let index = 0; index < word.length; index += columns) wrapped.push(word.slice(index, index + columns));
|
|
259
|
+
line = "";
|
|
260
|
+
}
|
|
261
|
+
wrapped.push(line);
|
|
262
|
+
if (wrapped.length >= linesperpage) break;
|
|
263
|
+
}
|
|
264
|
+
return wrapped.slice(0, linesperpage);
|
|
265
|
+
}
|
|
266
|
+
function pdfsegments(scrollheight, viewportheight, breaks) {
|
|
267
|
+
if (scrollheight <= 0) return [];
|
|
268
|
+
const step = viewportheight > 0 ? viewportheight : scrollheight;
|
|
269
|
+
const cuts = [0, ...breaks.filter((top) => Number.isFinite(top) && top > 0 && top < scrollheight).map((top) => Math.round(top))].filter((top, index2, list) => list.indexOf(top) === index2).sort((left, right) => left - right);
|
|
270
|
+
const segments = [];
|
|
271
|
+
let index = 0;
|
|
272
|
+
let cursor = 0;
|
|
273
|
+
while (cursor < scrollheight) {
|
|
274
|
+
while (index < cuts.length && (cuts[index] ?? 0) <= cursor) index += 1;
|
|
275
|
+
const nextcut = index < cuts.length ? cuts[index] : void 0;
|
|
276
|
+
const next = nextcut !== void 0 ? Math.min(nextcut, scrollheight) : Math.min(cursor + step, scrollheight);
|
|
277
|
+
if (next <= cursor) break;
|
|
278
|
+
segments.push({ top: cursor, height: next - cursor });
|
|
279
|
+
cursor = next;
|
|
280
|
+
}
|
|
281
|
+
return segments.length > 0 ? segments : [{ top: 0, height: scrollheight }];
|
|
282
|
+
}
|
|
283
|
+
function pdfescape(text2) {
|
|
284
|
+
let escaped = "";
|
|
285
|
+
for (const character of text2) {
|
|
286
|
+
const code = character.charCodeAt(0);
|
|
287
|
+
if (character === "(" || character === ")" || character === "\\") escaped += `\\${character}`;
|
|
288
|
+
else if (code >= 32 && code <= 255) escaped += character;
|
|
289
|
+
else escaped += "?";
|
|
290
|
+
}
|
|
291
|
+
return escaped;
|
|
292
|
+
}
|
|
293
|
+
function buildpdf(pages, options) {
|
|
294
|
+
const size = pdfpagesize(options);
|
|
295
|
+
const margins = pdfmargins(options);
|
|
296
|
+
const fontsize = pdffontsize(options);
|
|
297
|
+
const leading = fontsize * 1.35;
|
|
298
|
+
const laidout = (pages.length > 0 ? pages : [""]).map((text2) => pdftextlayout(text2, options));
|
|
299
|
+
const objects = [];
|
|
300
|
+
const kids = laidout.map((_, index) => `${4 + index * 2} 0 R`).join(" ");
|
|
301
|
+
objects.push(`<< /Type /Catalog /Pages 2 0 R >>`);
|
|
302
|
+
objects.push(`<< /Type /Pages /Kids [${kids}] /Count ${laidout.length} >>`);
|
|
303
|
+
objects.push(`<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>`);
|
|
304
|
+
for (let pageindex = 0; pageindex < laidout.length; pageindex += 1) {
|
|
305
|
+
const lines = laidout[pageindex] ?? [];
|
|
306
|
+
const operators = ["BT", `/F1 ${fontsize} Tf`, `${leading.toFixed(2)} TL`, `${margins.left.toFixed(2)} ${(size.height - margins.top - fontsize).toFixed(2)} Td`];
|
|
307
|
+
for (let lineindex = 0; lineindex < lines.length; lineindex += 1) {
|
|
308
|
+
if (lineindex > 0) operators.push("T*");
|
|
309
|
+
operators.push(`(${pdfescape(lines[lineindex] ?? "")}) Tj`);
|
|
310
|
+
}
|
|
311
|
+
operators.push("ET");
|
|
312
|
+
const content = operators.join("\n");
|
|
313
|
+
objects.push(`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${size.width.toFixed(2)} ${size.height.toFixed(2)}] /Resources << /Font << /F1 3 0 R >> >> /Contents ${5 + pageindex * 2} 0 R >>`);
|
|
314
|
+
objects.push(`<< /Length ${content.length} >>
|
|
315
|
+
stream
|
|
316
|
+
${content}
|
|
317
|
+
endstream`);
|
|
318
|
+
}
|
|
319
|
+
let document = "%PDF-1.4\n";
|
|
320
|
+
const offsets = [];
|
|
321
|
+
for (let index = 0; index < objects.length; index += 1) {
|
|
322
|
+
offsets.push(document.length);
|
|
323
|
+
document += `${index + 1} 0 obj
|
|
324
|
+
${objects[index]}
|
|
325
|
+
endobj
|
|
326
|
+
`;
|
|
327
|
+
}
|
|
328
|
+
const xrefstart = document.length;
|
|
329
|
+
document += `xref
|
|
330
|
+
0 ${objects.length + 1}
|
|
331
|
+
0000000000 65535 f
|
|
332
|
+
`;
|
|
333
|
+
for (const offset of offsets) document += `${String(offset).padStart(10, "0")} 00000 n
|
|
334
|
+
`;
|
|
335
|
+
document += `trailer
|
|
336
|
+
<< /Size ${objects.length + 1} /Root 1 0 R >>
|
|
337
|
+
startxref
|
|
338
|
+
${xrefstart}
|
|
339
|
+
%%EOF
|
|
340
|
+
`;
|
|
341
|
+
return { document, bytes: document.length, pages: laidout.length, pagewidth: Math.round(size.width), pageheight: Math.round(size.height) };
|
|
342
|
+
}
|
|
343
|
+
function recordingoptionsof(value) {
|
|
344
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
345
|
+
const options = value;
|
|
346
|
+
const normalized = {};
|
|
347
|
+
if (options.scope === "tab" || options.scope === "run") normalized.scope = options.scope;
|
|
348
|
+
if (typeof options.fps === "number" && Number.isFinite(options.fps)) normalized.fps = options.fps;
|
|
349
|
+
if (typeof options.bitrate === "number" && Number.isFinite(options.bitrate)) normalized.bitrate = options.bitrate;
|
|
350
|
+
if (typeof options.audio === "boolean") normalized.audio = options.audio;
|
|
351
|
+
return normalized;
|
|
352
|
+
}
|
|
353
|
+
function newrecording(input) {
|
|
354
|
+
return {
|
|
355
|
+
id: input.id,
|
|
356
|
+
runid: input.runid,
|
|
357
|
+
stepid: input.stepid,
|
|
358
|
+
tabid: input.tabid,
|
|
359
|
+
kind: input.kind,
|
|
360
|
+
scope: input.options.scope ?? "tab",
|
|
361
|
+
format: input.kind === "audio" ? "evidence" : "frames",
|
|
362
|
+
startedat: input.at,
|
|
363
|
+
at: input.at,
|
|
364
|
+
...input.options.fps !== void 0 ? { fps: input.options.fps } : {},
|
|
365
|
+
...input.options.bitrate !== void 0 ? { bitrate: input.options.bitrate } : {},
|
|
366
|
+
...input.options.audio !== void 0 ? { audio: input.options.audio } : {},
|
|
367
|
+
frames: []
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function finishrecording(record2, endat) {
|
|
371
|
+
return { ...record2, endedat: endat, duration: Math.max(0, endat - record2.startedat) };
|
|
372
|
+
}
|
|
373
|
+
function frameinterval(fps) {
|
|
374
|
+
if (!Number.isFinite(fps) || fps <= 0) return 1e3;
|
|
375
|
+
return Math.max(1, Math.round(1e3 / fps));
|
|
376
|
+
}
|
|
377
|
+
function imagefilterof(value) {
|
|
378
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
379
|
+
const options = value;
|
|
380
|
+
const normalized = {};
|
|
381
|
+
if (typeof options.selector === "string" && options.selector.trim()) normalized.selector = options.selector.trim();
|
|
382
|
+
if (typeof options.minwidth === "number" && Number.isFinite(options.minwidth)) normalized.minwidth = options.minwidth;
|
|
383
|
+
if (typeof options.minheight === "number" && Number.isFinite(options.minheight)) normalized.minheight = options.minheight;
|
|
384
|
+
if (Array.isArray(options.formats) && options.formats.every((item) => typeof item === "string" && item.trim())) normalized.formats = options.formats;
|
|
385
|
+
return normalized;
|
|
386
|
+
}
|
|
387
|
+
function imagematches(image, filter) {
|
|
388
|
+
if (filter.minwidth !== void 0 && image.width < filter.minwidth) return false;
|
|
389
|
+
if (filter.minheight !== void 0 && image.height < filter.minheight) return false;
|
|
390
|
+
if (filter.formats !== void 0 && filter.formats.length > 0) {
|
|
391
|
+
const mime = image.mime.toLowerCase();
|
|
392
|
+
const matches = filter.formats.some((format) => {
|
|
393
|
+
const wanted = format.toLowerCase().trim();
|
|
394
|
+
return mime === wanted || mime === `image/${wanted}` || mime.endsWith(`/${wanted}`);
|
|
395
|
+
});
|
|
396
|
+
if (!matches) return false;
|
|
397
|
+
}
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
function dedupeimages(images) {
|
|
401
|
+
const seen = /* @__PURE__ */ new Set();
|
|
402
|
+
const unique = [];
|
|
403
|
+
for (const image of images) {
|
|
404
|
+
if (seen.has(image.url)) continue;
|
|
405
|
+
seen.add(image.url);
|
|
406
|
+
unique.push(image);
|
|
407
|
+
}
|
|
408
|
+
return unique;
|
|
409
|
+
}
|
|
410
|
+
function imagenames(rule, run, step, count, extension) {
|
|
411
|
+
const names = [];
|
|
412
|
+
for (let index = 1; index <= Math.max(0, Math.round(count)); index += 1) names.push(buildname(rule, { run, step, sequence: index, kind: "image" }, extension));
|
|
413
|
+
return names;
|
|
414
|
+
}
|
|
415
|
+
function lapseplanof(value) {
|
|
416
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
417
|
+
const options = value;
|
|
418
|
+
if (typeof options.interval !== "number" || !Number.isFinite(options.interval)) return void 0;
|
|
419
|
+
if (typeof options.duration !== "number" || !Number.isFinite(options.duration)) return void 0;
|
|
420
|
+
const format = options.format === "jpeg" || options.format === "webp" ? options.format : "png";
|
|
421
|
+
return { interval: options.interval, duration: options.duration, format };
|
|
422
|
+
}
|
|
423
|
+
function lapseframes(plan) {
|
|
424
|
+
if (!(plan.interval > 0) || !(plan.duration > 0)) return [];
|
|
425
|
+
const frames = [];
|
|
426
|
+
for (let time = 0; time < plan.duration; time += plan.interval) frames.push(Math.round(time));
|
|
427
|
+
return frames;
|
|
428
|
+
}
|
|
429
|
+
function convertdirectiveof(value) {
|
|
430
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
431
|
+
const options = value;
|
|
432
|
+
if (options.target !== "png" && options.target !== "jpeg" && options.target !== "webp") return void 0;
|
|
433
|
+
const normalized = { target: options.target };
|
|
434
|
+
if (options.source === "png" || options.source === "jpeg" || options.source === "webp") normalized.source = options.source;
|
|
435
|
+
if (typeof options.quality === "number" && Number.isFinite(options.quality)) normalized.quality = options.quality;
|
|
436
|
+
return normalized;
|
|
437
|
+
}
|
|
438
|
+
function thumbdirectiveof(value) {
|
|
439
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
440
|
+
const options = value;
|
|
441
|
+
if (typeof options.size !== "number" || !Number.isFinite(options.size) || options.size <= 0) return void 0;
|
|
442
|
+
if (options.fit !== "cover" && options.fit !== "contain") return void 0;
|
|
443
|
+
if (typeof options.suffix !== "string" || !options.suffix.trim()) return void 0;
|
|
444
|
+
return { size: options.size, fit: options.fit, suffix: options.suffix.trim() };
|
|
445
|
+
}
|
|
446
|
+
function thumbgeometry(source, directive) {
|
|
447
|
+
const size = Math.max(1, Math.round(directive.size));
|
|
448
|
+
if (directive.fit === "contain") {
|
|
449
|
+
const scale2 = Math.min(size / Math.max(1, source.width), size / Math.max(1, source.height));
|
|
450
|
+
const dw = Math.max(1, Math.round(source.width * scale2));
|
|
451
|
+
const dh = Math.max(1, Math.round(source.height * scale2));
|
|
452
|
+
return { sx: 0, sy: 0, sw: source.width, sh: source.height, dx: Math.floor((size - dw) / 2), dy: Math.floor((size - dh) / 2), dw, dh, width: size, height: size };
|
|
453
|
+
}
|
|
454
|
+
const scale = Math.max(size / Math.max(1, source.width), size / Math.max(1, source.height));
|
|
455
|
+
const sw = Math.min(source.width, Math.round(size / scale));
|
|
456
|
+
const sh = Math.min(source.height, Math.round(size / scale));
|
|
457
|
+
return { sx: Math.floor((source.width - sw) / 2), sy: Math.floor((source.height - sh) / 2), sw, sh, dx: 0, dy: 0, dw: size, dh: size, width: size, height: size };
|
|
458
|
+
}
|
|
459
|
+
function mediaentries(raw) {
|
|
460
|
+
return raw.map((entry) => ({
|
|
461
|
+
url: typeof entry.url === "string" ? entry.url : "",
|
|
462
|
+
mime: typeof entry.mime === "string" ? entry.mime : "",
|
|
463
|
+
duration: typeof entry.duration === "number" && Number.isFinite(entry.duration) ? entry.duration : 0,
|
|
464
|
+
width: typeof entry.width === "number" && Number.isFinite(entry.width) ? Math.round(entry.width) : 0,
|
|
465
|
+
height: typeof entry.height === "number" && Number.isFinite(entry.height) ? Math.round(entry.height) : 0,
|
|
466
|
+
codecs: typeof entry.codecs === "string" ? entry.codecs : "",
|
|
467
|
+
tracks: Array.isArray(entry.tracks) ? entry.tracks.filter((item) => typeof item === "string") : []
|
|
468
|
+
}));
|
|
469
|
+
}
|
|
470
|
+
function assetentries(raw) {
|
|
471
|
+
return raw.map((entry) => ({
|
|
472
|
+
kind: entry.kind === "logo" ? "logo" : "favicon",
|
|
473
|
+
url: typeof entry.url === "string" ? entry.url : "",
|
|
474
|
+
bytes: typeof entry.bytes === "number" && Number.isFinite(entry.bytes) ? entry.bytes : 0,
|
|
475
|
+
...typeof entry.sizes === "string" && entry.sizes.trim() ? { sizes: entry.sizes.trim() } : {}
|
|
476
|
+
}));
|
|
477
|
+
}
|
|
478
|
+
function streamsummaries(raw) {
|
|
479
|
+
return raw.map((entry) => {
|
|
480
|
+
const tracks = Array.isArray(entry.tracks) ? entry.tracks : [];
|
|
481
|
+
return {
|
|
482
|
+
kind: typeof entry.kind === "string" ? entry.kind : "stream",
|
|
483
|
+
tracks: tracks.length,
|
|
484
|
+
label: typeof entry.label === "string" ? entry.label : "",
|
|
485
|
+
live: entry.live === true,
|
|
486
|
+
detail: tracks.map((track) => {
|
|
487
|
+
const item = track;
|
|
488
|
+
return {
|
|
489
|
+
kind: typeof item.kind === "string" ? item.kind : "",
|
|
490
|
+
label: typeof item.label === "string" ? item.label : "",
|
|
491
|
+
...typeof item.width === "number" && Number.isFinite(item.width) ? { width: Math.round(item.width) } : {},
|
|
492
|
+
...typeof item.height === "number" && Number.isFinite(item.height) ? { height: Math.round(item.height) } : {},
|
|
493
|
+
...typeof item.framerate === "number" && Number.isFinite(item.framerate) ? { framerate: item.framerate } : {},
|
|
494
|
+
state: typeof item.state === "string" ? item.state : ""
|
|
495
|
+
};
|
|
496
|
+
})
|
|
497
|
+
};
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
|
|
199
501
|
// memory.ts
|
|
200
502
|
var sessionmemory = class {
|
|
201
503
|
constructor(adapter) {
|
|
@@ -963,7 +1265,78 @@ var sessionmemory = class {
|
|
|
963
1265
|
for (const capture of await this.getcaptures()) runs.set(capture.id, capture.runid);
|
|
964
1266
|
return records.filter((item) => runs.get(item.beforeid) === runid);
|
|
965
1267
|
}
|
|
1268
|
+
/** Stores one media record of the 1.1.41 family with its bytes and step linkage, replacing the previous record of that id; the user configured media retention window expires the oldest bytes while the metadata and the recording index always survive. */
|
|
1269
|
+
async addmedia(record2) {
|
|
1270
|
+
const records = await this.getmediarecords();
|
|
1271
|
+
const retention = (await this.getsettings())?.mediaretention;
|
|
1272
|
+
const combined = [record2, ...records.filter((item) => item.id !== record2.id)];
|
|
1273
|
+
const stored = retention === void 0 ? combined : combined.map((item, index) => index < retention ? item : expiremediabytes(item));
|
|
1274
|
+
await this.adapter.set("media", stored);
|
|
1275
|
+
}
|
|
1276
|
+
/** Returns every stored media record, newest first. */
|
|
1277
|
+
async getmediarecords() {
|
|
1278
|
+
return await this.adapter.get("media") ?? [];
|
|
1279
|
+
}
|
|
1280
|
+
/** Returns the media records filtered by run and kind; an absent filter returns every record. */
|
|
1281
|
+
async listmedia(filter) {
|
|
1282
|
+
const records = await this.getmediarecords();
|
|
1283
|
+
return records.filter((item) => (filter.runid === void 0 || item.runid === filter.runid) && (filter.kind === void 0 || mediakindof(item) === filter.kind));
|
|
1284
|
+
}
|
|
1285
|
+
/** Returns one media record by its id. */
|
|
1286
|
+
async getmediarecord(id) {
|
|
1287
|
+
return (await this.getmediarecords()).find((item) => item.id === id);
|
|
1288
|
+
}
|
|
1289
|
+
/** Returns one recording with its file reference and frame index by its id. */
|
|
1290
|
+
async getrecording(id) {
|
|
1291
|
+
const found = await this.getmediarecord(id);
|
|
1292
|
+
return found !== void 0 && "startedat" in found ? found : void 0;
|
|
1293
|
+
}
|
|
1294
|
+
/** Removes one media record by its id; the audit trail keeps its outcome evidence. */
|
|
1295
|
+
async removemedia(id) {
|
|
1296
|
+
await this.adapter.set("media", (await this.getmediarecords()).filter((item) => item.id !== id));
|
|
1297
|
+
}
|
|
1298
|
+
/** Stores one observed image batch of a downloadimages step, replacing the previous batch of that id. */
|
|
1299
|
+
async addimagebatch(batch) {
|
|
1300
|
+
const records = await this.adapter.get("imagebatches") ?? [];
|
|
1301
|
+
await this.adapter.set("imagebatches", [batch, ...records.filter((item) => item.id !== batch.id)]);
|
|
1302
|
+
}
|
|
1303
|
+
/** Returns every observed image batch with its filter match counts, newest first. */
|
|
1304
|
+
async getimagebatches() {
|
|
1305
|
+
return await this.adapter.get("imagebatches") ?? [];
|
|
1306
|
+
}
|
|
1307
|
+
/** Stores one recording consent decision of an origin, replacing the previous record of that id. */
|
|
1308
|
+
async setrecordingconsent(record2) {
|
|
1309
|
+
const records = (await this.adapter.get("recordingconsents") ?? []).filter((item) => item.id !== record2.id);
|
|
1310
|
+
await this.adapter.set("recordingconsents", [record2, ...records]);
|
|
1311
|
+
}
|
|
1312
|
+
/** Returns every recording consent decision with its prompt and origin, newest first. */
|
|
1313
|
+
async getrecordingconsents() {
|
|
1314
|
+
return await this.adapter.get("recordingconsents") ?? [];
|
|
1315
|
+
}
|
|
966
1316
|
};
|
|
1317
|
+
function mediakindof(record2) {
|
|
1318
|
+
if ("pages" in record2) return "pdf";
|
|
1319
|
+
if ("startedat" in record2) return "recording";
|
|
1320
|
+
if ("timestamp" in record2) return "frame";
|
|
1321
|
+
if ("context" in record2) return "canvas";
|
|
1322
|
+
if ("tracks" in record2) return "stream";
|
|
1323
|
+
return "asset";
|
|
1324
|
+
}
|
|
1325
|
+
function expiremediabytes(record2) {
|
|
1326
|
+
if ("dataurl" in record2) {
|
|
1327
|
+
const source = record2;
|
|
1328
|
+
const copy = { ...source };
|
|
1329
|
+
delete copy.dataurl;
|
|
1330
|
+
return { ...copy, bytesexpired: true };
|
|
1331
|
+
}
|
|
1332
|
+
if ("startedat" in record2) {
|
|
1333
|
+
const source = record2;
|
|
1334
|
+
const copy = { ...source };
|
|
1335
|
+
delete copy.bytes;
|
|
1336
|
+
return { ...copy, bytesexpired: true };
|
|
1337
|
+
}
|
|
1338
|
+
return record2;
|
|
1339
|
+
}
|
|
967
1340
|
function expirecapturebytes(record2) {
|
|
968
1341
|
const { bytes, ...metadata } = record2;
|
|
969
1342
|
void bytes;
|
|
@@ -974,12 +1347,12 @@ function randomid() {
|
|
|
974
1347
|
}
|
|
975
1348
|
|
|
976
1349
|
// policy.ts
|
|
977
|
-
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"]);
|
|
1350
|
+
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"]);
|
|
978
1351
|
var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction"]);
|
|
979
|
-
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"]);
|
|
1352
|
+
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"]);
|
|
980
1353
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
981
1354
|
var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
|
|
982
|
-
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"]);
|
|
1355
|
+
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"]);
|
|
983
1356
|
var valueactions = /* @__PURE__ */ new Set(["presskey", "drag", "drop", "upload", "readattribute", "removeattribute", "waittext", "evaluate", "zoomset", "tabactivate", "tabclose", "tabreload", "windowclose", "windowresize", "tabcreate", "windowcreate", "downloadfile", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "chooseradio", "setslider", "setdate", "setcolor", "followlink", "setfragment", "handleauth", "navintent", "openclipboard", "checksafe", "reopentab", "spanav", "duplicatetab", "pintab", "mutetab", "movetab", "movetabwindow", "searchtabs", "badgetab", "attachmeta", "focuswindow", "maximizewindow", "minimizewindow", "restorewindow", "incognitowindow", "asksubmit", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword", "pausedownload", "resumedownload", "verifydownload", "writeclipboard", "quarantinedownload", "scanvirus"]);
|
|
984
1357
|
var tabscommandactions = /* @__PURE__ */ new Set(["querytabs", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "watchtab", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "savelayout", "restorelayout", "findclones", "searchtabs", "badgetab", "attachmeta", "listaudio", "reopenrun", "snapshotsession"]);
|
|
985
1358
|
var formactions = /* @__PURE__ */ new Set(["fillform", "filllabel", "fillplaceholder", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "submitform", "readerrors", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "handoffcaptcha", "fillcard", "fillcode", "consentpassword", "skiphoneypot", "detectlogin", "detecttemplate"]);
|
|
@@ -987,6 +1360,7 @@ var datasetactions = /* @__PURE__ */ new Set(["scrapetable", "exportcsv", "expor
|
|
|
987
1360
|
var exportactions = /* @__PURE__ */ new Set(["exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk"]);
|
|
988
1361
|
var filesactions = /* @__PURE__ */ new Set(["batchdownload", "pausedownload", "resumedownload", "verifydownload", "interceptmime", "exportnetlog", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "namecaptures", "cleanupartifacts"]);
|
|
989
1362
|
var captureactions = /* @__PURE__ */ new Set(["shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet"]);
|
|
1363
|
+
var mediaactions = /* @__PURE__ */ new Set(["capturepdf", "recordscreen", "captureaudio", "captureframe", "downloadimages", "shotcanvas", "probestream", "readmedia", "readassets", "timelapse", "convertimage", "makethumbs"]);
|
|
990
1364
|
var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
|
|
991
1365
|
var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
|
|
992
1366
|
var groupcolors = ["grey", "blue", "red", "yellow", "green", "pink", "purple", "cyan", "orange"];
|
|
@@ -1688,6 +2062,140 @@ function validatetabsgrammar(step, options) {
|
|
|
1688
2062
|
if (kind === "reopenrun" && !isnonempty(options.run)) return { allowed: false, reason: "A reviewed run id is required in options to reopen its tabs." };
|
|
1689
2063
|
return { allowed: true };
|
|
1690
2064
|
}
|
|
2065
|
+
function ismediakind(kind) {
|
|
2066
|
+
return mediaactions.has(kind);
|
|
2067
|
+
}
|
|
2068
|
+
function isrecordingkind(kind) {
|
|
2069
|
+
return kind === "recordscreen" || kind === "captureaudio";
|
|
2070
|
+
}
|
|
2071
|
+
function mediagate(session, tabid, origin, now) {
|
|
2072
|
+
if (!session || session.stoppedat) return { allowed: false, reason: "No active browser session exists for the media capture." };
|
|
2073
|
+
if (session.expiresat <= now) return { allowed: false, reason: "The browser session has expired and cannot capture media." };
|
|
2074
|
+
if (session.pausedat) return { allowed: false, reason: "The browser session is paused and cannot capture media." };
|
|
2075
|
+
if (session.tabid !== tabid) return { allowed: false, reason: `The media capture needs the active tab grant of session tab ${session.tabid} and refuses tab ${tabid}.` };
|
|
2076
|
+
if (!origingranted(session, origin)) return { allowed: false, reason: `The media capture of ${origin} needs the session origin grants first.` };
|
|
2077
|
+
return { allowed: true };
|
|
2078
|
+
}
|
|
2079
|
+
function recordingconsentgranted(step) {
|
|
2080
|
+
let options = {};
|
|
2081
|
+
try {
|
|
2082
|
+
options = parseoptions(step);
|
|
2083
|
+
} catch {
|
|
2084
|
+
options = {};
|
|
2085
|
+
}
|
|
2086
|
+
const consentref = options.consentref;
|
|
2087
|
+
if (typeof consentref !== "string" || !consentref.trim()) return { allowed: false, reason: "A recording of user activity requires a reviewed consent ref in options before it starts." };
|
|
2088
|
+
return { allowed: true };
|
|
2089
|
+
}
|
|
2090
|
+
function lapsebudgetallowed(interval, duration, wait) {
|
|
2091
|
+
if (!(interval > 0)) return { allowed: false, reason: "The reviewed lapse interval must be a positive number of milliseconds." };
|
|
2092
|
+
if (!(duration > 0)) return { allowed: false, reason: "The reviewed lapse duration must be a positive number of milliseconds." };
|
|
2093
|
+
if (wait !== void 0 && !(wait >= 0)) return { allowed: false, reason: "The reviewed wait budget must be zero or a positive number of milliseconds." };
|
|
2094
|
+
if (wait !== void 0 && duration > wait) return { allowed: false, reason: `The lapse duration of ${duration} milliseconds exceeds the reviewed wait budget of ${wait} milliseconds; review a wider budget or a shorter duration.` };
|
|
2095
|
+
return { allowed: true };
|
|
2096
|
+
}
|
|
2097
|
+
function validatemediagrammar(step, options) {
|
|
2098
|
+
const kind = step.kind;
|
|
2099
|
+
if (kind === "capturepdf") {
|
|
2100
|
+
const pdf = options.pdf;
|
|
2101
|
+
if (pdf !== void 0) {
|
|
2102
|
+
if (!pdf || typeof pdf !== "object" || Array.isArray(pdf)) return { allowed: false, reason: "The reviewed pdf options must be an object in options.pdf." };
|
|
2103
|
+
const pdfoptions = pdf;
|
|
2104
|
+
if (pdfoptions.paperwidth !== void 0 && (typeof pdfoptions.paperwidth !== "number" || !Number.isFinite(pdfoptions.paperwidth) || pdfoptions.paperwidth <= 0)) return { allowed: false, reason: "The reviewed pdf paper width must be a positive number of inches with no code cap." };
|
|
2105
|
+
if (pdfoptions.paperheight !== void 0 && (typeof pdfoptions.paperheight !== "number" || !Number.isFinite(pdfoptions.paperheight) || pdfoptions.paperheight <= 0)) return { allowed: false, reason: "The reviewed pdf paper height must be a positive number of inches with no code cap." };
|
|
2106
|
+
if (pdfoptions.margins !== void 0) {
|
|
2107
|
+
const margins = pdfoptions.margins;
|
|
2108
|
+
if (!margins || typeof margins !== "object" || Array.isArray(margins)) return { allowed: false, reason: "The reviewed pdf margins must be an object with top, right, bottom and left inches." };
|
|
2109
|
+
for (const side of ["top", "right", "bottom", "left"]) {
|
|
2110
|
+
const value = margins[side];
|
|
2111
|
+
if (value === void 0) continue;
|
|
2112
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return { allowed: false, reason: `The reviewed pdf ${side} margin must be zero or a positive number of inches; negative margins are refused.` };
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
if (pdfoptions.scale !== void 0 && (typeof pdfoptions.scale !== "number" || !Number.isFinite(pdfoptions.scale) || pdfoptions.scale <= 0)) return { allowed: false, reason: "The reviewed pdf scale must be a positive number with no code cap." };
|
|
2116
|
+
if (pdfoptions.landscape !== void 0 && typeof pdfoptions.landscape !== "boolean") return { allowed: false, reason: "The reviewed pdf landscape flag must be a boolean." };
|
|
2117
|
+
if (pdfoptions.paginate !== void 0 && typeof pdfoptions.paginate !== "boolean") return { allowed: false, reason: "The reviewed pdf paginate flag must be a boolean." };
|
|
2118
|
+
}
|
|
2119
|
+
if (options.breakpoints !== void 0 && (!Array.isArray(options.breakpoints) || options.breakpoints.length === 0 || !options.breakpoints.every((item) => isnonempty(item)))) return { allowed: false, reason: "The reviewed pdf break points must be a non-empty list of selectors when present." };
|
|
2120
|
+
if (options.exporttarget !== void 0 && options.exporttarget !== "memory" && options.exporttarget !== "download") return { allowed: false, reason: "The reviewed pdf export target must be memory or download; pdf documents do not route to the clipboard." };
|
|
2121
|
+
if (options.name !== void 0 && !isnonempty(options.name)) return { allowed: false, reason: "The reviewed pdf artifact name must be a non-empty string." };
|
|
2122
|
+
}
|
|
2123
|
+
if (kind === "recordscreen" || kind === "captureaudio") {
|
|
2124
|
+
const recording = options.recording;
|
|
2125
|
+
if (recording !== void 0) {
|
|
2126
|
+
if (!recording || typeof recording !== "object" || Array.isArray(recording)) return { allowed: false, reason: "The reviewed recording options must be an object in options.recording." };
|
|
2127
|
+
const recordoptions = recording;
|
|
2128
|
+
if (recordoptions.scope !== void 0 && recordoptions.scope !== "tab" && recordoptions.scope !== "run") return { allowed: false, reason: "The reviewed recording scope must be tab or run." };
|
|
2129
|
+
if (recordoptions.fps !== void 0 && (typeof recordoptions.fps !== "number" || !Number.isFinite(recordoptions.fps) || recordoptions.fps <= 0)) return { allowed: false, reason: "The reviewed recording fps must be a positive number with no code ceiling." };
|
|
2130
|
+
if (recordoptions.bitrate !== void 0 && (typeof recordoptions.bitrate !== "number" || !Number.isFinite(recordoptions.bitrate) || recordoptions.bitrate <= 0)) return { allowed: false, reason: "The reviewed recording bitrate must be a positive number with no code ceiling." };
|
|
2131
|
+
if (recordoptions.audio !== void 0 && typeof recordoptions.audio !== "boolean") return { allowed: false, reason: "The reviewed recording audio flag must be a boolean." };
|
|
2132
|
+
}
|
|
2133
|
+
if (options.duration !== void 0 && (typeof options.duration !== "number" || !Number.isFinite(options.duration) || options.duration <= 0)) return { allowed: false, reason: "The reviewed recording duration must be a positive number of milliseconds with no code ceiling." };
|
|
2134
|
+
const consent = recordingconsentgranted(step);
|
|
2135
|
+
if (!consent.allowed) return consent;
|
|
2136
|
+
}
|
|
2137
|
+
if (kind === "captureframe") {
|
|
2138
|
+
if (options.timestamp !== void 0 && (typeof options.timestamp !== "number" || !Number.isFinite(options.timestamp) || options.timestamp < 0)) return { allowed: false, reason: "The reviewed frame timestamp must be zero or a positive number of seconds." };
|
|
2139
|
+
if (options.poster !== void 0 && typeof options.poster !== "boolean") return { allowed: false, reason: "The reviewed poster flag must be a boolean." };
|
|
2140
|
+
const capturecheck = validatecaptureoptions(options.capture);
|
|
2141
|
+
if (!capturecheck.allowed) return capturecheck;
|
|
2142
|
+
}
|
|
2143
|
+
if (kind === "downloadimages") {
|
|
2144
|
+
const filter = options.imagefilter;
|
|
2145
|
+
if (!filter || typeof filter !== "object" || Array.isArray(filter)) return { allowed: false, reason: "A reviewed imagefilter is required in options before any image downloads." };
|
|
2146
|
+
const imagefilter = filter;
|
|
2147
|
+
if (imagefilter.selector !== void 0 && !isnonempty(imagefilter.selector)) return { allowed: false, reason: "The reviewed imagefilter selector must be a non-empty selector from the reviewed selector grammar." };
|
|
2148
|
+
if (imagefilter.minwidth !== void 0 && (typeof imagefilter.minwidth !== "number" || !Number.isFinite(imagefilter.minwidth) || imagefilter.minwidth < 0)) return { allowed: false, reason: "The reviewed imagefilter minimum width must be zero or a positive number of pixels." };
|
|
2149
|
+
if (imagefilter.minheight !== void 0 && (typeof imagefilter.minheight !== "number" || !Number.isFinite(imagefilter.minheight) || imagefilter.minheight < 0)) return { allowed: false, reason: "The reviewed imagefilter minimum height must be zero or a positive number of pixels." };
|
|
2150
|
+
if (imagefilter.formats !== void 0 && (!Array.isArray(imagefilter.formats) || imagefilter.formats.length === 0 || !imagefilter.formats.every((item) => isnonempty(item)))) return { allowed: false, reason: "The reviewed imagefilter format list must be a non-empty list of mime or extension patterns when present." };
|
|
2151
|
+
if (options.naming !== void 0) {
|
|
2152
|
+
const namingcheck = validatecapturenaming(options.naming);
|
|
2153
|
+
if (!namingcheck.allowed) return namingcheck;
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
if (kind === "shotcanvas") {
|
|
2157
|
+
const capturecheck = validatecaptureoptions(options.capture);
|
|
2158
|
+
if (!capturecheck.allowed) return capturecheck;
|
|
2159
|
+
}
|
|
2160
|
+
if (kind === "probestream" && options.selector !== void 0 && !isnonempty(options.selector)) return { allowed: false, reason: "The reviewed stream probe scope selector must be a non-empty string." };
|
|
2161
|
+
if (kind === "timelapse") {
|
|
2162
|
+
const lapse = options.lapse;
|
|
2163
|
+
if (!lapse || typeof lapse !== "object" || Array.isArray(lapse)) return { allowed: false, reason: "A reviewed lapse plan with interval, duration and format is required in options." };
|
|
2164
|
+
const plan = lapse;
|
|
2165
|
+
if (typeof plan.interval !== "number" || !Number.isFinite(plan.interval) || plan.interval <= 0) return { allowed: false, reason: "The reviewed lapse interval must be a positive number of milliseconds with no code ceiling." };
|
|
2166
|
+
if (typeof plan.duration !== "number" || !Number.isFinite(plan.duration) || plan.duration <= 0) return { allowed: false, reason: "The reviewed lapse duration must be a positive number of milliseconds with no code ceiling." };
|
|
2167
|
+
if (plan.format !== void 0 && plan.format !== "png" && plan.format !== "jpeg" && plan.format !== "webp") return { allowed: false, reason: "The reviewed lapse format must be png, jpeg or webp." };
|
|
2168
|
+
const budget = lapsebudgetallowed(plan.interval, plan.duration, typeof options.wait === "number" ? options.wait : void 0);
|
|
2169
|
+
if (!budget.allowed) return budget;
|
|
2170
|
+
const capturecheck = validatecaptureoptions(options.capture);
|
|
2171
|
+
if (!capturecheck.allowed) return capturecheck;
|
|
2172
|
+
}
|
|
2173
|
+
if (kind === "convertimage" || kind === "makethumbs") {
|
|
2174
|
+
const single = options.capture;
|
|
2175
|
+
const list = options.captures;
|
|
2176
|
+
const hasone = isnonempty(single);
|
|
2177
|
+
const haslist = Array.isArray(list) && list.length > 0 && list.every((item) => isnonempty(item));
|
|
2178
|
+
if (!hasone && !haslist) return { allowed: false, reason: "A reviewed capture id or a reviewed non-empty capture id list is required in options." };
|
|
2179
|
+
if (hasone && haslist) return { allowed: false, reason: "The reviewed step needs one capture id or a capture id list, not both." };
|
|
2180
|
+
}
|
|
2181
|
+
if (kind === "convertimage") {
|
|
2182
|
+
const convert = options.convert;
|
|
2183
|
+
if (!convert || typeof convert !== "object" || Array.isArray(convert)) return { allowed: false, reason: "A reviewed convert directive with a target format is required in options." };
|
|
2184
|
+
const directive = convert;
|
|
2185
|
+
if (directive.target !== "png" && directive.target !== "jpeg" && directive.target !== "webp") return { allowed: false, reason: "The reviewed conversion target must be png, jpeg or webp." };
|
|
2186
|
+
if (directive.source !== void 0 && directive.source !== "png" && directive.source !== "jpeg" && directive.source !== "webp") return { allowed: false, reason: "The reviewed conversion source must be png, jpeg or webp." };
|
|
2187
|
+
if (directive.quality !== void 0 && (typeof directive.quality !== "number" || !Number.isFinite(directive.quality) || directive.quality < 0 || directive.quality > 100)) return { allowed: false, reason: "The reviewed conversion quality must stay between zero and one hundred with no code cap inside that range." };
|
|
2188
|
+
}
|
|
2189
|
+
if (kind === "makethumbs") {
|
|
2190
|
+
const thumb = options.thumb;
|
|
2191
|
+
if (!thumb || typeof thumb !== "object" || Array.isArray(thumb)) return { allowed: false, reason: "A reviewed thumb directive with size, fit and suffix is required in options." };
|
|
2192
|
+
const directive = thumb;
|
|
2193
|
+
if (typeof directive.size !== "number" || !Number.isFinite(directive.size) || directive.size <= 0) return { allowed: false, reason: "The reviewed thumbnail size must be a positive number of pixels with no fixed set." };
|
|
2194
|
+
if (directive.fit !== "cover" && directive.fit !== "contain") return { allowed: false, reason: "The reviewed thumbnail fit must be cover or contain." };
|
|
2195
|
+
if (!isnonempty(directive.suffix)) return { allowed: false, reason: "The reviewed thumbnail naming suffix must be a non-empty string." };
|
|
2196
|
+
}
|
|
2197
|
+
return { allowed: true };
|
|
2198
|
+
}
|
|
1691
2199
|
function validatestep(step, origin) {
|
|
1692
2200
|
if (!allowedactions.has(step.kind)) return { allowed: false, reason: "Unsupported action kind." };
|
|
1693
2201
|
if (!step.summary.trim()) return { allowed: false, reason: "A human-readable action summary is required." };
|
|
@@ -1909,6 +2417,10 @@ function validatestep(step, origin) {
|
|
|
1909
2417
|
const capturecheck = validatecapturegrammar(step, options);
|
|
1910
2418
|
if (!capturecheck.allowed) return capturecheck;
|
|
1911
2419
|
}
|
|
2420
|
+
if (ismediakind(step.kind)) {
|
|
2421
|
+
const mediacheck = validatemediagrammar(step, options);
|
|
2422
|
+
if (!mediacheck.allowed) return mediacheck;
|
|
2423
|
+
}
|
|
1912
2424
|
if (step.kind === "tabcreate") {
|
|
1913
2425
|
if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
|
|
1914
2426
|
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." };
|
|
@@ -1980,6 +2492,14 @@ function canexecute(input) {
|
|
|
1980
2492
|
const target = captureoptions.capture?.exporttarget;
|
|
1981
2493
|
if (target !== void 0 && target !== "memory" && target !== "download" && target !== "clipboard") return { allowed: false, reason: "The capture export target must be memory, download or clipboard." };
|
|
1982
2494
|
}
|
|
2495
|
+
if (ismediakind(input.step.kind)) {
|
|
2496
|
+
const mediagatecheck = mediagate(input.session, input.tabid, input.origin, now);
|
|
2497
|
+
if (!mediagatecheck.allowed) return mediagatecheck;
|
|
2498
|
+
}
|
|
2499
|
+
if (isrecordingkind(input.step.kind)) {
|
|
2500
|
+
const recordinggate = recordingconsentgranted(input.step);
|
|
2501
|
+
if (!recordinggate.allowed) return recordinggate;
|
|
2502
|
+
}
|
|
1983
2503
|
if (input.step.kind === "openlink" || input.step.kind === "openprivate" || input.step.kind === "batchopen" || input.step.kind === "prefetch" || input.step.kind === "deeplink" || input.step.kind === "reopentab") {
|
|
1984
2504
|
let options = {};
|
|
1985
2505
|
try {
|
|
@@ -2001,7 +2521,7 @@ function canexecute(input) {
|
|
|
2001
2521
|
}
|
|
2002
2522
|
|
|
2003
2523
|
// version.ts
|
|
2004
|
-
var packageversion = "1.1.
|
|
2524
|
+
var packageversion = "1.1.41";
|
|
2005
2525
|
|
|
2006
2526
|
// types.ts
|
|
2007
2527
|
var protocolversion = packageversion;
|
|
@@ -2065,7 +2585,7 @@ function requestbody(input) {
|
|
|
2065
2585
|
return JSON.stringify({ version: protocolversion, objective: input.objective, session: input.session, observation: input.observation, capabilities: input.capabilities });
|
|
2066
2586
|
}
|
|
2067
2587
|
function outcomeresponse(input) {
|
|
2068
|
-
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 } : {} });
|
|
2588
|
+
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 } : {} });
|
|
2069
2589
|
}
|
|
2070
2590
|
function mapresponse(input) {
|
|
2071
2591
|
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, map: input.map });
|
|
@@ -2145,10 +2665,15 @@ function quarantinereport(input) {
|
|
|
2145
2665
|
function capturereport(input) {
|
|
2146
2666
|
return { version: protocolversion, records: input.records, pairs: input.pairs };
|
|
2147
2667
|
}
|
|
2668
|
+
function mediareport(input) {
|
|
2669
|
+
return { version: protocolversion, records: input.records, images: input.images };
|
|
2670
|
+
}
|
|
2148
2671
|
export {
|
|
2149
2672
|
annotationplanof,
|
|
2673
|
+
assetentries,
|
|
2150
2674
|
blendrows,
|
|
2151
2675
|
buildname,
|
|
2676
|
+
buildpdf,
|
|
2152
2677
|
buildsheet,
|
|
2153
2678
|
buildstitchplan,
|
|
2154
2679
|
canexecute,
|
|
@@ -2162,26 +2687,39 @@ export {
|
|
|
2162
2687
|
capturestitched,
|
|
2163
2688
|
capturetargets,
|
|
2164
2689
|
capturevisible,
|
|
2690
|
+
convertdirectiveof,
|
|
2165
2691
|
croprect,
|
|
2166
2692
|
crossesviewport,
|
|
2167
2693
|
datasetresponse,
|
|
2694
|
+
dedupeimages,
|
|
2168
2695
|
actionrisk as deriveactionrisk,
|
|
2169
2696
|
diffresponse,
|
|
2170
2697
|
downloadreport,
|
|
2171
2698
|
errorreportresponse,
|
|
2172
2699
|
eventresponse,
|
|
2173
2700
|
extractionreport,
|
|
2701
|
+
finishrecording,
|
|
2174
2702
|
fixedheadermatch,
|
|
2175
2703
|
formreportresponse,
|
|
2704
|
+
frameinterval,
|
|
2176
2705
|
generatedvalueallowed,
|
|
2177
2706
|
heldkeysreport,
|
|
2178
2707
|
hostpattern,
|
|
2708
|
+
imagefilterof,
|
|
2709
|
+
imagematches,
|
|
2710
|
+
imagenames,
|
|
2179
2711
|
isformkind,
|
|
2180
2712
|
iswatchkind,
|
|
2713
|
+
lapseframes,
|
|
2714
|
+
lapseplanof,
|
|
2181
2715
|
layoutreport,
|
|
2182
2716
|
mapresponse,
|
|
2717
|
+
mediaentries,
|
|
2718
|
+
mediakinds,
|
|
2719
|
+
mediareport,
|
|
2183
2720
|
navstateresponse,
|
|
2184
2721
|
netlogreport,
|
|
2722
|
+
newrecording,
|
|
2185
2723
|
normalizeendpoint,
|
|
2186
2724
|
observationmodeof,
|
|
2187
2725
|
observationresponse,
|
|
@@ -2189,11 +2727,16 @@ export {
|
|
|
2189
2727
|
pairstates,
|
|
2190
2728
|
parseproposal,
|
|
2191
2729
|
passwordconsentgranted,
|
|
2730
|
+
pdfoptionsof,
|
|
2731
|
+
pdfpagesize,
|
|
2732
|
+
pdfsegments,
|
|
2733
|
+
pdftextlayout,
|
|
2192
2734
|
profilegrantgranted,
|
|
2193
2735
|
protocolversion,
|
|
2194
2736
|
provenancereport,
|
|
2195
2737
|
quarantinereport,
|
|
2196
2738
|
randomid,
|
|
2739
|
+
recordingoptionsof,
|
|
2197
2740
|
regionsteps,
|
|
2198
2741
|
requestbody,
|
|
2199
2742
|
resolutionverdict,
|
|
@@ -2203,8 +2746,11 @@ export {
|
|
|
2203
2746
|
selectorresponse,
|
|
2204
2747
|
sessionmemory,
|
|
2205
2748
|
signalsreport,
|
|
2749
|
+
streamsummaries,
|
|
2206
2750
|
submitreviewgranted,
|
|
2207
2751
|
tabreportresponse,
|
|
2752
|
+
thumbdirectiveof,
|
|
2753
|
+
thumbgeometry,
|
|
2208
2754
|
trailreport,
|
|
2209
2755
|
transformgrammar,
|
|
2210
2756
|
validatefieldmatch,
|