@3deye-toolkit/react-event-search 0.0.1 → 0.0.3-alpha.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/react-event-search.css +228 -825
- package/dist/react-event-search.d.ts +449 -102
- package/dist/react-event-search.js +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +17 -18
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
|
|
3
1
|
import { BehaviorSubject } from 'rxjs';
|
|
4
2
|
import crossfilter from 'crossfilter2';
|
|
5
3
|
import type { IReactionDisposer } from 'mobx';
|
|
@@ -7,6 +5,7 @@ import { Observable } from 'rxjs';
|
|
|
7
5
|
import { default as React_2 } from 'react';
|
|
8
6
|
import { Subject } from 'rxjs';
|
|
9
7
|
import { Subscription } from 'rxjs';
|
|
8
|
+
import { z } from 'zod';
|
|
10
9
|
|
|
11
10
|
declare class AccountStore extends ApiStore {
|
|
12
11
|
private notification?;
|
|
@@ -26,13 +25,68 @@ declare class AccountStore extends ApiStore {
|
|
|
26
25
|
firstName: string;
|
|
27
26
|
lastName: string;
|
|
28
27
|
}): Observable<RawUser>;
|
|
29
|
-
|
|
28
|
+
updateUserLanguage(languageCode: string): Observable<RawUser>;
|
|
29
|
+
updateCustomPreferences: (preferences: Partial<Preferences>) => Observable<RawUser>;
|
|
30
30
|
setDefaultGroup(groupId: number): Observable<RawUser> | undefined;
|
|
31
|
-
|
|
31
|
+
get preferences(): Preferences;
|
|
32
|
+
getPreference: <T extends PREFERENCES>(key: T) => {
|
|
33
|
+
utc: boolean;
|
|
34
|
+
hour12: boolean;
|
|
35
|
+
startOfWeek: "monday" | "sunday";
|
|
36
|
+
defaultVideoResizeMode?: VideoResizeMode | undefined;
|
|
37
|
+
camerasResizeMode?: [number, VideoResizeMode][] | undefined;
|
|
38
|
+
fisheyeCameras?: [number, [number, number, number] | {
|
|
39
|
+
params: {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
r: number;
|
|
43
|
+
s: number;
|
|
44
|
+
};
|
|
45
|
+
positions?: [{
|
|
46
|
+
lat: number;
|
|
47
|
+
lon: number;
|
|
48
|
+
fov: number;
|
|
49
|
+
}, {
|
|
50
|
+
lat: number;
|
|
51
|
+
lon: number;
|
|
52
|
+
fov: number;
|
|
53
|
+
}, {
|
|
54
|
+
lat: number;
|
|
55
|
+
lon: number;
|
|
56
|
+
fov: number;
|
|
57
|
+
}] | undefined;
|
|
58
|
+
} | null][] | undefined;
|
|
59
|
+
}[T];
|
|
32
60
|
private retryOnVersionMismatch;
|
|
33
61
|
}
|
|
34
62
|
|
|
35
|
-
declare class
|
|
63
|
+
declare class AllEventsLoaderFilters implements EventsLoaderFilters {
|
|
64
|
+
from: Date | null;
|
|
65
|
+
to: Date | null;
|
|
66
|
+
probabilityThreshold: number | null;
|
|
67
|
+
cameras: number[];
|
|
68
|
+
detectedObjects: string[];
|
|
69
|
+
colors: Set<string>;
|
|
70
|
+
regions: {
|
|
71
|
+
x: number;
|
|
72
|
+
y: number;
|
|
73
|
+
}[][] | null;
|
|
74
|
+
eventTypes: SensorEventType[];
|
|
75
|
+
sortDirection: 'ASC' | 'DESC';
|
|
76
|
+
updated$: Subject<null>;
|
|
77
|
+
get regionsWkt(): string[];
|
|
78
|
+
constructor();
|
|
79
|
+
apply(data: CameraEvent[]): CameraEvent[];
|
|
80
|
+
get filterJson(): string | null;
|
|
81
|
+
/**
|
|
82
|
+
* given region as array of vertices in normalized coordinates
|
|
83
|
+
* returns its representation in WKT: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry
|
|
84
|
+
* @param region
|
|
85
|
+
*/
|
|
86
|
+
private regionToWktPolygon;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
declare class Api<T extends DeepPartial<IApi>> {
|
|
36
90
|
[key: string]: any;
|
|
37
91
|
static create<T extends PartialApi>(apiConfig: T | null, authStore: Auth, createConnection: (accessToken: string) => Connection): Api<T> & ExtractHubs<IApi, T>;
|
|
38
92
|
connectionShutdown$: Subject<null>;
|
|
@@ -178,6 +232,7 @@ declare class Auth {
|
|
|
178
232
|
agreedWithTerms?: boolean;
|
|
179
233
|
code?: string;
|
|
180
234
|
}) => Promise<Token> | undefined;
|
|
235
|
+
signInWithToken: (token: RawToken) => void;
|
|
181
236
|
invalidateToken: () => void;
|
|
182
237
|
getTokenFromStorage(): Promise<Token | null>;
|
|
183
238
|
private storeToken;
|
|
@@ -195,6 +250,13 @@ declare interface AuthStoreOptions {
|
|
|
195
250
|
clientId: string;
|
|
196
251
|
}
|
|
197
252
|
|
|
253
|
+
declare interface BoundingBox {
|
|
254
|
+
Left: number;
|
|
255
|
+
Top: number;
|
|
256
|
+
Right: number;
|
|
257
|
+
Bottom: number;
|
|
258
|
+
}
|
|
259
|
+
|
|
198
260
|
declare interface Box {
|
|
199
261
|
Top: number;
|
|
200
262
|
Left: number;
|
|
@@ -208,10 +270,7 @@ declare class Camera {
|
|
|
208
270
|
imageUrl: string;
|
|
209
271
|
streamUrl: string;
|
|
210
272
|
dashStreamUrl: string;
|
|
211
|
-
address:
|
|
212
|
-
Lat: number;
|
|
213
|
-
Lng: number;
|
|
214
|
-
} | null;
|
|
273
|
+
address: CameraAddress | null;
|
|
215
274
|
archiveDuration: number;
|
|
216
275
|
dvrWindowLength: number;
|
|
217
276
|
stateUpdatedAt: Date;
|
|
@@ -227,31 +286,56 @@ declare class Camera {
|
|
|
227
286
|
get supportsWebRTC(): boolean;
|
|
228
287
|
constructor(raw: RawCamera);
|
|
229
288
|
update: (raw: RawCamera) => void;
|
|
289
|
+
can: (permission: CameraPermissions) => number;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
declare interface CameraAddress {
|
|
293
|
+
Lat: number;
|
|
294
|
+
Lng: number;
|
|
295
|
+
Country: string;
|
|
296
|
+
State: string;
|
|
297
|
+
City: string;
|
|
298
|
+
Address: string;
|
|
230
299
|
}
|
|
231
300
|
|
|
232
301
|
declare class CameraEvent {
|
|
302
|
+
id: number;
|
|
233
303
|
cameraId: number;
|
|
234
304
|
type: EventType;
|
|
235
305
|
raw: RawSensorEvent;
|
|
236
306
|
thumbnailUrl: string;
|
|
307
|
+
thumbnailWidth: number;
|
|
308
|
+
thumbnailHeight: number;
|
|
237
309
|
detectedObjects: DetectedObject[];
|
|
238
310
|
faces: Face[];
|
|
239
311
|
instant: boolean;
|
|
240
|
-
get id(): number;
|
|
241
312
|
get startTime(): Date;
|
|
242
313
|
get endTime(): Date;
|
|
243
314
|
get isLive(): boolean;
|
|
244
315
|
get acknowledged(): boolean;
|
|
316
|
+
update: (raw: RawSensorEvent) => void;
|
|
245
317
|
constructor(raw: RawSensorEvent);
|
|
246
318
|
}
|
|
247
319
|
|
|
320
|
+
declare const enum CameraPermissions {
|
|
321
|
+
View = 1,
|
|
322
|
+
SaveClip = 2,
|
|
323
|
+
Share = 4,
|
|
324
|
+
Ptz = 8,
|
|
325
|
+
EditSettings = 16,
|
|
326
|
+
Timelapse = 32,
|
|
327
|
+
Delete = 64
|
|
328
|
+
}
|
|
329
|
+
|
|
248
330
|
declare class CamerasStore extends ApiStore {
|
|
249
331
|
camerasById: Map<number, Camera>;
|
|
250
332
|
data: Camera[];
|
|
251
333
|
loading: boolean;
|
|
252
334
|
loaded: boolean;
|
|
335
|
+
pendingLoadRequest?: Observable<RawCamera[]>;
|
|
336
|
+
requestsCanceler: Subject<void>;
|
|
253
337
|
constructor();
|
|
254
|
-
load: () => Observable<RawCamera[]
|
|
338
|
+
load: () => Observable<RawCamera[]>;
|
|
255
339
|
add: (cameras: RawCamera[]) => void;
|
|
256
340
|
sync: () => Observable<RawCamera[]>;
|
|
257
341
|
protected afterInit(): void;
|
|
@@ -271,6 +355,16 @@ declare interface CamgroupItem {
|
|
|
271
355
|
order: number;
|
|
272
356
|
}
|
|
273
357
|
|
|
358
|
+
declare interface Car {
|
|
359
|
+
Type: 'Car';
|
|
360
|
+
BodyType?: string;
|
|
361
|
+
Box: BoundingBox;
|
|
362
|
+
Probability: number;
|
|
363
|
+
Colors?: {
|
|
364
|
+
Color: string;
|
|
365
|
+
}[];
|
|
366
|
+
}
|
|
367
|
+
|
|
274
368
|
declare interface Chunk {
|
|
275
369
|
json?: string;
|
|
276
370
|
startTime: Date;
|
|
@@ -285,6 +379,44 @@ declare interface ChunksQuery {
|
|
|
285
379
|
to: Date;
|
|
286
380
|
}
|
|
287
381
|
|
|
382
|
+
declare class Clip {
|
|
383
|
+
id: number;
|
|
384
|
+
cameraId: number;
|
|
385
|
+
name: string;
|
|
386
|
+
startTime: Date;
|
|
387
|
+
endTime: Date;
|
|
388
|
+
type: 'Archive' | 'Timelaps' | 'Timelaps to do';
|
|
389
|
+
createdAt: Date;
|
|
390
|
+
/**
|
|
391
|
+
* clip duration in seconds
|
|
392
|
+
*/
|
|
393
|
+
duration: number;
|
|
394
|
+
chunks: ArchiveChunk[];
|
|
395
|
+
clipUrl?: string;
|
|
396
|
+
description: string;
|
|
397
|
+
version: string;
|
|
398
|
+
raw: RawClip;
|
|
399
|
+
isDownloading: boolean;
|
|
400
|
+
archives?: ArchiveChunk[];
|
|
401
|
+
constructor(raw: RawClip);
|
|
402
|
+
get isTimelapse(): boolean;
|
|
403
|
+
update(raw: RawClip): void;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
declare interface ClipParams {
|
|
407
|
+
cameraId: number;
|
|
408
|
+
startTime: Date;
|
|
409
|
+
endTime: Date;
|
|
410
|
+
name: string;
|
|
411
|
+
description?: string;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
declare interface ClipsQuery {
|
|
415
|
+
cameraId: number;
|
|
416
|
+
from: Date;
|
|
417
|
+
to: Date;
|
|
418
|
+
}
|
|
419
|
+
|
|
288
420
|
declare interface Connection {
|
|
289
421
|
state: CONNECTION_STATE;
|
|
290
422
|
stop: () => void;
|
|
@@ -321,21 +453,14 @@ declare type DeepPartial<T> = {
|
|
|
321
453
|
[K in keyof T]?: DeepPartial<T[K]>;
|
|
322
454
|
};
|
|
323
455
|
|
|
324
|
-
declare
|
|
325
|
-
Type:
|
|
326
|
-
|
|
327
|
-
Number?: string;
|
|
328
|
-
Box: {
|
|
329
|
-
Left: number;
|
|
330
|
-
Top: number;
|
|
331
|
-
Right: number;
|
|
332
|
-
Bottom: number;
|
|
333
|
-
};
|
|
456
|
+
declare type DetectedObject = Car | LicensePlate | {
|
|
457
|
+
Type: 'Person' | 'Animal' | 'Bicycle' | 'Luggage' | 'Boat' | 'HardHat' | 'NoHardHat' | 'Fire' | 'Smoke' | 'Face';
|
|
458
|
+
Box: BoundingBox;
|
|
334
459
|
Probability: number;
|
|
335
460
|
Colors?: {
|
|
336
461
|
Color: string;
|
|
337
462
|
}[];
|
|
338
|
-
}
|
|
463
|
+
};
|
|
339
464
|
|
|
340
465
|
declare interface DetectedObjectOption {
|
|
341
466
|
id: string;
|
|
@@ -369,14 +494,15 @@ export default EventSearch;
|
|
|
369
494
|
declare class EventSearchStore extends ApiStore {
|
|
370
495
|
eventSchema: EventSchemaStore;
|
|
371
496
|
events: EventsStore;
|
|
497
|
+
private account;
|
|
372
498
|
private notification;
|
|
373
499
|
private heatmaps?;
|
|
374
500
|
api: ExtendedApi;
|
|
375
501
|
disposables: (IReactionDisposer | Subscription)[];
|
|
376
502
|
readonly analyticsEnabled: boolean;
|
|
377
|
-
disposeReactionToCamera: any;
|
|
378
503
|
cameraId: number | null;
|
|
379
504
|
date: Date | null;
|
|
505
|
+
get startTime(): Date | null;
|
|
380
506
|
regions: {
|
|
381
507
|
x: number;
|
|
382
508
|
y: number;
|
|
@@ -388,14 +514,22 @@ declare class EventSearchStore extends ApiStore {
|
|
|
388
514
|
heatmapLoading: boolean;
|
|
389
515
|
data: CameraEvent[];
|
|
390
516
|
heatmap: Heatmap | null;
|
|
391
|
-
peopleCountingData:
|
|
517
|
+
peopleCountingData: RawPeopleCountingData[];
|
|
392
518
|
probabilityThreshold: number;
|
|
393
519
|
brushFilter: null | [Date, Date];
|
|
520
|
+
loadTrigger: number;
|
|
394
521
|
eventsLoader: EventsLoader;
|
|
522
|
+
loaderFilters: AllEventsLoaderFilters;
|
|
395
523
|
get params(): SchemaDescriptionParameter[];
|
|
396
524
|
get filteredData(): CameraEvent[];
|
|
397
|
-
get filteredPeopleCountingData():
|
|
398
|
-
constructor(eventSchema: EventSchemaStore, events: EventsStore, notification: NotificationService, heatmaps?: HeatmapsStore | undefined);
|
|
525
|
+
get filteredPeopleCountingData(): RawPeopleCountingData[];
|
|
526
|
+
constructor(eventSchema: EventSchemaStore, events: EventsStore, account: AccountStore, notification: NotificationService, heatmaps?: HeatmapsStore | undefined);
|
|
527
|
+
/**
|
|
528
|
+
* Converts box (Top, Left, Bottom, Right) to axis-aligned bounding box
|
|
529
|
+
* @param box
|
|
530
|
+
* @returns
|
|
531
|
+
*/
|
|
532
|
+
private boxToAabb;
|
|
399
533
|
setDate: (value: Date) => void;
|
|
400
534
|
setFilters: (filters: DetectedObjectOption[]) => void;
|
|
401
535
|
getProbabilityThreshold: () => number;
|
|
@@ -405,8 +539,8 @@ declare class EventSearchStore extends ApiStore {
|
|
|
405
539
|
cameraId: number;
|
|
406
540
|
box: Box;
|
|
407
541
|
}) => void;
|
|
408
|
-
openForPlayer: (cameraId: number) => void;
|
|
409
542
|
searchFullFrame: (cameraId: number) => void;
|
|
543
|
+
triggerLoad: () => void;
|
|
410
544
|
setRegions: (polies: {
|
|
411
545
|
x: number;
|
|
412
546
|
y: number;
|
|
@@ -431,8 +565,12 @@ declare class EventSearchStore extends ApiStore {
|
|
|
431
565
|
|
|
432
566
|
declare class EventsLoader extends ApiStore {
|
|
433
567
|
private eventsStore;
|
|
434
|
-
|
|
435
|
-
api:
|
|
568
|
+
filters: EventsLoaderFilters;
|
|
569
|
+
fetcher: (api: Api<IApi> & IApi, pageToken?: number) => Observable<ApiPageResult<RawSensorEvent>>;
|
|
570
|
+
transformData: (data: CameraEvent) => {
|
|
571
|
+
data: CameraEvent;
|
|
572
|
+
objectIdx: number;
|
|
573
|
+
}[];
|
|
436
574
|
data: {
|
|
437
575
|
data: CameraEvent;
|
|
438
576
|
objectIdx: number;
|
|
@@ -442,49 +580,28 @@ declare class EventsLoader extends ApiStore {
|
|
|
442
580
|
objectIdx: number;
|
|
443
581
|
}[];
|
|
444
582
|
liveUpdateMode: 'manual' | 'auto' | 'disabled';
|
|
445
|
-
updateTrigger: number;
|
|
446
|
-
colors: Set<string>;
|
|
447
583
|
disposables: (IReactionDisposer | Subscription)[];
|
|
448
584
|
pageInfo: PageInfo_2 | null;
|
|
449
585
|
loading: boolean;
|
|
450
586
|
loadMoreTrigger: number;
|
|
451
587
|
retryTrigger: number;
|
|
452
588
|
error: Error | null;
|
|
453
|
-
|
|
454
|
-
probabilityThreshold: null | number;
|
|
455
|
-
from?: Date;
|
|
456
|
-
to?: Date;
|
|
457
|
-
cameras: number[];
|
|
458
|
-
detectedObjects: string[];
|
|
459
|
-
regions: {
|
|
460
|
-
x: number;
|
|
461
|
-
y: number;
|
|
462
|
-
}[][] | null;
|
|
463
|
-
eventTypes: SensorEventType[];
|
|
464
|
-
private loadingInited;
|
|
589
|
+
private loadingInitiated;
|
|
465
590
|
get isLive(): boolean;
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
591
|
+
constructor(eventsStore: EventsStore, filters: EventsLoaderFilters, fetcher: (api: Api<IApi> & IApi, pageToken?: number) => Observable<ApiPageResult<RawSensorEvent>>, transformData?: (data: CameraEvent) => {
|
|
592
|
+
data: CameraEvent;
|
|
593
|
+
objectIdx: number;
|
|
594
|
+
}[]);
|
|
469
595
|
flushUpdates: () => void;
|
|
470
596
|
setLiveUpdateMode: (mode: 'manual' | 'auto' | 'disabled') => void;
|
|
471
597
|
load: () => void;
|
|
472
598
|
reload: () => void;
|
|
473
599
|
loadMore: () => void;
|
|
474
|
-
private
|
|
600
|
+
private queryEvents;
|
|
475
601
|
private initDataLoading;
|
|
476
602
|
private initLiveUpdates;
|
|
477
|
-
private filter;
|
|
478
|
-
private toObjects;
|
|
479
|
-
private boxToAabb;
|
|
480
603
|
/**
|
|
481
|
-
*
|
|
482
|
-
* returns its representation in WKT: https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry
|
|
483
|
-
* @param region
|
|
484
|
-
*/
|
|
485
|
-
private regionToWktPolygon;
|
|
486
|
-
/**
|
|
487
|
-
* Joins to arrays leaving only unique events
|
|
604
|
+
* Joins two arrays leaving only unique events
|
|
488
605
|
* TODO: check if using map only on joint is more efficient
|
|
489
606
|
*
|
|
490
607
|
* requested events current data
|
|
@@ -497,6 +614,16 @@ declare class EventsLoader extends ApiStore {
|
|
|
497
614
|
dispose(): void;
|
|
498
615
|
}
|
|
499
616
|
|
|
617
|
+
declare interface EventsLoaderFilters {
|
|
618
|
+
updated$: Observable<null>;
|
|
619
|
+
sortDirection: 'ASC' | 'DESC';
|
|
620
|
+
cameras: number[];
|
|
621
|
+
from: Date | null;
|
|
622
|
+
to: Date | null;
|
|
623
|
+
probabilityThreshold: number | null;
|
|
624
|
+
apply: (events: CameraEvent[]) => CameraEvent[];
|
|
625
|
+
}
|
|
626
|
+
|
|
500
627
|
declare interface EventsQuery {
|
|
501
628
|
cameraIds?: number[];
|
|
502
629
|
eventTypes?: EventType[];
|
|
@@ -521,10 +648,10 @@ declare class EventsStore extends ApiStore {
|
|
|
521
648
|
pendingRequestsByEnd: crossfilter.Dimension<PendingRequest, number>;
|
|
522
649
|
pendingRequestsByStart: crossfilter.Dimension<PendingRequest, number>;
|
|
523
650
|
pendingRequestsByCameraId: crossfilter.Dimension<PendingRequest, number>;
|
|
524
|
-
knownIntervals: crossfilter.Crossfilter<
|
|
525
|
-
knownIntervalsByCameraId: crossfilter.Dimension<
|
|
526
|
-
knownIntervalsByStart: crossfilter.Dimension<
|
|
527
|
-
knownIntervalsByEnd: crossfilter.Dimension<
|
|
651
|
+
knownIntervals: crossfilter.Crossfilter<Interval>;
|
|
652
|
+
knownIntervalsByCameraId: crossfilter.Dimension<Interval, number>;
|
|
653
|
+
knownIntervalsByStart: crossfilter.Dimension<Interval, number>;
|
|
654
|
+
knownIntervalsByEnd: crossfilter.Dimension<Interval, number>;
|
|
528
655
|
eventsById: Map<number, CameraEvent>;
|
|
529
656
|
updates: number;
|
|
530
657
|
/**
|
|
@@ -581,14 +708,9 @@ declare class EventsStore extends ApiStore {
|
|
|
581
708
|
dispose(): void;
|
|
582
709
|
}
|
|
583
710
|
|
|
584
|
-
declare type EventType = 'Motion' | 'Tampering' | 'PanTiltZoom' | 'CrossLine' | 'Intrusion' | 'LicensePlate' | 'FaceDetection' | 'Audio' | 'Analytic' | 'SpeedDetection' | 'PeopleCounter' | 'Temperature' | 'PoS' | 'GPS' | 'DigitalInput' | 'Normal' | 'Suspicious' | 'Loitering' | 'Vandalism' | 'Trespass' | 'Emergency' | 'LifeInDanger' | 'ErroneousAlert' | 'Misidentification' | 'Fire' | 'MedicalDuress' | 'HoldUp' | 'CheckIn' | 'CheckOut' | 'ClockIn' | 'ClockOut' | 'ParkingStart' | 'ParkingEnd' | 'ParkingViolation' | 'GateAccess' | 'DoorAccess' | 'TemperatureCheck' | 'IDCheck' | 'PPECheck' | 'WelfareCheck' | '
|
|
711
|
+
declare type EventType = 'Motion' | 'Tampering' | 'PanTiltZoom' | 'CrossLine' | 'Intrusion' | 'LicensePlate' | 'FaceDetection' | 'Audio' | 'Analytic' | 'SpeedDetection' | 'PeopleCounter' | 'Temperature' | 'PoS' | 'GPS' | 'DigitalInput' | 'Normal' | 'Suspicious' | 'Loitering' | 'Vandalism' | 'Trespass' | 'Emergency' | 'LifeInDanger' | 'ErroneousAlert' | 'Misidentification' | 'Fire' | 'MedicalDuress' | 'HoldUp' | 'CheckIn' | 'CheckOut' | 'ClockIn' | 'ClockOut' | 'ParkingStart' | 'ParkingEnd' | 'ParkingViolation' | 'GateAccess' | 'DoorAccess' | 'TemperatureCheck' | 'IDCheck' | 'PPECheck' | 'WelfareCheck' | 'VehicleBreakIn' | 'DrugTrafficking' | 'Assault' | 'PackageDelivery' | 'Uncategorized';
|
|
585
712
|
|
|
586
713
|
declare type ExtendedApi = Api<IApi> & IApi & {
|
|
587
|
-
cameras: {
|
|
588
|
-
GetPeopleCountingData: (cameraId: number, startTime: Date, endTime: Date, box: Box) => Observable<ApiResult<RawPeopleContingData>>;
|
|
589
|
-
GetLicensePlateLookUp: (value: string, limit: number) => Observable<ApiResult<string>>;
|
|
590
|
-
GetSensorEventsLprPage: (query: object, plates: string[]) => Observable<any>;
|
|
591
|
-
};
|
|
592
714
|
archives: {
|
|
593
715
|
GetLongLastingTimeLaps: (cameraId: number) => Observable<any>;
|
|
594
716
|
};
|
|
@@ -637,7 +759,6 @@ declare class Heatmap {
|
|
|
637
759
|
declare type HeatmapMode = 'fullframe' | 'selection' | 'none';
|
|
638
760
|
|
|
639
761
|
declare class HeatmapsStore extends ApiStore {
|
|
640
|
-
api: ExtendedApi;
|
|
641
762
|
fetchHeatmaps(cameraId: number, from: Date, to: Date, count: number): Observable<Heatmap[]>;
|
|
642
763
|
}
|
|
643
764
|
|
|
@@ -654,9 +775,13 @@ declare interface IApi {
|
|
|
654
775
|
DeleteClip: (params: any) => Observable<any>;
|
|
655
776
|
SaveClip: (params: any) => Observable<any>;
|
|
656
777
|
SaveTimelaps: (params: any) => Observable<any>;
|
|
657
|
-
SaveArchive: (params: any) => Observable<
|
|
658
|
-
DeleteArchive: (params:
|
|
659
|
-
|
|
778
|
+
SaveArchive: (params: any) => Observable<ApiResult<RawClip>>;
|
|
779
|
+
DeleteArchive: (params: {
|
|
780
|
+
id: number;
|
|
781
|
+
cameraId: number;
|
|
782
|
+
version: string;
|
|
783
|
+
}) => Observable<ApiResult<RawClip>>;
|
|
784
|
+
ShareClip: (sharedClip: PartialExcept<RawSharedClip, 'name' | 'description' | 'recordId' | 'validTo'>) => Observable<ApiResult<RawSharedClip>>;
|
|
660
785
|
GetSharedClips: (recordId: number | null) => Observable<ApiResult<RawSharedClip>>;
|
|
661
786
|
UpdateSharedClip: (sharedClip: RawSharedClip) => Observable<ApiResult<RawSharedClip>>;
|
|
662
787
|
DeleteSharedClip: (recordId: number) => Observable<ApiResult<RawSharedClip>>;
|
|
@@ -669,6 +794,9 @@ declare interface IApi {
|
|
|
669
794
|
GetSensorDataSchema: (eventType: EventType) => Observable<any>;
|
|
670
795
|
GetSensorEvents: (params: SensorEventsParams, filter: string, box: Box) => Observable<ApiResult<RawSensorEvent>>;
|
|
671
796
|
GetSensorEventsPage: (request: SensorEventsRequest, filter: string | null, searchPolygons: string[]) => Observable<ApiPageResult<RawSensorEvent>>;
|
|
797
|
+
GetPeopleCountingData: (cameraId: number, startTime: Date, endTime: Date, box: Box) => Observable<ApiResult<RawPeopleCountingData>>;
|
|
798
|
+
GetLicensePlateLookUp: (value: string, limit: number) => Observable<ApiResult<string>>;
|
|
799
|
+
GetSensorEventsLprPage: (query: object, plates: string[]) => Observable<ApiPageResult<RawSensorEvent>>;
|
|
672
800
|
AddUserSensorEvent: (event: PartialExcept<RawSensorEvent, 'id' | 'eventType' | 'message'>) => Observable<ApiResult<RawSensorEvent>>;
|
|
673
801
|
AcknowledgeSensorEvent: (event: PartialExcept<RawSensorEvent, 'id' | 'ackEventType' | 'message'>) => Observable<ApiResult<RawSensorEvent>>;
|
|
674
802
|
MoveCamera: (camera: {
|
|
@@ -702,18 +830,18 @@ declare interface IApi {
|
|
|
702
830
|
from: Date;
|
|
703
831
|
to: Date;
|
|
704
832
|
count: number;
|
|
705
|
-
}) => Observable<
|
|
833
|
+
}) => Observable<ApiResult<RawThumbnail>>;
|
|
706
834
|
GetThumbnailInfo: (params: {
|
|
707
835
|
cameraId: number;
|
|
708
836
|
from: Date;
|
|
709
837
|
to: Date;
|
|
710
|
-
}) => Observable<
|
|
838
|
+
}) => Observable<ApiResult<RawThumbnail>>;
|
|
711
839
|
GetHeatMapsInfo: (params: {
|
|
712
840
|
cameraId: number;
|
|
713
841
|
from: Date;
|
|
714
842
|
to: Date;
|
|
715
843
|
count: number;
|
|
716
|
-
}) => Observable<
|
|
844
|
+
}) => Observable<ApiResult<RawHeatmap>>;
|
|
717
845
|
};
|
|
718
846
|
users: {
|
|
719
847
|
GetUser: () => Observable<ApiResult<RawUser>>;
|
|
@@ -732,22 +860,67 @@ declare interface InitParams {
|
|
|
732
860
|
tokenServiceUrl?: string;
|
|
733
861
|
}
|
|
734
862
|
|
|
735
|
-
declare interface
|
|
863
|
+
declare interface Interval {
|
|
736
864
|
cameraId: number;
|
|
737
865
|
from: Date;
|
|
738
866
|
to: Date;
|
|
739
867
|
}
|
|
740
868
|
|
|
741
869
|
declare type IntervalState = {
|
|
742
|
-
state: '
|
|
870
|
+
state: 'fulfilled';
|
|
743
871
|
data: Thumbnail;
|
|
744
872
|
} | {
|
|
745
873
|
state: 'pending';
|
|
746
|
-
request: Observable<
|
|
874
|
+
request: Observable<Thumbnail[]>;
|
|
747
875
|
};
|
|
748
876
|
|
|
877
|
+
declare class LibraryStore extends ApiStore {
|
|
878
|
+
private notification?;
|
|
879
|
+
data: crossfilter.Crossfilter<Clip>;
|
|
880
|
+
clipsByCameraId: crossfilter.Dimension<Clip, number>;
|
|
881
|
+
clipsByCreationDate: crossfilter.Dimension<Clip, number>;
|
|
882
|
+
clipsByStart: crossfilter.Dimension<Clip, number>;
|
|
883
|
+
clipsByEnd: crossfilter.Dimension<Clip, number>;
|
|
884
|
+
clipsByType: crossfilter.Dimension<Clip, string>;
|
|
885
|
+
clipsById: crossfilter.Dimension<Clip, number>;
|
|
886
|
+
clipsMap: Map<number, Clip>;
|
|
887
|
+
loaded: boolean;
|
|
888
|
+
loading: boolean;
|
|
889
|
+
updates: number;
|
|
890
|
+
constructor(notification?: NotificationService | undefined);
|
|
891
|
+
/**
|
|
892
|
+
* Fetches all clips from the server and updates the store
|
|
893
|
+
*/
|
|
894
|
+
fetch(): Observable<Clip[]>;
|
|
895
|
+
add: (clips: Clip[]) => void;
|
|
896
|
+
addOrUpdate: (clips: Clip[]) => void;
|
|
897
|
+
removeFromStore: (clips: {
|
|
898
|
+
id: number;
|
|
899
|
+
}[]) => void;
|
|
900
|
+
getClips({ cameraId, from, to }: ClipsQuery): Clip[];
|
|
901
|
+
getTimelapses(): Clip[];
|
|
902
|
+
getRecentlyAdded(): Clip[];
|
|
903
|
+
all(): Clip[];
|
|
904
|
+
getOnly(type: 'clips' | 'timelapses' | null, sortDirection?: 'asc' | 'desc'): Clip[];
|
|
905
|
+
createClip: (data: ClipParams) => void;
|
|
906
|
+
createTimelapse: (data: TimelapseParams) => void;
|
|
907
|
+
rename(clip: Clip, name: string): void;
|
|
908
|
+
delete(clip: Clip): void;
|
|
909
|
+
protected afterInit(): void;
|
|
910
|
+
dispose(): void;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
declare interface LicensePlate {
|
|
914
|
+
Type: 'LicensePlate';
|
|
915
|
+
Value: string;
|
|
916
|
+
Number: string;
|
|
917
|
+
ParentIndex: number;
|
|
918
|
+
Box: BoundingBox;
|
|
919
|
+
Probability: number;
|
|
920
|
+
}
|
|
921
|
+
|
|
749
922
|
declare interface NotificationOptions_2 {
|
|
750
|
-
|
|
923
|
+
duration: number;
|
|
751
924
|
}
|
|
752
925
|
|
|
753
926
|
declare class NotificationService implements Notifier {
|
|
@@ -810,9 +983,177 @@ declare interface PendingRequest_2 {
|
|
|
810
983
|
from: Date;
|
|
811
984
|
to: Date;
|
|
812
985
|
count: number;
|
|
813
|
-
request: Observable<
|
|
986
|
+
request: Observable<Thumbnail[]>;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
declare enum PREFERENCES {
|
|
990
|
+
DEFAULT_VIDEO_RESIZE_MODE = "defaultVideoResizeMode",
|
|
991
|
+
RESIZE_MODE_PER_CAMERA = "camerasResizeMode",
|
|
992
|
+
FISHEYE_CAMERAS = "fisheyeCameras",
|
|
993
|
+
UTC = "utc",
|
|
994
|
+
HOUR12 = "hour12",
|
|
995
|
+
START_OF_WEEK = "startOfWeek"
|
|
814
996
|
}
|
|
815
997
|
|
|
998
|
+
declare type Preferences = z.infer<typeof preferencesSchema>;
|
|
999
|
+
|
|
1000
|
+
declare const preferencesSchema: z.ZodObject<{
|
|
1001
|
+
defaultVideoResizeMode: z.ZodOptional<z.ZodNativeEnum<typeof VideoResizeMode>>;
|
|
1002
|
+
camerasResizeMode: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNativeEnum<typeof VideoResizeMode>], null>, "many">>;
|
|
1003
|
+
fisheyeCameras: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodObject<{
|
|
1004
|
+
params: z.ZodObject<{
|
|
1005
|
+
x: z.ZodNumber;
|
|
1006
|
+
y: z.ZodNumber;
|
|
1007
|
+
r: z.ZodNumber;
|
|
1008
|
+
s: z.ZodNumber;
|
|
1009
|
+
}, "strip", z.ZodTypeAny, {
|
|
1010
|
+
x: number;
|
|
1011
|
+
y: number;
|
|
1012
|
+
r: number;
|
|
1013
|
+
s: number;
|
|
1014
|
+
}, {
|
|
1015
|
+
x: number;
|
|
1016
|
+
y: number;
|
|
1017
|
+
r: number;
|
|
1018
|
+
s: number;
|
|
1019
|
+
}>;
|
|
1020
|
+
positions: z.ZodOptional<z.ZodTuple<[z.ZodObject<{
|
|
1021
|
+
lat: z.ZodNumber;
|
|
1022
|
+
lon: z.ZodNumber;
|
|
1023
|
+
fov: z.ZodNumber;
|
|
1024
|
+
}, "strip", z.ZodTypeAny, {
|
|
1025
|
+
lat: number;
|
|
1026
|
+
lon: number;
|
|
1027
|
+
fov: number;
|
|
1028
|
+
}, {
|
|
1029
|
+
lat: number;
|
|
1030
|
+
lon: number;
|
|
1031
|
+
fov: number;
|
|
1032
|
+
}>, z.ZodObject<{
|
|
1033
|
+
lat: z.ZodNumber;
|
|
1034
|
+
lon: z.ZodNumber;
|
|
1035
|
+
fov: z.ZodNumber;
|
|
1036
|
+
}, "strip", z.ZodTypeAny, {
|
|
1037
|
+
lat: number;
|
|
1038
|
+
lon: number;
|
|
1039
|
+
fov: number;
|
|
1040
|
+
}, {
|
|
1041
|
+
lat: number;
|
|
1042
|
+
lon: number;
|
|
1043
|
+
fov: number;
|
|
1044
|
+
}>, z.ZodObject<{
|
|
1045
|
+
lat: z.ZodNumber;
|
|
1046
|
+
lon: z.ZodNumber;
|
|
1047
|
+
fov: z.ZodNumber;
|
|
1048
|
+
}, "strip", z.ZodTypeAny, {
|
|
1049
|
+
lat: number;
|
|
1050
|
+
lon: number;
|
|
1051
|
+
fov: number;
|
|
1052
|
+
}, {
|
|
1053
|
+
lat: number;
|
|
1054
|
+
lon: number;
|
|
1055
|
+
fov: number;
|
|
1056
|
+
}>], null>>;
|
|
1057
|
+
}, "strip", z.ZodTypeAny, {
|
|
1058
|
+
params: {
|
|
1059
|
+
x: number;
|
|
1060
|
+
y: number;
|
|
1061
|
+
r: number;
|
|
1062
|
+
s: number;
|
|
1063
|
+
};
|
|
1064
|
+
positions?: [{
|
|
1065
|
+
lat: number;
|
|
1066
|
+
lon: number;
|
|
1067
|
+
fov: number;
|
|
1068
|
+
}, {
|
|
1069
|
+
lat: number;
|
|
1070
|
+
lon: number;
|
|
1071
|
+
fov: number;
|
|
1072
|
+
}, {
|
|
1073
|
+
lat: number;
|
|
1074
|
+
lon: number;
|
|
1075
|
+
fov: number;
|
|
1076
|
+
}] | undefined;
|
|
1077
|
+
}, {
|
|
1078
|
+
params: {
|
|
1079
|
+
x: number;
|
|
1080
|
+
y: number;
|
|
1081
|
+
r: number;
|
|
1082
|
+
s: number;
|
|
1083
|
+
};
|
|
1084
|
+
positions?: [{
|
|
1085
|
+
lat: number;
|
|
1086
|
+
lon: number;
|
|
1087
|
+
fov: number;
|
|
1088
|
+
}, {
|
|
1089
|
+
lat: number;
|
|
1090
|
+
lon: number;
|
|
1091
|
+
fov: number;
|
|
1092
|
+
}, {
|
|
1093
|
+
lat: number;
|
|
1094
|
+
lon: number;
|
|
1095
|
+
fov: number;
|
|
1096
|
+
}] | undefined;
|
|
1097
|
+
}>, z.ZodNull]>], null>, "many">>;
|
|
1098
|
+
utc: z.ZodDefault<z.ZodBoolean>;
|
|
1099
|
+
hour12: z.ZodDefault<z.ZodBoolean>;
|
|
1100
|
+
startOfWeek: z.ZodDefault<z.ZodEnum<["monday", "sunday"]>>;
|
|
1101
|
+
}, "strip", z.ZodTypeAny, {
|
|
1102
|
+
utc: boolean;
|
|
1103
|
+
hour12: boolean;
|
|
1104
|
+
startOfWeek: "monday" | "sunday";
|
|
1105
|
+
defaultVideoResizeMode?: VideoResizeMode | undefined;
|
|
1106
|
+
camerasResizeMode?: [number, VideoResizeMode][] | undefined;
|
|
1107
|
+
fisheyeCameras?: [number, [number, number, number] | {
|
|
1108
|
+
params: {
|
|
1109
|
+
x: number;
|
|
1110
|
+
y: number;
|
|
1111
|
+
r: number;
|
|
1112
|
+
s: number;
|
|
1113
|
+
};
|
|
1114
|
+
positions?: [{
|
|
1115
|
+
lat: number;
|
|
1116
|
+
lon: number;
|
|
1117
|
+
fov: number;
|
|
1118
|
+
}, {
|
|
1119
|
+
lat: number;
|
|
1120
|
+
lon: number;
|
|
1121
|
+
fov: number;
|
|
1122
|
+
}, {
|
|
1123
|
+
lat: number;
|
|
1124
|
+
lon: number;
|
|
1125
|
+
fov: number;
|
|
1126
|
+
}] | undefined;
|
|
1127
|
+
} | null][] | undefined;
|
|
1128
|
+
}, {
|
|
1129
|
+
defaultVideoResizeMode?: VideoResizeMode | undefined;
|
|
1130
|
+
camerasResizeMode?: [number, VideoResizeMode][] | undefined;
|
|
1131
|
+
fisheyeCameras?: [number, [number, number, number] | {
|
|
1132
|
+
params: {
|
|
1133
|
+
x: number;
|
|
1134
|
+
y: number;
|
|
1135
|
+
r: number;
|
|
1136
|
+
s: number;
|
|
1137
|
+
};
|
|
1138
|
+
positions?: [{
|
|
1139
|
+
lat: number;
|
|
1140
|
+
lon: number;
|
|
1141
|
+
fov: number;
|
|
1142
|
+
}, {
|
|
1143
|
+
lat: number;
|
|
1144
|
+
lon: number;
|
|
1145
|
+
fov: number;
|
|
1146
|
+
}, {
|
|
1147
|
+
lat: number;
|
|
1148
|
+
lon: number;
|
|
1149
|
+
fov: number;
|
|
1150
|
+
}] | undefined;
|
|
1151
|
+
} | null][] | undefined;
|
|
1152
|
+
utc?: boolean | undefined;
|
|
1153
|
+
hour12?: boolean | undefined;
|
|
1154
|
+
startOfWeek?: "monday" | "sunday" | undefined;
|
|
1155
|
+
}>;
|
|
1156
|
+
|
|
816
1157
|
declare interface Props {
|
|
817
1158
|
store: EventSearchStore;
|
|
818
1159
|
onEventClick: (event: CameraEvent) => void;
|
|
@@ -878,27 +1219,18 @@ declare interface RawCamera {
|
|
|
878
1219
|
declare interface RawCamgroup {
|
|
879
1220
|
id: number;
|
|
880
1221
|
name: string | null;
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
dynamic: boolean;
|
|
886
|
-
allowDuplicates: boolean;
|
|
887
|
-
allowDrop: boolean;
|
|
888
|
-
allowNodeDropInView: boolean;
|
|
889
|
-
visible: boolean;
|
|
890
|
-
layout_id: string;
|
|
891
|
-
contentFilter: null;
|
|
892
|
-
customerWideGroup: boolean;
|
|
1222
|
+
description: string | null;
|
|
1223
|
+
imageUrl: string | null;
|
|
1224
|
+
layoutId: string | null;
|
|
1225
|
+
layout_id: string | null;
|
|
893
1226
|
cameras: CamgroupItem[];
|
|
894
1227
|
camgroups: CamgroupItem[];
|
|
895
1228
|
version: string;
|
|
896
|
-
order: number;
|
|
897
1229
|
}
|
|
898
1230
|
|
|
899
1231
|
declare interface RawClip {
|
|
900
1232
|
id: number;
|
|
901
|
-
recordType:
|
|
1233
|
+
recordType: 'Archive' | 'Timelaps' | 'Timelaps to do';
|
|
902
1234
|
isReady: boolean;
|
|
903
1235
|
name: string;
|
|
904
1236
|
description: string;
|
|
@@ -922,7 +1254,7 @@ declare interface RawHeatmap {
|
|
|
922
1254
|
maxMotion: number;
|
|
923
1255
|
}
|
|
924
1256
|
|
|
925
|
-
declare interface
|
|
1257
|
+
declare interface RawPeopleCountingData {
|
|
926
1258
|
EventId: number;
|
|
927
1259
|
TimeStamp: Date;
|
|
928
1260
|
Motions: number;
|
|
@@ -966,6 +1298,12 @@ declare interface RawSharedClip {
|
|
|
966
1298
|
validTo: string | Date;
|
|
967
1299
|
}
|
|
968
1300
|
|
|
1301
|
+
declare interface RawThumbnail {
|
|
1302
|
+
timestamp: string;
|
|
1303
|
+
realtimestamp: string;
|
|
1304
|
+
url: string;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
969
1307
|
declare type RawToken = {
|
|
970
1308
|
accessToken: string;
|
|
971
1309
|
accessTokenExpires: string;
|
|
@@ -1086,8 +1424,11 @@ declare enum SensorEventType {
|
|
|
1086
1424
|
IDCheck = 37,
|
|
1087
1425
|
PPECheck = 38,
|
|
1088
1426
|
WelfareCheck = 39,
|
|
1089
|
-
|
|
1090
|
-
|
|
1427
|
+
VehicleBreakIn = 40,
|
|
1428
|
+
DrugTrafficking = 41,
|
|
1429
|
+
Assault = 42,
|
|
1430
|
+
PackageDelivery = 43,
|
|
1431
|
+
Uncategorized = 999
|
|
1091
1432
|
}
|
|
1092
1433
|
|
|
1093
1434
|
declare interface Storage_2 {
|
|
@@ -1101,8 +1442,6 @@ declare interface Thumbnail {
|
|
|
1101
1442
|
timestamp: Date;
|
|
1102
1443
|
realTimestamp: Date;
|
|
1103
1444
|
url: string;
|
|
1104
|
-
width: number;
|
|
1105
|
-
height: number;
|
|
1106
1445
|
}
|
|
1107
1446
|
|
|
1108
1447
|
declare class ThumbnailsStore extends ApiStore {
|
|
@@ -1124,7 +1463,7 @@ declare class ThumbnailsStore extends ApiStore {
|
|
|
1124
1463
|
* @param to - end of the period
|
|
1125
1464
|
* @param count - number of thumbnails
|
|
1126
1465
|
*/
|
|
1127
|
-
fetchThumbnails(cameraId: number, from: Date, to: Date, count: number)
|
|
1466
|
+
fetchThumbnails: (cameraId: number, from: Date, to: Date, count: number) => Observable<Thumbnail[]>;
|
|
1128
1467
|
getIntervalState(cameraId: number, from: Date, to: Date): IntervalState | null;
|
|
1129
1468
|
fetchThumbnail(cameraId: number, from: Date, to: Date): Observable<Thumbnail>;
|
|
1130
1469
|
/**
|
|
@@ -1135,14 +1474,16 @@ declare class ThumbnailsStore extends ApiStore {
|
|
|
1135
1474
|
* Returns previously obtained thumbnails for given camera within period
|
|
1136
1475
|
*/
|
|
1137
1476
|
getThumbnails({ cameraId, from, to }: GetThumbnailParams): Thumbnail[];
|
|
1138
|
-
toThumbnail: (cameraId: number) => ({ realtimestamp, url
|
|
1477
|
+
toThumbnail: (cameraId: number) => ({ realtimestamp, url }: {
|
|
1139
1478
|
realtimestamp: string;
|
|
1140
1479
|
url: string;
|
|
1141
|
-
width: number;
|
|
1142
|
-
height: number;
|
|
1143
1480
|
}) => Thumbnail;
|
|
1144
1481
|
}
|
|
1145
1482
|
|
|
1483
|
+
declare type TimelapseParams = ClipParams & {
|
|
1484
|
+
duration: number;
|
|
1485
|
+
};
|
|
1486
|
+
|
|
1146
1487
|
declare class Token {
|
|
1147
1488
|
accessToken: string;
|
|
1148
1489
|
accessTokenExpires: Date;
|
|
@@ -1171,6 +1512,7 @@ declare class ToolkitApp {
|
|
|
1171
1512
|
thumbnails: ThumbnailsStore;
|
|
1172
1513
|
account: AccountStore;
|
|
1173
1514
|
notification: NotificationService;
|
|
1515
|
+
library: LibraryStore;
|
|
1174
1516
|
auth: Auth;
|
|
1175
1517
|
api: Api<IApi> & IApi;
|
|
1176
1518
|
private disposables;
|
|
@@ -1189,4 +1531,9 @@ declare class ToolkitApp {
|
|
|
1189
1531
|
|
|
1190
1532
|
declare type User = RawUser;
|
|
1191
1533
|
|
|
1534
|
+
declare enum VideoResizeMode {
|
|
1535
|
+
Fit = "contain",
|
|
1536
|
+
Stretch = "fill"
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1192
1539
|
export { }
|