@scanly/browser 2.0.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/README.md +3 -0
- package/dist/batch/batch-controller.d.ts +71 -0
- package/dist/batch/batch-controller.d.ts.map +1 -0
- package/dist/batch/batch-controller.js +422 -0
- package/dist/batch/batch-controller.js.map +1 -0
- package/dist/batch/batch-session.d.ts +53 -0
- package/dist/batch/batch-session.d.ts.map +1 -0
- package/dist/batch/batch-session.js +267 -0
- package/dist/batch/batch-session.js.map +1 -0
- package/dist/batch/index.d.ts +4 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/batch/index.js +4 -0
- package/dist/batch/index.js.map +1 -0
- package/dist/batch/types.d.ts +101 -0
- package/dist/batch/types.d.ts.map +1 -0
- package/dist/batch/types.js +2 -0
- package/dist/batch/types.js.map +1 -0
- package/dist/browser-session.d.ts +51 -0
- package/dist/browser-session.d.ts.map +1 -0
- package/dist/browser-session.js +168 -0
- package/dist/browser-session.js.map +1 -0
- package/dist/camera-source.d.ts +89 -0
- package/dist/camera-source.d.ts.map +1 -0
- package/dist/camera-source.js +366 -0
- package/dist/camera-source.js.map +1 -0
- package/dist/camera-strategy.d.ts +36 -0
- package/dist/camera-strategy.d.ts.map +1 -0
- package/dist/camera-strategy.js +94 -0
- package/dist/camera-strategy.js.map +1 -0
- package/dist/decode-upload.d.ts +13 -0
- package/dist/decode-upload.d.ts.map +1 -0
- package/dist/decode-upload.js +23 -0
- package/dist/decode-upload.js.map +1 -0
- package/dist/image-loader.d.ts +11 -0
- package/dist/image-loader.d.ts.map +1 -0
- package/dist/image-loader.js +63 -0
- package/dist/image-loader.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +14 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scanner/camera-capabilities.d.ts +20 -0
- package/dist/scanner/camera-capabilities.d.ts.map +1 -0
- package/dist/scanner/camera-capabilities.js +181 -0
- package/dist/scanner/camera-capabilities.js.map +1 -0
- package/dist/scanner/camera-platform.d.ts +75 -0
- package/dist/scanner/camera-platform.d.ts.map +1 -0
- package/dist/scanner/camera-platform.js +145 -0
- package/dist/scanner/camera-platform.js.map +1 -0
- package/dist/scanner/decode-escalation.d.ts +20 -0
- package/dist/scanner/decode-escalation.d.ts.map +1 -0
- package/dist/scanner/decode-escalation.js +40 -0
- package/dist/scanner/decode-escalation.js.map +1 -0
- package/dist/scanner/frame-quality.d.ts +24 -0
- package/dist/scanner/frame-quality.d.ts.map +1 -0
- package/dist/scanner/frame-quality.js +90 -0
- package/dist/scanner/frame-quality.js.map +1 -0
- package/dist/scanner/frame-scheduler.d.ts +59 -0
- package/dist/scanner/frame-scheduler.d.ts.map +1 -0
- package/dist/scanner/frame-scheduler.js +148 -0
- package/dist/scanner/frame-scheduler.js.map +1 -0
- package/dist/scanner/frame-source.d.ts +70 -0
- package/dist/scanner/frame-source.d.ts.map +1 -0
- package/dist/scanner/frame-source.js +263 -0
- package/dist/scanner/frame-source.js.map +1 -0
- package/dist/scanner/index.d.ts +12 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +12 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/repeat-suppressor.d.ts +23 -0
- package/dist/scanner/repeat-suppressor.d.ts.map +1 -0
- package/dist/scanner/repeat-suppressor.js +69 -0
- package/dist/scanner/repeat-suppressor.js.map +1 -0
- package/dist/scanner/scanner-session.d.ts +160 -0
- package/dist/scanner/scanner-session.d.ts.map +1 -0
- package/dist/scanner/scanner-session.js +766 -0
- package/dist/scanner/scanner-session.js.map +1 -0
- package/dist/scanner/temporal-confirmation.d.ts +30 -0
- package/dist/scanner/temporal-confirmation.d.ts.map +1 -0
- package/dist/scanner/temporal-confirmation.js +71 -0
- package/dist/scanner/temporal-confirmation.js.map +1 -0
- package/dist/scanner/temporal-roi.d.ts +27 -0
- package/dist/scanner/temporal-roi.d.ts.map +1 -0
- package/dist/scanner/temporal-roi.js +50 -0
- package/dist/scanner/temporal-roi.js.map +1 -0
- package/dist/scanner/types.d.ts +232 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +2 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/tracking/barcode-tracker.d.ts +28 -0
- package/dist/tracking/barcode-tracker.d.ts.map +1 -0
- package/dist/tracking/barcode-tracker.js +279 -0
- package/dist/tracking/barcode-tracker.js.map +1 -0
- package/dist/tracking/geometry.d.ts +13 -0
- package/dist/tracking/geometry.d.ts.map +1 -0
- package/dist/tracking/geometry.js +51 -0
- package/dist/tracking/geometry.js.map +1 -0
- package/dist/tracking/index.d.ts +8 -0
- package/dist/tracking/index.d.ts.map +1 -0
- package/dist/tracking/index.js +8 -0
- package/dist/tracking/index.js.map +1 -0
- package/dist/tracking/scanner-tracking-runtime.d.ts +45 -0
- package/dist/tracking/scanner-tracking-runtime.d.ts.map +1 -0
- package/dist/tracking/scanner-tracking-runtime.js +93 -0
- package/dist/tracking/scanner-tracking-runtime.js.map +1 -0
- package/dist/tracking/track-association.d.ts +19 -0
- package/dist/tracking/track-association.d.ts.map +1 -0
- package/dist/tracking/track-association.js +191 -0
- package/dist/tracking/track-association.js.map +1 -0
- package/dist/tracking/track-overlay.d.ts +4 -0
- package/dist/tracking/track-overlay.d.ts.map +1 -0
- package/dist/tracking/track-overlay.js +16 -0
- package/dist/tracking/track-overlay.js.map +1 -0
- package/dist/tracking/track-roi-set.d.ts +17 -0
- package/dist/tracking/track-roi-set.d.ts.map +1 -0
- package/dist/tracking/track-roi-set.js +119 -0
- package/dist/tracking/track-roi-set.js.map +1 -0
- package/dist/tracking/types.d.ts +154 -0
- package/dist/tracking/types.d.ts.map +1 -0
- package/dist/tracking/types.js +2 -0
- package/dist/tracking/types.js.map +1 -0
- package/dist/worker/decode-worker.d.ts +2 -0
- package/dist/worker/decode-worker.d.ts.map +1 -0
- package/dist/worker/decode-worker.js +84 -0
- package/dist/worker/decode-worker.js.map +1 -0
- package/dist/worker/transferable-buffer.d.ts +18 -0
- package/dist/worker/transferable-buffer.d.ts.map +1 -0
- package/dist/worker/transferable-buffer.js +24 -0
- package/dist/worker/transferable-buffer.js.map +1 -0
- package/dist/worker/worker-client.d.ts +86 -0
- package/dist/worker/worker-client.d.ts.map +1 -0
- package/dist/worker/worker-client.js +286 -0
- package/dist/worker/worker-client.js.map +1 -0
- package/dist/worker/worker-messages.d.ts +75 -0
- package/dist/worker/worker-messages.d.ts.map +1 -0
- package/dist/worker/worker-messages.js +244 -0
- package/dist/worker/worker-messages.js.map +1 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# @scanly/browser
|
|
2
|
+
|
|
3
|
+
Reusable upload Worker and camera-source lifecycle for plain browser JavaScript, bundlers, and React adapters. Worker code is self-hosted through `new URL(..., import.meta.url)` and no network service or telemetry is used. Deployments must allow the emitted Worker URL in `worker-src`; future WASM engines will require an explicit self-hosted asset resolver.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { BarcodeTrack, BarcodeTrackerUpdate } from "../tracking/types.js";
|
|
2
|
+
import type { BatchEventListener, BatchMode, BatchState, BatchStatistics, BatchUnsubscribe, ExpectedBatchItem, TrackListener } from "./types.js";
|
|
3
|
+
export interface BatchControllerOptions {
|
|
4
|
+
mode?: BatchMode;
|
|
5
|
+
expectedCount?: number;
|
|
6
|
+
expected?: readonly ExpectedBatchItem[];
|
|
7
|
+
/** Maximum live track snapshots retained by the batch view. Defaults to 64. */
|
|
8
|
+
maxRetainedTracks?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Maximum confirmed physical-instance snapshots retained for completion and
|
|
11
|
+
* classification. Defaults to 256 and may not exceed 4096.
|
|
12
|
+
*/
|
|
13
|
+
maxRetainedPhysicalInstances?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const DEFAULT_BATCH_MAX_RETAINED_TRACKS = 64;
|
|
16
|
+
export declare const DEFAULT_BATCH_MAX_RETAINED_PHYSICAL_INSTANCES = 256;
|
|
17
|
+
export declare const MAX_BATCH_RETENTION_LIMIT = 4096;
|
|
18
|
+
/**
|
|
19
|
+
* Pure batch state machine. It consumes tracker updates and never counts raw
|
|
20
|
+
* decoder events, so repeated observations cannot complete a batch early.
|
|
21
|
+
*/
|
|
22
|
+
export declare class BatchController {
|
|
23
|
+
private readonly mode;
|
|
24
|
+
private readonly expectedCount?;
|
|
25
|
+
private readonly expectedSlots;
|
|
26
|
+
private readonly maxRetainedTracks;
|
|
27
|
+
private readonly maxRetainedPhysicalInstances;
|
|
28
|
+
private readonly tracks;
|
|
29
|
+
private readonly confirmedByPhysicalInstance;
|
|
30
|
+
private readonly unexpectedByPhysicalInstance;
|
|
31
|
+
private readonly duplicateByPhysicalInstance;
|
|
32
|
+
private readonly trackListeners;
|
|
33
|
+
private readonly eventListeners;
|
|
34
|
+
private status;
|
|
35
|
+
private completedAt?;
|
|
36
|
+
private failureReason?;
|
|
37
|
+
private counters;
|
|
38
|
+
constructor(options?: BatchControllerOptions);
|
|
39
|
+
getTracks(): readonly BarcodeTrack[];
|
|
40
|
+
getState(): BatchState;
|
|
41
|
+
getStatistics(): BatchStatistics;
|
|
42
|
+
onTrack(listener: TrackListener): BatchUnsubscribe;
|
|
43
|
+
onEvent(listener: BatchEventListener): BatchUnsubscribe;
|
|
44
|
+
/** Apply one complete, frame-level BarcodeTracker update. */
|
|
45
|
+
applyTrackerUpdate(update: BarcodeTrackerUpdate): void;
|
|
46
|
+
/**
|
|
47
|
+
* Convenience for adapters/tests that already own stable tracker snapshots.
|
|
48
|
+
* Each supplied confirmed track is still de-duplicated by physical identity.
|
|
49
|
+
*/
|
|
50
|
+
applyTracks(tracks: readonly BarcodeTrack[], timestamp?: number): void;
|
|
51
|
+
cancel(): void;
|
|
52
|
+
fail(error: unknown): void;
|
|
53
|
+
reset(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Release frame-derived evidence while preserving terminal status and
|
|
56
|
+
* aggregate counters. A subsequent start() calls reset() for a fresh batch.
|
|
57
|
+
*/
|
|
58
|
+
releaseRetainedState(): void;
|
|
59
|
+
clear(): void;
|
|
60
|
+
private upsertTrack;
|
|
61
|
+
private confirmPhysicalTrack;
|
|
62
|
+
private evictOldestNonMatchedPhysicalInstance;
|
|
63
|
+
private recordRetentionPeaks;
|
|
64
|
+
private classifyChecklistTrack;
|
|
65
|
+
private completeIfSatisfied;
|
|
66
|
+
private matchedItems;
|
|
67
|
+
private missingItems;
|
|
68
|
+
private emitTrack;
|
|
69
|
+
private emit;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=batch-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-controller.d.ts","sourceRoot":"","sources":["../../src/batch/batch-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,KAAK,EAEV,kBAAkB,EAGlB,SAAS,EACT,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EAEjB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACxC,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,eAAO,MAAM,iCAAiC,KAAK,CAAC;AACpD,eAAO,MAAM,6CAA6C,MAAM,CAAC;AACjE,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAa/C;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAS;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAmC;IAC/E,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAmC;IAChF,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAmC;IAC/E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAcd;gBAEU,OAAO,GAAE,sBAA2B;IAwBhD,SAAS,IAAI,SAAS,YAAY,EAAE;IAIpC,QAAQ,IAAI,UAAU;IAiBtB,aAAa,IAAI,eAAe;IAyBhC,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,gBAAgB;IAKlD,OAAO,CAAC,QAAQ,EAAE,kBAAkB,GAAG,gBAAgB;IAKvD,6DAA6D;IAC7D,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IA+CtD;;;OAGG;IACH,WAAW,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,SAAS,SAAa,GAAG,IAAI;IAuB1E,MAAM,IAAI,IAAI;IAMd,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAO1B,KAAK,IAAI,IAAI;IA0Bb;;;OAGG;IACH,oBAAoB,IAAI,IAAI;IAQ5B,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,oBAAoB;IAwC5B,OAAO,CAAC,qCAAqC;IAa7C,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,IAAI;CAKb"}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
export const DEFAULT_BATCH_MAX_RETAINED_TRACKS = 64;
|
|
2
|
+
export const DEFAULT_BATCH_MAX_RETAINED_PHYSICAL_INSTANCES = 256;
|
|
3
|
+
export const MAX_BATCH_RETENTION_LIMIT = 4_096;
|
|
4
|
+
/**
|
|
5
|
+
* Pure batch state machine. It consumes tracker updates and never counts raw
|
|
6
|
+
* decoder events, so repeated observations cannot complete a batch early.
|
|
7
|
+
*/
|
|
8
|
+
export class BatchController {
|
|
9
|
+
mode;
|
|
10
|
+
expectedCount;
|
|
11
|
+
expectedSlots;
|
|
12
|
+
maxRetainedTracks;
|
|
13
|
+
maxRetainedPhysicalInstances;
|
|
14
|
+
tracks = new Map();
|
|
15
|
+
confirmedByPhysicalInstance = new Map();
|
|
16
|
+
unexpectedByPhysicalInstance = new Map();
|
|
17
|
+
duplicateByPhysicalInstance = new Map();
|
|
18
|
+
trackListeners = new Set();
|
|
19
|
+
eventListeners = new Set();
|
|
20
|
+
status = "collecting";
|
|
21
|
+
completedAt;
|
|
22
|
+
failureReason;
|
|
23
|
+
counters = {
|
|
24
|
+
trackAddedEvents: 0,
|
|
25
|
+
trackUpdatedEvents: 0,
|
|
26
|
+
trackLostEvents: 0,
|
|
27
|
+
trackRestoredEvents: 0,
|
|
28
|
+
trackRetiredEvents: 0,
|
|
29
|
+
batchCompletedEvents: 0,
|
|
30
|
+
peakRetainedTrackCount: 0,
|
|
31
|
+
peakRetainedPhysicalInstanceCount: 0,
|
|
32
|
+
peakUnexpectedQuantity: 0,
|
|
33
|
+
peakDuplicateQuantity: 0,
|
|
34
|
+
retentionRejectedTrackCount: 0,
|
|
35
|
+
retentionRejectedPhysicalInstanceCount: 0,
|
|
36
|
+
retentionEvictedPhysicalInstanceCount: 0,
|
|
37
|
+
};
|
|
38
|
+
constructor(options = {}) {
|
|
39
|
+
this.mode = options.mode ?? "continuous";
|
|
40
|
+
this.maxRetainedTracks = validateRetentionLimit("maxRetainedTracks", options.maxRetainedTracks, DEFAULT_BATCH_MAX_RETAINED_TRACKS);
|
|
41
|
+
this.maxRetainedPhysicalInstances = validateRetentionLimit("maxRetainedPhysicalInstances", options.maxRetainedPhysicalInstances, DEFAULT_BATCH_MAX_RETAINED_PHYSICAL_INSTANCES);
|
|
42
|
+
this.expectedCount = validateExpectedCount(this.mode, options.expectedCount);
|
|
43
|
+
this.expectedSlots = validateExpectedItems(this.mode, options.expected);
|
|
44
|
+
const requiredPhysicalInstances = this.mode === "checklist"
|
|
45
|
+
? this.expectedSlots.reduce((total, slot) => total + slot.quantity, 0)
|
|
46
|
+
: this.expectedCount ?? 0;
|
|
47
|
+
if (requiredPhysicalInstances > this.maxRetainedPhysicalInstances) {
|
|
48
|
+
throw new RangeError(`maxRetainedPhysicalInstances (${this.maxRetainedPhysicalInstances}) must cover the batch objective (${requiredPhysicalInstances}).`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
getTracks() {
|
|
52
|
+
return [...this.tracks.values()].map(cloneTrack);
|
|
53
|
+
}
|
|
54
|
+
getState() {
|
|
55
|
+
const matched = this.matchedItems();
|
|
56
|
+
const missing = this.missingItems();
|
|
57
|
+
return {
|
|
58
|
+
mode: this.mode,
|
|
59
|
+
status: this.status,
|
|
60
|
+
...(this.expectedCount === undefined ? {} : { expectedCount: this.expectedCount }),
|
|
61
|
+
confirmedPhysicalInstanceCount: this.confirmedByPhysicalInstance.size,
|
|
62
|
+
matched,
|
|
63
|
+
missing,
|
|
64
|
+
unexpected: [...this.unexpectedByPhysicalInstance.values()].map(cloneTrack),
|
|
65
|
+
duplicate: [...this.duplicateByPhysicalInstance.values()].map(cloneTrack),
|
|
66
|
+
...(this.completedAt === undefined ? {} : { completedAt: this.completedAt }),
|
|
67
|
+
...(this.failureReason === undefined ? {} : { failureReason: this.failureReason }),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
getStatistics() {
|
|
71
|
+
const state = this.getState();
|
|
72
|
+
const matchedQuantity = state.matched.length;
|
|
73
|
+
const missingQuantity = state.missing.reduce((total, entry) => total + entry.quantity, 0);
|
|
74
|
+
const objective = this.mode === "checklist"
|
|
75
|
+
? matchedQuantity + missingQuantity
|
|
76
|
+
: this.expectedCount;
|
|
77
|
+
const progress = this.mode === "checklist" ? matchedQuantity : state.confirmedPhysicalInstanceCount;
|
|
78
|
+
return {
|
|
79
|
+
confirmedPhysicalInstanceCount: state.confirmedPhysicalInstanceCount,
|
|
80
|
+
maxRetainedTracks: this.maxRetainedTracks,
|
|
81
|
+
maxRetainedPhysicalInstances: this.maxRetainedPhysicalInstances,
|
|
82
|
+
retainedTrackCount: this.tracks.size,
|
|
83
|
+
retainedPhysicalInstanceCount: this.confirmedByPhysicalInstance.size,
|
|
84
|
+
matchedQuantity,
|
|
85
|
+
missingQuantity,
|
|
86
|
+
unexpectedQuantity: state.unexpected.length,
|
|
87
|
+
duplicateQuantity: state.duplicate.length,
|
|
88
|
+
...this.counters,
|
|
89
|
+
completionAccuracy: objective === undefined || objective === 0
|
|
90
|
+
? 0
|
|
91
|
+
: Math.min(1, progress / objective),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
onTrack(listener) {
|
|
95
|
+
this.trackListeners.add(listener);
|
|
96
|
+
return () => this.trackListeners.delete(listener);
|
|
97
|
+
}
|
|
98
|
+
onEvent(listener) {
|
|
99
|
+
this.eventListeners.add(listener);
|
|
100
|
+
return () => this.eventListeners.delete(listener);
|
|
101
|
+
}
|
|
102
|
+
/** Apply one complete, frame-level BarcodeTracker update. */
|
|
103
|
+
applyTrackerUpdate(update) {
|
|
104
|
+
if (this.status !== "collecting")
|
|
105
|
+
return;
|
|
106
|
+
const emittedTrackIds = new Set();
|
|
107
|
+
for (const track of update.newTracks) {
|
|
108
|
+
this.upsertTrack(track);
|
|
109
|
+
this.emitTrack({ type: "track-added", track: cloneTrack(track) });
|
|
110
|
+
emittedTrackIds.add(track.trackId);
|
|
111
|
+
}
|
|
112
|
+
for (const track of update.restoredTracks) {
|
|
113
|
+
this.upsertTrack(track);
|
|
114
|
+
this.emitTrack({ type: "track-restored", track: cloneTrack(track) });
|
|
115
|
+
emittedTrackIds.add(track.trackId);
|
|
116
|
+
}
|
|
117
|
+
for (const track of update.lostTracks) {
|
|
118
|
+
this.upsertTrack(track);
|
|
119
|
+
this.emitTrack({ type: "track-lost", trackId: track.trackId, track: cloneTrack(track) });
|
|
120
|
+
emittedTrackIds.add(track.trackId);
|
|
121
|
+
}
|
|
122
|
+
for (const track of update.retiredTracks) {
|
|
123
|
+
this.tracks.delete(track.trackId);
|
|
124
|
+
this.emitTrack({ type: "track-retired", trackId: track.trackId, track: cloneTrack(track) });
|
|
125
|
+
emittedTrackIds.add(track.trackId);
|
|
126
|
+
}
|
|
127
|
+
for (const track of update.updatedTracks) {
|
|
128
|
+
this.upsertTrack(track);
|
|
129
|
+
if (!emittedTrackIds.has(track.trackId)) {
|
|
130
|
+
this.emitTrack({ type: "track-updated", track: cloneTrack(track) });
|
|
131
|
+
emittedTrackIds.add(track.trackId);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// `tracks` is authoritative for the latest non-retired snapshots. This
|
|
135
|
+
// also makes the controller tolerant of tracker implementations that only
|
|
136
|
+
// populate a subset of transition arrays.
|
|
137
|
+
for (const track of update.tracks) {
|
|
138
|
+
const prior = this.tracks.get(track.trackId);
|
|
139
|
+
this.upsertTrack(track);
|
|
140
|
+
if (!prior && !emittedTrackIds.has(track.trackId)) {
|
|
141
|
+
this.emitTrack({ type: "track-added", track: cloneTrack(track) });
|
|
142
|
+
}
|
|
143
|
+
if (track.state === "confirmed")
|
|
144
|
+
this.confirmPhysicalTrack(track);
|
|
145
|
+
}
|
|
146
|
+
this.completeIfSatisfied(update.timestamp);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Convenience for adapters/tests that already own stable tracker snapshots.
|
|
150
|
+
* Each supplied confirmed track is still de-duplicated by physical identity.
|
|
151
|
+
*/
|
|
152
|
+
applyTracks(tracks, timestamp = Date.now()) {
|
|
153
|
+
if (this.status !== "collecting")
|
|
154
|
+
return;
|
|
155
|
+
for (const track of tracks) {
|
|
156
|
+
if (track.state === "retired") {
|
|
157
|
+
this.tracks.delete(track.trackId);
|
|
158
|
+
this.emitTrack({ type: "track-retired", trackId: track.trackId, track: cloneTrack(track) });
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const prior = this.tracks.get(track.trackId);
|
|
162
|
+
this.upsertTrack(track);
|
|
163
|
+
if (!prior)
|
|
164
|
+
this.emitTrack({ type: "track-added", track: cloneTrack(track) });
|
|
165
|
+
else if (prior.state === "lost" && track.state === "confirmed") {
|
|
166
|
+
this.emitTrack({ type: "track-restored", track: cloneTrack(track) });
|
|
167
|
+
}
|
|
168
|
+
else if (prior.state !== "lost" && track.state === "lost") {
|
|
169
|
+
this.emitTrack({ type: "track-lost", trackId: track.trackId, track: cloneTrack(track) });
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
this.emitTrack({ type: "track-updated", track: cloneTrack(track) });
|
|
173
|
+
}
|
|
174
|
+
if (track.state === "confirmed")
|
|
175
|
+
this.confirmPhysicalTrack(track);
|
|
176
|
+
}
|
|
177
|
+
this.completeIfSatisfied(timestamp);
|
|
178
|
+
}
|
|
179
|
+
cancel() {
|
|
180
|
+
if (this.status !== "collecting")
|
|
181
|
+
return;
|
|
182
|
+
this.status = "cancelled";
|
|
183
|
+
this.emit({ type: "batch-cancelled", state: this.getState() });
|
|
184
|
+
}
|
|
185
|
+
fail(error) {
|
|
186
|
+
if (this.status === "complete" || this.status === "failed" || this.status === "cancelled")
|
|
187
|
+
return;
|
|
188
|
+
this.status = "failed";
|
|
189
|
+
this.failureReason = error instanceof Error ? error.message : String(error);
|
|
190
|
+
this.emit({ type: "batch-failed", state: this.getState(), error });
|
|
191
|
+
}
|
|
192
|
+
reset() {
|
|
193
|
+
this.tracks.clear();
|
|
194
|
+
this.confirmedByPhysicalInstance.clear();
|
|
195
|
+
this.unexpectedByPhysicalInstance.clear();
|
|
196
|
+
this.duplicateByPhysicalInstance.clear();
|
|
197
|
+
for (const slot of this.expectedSlots)
|
|
198
|
+
slot.physicalInstanceIds = [];
|
|
199
|
+
this.status = "collecting";
|
|
200
|
+
this.completedAt = undefined;
|
|
201
|
+
this.failureReason = undefined;
|
|
202
|
+
this.counters = {
|
|
203
|
+
trackAddedEvents: 0,
|
|
204
|
+
trackUpdatedEvents: 0,
|
|
205
|
+
trackLostEvents: 0,
|
|
206
|
+
trackRestoredEvents: 0,
|
|
207
|
+
trackRetiredEvents: 0,
|
|
208
|
+
batchCompletedEvents: 0,
|
|
209
|
+
peakRetainedTrackCount: 0,
|
|
210
|
+
peakRetainedPhysicalInstanceCount: 0,
|
|
211
|
+
peakUnexpectedQuantity: 0,
|
|
212
|
+
peakDuplicateQuantity: 0,
|
|
213
|
+
retentionRejectedTrackCount: 0,
|
|
214
|
+
retentionRejectedPhysicalInstanceCount: 0,
|
|
215
|
+
retentionEvictedPhysicalInstanceCount: 0,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Release frame-derived evidence while preserving terminal status and
|
|
220
|
+
* aggregate counters. A subsequent start() calls reset() for a fresh batch.
|
|
221
|
+
*/
|
|
222
|
+
releaseRetainedState() {
|
|
223
|
+
this.tracks.clear();
|
|
224
|
+
this.confirmedByPhysicalInstance.clear();
|
|
225
|
+
this.unexpectedByPhysicalInstance.clear();
|
|
226
|
+
this.duplicateByPhysicalInstance.clear();
|
|
227
|
+
for (const slot of this.expectedSlots)
|
|
228
|
+
slot.physicalInstanceIds = [];
|
|
229
|
+
}
|
|
230
|
+
clear() {
|
|
231
|
+
this.reset();
|
|
232
|
+
this.trackListeners.clear();
|
|
233
|
+
this.eventListeners.clear();
|
|
234
|
+
}
|
|
235
|
+
upsertTrack(track) {
|
|
236
|
+
if (!this.tracks.has(track.trackId) && this.tracks.size >= this.maxRetainedTracks) {
|
|
237
|
+
this.counters.retentionRejectedTrackCount += 1;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.tracks.set(track.trackId, cloneTrack(track));
|
|
241
|
+
const existing = this.confirmedByPhysicalInstance.get(track.physicalInstanceId);
|
|
242
|
+
if (existing)
|
|
243
|
+
this.confirmedByPhysicalInstance.set(track.physicalInstanceId, cloneTrack(track));
|
|
244
|
+
if (this.unexpectedByPhysicalInstance.has(track.physicalInstanceId)) {
|
|
245
|
+
this.unexpectedByPhysicalInstance.set(track.physicalInstanceId, cloneTrack(track));
|
|
246
|
+
}
|
|
247
|
+
if (this.duplicateByPhysicalInstance.has(track.physicalInstanceId)) {
|
|
248
|
+
this.duplicateByPhysicalInstance.set(track.physicalInstanceId, cloneTrack(track));
|
|
249
|
+
}
|
|
250
|
+
this.recordRetentionPeaks();
|
|
251
|
+
}
|
|
252
|
+
confirmPhysicalTrack(track) {
|
|
253
|
+
const physicalInstanceId = track.physicalInstanceId.trim();
|
|
254
|
+
if (!physicalInstanceId)
|
|
255
|
+
throw new Error("A confirmed BarcodeTrack requires a physicalInstanceId.");
|
|
256
|
+
const prior = this.confirmedByPhysicalInstance.get(physicalInstanceId);
|
|
257
|
+
if (prior) {
|
|
258
|
+
if (prior.payload !== track.payload || prior.format !== track.format) {
|
|
259
|
+
throw new Error(`Physical instance ${physicalInstanceId} changed barcode identity.`);
|
|
260
|
+
}
|
|
261
|
+
this.confirmedByPhysicalInstance.set(physicalInstanceId, cloneTrack(track));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const snapshot = cloneTrack(track);
|
|
265
|
+
const classification = this.mode === "checklist" ? this.classifyChecklistTrack(snapshot) : undefined;
|
|
266
|
+
if (this.confirmedByPhysicalInstance.size >= this.maxRetainedPhysicalInstances) {
|
|
267
|
+
const madeRoom = classification?.kind === "matched" && this.evictOldestNonMatchedPhysicalInstance();
|
|
268
|
+
if (!madeRoom) {
|
|
269
|
+
this.counters.retentionRejectedPhysicalInstanceCount += 1;
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
this.confirmedByPhysicalInstance.set(physicalInstanceId, snapshot);
|
|
274
|
+
if (!classification) {
|
|
275
|
+
this.recordRetentionPeaks();
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (classification.kind === "matched") {
|
|
279
|
+
classification.slot.physicalInstanceIds.push(physicalInstanceId);
|
|
280
|
+
this.emit({ type: "item-matched", item: cloneItem(classification.slot.item), track: snapshot });
|
|
281
|
+
}
|
|
282
|
+
else if (classification.kind === "duplicate") {
|
|
283
|
+
this.duplicateByPhysicalInstance.set(physicalInstanceId, snapshot);
|
|
284
|
+
this.emit({ type: "duplicate-item", item: cloneItem(classification.slot.item), track: snapshot });
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
this.unexpectedByPhysicalInstance.set(physicalInstanceId, snapshot);
|
|
288
|
+
this.emit({ type: "unexpected-item", track: snapshot });
|
|
289
|
+
}
|
|
290
|
+
this.recordRetentionPeaks();
|
|
291
|
+
}
|
|
292
|
+
evictOldestNonMatchedPhysicalInstance() {
|
|
293
|
+
for (const physicalInstanceId of this.confirmedByPhysicalInstance.keys()) {
|
|
294
|
+
if (!this.unexpectedByPhysicalInstance.has(physicalInstanceId)
|
|
295
|
+
&& !this.duplicateByPhysicalInstance.has(physicalInstanceId))
|
|
296
|
+
continue;
|
|
297
|
+
this.confirmedByPhysicalInstance.delete(physicalInstanceId);
|
|
298
|
+
this.unexpectedByPhysicalInstance.delete(physicalInstanceId);
|
|
299
|
+
this.duplicateByPhysicalInstance.delete(physicalInstanceId);
|
|
300
|
+
this.counters.retentionEvictedPhysicalInstanceCount += 1;
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
recordRetentionPeaks() {
|
|
306
|
+
this.counters.peakRetainedTrackCount = Math.max(this.counters.peakRetainedTrackCount, this.tracks.size);
|
|
307
|
+
this.counters.peakRetainedPhysicalInstanceCount = Math.max(this.counters.peakRetainedPhysicalInstanceCount, this.confirmedByPhysicalInstance.size);
|
|
308
|
+
this.counters.peakUnexpectedQuantity = Math.max(this.counters.peakUnexpectedQuantity, this.unexpectedByPhysicalInstance.size);
|
|
309
|
+
this.counters.peakDuplicateQuantity = Math.max(this.counters.peakDuplicateQuantity, this.duplicateByPhysicalInstance.size);
|
|
310
|
+
}
|
|
311
|
+
classifyChecklistTrack(track) {
|
|
312
|
+
const candidates = this.expectedSlots
|
|
313
|
+
.filter((slot) => slot.item.payload === track.payload && (slot.item.format === undefined || slot.item.format === track.format))
|
|
314
|
+
.sort((left, right) => Number(right.item.format === track.format) - Number(left.item.format === track.format));
|
|
315
|
+
const available = candidates.find((slot) => slot.physicalInstanceIds.length < slot.quantity);
|
|
316
|
+
if (available)
|
|
317
|
+
return { kind: "matched", slot: available };
|
|
318
|
+
return candidates[0] ? { kind: "duplicate", slot: candidates[0] } : { kind: "unexpected" };
|
|
319
|
+
}
|
|
320
|
+
completeIfSatisfied(timestamp) {
|
|
321
|
+
if (this.status !== "collecting")
|
|
322
|
+
return;
|
|
323
|
+
const complete = this.mode === "checklist"
|
|
324
|
+
? this.expectedSlots.every((slot) => slot.physicalInstanceIds.length === slot.quantity)
|
|
325
|
+
: (this.mode === "expected-count" || this.mode === "unique-physical-instance")
|
|
326
|
+
&& this.expectedCount !== undefined
|
|
327
|
+
&& this.confirmedByPhysicalInstance.size >= this.expectedCount;
|
|
328
|
+
if (!complete)
|
|
329
|
+
return;
|
|
330
|
+
this.status = "complete";
|
|
331
|
+
this.completedAt = timestamp;
|
|
332
|
+
this.counters.batchCompletedEvents += 1;
|
|
333
|
+
this.emit({ type: "batch-completed", state: this.getState() });
|
|
334
|
+
}
|
|
335
|
+
matchedItems() {
|
|
336
|
+
return this.expectedSlots.flatMap((slot) => slot.physicalInstanceIds.flatMap((id) => {
|
|
337
|
+
const track = this.confirmedByPhysicalInstance.get(id);
|
|
338
|
+
return track ? [{ item: cloneItem(slot.item), track: cloneTrack(track) }] : [];
|
|
339
|
+
}));
|
|
340
|
+
}
|
|
341
|
+
missingItems() {
|
|
342
|
+
return this.expectedSlots.flatMap((slot) => {
|
|
343
|
+
const quantity = slot.quantity - slot.physicalInstanceIds.length;
|
|
344
|
+
return quantity > 0 ? [{ item: cloneItem(slot.item), quantity }] : [];
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
emitTrack(event) {
|
|
348
|
+
const counter = `${event.type.replaceAll("-", "")}Events`;
|
|
349
|
+
if (counter === "trackaddedEvents")
|
|
350
|
+
this.counters.trackAddedEvents += 1;
|
|
351
|
+
else if (counter === "trackupdatedEvents")
|
|
352
|
+
this.counters.trackUpdatedEvents += 1;
|
|
353
|
+
else if (counter === "tracklostEvents")
|
|
354
|
+
this.counters.trackLostEvents += 1;
|
|
355
|
+
else if (counter === "trackrestoredEvents")
|
|
356
|
+
this.counters.trackRestoredEvents += 1;
|
|
357
|
+
else if (counter === "trackretiredEvents")
|
|
358
|
+
this.counters.trackRetiredEvents += 1;
|
|
359
|
+
for (const listener of this.trackListeners) {
|
|
360
|
+
try {
|
|
361
|
+
listener(event);
|
|
362
|
+
}
|
|
363
|
+
catch { /* observers do not own batch state */ }
|
|
364
|
+
}
|
|
365
|
+
this.emit(event);
|
|
366
|
+
}
|
|
367
|
+
emit(event) {
|
|
368
|
+
for (const listener of this.eventListeners) {
|
|
369
|
+
try {
|
|
370
|
+
listener(event);
|
|
371
|
+
}
|
|
372
|
+
catch { /* observers do not own batch state */ }
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function validateExpectedCount(mode, value) {
|
|
377
|
+
const required = mode === "expected-count";
|
|
378
|
+
if (value === undefined) {
|
|
379
|
+
if (required)
|
|
380
|
+
throw new RangeError("expected-count mode requires expectedCount.");
|
|
381
|
+
return undefined;
|
|
382
|
+
}
|
|
383
|
+
if (!Number.isInteger(value) || value <= 0)
|
|
384
|
+
throw new RangeError("expectedCount must be a positive integer.");
|
|
385
|
+
return value;
|
|
386
|
+
}
|
|
387
|
+
function validateRetentionLimit(name, value, fallback) {
|
|
388
|
+
const resolved = value ?? fallback;
|
|
389
|
+
if (!Number.isInteger(resolved) || resolved <= 0 || resolved > MAX_BATCH_RETENTION_LIMIT) {
|
|
390
|
+
throw new RangeError(`${name} must be a positive integer no greater than ${MAX_BATCH_RETENTION_LIMIT}.`);
|
|
391
|
+
}
|
|
392
|
+
return resolved;
|
|
393
|
+
}
|
|
394
|
+
function validateExpectedItems(mode, expected) {
|
|
395
|
+
if (mode !== "checklist")
|
|
396
|
+
return [];
|
|
397
|
+
if (!expected?.length)
|
|
398
|
+
throw new RangeError("checklist mode requires at least one expected item.");
|
|
399
|
+
return expected.map((item) => {
|
|
400
|
+
if (!item.payload)
|
|
401
|
+
throw new RangeError("Expected batch item payload must not be empty.");
|
|
402
|
+
const quantity = item.quantity ?? 1;
|
|
403
|
+
if (!Number.isInteger(quantity) || quantity <= 0)
|
|
404
|
+
throw new RangeError("Expected batch item quantity must be a positive integer.");
|
|
405
|
+
return { item: { ...item, quantity }, quantity, physicalInstanceIds: [] };
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
function cloneItem(item) {
|
|
409
|
+
return { ...item };
|
|
410
|
+
}
|
|
411
|
+
function cloneTrack(track) {
|
|
412
|
+
return {
|
|
413
|
+
...track,
|
|
414
|
+
geometry: {
|
|
415
|
+
...track.geometry,
|
|
416
|
+
boundingBox: { ...track.geometry.boundingBox },
|
|
417
|
+
cornerPoints: track.geometry.cornerPoints.map((point) => ({ ...point })),
|
|
418
|
+
},
|
|
419
|
+
...(track.velocity ? { velocity: { ...track.velocity } } : {}),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=batch-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-controller.js","sourceRoot":"","sources":["../../src/batch/batch-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ScannerSession } from "../scanner/scanner-session.js";
|
|
2
|
+
import { BarcodeTracker } from "../tracking/barcode-tracker.js";
|
|
3
|
+
import type { BarcodeObservation, BarcodeTrack, BarcodeTrackerOptions, BarcodeTrackerUpdate, TrackingFrame } from "../tracking/types.js";
|
|
4
|
+
import { type BatchControllerOptions } from "./batch-controller.js";
|
|
5
|
+
import type { BatchEventListener, BatchState, BatchStatistics, BatchUnsubscribe, TrackListener } from "./types.js";
|
|
6
|
+
export interface BatchScanSessionOptions extends BatchControllerOptions {
|
|
7
|
+
/** Existing camera runtime; BatchScanSession never creates a second one. */
|
|
8
|
+
scanner: ScannerSession;
|
|
9
|
+
tracker?: BarcodeTracker;
|
|
10
|
+
trackerOptions?: BarcodeTrackerOptions;
|
|
11
|
+
/** Defaults to true because BatchScanSession owns the delegated lifecycle. */
|
|
12
|
+
disposeScanner?: boolean;
|
|
13
|
+
/** Defaults to true for both injected and internally-created trackers. */
|
|
14
|
+
disposeTracker?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* ScannerSession + BarcodeTracker + BatchController composition. React and
|
|
18
|
+
* other UI layers only subscribe to the resulting SDK state.
|
|
19
|
+
*/
|
|
20
|
+
export declare class BatchScanSession {
|
|
21
|
+
private readonly scanner;
|
|
22
|
+
private readonly tracker;
|
|
23
|
+
private readonly controller;
|
|
24
|
+
private readonly disposeScanner;
|
|
25
|
+
private readonly disposeTracker;
|
|
26
|
+
private readonly subscriptions;
|
|
27
|
+
private readonly pendingScannerFrames;
|
|
28
|
+
private generation;
|
|
29
|
+
private stopRequested;
|
|
30
|
+
private disposed;
|
|
31
|
+
constructor(options: BatchScanSessionOptions);
|
|
32
|
+
start(): Promise<void>;
|
|
33
|
+
pause(): void;
|
|
34
|
+
resume(): void;
|
|
35
|
+
stop(): Promise<void>;
|
|
36
|
+
dispose(): Promise<void>;
|
|
37
|
+
getTracks(): readonly BarcodeTrack[];
|
|
38
|
+
getBatchState(): BatchState;
|
|
39
|
+
getStatistics(): BatchStatistics;
|
|
40
|
+
onTrack(listener: TrackListener): BatchUnsubscribe;
|
|
41
|
+
onBatchEvent(listener: BatchEventListener): BatchUnsubscribe;
|
|
42
|
+
/** Explicit frame API used by deterministic runtimes and custom capture adapters. */
|
|
43
|
+
processFrame(observations: readonly BarcodeObservation[], frame: TrackingFrame): BarcodeTrackerUpdate;
|
|
44
|
+
/** Accept an update from an externally-driven instance of the same tracker. */
|
|
45
|
+
applyTrackerUpdate(update: BarcodeTrackerUpdate): void;
|
|
46
|
+
private observeScannerDiagnostic;
|
|
47
|
+
private observeScannerObservationSet;
|
|
48
|
+
private flushScannerFrame;
|
|
49
|
+
private observeScannerState;
|
|
50
|
+
private invalidatePendingFrames;
|
|
51
|
+
private assertUsable;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=batch-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-session.d.ts","sourceRoot":"","sources":["../../src/batch/batch-session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAmB,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,KAAK,EACV,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,4EAA4E;IAC5E,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,8EAA8E;IAC9E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AASD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA0C;IAC/E,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE,uBAAuB;IAYtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B,KAAK,IAAI,IAAI;IAMb,MAAM,IAAI,IAAI;IAKR,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC9B,SAAS,IAAI,SAAS,YAAY,EAAE;IAIpC,aAAa,IAAI,UAAU;IAI3B,aAAa,IAAI,eAAe;IAIhC,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,gBAAgB;IAIlD,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,gBAAgB;IAI5D,qFAAqF;IACrF,YAAY,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,EAAE,KAAK,EAAE,aAAa,GAAG,oBAAoB;IAOrG,+EAA+E;IAC/E,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAKtD,OAAO,CAAC,wBAAwB;IA2BhC,OAAO,CAAC,4BAA4B;IAcpC,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,YAAY;CAGrB"}
|