pelagora 0.1.5

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.
Files changed (122) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/LICENSE +663 -0
  3. package/README.md +139 -0
  4. package/dist/ai/product-lookup.d.ts +26 -0
  5. package/dist/ai/product-lookup.d.ts.map +1 -0
  6. package/dist/ai/product-lookup.js +153 -0
  7. package/dist/ai/product-lookup.js.map +1 -0
  8. package/dist/api/collections.d.ts +3 -0
  9. package/dist/api/collections.d.ts.map +1 -0
  10. package/dist/api/collections.js +69 -0
  11. package/dist/api/collections.js.map +1 -0
  12. package/dist/api/favorites.d.ts +3 -0
  13. package/dist/api/favorites.d.ts.map +1 -0
  14. package/dist/api/favorites.js +43 -0
  15. package/dist/api/favorites.js.map +1 -0
  16. package/dist/api/health.d.ts +12 -0
  17. package/dist/api/health.d.ts.map +1 -0
  18. package/dist/api/health.js +54 -0
  19. package/dist/api/health.js.map +1 -0
  20. package/dist/api/index.d.ts +3 -0
  21. package/dist/api/index.d.ts.map +1 -0
  22. package/dist/api/index.js +56 -0
  23. package/dist/api/index.js.map +1 -0
  24. package/dist/api/items.d.ts +3 -0
  25. package/dist/api/items.d.ts.map +1 -0
  26. package/dist/api/items.js +170 -0
  27. package/dist/api/items.js.map +1 -0
  28. package/dist/api/media.d.ts +3 -0
  29. package/dist/api/media.d.ts.map +1 -0
  30. package/dist/api/media.js +241 -0
  31. package/dist/api/media.js.map +1 -0
  32. package/dist/api/negotiations.d.ts +3 -0
  33. package/dist/api/negotiations.d.ts.map +1 -0
  34. package/dist/api/negotiations.js +244 -0
  35. package/dist/api/negotiations.js.map +1 -0
  36. package/dist/api/offers.d.ts +3 -0
  37. package/dist/api/offers.d.ts.map +1 -0
  38. package/dist/api/offers.js +57 -0
  39. package/dist/api/offers.js.map +1 -0
  40. package/dist/api/refs.d.ts +3 -0
  41. package/dist/api/refs.d.ts.map +1 -0
  42. package/dist/api/refs.js +390 -0
  43. package/dist/api/refs.js.map +1 -0
  44. package/dist/api/scans.d.ts +3 -0
  45. package/dist/api/scans.d.ts.map +1 -0
  46. package/dist/api/scans.js +384 -0
  47. package/dist/api/scans.js.map +1 -0
  48. package/dist/api/settings.d.ts +3 -0
  49. package/dist/api/settings.d.ts.map +1 -0
  50. package/dist/api/settings.js +442 -0
  51. package/dist/api/settings.js.map +1 -0
  52. package/dist/db/index.d.ts +4 -0
  53. package/dist/db/index.d.ts.map +1 -0
  54. package/dist/db/index.js +18 -0
  55. package/dist/db/index.js.map +1 -0
  56. package/dist/db/queries.d.ts +237 -0
  57. package/dist/db/queries.d.ts.map +1 -0
  58. package/dist/db/queries.js +891 -0
  59. package/dist/db/queries.js.map +1 -0
  60. package/dist/db/schema.d.ts +6 -0
  61. package/dist/db/schema.d.ts.map +1 -0
  62. package/dist/db/schema.js +531 -0
  63. package/dist/db/schema.js.map +1 -0
  64. package/dist/dht/discovery.d.ts +33 -0
  65. package/dist/dht/discovery.d.ts.map +1 -0
  66. package/dist/dht/discovery.js +281 -0
  67. package/dist/dht/discovery.js.map +1 -0
  68. package/dist/dht/index.d.ts +2 -0
  69. package/dist/dht/index.d.ts.map +1 -0
  70. package/dist/dht/index.js +6 -0
  71. package/dist/dht/index.js.map +1 -0
  72. package/dist/index.d.ts +2 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +215 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/ref-schemas.d.ts +59 -0
  77. package/dist/ref-schemas.d.ts.map +1 -0
  78. package/dist/ref-schemas.js +1038 -0
  79. package/dist/ref-schemas.js.map +1 -0
  80. package/dist/skills/export.d.ts +12 -0
  81. package/dist/skills/export.d.ts.map +1 -0
  82. package/dist/skills/export.js +54 -0
  83. package/dist/skills/export.js.map +1 -0
  84. package/dist/skills/index.d.ts +4 -0
  85. package/dist/skills/index.d.ts.map +1 -0
  86. package/dist/skills/index.js +11 -0
  87. package/dist/skills/index.js.map +1 -0
  88. package/dist/skills/loader.d.ts +37 -0
  89. package/dist/skills/loader.d.ts.map +1 -0
  90. package/dist/skills/loader.js +183 -0
  91. package/dist/skills/loader.js.map +1 -0
  92. package/dist/skills/registry.d.ts +37 -0
  93. package/dist/skills/registry.d.ts.map +1 -0
  94. package/dist/skills/registry.js +136 -0
  95. package/dist/skills/registry.js.map +1 -0
  96. package/dist/sync/index.d.ts +58 -0
  97. package/dist/sync/index.d.ts.map +1 -0
  98. package/dist/sync/index.js +331 -0
  99. package/dist/sync/index.js.map +1 -0
  100. package/dist/sync/reffo-client.d.ts +144 -0
  101. package/dist/sync/reffo-client.d.ts.map +1 -0
  102. package/dist/sync/reffo-client.js +279 -0
  103. package/dist/sync/reffo-client.js.map +1 -0
  104. package/dist/taxonomy.d.ts +4 -0
  105. package/dist/taxonomy.d.ts.map +1 -0
  106. package/dist/taxonomy.js +141 -0
  107. package/dist/taxonomy.js.map +1 -0
  108. package/dist/types/index.d.ts +198 -0
  109. package/dist/types/index.d.ts.map +1 -0
  110. package/dist/types/index.js +25 -0
  111. package/dist/types/index.js.map +1 -0
  112. package/dist/ui.d.ts +2 -0
  113. package/dist/ui.d.ts.map +1 -0
  114. package/dist/ui.js +6786 -0
  115. package/dist/ui.js.map +1 -0
  116. package/dist/version.d.ts +2 -0
  117. package/dist/version.d.ts.map +1 -0
  118. package/dist/version.js +14 -0
  119. package/dist/version.js.map +1 -0
  120. package/footer-brand.png +0 -0
  121. package/header-brand.png +0 -0
  122. package/package.json +61 -0
