@aspiresys/visor 1.3.5 → 1.4.1
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/app.js +2 -2
- package/dist/config.js +2 -2
- package/dist/dialog.js +4 -4
- package/dist/display.js +2 -2
- package/dist/index.d.ts +156 -139
- package/dist/index.js +201 -164
- package/dist/inspector/index.js +10 -8
- package/dist/matcher.d.ts +1 -1
- package/dist/matcher.js +43 -33
- package/dist/mouse.d.ts +1 -1
- package/dist/mouse.js +4 -4
- package/dist/ocr.d.ts +2 -1
- package/dist/ocr.js +15 -15
- package/dist/path.js +1 -1
- package/dist/region.js +3 -4
- package/dist/screen.js +5 -5
- package/dist/src/index.js +15 -16
- package/dist/src/matcher.d.ts +1 -1
- package/dist/src/matcher.js +13 -12
- package/dist/src/mouse.d.ts +1 -1
- package/dist/src/mouse.js +9 -11
- package/dist/src/screen.js +12 -10
- package/dist/src/types.js +2 -2
- package/dist/templateMetadata.js +8 -2
- package/dist/text.d.ts +1 -1
- package/dist/text.js +8 -8
- package/dist/types.d.ts +249 -159
- package/dist/types.js +330 -170
- package/dist/version.d.ts +1 -0
- package/dist/version.js +18 -0
- package/inspector/index.html +82 -55
- package/inspector/main.js +135 -207
- package/inspector/src/preload.js +10 -15
- package/inspector/src/renderer.js +180 -235
- package/inspector/start.js +8 -16
- package/inspector/styles.css +456 -458
- package/package.json +57 -51
- package/readme.md +790 -799
package/dist/types.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.Region = void 0;
|
|
4
7
|
const nut_js_1 = require("@nut-tree-fork/nut-js");
|
|
@@ -11,6 +14,9 @@ const path_1 = require("./path");
|
|
|
11
14
|
const config_1 = require("./config");
|
|
12
15
|
const console_1 = require("console");
|
|
13
16
|
const display_1 = require("./display");
|
|
17
|
+
const templateMetadata_1 = require("./templateMetadata");
|
|
18
|
+
const opencv_js_1 = __importDefault(require("@techstark/opencv-js"));
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
20
|
/**
|
|
15
21
|
* Represents a rectangular screen region.
|
|
16
22
|
*
|
|
@@ -48,90 +54,134 @@ class Region {
|
|
|
48
54
|
}
|
|
49
55
|
const missing = [];
|
|
50
56
|
if (!config_1.visorConfig.imagePath) {
|
|
51
|
-
missing.push(
|
|
57
|
+
missing.push('imagePath');
|
|
52
58
|
}
|
|
53
59
|
if (!config_1.visorConfig.outputPath) {
|
|
54
|
-
missing.push(
|
|
60
|
+
missing.push('outputPath');
|
|
55
61
|
}
|
|
56
62
|
if (missing.length > 0) {
|
|
57
63
|
(0, console_1.warn)(`[VISOR] Configuration incomplete.\n` +
|
|
58
|
-
`Missing: ${missing.join(
|
|
64
|
+
`Missing: ${missing.join(', ')}\n\n` +
|
|
59
65
|
`Relative paths may not work correctly.\n` +
|
|
60
66
|
`Use visor.loadConfig(...) or provide absolute paths directly to functions.`);
|
|
61
67
|
}
|
|
62
68
|
if (!config_1.visorConfig.initialized) {
|
|
63
69
|
config_1.visorConfig.scaleFactor = (0, display_1.getWindowsScaleFactor)();
|
|
64
|
-
(0, console_1.warn)(`[VISOR] Configuration not loaded.\n` +
|
|
65
|
-
`Auto-detected scaleFactor=${config_1.visorConfig.scaleFactor}.\n`);
|
|
70
|
+
(0, console_1.warn)(`[VISOR] Configuration not loaded.\n` + `Auto-detected scaleFactor=${config_1.visorConfig.scaleFactor}.\n`);
|
|
66
71
|
}
|
|
67
72
|
if (missing.length > 0 || !config_1.visorConfig.initialized) {
|
|
68
73
|
Region.configWarningShown = true;
|
|
69
74
|
}
|
|
70
75
|
}
|
|
71
76
|
/**
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
* Captures a screenshot of the
|
|
78
|
+
* region and saves it
|
|
79
|
+
* to the specified path.
|
|
80
|
+
*
|
|
81
|
+
* Supported formats depend on
|
|
82
|
+
* the output file extension.
|
|
83
|
+
*
|
|
84
|
+
* @param path Output image path.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* await region.capture(
|
|
88
|
+
* "./screenshots/output.png"
|
|
89
|
+
* );
|
|
90
|
+
*/
|
|
91
|
+
async capture(path) {
|
|
92
|
+
this.checkConfig();
|
|
93
|
+
const screenshot = await (0, screen_1.captureScreen)();
|
|
94
|
+
path = config_1.visorConfig.outputPath + '/' + path;
|
|
95
|
+
try {
|
|
96
|
+
const cropped = (0, matcher_1.cropMat)(screenshot, this);
|
|
97
|
+
const png = new opencv_js_1.default.Mat();
|
|
98
|
+
opencv_js_1.default.cvtColor(cropped, png, opencv_js_1.default.COLOR_RGBA2BGRA);
|
|
99
|
+
const imageData = {
|
|
100
|
+
width: png.cols,
|
|
101
|
+
height: png.rows,
|
|
102
|
+
data: Buffer.from(png.data),
|
|
103
|
+
};
|
|
104
|
+
const { PNG } = require('pngjs');
|
|
105
|
+
const output = new PNG({
|
|
106
|
+
width: imageData.width,
|
|
107
|
+
height: imageData.height,
|
|
108
|
+
});
|
|
109
|
+
output.data = imageData.data;
|
|
110
|
+
await new Promise((resolve) => {
|
|
111
|
+
output.pack().pipe(fs_1.default.createWriteStream(path)).on('finish', resolve);
|
|
112
|
+
});
|
|
113
|
+
png.delete();
|
|
114
|
+
cropped.delete();
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
screenshot.delete();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Returns the center point of the region.
|
|
122
|
+
*
|
|
123
|
+
* Useful for:
|
|
124
|
+
* - mouse movement
|
|
125
|
+
* - coordinate calculations
|
|
126
|
+
* - custom interactions
|
|
127
|
+
*/
|
|
79
128
|
center() {
|
|
80
129
|
return {
|
|
81
130
|
x: this.x + Math.floor(this.width / 2),
|
|
82
|
-
y: this.y + Math.floor(this.height / 2)
|
|
131
|
+
y: this.y + Math.floor(this.height / 2),
|
|
83
132
|
};
|
|
84
133
|
}
|
|
85
134
|
/**
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
135
|
+
* Moves the mouse to the center of the region.
|
|
136
|
+
*
|
|
137
|
+
* Mouse coordinates are automatically
|
|
138
|
+
* adjusted for display scaling.
|
|
139
|
+
*/
|
|
91
140
|
async move() {
|
|
92
141
|
await (0, mouse_1.moveToRegion)(this);
|
|
93
142
|
}
|
|
94
143
|
/**
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
144
|
+
* Performs a left click on the region.
|
|
145
|
+
*
|
|
146
|
+
* Clicks the center of the region by default.
|
|
147
|
+
*
|
|
148
|
+
* Optional offset can be supplied to click
|
|
149
|
+
* a specific position relative to the center.
|
|
150
|
+
*/
|
|
102
151
|
async click(offset) {
|
|
103
152
|
await (0, mouse_1.clickRegion)(this, offset);
|
|
153
|
+
console.log(`[CLICK] ${this.constructor.name} at center (${this.center().x}, ${this.center().y}) with confidence ${this.confidence.toFixed(2)})`);
|
|
104
154
|
}
|
|
105
155
|
/**
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
156
|
+
* Finds an image in the Region using OpenCV
|
|
157
|
+
* and performs a left mouse click
|
|
158
|
+
* on the matched region.
|
|
159
|
+
*
|
|
160
|
+
* @param image Optional image filename or path.
|
|
161
|
+
*
|
|
162
|
+
* @param confidence Match confidence threshold.
|
|
163
|
+
*
|
|
164
|
+
* Accepted range:
|
|
165
|
+
* 0.0 to 1.0
|
|
166
|
+
*
|
|
167
|
+
* Default:
|
|
168
|
+
* 0.8
|
|
169
|
+
*
|
|
170
|
+
* Recommended values:
|
|
171
|
+
* - 0.7 for dynamic UI
|
|
172
|
+
* - 0.8 for standard usage
|
|
173
|
+
* - 0.9+ for strict matching
|
|
174
|
+
*
|
|
175
|
+
* Lower confidence increases
|
|
176
|
+
* flexibility but may increase
|
|
177
|
+
* false positives.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* await region.clickImg("save.png");
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* await region.clickImg("./images/save.png", 0.9);
|
|
184
|
+
*/
|
|
135
185
|
async clickImg(image, confidence = 0.8, offset) {
|
|
136
186
|
this.checkConfig();
|
|
137
187
|
const region = await this.find(image, confidence);
|
|
@@ -211,130 +261,230 @@ class Region {
|
|
|
211
261
|
await region.doubleClick(offset);
|
|
212
262
|
}
|
|
213
263
|
/**
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
264
|
+
* Waits until an image appears
|
|
265
|
+
* in the Region.
|
|
266
|
+
*
|
|
267
|
+
* @param image Image filename or path.
|
|
268
|
+
*
|
|
269
|
+
* @param confidence Match confidence threshold.
|
|
270
|
+
*
|
|
271
|
+
* Accepted range:
|
|
272
|
+
* 0.0 to 1.0
|
|
273
|
+
*
|
|
274
|
+
* Default:
|
|
275
|
+
* 0.8
|
|
276
|
+
*
|
|
277
|
+
* Recommended values:
|
|
278
|
+
* - 0.7 for dynamic UI
|
|
279
|
+
* - 0.8 for standard usage
|
|
280
|
+
* - 0.9+ for strict matching
|
|
281
|
+
*
|
|
282
|
+
* @param timeout Timeout duration
|
|
283
|
+
* in milliseconds.
|
|
284
|
+
*
|
|
285
|
+
* Default:
|
|
286
|
+
* 5000ms
|
|
287
|
+
*
|
|
288
|
+
* Recommended range:
|
|
289
|
+
* 1000ms to 30000ms
|
|
290
|
+
*
|
|
291
|
+
* @throws Error if timeout occurs.
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* await region.waitImg("loading-done.png");
|
|
295
|
+
*/
|
|
246
296
|
async waitImg(image, { confidence = 0.8, timeout = 5000 } = {}) {
|
|
247
297
|
this.checkConfig();
|
|
248
298
|
const interval = 300;
|
|
249
299
|
const attempts = Math.ceil(timeout / interval);
|
|
250
300
|
for (let i = 0; i < attempts; i++) {
|
|
301
|
+
(0, console_1.log)(`[WAIT] ${image} (${i + 1}/${attempts})`);
|
|
251
302
|
if (await this.exists(image, confidence)) {
|
|
303
|
+
(0, console_1.log)(`[WAIT] Found: ${image}`);
|
|
252
304
|
return true;
|
|
253
305
|
}
|
|
254
306
|
await this.sleep(interval);
|
|
255
307
|
}
|
|
308
|
+
(0, console_1.log)(`[WAIT] Timeout: ${image}`);
|
|
256
309
|
throw new Error(`Timeout waiting for image: ${image}`);
|
|
257
310
|
}
|
|
258
311
|
/**
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
312
|
+
* Waits until any image from
|
|
313
|
+
* a list appears in the Region.
|
|
314
|
+
*
|
|
315
|
+
* Useful for handling:
|
|
316
|
+
* - multiple themes
|
|
317
|
+
* - alternate UI layouts
|
|
318
|
+
* - dynamic application states
|
|
319
|
+
*
|
|
320
|
+
* @param images Array of image
|
|
321
|
+
* filenames or paths.
|
|
322
|
+
*
|
|
323
|
+
* @param confidence Match confidence threshold.
|
|
324
|
+
*
|
|
325
|
+
* Accepted range:
|
|
326
|
+
* 0.0 to 1.0
|
|
327
|
+
*
|
|
328
|
+
* Default:
|
|
329
|
+
* 0.8
|
|
330
|
+
*
|
|
331
|
+
* Recommended values:
|
|
332
|
+
* - 0.7 for dynamic UI
|
|
333
|
+
* - 0.8 for standard usage
|
|
334
|
+
* - 0.9+ for strict matching
|
|
335
|
+
*
|
|
336
|
+
* Lower confidence increases
|
|
337
|
+
* flexibility but may increase
|
|
338
|
+
* false positives.
|
|
339
|
+
*
|
|
340
|
+
* @param timeout Timeout duration
|
|
341
|
+
* in milliseconds.
|
|
342
|
+
*
|
|
343
|
+
* Default:
|
|
344
|
+
* 5000ms
|
|
345
|
+
*
|
|
346
|
+
* Recommended range:
|
|
347
|
+
* 1000ms to 30000ms
|
|
348
|
+
*
|
|
349
|
+
* @throws Error if timeout occurs.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* await visor.waitAnyImg([
|
|
353
|
+
* "home-light.png",
|
|
354
|
+
* "home-dark.png"
|
|
355
|
+
* ]);
|
|
356
|
+
*/
|
|
357
|
+
async waitAnyImg(images, { confidence = 0.8, timeout = 5000 } = {}) {
|
|
358
|
+
this.checkConfig();
|
|
359
|
+
const interval = 300;
|
|
360
|
+
const attempts = Math.ceil(timeout / interval);
|
|
361
|
+
for (let i = 0; i < attempts; i++) {
|
|
362
|
+
for (const image of images) {
|
|
363
|
+
const region = await this.find(image, confidence);
|
|
364
|
+
if (region) {
|
|
365
|
+
return region;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
await this.sleep(interval);
|
|
369
|
+
}
|
|
370
|
+
throw new Error(`Timeout waiting for images: ${images.join(', ')}`);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Finds the first matching image
|
|
374
|
+
* within the current Region and
|
|
375
|
+
* performs a click.
|
|
376
|
+
*
|
|
377
|
+
* Useful for:
|
|
378
|
+
* - theme variations
|
|
379
|
+
* - alternate UI states
|
|
380
|
+
* - dynamic controls
|
|
381
|
+
*
|
|
382
|
+
* @param images Array of image paths.
|
|
383
|
+
* @param confidence Match confidence.
|
|
384
|
+
* @param offset Optional click offset.
|
|
385
|
+
*
|
|
386
|
+
* @returns Matched Region.
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* await region.clickAny([
|
|
390
|
+
* "save-light.png",
|
|
391
|
+
* "save-dark.png"
|
|
392
|
+
* ]);
|
|
393
|
+
*/
|
|
394
|
+
async clickAny(images, confidence = 0.8, offset) {
|
|
395
|
+
this.checkConfig();
|
|
396
|
+
for (const image of images) {
|
|
397
|
+
const region = await this.find(image, confidence);
|
|
398
|
+
if (region) {
|
|
399
|
+
await region.click(offset);
|
|
400
|
+
return region;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
throw new Error(`None of the images were found: ${images.join(', ')}`);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Performs a double left click on the region.
|
|
407
|
+
*
|
|
408
|
+
* Optional offset can be supplied to click
|
|
409
|
+
* a specific position relative to the center.
|
|
410
|
+
*/
|
|
264
411
|
async doubleClick(offset) {
|
|
265
412
|
await (0, mouse_1.moveToRegion)(this, offset);
|
|
266
413
|
await nut_js_1.mouse.doubleClick(nut_js_1.Button.LEFT);
|
|
267
414
|
}
|
|
268
415
|
/**
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
416
|
+
* Performs a right click on the region.
|
|
417
|
+
*
|
|
418
|
+
* Optional offset can be supplied to click
|
|
419
|
+
* a specific position relative to the center.
|
|
420
|
+
*/
|
|
274
421
|
async rightClick(offset) {
|
|
275
422
|
await (0, mouse_1.moveToRegion)(this, offset);
|
|
276
423
|
await nut_js_1.mouse.click(nut_js_1.Button.RIGHT);
|
|
277
424
|
}
|
|
278
425
|
/**
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
426
|
+
* Checks whether the supplied coordinates
|
|
427
|
+
* are located inside this region.
|
|
428
|
+
*
|
|
429
|
+
* Returns:
|
|
430
|
+
* - true if inside
|
|
431
|
+
* - false otherwise
|
|
432
|
+
*/
|
|
286
433
|
contains(x, y) {
|
|
287
|
-
return
|
|
434
|
+
return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height;
|
|
288
435
|
}
|
|
289
436
|
/**
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
437
|
+
* Creates a new Region shifted by the
|
|
438
|
+
* supplied x and y offsets.
|
|
439
|
+
*
|
|
440
|
+
* Original region remains unchanged.
|
|
441
|
+
*/
|
|
295
442
|
offset(x, y) {
|
|
296
443
|
return new Region(this.x + x, this.y + y, this.width, this.height, this.confidence);
|
|
297
444
|
}
|
|
298
445
|
/**
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
446
|
+
* Checks whether this region overlaps
|
|
447
|
+
* with another region.
|
|
448
|
+
*
|
|
449
|
+
* Returns:
|
|
450
|
+
* - true if regions intersect
|
|
451
|
+
* - false otherwise
|
|
452
|
+
*/
|
|
306
453
|
intersects(region) {
|
|
307
|
-
return (this.x <= region.x + region.width
|
|
454
|
+
return (this.x <= region.x + region.width &&
|
|
455
|
+
this.x + this.width >= region.x &&
|
|
456
|
+
this.y <= region.y + region.height &&
|
|
457
|
+
this.y + this.height >= region.y);
|
|
308
458
|
}
|
|
309
459
|
/**
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
460
|
+
* Returns the total area of the region
|
|
461
|
+
* in pixels.
|
|
462
|
+
*/
|
|
313
463
|
area() {
|
|
314
464
|
return this.width * this.height;
|
|
315
465
|
}
|
|
316
466
|
/**
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
467
|
+
* Extracts OCR text from this region.
|
|
468
|
+
*
|
|
469
|
+
* Returns full OCR output including:
|
|
470
|
+
* - text
|
|
471
|
+
* - TSV data
|
|
472
|
+
* - HOCR data
|
|
473
|
+
* - block information
|
|
474
|
+
*/
|
|
325
475
|
async readText() {
|
|
326
476
|
this.checkConfig();
|
|
327
477
|
return await (0, ocr_1.extractTextFromRegion)(this);
|
|
328
478
|
}
|
|
329
479
|
/**
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
480
|
+
* Searches for text within this region.
|
|
481
|
+
*
|
|
482
|
+
* Returns the matching text region
|
|
483
|
+
* if found, otherwise null.
|
|
484
|
+
*
|
|
485
|
+
* Supports selecting a specific match
|
|
486
|
+
* using the index parameter.
|
|
487
|
+
*/
|
|
338
488
|
async findText(text, index = 0) {
|
|
339
489
|
this.checkConfig();
|
|
340
490
|
const match = await (0, text_1.findText)(text, index, this);
|
|
@@ -344,35 +494,42 @@ class Region {
|
|
|
344
494
|
return match.offset(this.x, this.y);
|
|
345
495
|
}
|
|
346
496
|
/**
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
497
|
+
* Checks whether the supplied text
|
|
498
|
+
* exists within this region.
|
|
499
|
+
*
|
|
500
|
+
* Returns:
|
|
501
|
+
* - true if found
|
|
502
|
+
* - false otherwise
|
|
503
|
+
*/
|
|
354
504
|
async existsText(text) {
|
|
355
505
|
this.checkConfig();
|
|
356
506
|
return await (0, text_1.existsText)(text, this);
|
|
357
507
|
}
|
|
358
508
|
/**
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
509
|
+
* Searches for an image within this region.
|
|
510
|
+
*
|
|
511
|
+
* Matching is performed only inside
|
|
512
|
+
* the current region, improving speed
|
|
513
|
+
* and reducing false positives.
|
|
514
|
+
*
|
|
515
|
+
* Returns:
|
|
516
|
+
* - matching Region if found
|
|
517
|
+
* - null otherwise
|
|
518
|
+
*/
|
|
369
519
|
async find(image, confidence = 0.8) {
|
|
370
520
|
this.checkConfig();
|
|
371
521
|
const screenshot = await (0, screen_1.captureScreen)();
|
|
372
522
|
const croppedScreenshot = await (0, matcher_1.cropMat)(screenshot, this);
|
|
373
523
|
const template = await (0, matcher_1.loadTemplate)((0, path_1.resolveImagePath)(image));
|
|
524
|
+
const metadata = (0, templateMetadata_1.loadTemplateMetadata)((0, path_1.resolveImagePath)(image));
|
|
374
525
|
try {
|
|
375
|
-
|
|
526
|
+
if (metadata) {
|
|
527
|
+
metadata.currentResolution = {
|
|
528
|
+
width: screenshot.cols,
|
|
529
|
+
height: screenshot.rows,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const match = (0, matcher_1.matchTemplate)(croppedScreenshot, template, confidence, metadata);
|
|
376
533
|
if (!match) {
|
|
377
534
|
return null;
|
|
378
535
|
}
|
|
@@ -384,14 +541,17 @@ class Region {
|
|
|
384
541
|
template.delete();
|
|
385
542
|
}
|
|
386
543
|
}
|
|
544
|
+
expand(pixels) {
|
|
545
|
+
return new Region(this.x - pixels, this.y - pixels, this.width + pixels * 2, this.height + pixels * 2, this.confidence);
|
|
546
|
+
}
|
|
387
547
|
/**
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
548
|
+
* Finds all image matches within this region.
|
|
549
|
+
*
|
|
550
|
+
* Matching is performed only inside
|
|
551
|
+
* the current region.
|
|
552
|
+
*
|
|
553
|
+
* Returns an array of matching regions.
|
|
554
|
+
*/
|
|
395
555
|
async findAll(image, confidence = 0.8) {
|
|
396
556
|
this.checkConfig();
|
|
397
557
|
const screenshot = await (0, screen_1.captureScreen)();
|
|
@@ -399,7 +559,7 @@ class Region {
|
|
|
399
559
|
const template = await (0, matcher_1.loadTemplate)((0, path_1.resolveImagePath)(image));
|
|
400
560
|
try {
|
|
401
561
|
const matches = (0, matcher_1.findAllMatches)(croppedScreenshot, template, confidence);
|
|
402
|
-
return matches.map(match => match.offset(this.x, this.y));
|
|
562
|
+
return matches.map((match) => match.offset(this.x, this.y));
|
|
403
563
|
}
|
|
404
564
|
finally {
|
|
405
565
|
screenshot.delete();
|
|
@@ -408,15 +568,15 @@ class Region {
|
|
|
408
568
|
}
|
|
409
569
|
}
|
|
410
570
|
/**
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
571
|
+
* Checks whether an image exists
|
|
572
|
+
* within this region.
|
|
573
|
+
*
|
|
574
|
+
* Returns:
|
|
575
|
+
* - true if found
|
|
576
|
+
* - false otherwise
|
|
577
|
+
*/
|
|
418
578
|
async exists(image, confidence = 0.8) {
|
|
419
|
-
return await this.find(image, confidence) !== null;
|
|
579
|
+
return (await this.find(image, confidence)) !== null;
|
|
420
580
|
}
|
|
421
581
|
}
|
|
422
582
|
exports.Region = Region;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getVersion(): string;
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getVersion = getVersion;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function getVersion() {
|
|
10
|
+
try {
|
|
11
|
+
const packageJsonPath = path_1.default.join(__dirname, '..', 'package.json');
|
|
12
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
|
|
13
|
+
return packageJson.version;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return 'unknown';
|
|
17
|
+
}
|
|
18
|
+
}
|