obsidian-integration-testing 10.1.0 → 10.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/cjs/fit-screenshot.cjs +103 -0
- package/dist/lib/cjs/fit-screenshot.d.cts +117 -0
- package/dist/lib/cjs/index.cjs +15 -1
- package/dist/lib/cjs/index.d.cts +4 -0
- package/dist/lib/cjs/label-screenshot.cjs +81 -0
- package/dist/lib/cjs/label-screenshot.d.cts +98 -0
- package/dist/lib/cjs/library.cjs +1 -1
- package/dist/lib/cjs/sharp-loader.cjs +50 -0
- package/dist/lib/cjs/sharp-loader.d.cts +56 -0
- package/dist/lib/esm/fit-screenshot.d.mts +117 -0
- package/dist/lib/esm/fit-screenshot.mjs +78 -0
- package/dist/lib/esm/index.d.mts +4 -0
- package/dist/lib/esm/index.mjs +17 -1
- package/dist/lib/esm/label-screenshot.d.mts +98 -0
- package/dist/lib/esm/label-screenshot.mjs +54 -0
- package/dist/lib/esm/library.mjs +1 -1
- package/dist/lib/esm/sharp-loader.d.mts +56 -0
- package/dist/lib/esm/sharp-loader.mjs +16 -0
- package/dist/obsidian-integration-testing-10.3.0.tgz +0 -0
- package/package.json +8 -1
- package/dist/obsidian-integration-testing-10.1.0.tgz +0 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var fit_screenshot_exports = {};
|
|
20
|
+
__export(fit_screenshot_exports, {
|
|
21
|
+
computeFitToCanvas: () => computeFitToCanvas,
|
|
22
|
+
fitScreenshotToCanvas: () => fitScreenshotToCanvas
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(fit_screenshot_exports);
|
|
25
|
+
var import_sharp_loader = require("./sharp-loader.cjs");
|
|
26
|
+
const DEFAULT_BLUR_SIGMA = 24;
|
|
27
|
+
const MARGIN_SIDES = 2;
|
|
28
|
+
function computeFitToCanvas(params) {
|
|
29
|
+
const {
|
|
30
|
+
canvasHeightInPixels,
|
|
31
|
+
canvasWidthInPixels,
|
|
32
|
+
sourceHeightInPixels,
|
|
33
|
+
sourceWidthInPixels
|
|
34
|
+
} = params;
|
|
35
|
+
const namedDimensions = [
|
|
36
|
+
["canvasHeightInPixels", canvasHeightInPixels],
|
|
37
|
+
["canvasWidthInPixels", canvasWidthInPixels],
|
|
38
|
+
["sourceHeightInPixels", sourceHeightInPixels],
|
|
39
|
+
["sourceWidthInPixels", sourceWidthInPixels]
|
|
40
|
+
];
|
|
41
|
+
for (const [name, value] of namedDimensions) {
|
|
42
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
43
|
+
throw new Error(`computeFitToCanvas: ${name} must be a positive number, got ${String(value)}.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const scaledHeightInPixels = canvasHeightInPixels;
|
|
47
|
+
const exactScaledWidth = sourceWidthInPixels * (canvasHeightInPixels / sourceHeightInPixels);
|
|
48
|
+
const scaledWidthInPixels = roundToMatchingParity(exactScaledWidth, canvasWidthInPixels);
|
|
49
|
+
if (scaledWidthInPixels > canvasWidthInPixels) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`computeFitToCanvas: the source is wider than the canvas once scaled to its height (${String(scaledWidthInPixels)} > ${String(canvasWidthInPixels)}); this fits by height and cannot letterbox.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
const marginInPixels = (canvasWidthInPixels - scaledWidthInPixels) / MARGIN_SIDES;
|
|
55
|
+
return {
|
|
56
|
+
marginInPixels,
|
|
57
|
+
offsetXInPixels: marginInPixels,
|
|
58
|
+
offsetYInPixels: 0,
|
|
59
|
+
scaledHeightInPixels,
|
|
60
|
+
scaledWidthInPixels
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async function fitScreenshotToCanvas(bytes, options) {
|
|
64
|
+
const {
|
|
65
|
+
blurSigma = DEFAULT_BLUR_SIGMA,
|
|
66
|
+
canvasHeightInPixels,
|
|
67
|
+
canvasWidthInPixels
|
|
68
|
+
} = options;
|
|
69
|
+
const sharp = await (0, import_sharp_loader.importSharp)("fitScreenshotToCanvas");
|
|
70
|
+
const metadata = await sharp(bytes).metadata();
|
|
71
|
+
const sourceWidthInPixels = metadata.width;
|
|
72
|
+
const sourceHeightInPixels = metadata.height;
|
|
73
|
+
if (sourceWidthInPixels === void 0 || sourceHeightInPixels === void 0) {
|
|
74
|
+
throw new Error("fitScreenshotToCanvas: could not read the source image dimensions.");
|
|
75
|
+
}
|
|
76
|
+
const geometry = computeFitToCanvas({
|
|
77
|
+
canvasHeightInPixels,
|
|
78
|
+
canvasWidthInPixels,
|
|
79
|
+
sourceHeightInPixels,
|
|
80
|
+
sourceWidthInPixels
|
|
81
|
+
});
|
|
82
|
+
const background = await sharp(bytes).resize(canvasWidthInPixels, canvasHeightInPixels, { fit: "cover" }).blur(blurSigma).toBuffer();
|
|
83
|
+
const foreground = await sharp(bytes).resize(geometry.scaledWidthInPixels, geometry.scaledHeightInPixels, { fit: "fill" }).toBuffer();
|
|
84
|
+
const composed = await sharp(background).composite([{
|
|
85
|
+
input: foreground,
|
|
86
|
+
left: geometry.offsetXInPixels,
|
|
87
|
+
top: geometry.offsetYInPixels
|
|
88
|
+
}]).png().toBuffer();
|
|
89
|
+
return new Uint8Array(composed);
|
|
90
|
+
}
|
|
91
|
+
function roundToMatchingParity(value, target) {
|
|
92
|
+
const rounded = Math.round(value);
|
|
93
|
+
if ((target - rounded) % MARGIN_SIDES === 0) {
|
|
94
|
+
return rounded;
|
|
95
|
+
}
|
|
96
|
+
return value >= rounded ? rounded + 1 : rounded - 1;
|
|
97
|
+
}
|
|
98
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
99
|
+
0 && (module.exports = {
|
|
100
|
+
computeFitToCanvas,
|
|
101
|
+
fitScreenshotToCanvas
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2ZpdC1zY3JlZW5zaG90LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRml0cyBhIHNjcmVlbnNob3Qgb250byBhIGNhbnZhcyBvZiBhIGRpZmZlcmVudCBhc3BlY3QgcmF0aW8gd2l0aG91dCBjcm9wcGluZ1xuICogaXQgb3IgZGlzdG9ydGluZyBpdCwgZmlsbGluZyB0aGUgbGVmdG92ZXIgbWFyZ2lucyB3aXRoIGEgYmx1cnJlZCwgZW5sYXJnZWRcbiAqIGNvcHkgb2YgdGhlIHNhbWUgaW1hZ2UgKHRoZSBcInBpbGxhcmJveFwiIHRyZWF0bWVudCB1c2VkIGJ5IHN0b3JlIGxpc3RpbmdzKS5cbiAqXG4gKiBUaGUgbW90aXZhdGluZyBjYXNlIGlzIGEgbW9iaWxlIHN0b3JlIHNjcmVlbnNob3QuIFRoZSBBbmRyb2lkIGVtdWxhdG9yJ3NcbiAqIGZyYW1lYnVmZmVyIGlzIHdoYXRldmVyIHRoZSBBVkQncyBzY3JlZW4gaXMgXHUyMDE0IGEgUGl4ZWwgMTAgUHJvIFhMIGlzIDEzNDR4Mjk5MixcbiAqIHJvdWdobHkgOToyMCBcdTIwMTQgd2hpbGUgdGhlIGNvbW11bml0eSBzdG9yZSBhc2tzIGZvciA5MDB4MTYwMCAoOToxNikuIENyb3BwaW5nXG4gKiB0byA5OjE2IHRocm93cyBhd2F5IGEgZmlmdGggb2YgdGhlIGZyYW1lLCBhbmQgc3RyZXRjaGluZyBkaXN0b3J0cyB0aGUgVUksIHNvXG4gKiB0aGUgaW1hZ2UgaXMgc2NhbGVkIHRvIGZpdCB0aGUgSEVJR0hUIGFuZCB0aGUgdHdvIHNpZGUgbWFyZ2lucyBhcmUgZmlsbGVkLlxuICpcbiAqIFRoZSBnZW9tZXRyeSBpcyBhIHB1cmUgZnVuY3Rpb24gc28gaXQgY2FuIGJlIHVuaXQtdGVzdGVkOyB0aGUgcGl4ZWwgd29yayBuZWVkc1xuICogYHNoYXJwYCwgd2hpY2ggaXMgYW4gT1BUSU9OQUwgcGVlciBkZXBlbmRlbmN5IFx1MjAxNCBkZWNsYXJlZCByYXRoZXIgdGhhbiBidW5kbGVkXG4gKiBiZWNhdXNlIG9ubHkgc2NyZWVuc2hvdCBjYXB0dXJlIG5lZWRzIGl0LCBhbmQgaXQgc2hpcHMgcGxhdGZvcm0tc3BlY2lmaWNcbiAqIG5hdGl2ZSBiaW5hcmllcyB0aGF0IGV2ZXJ5IG90aGVyIGNvbnN1bWVyIHdvdWxkIHBheSBmb3IuXG4gKi9cblxuaW1wb3J0IHsgaW1wb3J0U2hhcnAgfSBmcm9tICcuL3NoYXJwLWxvYWRlci5janMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjb21wdXRlRml0VG9DYW52YXN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVGaXRUb0NhbnZhc1BhcmFtcyB7XG4gIC8qKlxuICAgKiBIZWlnaHQgb2YgdGhlIHRhcmdldCBjYW52YXMsIGluIHBpeGVscy5cbiAgICovXG4gIHJlYWRvbmx5IGNhbnZhc0hlaWdodEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdpZHRoIG9mIHRoZSB0YXJnZXQgY2FudmFzLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBjYW52YXNXaWR0aEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEhlaWdodCBvZiB0aGUgc291cmNlIGltYWdlLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VIZWlnaHRJblBpeGVsczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaWR0aCBvZiB0aGUgc291cmNlIGltYWdlLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VXaWR0aEluUGl4ZWxzOiBudW1iZXI7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIGZpdFNjcmVlbnNob3RUb0NhbnZhc30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRml0U2NyZWVuc2hvdFRvQ2FudmFzT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBHYXVzc2lhbiBibHVyIHN0cmVuZ3RoIGFwcGxpZWQgdG8gdGhlIG1hcmdpbiBmaWxsLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMjRgXG4gICAqL1xuICByZWFkb25seSBibHVyU2lnbWE/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEhlaWdodCBvZiB0aGUgdGFyZ2V0IGNhbnZhcywgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgY2FudmFzSGVpZ2h0SW5QaXhlbHM6IG51bWJlcjtcblxuICAvKipcbiAgICogV2lkdGggb2YgdGhlIHRhcmdldCBjYW52YXMsIGluIHBpeGVscy5cbiAgICovXG4gIHJlYWRvbmx5IGNhbnZhc1dpZHRoSW5QaXhlbHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBXaGVyZSB0aGUgc2NhbGVkIHNvdXJjZSBpbWFnZSBzaXRzIG9uIHRoZSBjYW52YXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRml0VG9DYW52YXNHZW9tZXRyeSB7XG4gIC8qKlxuICAgKiBXaWR0aCBvZiBlYWNoIHNpZGUgbWFyZ2luLCBpbiBwaXhlbHMuIEJvdGggc2lkZXMgYXJlIGVxdWFsIGJ5IGNvbnN0cnVjdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IG1hcmdpbkluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIExlZnQgb2Zmc2V0IG9mIHRoZSBzY2FsZWQgaW1hZ2Ugb24gdGhlIGNhbnZhcywgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgb2Zmc2V0WEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRvcCBvZmZzZXQgb2YgdGhlIHNjYWxlZCBpbWFnZSBvbiB0aGUgY2FudmFzLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBvZmZzZXRZSW5QaXhlbHM6IG51bWJlcjtcblxuICAvKipcbiAgICogSGVpZ2h0IHRoZSBzb3VyY2UgaXMgc2NhbGVkIHRvLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBzY2FsZWRIZWlnaHRJblBpeGVsczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaWR0aCB0aGUgc291cmNlIGlzIHNjYWxlZCB0bywgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgc2NhbGVkV2lkdGhJblBpeGVsczogbnVtYmVyO1xufVxuXG4vKipcbiAqIERlZmF1bHQgR2F1c3NpYW4gYmx1ciBzdHJlbmd0aCBmb3IgdGhlIG1hcmdpbiBmaWxsOiBzb2Z0IGVub3VnaCB0aGF0IG5vXG4gKiBkZXRhaWwgcmVhZHMgYXMgY29udGVudCwgZ2VudGxlIGVub3VnaCB0byBrZWVwIHRoZSBmcmFtZSdzIGNvbG9ycy5cbiAqL1xuY29uc3QgREVGQVVMVF9CTFVSX1NJR01BID0gMjQ7XG5cbi8qKlxuICogVGhlIG51bWJlciBvZiBzaWRlIG1hcmdpbnMgdGhlIGxlZnRvdmVyIHdpZHRoIGlzIHNwbGl0IGJldHdlZW4uXG4gKi9cbmNvbnN0IE1BUkdJTl9TSURFUyA9IDI7XG5cbi8qKlxuICogQ29tcHV0ZXMgaG93IGEgc291cmNlIGltYWdlIGlzIHNjYWxlZCBhbmQgcGxhY2VkIHRvIGZpbGwgYSBjYW52YXMncyBoZWlnaHQsXG4gKiB3aXRoIGVxdWFsIG1hcmdpbnMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0LlxuICpcbiAqIFRoZSBzY2FsZWQgd2lkdGggaXMgcm91bmRlZCB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyIHRoYXQgbGVhdmVzIGFuIEVWRU5cbiAqIHJlbWFpbmRlciwgc28gdGhlIHR3byBtYXJnaW5zIGFyZSBleGFjdGx5IGVxdWFsIFx1MjAxNCBhbiBhc3ltbWV0cmljIHBpbGxhcmJveCBpc1xuICogdmlzaWJsZSBhdCBhIGdsYW5jZSBhbmQgbG9va3MgbGlrZSBhIG1pc3Rha2UuIFdoZXJlIGJvdGggbmVpZ2hib3JzIHF1YWxpZnksXG4gKiB0aGUgb25lIGNsb3NlciB0byB0aGUgdHJ1ZSBzY2FsZWQgd2lkdGggd2lucywgc28gdGhlIGFzcGVjdCBlcnJvciBzdGF5cyBiZWxvd1xuICogb25lIHBhcnQgaW4gYSB0aG91c2FuZC5cbiAqXG4gKiBXb3JrZWQgZXhhbXBsZSwgdGhlIG1vYmlsZSBzdG9yZSBjYXNlOiBhIDEzNDR4Mjk5MiBmcmFtZSBvbnRvIGEgOTAweDE2MDBcbiAqIGNhbnZhcyBzY2FsZXMgYnkgYDE2MDAvMjk5MmAgdG8gNzE4LjcyIHdpZGUuIDcxOSB3b3VsZCBsZWF2ZSBhIDE4MXB4XG4gKiByZW1haW5kZXIsIHdoaWNoIGNhbm5vdCBzcGxpdCBldmVubHksIHNvIDcxOCBpcyBjaG9zZW4gKG1hcmdpbiA5MSkgb3ZlciA3MjBcbiAqIChtYXJnaW4gOTApIGJlY2F1c2UgNzE4IGlzIG5lYXJlciA3MTguNzIuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzb3VyY2UgYW5kIGNhbnZhcyBkaW1lbnNpb25zLlxuICogQHJldHVybnMgVGhlIHNjYWxlZCBzaXplLCB0aGUgb2Zmc2V0cywgYW5kIHRoZSBzaWRlIG1hcmdpbi5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgYW55IGRpbWVuc2lvbiBpcyBub3QgYSBwb3NpdGl2ZSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlRml0VG9DYW52YXMocGFyYW1zOiBDb21wdXRlRml0VG9DYW52YXNQYXJhbXMpOiBGaXRUb0NhbnZhc0dlb21ldHJ5IHtcbiAgY29uc3Qge1xuICAgIGNhbnZhc0hlaWdodEluUGl4ZWxzLFxuICAgIGNhbnZhc1dpZHRoSW5QaXhlbHMsXG4gICAgc291cmNlSGVpZ2h0SW5QaXhlbHMsXG4gICAgc291cmNlV2lkdGhJblBpeGVsc1xuICB9ID0gcGFyYW1zO1xuXG4gIGNvbnN0IG5hbWVkRGltZW5zaW9uczogW3N0cmluZywgbnVtYmVyXVtdID0gW1xuICAgIFsnY2FudmFzSGVpZ2h0SW5QaXhlbHMnLCBjYW52YXNIZWlnaHRJblBpeGVsc10sXG4gICAgWydjYW52YXNXaWR0aEluUGl4ZWxzJywgY2FudmFzV2lkdGhJblBpeGVsc10sXG4gICAgWydzb3VyY2VIZWlnaHRJblBpeGVscycsIHNvdXJjZUhlaWdodEluUGl4ZWxzXSxcbiAgICBbJ3NvdXJjZVdpZHRoSW5QaXhlbHMnLCBzb3VyY2VXaWR0aEluUGl4ZWxzXVxuICBdO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBuYW1lZERpbWVuc2lvbnMpIHtcbiAgICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgfHwgdmFsdWUgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb21wdXRlRml0VG9DYW52YXM6ICR7bmFtZX0gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlciwgZ290ICR7U3RyaW5nKHZhbHVlKX0uYCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2NhbGVkSGVpZ2h0SW5QaXhlbHMgPSBjYW52YXNIZWlnaHRJblBpeGVscztcbiAgY29uc3QgZXhhY3RTY2FsZWRXaWR0aCA9IHNvdXJjZVdpZHRoSW5QaXhlbHMgKiAoY2FudmFzSGVpZ2h0SW5QaXhlbHMgLyBzb3VyY2VIZWlnaHRJblBpeGVscyk7XG4gIGNvbnN0IHNjYWxlZFdpZHRoSW5QaXhlbHMgPSByb3VuZFRvTWF0Y2hpbmdQYXJpdHkoZXhhY3RTY2FsZWRXaWR0aCwgY2FudmFzV2lkdGhJblBpeGVscyk7XG5cbiAgaWYgKHNjYWxlZFdpZHRoSW5QaXhlbHMgPiBjYW52YXNXaWR0aEluUGl4ZWxzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ2NvbXB1dGVGaXRUb0NhbnZhczogdGhlIHNvdXJjZSBpcyB3aWRlciB0aGFuIHRoZSBjYW52YXMgb25jZSBzY2FsZWQgdG8gaXRzIGhlaWdodCAnXG4gICAgICAgICsgYCgke1N0cmluZyhzY2FsZWRXaWR0aEluUGl4ZWxzKX0gPiAke1N0cmluZyhjYW52YXNXaWR0aEluUGl4ZWxzKX0pOyB0aGlzIGZpdHMgYnkgaGVpZ2h0IGFuZCBjYW5ub3QgbGV0dGVyYm94LmBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgbWFyZ2luSW5QaXhlbHMgPSAoY2FudmFzV2lkdGhJblBpeGVscyAtIHNjYWxlZFdpZHRoSW5QaXhlbHMpIC8gTUFSR0lOX1NJREVTO1xuXG4gIHJldHVybiB7XG4gICAgbWFyZ2luSW5QaXhlbHMsXG4gICAgb2Zmc2V0WEluUGl4ZWxzOiBtYXJnaW5JblBpeGVscyxcbiAgICBvZmZzZXRZSW5QaXhlbHM6IDAsXG4gICAgc2NhbGVkSGVpZ2h0SW5QaXhlbHMsXG4gICAgc2NhbGVkV2lkdGhJblBpeGVsc1xuICB9O1xufVxuXG4vKipcbiAqIFNjYWxlcyBhIHNjcmVlbnNob3QgdG8gZmlsbCBhIGNhbnZhcydzIGhlaWdodCBhbmQgZmlsbHMgdGhlIHNpZGUgbWFyZ2lucyB3aXRoXG4gKiBhIGJsdXJyZWQsIGVubGFyZ2VkIGNvcHkgb2YgdGhlIHNhbWUgaW1hZ2UuXG4gKlxuICogTm90aGluZyBpcyBjcm9wcGVkIGFuZCBub3RoaW5nIGlzIHN0cmV0Y2hlZDogdGhlIHZpc2libGUgc2NyZWVuc2hvdCBrZWVwcyBpdHNcbiAqIGFzcGVjdCByYXRpbyB0byB3aXRoaW4gYSByb3VuZGluZyBwaXhlbCwgYW5kIHRoZSBtYXJnaW5zIGFyZSBtYWRlIG9mIHRoZVxuICogaW1hZ2UgaXRzZWxmIHJhdGhlciB0aGFuIGEgZmxhdCBjb2xvciwgc28gdGhlIHJlc3VsdCByZWFkcyBhcyBvbmUgZnJhbWUuXG4gKlxuICogQHBhcmFtIGJ5dGVzIC0gVGhlIHNvdXJjZSBQTkcuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSB0YXJnZXQgY2FudmFzIHNpemUgYW5kIGJsdXIgc3RyZW5ndGguXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjb21wb3NlZCBQTkcsIGV4YWN0bHkgdGhlIGNhbnZhcyBzaXplLlxuICogQHRocm93cyBFcnJvciBpZiBgc2hhcnBgIGlzIG5vdCBpbnN0YWxsZWQsIG9yIHRoZSBzb3VyY2UgZGltZW5zaW9ucyBjYW5ub3QgYmUgcmVhZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpdFNjcmVlbnNob3RUb0NhbnZhcyhieXRlczogVWludDhBcnJheSwgb3B0aW9uczogRml0U2NyZWVuc2hvdFRvQ2FudmFzT3B0aW9ucyk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICBjb25zdCB7XG4gICAgYmx1clNpZ21hID0gREVGQVVMVF9CTFVSX1NJR01BLFxuICAgIGNhbnZhc0hlaWdodEluUGl4ZWxzLFxuICAgIGNhbnZhc1dpZHRoSW5QaXhlbHNcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3Qgc2hhcnAgPSBhd2FpdCBpbXBvcnRTaGFycCgnZml0U2NyZWVuc2hvdFRvQ2FudmFzJyk7XG4gIGNvbnN0IG1ldGFkYXRhID0gYXdhaXQgc2hhcnAoYnl0ZXMpLm1ldGFkYXRhKCk7XG4gIGNvbnN0IHNvdXJjZVdpZHRoSW5QaXhlbHMgPSBtZXRhZGF0YS53aWR0aDtcbiAgY29uc3Qgc291cmNlSGVpZ2h0SW5QaXhlbHMgPSBtZXRhZGF0YS5oZWlnaHQ7XG5cbiAgLyogdjggaWdub3JlIG5leHQgMyAtLSBEZWZlbnNpdmU6IGBzaGFycGAgcmVqZWN0cyBhIG5vbi1pbWFnZSBiZWZvcmUgaXQgY2FuIHJlcG9ydCBtZXRhZGF0YSB3aXRob3V0IGRpbWVuc2lvbnMsIHNvIHRoaXMgYnJhbmNoIGlzIHVucmVhY2hhYmxlIGZyb20gYSB0ZXN0LiAqL1xuICBpZiAoc291cmNlV2lkdGhJblBpeGVscyA9PT0gdW5kZWZpbmVkIHx8IHNvdXJjZUhlaWdodEluUGl4ZWxzID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZpdFNjcmVlbnNob3RUb0NhbnZhczogY291bGQgbm90IHJlYWQgdGhlIHNvdXJjZSBpbWFnZSBkaW1lbnNpb25zLicpO1xuICB9XG5cbiAgY29uc3QgZ2VvbWV0cnkgPSBjb21wdXRlRml0VG9DYW52YXMoe1xuICAgIGNhbnZhc0hlaWdodEluUGl4ZWxzLFxuICAgIGNhbnZhc1dpZHRoSW5QaXhlbHMsXG4gICAgc291cmNlSGVpZ2h0SW5QaXhlbHMsXG4gICAgc291cmNlV2lkdGhJblBpeGVsc1xuICB9KTtcblxuICAvLyBUaGUgYmFja2dyb3VuZCBpcyB0aGUgc2FtZSBmcmFtZSBibG93biB1cCB0byBDT1ZFUiB0aGUgY2FudmFzIGFuZCBibHVycmVkLFxuICAvLyBTbyB0aGUgbWFyZ2lucyBjYXJyeSB0aGUgc2NyZWVuc2hvdCdzIG93biBjb2xvcnMgaW5zdGVhZCBvZiBhIGZsYXQgYmFyLlxuICBjb25zdCBiYWNrZ3JvdW5kID0gYXdhaXQgc2hhcnAoYnl0ZXMpXG4gICAgLnJlc2l6ZShjYW52YXNXaWR0aEluUGl4ZWxzLCBjYW52YXNIZWlnaHRJblBpeGVscywgeyBmaXQ6ICdjb3ZlcicgfSlcbiAgICAuYmx1cihibHVyU2lnbWEpXG4gICAgLnRvQnVmZmVyKCk7XG5cbiAgY29uc3QgZm9yZWdyb3VuZCA9IGF3YWl0IHNoYXJwKGJ5dGVzKVxuICAgIC5yZXNpemUoZ2VvbWV0cnkuc2NhbGVkV2lkdGhJblBpeGVscywgZ2VvbWV0cnkuc2NhbGVkSGVpZ2h0SW5QaXhlbHMsIHsgZml0OiAnZmlsbCcgfSlcbiAgICAudG9CdWZmZXIoKTtcblxuICBjb25zdCBjb21wb3NlZCA9IGF3YWl0IHNoYXJwKGJhY2tncm91bmQpXG4gICAgLmNvbXBvc2l0ZShbe1xuICAgICAgaW5wdXQ6IGZvcmVncm91bmQsXG4gICAgICBsZWZ0OiBnZW9tZXRyeS5vZmZzZXRYSW5QaXhlbHMsXG4gICAgICB0b3A6IGdlb21ldHJ5Lm9mZnNldFlJblBpeGVsc1xuICAgIH1dKVxuICAgIC5wbmcoKVxuICAgIC50b0J1ZmZlcigpO1xuXG4gIHJldHVybiBuZXcgVWludDhBcnJheShjb21wb3NlZCk7XG59XG5cbi8qKlxuICogUm91bmRzIGEgd2lkdGggdG8gdGhlIG5lYXJlc3QgaW50ZWdlciBzaGFyaW5nIGB0YXJnZXRgJ3MgcGFyaXR5LCBzb1xuICogYHRhcmdldCAtIHJlc3VsdGAgaXMgZXZlbiBhbmQgc3BsaXRzIGludG8gdHdvIGVxdWFsIG1hcmdpbnMuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIGV4YWN0IHNjYWxlZCB3aWR0aC5cbiAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgY2FudmFzIHdpZHRoIHdob3NlIHBhcml0eSBtdXN0IGJlIG1hdGNoZWQuXG4gKiBAcmV0dXJucyBUaGUgbmVhcmVzdCBpbnRlZ2VyIG9mIHRoZSBzYW1lIHBhcml0eSBhcyBgdGFyZ2V0YC5cbiAqL1xuZnVuY3Rpb24gcm91bmRUb01hdGNoaW5nUGFyaXR5KHZhbHVlOiBudW1iZXIsIHRhcmdldDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3Qgcm91bmRlZCA9IE1hdGgucm91bmQodmFsdWUpO1xuICBpZiAoKHRhcmdldCAtIHJvdW5kZWQpICUgTUFSR0lOX1NJREVTID09PSAwKSB7XG4gICAgcmV0dXJuIHJvdW5kZWQ7XG4gIH1cblxuICAvLyBgcm91bmRlZGAgbGVhdmVzIGFuIG9kZCByZW1haW5kZXIsIHNvIHN0ZXAgdG8gd2hpY2hldmVyIG5laWdoYm9yIGlzIGNsb3NlclxuICAvLyBUbyB0aGUgdHJ1ZSB2YWx1ZTsgYm90aCBoYXZlIHRoZSBwYXJpdHkgYHJvdW5kZWRgIGxhY2tzLlxuICByZXR1cm4gdmFsdWUgPj0gcm91bmRlZCA/IHJvdW5kZWQgKyAxIDogcm91bmRlZCAtIDE7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFtQkEsMEJBQTRCO0FBbUY1QixNQUFNLHFCQUFxQjtBQUszQixNQUFNLGVBQWU7QUFxQmQsU0FBUyxtQkFBbUIsUUFBdUQ7QUFDeEYsUUFBTTtBQUFBLElBQ0o7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGLElBQUk7QUFFSixRQUFNLGtCQUFzQztBQUFBLElBQzFDLENBQUMsd0JBQXdCLG9CQUFvQjtBQUFBLElBQzdDLENBQUMsdUJBQXVCLG1CQUFtQjtBQUFBLElBQzNDLENBQUMsd0JBQXdCLG9CQUFvQjtBQUFBLElBQzdDLENBQUMsdUJBQXVCLG1CQUFtQjtBQUFBLEVBQzdDO0FBRUEsYUFBVyxDQUFDLE1BQU0sS0FBSyxLQUFLLGlCQUFpQjtBQUMzQyxRQUFJLENBQUMsT0FBTyxTQUFTLEtBQUssS0FBSyxTQUFTLEdBQUc7QUFDekMsWUFBTSxJQUFJLE1BQU0sdUJBQXVCLElBQUksbUNBQW1DLE9BQU8sS0FBSyxDQUFDLEdBQUc7QUFBQSxJQUNoRztBQUFBLEVBQ0Y7QUFFQSxRQUFNLHVCQUF1QjtBQUM3QixRQUFNLG1CQUFtQix1QkFBdUIsdUJBQXVCO0FBQ3ZFLFFBQU0sc0JBQXNCLHNCQUFzQixrQkFBa0IsbUJBQW1CO0FBRXZGLE1BQUksc0JBQXNCLHFCQUFxQjtBQUM3QyxVQUFNLElBQUk7QUFBQSxNQUNSLHNGQUNRLE9BQU8sbUJBQW1CLENBQUMsTUFBTSxPQUFPLG1CQUFtQixDQUFDO0FBQUEsSUFDdEU7QUFBQSxFQUNGO0FBRUEsUUFBTSxrQkFBa0Isc0JBQXNCLHVCQUF1QjtBQUVyRSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsaUJBQWlCO0FBQUEsSUFDakIsaUJBQWlCO0FBQUEsSUFDakI7QUFBQSxJQUNBO0FBQUEsRUFDRjtBQUNGO0FBZUEsZUFBc0Isc0JBQXNCLE9BQW1CLFNBQTREO0FBQ3pILFFBQU07QUFBQSxJQUNKLFlBQVk7QUFBQSxJQUNaO0FBQUEsSUFDQTtBQUFBLEVBQ0YsSUFBSTtBQUVKLFFBQU0sUUFBUSxVQUFNLGlDQUFZLHVCQUF1QjtBQUN2RCxRQUFNLFdBQVcsTUFBTSxNQUFNLEtBQUssRUFBRSxTQUFTO0FBQzdDLFFBQU0sc0JBQXNCLFNBQVM7QUFDckMsUUFBTSx1QkFBdUIsU0FBUztBQUd0QyxNQUFJLHdCQUF3QixVQUFhLHlCQUF5QixRQUFXO0FBQzNFLFVBQU0sSUFBSSxNQUFNLG9FQUFvRTtBQUFBLEVBQ3RGO0FBRUEsUUFBTSxXQUFXLG1CQUFtQjtBQUFBLElBQ2xDO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixDQUFDO0FBSUQsUUFBTSxhQUFhLE1BQU0sTUFBTSxLQUFLLEVBQ2pDLE9BQU8scUJBQXFCLHNCQUFzQixFQUFFLEtBQUssUUFBUSxDQUFDLEVBQ2xFLEtBQUssU0FBUyxFQUNkLFNBQVM7QUFFWixRQUFNLGFBQWEsTUFBTSxNQUFNLEtBQUssRUFDakMsT0FBTyxTQUFTLHFCQUFxQixTQUFTLHNCQUFzQixFQUFFLEtBQUssT0FBTyxDQUFDLEVBQ25GLFNBQVM7QUFFWixRQUFNLFdBQVcsTUFBTSxNQUFNLFVBQVUsRUFDcEMsVUFBVSxDQUFDO0FBQUEsSUFDVixPQUFPO0FBQUEsSUFDUCxNQUFNLFNBQVM7QUFBQSxJQUNmLEtBQUssU0FBUztBQUFBLEVBQ2hCLENBQUMsQ0FBQyxFQUNELElBQUksRUFDSixTQUFTO0FBRVosU0FBTyxJQUFJLFdBQVcsUUFBUTtBQUNoQztBQVVBLFNBQVMsc0JBQXNCLE9BQWUsUUFBd0I7QUFDcEUsUUFBTSxVQUFVLEtBQUssTUFBTSxLQUFLO0FBQ2hDLE9BQUssU0FBUyxXQUFXLGlCQUFpQixHQUFHO0FBQzNDLFdBQU87QUFBQSxFQUNUO0FBSUEsU0FBTyxTQUFTLFVBQVUsVUFBVSxJQUFJLFVBQVU7QUFDcEQ7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Fits a screenshot onto a canvas of a different aspect ratio without cropping
|
|
5
|
+
* it or distorting it, filling the leftover margins with a blurred, enlarged
|
|
6
|
+
* copy of the same image (the "pillarbox" treatment used by store listings).
|
|
7
|
+
*
|
|
8
|
+
* The motivating case is a mobile store screenshot. The Android emulator's
|
|
9
|
+
* framebuffer is whatever the AVD's screen is — a Pixel 10 Pro XL is 1344x2992,
|
|
10
|
+
* roughly 9:20 — while the community store asks for 900x1600 (9:16). Cropping
|
|
11
|
+
* to 9:16 throws away a fifth of the frame, and stretching distorts the UI, so
|
|
12
|
+
* the image is scaled to fit the HEIGHT and the two side margins are filled.
|
|
13
|
+
*
|
|
14
|
+
* The geometry is a pure function so it can be unit-tested; the pixel work needs
|
|
15
|
+
* `sharp`, which is an OPTIONAL peer dependency — declared rather than bundled
|
|
16
|
+
* because only screenshot capture needs it, and it ships platform-specific
|
|
17
|
+
* native binaries that every other consumer would pay for.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Parameters for {@link computeFitToCanvas}.
|
|
21
|
+
*/
|
|
22
|
+
export interface ComputeFitToCanvasParams {
|
|
23
|
+
/**
|
|
24
|
+
* Height of the target canvas, in pixels.
|
|
25
|
+
*/
|
|
26
|
+
readonly canvasHeightInPixels: number;
|
|
27
|
+
/**
|
|
28
|
+
* Width of the target canvas, in pixels.
|
|
29
|
+
*/
|
|
30
|
+
readonly canvasWidthInPixels: number;
|
|
31
|
+
/**
|
|
32
|
+
* Height of the source image, in pixels.
|
|
33
|
+
*/
|
|
34
|
+
readonly sourceHeightInPixels: number;
|
|
35
|
+
/**
|
|
36
|
+
* Width of the source image, in pixels.
|
|
37
|
+
*/
|
|
38
|
+
readonly sourceWidthInPixels: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Options for {@link fitScreenshotToCanvas}.
|
|
42
|
+
*/
|
|
43
|
+
export interface FitScreenshotToCanvasOptions {
|
|
44
|
+
/**
|
|
45
|
+
* Gaussian blur strength applied to the margin fill.
|
|
46
|
+
*
|
|
47
|
+
* @default `24`
|
|
48
|
+
*/
|
|
49
|
+
readonly blurSigma?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Height of the target canvas, in pixels.
|
|
52
|
+
*/
|
|
53
|
+
readonly canvasHeightInPixels: number;
|
|
54
|
+
/**
|
|
55
|
+
* Width of the target canvas, in pixels.
|
|
56
|
+
*/
|
|
57
|
+
readonly canvasWidthInPixels: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Where the scaled source image sits on the canvas.
|
|
61
|
+
*/
|
|
62
|
+
export interface FitToCanvasGeometry {
|
|
63
|
+
/**
|
|
64
|
+
* Width of each side margin, in pixels. Both sides are equal by construction.
|
|
65
|
+
*/
|
|
66
|
+
readonly marginInPixels: number;
|
|
67
|
+
/**
|
|
68
|
+
* Left offset of the scaled image on the canvas, in pixels.
|
|
69
|
+
*/
|
|
70
|
+
readonly offsetXInPixels: number;
|
|
71
|
+
/**
|
|
72
|
+
* Top offset of the scaled image on the canvas, in pixels.
|
|
73
|
+
*/
|
|
74
|
+
readonly offsetYInPixels: number;
|
|
75
|
+
/**
|
|
76
|
+
* Height the source is scaled to, in pixels.
|
|
77
|
+
*/
|
|
78
|
+
readonly scaledHeightInPixels: number;
|
|
79
|
+
/**
|
|
80
|
+
* Width the source is scaled to, in pixels.
|
|
81
|
+
*/
|
|
82
|
+
readonly scaledWidthInPixels: number;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Computes how a source image is scaled and placed to fill a canvas's height,
|
|
86
|
+
* with equal margins on the left and right.
|
|
87
|
+
*
|
|
88
|
+
* The scaled width is rounded to the nearest integer that leaves an EVEN
|
|
89
|
+
* remainder, so the two margins are exactly equal — an asymmetric pillarbox is
|
|
90
|
+
* visible at a glance and looks like a mistake. Where both neighbors qualify,
|
|
91
|
+
* the one closer to the true scaled width wins, so the aspect error stays below
|
|
92
|
+
* one part in a thousand.
|
|
93
|
+
*
|
|
94
|
+
* Worked example, the mobile store case: a 1344x2992 frame onto a 900x1600
|
|
95
|
+
* canvas scales by `1600/2992` to 718.72 wide. 719 would leave a 181px
|
|
96
|
+
* remainder, which cannot split evenly, so 718 is chosen (margin 91) over 720
|
|
97
|
+
* (margin 90) because 718 is nearer 718.72.
|
|
98
|
+
*
|
|
99
|
+
* @param params - The source and canvas dimensions.
|
|
100
|
+
* @returns The scaled size, the offsets, and the side margin.
|
|
101
|
+
* @throws Error if any dimension is not a positive number.
|
|
102
|
+
*/
|
|
103
|
+
export declare function computeFitToCanvas(params: ComputeFitToCanvasParams): FitToCanvasGeometry;
|
|
104
|
+
/**
|
|
105
|
+
* Scales a screenshot to fill a canvas's height and fills the side margins with
|
|
106
|
+
* a blurred, enlarged copy of the same image.
|
|
107
|
+
*
|
|
108
|
+
* Nothing is cropped and nothing is stretched: the visible screenshot keeps its
|
|
109
|
+
* aspect ratio to within a rounding pixel, and the margins are made of the
|
|
110
|
+
* image itself rather than a flat color, so the result reads as one frame.
|
|
111
|
+
*
|
|
112
|
+
* @param bytes - The source PNG.
|
|
113
|
+
* @param options - The target canvas size and blur strength.
|
|
114
|
+
* @returns A {@link Promise} that resolves to the composed PNG, exactly the canvas size.
|
|
115
|
+
* @throws Error if `sharp` is not installed, or the source dimensions cannot be read.
|
|
116
|
+
*/
|
|
117
|
+
export declare function fitScreenshotToCanvas(bytes: Uint8Array, options: FitScreenshotToCanvasOptions): Promise<Uint8Array>;
|
package/dist/lib/cjs/index.cjs
CHANGED
|
@@ -30,13 +30,19 @@ __export(index_exports, {
|
|
|
30
30
|
TemporaryVault: () => import_temporary_vault.TemporaryVault,
|
|
31
31
|
buildDemoVaultPopulate: () => import_demo_vault_populate.buildDemoVaultPopulate,
|
|
32
32
|
buildDeviceMetricsOverride: () => import_capture_screenshot.buildDeviceMetricsOverride,
|
|
33
|
+
buildLabelSvg: () => import_label_screenshot.buildLabelSvg,
|
|
33
34
|
captureObsidianScreenshot: () => import_capture_obsidian_screenshot.captureObsidianScreenshot,
|
|
35
|
+
computeFitToCanvas: () => import_fit_screenshot.computeFitToCanvas,
|
|
36
|
+
computeLabelBand: () => import_label_screenshot.computeLabelBand,
|
|
34
37
|
connectToCdp: () => import_connect_to_cdp.connectToCdp,
|
|
35
38
|
createTransportFromOptions: () => import_transport_factory.createTransportFromOptions,
|
|
36
39
|
decodeBase64Png: () => import_capture_screenshot.decodeBase64Png,
|
|
40
|
+
escapeSvgText: () => import_label_screenshot.escapeSvgText,
|
|
37
41
|
evalInObsidian: () => import_eval_in_obsidian.evalInObsidian,
|
|
42
|
+
fitScreenshotToCanvas: () => import_fit_screenshot.fitScreenshotToCanvas,
|
|
38
43
|
getVersionMetadata: () => import_obsidian_metadata.getVersionMetadata,
|
|
39
44
|
isPng: () => import_capture_screenshot.isPng,
|
|
45
|
+
labelScreenshot: () => import_label_screenshot.labelScreenshot,
|
|
40
46
|
pollInObsidian: () => import_poll_in_obsidian.pollInObsidian,
|
|
41
47
|
readDemoVaultTree: () => import_demo_vault_tree.readDemoVaultTree,
|
|
42
48
|
readPngDimensions: () => import_capture_screenshot.readPngDimensions,
|
|
@@ -61,8 +67,10 @@ var import_demo_vault_populate = require("./demo-vault-populate.cjs");
|
|
|
61
67
|
var import_demo_vault_tree = require("./demo-vault-tree.cjs");
|
|
62
68
|
var import_electron_compatibility = require("./electron-compatibility.cjs");
|
|
63
69
|
var import_eval_in_obsidian = require("./eval-in-obsidian.cjs");
|
|
70
|
+
var import_fit_screenshot = require("./fit-screenshot.cjs");
|
|
64
71
|
var import_incompatible_installer_version_error = require("./incompatible-installer-version-error.cjs");
|
|
65
72
|
var import_installer_compatibility = require("./installer-compatibility.cjs");
|
|
73
|
+
var import_label_screenshot = require("./label-screenshot.cjs");
|
|
66
74
|
var import_lib_registry = require("./lib-registry.cjs");
|
|
67
75
|
var import_obsidian_metadata = require("./obsidian-metadata.cjs");
|
|
68
76
|
var import_obsidian_version = require("./obsidian-version.cjs");
|
|
@@ -90,13 +98,19 @@ var import_version_matrix = require("./version-matrix.cjs");
|
|
|
90
98
|
TemporaryVault,
|
|
91
99
|
buildDemoVaultPopulate,
|
|
92
100
|
buildDeviceMetricsOverride,
|
|
101
|
+
buildLabelSvg,
|
|
93
102
|
captureObsidianScreenshot,
|
|
103
|
+
computeFitToCanvas,
|
|
104
|
+
computeLabelBand,
|
|
94
105
|
connectToCdp,
|
|
95
106
|
createTransportFromOptions,
|
|
96
107
|
decodeBase64Png,
|
|
108
|
+
escapeSvgText,
|
|
97
109
|
evalInObsidian,
|
|
110
|
+
fitScreenshotToCanvas,
|
|
98
111
|
getVersionMetadata,
|
|
99
112
|
isPng,
|
|
113
|
+
labelScreenshot,
|
|
100
114
|
pollInObsidian,
|
|
101
115
|
readDemoVaultTree,
|
|
102
116
|
readPngDimensions,
|
|
@@ -110,4 +124,4 @@ var import_version_matrix = require("./version-matrix.cjs");
|
|
|
110
124
|
setVaultPathResolver,
|
|
111
125
|
unregisterVault
|
|
112
126
|
});
|
|
113
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
127
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgaW50ZWdyYXRpb24gdGVzdGluZyBtb2R1bGUuXG4gKi9cblxuZXhwb3J0IHR5cGUge1xuICBBc2FyRmFsbGJhY2ssXG4gIEFzYXJGYWxsYmFja1RpZXIsXG4gIFJlc29sdmVBc2FyRmFsbGJhY2tQYXJhbXNcbn0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5janMnO1xuZXhwb3J0IHsgcmVzb2x2ZUFzYXJGYWxsYmFjayB9IGZyb20gJy4vYXNhci1mYWxsYmFjay1kZXRlY3Rpb24uY2pzJztcbmV4cG9ydCB0eXBlIHsgQ2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdE9wdGlvbnMgfSBmcm9tICcuL2NhcHR1cmUtb2JzaWRpYW4tc2NyZWVuc2hvdC5janMnO1xuZXhwb3J0IHsgY2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdCB9IGZyb20gJy4vY2FwdHVyZS1vYnNpZGlhbi1zY3JlZW5zaG90LmNqcyc7XG5leHBvcnQgdHlwZSB7XG4gIENhcHR1cmVTY3JlZW5zaG90UGFyYW1zLFxuICBQbmdEaW1lbnNpb25zXG59IGZyb20gJy4vY2FwdHVyZS1zY3JlZW5zaG90LmNqcyc7XG5leHBvcnQge1xuICBidWlsZERldmljZU1ldHJpY3NPdmVycmlkZSxcbiAgZGVjb2RlQmFzZTY0UG5nLFxuICBpc1BuZyxcbiAgcmVhZFBuZ0RpbWVuc2lvbnNcbn0gZnJvbSAnLi9jYXB0dXJlLXNjcmVlbnNob3QuY2pzJztcbmV4cG9ydCB0eXBlIHtcbiAgQ2RwQ29ubmVjdGlvbixcbiAgQ29ubmVjdFRvQ2RwT3B0aW9uc1xufSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLmNqcyc7XG5leHBvcnQgeyBjb25uZWN0VG9DZHAgfSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLmNqcyc7XG5leHBvcnQgeyBDb250ZXh0SWQgfSBmcm9tICcuL2NvbnRleHQtaWQuY2pzJztcbmV4cG9ydCB0eXBlIHtcbiAgVHJhbnNwb3J0T3B0aW9uc1Jlc29sdmVyLFxuICBWYXVsdFBhdGhSZXNvbHZlclxufSBmcm9tICcuL2NvbnRleHQtcHJvdmlkZXIuY2pzJztcbmV4cG9ydCB7XG4gIHNldFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlcixcbiAgc2V0VmF1bHRQYXRoUmVzb2x2ZXJcbn0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLmNqcyc7XG5leHBvcnQgdHlwZSB7XG4gIEJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGVQYXJhbXMsXG4gIEluamVjdFBsdWdpblBhcmFtc1xufSBmcm9tICcuL2RlbW8tdmF1bHQtcG9wdWxhdGUuY2pzJztcbmV4cG9ydCB7IGJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGUgfSBmcm9tICcuL2RlbW8tdmF1bHQtcG9wdWxhdGUuY2pzJztcbmV4cG9ydCB0eXBlIHsgUmVhZERlbW9WYXVsdFRyZWVQYXJhbXMgfSBmcm9tICcuL2RlbW8tdmF1bHQtdHJlZS5janMnO1xuZXhwb3J0IHsgcmVhZERlbW9WYXVsdFRyZWUgfSBmcm9tICcuL2RlbW8tdmF1bHQtdHJlZS5janMnO1xuZXhwb3J0IHR5cGUge1xuICBFbGVjdHJvbkNvbXBhdGliaWxpdHksXG4gIEVsZWN0cm9uQ29tcGF0aWJpbGl0eVRpZXIsXG4gIFJlc29sdmVFbGVjdHJvbkNvbXBhdGliaWxpdHlQYXJhbXNcbn0gZnJvbSAnLi9lbGVjdHJvbi1jb21wYXRpYmlsaXR5LmNqcyc7XG5leHBvcnQgeyByZXNvbHZlRWxlY3Ryb25Db21wYXRpYmlsaXR5IH0gZnJvbSAnLi9lbGVjdHJvbi1jb21wYXRpYmlsaXR5LmNqcyc7XG5leHBvcnQgdHlwZSB7XG4gIEV2YWxJbk9ic2lkaWFuUGFyYW1zLFxuICBIb3ZlckVsZW1lbnRQYXJhbXMsXG4gIExpYixcbiAgTW92ZU1vdXNlUGFyYW1zLFxuICBQcmVzc0tleVBhcmFtcyxcbiAgVHlwZUludG9FZGl0b3JQYXJhbXMsXG4gIFVuaG92ZXJFbGVtZW50UGFyYW1zLFxuICBXYWl0VW50aWxQYXJhbXNcbn0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLmNqcyc7XG5leHBvcnQgeyBldmFsSW5PYnNpZGlhbiB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5janMnO1xuZXhwb3J0IHR5cGUge1xuICBDb21wdXRlRml0VG9DYW52YXNQYXJhbXMsXG4gIEZpdFNjcmVlbnNob3RUb0NhbnZhc09wdGlvbnMsXG4gIEZpdFRvQ2FudmFzR2VvbWV0cnlcbn0gZnJvbSAnLi9maXQtc2NyZWVuc2hvdC5janMnO1xuZXhwb3J0IHtcbiAgY29tcHV0ZUZpdFRvQ2FudmFzLFxuICBmaXRTY3JlZW5zaG90VG9DYW52YXNcbn0gZnJvbSAnLi9maXQtc2NyZWVuc2hvdC5janMnO1xuZXhwb3J0IHR5cGUgeyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3JDb25zdHJ1Y3RvclBhcmFtcyB9IGZyb20gJy4vaW5jb21wYXRpYmxlLWluc3RhbGxlci12ZXJzaW9uLWVycm9yLmNqcyc7XG5leHBvcnQgeyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3IgfSBmcm9tICcuL2luY29tcGF0aWJsZS1pbnN0YWxsZXItdmVyc2lvbi1lcnJvci5janMnO1xuZXhwb3J0IHR5cGUge1xuICBJbnN0YWxsZXJDb21wYXRpYmlsaXR5LFxuICBJbnN0YWxsZXJDb21wYXRpYmlsaXR5VGllcixcbiAgUmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHlQYXJhbXNcbn0gZnJvbSAnLi9pbnN0YWxsZXItY29tcGF0aWJpbGl0eS5janMnO1xuZXhwb3J0IHsgcmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2luc3RhbGxlci1jb21wYXRpYmlsaXR5LmNqcyc7XG5leHBvcnQgdHlwZSB7XG4gIENvbXB1dGVMYWJlbEJhbmRQYXJhbXMsXG4gIExhYmVsQmFuZEdlb21ldHJ5LFxuICBMYWJlbFNjcmVlbnNob3RPcHRpb25zXG59IGZyb20gJy4vbGFiZWwtc2NyZWVuc2hvdC5janMnO1xuZXhwb3J0IHtcbiAgYnVpbGRMYWJlbFN2ZyxcbiAgY29tcHV0ZUxhYmVsQmFuZCxcbiAgZXNjYXBlU3ZnVGV4dCxcbiAgbGFiZWxTY3JlZW5zaG90XG59IGZyb20gJy4vbGFiZWwtc2NyZWVuc2hvdC5janMnO1xuZXhwb3J0IHR5cGUgeyBMaWJSZXNvbHZlciB9IGZyb20gJy4vbGliLXJlZ2lzdHJ5LmNqcyc7XG5leHBvcnQgeyByZWdpc3RlckxpYlJlc29sdmVyIH0gZnJvbSAnLi9saWItcmVnaXN0cnkuY2pzJztcbmV4cG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5SdW50aW1lVmVyc2lvbnMsXG4gIE9ic2lkaWFuVmVyc2lvbkRvd25sb2FkcyxcbiAgT2JzaWRpYW5WZXJzaW9uTWV0YWRhdGFcbn0gZnJvbSAnLi9vYnNpZGlhbi1tZXRhZGF0YS5janMnO1xuZXhwb3J0IHsgZ2V0VmVyc2lvbk1ldGFkYXRhIH0gZnJvbSAnLi9vYnNpZGlhbi1tZXRhZGF0YS5janMnO1xuZXhwb3J0IHtcbiAgQ0FUQUxZU1RfTEFURVNULFxuICBQVUJMSUNfTEFURVNUXG59IGZyb20gJy4vb2JzaWRpYW4tdmVyc2lvbi5janMnO1xuZXhwb3J0IHR5cGUgeyBQb2xsSW5PYnNpZGlhblBhcmFtcyB9IGZyb20gJy4vcG9sbC1pbi1vYnNpZGlhbi5janMnO1xuZXhwb3J0IHsgcG9sbEluT2JzaWRpYW4gfSBmcm9tICcuL3BvbGwtaW4tb2JzaWRpYW4uY2pzJztcbmV4cG9ydCB7IFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3IgfSBmcm9tICcuL3JlbmRlcmVyLWZhaWxlZC10by1pbml0aWFsaXplLWVycm9yLmNqcyc7XG5leHBvcnQgdHlwZSB7IFJ1bk9ic2lkaWFuVmVyc2lvbk1hdHJpeFBhcmFtcyB9IGZyb20gJy4vcnVuLXZlcnNpb24tbWF0cml4LmNqcyc7XG5leHBvcnQgeyBydW5PYnNpZGlhblZlcnNpb25NYXRyaXggfSBmcm9tICcuL3J1bi12ZXJzaW9uLW1hdHJpeC5janMnO1xuZXhwb3J0IHR5cGUgeyBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvckNvbnN0cnVjdG9yUGFyYW1zIH0gZnJvbSAnLi9zaWxlbnQtYXNhci1mYWxsYmFjay1lcnJvci5janMnO1xuZXhwb3J0IHsgU2lsZW50QXNhckZhbGxiYWNrRXJyb3IgfSBmcm9tICcuL3NpbGVudC1hc2FyLWZhbGxiYWNrLWVycm9yLmNqcyc7XG5leHBvcnQgdHlwZSB7XG4gIFBvcHVsYXRlRmlsZUNvbnRlbnQsXG4gIFBvcHVsYXRlRmlsZXNQYXJhbXNcbn0gZnJvbSAnLi90ZW1wb3JhcnktdmF1bHQuY2pzJztcbmV4cG9ydCB7IFRlbXBvcmFyeVZhdWx0IH0gZnJvbSAnLi90ZW1wb3JhcnktdmF1bHQuY2pzJztcbmV4cG9ydCB0eXBlIHtcbiAgQXBwaXVtU2Vzc2lvbkluZm8sXG4gIEFwcGl1bVRyYW5zcG9ydENvbmZpZ1xufSBmcm9tICcuL3RyYW5zcG9ydC1hcHBpdW0uY2pzJztcbmV4cG9ydCB7IEFwcGl1bVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5janMnO1xuZXhwb3J0IHR5cGUge1xuICBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnLFxuICBPd25lZEluc3RhbmNlQXNhcixcbiAgT3duZWRJbnN0YW5jZUNvbmZpZ1xufSBmcm9tICcuL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC5janMnO1xuZXhwb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLmNqcyc7XG5leHBvcnQgeyBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcbmV4cG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucyxcbiAgT2JzaWRpYW5DZHBUcmFuc3BvcnRPcHRpb25zLFxuICBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnNcbn0gZnJvbSAnLi90cmFuc3BvcnQtb3B0aW9ucy5janMnO1xuZXhwb3J0IHR5cGUge1xuICBPYnNpZGlhblRyYW5zcG9ydCxcbiAgVHJhbnNwb3J0RXZhbE9wdGlvbnNcbn0gZnJvbSAnLi90cmFuc3BvcnQuY2pzJztcbmV4cG9ydCB7XG4gIHJlZ2lzdGVyVmF1bHQsXG4gIHVucmVnaXN0ZXJWYXVsdFxufSBmcm9tICcuL3ZhdWx0LXJlZ2lzdHJ5LmNqcyc7XG5leHBvcnQgdHlwZSB7IE9ic2lkaWFuVmVyc2lvbk1hdHJpeEVudHJ5IH0gZnJvbSAnLi92ZXJzaW9uLW1hdHJpeC5janMnO1xuZXhwb3J0IHsgREVGQVVMVF9PQlNJRElBTl9WRVJTSU9OX1NQRUNTIH0gZnJvbSAnLi92ZXJzaW9uLW1hdHJpeC5janMnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQVdBLHFDQUFvQztBQUVwQyx5Q0FBMEM7QUFLMUMsZ0NBS087QUFLUCw0QkFBNkI7QUFDN0Isd0JBQTBCO0FBSzFCLDhCQUdPO0FBS1AsaUNBQXVDO0FBRXZDLDZCQUFrQztBQU1sQyxvQ0FBNkM7QUFXN0MsOEJBQStCO0FBTS9CLDRCQUdPO0FBRVAsa0RBQWtEO0FBTWxELHFDQUE4QztBQU05Qyw4QkFLTztBQUVQLDBCQUFvQztBQU1wQywrQkFBbUM7QUFDbkMsOEJBR087QUFFUCw4QkFBK0I7QUFDL0IsaURBQWdEO0FBRWhELGdDQUF5QztBQUV6Qyx3Q0FBd0M7QUFLeEMsNkJBQStCO0FBSy9CLDhCQUFnQztBQU1oQyxtQ0FBb0M7QUFDcEMsK0JBQTJDO0FBVTNDLDRCQUdPO0FBRVAsNEJBQStDOyIsCiAgIm5hbWVzIjogW10KfQo=
|
package/dist/lib/cjs/index.d.cts
CHANGED
|
@@ -22,10 +22,14 @@ export type { ElectronCompatibility, ElectronCompatibilityTier, ResolveElectronC
|
|
|
22
22
|
export { resolveElectronCompatibility } from './electron-compatibility.cjs';
|
|
23
23
|
export type { EvalInObsidianParams, HoverElementParams, Lib, MoveMouseParams, PressKeyParams, TypeIntoEditorParams, UnhoverElementParams, WaitUntilParams } from './eval-in-obsidian.cjs';
|
|
24
24
|
export { evalInObsidian } from './eval-in-obsidian.cjs';
|
|
25
|
+
export type { ComputeFitToCanvasParams, FitScreenshotToCanvasOptions, FitToCanvasGeometry } from './fit-screenshot.cjs';
|
|
26
|
+
export { computeFitToCanvas, fitScreenshotToCanvas } from './fit-screenshot.cjs';
|
|
25
27
|
export type { IncompatibleInstallerVersionErrorConstructorParams } from './incompatible-installer-version-error.cjs';
|
|
26
28
|
export { IncompatibleInstallerVersionError } from './incompatible-installer-version-error.cjs';
|
|
27
29
|
export type { InstallerCompatibility, InstallerCompatibilityTier, ResolveInstallerCompatibilityParams } from './installer-compatibility.cjs';
|
|
28
30
|
export { resolveInstallerCompatibility } from './installer-compatibility.cjs';
|
|
31
|
+
export type { ComputeLabelBandParams, LabelBandGeometry, LabelScreenshotOptions } from './label-screenshot.cjs';
|
|
32
|
+
export { buildLabelSvg, computeLabelBand, escapeSvgText, labelScreenshot } from './label-screenshot.cjs';
|
|
29
33
|
export type { LibResolver } from './lib-registry.cjs';
|
|
30
34
|
export { registerLibResolver } from './lib-registry.cjs';
|
|
31
35
|
export type { ObsidianRuntimeVersions, ObsidianVersionDownloads, ObsidianVersionMetadata } from './obsidian-metadata.cjs';
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var label_screenshot_exports = {};
|
|
20
|
+
__export(label_screenshot_exports, {
|
|
21
|
+
buildLabelSvg: () => buildLabelSvg,
|
|
22
|
+
computeLabelBand: () => computeLabelBand,
|
|
23
|
+
escapeSvgText: () => escapeSvgText,
|
|
24
|
+
labelScreenshot: () => labelScreenshot
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(label_screenshot_exports);
|
|
27
|
+
var import_sharp_loader = require("./sharp-loader.cjs");
|
|
28
|
+
const FONT_SIZE_RATIO = 0.034;
|
|
29
|
+
const BAND_HEIGHT_RATIO = 2.2;
|
|
30
|
+
const BAND_OPACITY = 0.82;
|
|
31
|
+
const MINIMUM_FONT_SIZE_IN_PIXELS = 18;
|
|
32
|
+
const CENTER_DIVISOR = 2;
|
|
33
|
+
function buildLabelSvg(text, geometry, imageWidthInPixels) {
|
|
34
|
+
const { fontSizeInPixels, heightInPixels } = geometry;
|
|
35
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${String(imageWidthInPixels)}" height="${String(heightInPixels)}"><rect x="0" y="0" width="${String(imageWidthInPixels)}" height="${String(heightInPixels)}" fill="#000000" fill-opacity="${String(BAND_OPACITY)}"/><text x="${String(imageWidthInPixels / CENTER_DIVISOR)}" y="${String(heightInPixels / CENTER_DIVISOR)}" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="${String(fontSizeInPixels)}" font-weight="600" fill="#ffffff" text-anchor="middle" dominant-baseline="central">${escapeSvgText(text)}</text></svg>`;
|
|
36
|
+
}
|
|
37
|
+
function computeLabelBand(params) {
|
|
38
|
+
const { imageHeightInPixels, imageWidthInPixels } = params;
|
|
39
|
+
if (!Number.isFinite(imageWidthInPixels) || imageWidthInPixels <= 0) {
|
|
40
|
+
throw new Error(`computeLabelBand: imageWidthInPixels must be a positive number, got ${String(imageWidthInPixels)}.`);
|
|
41
|
+
}
|
|
42
|
+
if (!Number.isFinite(imageHeightInPixels) || imageHeightInPixels <= 0) {
|
|
43
|
+
throw new Error(`computeLabelBand: imageHeightInPixels must be a positive number, got ${String(imageHeightInPixels)}.`);
|
|
44
|
+
}
|
|
45
|
+
const fontSizeInPixels = Math.max(MINIMUM_FONT_SIZE_IN_PIXELS, Math.round(imageWidthInPixels * FONT_SIZE_RATIO));
|
|
46
|
+
const heightInPixels = Math.min(imageHeightInPixels, Math.round(fontSizeInPixels * BAND_HEIGHT_RATIO));
|
|
47
|
+
return {
|
|
48
|
+
fontSizeInPixels,
|
|
49
|
+
heightInPixels,
|
|
50
|
+
topInPixels: imageHeightInPixels - heightInPixels
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function escapeSvgText(text) {
|
|
54
|
+
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
55
|
+
}
|
|
56
|
+
async function labelScreenshot(bytes, options) {
|
|
57
|
+
const sharp = await (0, import_sharp_loader.importSharp)("labelScreenshot");
|
|
58
|
+
const metadata = await sharp(bytes).metadata();
|
|
59
|
+
const imageWidthInPixels = metadata.width;
|
|
60
|
+
const imageHeightInPixels = metadata.height;
|
|
61
|
+
if (imageWidthInPixels === void 0 || imageHeightInPixels === void 0) {
|
|
62
|
+
throw new Error("labelScreenshot: could not read the source image dimensions.");
|
|
63
|
+
}
|
|
64
|
+
const geometry = computeLabelBand({ imageHeightInPixels, imageWidthInPixels });
|
|
65
|
+
const svg = buildLabelSvg(options.text, geometry, imageWidthInPixels);
|
|
66
|
+
const layer = {
|
|
67
|
+
input: Buffer.from(svg),
|
|
68
|
+
left: 0,
|
|
69
|
+
top: geometry.topInPixels
|
|
70
|
+
};
|
|
71
|
+
const labeled = await sharp(bytes).composite([layer]).png().toBuffer();
|
|
72
|
+
return new Uint8Array(labeled);
|
|
73
|
+
}
|
|
74
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
75
|
+
0 && (module.exports = {
|
|
76
|
+
buildLabelSvg,
|
|
77
|
+
computeLabelBand,
|
|
78
|
+
escapeSvgText,
|
|
79
|
+
labelScreenshot
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2xhYmVsLXNjcmVlbnNob3QudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBZGRzIGEgY2FwdGlvbiBiYW5kIHRvIGFuIGFscmVhZHktY2FwdHVyZWQgc2NyZWVuc2hvdC5cbiAqXG4gKiBBIHN0b3JlIGxpc3Rpbmcgc2hvd3Mgc2NyZWVuc2hvdHMgT05FIEFUIEEgVElNRSwgaW4gYSBjYXJvdXNlbCwgd2l0aCBub1xuICogY2FwdGlvbiBvZiBpdHMgb3duIFx1MjAxNCBzbyBhbiBpbWFnZSBoYXMgdG8gc2F5IHdoYXQgaXQgaXMgc2hvd2luZy4gV2l0aG91dCB0aGF0LFxuICogYSBzaG90IG9mIHRoZSBzdGF0ZSBhIHBsdWdpbiByZW1vdmVzIHJlYWRzIGFzIGEgc2hvdCBvZiB0aGUgc3RhdGUgdGhlIHBsdWdpblxuICogY2F1c2VzLCB3aGljaCBpcyB0aGUgb3Bwb3NpdGUgb2YgdGhlIG1lc3NhZ2UuXG4gKlxuICogVGhlIGJhbmQgaXMgZHJhd24gb3ZlciB0aGUgQk9UVE9NIG9mIHRoZSBmcmFtZSwgZm9yIHR3byByZWFzb25zOiB0aGUgdG9wIGlzXG4gKiB3aGVyZSB0aGUgY29udGVudCBiZWluZyBkZW1vbnN0cmF0ZWQgdXN1YWxseSBzdGFydHMsIGFuZCB0aGUgYm90dG9tIG9mIGFuXG4gKiBPYnNpZGlhbiBmcmFtZSBpcyBjaHJvbWUgXHUyMDE0IHN0YXR1cyBiYXIsIHdvcmQgY291bnQsIHN5bmMgaW5kaWNhdG9yIFx1MjAxNCB3aGljaCB0aGVcbiAqIGJhbmQgdGhlbiBjb3ZlcnMgcmF0aGVyIHRoYW4gY29tcGV0aW5nIHdpdGguXG4gKlxuICogVGhpcyBpcyBwb3N0LXByb2Nlc3NpbmcsIGRlbGliZXJhdGVseS4gVGhlIGNhcHR1cmUgc3RheXMgYW4gdW50b3VjaGVkIGRldmljZVxuICogZnJhbWUsIGFuZCByZXdvcmRpbmcgYSBsYWJlbCBuZWVkcyBubyByZS1zaG9vdC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFNoYXJwQ29tcG9zaXRlTGF5ZXIgfSBmcm9tICcuL3NoYXJwLWxvYWRlci5janMnO1xuXG5pbXBvcnQgeyBpbXBvcnRTaGFycCB9IGZyb20gJy4vc2hhcnAtbG9hZGVyLmNqcyc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvbXB1dGVMYWJlbEJhbmR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVMYWJlbEJhbmRQYXJhbXMge1xuICAvKipcbiAgICogSGVpZ2h0IG9mIHRoZSBpbWFnZSBiZWluZyBsYWJlbGVkLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBpbWFnZUhlaWdodEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdpZHRoIG9mIHRoZSBpbWFnZSBiZWluZyBsYWJlbGVkLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBpbWFnZVdpZHRoSW5QaXhlbHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgZ2VvbWV0cnkgb2YgdGhlIGNhcHRpb24gYmFuZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYWJlbEJhbmRHZW9tZXRyeSB7XG4gIC8qKlxuICAgKiBGb250IHNpemUgZm9yIHRoZSBjYXB0aW9uLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBmb250U2l6ZUluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEhlaWdodCBvZiB0aGUgYmFuZCwgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgaGVpZ2h0SW5QaXhlbHM6IG51bWJlcjtcblxuICAvKipcbiAgICogRGlzdGFuY2UgZnJvbSB0aGUgdG9wIG9mIHRoZSBpbWFnZSB0byB0aGUgdG9wIG9mIHRoZSBiYW5kLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSB0b3BJblBpeGVsczogbnVtYmVyO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBsYWJlbFNjcmVlbnNob3R9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExhYmVsU2NyZWVuc2hvdE9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIGNhcHRpb24uIEtlZXAgaXQgdG8gYSBoYW5kZnVsIG9mIHdvcmRzOiBpdCBpcyByZWFkIGF0IGxpc3RpbmctdGh1bWJuYWlsXG4gICAqIHNpemUsIGFuZCBpdCBpcyBjbGlwcGVkIHJhdGhlciB0aGFuIHdyYXBwZWQuXG4gICAqL1xuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ2FwdGlvbiBzaXplIGFzIGEgZnJhY3Rpb24gb2YgaW1hZ2UgV0lEVEgsIG5vdCBoZWlnaHQuXG4gKlxuICogV2lkdGggaXMgd2hhdCBnb3Zlcm5zIGxlZ2liaWxpdHkgaGVyZTogYSA5MDB4MTYwMCBwaG9uZSBmcmFtZSBhbmQgYSAxMjAweDgwMFxuICogZGVza3RvcCBmcmFtZSBhcmUgcmVhZCBhdCBzaW1pbGFyIG9uLXNjcmVlbiB3aWR0aHMgaW4gYSBsaXN0aW5nLCBzbyBzaXppbmcgYnlcbiAqIHdpZHRoIGtlZXBzIHRoZSBjYXB0aW9uIHZpc3VhbGx5IGNvbnNpc3RlbnQgYWNyb3NzIHRoZSB0d28uXG4gKi9cbmNvbnN0IEZPTlRfU0laRV9SQVRJTyA9IDAuMDM0O1xuXG4vKipcbiAqIEJhbmQgaGVpZ2h0IGFzIGEgbXVsdGlwbGUgb2YgdGhlIGZvbnQgc2l6ZSBcdTIwMTQgZW5vdWdoIHRvIHNpdCB0aGUgdGV4dCBvbiB3aXRoXG4gKiBjbGVhciBzcGFjZSBhYm92ZSBhbmQgYmVsb3cuXG4gKi9cbmNvbnN0IEJBTkRfSEVJR0hUX1JBVElPID0gMi4yO1xuXG4vKipcbiAqIE9wYWNpdHkgb2YgdGhlIGJhbmQsIGRhcmsgZW5vdWdoIHRvIGNhcnJ5IGxpZ2h0IHRleHQgb3ZlciBhbnkgT2JzaWRpYW4gdGhlbWVcbiAqIHdoaWxlIHRoZSBmcmFtZSBiZW5lYXRoIHN0YXlzIGZhaW50bHkgdmlzaWJsZSByYXRoZXIgdGhhbiBsb29raW5nIGN1dCBvZmYuXG4gKi9cbmNvbnN0IEJBTkRfT1BBQ0lUWSA9IDAuODI7XG5cbmNvbnN0IE1JTklNVU1fRk9OVF9TSVpFX0lOX1BJWEVMUyA9IDE4O1xuXG4vKipcbiAqIERpdmlzb3IgdGhhdCB0dXJucyBhIHNwYW4gaW50byBpdHMgbWlkcG9pbnQsIGZvciBjZW50ZXJpbmcgdGhlIGNhcHRpb24uXG4gKi9cbmNvbnN0IENFTlRFUl9ESVZJU09SID0gMjtcblxuLyoqXG4gKiBCdWlsZHMgdGhlIFNWRyBmb3IgdGhlIGNhcHRpb24gYmFuZC5cbiAqXG4gKiBAcGFyYW0gdGV4dCAtIFRoZSBjYXB0aW9uLlxuICogQHBhcmFtIGdlb21ldHJ5IC0gVGhlIGJhbmQgZ2VvbWV0cnkuXG4gKiBAcGFyYW0gaW1hZ2VXaWR0aEluUGl4ZWxzIC0gV2lkdGggb2YgdGhlIGltYWdlLCBzbyB0aGUgYmFuZCBzcGFucyBpdC5cbiAqIEByZXR1cm5zIFRoZSBTVkcgbWFya3VwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRMYWJlbFN2Zyh0ZXh0OiBzdHJpbmcsIGdlb21ldHJ5OiBMYWJlbEJhbmRHZW9tZXRyeSwgaW1hZ2VXaWR0aEluUGl4ZWxzOiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCB7IGZvbnRTaXplSW5QaXhlbHMsIGhlaWdodEluUGl4ZWxzIH0gPSBnZW9tZXRyeTtcblxuICByZXR1cm4gYDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiJHtTdHJpbmcoaW1hZ2VXaWR0aEluUGl4ZWxzKX1cIiBoZWlnaHQ9XCIke1N0cmluZyhoZWlnaHRJblBpeGVscyl9XCI+YFxuICAgICsgYDxyZWN0IHg9XCIwXCIgeT1cIjBcIiB3aWR0aD1cIiR7U3RyaW5nKGltYWdlV2lkdGhJblBpeGVscyl9XCIgaGVpZ2h0PVwiJHtTdHJpbmcoaGVpZ2h0SW5QaXhlbHMpfVwiIGBcbiAgICArIGBmaWxsPVwiIzAwMDAwMFwiIGZpbGwtb3BhY2l0eT1cIiR7U3RyaW5nKEJBTkRfT1BBQ0lUWSl9XCIvPmBcbiAgICArIGA8dGV4dCB4PVwiJHtTdHJpbmcoaW1hZ2VXaWR0aEluUGl4ZWxzIC8gQ0VOVEVSX0RJVklTT1IpfVwiIHk9XCIke1N0cmluZyhoZWlnaHRJblBpeGVscyAvIENFTlRFUl9ESVZJU09SKX1cIiBgXG4gICAgKyBgZm9udC1mYW1pbHk9XCJTZWdvZSBVSSwgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZlwiIGZvbnQtc2l6ZT1cIiR7U3RyaW5nKGZvbnRTaXplSW5QaXhlbHMpfVwiIGBcbiAgICArICdmb250LXdlaWdodD1cIjYwMFwiIGZpbGw9XCIjZmZmZmZmXCIgdGV4dC1hbmNob3I9XCJtaWRkbGVcIiBkb21pbmFudC1iYXNlbGluZT1cImNlbnRyYWxcIj4nXG4gICAgKyBgJHtlc2NhcGVTdmdUZXh0KHRleHQpfTwvdGV4dD48L3N2Zz5gO1xufVxuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBjYXB0aW9uIGJhbmQncyBzaXplIGFuZCBwb3NpdGlvbiBmb3IgYSBnaXZlbiBpbWFnZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGltYWdlIGRpbWVuc2lvbnMuXG4gKiBAcmV0dXJucyBUaGUgYmFuZCBnZW9tZXRyeS5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgZWl0aGVyIGRpbWVuc2lvbiBpcyBub3QgYSBwb3NpdGl2ZSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlTGFiZWxCYW5kKHBhcmFtczogQ29tcHV0ZUxhYmVsQmFuZFBhcmFtcyk6IExhYmVsQmFuZEdlb21ldHJ5IHtcbiAgY29uc3QgeyBpbWFnZUhlaWdodEluUGl4ZWxzLCBpbWFnZVdpZHRoSW5QaXhlbHMgfSA9IHBhcmFtcztcblxuICBpZiAoIU51bWJlci5pc0Zpbml0ZShpbWFnZVdpZHRoSW5QaXhlbHMpIHx8IGltYWdlV2lkdGhJblBpeGVscyA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb21wdXRlTGFiZWxCYW5kOiBpbWFnZVdpZHRoSW5QaXhlbHMgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlciwgZ290ICR7U3RyaW5nKGltYWdlV2lkdGhJblBpeGVscyl9LmApO1xuICB9XG5cbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoaW1hZ2VIZWlnaHRJblBpeGVscykgfHwgaW1hZ2VIZWlnaHRJblBpeGVscyA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb21wdXRlTGFiZWxCYW5kOiBpbWFnZUhlaWdodEluUGl4ZWxzIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIsIGdvdCAke1N0cmluZyhpbWFnZUhlaWdodEluUGl4ZWxzKX0uYCk7XG4gIH1cblxuICBjb25zdCBmb250U2l6ZUluUGl4ZWxzID0gTWF0aC5tYXgoTUlOSU1VTV9GT05UX1NJWkVfSU5fUElYRUxTLCBNYXRoLnJvdW5kKGltYWdlV2lkdGhJblBpeGVscyAqIEZPTlRfU0laRV9SQVRJTykpO1xuICBjb25zdCBoZWlnaHRJblBpeGVscyA9IE1hdGgubWluKGltYWdlSGVpZ2h0SW5QaXhlbHMsIE1hdGgucm91bmQoZm9udFNpemVJblBpeGVscyAqIEJBTkRfSEVJR0hUX1JBVElPKSk7XG5cbiAgcmV0dXJuIHtcbiAgICBmb250U2l6ZUluUGl4ZWxzLFxuICAgIGhlaWdodEluUGl4ZWxzLFxuICAgIHRvcEluUGl4ZWxzOiBpbWFnZUhlaWdodEluUGl4ZWxzIC0gaGVpZ2h0SW5QaXhlbHNcbiAgfTtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHRleHQgZm9yIGluY2x1c2lvbiBpbiBTVkcgY2hhcmFjdGVyIGRhdGEuXG4gKlxuICogQSBjYXB0aW9uIGlzIGF1dGhvcmVkIHBlciBzY3JlZW5zaG90IGFuZCBjYW4gbGVnaXRpbWF0ZWx5IGNvbnRhaW4gYCZgIG9yIHRoZVxuICogYW5nbGUgYnJhY2tldHMgT2JzaWRpYW4gdXNlcyBpbiBsaW5rIHN5bnRheDsgdW5lc2NhcGVkLCB0aG9zZSBtYWtlIHRoZSBTVkdcbiAqIGltcG9zc2libGUgdG8gcGFyc2UgYW5kIGBzaGFycGAgZmFpbHMgb24gYSBjYXB0aW9uIHJhdGhlciB0aGFuIG9uIGFuIGltYWdlLlxuICpcbiAqIEBwYXJhbSB0ZXh0IC0gVGhlIHJhdyBjYXB0aW9uLlxuICogQHJldHVybnMgVGhlIGNhcHRpb24sIHNhZmUgdG8gZW1iZWQgaW4gU1ZHLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlU3ZnVGV4dCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlQWxsKCcmJywgJyZhbXA7JylcbiAgICAucmVwbGFjZUFsbCgnPCcsICcmbHQ7JylcbiAgICAucmVwbGFjZUFsbCgnPicsICcmZ3Q7JylcbiAgICAucmVwbGFjZUFsbCgnXCInLCAnJnF1b3Q7JylcbiAgICAucmVwbGFjZUFsbCgnXFwnJywgJyZhcG9zOycpO1xufVxuXG4vKipcbiAqIERyYXdzIGEgY2FwdGlvbiBiYW5kIGFjcm9zcyB0aGUgYm90dG9tIG9mIGEgc2NyZWVuc2hvdC5cbiAqXG4gKiBUaGUgaW1hZ2Uga2VlcHMgaXRzIGRpbWVuc2lvbnMgZXhhY3RseTogdGhlIGJhbmQgaXMgY29tcG9zaXRlZCBPVkVSIHRoZVxuICogZnJhbWUsIG5ldmVyIGFwcGVuZGVkIHRvIGl0LCBiZWNhdXNlIHRoZSBzdG9yZSBleHBlY3RzIGEgc3BlY2lmaWMgc2l6ZS5cbiAqXG4gKiBAcGFyYW0gYnl0ZXMgLSBUaGUgY2FwdHVyZWQgUE5HLlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgY2FwdGlvbi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxhYmVsZWQgUE5HLCB0aGUgc2FtZSBzaXplIGFzIHRoZSBpbnB1dC5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgYHNoYXJwYCBpcyBub3QgaW5zdGFsbGVkLCBvciB0aGUgaW1hZ2UgZGltZW5zaW9ucyBjYW5ub3QgYmUgcmVhZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxhYmVsU2NyZWVuc2hvdChieXRlczogVWludDhBcnJheSwgb3B0aW9uczogTGFiZWxTY3JlZW5zaG90T3B0aW9ucyk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICBjb25zdCBzaGFycCA9IGF3YWl0IGltcG9ydFNoYXJwKCdsYWJlbFNjcmVlbnNob3QnKTtcbiAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCBzaGFycChieXRlcykubWV0YWRhdGEoKTtcbiAgY29uc3QgaW1hZ2VXaWR0aEluUGl4ZWxzID0gbWV0YWRhdGEud2lkdGg7XG4gIGNvbnN0IGltYWdlSGVpZ2h0SW5QaXhlbHMgPSBtZXRhZGF0YS5oZWlnaHQ7XG5cbiAgLyogdjggaWdub3JlIG5leHQgMyAtLSBEZWZlbnNpdmU6IGBzaGFycGAgcmVqZWN0cyBhIG5vbi1pbWFnZSBiZWZvcmUgaXQgY2FuIHJlcG9ydCBtZXRhZGF0YSB3aXRob3V0IGRpbWVuc2lvbnMsIHNvIHRoaXMgYnJhbmNoIGlzIHVucmVhY2hhYmxlIGZyb20gYSB0ZXN0LiAqL1xuICBpZiAoaW1hZ2VXaWR0aEluUGl4ZWxzID09PSB1bmRlZmluZWQgfHwgaW1hZ2VIZWlnaHRJblBpeGVscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdsYWJlbFNjcmVlbnNob3Q6IGNvdWxkIG5vdCByZWFkIHRoZSBzb3VyY2UgaW1hZ2UgZGltZW5zaW9ucy4nKTtcbiAgfVxuXG4gIGNvbnN0IGdlb21ldHJ5ID0gY29tcHV0ZUxhYmVsQmFuZCh7IGltYWdlSGVpZ2h0SW5QaXhlbHMsIGltYWdlV2lkdGhJblBpeGVscyB9KTtcbiAgY29uc3Qgc3ZnID0gYnVpbGRMYWJlbFN2ZyhvcHRpb25zLnRleHQsIGdlb21ldHJ5LCBpbWFnZVdpZHRoSW5QaXhlbHMpO1xuICBjb25zdCBsYXllcjogU2hhcnBDb21wb3NpdGVMYXllciA9IHtcbiAgICBpbnB1dDogQnVmZmVyLmZyb20oc3ZnKSxcbiAgICBsZWZ0OiAwLFxuICAgIHRvcDogZ2VvbWV0cnkudG9wSW5QaXhlbHNcbiAgfTtcblxuICBjb25zdCBsYWJlbGVkID0gYXdhaXQgc2hhcnAoYnl0ZXMpXG4gICAgLmNvbXBvc2l0ZShbbGF5ZXJdKVxuICAgIC5wbmcoKVxuICAgIC50b0J1ZmZlcigpO1xuXG4gIHJldHVybiBuZXcgVWludDhBcnJheShsYWJlbGVkKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFxQkEsMEJBQTRCO0FBdUQ1QixNQUFNLGtCQUFrQjtBQU14QixNQUFNLG9CQUFvQjtBQU0xQixNQUFNLGVBQWU7QUFFckIsTUFBTSw4QkFBOEI7QUFLcEMsTUFBTSxpQkFBaUI7QUFVaEIsU0FBUyxjQUFjLE1BQWMsVUFBNkIsb0JBQW9DO0FBQzNHLFFBQU0sRUFBRSxrQkFBa0IsZUFBZSxJQUFJO0FBRTdDLFNBQU8sa0RBQWtELE9BQU8sa0JBQWtCLENBQUMsYUFBYSxPQUFPLGNBQWMsQ0FBQyw4QkFDdEYsT0FBTyxrQkFBa0IsQ0FBQyxhQUFhLE9BQU8sY0FBYyxDQUFDLGtDQUN6RCxPQUFPLFlBQVksQ0FBQyxlQUN4QyxPQUFPLHFCQUFxQixjQUFjLENBQUMsUUFBUSxPQUFPLGlCQUFpQixjQUFjLENBQUMscUVBQ25DLE9BQU8sZ0JBQWdCLENBQUMsdUZBRXhGLGNBQWMsSUFBSSxDQUFDO0FBQzVCO0FBU08sU0FBUyxpQkFBaUIsUUFBbUQ7QUFDbEYsUUFBTSxFQUFFLHFCQUFxQixtQkFBbUIsSUFBSTtBQUVwRCxNQUFJLENBQUMsT0FBTyxTQUFTLGtCQUFrQixLQUFLLHNCQUFzQixHQUFHO0FBQ25FLFVBQU0sSUFBSSxNQUFNLHVFQUF1RSxPQUFPLGtCQUFrQixDQUFDLEdBQUc7QUFBQSxFQUN0SDtBQUVBLE1BQUksQ0FBQyxPQUFPLFNBQVMsbUJBQW1CLEtBQUssdUJBQXVCLEdBQUc7QUFDckUsVUFBTSxJQUFJLE1BQU0sd0VBQXdFLE9BQU8sbUJBQW1CLENBQUMsR0FBRztBQUFBLEVBQ3hIO0FBRUEsUUFBTSxtQkFBbUIsS0FBSyxJQUFJLDZCQUE2QixLQUFLLE1BQU0scUJBQXFCLGVBQWUsQ0FBQztBQUMvRyxRQUFNLGlCQUFpQixLQUFLLElBQUkscUJBQXFCLEtBQUssTUFBTSxtQkFBbUIsaUJBQWlCLENBQUM7QUFFckcsU0FBTztBQUFBLElBQ0w7QUFBQSxJQUNBO0FBQUEsSUFDQSxhQUFhLHNCQUFzQjtBQUFBLEVBQ3JDO0FBQ0Y7QUFZTyxTQUFTLGNBQWMsTUFBc0I7QUFDbEQsU0FBTyxLQUNKLFdBQVcsS0FBSyxPQUFPLEVBQ3ZCLFdBQVcsS0FBSyxNQUFNLEVBQ3RCLFdBQVcsS0FBSyxNQUFNLEVBQ3RCLFdBQVcsS0FBSyxRQUFRLEVBQ3hCLFdBQVcsS0FBTSxRQUFRO0FBQzlCO0FBYUEsZUFBc0IsZ0JBQWdCLE9BQW1CLFNBQXNEO0FBQzdHLFFBQU0sUUFBUSxVQUFNLGlDQUFZLGlCQUFpQjtBQUNqRCxRQUFNLFdBQVcsTUFBTSxNQUFNLEtBQUssRUFBRSxTQUFTO0FBQzdDLFFBQU0scUJBQXFCLFNBQVM7QUFDcEMsUUFBTSxzQkFBc0IsU0FBUztBQUdyQyxNQUFJLHVCQUF1QixVQUFhLHdCQUF3QixRQUFXO0FBQ3pFLFVBQU0sSUFBSSxNQUFNLDhEQUE4RDtBQUFBLEVBQ2hGO0FBRUEsUUFBTSxXQUFXLGlCQUFpQixFQUFFLHFCQUFxQixtQkFBbUIsQ0FBQztBQUM3RSxRQUFNLE1BQU0sY0FBYyxRQUFRLE1BQU0sVUFBVSxrQkFBa0I7QUFDcEUsUUFBTSxRQUE2QjtBQUFBLElBQ2pDLE9BQU8sT0FBTyxLQUFLLEdBQUc7QUFBQSxJQUN0QixNQUFNO0FBQUEsSUFDTixLQUFLLFNBQVM7QUFBQSxFQUNoQjtBQUVBLFFBQU0sVUFBVSxNQUFNLE1BQU0sS0FBSyxFQUM5QixVQUFVLENBQUMsS0FBSyxDQUFDLEVBQ2pCLElBQUksRUFDSixTQUFTO0FBRVosU0FBTyxJQUFJLFdBQVcsT0FBTztBQUMvQjsiLAogICJuYW1lcyI6IFtdCn0K
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Adds a caption band to an already-captured screenshot.
|
|
5
|
+
*
|
|
6
|
+
* A store listing shows screenshots ONE AT A TIME, in a carousel, with no
|
|
7
|
+
* caption of its own — so an image has to say what it is showing. Without that,
|
|
8
|
+
* a shot of the state a plugin removes reads as a shot of the state the plugin
|
|
9
|
+
* causes, which is the opposite of the message.
|
|
10
|
+
*
|
|
11
|
+
* The band is drawn over the BOTTOM of the frame, for two reasons: the top is
|
|
12
|
+
* where the content being demonstrated usually starts, and the bottom of an
|
|
13
|
+
* Obsidian frame is chrome — status bar, word count, sync indicator — which the
|
|
14
|
+
* band then covers rather than competing with.
|
|
15
|
+
*
|
|
16
|
+
* This is post-processing, deliberately. The capture stays an untouched device
|
|
17
|
+
* frame, and rewording a label needs no re-shoot.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Parameters for {@link computeLabelBand}.
|
|
21
|
+
*/
|
|
22
|
+
export interface ComputeLabelBandParams {
|
|
23
|
+
/**
|
|
24
|
+
* Height of the image being labeled, in pixels.
|
|
25
|
+
*/
|
|
26
|
+
readonly imageHeightInPixels: number;
|
|
27
|
+
/**
|
|
28
|
+
* Width of the image being labeled, in pixels.
|
|
29
|
+
*/
|
|
30
|
+
readonly imageWidthInPixels: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The geometry of the caption band.
|
|
34
|
+
*/
|
|
35
|
+
export interface LabelBandGeometry {
|
|
36
|
+
/**
|
|
37
|
+
* Font size for the caption, in pixels.
|
|
38
|
+
*/
|
|
39
|
+
readonly fontSizeInPixels: number;
|
|
40
|
+
/**
|
|
41
|
+
* Height of the band, in pixels.
|
|
42
|
+
*/
|
|
43
|
+
readonly heightInPixels: number;
|
|
44
|
+
/**
|
|
45
|
+
* Distance from the top of the image to the top of the band, in pixels.
|
|
46
|
+
*/
|
|
47
|
+
readonly topInPixels: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Options for {@link labelScreenshot}.
|
|
51
|
+
*/
|
|
52
|
+
export interface LabelScreenshotOptions {
|
|
53
|
+
/**
|
|
54
|
+
* The caption. Keep it to a handful of words: it is read at listing-thumbnail
|
|
55
|
+
* size, and it is clipped rather than wrapped.
|
|
56
|
+
*/
|
|
57
|
+
readonly text: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Builds the SVG for the caption band.
|
|
61
|
+
*
|
|
62
|
+
* @param text - The caption.
|
|
63
|
+
* @param geometry - The band geometry.
|
|
64
|
+
* @param imageWidthInPixels - Width of the image, so the band spans it.
|
|
65
|
+
* @returns The SVG markup.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildLabelSvg(text: string, geometry: LabelBandGeometry, imageWidthInPixels: number): string;
|
|
68
|
+
/**
|
|
69
|
+
* Computes the caption band's size and position for a given image.
|
|
70
|
+
*
|
|
71
|
+
* @param params - The image dimensions.
|
|
72
|
+
* @returns The band geometry.
|
|
73
|
+
* @throws Error if either dimension is not a positive number.
|
|
74
|
+
*/
|
|
75
|
+
export declare function computeLabelBand(params: ComputeLabelBandParams): LabelBandGeometry;
|
|
76
|
+
/**
|
|
77
|
+
* Escapes text for inclusion in SVG character data.
|
|
78
|
+
*
|
|
79
|
+
* A caption is authored per screenshot and can legitimately contain `&` or the
|
|
80
|
+
* angle brackets Obsidian uses in link syntax; unescaped, those make the SVG
|
|
81
|
+
* impossible to parse and `sharp` fails on a caption rather than on an image.
|
|
82
|
+
*
|
|
83
|
+
* @param text - The raw caption.
|
|
84
|
+
* @returns The caption, safe to embed in SVG.
|
|
85
|
+
*/
|
|
86
|
+
export declare function escapeSvgText(text: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* Draws a caption band across the bottom of a screenshot.
|
|
89
|
+
*
|
|
90
|
+
* The image keeps its dimensions exactly: the band is composited OVER the
|
|
91
|
+
* frame, never appended to it, because the store expects a specific size.
|
|
92
|
+
*
|
|
93
|
+
* @param bytes - The captured PNG.
|
|
94
|
+
* @param options - The caption.
|
|
95
|
+
* @returns A {@link Promise} that resolves to the labeled PNG, the same size as the input.
|
|
96
|
+
* @throws Error if `sharp` is not installed, or the image dimensions cannot be read.
|
|
97
|
+
*/
|
|
98
|
+
export declare function labelScreenshot(bytes: Uint8Array, options: LabelScreenshotOptions): Promise<Uint8Array>;
|
package/dist/lib/cjs/library.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(library_exports, {
|
|
|
21
21
|
LIBRARY_VERSION: () => LIBRARY_VERSION
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(library_exports);
|
|
24
|
-
const LIBRARY_VERSION = false ? "dev" : "10.
|
|
24
|
+
const LIBRARY_VERSION = false ? "dev" : "10.2.0";
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
27
|
LIBRARY_VERSION
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var sharp_loader_exports = {};
|
|
30
|
+
__export(sharp_loader_exports, {
|
|
31
|
+
importSharp: () => importSharp
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(sharp_loader_exports);
|
|
34
|
+
async function importSharp(caller) {
|
|
35
|
+
try {
|
|
36
|
+
const sharpModule = await import("sharp");
|
|
37
|
+
const factory = sharpModule.default;
|
|
38
|
+
return factory;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`${caller} needs the optional peer dependency "sharp". Install it in the consuming project (npm i -D sharp).`,
|
|
42
|
+
{ cause: error }
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
47
|
+
0 && (module.exports = {
|
|
48
|
+
importSharp
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NoYXJwLWxvYWRlci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIExhemlseSBsb2FkcyBgc2hhcnBgLCB0aGUgT1BUSU9OQUwgcGVlciBkZXBlbmRlbmN5IHRoZSBpbWFnZSBoZWxwZXJzIG5lZWQsIGFuZFxuICogZGVzY3JpYmVzIHRoZSBzbGljZSBvZiBpdHMgc3VyZmFjZSB0aGV5IHVzZS5cbiAqXG4gKiBUaGUgbG9hZCBpcyBkZWZlcnJlZCBiZWNhdXNlIGEgc3RhdGljIGltcG9ydCB3b3VsZCBkcmFnIGBzaGFycGAnc1xuICogcGxhdGZvcm0tc3BlY2lmaWMgbmF0aXZlIGJpbmFyaWVzIGludG8gZXZlcnkgY29uc3VtZXIgb2YgdGhpcyBwYWNrYWdlJ3MgaW5kZXgsXG4gKiB3aGVuIG9ubHkgc2NyZWVuc2hvdCBwb3N0LXByb2Nlc3NpbmcgbmVlZHMgdGhlbS4gVGhlIHR5cGUgaXMgc3RydWN0dXJhbCBmb3JcbiAqIHRoZSBzYW1lIHJlYXNvbjogdGhpcyBtb2R1bGUgdHlwZS1jaGVja3Mgd2l0aG91dCBgc2hhcnBgJ3Mgb3duIHR5cGVzIGJlaW5nXG4gKiByZXNvbHZhYmxlLlxuICovXG5cbi8qKlxuICogQSBsYXllciBwYXNzZWQgdG8gYHNoYXJwYCdzIGBjb21wb3NpdGVgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJwQ29tcG9zaXRlTGF5ZXIge1xuICByZWFkb25seSBpbnB1dDogQnVmZmVyO1xuICByZWFkb25seSBsZWZ0OiBudW1iZXI7XG4gIHJlYWRvbmx5IHRvcDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBgc2hhcnBgIGVudHJ5IHBvaW50IHRoZSBpbWFnZSBoZWxwZXJzIHVzZS5cbiAqL1xuZXhwb3J0IHR5cGUgU2hhcnBGYWN0b3J5ID0gKGlucHV0OiBVaW50OEFycmF5KSA9PiBTaGFycEluc3RhbmNlO1xuXG4vKipcbiAqIE9uZSBgc2hhcnBgIHBpcGVsaW5lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJwSW5zdGFuY2Uge1xuICBibHVyKHRoaXM6IHZvaWQsIHNpZ21hOiBudW1iZXIpOiBTaGFycEluc3RhbmNlO1xuICBjb21wb3NpdGUodGhpczogdm9pZCwgbGF5ZXJzOiBTaGFycENvbXBvc2l0ZUxheWVyW10pOiBTaGFycEluc3RhbmNlO1xuICBtZXRhZGF0YSh0aGlzOiB2b2lkKTogUHJvbWlzZTxTaGFycE1ldGFkYXRhPjtcbiAgcG5nKHRoaXM6IHZvaWQpOiBTaGFycEluc3RhbmNlO1xuICByZXNpemUodGhpczogdm9pZCwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIG9wdGlvbnM/OiBTaGFycFJlc2l6ZU9wdGlvbnMpOiBTaGFycEluc3RhbmNlO1xuICB0b0J1ZmZlcih0aGlzOiB2b2lkKTogUHJvbWlzZTxCdWZmZXI+O1xufVxuXG4vKipcbiAqIFRoZSBzdWJzZXQgb2YgYHNoYXJwYCdzIG1ldGFkYXRhIHRoZSBpbWFnZSBoZWxwZXJzIHJlYWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcnBNZXRhZGF0YSB7XG4gIHJlYWRvbmx5IGhlaWdodD86IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgd2lkdGg/OiBudW1iZXIgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogVGhlIHN1YnNldCBvZiBgc2hhcnBgJ3MgcmVzaXplIG9wdGlvbnMgdGhlIGltYWdlIGhlbHBlcnMgc2V0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJwUmVzaXplT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGZpdDogJ2NvdmVyJyB8ICdmaWxsJztcbn1cblxuLyoqXG4gKiBMb2FkcyBgc2hhcnBgIG9uIGRlbWFuZC5cbiAqXG4gKiBAcGFyYW0gY2FsbGVyIC0gTmFtZSBvZiB0aGUgY2FsbGluZyBoZWxwZXIsIHNvIHRoZSBlcnJvciBzYXlzIHdoaWNoIG9uZSBuZWVkcyBpdC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGBzaGFycGAgZmFjdG9yeS5cbiAqIEB0aHJvd3MgRXJyb3IgbmFtaW5nIHRoZSBtaXNzaW5nIG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGltcG9ydFNoYXJwKGNhbGxlcjogc3RyaW5nKTogUHJvbWlzZTxTaGFycEZhY3Rvcnk+IHtcbiAgdHJ5IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gYHNoYXJwYCBpcyBhbiBPUFRJT05BTCBwZWVyLCBzbyBpdCBtdXN0IGJlIGxvYWRlZCBsYXppbHk6IGEgc3RhdGljIGltcG9ydCB3b3VsZCBkcmFnIGl0cyBuYXRpdmUgYmluYXJpZXMgaW50byBldmVyeSBjb25zdW1lciBvZiB0aGlzIHBhY2thZ2UncyBpbmRleC5cbiAgICBjb25zdCBzaGFycE1vZHVsZSA9IGF3YWl0IGltcG9ydCgnc2hhcnAnKTtcbiAgICBjb25zdCBmYWN0b3J5OiB1bmtub3duID0gc2hhcnBNb2R1bGUuZGVmYXVsdDtcbiAgICByZXR1cm4gZmFjdG9yeSBhcyBTaGFycEZhY3Rvcnk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgLyogdjggaWdub3JlIHN0YXJ0IC0tIFJlYWNoZWQgb25seSB3aGVuIHRoZSBvcHRpb25hbCBwZWVyIGlzIGFic2VudCwgd2hpY2ggaXQgbmV2ZXIgaXMgaW4gdGhpcyBwYWNrYWdlJ3Mgb3duIHRlc3QgcnVuLiAqL1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGAke2NhbGxlcn0gbmVlZHMgdGhlIG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeSBcInNoYXJwXCIuIGBcbiAgICAgICAgKyAnSW5zdGFsbCBpdCBpbiB0aGUgY29uc3VtaW5nIHByb2plY3QgKG5wbSBpIC1EIHNoYXJwKS4nLFxuICAgICAgeyBjYXVzZTogZXJyb3IgfVxuICAgICk7XG4gICAgLyogdjggaWdub3JlIHN0b3AgKi9cbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUE2REEsZUFBc0IsWUFBWSxRQUF1QztBQUN2RSxNQUFJO0FBRUYsVUFBTSxjQUFjLE1BQU0sT0FBTyxPQUFPO0FBQ3hDLFVBQU0sVUFBbUIsWUFBWTtBQUNyQyxXQUFPO0FBQUEsRUFDVCxTQUFTLE9BQWdCO0FBRXZCLFVBQU0sSUFBSTtBQUFBLE1BQ1IsR0FBRyxNQUFNO0FBQUEsTUFFVCxFQUFFLE9BQU8sTUFBTTtBQUFBLElBQ2pCO0FBQUEsRUFFRjtBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=
|