@olane/o-node 0.7.12-alpha.39 → 0.7.12-alpha.40
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/o-core/src/connection/index.d.ts +8 -0
- package/dist/o-core/src/connection/index.d.ts.map +1 -0
- package/dist/o-core/src/connection/index.js +7 -0
- package/dist/o-core/src/connection/interfaces/connection-manager.config.d.ts +15 -0
- package/dist/o-core/src/connection/interfaces/connection-manager.config.d.ts.map +1 -0
- package/dist/o-core/src/connection/interfaces/connection-manager.config.js +1 -0
- package/dist/o-core/src/connection/interfaces/connection-send-params.interface.d.ts +9 -0
- package/dist/o-core/src/connection/interfaces/connection-send-params.interface.d.ts.map +1 -0
- package/dist/o-core/src/connection/interfaces/connection-send-params.interface.js +1 -0
- package/dist/o-core/src/connection/interfaces/connection.config.d.ts +20 -0
- package/dist/o-core/src/connection/interfaces/connection.config.d.ts.map +1 -0
- package/dist/o-core/src/connection/interfaces/connection.config.js +1 -0
- package/dist/o-core/src/connection/interfaces/index.d.ts +5 -0
- package/dist/o-core/src/connection/interfaces/index.d.ts.map +1 -0
- package/dist/o-core/src/connection/interfaces/index.js +4 -0
- package/dist/o-core/src/connection/interfaces/request-state.enum.d.ts +7 -0
- package/dist/o-core/src/connection/interfaces/request-state.enum.d.ts.map +1 -0
- package/dist/o-core/src/connection/interfaces/request-state.enum.js +7 -0
- package/dist/o-core/src/connection/o-connection-manager.d.ts +19 -0
- package/dist/o-core/src/connection/o-connection-manager.d.ts.map +1 -0
- package/dist/o-core/src/connection/o-connection-manager.js +27 -0
- package/dist/o-core/src/connection/o-connection.d.ts +26 -0
- package/dist/o-core/src/connection/o-connection.d.ts.map +1 -0
- package/dist/o-core/src/connection/o-connection.js +54 -0
- package/dist/o-core/src/connection/o-request.d.ts +23 -0
- package/dist/o-core/src/connection/o-request.d.ts.map +1 -0
- package/dist/o-core/src/connection/o-request.js +42 -0
- package/dist/o-core/src/connection/o-response.d.ts +1 -0
- package/dist/o-core/src/connection/o-response.d.ts.map +1 -1
- package/dist/o-core/src/connection/o-response.js +7 -0
- package/dist/o-core/src/core/defaults/config.d.ts +4 -0
- package/dist/o-core/src/core/defaults/config.d.ts.map +1 -0
- package/dist/o-core/src/core/defaults/config.js +5 -0
- package/dist/o-core/src/core/defaults/index.d.ts +2 -0
- package/dist/o-core/src/core/defaults/index.d.ts.map +1 -0
- package/dist/o-core/src/core/defaults/index.js +1 -0
- package/dist/o-core/src/core/graceful-shutdown.d.ts +25 -0
- package/dist/o-core/src/core/graceful-shutdown.d.ts.map +1 -0
- package/dist/o-core/src/core/graceful-shutdown.js +84 -0
- package/dist/o-core/src/core/index.d.ts +9 -0
- package/dist/o-core/src/core/index.d.ts.map +1 -0
- package/dist/o-core/src/core/index.js +8 -0
- package/dist/o-core/src/core/interfaces/index.d.ts +7 -0
- package/dist/o-core/src/core/interfaces/index.d.ts.map +1 -0
- package/dist/o-core/src/core/interfaces/index.js +6 -0
- package/dist/o-core/src/core/interfaces/node-type.enum.d.ts +10 -0
- package/dist/o-core/src/core/interfaces/node-type.enum.d.ts.map +1 -0
- package/dist/o-core/src/core/interfaces/node-type.enum.js +10 -0
- package/dist/o-core/src/core/interfaces/o-core.config.d.ts +23 -0
- package/dist/o-core/src/core/interfaces/o-core.config.d.ts.map +1 -0
- package/dist/o-core/src/core/interfaces/o-core.config.js +1 -0
- package/dist/o-core/src/core/interfaces/o-core.interface.d.ts +18 -0
- package/dist/o-core/src/core/interfaces/o-core.interface.d.ts.map +1 -0
- package/dist/o-core/src/core/interfaces/o-core.interface.js +1 -0
- package/dist/o-core/src/core/interfaces/state.enum.d.ts +8 -0
- package/dist/o-core/src/core/interfaces/state.enum.d.ts.map +1 -0
- package/dist/o-core/src/core/interfaces/state.enum.js +8 -0
- package/dist/o-core/src/core/interfaces/use-options.interface.d.ts +11 -0
- package/dist/o-core/src/core/interfaces/use-options.interface.d.ts.map +1 -0
- package/dist/o-core/src/core/interfaces/use-options.interface.js +1 -0
- package/dist/o-core/src/core/interfaces/use-stream-options.interface.d.ts +4 -0
- package/dist/o-core/src/core/interfaces/use-stream-options.interface.d.ts.map +1 -0
- package/dist/o-core/src/core/interfaces/use-stream-options.interface.js +1 -0
- package/dist/o-core/src/core/lib/events/connection-events.d.ts +31 -0
- package/dist/o-core/src/core/lib/events/connection-events.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/events/connection-events.js +46 -0
- package/dist/o-core/src/core/lib/events/hierarchy-events.d.ts +69 -0
- package/dist/o-core/src/core/lib/events/hierarchy-events.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/events/hierarchy-events.js +100 -0
- package/dist/o-core/src/core/lib/events/index.d.ts +6 -0
- package/dist/o-core/src/core/lib/events/index.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/events/index.js +5 -0
- package/dist/o-core/src/core/lib/events/node-events.d.ts +40 -0
- package/dist/o-core/src/core/lib/events/node-events.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/events/node-events.js +58 -0
- package/dist/o-core/src/core/lib/events/o-notification-event.d.ts +26 -0
- package/dist/o-core/src/core/lib/events/o-notification-event.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/events/o-notification-event.js +30 -0
- package/dist/o-core/src/core/lib/index.d.ts +8 -0
- package/dist/o-core/src/core/lib/index.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/index.js +7 -0
- package/dist/o-core/src/core/lib/interfaces/notification-types.d.ts +49 -0
- package/dist/o-core/src/core/lib/interfaces/notification-types.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/interfaces/notification-types.js +1 -0
- package/dist/o-core/src/core/lib/o-hierarchy.manager.d.ts +24 -0
- package/dist/o-core/src/core/lib/o-hierarchy.manager.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/o-hierarchy.manager.js +58 -0
- package/dist/o-core/src/core/lib/o-metrics.d.ts +5 -0
- package/dist/o-core/src/core/lib/o-metrics.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/o-metrics.js +6 -0
- package/dist/o-core/src/core/lib/o-notification.manager.d.ts +58 -0
- package/dist/o-core/src/core/lib/o-notification.manager.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/o-notification.manager.js +159 -0
- package/dist/o-core/src/core/lib/o-request.manager.d.ts +10 -0
- package/dist/o-core/src/core/lib/o-request.manager.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/o-request.manager.js +18 -0
- package/dist/o-core/src/core/lib/utils/event-filters.d.ts +38 -0
- package/dist/o-core/src/core/lib/utils/event-filters.d.ts.map +1 -0
- package/dist/o-core/src/core/lib/utils/event-filters.js +159 -0
- package/dist/o-core/src/core/o-core.d.ts +240 -0
- package/dist/o-core/src/core/o-core.d.ts.map +1 -0
- package/dist/o-core/src/core/o-core.js +463 -0
- package/dist/o-core/src/core/o-dependency.d.ts +9 -0
- package/dist/o-core/src/core/o-dependency.d.ts.map +1 -0
- package/dist/o-core/src/core/o-dependency.js +15 -0
- package/dist/o-core/src/core/o-object.d.ts +7 -0
- package/dist/o-core/src/core/o-object.d.ts.map +1 -0
- package/dist/o-core/src/core/o-object.js +10 -0
- package/dist/o-core/src/core/o-parameter.d.ts +12 -0
- package/dist/o-core/src/core/o-parameter.d.ts.map +1 -0
- package/dist/o-core/src/core/o-parameter.js +21 -0
- package/dist/o-core/src/error/index.d.ts +3 -0
- package/dist/o-core/src/error/index.d.ts.map +1 -0
- package/dist/o-core/src/error/index.js +2 -0
- package/dist/o-core/src/index.d.ts +8 -0
- package/dist/o-core/src/index.d.ts.map +1 -0
- package/dist/o-core/src/index.js +7 -0
- package/dist/o-core/src/response/index.d.ts +2 -0
- package/dist/o-core/src/response/index.d.ts.map +1 -0
- package/dist/o-core/src/response/index.js +1 -0
- package/dist/o-core/src/response/response-builder.d.ts +140 -0
- package/dist/o-core/src/response/response-builder.d.ts.map +1 -0
- package/dist/o-core/src/response/response-builder.js +190 -0
- package/dist/o-core/src/router/enums/restricted-addresses.enum.d.ts +8 -0
- package/dist/o-core/src/router/enums/restricted-addresses.enum.d.ts.map +1 -0
- package/dist/o-core/src/router/enums/restricted-addresses.enum.js +13 -0
- package/dist/o-core/src/router/index.d.ts +11 -0
- package/dist/o-core/src/router/index.d.ts.map +1 -0
- package/dist/o-core/src/router/index.js +10 -0
- package/dist/o-core/src/router/interfaces/resolve.request.d.ts +10 -0
- package/dist/o-core/src/router/interfaces/resolve.request.d.ts.map +1 -0
- package/dist/o-core/src/router/interfaces/resolve.request.js +1 -0
- package/dist/o-core/src/router/interfaces/route.response.d.ts +8 -0
- package/dist/o-core/src/router/interfaces/route.response.d.ts.map +1 -0
- package/dist/o-core/src/router/interfaces/route.response.js +1 -0
- package/dist/o-core/src/router/o-address-resolver.d.ts +14 -0
- package/dist/o-core/src/router/o-address-resolver.d.ts.map +1 -0
- package/dist/o-core/src/router/o-address-resolver.js +19 -0
- package/dist/o-core/src/router/o-address.d.ts +33 -0
- package/dist/o-core/src/router/o-address.d.ts.map +1 -0
- package/dist/o-core/src/router/o-address.js +114 -0
- package/dist/o-core/src/router/o-request-preparation.d.ts +37 -0
- package/dist/o-core/src/router/o-request-preparation.d.ts.map +1 -0
- package/dist/o-core/src/router/o-request-preparation.js +75 -0
- package/dist/o-core/src/router/o-request.router.d.ts +18 -0
- package/dist/o-core/src/router/o-request.router.d.ts.map +1 -0
- package/dist/o-core/src/router/o-request.router.js +12 -0
- package/dist/o-core/src/router/o-resolver-chain.d.ts +32 -0
- package/dist/o-core/src/router/o-resolver-chain.d.ts.map +1 -0
- package/dist/o-core/src/router/o-resolver-chain.js +62 -0
- package/dist/o-core/src/router/o-router.d.ts +19 -0
- package/dist/o-core/src/router/o-router.d.ts.map +1 -0
- package/dist/o-core/src/router/o-router.js +14 -0
- package/dist/o-core/src/router/o-routing-policy.d.ts +36 -0
- package/dist/o-core/src/router/o-routing-policy.d.ts.map +1 -0
- package/dist/o-core/src/router/o-routing-policy.js +19 -0
- package/dist/o-core/src/transports/custom.transport.d.ts +6 -0
- package/dist/o-core/src/transports/custom.transport.d.ts.map +1 -0
- package/dist/o-core/src/transports/custom.transport.js +10 -0
- package/dist/o-core/src/transports/index.d.ts +4 -0
- package/dist/o-core/src/transports/index.d.ts.map +1 -0
- package/dist/o-core/src/transports/index.js +3 -0
- package/dist/o-core/src/transports/interfaces/transport-type.enum.d.ts +5 -0
- package/dist/o-core/src/transports/interfaces/transport-type.enum.d.ts.map +1 -0
- package/dist/o-core/src/transports/interfaces/transport-type.enum.js +5 -0
- package/dist/o-core/src/transports/o-transport.d.ts +10 -0
- package/dist/o-core/src/transports/o-transport.d.ts.map +1 -0
- package/dist/o-core/src/transports/o-transport.js +16 -0
- package/dist/o-core/src/utils/core.utils.d.ts +34 -0
- package/dist/o-core/src/utils/core.utils.d.ts.map +1 -0
- package/dist/o-core/src/utils/core.utils.js +123 -0
- package/dist/o-core/src/utils/index.d.ts +6 -0
- package/dist/o-core/src/utils/index.d.ts.map +1 -0
- package/dist/o-core/src/utils/index.js +5 -0
- package/dist/o-core/src/utils/logger.d.ts +14 -0
- package/dist/o-core/src/utils/logger.d.ts.map +1 -0
- package/dist/o-core/src/utils/logger.js +31 -0
- package/dist/o-core/src/utils/object.utils.d.ts +5 -0
- package/dist/o-core/src/utils/object.utils.d.ts.map +1 -0
- package/dist/o-core/src/utils/object.utils.js +23 -0
- package/dist/o-core/src/utils/regex.utils.d.ts +4 -0
- package/dist/o-core/src/utils/regex.utils.d.ts.map +1 -0
- package/dist/o-core/src/utils/regex.utils.js +13 -0
- package/dist/o-core/src/utils/remote.utils.d.ts +4 -0
- package/dist/o-core/src/utils/remote.utils.d.ts.map +1 -0
- package/dist/o-core/src/utils/remote.utils.js +5 -0
- package/dist/o-node/src/connection/o-node-connection.d.ts +2 -2
- package/dist/o-node/src/connection/o-node-connection.d.ts.map +1 -1
- package/dist/o-node/src/connection/o-node-connection.js +36 -23
- package/dist/o-node/src/connection/o-node-connection.manager.d.ts.map +1 -1
- package/dist/o-node/src/connection/o-node-connection.manager.js +13 -41
- package/dist/o-node/src/index.d.ts +1 -0
- package/dist/o-node/src/index.d.ts.map +1 -1
- package/dist/o-node/src/index.js +1 -0
- package/dist/o-node/src/interfaces/o-node.config.d.ts +0 -17
- package/dist/o-node/src/interfaces/o-node.config.d.ts.map +1 -1
- package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts +1 -0
- package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -1
- package/dist/o-node/src/managers/o-connection-heartbeat.manager.js +17 -3
- package/dist/o-node/src/o-node.d.ts +11 -12
- package/dist/o-node/src/o-node.d.ts.map +1 -1
- package/dist/o-node/src/o-node.js +104 -25
- package/dist/o-node/src/o-node.notification-manager.js +4 -1
- package/dist/o-node/src/o-node.tool.d.ts.map +1 -1
- package/dist/o-node/src/o-node.tool.js +16 -23
- package/dist/o-node/src/router/o-node.router.d.ts +1 -0
- package/dist/o-node/src/router/o-node.router.d.ts.map +1 -1
- package/dist/o-node/src/router/o-node.router.js +53 -7
- package/dist/o-node/src/router/resolvers/o-node.resolver.d.ts.map +1 -1
- package/dist/o-node/src/router/resolvers/o-node.resolver.js +5 -1
- package/dist/o-node/src/ui/index.d.ts +3 -0
- package/dist/o-node/src/ui/index.d.ts.map +1 -0
- package/dist/o-node/src/ui/index.js +2 -0
- package/dist/o-node/src/ui/types.d.ts +110 -0
- package/dist/o-node/src/ui/types.d.ts.map +1 -0
- package/dist/o-node/src/ui/types.js +17 -0
- package/dist/o-node/src/ui/ui-graph.manager.d.ts +70 -0
- package/dist/o-node/src/ui/ui-graph.manager.d.ts.map +1 -0
- package/dist/o-node/src/ui/ui-graph.manager.js +274 -0
- package/dist/o-node/src/utils/index.d.ts +0 -2
- package/dist/o-node/src/utils/index.d.ts.map +1 -1
- package/dist/o-node/src/utils/index.js +0 -2
- package/dist/o-node/src/utils/stream.utils.d.ts.map +1 -1
- package/dist/o-node/src/utils/stream.utils.js +25 -21
- package/dist/o-node/test/helpers/test-node.tool.d.ts +15 -0
- package/dist/o-node/test/helpers/test-node.tool.d.ts.map +1 -0
- package/dist/o-node/test/helpers/test-node.tool.js +27 -0
- package/dist/src/connection/o-node-connection.manager.d.ts +14 -4
- package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.manager.js +61 -29
- package/package.json +6 -6
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { oObject } from '../o-object.js';
|
|
2
|
+
export class oHierarchyManager extends oObject {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
super();
|
|
5
|
+
this.leaders = [];
|
|
6
|
+
this.children = [];
|
|
7
|
+
this.parents = []; // multiple parents allow for more flexibility with address construction
|
|
8
|
+
this.leaders = config.leaders || [];
|
|
9
|
+
this.children = config.children || [];
|
|
10
|
+
this.parents = config.parents || [];
|
|
11
|
+
}
|
|
12
|
+
clear() {
|
|
13
|
+
this.leaders = [];
|
|
14
|
+
this.children = [];
|
|
15
|
+
this.parents = [];
|
|
16
|
+
}
|
|
17
|
+
deduplicate(addresses) {
|
|
18
|
+
const added = {};
|
|
19
|
+
return addresses.filter((a) => {
|
|
20
|
+
if (added[a.toString()]) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
added[a.toString()] = true;
|
|
24
|
+
return true;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
addChild(address) {
|
|
28
|
+
// remove child if it exists
|
|
29
|
+
this.removeChild(address);
|
|
30
|
+
// deduplicate
|
|
31
|
+
this.children = this.deduplicate([...this.children, address]);
|
|
32
|
+
}
|
|
33
|
+
getChild(address) {
|
|
34
|
+
return this.children.find((a) => a.toStaticAddress().toString() === address.toStaticAddress().toString());
|
|
35
|
+
}
|
|
36
|
+
removeChild(address) {
|
|
37
|
+
this.children = this.deduplicate([
|
|
38
|
+
...this.children.filter((a) => a.toString() !== address.toString()),
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
addParent(address) {
|
|
42
|
+
this.parents = this.deduplicate([...this.parents, address]);
|
|
43
|
+
}
|
|
44
|
+
removeParent(address) {
|
|
45
|
+
this.parents = this.deduplicate([
|
|
46
|
+
...this.parents.filter((a) => a.toString() !== address.toString()),
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
getChildren() {
|
|
50
|
+
return this.children;
|
|
51
|
+
}
|
|
52
|
+
getParents() {
|
|
53
|
+
return this.parents;
|
|
54
|
+
}
|
|
55
|
+
getLeaders() {
|
|
56
|
+
return this.leaders;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"o-metrics.d.ts","sourceRoot":"","sources":["../../../../../../o-core/src/core/lib/o-metrics.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAQ;IACZ,YAAY,EAAE,MAAM,CAAK;IACzB,UAAU,EAAE,MAAM,CAAK;CAC/B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { oObject } from '../o-object.js';
|
|
2
|
+
import { oNotificationEvent } from './events/o-notification-event.js';
|
|
3
|
+
import { EventFilter, NotificationHandler, Subscription } from './interfaces/notification-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Abstract notification manager - transport agnostic
|
|
6
|
+
* NO dependencies on libp2p, HTTP, or any specific transport
|
|
7
|
+
*
|
|
8
|
+
* Subclasses implement setupListeners() to wire up transport-specific events
|
|
9
|
+
*/
|
|
10
|
+
export declare abstract class oNotificationManager extends oObject {
|
|
11
|
+
private eventTarget;
|
|
12
|
+
private subscriptions;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Subscribe to a notification event
|
|
16
|
+
*
|
|
17
|
+
* @param eventType - The event type to subscribe to (e.g., "node:connected", "child:joined")
|
|
18
|
+
* @param handler - The handler function to call when event is emitted
|
|
19
|
+
* @param filter - Optional filter to apply to events
|
|
20
|
+
* @returns Subscription handle
|
|
21
|
+
*/
|
|
22
|
+
on(eventType: string, handler: NotificationHandler, filter?: EventFilter): Subscription;
|
|
23
|
+
/**
|
|
24
|
+
* Unsubscribe from a notification event
|
|
25
|
+
*/
|
|
26
|
+
off(subscription: Subscription): void;
|
|
27
|
+
/**
|
|
28
|
+
* Emit a notification event
|
|
29
|
+
*/
|
|
30
|
+
emit(event: oNotificationEvent): void;
|
|
31
|
+
/**
|
|
32
|
+
* Check if an event matches a filter
|
|
33
|
+
*/
|
|
34
|
+
protected matchesFilter(event: oNotificationEvent, filter: EventFilter): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Get all active subscriptions for an event type
|
|
37
|
+
*/
|
|
38
|
+
getSubscriptions(eventType?: string): Subscription[];
|
|
39
|
+
/**
|
|
40
|
+
* Get count of active subscriptions
|
|
41
|
+
*/
|
|
42
|
+
getSubscriptionCount(eventType?: string): number;
|
|
43
|
+
/**
|
|
44
|
+
* Subclasses must implement this to wire up transport-specific listeners
|
|
45
|
+
* This is where libp2p/HTTP/WebSocket events get connected
|
|
46
|
+
*/
|
|
47
|
+
protected abstract setupListeners(): void | Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Initialize the notification manager
|
|
50
|
+
* Calls setupListeners() to wire up transport events
|
|
51
|
+
*/
|
|
52
|
+
initialize(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Cleanup all subscriptions
|
|
55
|
+
*/
|
|
56
|
+
teardown(): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=o-notification.manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"o-notification.manager.d.ts","sourceRoot":"","sources":["../../../../../../o-core/src/core/lib/o-notification.manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,YAAY,EACb,MAAM,oCAAoC,CAAC;AAG5C;;;;;GAKG;AACH,8BAAsB,oBAAqB,SAAQ,OAAO;IACxD,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAAiC;;IAQtD;;;;;;;OAOG;IACH,EAAE,CACA,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mBAAmB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,YAAY;IAoDf;;OAEG;IACH,GAAG,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IA6BrC;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAUrC;;OAEG;IACH,SAAS,CAAC,aAAa,CACrB,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,WAAW,GAClB,OAAO;IAyBV;;OAEG;IACH,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE;IAcpD;;OAEG;IACH,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAIhD;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAEzD;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAYhC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import { oObject } from '../o-object.js';
|
|
3
|
+
import { EventFilters } from './utils/event-filters.js';
|
|
4
|
+
/**
|
|
5
|
+
* Abstract notification manager - transport agnostic
|
|
6
|
+
* NO dependencies on libp2p, HTTP, or any specific transport
|
|
7
|
+
*
|
|
8
|
+
* Subclasses implement setupListeners() to wire up transport-specific events
|
|
9
|
+
*/
|
|
10
|
+
export class oNotificationManager extends oObject {
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
this.eventTarget = new EventTarget();
|
|
14
|
+
this.subscriptions = new Map();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Subscribe to a notification event
|
|
18
|
+
*
|
|
19
|
+
* @param eventType - The event type to subscribe to (e.g., "node:connected", "child:joined")
|
|
20
|
+
* @param handler - The handler function to call when event is emitted
|
|
21
|
+
* @param filter - Optional filter to apply to events
|
|
22
|
+
* @returns Subscription handle
|
|
23
|
+
*/
|
|
24
|
+
on(eventType, handler, filter) {
|
|
25
|
+
const subscriptionId = uuidv4();
|
|
26
|
+
const subscription = {
|
|
27
|
+
id: subscriptionId,
|
|
28
|
+
eventType,
|
|
29
|
+
handler,
|
|
30
|
+
filter,
|
|
31
|
+
unsubscribe: () => {
|
|
32
|
+
this.off(subscription);
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
// Add to subscriptions map
|
|
36
|
+
if (!this.subscriptions.has(eventType)) {
|
|
37
|
+
this.subscriptions.set(eventType, new Set());
|
|
38
|
+
}
|
|
39
|
+
this.subscriptions.get(eventType).add(subscription);
|
|
40
|
+
// Add DOM event listener
|
|
41
|
+
const wrappedHandler = async (event) => {
|
|
42
|
+
if (!(event instanceof CustomEvent)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const notificationEvent = event.detail;
|
|
46
|
+
// Apply filter if provided
|
|
47
|
+
if (filter && !this.matchesFilter(notificationEvent, filter)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
await handler(notificationEvent);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
this.logger.error(`Error in notification handler for ${eventType}:`, error);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
// Store wrapped handler for later removal
|
|
58
|
+
subscription._wrappedHandler = wrappedHandler;
|
|
59
|
+
this.eventTarget.addEventListener(eventType, wrappedHandler);
|
|
60
|
+
this.logger.debug(`Subscribed to ${eventType} with ID ${subscriptionId}`);
|
|
61
|
+
return subscription;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Unsubscribe from a notification event
|
|
65
|
+
*/
|
|
66
|
+
off(subscription) {
|
|
67
|
+
const subscriptionsForType = this.subscriptions.get(subscription.eventType);
|
|
68
|
+
if (!subscriptionsForType) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Remove from subscriptions set
|
|
72
|
+
subscriptionsForType.delete(subscription);
|
|
73
|
+
// Remove DOM event listener
|
|
74
|
+
const wrappedHandler = subscription._wrappedHandler;
|
|
75
|
+
if (wrappedHandler) {
|
|
76
|
+
this.eventTarget.removeEventListener(subscription.eventType, wrappedHandler);
|
|
77
|
+
}
|
|
78
|
+
// Clean up empty sets
|
|
79
|
+
if (subscriptionsForType.size === 0) {
|
|
80
|
+
this.subscriptions.delete(subscription.eventType);
|
|
81
|
+
}
|
|
82
|
+
this.logger.verbose(`Unsubscribed from ${subscription.eventType} with ID ${subscription.id}`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Emit a notification event
|
|
86
|
+
*/
|
|
87
|
+
emit(event) {
|
|
88
|
+
this.logger.verbose(`Emitting event: ${event.type}`, event.toJSON());
|
|
89
|
+
const customEvent = new CustomEvent(event.type, {
|
|
90
|
+
detail: event,
|
|
91
|
+
});
|
|
92
|
+
this.eventTarget.dispatchEvent(customEvent);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if an event matches a filter
|
|
96
|
+
*/
|
|
97
|
+
matchesFilter(event, filter) {
|
|
98
|
+
// Check event type filter
|
|
99
|
+
if (filter.eventTypes && !filter.eventTypes.includes(event.type)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
// Check address pattern filter
|
|
103
|
+
if (filter.addressPattern) {
|
|
104
|
+
const eventAddress = EventFilters.getEventAddress(event);
|
|
105
|
+
if (!eventAddress ||
|
|
106
|
+
!EventFilters.addressMatches(eventAddress, filter.addressPattern)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Check custom filter
|
|
111
|
+
if (filter.customFilter && !filter.customFilter(event)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get all active subscriptions for an event type
|
|
118
|
+
*/
|
|
119
|
+
getSubscriptions(eventType) {
|
|
120
|
+
if (eventType) {
|
|
121
|
+
const subs = this.subscriptions.get(eventType);
|
|
122
|
+
return subs ? Array.from(subs) : [];
|
|
123
|
+
}
|
|
124
|
+
// Return all subscriptions
|
|
125
|
+
const allSubs = [];
|
|
126
|
+
for (const subs of this.subscriptions.values()) {
|
|
127
|
+
allSubs.push(...Array.from(subs));
|
|
128
|
+
}
|
|
129
|
+
return allSubs;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get count of active subscriptions
|
|
133
|
+
*/
|
|
134
|
+
getSubscriptionCount(eventType) {
|
|
135
|
+
return this.getSubscriptions(eventType).length;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Initialize the notification manager
|
|
139
|
+
* Calls setupListeners() to wire up transport events
|
|
140
|
+
*/
|
|
141
|
+
async initialize() {
|
|
142
|
+
this.logger.debug('Initializing notification manager...');
|
|
143
|
+
await this.setupListeners();
|
|
144
|
+
this.logger.debug('Notification manager initialized');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Cleanup all subscriptions
|
|
148
|
+
*/
|
|
149
|
+
async teardown() {
|
|
150
|
+
this.logger.debug('Tearing down notification manager...');
|
|
151
|
+
// Unsubscribe all
|
|
152
|
+
const allSubs = this.getSubscriptions();
|
|
153
|
+
for (const sub of allSubs) {
|
|
154
|
+
this.off(sub);
|
|
155
|
+
}
|
|
156
|
+
this.subscriptions.clear();
|
|
157
|
+
this.logger.debug('Notification manager torn down');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { oRequest } from '../../connection/o-request.js';
|
|
2
|
+
export declare class oRequestManager {
|
|
3
|
+
private requests;
|
|
4
|
+
constructor();
|
|
5
|
+
addRequest(request: oRequest): void;
|
|
6
|
+
removeRequest(request: oRequest): void;
|
|
7
|
+
getRequest(id: string): oRequest | undefined;
|
|
8
|
+
get activeRequests(): oRequest[];
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=o-request.manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"o-request.manager.d.ts","sourceRoot":"","sources":["../../../../../../o-core/src/core/lib/o-request.manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAEzD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAkB;;IAGlC,UAAU,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI;IAInC,aAAa,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI;IAItC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI5C,IAAI,cAAc,IAAI,QAAQ,EAAE,CAE/B;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RequestState } from '../../connection/interfaces/request-state.enum.js';
|
|
2
|
+
export class oRequestManager {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.requests = [];
|
|
5
|
+
}
|
|
6
|
+
addRequest(request) {
|
|
7
|
+
this.requests.push(request);
|
|
8
|
+
}
|
|
9
|
+
removeRequest(request) {
|
|
10
|
+
this.requests = this.requests.filter((r) => r !== request);
|
|
11
|
+
}
|
|
12
|
+
getRequest(id) {
|
|
13
|
+
return this.requests.find((r) => r.id === id);
|
|
14
|
+
}
|
|
15
|
+
get activeRequests() {
|
|
16
|
+
return this.requests.filter((r) => r.state === RequestState.PENDING);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { oAddress } from '../../../router/o-address.js';
|
|
2
|
+
import { oNotificationEvent } from '../events/o-notification-event.js';
|
|
3
|
+
/**
|
|
4
|
+
* Utility functions for filtering notification events
|
|
5
|
+
*/
|
|
6
|
+
export declare class EventFilters {
|
|
7
|
+
/**
|
|
8
|
+
* Check if an address matches a pattern
|
|
9
|
+
* Supports:
|
|
10
|
+
* - Regex patterns: any string starting with '/' or containing regex special chars
|
|
11
|
+
* - Wildcards: * for single segment, ** for multiple segments
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* Wildcards:
|
|
15
|
+
* - "o://leader/*" matches "o://leader/child1" but not "o://leader/child1/grandchild"
|
|
16
|
+
* - "o://leader/**" matches "o://leader/child1" and "o://leader/child1/grandchild"
|
|
17
|
+
* - "o://leader/tools/*" matches "o://leader/tools/calculator"
|
|
18
|
+
*
|
|
19
|
+
* Regex (use standard regex patterns with / delimiters):
|
|
20
|
+
* - /^o:\/\/leader\/.*\/ matches any path starting with o://leader/
|
|
21
|
+
* - /tool-\d+/ matches paths with tool-1, tool-99, etc.
|
|
22
|
+
* - /o:\/\/leader\/(analytics|reporting)\// matches analytics or reporting paths
|
|
23
|
+
*/
|
|
24
|
+
static addressMatches(address: oAddress, pattern: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Filter events to only include direct children of a parent address
|
|
27
|
+
*/
|
|
28
|
+
static childrenOnly(event: oNotificationEvent, parentAddress: oAddress): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Filter events to only include descendants (children, grandchildren, etc.) of an ancestor address
|
|
31
|
+
*/
|
|
32
|
+
static descendantsOnly(event: oNotificationEvent, ancestorAddress: oAddress): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get the address from an event based on its type
|
|
35
|
+
*/
|
|
36
|
+
static getEventAddress(event: oNotificationEvent): oAddress | null;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=event-filters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-filters.d.ts","sourceRoot":"","sources":["../../../../../../../o-core/src/core/lib/utils/event-filters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAUvE;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAiElE;;OAEG;IACH,MAAM,CAAC,YAAY,CACjB,KAAK,EAAE,kBAAkB,EACzB,aAAa,EAAE,QAAQ,GACtB,OAAO;IAiCV;;OAEG;IACH,MAAM,CAAC,eAAe,CACpB,KAAK,EAAE,kBAAkB,EACzB,eAAe,EAAE,QAAQ,GACxB,OAAO;IAgDV;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,QAAQ,GAAG,IAAI;CAcnE"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { ChildJoinedEvent, ChildLeftEvent, } from '../events/hierarchy-events.js';
|
|
2
|
+
import { NodeConnectedEvent, NodeDisconnectedEvent, } from '../events/node-events.js';
|
|
3
|
+
/**
|
|
4
|
+
* Utility functions for filtering notification events
|
|
5
|
+
*/
|
|
6
|
+
export class EventFilters {
|
|
7
|
+
/**
|
|
8
|
+
* Check if an address matches a pattern
|
|
9
|
+
* Supports:
|
|
10
|
+
* - Regex patterns: any string starting with '/' or containing regex special chars
|
|
11
|
+
* - Wildcards: * for single segment, ** for multiple segments
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* Wildcards:
|
|
15
|
+
* - "o://leader/*" matches "o://leader/child1" but not "o://leader/child1/grandchild"
|
|
16
|
+
* - "o://leader/**" matches "o://leader/child1" and "o://leader/child1/grandchild"
|
|
17
|
+
* - "o://leader/tools/*" matches "o://leader/tools/calculator"
|
|
18
|
+
*
|
|
19
|
+
* Regex (use standard regex patterns with / delimiters):
|
|
20
|
+
* - /^o:\/\/leader\/.*\/ matches any path starting with o://leader/
|
|
21
|
+
* - /tool-\d+/ matches paths with tool-1, tool-99, etc.
|
|
22
|
+
* - /o:\/\/leader\/(analytics|reporting)\// matches analytics or reporting paths
|
|
23
|
+
*/
|
|
24
|
+
static addressMatches(address, pattern) {
|
|
25
|
+
const addressStr = address.toString();
|
|
26
|
+
// Check if pattern is a regex (starts with / or contains regex special chars like ^, $, [], (), |)
|
|
27
|
+
const isRegex = pattern.startsWith('/') || /[\^\$\[\]\(\)\|]/.test(pattern);
|
|
28
|
+
if (isRegex) {
|
|
29
|
+
try {
|
|
30
|
+
// Extract regex pattern and flags if format is /pattern/flags
|
|
31
|
+
let regexPattern = pattern;
|
|
32
|
+
let flags = '';
|
|
33
|
+
if (pattern.startsWith('/')) {
|
|
34
|
+
const lastSlash = pattern.lastIndexOf('/');
|
|
35
|
+
if (lastSlash > 0) {
|
|
36
|
+
regexPattern = pattern.slice(1, lastSlash);
|
|
37
|
+
flags = pattern.slice(lastSlash + 1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const regex = new RegExp(regexPattern, flags);
|
|
41
|
+
return regex.test(addressStr);
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
// If regex compilation fails, fall back to exact match
|
|
45
|
+
console.warn(`Invalid regex pattern: ${pattern}`, e);
|
|
46
|
+
return addressStr === pattern;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Handle wildcard patterns (backward compatibility)
|
|
50
|
+
const addressPaths = address.paths;
|
|
51
|
+
const patternPaths = pattern.replace('o://', '').split('/').filter(Boolean);
|
|
52
|
+
// Handle exact match
|
|
53
|
+
if (addressStr === pattern) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
// Handle wildcard patterns
|
|
57
|
+
for (let i = 0; i < patternPaths.length; i++) {
|
|
58
|
+
const patternSegment = patternPaths[i];
|
|
59
|
+
// ** matches rest of path
|
|
60
|
+
if (patternSegment === '**') {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
// * matches single segment
|
|
64
|
+
if (patternSegment === '*') {
|
|
65
|
+
if (i >= addressPaths.length) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// Exact segment match
|
|
71
|
+
if (addressPaths[i] !== patternSegment) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Pattern must match full address length (unless ended with **)
|
|
76
|
+
return addressPaths.length === patternPaths.length;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Filter events to only include direct children of a parent address
|
|
80
|
+
*/
|
|
81
|
+
static childrenOnly(event, parentAddress) {
|
|
82
|
+
// Check if event is a hierarchy event
|
|
83
|
+
if (event instanceof ChildJoinedEvent || event instanceof ChildLeftEvent) {
|
|
84
|
+
return event.parentAddress.toString() === parentAddress.toString();
|
|
85
|
+
}
|
|
86
|
+
// For node events, check if the node is a direct child
|
|
87
|
+
if (event instanceof NodeConnectedEvent ||
|
|
88
|
+
event instanceof NodeDisconnectedEvent) {
|
|
89
|
+
const nodeAddr = event.nodeAddress;
|
|
90
|
+
const parentPaths = parentAddress.paths;
|
|
91
|
+
const nodePaths = nodeAddr.paths;
|
|
92
|
+
// Direct child has exactly one more path segment
|
|
93
|
+
if (nodePaths.length !== parentPaths.length + 1) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
// Check all parent segments match
|
|
97
|
+
for (let i = 0; i < parentPaths.length; i++) {
|
|
98
|
+
if (parentPaths[i] !== nodePaths[i]) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Filter events to only include descendants (children, grandchildren, etc.) of an ancestor address
|
|
108
|
+
*/
|
|
109
|
+
static descendantsOnly(event, ancestorAddress) {
|
|
110
|
+
// Check if event is a hierarchy event
|
|
111
|
+
if (event instanceof ChildJoinedEvent || event instanceof ChildLeftEvent) {
|
|
112
|
+
// Check if parent is a descendant of or equal to ancestor
|
|
113
|
+
const parentPaths = event.parentAddress.paths;
|
|
114
|
+
const ancestorPaths = ancestorAddress.paths;
|
|
115
|
+
if (parentPaths.length < ancestorPaths.length) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
// Check all ancestor segments match
|
|
119
|
+
for (let i = 0; i < ancestorPaths.length; i++) {
|
|
120
|
+
if (ancestorPaths[i] !== parentPaths[i]) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
// For node events, check if the node is a descendant
|
|
127
|
+
if (event instanceof NodeConnectedEvent ||
|
|
128
|
+
event instanceof NodeDisconnectedEvent) {
|
|
129
|
+
const nodeAddr = event.nodeAddress;
|
|
130
|
+
const nodePaths = nodeAddr.paths;
|
|
131
|
+
const ancestorPaths = ancestorAddress.paths;
|
|
132
|
+
// Descendant must have more path segments
|
|
133
|
+
if (nodePaths.length <= ancestorPaths.length) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
// Check all ancestor segments match
|
|
137
|
+
for (let i = 0; i < ancestorPaths.length; i++) {
|
|
138
|
+
if (ancestorPaths[i] !== nodePaths[i]) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get the address from an event based on its type
|
|
148
|
+
*/
|
|
149
|
+
static getEventAddress(event) {
|
|
150
|
+
if (event instanceof NodeConnectedEvent ||
|
|
151
|
+
event instanceof NodeDisconnectedEvent) {
|
|
152
|
+
return event.nodeAddress;
|
|
153
|
+
}
|
|
154
|
+
if (event instanceof ChildJoinedEvent || event instanceof ChildLeftEvent) {
|
|
155
|
+
return event.childAddress;
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|