@@ -0,0 +1,33 @@
1
+ import type { PeerMessage, QueryPayload } from '@pelagora/pim-protocol';
2
+ export declare class DhtDiscovery {
3
+ private swarm;
4
+ private beaconId;
5
+ private peers;
6
+ private beaconIdMap;
7
+ private messageHandlers;
8
+ private onPeerConnect?;
9
+ httpPort: number;
10
+ constructor(beaconId: string);
11
+ start(onPeerConnect?: (count: number) => void): Promise<void>;
12
+ private sendAnnouncement;
13
+ /** Register a custom message handler for skill-defined message types */
14
+ registerMessageHandler(type: string, handler: (fromBeaconId: string, payload: unknown) => void): void;
15
+ /** Broadcast a message to all connected peers */
16
+ broadcastToPeers(msg: PeerMessage): void;
17
+ private handleMessage;
18
+ private handleQuery;
19
+ /** Map a Hyperswarm peer stream to its Reffo beaconId */
20
+ private updatePeerBeaconId;
21
+ /** Send a message to a specific peer by their Reffo beaconId */
22
+ sendToPeer(targetBeaconId: string, msg: PeerMessage): boolean;
23
+ /** Handle incoming proposal from a buyer */
24
+ private handleProposal;
25
+ /** Handle incoming proposal response from a seller */
26
+ private handleProposalResponse;
27
+ /** Query all connected peers and collect responses */
28
+ queryPeers(query: QueryPayload, timeoutMs?: number): Promise<PeerMessage[]>;
29
+ get peerCount(): number;
30
+ get isConnected(): boolean;
31
+ stop(): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/dht/discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAA6D,MAAM,wBAAwB,CAAC;AAMnI,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAA6D;IAC1E,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,eAAe,CAAuE;IAC9F,OAAO,CAAC,aAAa,CAAC,CAA0B;IAChD,QAAQ,SAAK;gBAED,QAAQ,EAAE,MAAM;IAKtB,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCnE,OAAO,CAAC,gBAAgB;IAkCxB,wEAAwE;IACxE,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAIrG,iDAAiD;IACjD,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAWxC,OAAO,CAAC,aAAa;IA6BrB,OAAO,CAAC,WAAW;IA+DnB,yDAAyD;IACzD,OAAO,CAAC,kBAAkB;IAS1B,gEAAgE;IAChE,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO;IAsB7D,4CAA4C;IAC5C,OAAO,CAAC,cAAc;IAkBtB,sDAAsD;IACtD,OAAO,CAAC,sBAAsB;IAkB9B,sDAAsD;IACtD,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA2BzE,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK5B"}
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DhtDiscovery = void 0;
7
+ const hyperswarm_1 = __importDefault(require("hyperswarm"));
8
+ const b4a_1 = __importDefault(require("b4a"));
9
+ const crypto_1 = __importDefault(require("crypto"));
10
+ const db_1 = require("../db");
11
+ const pim_protocol_1 = require("@pelagora/pim-protocol");
12
+ // All Reffo beacons join this topic to find each other
13
+ const REFFO_TOPIC = crypto_1.default.createHash('sha256').update('reffo-beacon-v1').digest();
14
+ class DhtDiscovery {
15
+ swarm;
16
+ beaconId;
17
+ peers = new Map();
18
+ beaconIdMap = new Map(); // reffoBeaconId -> hyperswarm peerId
19
+ messageHandlers = new Map();
20
+ onPeerConnect;
21
+ httpPort = 0;
22
+ constructor(beaconId) {
23
+ this.swarm = new hyperswarm_1.default();
24
+ this.beaconId = beaconId;
25
+ }
26
+ async start(onPeerConnect) {
27
+ this.onPeerConnect = onPeerConnect;
28
+ this.swarm.on('connection', (stream, info) => {
29
+ const peerId = b4a_1.default.toString(stream.remotePublicKey, 'hex');
30
+ console.log(`[DHT] Peer connected: ${peerId.slice(0, 8)}...`);
31
+ this.peers.set(peerId, { stream, beaconId: peerId });
32
+ this.onPeerConnect?.(this.peers.size);
33
+ // Send our announcement on connect
34
+ this.sendAnnouncement(stream);
35
+ stream.on('data', (data) => {
36
+ const msg = (0, pim_protocol_1.parseDhtMessage)(b4a_1.default.toString(data));
37
+ if (msg)
38
+ this.handleMessage(msg, stream);
39
+ });
40
+ stream.on('close', () => {
41
+ this.peers.delete(peerId);
42
+ console.log(`[DHT] Peer disconnected: ${peerId.slice(0, 8)}...`);
43
+ this.onPeerConnect?.(this.peers.size);
44
+ });
45
+ stream.on('error', () => {
46
+ this.peers.delete(peerId);
47
+ this.onPeerConnect?.(this.peers.size);
48
+ });
49
+ });
50
+ // Join the Reffo topic so all beacons can discover each other
51
+ const discovery = this.swarm.join(REFFO_TOPIC, { server: true, client: true });
52
+ await discovery.flushed();
53
+ console.log(`[DHT] Joined Pelagora network. Topic: ${b4a_1.default.toString(REFFO_TOPIC, 'hex').slice(0, 16)}...`);
54
+ }
55
+ sendAnnouncement(stream) {
56
+ const refs = new db_1.RefQueries();
57
+ const offers = new db_1.OfferQueries();
58
+ const discoverableRefs = refs.listDiscoverable();
59
+ const discoverableRefIds = new Set(discoverableRefs.map(i => i.id));
60
+ const payload = {
61
+ refs: discoverableRefs.map(i => {
62
+ const blurred = (i.locationLat != null && i.locationLng != null)
63
+ ? (0, pim_protocol_1.blurLocation)(i.locationLat, i.locationLng) : null;
64
+ return {
65
+ id: i.id, name: i.name, category: i.category, subcategory: i.subcategory, listingStatus: i.listingStatus,
66
+ locationLat: blurred?.lat, locationLng: blurred?.lng,
67
+ locationCity: i.locationCity, locationState: i.locationState,
68
+ locationZip: i.locationZip, locationCountry: i.locationCountry,
69
+ sellingScope: i.sellingScope, sellingRadiusMiles: i.sellingRadiusMiles,
70
+ };
71
+ }),
72
+ offers: offers.list().filter(o => discoverableRefIds.has(o.refId)).map(o => ({
73
+ id: o.id, refId: o.refId, price: o.price,
74
+ priceCurrency: o.priceCurrency, status: o.status,
75
+ })),
76
+ };
77
+ const msg = {
78
+ type: 'announce',
79
+ beaconId: this.beaconId,
80
+ payload,
81
+ };
82
+ stream.write(b4a_1.default.from(JSON.stringify(msg)));
83
+ }
84
+ /** Register a custom message handler for skill-defined message types */
85
+ registerMessageHandler(type, handler) {
86
+ this.messageHandlers.set(type, handler);
87
+ }
88
+ /** Broadcast a message to all connected peers */
89
+ broadcastToPeers(msg) {
90
+ const msgBuf = b4a_1.default.from(JSON.stringify(msg));
91
+ for (const [, peer] of this.peers) {
92
+ try {
93
+ peer.stream.write(msgBuf);
94
+ }
95
+ catch {
96
+ // Ignore write errors to individual peers
97
+ }
98
+ }
99
+ }
100
+ handleMessage(msg, stream) {
101
+ switch (msg.type) {
102
+ case 'query':
103
+ this.handleQuery(msg.payload, stream, msg.beaconId);
104
+ break;
105
+ case 'announce':
106
+ console.log(`[DHT] Received announcement from ${msg.beaconId.slice(0, 8)}...`);
107
+ this.updatePeerBeaconId(stream, msg.beaconId);
108
+ break;
109
+ case 'response':
110
+ // Responses are handled by the caller
111
+ break;
112
+ case 'proposal':
113
+ this.handleProposal(msg.beaconId, msg.payload);
114
+ break;
115
+ case 'proposal_response':
116
+ this.handleProposalResponse(msg.beaconId, msg.payload);
117
+ break;
118
+ default: {
119
+ // Check for skill-registered message handlers
120
+ const handler = this.messageHandlers.get(msg.type);
121
+ if (handler) {
122
+ handler(msg.beaconId, msg.payload);
123
+ }
124
+ break;
125
+ }
126
+ }
127
+ }
128
+ handleQuery(query, stream, fromBeacon) {
129
+ console.log(`[DHT] Query from ${fromBeacon.slice(0, 8)}...:`, query);
130
+ const refs = new db_1.RefQueries();
131
+ const offers = new db_1.OfferQueries();
132
+ const mediaQ = new db_1.MediaQueries();
133
+ const searchTerm = query.search ? (0, pim_protocol_1.sanitizeField)(query.search, 'search') : undefined;
134
+ let results = searchTerm
135
+ ? refs.searchDiscoverable(searchTerm)
136
+ : refs.listDiscoverable(query.category, query.subcategory);
137
+ // Build response with matching offers
138
+ const matchingOffers = results.flatMap(ref => {
139
+ const refOffers = offers.list(ref.id).filter(o => o.status === 'active');
140
+ if (query.maxPrice !== undefined) {
141
+ return refOffers.filter(o => o.price <= query.maxPrice);
142
+ }
143
+ return refOffers;
144
+ });
145
+ // Geo-filter if query has lat/lng/radiusMiles
146
+ if (query.lat != null && query.lng != null && query.radiusMiles != null) {
147
+ results = results.filter(ref => {
148
+ const scope = ref.sellingScope || 'global';
149
+ if (scope === 'global')
150
+ return true;
151
+ if (scope === 'national')
152
+ return true;
153
+ if (ref.locationLat == null || ref.locationLng == null)
154
+ return true; // no location = show everywhere
155
+ const dist = (0, pim_protocol_1.haversineDistanceMiles)(query.lat, query.lng, ref.locationLat, ref.locationLng);
156
+ if (scope === 'range')
157
+ return dist <= (ref.sellingRadiusMiles || Infinity);
158
+ return dist <= query.radiusMiles;
159
+ });
160
+ }
161
+ // Include media metadata per item
162
+ const mediaMap = {};
163
+ for (const ref of results) {
164
+ const media = mediaQ.listForRef(ref.id);
165
+ if (media.length > 0) {
166
+ mediaMap[ref.id] = media.map(m => ({ id: m.id, filePath: m.filePath, mediaType: m.mediaType }));
167
+ }
168
+ }
169
+ // Blur location in response — never send exact lat/lng or address
170
+ const blurredResults = results.map(ref => {
171
+ const blurred = (ref.locationLat != null && ref.locationLng != null)
172
+ ? (0, pim_protocol_1.blurLocation)(ref.locationLat, ref.locationLng) : null;
173
+ return {
174
+ ...ref,
175
+ locationLat: blurred?.lat,
176
+ locationLng: blurred?.lng,
177
+ locationAddress: undefined, // never share street address
178
+ };
179
+ });
180
+ const response = {
181
+ type: 'response',
182
+ beaconId: this.beaconId,
183
+ payload: { refs: blurredResults, offers: matchingOffers, media: mediaMap, httpPort: this.httpPort },
184
+ };
185
+ stream.write(b4a_1.default.from(JSON.stringify(response)));
186
+ }
187
+ /** Map a Hyperswarm peer stream to its Reffo beaconId */
188
+ updatePeerBeaconId(stream, reffoBeaconId) {
189
+ const peerId = b4a_1.default.toString(stream.remotePublicKey, 'hex');
190
+ const peer = this.peers.get(peerId);
191
+ if (peer) {
192
+ peer.beaconId = reffoBeaconId;
193
+ this.beaconIdMap.set(reffoBeaconId, peerId);
194
+ }
195
+ }
196
+ /** Send a message to a specific peer by their Reffo beaconId */
197
+ sendToPeer(targetBeaconId, msg) {
198
+ // Look up by beaconId map first
199
+ const peerId = this.beaconIdMap.get(targetBeaconId);
200
+ if (peerId) {
201
+ const peer = this.peers.get(peerId);
202
+ if (peer) {
203
+ peer.stream.write(b4a_1.default.from(JSON.stringify(msg)));
204
+ return true;
205
+ }
206
+ }
207
+ // Fallback: search all peers
208
+ for (const [, peer] of this.peers) {
209
+ if (peer.beaconId === targetBeaconId) {
210
+ peer.stream.write(b4a_1.default.from(JSON.stringify(msg)));
211
+ return true;
212
+ }
213
+ }
214
+ return false;
215
+ }
216
+ /** Handle incoming proposal from a buyer */
217
+ handleProposal(fromBeaconId, payload) {
218
+ console.log(`[DHT] Received proposal from ${fromBeaconId.slice(0, 8)}... for ref ${payload.refId}`);
219
+ const negotiations = new db_1.NegotiationQueries();
220
+ const clean = (0, pim_protocol_1.sanitizeObject)(payload);
221
+ negotiations.create({
222
+ id: clean.negotiationId,
223
+ refId: clean.refId,
224
+ refName: clean.refName || '',
225
+ buyerBeaconId: fromBeaconId,
226
+ sellerBeaconId: this.beaconId,
227
+ price: clean.price,
228
+ priceCurrency: clean.priceCurrency || 'USD',
229
+ message: clean.message || '',
230
+ role: 'seller',
231
+ });
232
+ }
233
+ /** Handle incoming proposal response from a seller */
234
+ handleProposalResponse(fromBeaconId, payload) {
235
+ console.log(`[DHT] Received proposal response from ${fromBeaconId.slice(0, 8)}... for negotiation ${payload.negotiationId}`);
236
+ const negotiations = new db_1.NegotiationQueries();
237
+ const existing = negotiations.get(payload.negotiationId);
238
+ if (!existing || existing.role !== 'buyer') {
239
+ console.log(`[DHT] Unknown or invalid negotiation: ${payload.negotiationId}`);
240
+ return;
241
+ }
242
+ negotiations.updateStatus(payload.negotiationId, payload.status, payload.counterPrice, payload.responseMessage);
243
+ }
244
+ /** Query all connected peers and collect responses */
245
+ queryPeers(query, timeoutMs = 5000) {
246
+ return new Promise((resolve) => {
247
+ const responses = [];
248
+ const msg = {
249
+ type: 'query',
250
+ beaconId: this.beaconId,
251
+ payload: query,
252
+ };
253
+ const msgBuf = b4a_1.default.from(JSON.stringify(msg));
254
+ for (const [, peer] of this.peers) {
255
+ const handler = (data) => {
256
+ const resp = (0, pim_protocol_1.parseDhtMessage)(b4a_1.default.toString(data));
257
+ if (resp && resp.type === 'response') {
258
+ responses.push(resp);
259
+ peer.stream.off('data', handler);
260
+ }
261
+ };
262
+ peer.stream.on('data', handler);
263
+ peer.stream.write(msgBuf);
264
+ }
265
+ setTimeout(() => resolve(responses), timeoutMs);
266
+ });
267
+ }
268
+ get peerCount() {
269
+ return this.peers.size;
270
+ }
271
+ get isConnected() {
272
+ return true; // Swarm is always "connected" once started
273
+ }
274
+ async stop() {
275
+ await this.swarm.destroy();
276
+ this.peers.clear();
277
+ console.log('[DHT] Disconnected from Pelagora network');
278
+ }
279
+ }
280
+ exports.DhtDiscovery = DhtDiscovery;
281
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/dht/discovery.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AACpC,8CAAsB;AACtB,oDAA4B;AAC5B,8BAAmF;AAEnF,yDAA8H;AAE9H,uDAAuD;AACvD,MAAM,WAAW,GAAG,gBAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,MAAM,EAAE,CAAC;AAEnF,MAAa,YAAY;IACf,KAAK,CAAa;IAClB,QAAQ,CAAS;IACjB,KAAK,GAAmD,IAAI,GAAG,EAAE,CAAC;IAClE,WAAW,GAAwB,IAAI,GAAG,EAAE,CAAC,CAAC,qCAAqC;IACnF,eAAe,GAAG,IAAI,GAAG,EAA4D,CAAC;IACtF,aAAa,CAA2B;IAChD,QAAQ,GAAG,CAAC,CAAC;IAEb,YAAY,QAAgB;QAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,oBAAU,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,aAAuC;QACjD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QAEnC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAW,EAAE,IAAS,EAAE,EAAE;YACrD,MAAM,MAAM,GAAG,aAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAE9D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEtC,mCAAmC;YACnC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAE9B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACjC,MAAM,GAAG,GAAG,IAAA,8BAAe,EAAC,aAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBAChD,IAAI,GAAG;oBAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;gBACjE,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1B,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,8DAA8D;QAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,yCAAyC,aAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAC3G,CAAC;IAEO,gBAAgB,CAAC,MAAW;QAClC,MAAM,IAAI,GAAG,IAAI,eAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,iBAAY,EAAE,CAAC;QAElC,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACjD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpE,MAAM,OAAO,GAAoB;YAC/B,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBAC7B,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC;oBAC9D,CAAC,CAAC,IAAA,2BAAY,EAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACtD,OAAO;oBACL,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC,aAAa;oBACxG,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG;oBACpD,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,aAAa;oBAC5D,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe;oBAC9D,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,kBAAkB,EAAE,CAAC,CAAC,kBAAkB;iBACvE,CAAC;YACJ,CAAC,CAAC;YACF,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC3E,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK;gBACxC,aAAa,EAAE,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM;aACjD,CAAC,CAAC;SACJ,CAAC;QAEF,MAAM,GAAG,GAAgB;YACvB,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO;SACR,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,aAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,wEAAwE;IACxE,sBAAsB,CAAC,IAAY,EAAE,OAAyD;QAC5F,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,iDAAiD;IACjD,gBAAgB,CAAC,GAAgB;QAC/B,MAAM,MAAM,GAAG,aAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,0CAA0C;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,GAAgB,EAAE,MAAW;QACjD,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO;gBACV,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAuB,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACpE,MAAM;YACR,KAAK,UAAU;gBACb,OAAO,CAAC,GAAG,CAAC,oCAAoC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC/E,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC9C,MAAM;YACR,KAAK,UAAU;gBACb,sCAAsC;gBACtC,MAAM;YACR,KAAK,UAAU;gBACb,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAA0B,CAAC,CAAC;gBAClE,MAAM;YACR,KAAK,mBAAmB;gBACtB,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAkC,CAAC,CAAC;gBAClF,MAAM;YACR,OAAO,CAAC,CAAC,CAAC;gBACR,8CAA8C;gBAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACnD,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrC,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,KAAmB,EAAE,MAAW,EAAE,UAAkB;QACtE,OAAO,CAAC,GAAG,CAAC,oBAAoB,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,IAAI,eAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,iBAAY,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,iBAAY,EAAE,CAAC;QAElC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,4BAAa,EAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpF,IAAI,OAAO,GAAG,UAAU;YACtB,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC;YACrC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAE7D,sCAAsC;QACtC,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAC3C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;YACzE,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACjC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,QAAS,CAAC,CAAC;YAC3D,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,IAAI,KAAK,CAAC,GAAG,IAAI,IAAI,IAAI,KAAK,CAAC,GAAG,IAAI,IAAI,IAAI,KAAK,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YACxE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;gBAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC;gBAC3C,IAAI,KAAK,KAAK,QAAQ;oBAAE,OAAO,IAAI,CAAC;gBACpC,IAAI,KAAK,KAAK,UAAU;oBAAE,OAAO,IAAI,CAAC;gBACtC,IAAI,GAAG,CAAC,WAAW,IAAI,IAAI,IAAI,GAAG,CAAC,WAAW,IAAI,IAAI;oBAAE,OAAO,IAAI,CAAC,CAAC,gCAAgC;gBACrG,MAAM,IAAI,GAAG,IAAA,qCAAsB,EAAC,KAAK,CAAC,GAAI,EAAE,KAAK,CAAC,GAAI,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC9F,IAAI,KAAK,KAAK,OAAO;oBAAE,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ,CAAC,CAAC;gBAC3E,OAAO,IAAI,IAAI,KAAK,CAAC,WAAY,CAAC;YACpC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,kCAAkC;QAClC,MAAM,QAAQ,GAA0E,EAAE,CAAC;QAC3F,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAClG,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACvC,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,IAAI,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC;gBAClE,CAAC,CAAC,IAAA,2BAAY,EAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1D,OAAO;gBACL,GAAG,GAAG;gBACN,WAAW,EAAE,OAAO,EAAE,GAAG;gBACzB,WAAW,EAAE,OAAO,EAAE,GAAG;gBACzB,eAAe,EAAE,SAAS,EAAE,6BAA6B;aAC1D,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAgB;YAC5B,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;SACpG,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,aAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,yDAAyD;IACjD,kBAAkB,CAAC,MAAW,EAAE,aAAqB;QAC3D,MAAM,MAAM,GAAG,aAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,aAAa,CAAC;YAC9B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,UAAU,CAAC,cAAsB,EAAE,GAAgB;QACjD,gCAAgC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;gBACrC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4CAA4C;IACpC,cAAc,CAAC,YAAoB,EAAE,OAAwB;QACnE,OAAO,CAAC,GAAG,CAAC,gCAAgC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACpG,MAAM,YAAY,GAAG,IAAI,uBAAkB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAA,6BAAc,EAAC,OAA6C,CAA+B,CAAC;QAE1G,YAAY,CAAC,MAAM,CAAC;YAClB,EAAE,EAAE,KAAK,CAAC,aAAa;YACvB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;YAC5B,aAAa,EAAE,YAAY;YAC3B,cAAc,EAAE,IAAI,CAAC,QAAQ;YAC7B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK;YAC3C,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;YAC5B,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;IACL,CAAC;IAED,sDAAsD;IAC9C,sBAAsB,CAAC,YAAoB,EAAE,OAAgC;QACnF,OAAO,CAAC,GAAG,CAAC,yCAAyC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,uBAAuB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QAC7H,MAAM,YAAY,GAAG,IAAI,uBAAkB,EAAE,CAAC;QAE9C,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,yCAAyC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,YAAY,CAAC,YAAY,CACvB,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,eAAe,CACxB,CAAC;IACJ,CAAC;IAED,sDAAsD;IACtD,UAAU,CAAC,KAAmB,EAAE,SAAS,GAAG,IAAI;QAC9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,SAAS,GAAkB,EAAE,CAAC;YACpC,MAAM,GAAG,GAAgB;gBACvB,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,KAAK;aACf,CAAC;YAEF,MAAM,MAAM,GAAG,aAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAE7C,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAClC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE;oBAC/B,MAAM,IAAI,GAAG,IAAA,8BAAe,EAAC,aAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;oBACjD,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;wBACrC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC,CAAC;gBACF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YAED,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,CAAC,2CAA2C;IAC1D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;CACF;AAjTD,oCAiTC"}
@@ -0,0 +1,2 @@
1
+ export { DhtDiscovery } from './discovery';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dht/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DhtDiscovery = void 0;
4
+ var discovery_1 = require("./discovery");
5
+ Object.defineProperty(exports, "DhtDiscovery", { enumerable: true, get: function () { return discovery_1.DhtDiscovery; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dht/index.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAAlC,yGAAA,YAAY,OAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const crypto_1 = __importDefault(require("crypto"));
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const api_1 = require("./api");
10
+ const health_1 = require("./api/health");
11
+ const dht_1 = require("./dht");
12
+ const db_1 = require("./db");
13
+ const sync_1 = require("./sync");
14
+ const reffo_client_1 = require("./sync/reffo-client");
15
+ const version_1 = require("./version");
16
+ const skills_1 = require("./skills");
17
+ // Load .env into process.env (no dotenv dependency)
18
+ function loadEnv() {
19
+ const envPath = path_1.default.join(process.cwd(), '.env');
20
+ if (!fs_1.default.existsSync(envPath))
21
+ return;
22
+ const content = fs_1.default.readFileSync(envPath, 'utf-8');
23
+ for (const line of content.split('\n')) {
24
+ const trimmed = line.split('#')[0].trim();
25
+ if (!trimmed)
26
+ continue;
27
+ const eqIdx = trimmed.indexOf('=');
28
+ if (eqIdx === -1)
29
+ continue;
30
+ const key = trimmed.slice(0, eqIdx).trim();
31
+ const value = trimmed.slice(eqIdx + 1).trim();
32
+ if (!process.env[key])
33
+ process.env[key] = value;
34
+ }
35
+ }
36
+ loadEnv();
37
+ const PORT = parseInt(process.env.PORT || '3000', 10);
38
+ function getOrCreateBeaconId() {
39
+ if (process.env.BEACON_ID)
40
+ return process.env.BEACON_ID;
41
+ const idFile = path_1.default.join(process.cwd(), 'data', 'beacon-id');
42
+ try {
43
+ return fs_1.default.readFileSync(idFile, 'utf-8').trim();
44
+ }
45
+ catch {
46
+ const id = crypto_1.default.randomUUID();
47
+ fs_1.default.mkdirSync(path_1.default.dirname(idFile), { recursive: true });
48
+ fs_1.default.writeFileSync(idFile, id);
49
+ return id;
50
+ }
51
+ }
52
+ const BEACON_ID = getOrCreateBeaconId();
53
+ async function main() {
54
+ // Ensure uploads directory exists
55
+ fs_1.default.mkdirSync(path_1.default.join(process.cwd(), 'uploads'), { recursive: true });
56
+ // Initialize database
57
+ (0, db_1.getDb)();
58
+ console.log('[DB] SQLite initialized');
59
+ // Create Express app
60
+ const app = (0, api_1.createApp)();
61
+ app.set('beaconId', BEACON_ID);
62
+ app.set('startTime', Date.now());
63
+ (0, health_1.setBeaconId)(BEACON_ID);
64
+ // Initialize Reffo.ai sync if API key is configured
65
+ const reffoApiKey = process.env.REFFO_API_KEY;
66
+ if (reffoApiKey) {
67
+ const reffoUrl = process.env.REFFO_API_URL || 'https://reffo.ai';
68
+ const syncManager = new sync_1.SyncManager(reffoApiKey, BEACON_ID, reffoUrl);
69
+ const beaconUrl = process.env.BEACON_URL || `http://localhost:${PORT}`;
70
+ app.set('syncManager', syncManager);
71
+ syncManager.registerBeacon('Reffo Beacon', (0, version_1.getVersion)(), beaconUrl)
72
+ .then(result => {
73
+ if (result.ok) {
74
+ syncManager.registered = true;
75
+ syncManager.lastError = null;
76
+ console.log('[Sync] Registered with Reffo.ai');
77
+ syncManager.startHeartbeat();
78
+ }
79
+ else {
80
+ syncManager.registered = false;
81
+ syncManager.lastError = result.error || 'Registration failed';
82
+ console.warn('[Sync] Registration failed:', result.error);
83
+ }
84
+ })
85
+ .catch(err => {
86
+ syncManager.lastError = err.message;
87
+ console.warn('[Sync] Registration error:', err.message);
88
+ });
89
+ }
90
+ // Start DHT discovery
91
+ const dht = new dht_1.DhtDiscovery(BEACON_ID);
92
+ dht.httpPort = PORT;
93
+ app.set('dht', dht);
94
+ // Load skill plugins
95
+ const db = (0, db_1.getDb)();
96
+ const skillLoader = new skills_1.SkillLoader(db, BEACON_ID, dht);
97
+ await skillLoader.loadAll(app);
98
+ // Mount skill registry API and export routes
99
+ app.use('/skills', (0, skills_1.createSkillRegistryRouter)(skillLoader.getRegistry()));
100
+ app.use('/skills', (0, skills_1.createSkillExportRouter)(skillLoader.getSkills()));
101
+ // Expose DHT + Reffo search endpoint
102
+ app.get('/search', async (req, res) => {
103
+ const { q, c, sc, maxPrice, lat, lng, radius, source } = req.query;
104
+ const searchSource = typeof source === 'string' ? source : 'all';
105
+ const query = {
106
+ search: typeof q === 'string' ? q : undefined,
107
+ category: typeof c === 'string' ? c : undefined,
108
+ subcategory: typeof sc === 'string' ? sc : undefined,
109
+ maxPrice: typeof maxPrice === 'string' ? parseFloat(maxPrice) : undefined,
110
+ lat: typeof lat === 'string' ? parseFloat(lat) : undefined,
111
+ lng: typeof lng === 'string' ? parseFloat(lng) : undefined,
112
+ radiusMiles: typeof radius === 'string' ? parseFloat(radius) : undefined,
113
+ };
114
+ const dhtPromise = (searchSource === 'reffo')
115
+ ? Promise.resolve([])
116
+ : dht.queryPeers(query);
117
+ const reffoUrl = process.env.REFFO_API_URL || 'https://reffo.ai';
118
+ const reffoPromise = (searchSource === 'beacons')
119
+ ? Promise.resolve({ results: [], total: 0 })
120
+ : (0, reffo_client_1.searchReffo)({
121
+ search: query.search,
122
+ category: query.category,
123
+ lat: query.lat,
124
+ lng: query.lng,
125
+ radiusMiles: query.radiusMiles,
126
+ sort: typeof req.query.sort === 'string' ? req.query.sort : undefined,
127
+ }, reffoUrl);
128
+ const [dhtResult, reffoResult] = await Promise.allSettled([dhtPromise, reffoPromise]);
129
+ const dhtResponses = dhtResult.status === 'fulfilled' ? dhtResult.value : [];
130
+ const reffoData = reffoResult.status === 'fulfilled' ? reffoResult.value : { results: [], total: 0 };
131
+ // Build DHT results with source tag
132
+ const dhtResults = dhtResponses.map(r => ({
133
+ beaconId: r.beaconId,
134
+ source: 'dht',
135
+ ...r.payload,
136
+ }));
137
+ // Convert Reffo results to peer-like format with source tag
138
+ const reffoResults = reffoData.results.map(r => ({
139
+ beaconId: r.beaconId,
140
+ source: 'reffo',
141
+ refs: [{
142
+ id: r.localId,
143
+ name: r.name,
144
+ description: r.description,
145
+ category: r.category,
146
+ subcategory: r.subcategory,
147
+ listingStatus: r.listingStatus,
148
+ condition: r.condition,
149
+ locationCity: r.location?.city || null,
150
+ locationState: r.location?.state || null,
151
+ locationZip: r.location?.zip || null,
152
+ createdAt: r.createdAt,
153
+ }],
154
+ offers: r.price != null ? [{
155
+ refId: r.localId,
156
+ price: r.price,
157
+ priceCurrency: r.currency,
158
+ status: 'active',
159
+ }] : [],
160
+ media: r.photos.length > 0 ? {
161
+ [r.localId]: r.photos.map((url, i) => ({
162
+ mediaType: 'photo',
163
+ filePath: url,
164
+ sortOrder: i,
165
+ })),
166
+ } : {},
167
+ }));
168
+ res.json({
169
+ peers: dhtResults.length,
170
+ reffoTotal: reffoData.total,
171
+ results: [...dhtResults, ...reffoResults],
172
+ });
173
+ });
174
+ await dht.start((peerCount) => {
175
+ (0, health_1.setDhtStatus)({ connected: dht.isConnected, peers: peerCount });
176
+ });
177
+ (0, health_1.setDhtStatus)({ connected: dht.isConnected, peers: dht.peerCount });
178
+ // Start HTTP server
179
+ const server = app.listen(PORT, () => {
180
+ console.log(`[Beacon] Reffo Beacon running on http://localhost:${PORT}`);
181
+ console.log(`[Beacon] ID: ${BEACON_ID.slice(0, 16)}...`);
182
+ console.log(`[Beacon] Endpoints:`);
183
+ console.log(` GET / - Web UI`);
184
+ console.log(` GET /health - Beacon status`);
185
+ console.log(` GET /taxonomy - Category taxonomy`);
186
+ console.log(` GET /refs - List refs`);
187
+ console.log(` POST /refs - Create ref`);
188
+ console.log(` POST /refs/:id/media - Upload media`);
189
+ console.log(` GET /offers - List offers`);
190
+ console.log(` POST /offers - Create offer`);
191
+ console.log(` GET /negotiations - List negotiations`);
192
+ console.log(` POST /negotiations - Create proposal`);
193
+ console.log(` GET /search?q=... - Search peer network`);
194
+ });
195
+ // Graceful shutdown
196
+ const shutdown = async () => {
197
+ console.log('\n[Beacon] Shutting down...');
198
+ server.close();
199
+ // Force exit after 2s if DHT hangs
200
+ const forceExit = setTimeout(() => process.exit(0), 2000);
201
+ try {
202
+ await dht.stop();
203
+ }
204
+ catch { }
205
+ clearTimeout(forceExit);
206
+ process.exit(0);
207
+ };
208
+ process.on('SIGINT', shutdown);
209
+ process.on('SIGTERM', shutdown);
210
+ }
211
+ main().catch((err) => {
212
+ console.error('[Beacon] Fatal error:', err);
213
+ process.exit(1);
214
+ });
215
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Category Schema Definitions for Reffo Refs
3
+ *
4
+ * Each category schema defines:
5
+ * - schemaOrgType: The Schema.org type (e.g., "Car", "SingleFamilyResidence")
6
+ * - traits: Array of trait names this category composes
7
+ * - conditionOptions: Category-appropriate condition values
8
+ * - attributes: Form field definitions with Schema.org property mappings
9
+ * - buildSchemaOrg(): Transforms flat attributes into Schema.org JSON-LD
10
+ */
11
+ export interface AttributeField {
12
+ key: string;
13
+ label: string;
14
+ type: 'text' | 'number' | 'select' | 'boolean';
15
+ placeholder?: string;
16
+ options?: string[];
17
+ schemaOrg?: string;
18
+ summary?: boolean;
19
+ unit?: string;
20
+ }
21
+ export interface CategorySchema {
22
+ schemaOrgType: string;
23
+ additionalType?: string;
24
+ traits: string[];
25
+ conditionOptions: string[];
26
+ attributes: AttributeField[];
27
+ buildSchemaOrg(attrs: Record<string, unknown>): Record<string, unknown>;
28
+ }
29
+ declare const defaultSchema: CategorySchema;
30
+ /**
31
+ * Map of "Category|Subcategory" → CategorySchema.
32
+ * Use getCategorySchema(category, subcategory) for lookup.
33
+ */
34
+ declare const CATEGORY_SCHEMAS: Record<string, CategorySchema>;
35
+ /**
36
+ * Look up the CategorySchema for a given category + subcategory.
37
+ * Returns defaultSchema when no exact match found.
38
+ */
39
+ export declare function getCategorySchema(category?: string, subcategory?: string): CategorySchema;
40
+ /**
41
+ * Build a Schema.org JSON-LD object from a ref's attributes and category schema.
42
+ */
43
+ export declare function buildSchemaOrgLD(category: string | undefined, subcategory: string | undefined, attrs: Record<string, unknown>, baseFields: {
44
+ name?: string;
45
+ description?: string;
46
+ price?: number;
47
+ currency?: string;
48
+ condition?: string;
49
+ image?: string;
50
+ sku?: string;
51
+ createdAt?: string;
52
+ updatedAt?: string;
53
+ offerStatus?: string;
54
+ sellerId?: string;
55
+ offerLocation?: string;
56
+ }): Record<string, unknown>;
57
+ export declare function getAttributeKeys(category?: string, subcategory?: string): string[];
58
+ export { CATEGORY_SCHEMAS, defaultSchema };
59
+ //# sourceMappingURL=ref-schemas.d.ts.map