homebridge 2.0.0-alpha.40 → 2.0.0-alpha.41
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/config-sample.json +1 -12
- package/dist/api.d.ts +4 -20
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -27
- package/dist/api.js.map +1 -1
- package/dist/bridgeService.d.ts +12 -15
- package/dist/bridgeService.d.ts.map +1 -1
- package/dist/bridgeService.js +7 -7
- package/dist/bridgeService.js.map +1 -1
- package/dist/childBridgeService.d.ts +1 -0
- package/dist/childBridgeService.d.ts.map +1 -1
- package/dist/childBridgeService.js +1 -0
- package/dist/childBridgeService.js.map +1 -1
- package/dist/childMatterBridgeFork.d.ts +108 -0
- package/dist/childMatterBridgeFork.d.ts.map +1 -0
- package/dist/childMatterBridgeFork.js +330 -0
- package/dist/childMatterBridgeFork.js.map +1 -0
- package/dist/childMatterBridgeService.d.ts +166 -0
- package/dist/childMatterBridgeService.d.ts.map +1 -0
- package/dist/childMatterBridgeService.js +623 -0
- package/dist/childMatterBridgeService.js.map +1 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/ipcService.d.ts +19 -3
- package/dist/ipcService.d.ts.map +1 -1
- package/dist/ipcService.js +13 -0
- package/dist/ipcService.js.map +1 -1
- package/dist/matter/index.d.ts +13 -0
- package/dist/matter/index.d.ts.map +1 -0
- package/dist/matter/index.js +12 -0
- package/dist/matter/index.js.map +1 -0
- package/dist/matter/matterBridge.d.ts +64 -0
- package/dist/matter/matterBridge.d.ts.map +1 -0
- package/dist/matter/matterBridge.js +154 -0
- package/dist/matter/matterBridge.js.map +1 -0
- package/dist/matter/matterConfigValidator.d.ts +27 -0
- package/dist/matter/matterConfigValidator.d.ts.map +1 -0
- package/dist/matter/matterConfigValidator.js +162 -0
- package/dist/matter/matterConfigValidator.js.map +1 -0
- package/dist/matter/matterDevice.d.ts +107 -0
- package/dist/matter/matterDevice.d.ts.map +1 -0
- package/dist/matter/matterDevice.js +913 -0
- package/dist/matter/matterDevice.js.map +1 -0
- package/dist/matter/matterDiagnostics.d.ts +121 -0
- package/dist/matter/matterDiagnostics.d.ts.map +1 -0
- package/dist/matter/matterDiagnostics.js +323 -0
- package/dist/matter/matterDiagnostics.js.map +1 -0
- package/dist/matter/matterErrorHandler.d.ts +113 -0
- package/dist/matter/matterErrorHandler.d.ts.map +1 -0
- package/dist/matter/matterErrorHandler.js +482 -0
- package/dist/matter/matterErrorHandler.js.map +1 -0
- package/dist/matter/matterNetworkMonitor.d.ts +65 -0
- package/dist/matter/matterNetworkMonitor.d.ts.map +1 -0
- package/dist/matter/matterNetworkMonitor.js +227 -0
- package/dist/matter/matterNetworkMonitor.js.map +1 -0
- package/dist/matter/matterServer.d.ts +110 -0
- package/dist/matter/matterServer.d.ts.map +1 -0
- package/dist/matter/matterServer.js +584 -0
- package/dist/matter/matterServer.js.map +1 -0
- package/dist/matter/matterSharedTypes.d.ts +167 -0
- package/dist/matter/matterSharedTypes.d.ts.map +1 -0
- package/dist/matter/matterSharedTypes.js +55 -0
- package/dist/matter/matterSharedTypes.js.map +1 -0
- package/dist/{matterTypes.d.ts → matter/matterTypes.d.ts} +15 -0
- package/dist/matter/matterTypes.d.ts.map +1 -0
- package/dist/{matterTypes.js → matter/matterTypes.js} +4 -4
- package/dist/matter/matterTypes.js.map +1 -0
- package/dist/matter/portAllocator.d.ts +85 -0
- package/dist/matter/portAllocator.d.ts.map +1 -0
- package/dist/matter/portAllocator.js +296 -0
- package/dist/matter/portAllocator.js.map +1 -0
- package/dist/server.d.ts +9 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +363 -31
- package/dist/server.js.map +1 -1
- package/package.json +10 -10
- package/dist/matterConfigValidator.d.ts +0 -34
- package/dist/matterConfigValidator.d.ts.map +0 -1
- package/dist/matterConfigValidator.js +0 -249
- package/dist/matterConfigValidator.js.map +0 -1
- package/dist/matterService.d.ts +0 -168
- package/dist/matterService.d.ts.map +0 -1
- package/dist/matterService.js +0 -677
- package/dist/matterService.js.map +0 -1
- package/dist/matterTypes.d.ts.map +0 -1
- package/dist/matterTypes.js.map +0 -1
- package/dist/util/matter-cli.d.ts +0 -3
- package/dist/util/matter-cli.d.ts.map +0 -1
- package/dist/util/matter-cli.js +0 -211
- package/dist/util/matter-cli.js.map +0 -1
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
/* global NodeJS */
|
|
2
|
+
/**
|
|
3
|
+
* Real Matter.js Server Implementation
|
|
4
|
+
*
|
|
5
|
+
* Complete Matter.js integration
|
|
6
|
+
* and official Matter.js v0.15 documentation
|
|
7
|
+
*/
|
|
8
|
+
import * as crypto from 'node:crypto';
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
import { access } from 'node:fs/promises';
|
|
11
|
+
import * as os from 'node:os';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import process from 'node:process';
|
|
14
|
+
import { Endpoint, Environment, ServerNode, StorageService, VendorId, } from '@matter/main';
|
|
15
|
+
import { AggregatorEndpoint } from '@matter/main/endpoints';
|
|
16
|
+
import { ManualPairingCodeCodec, QrPairingCodeCodec, } from '@matter/types/schema';
|
|
17
|
+
import * as fse from 'fs-extra';
|
|
18
|
+
import QRCode from 'qrcode-terminal';
|
|
19
|
+
import { Logger } from '../logger.js';
|
|
20
|
+
import getVersion from '../version.js';
|
|
21
|
+
import { MatterDevice } from './matterDevice.js';
|
|
22
|
+
import { diagnostics } from './matterDiagnostics.js';
|
|
23
|
+
import { errorHandler } from './matterErrorHandler.js';
|
|
24
|
+
import { networkMonitor } from './matterNetworkMonitor.js';
|
|
25
|
+
const log = Logger.withPrefix('Matter');
|
|
26
|
+
/**
|
|
27
|
+
* Real Matter.js Server for Homebridge
|
|
28
|
+
* Creates a Matter bridge that exposes HAP accessories to Matter controllers
|
|
29
|
+
*/
|
|
30
|
+
export class MatterServer {
|
|
31
|
+
config;
|
|
32
|
+
serverNode = null;
|
|
33
|
+
aggregator = null;
|
|
34
|
+
devices = new Map();
|
|
35
|
+
removedDevices = new Set(); // Track removed devices for restart
|
|
36
|
+
isRunning = false;
|
|
37
|
+
restartTimer = null;
|
|
38
|
+
isRestarting = false;
|
|
39
|
+
MAX_DEVICES = 1000; // Maximum number of devices
|
|
40
|
+
MAX_REMOVED_DEVICES = 10; // Trigger restart after this many removals
|
|
41
|
+
RESTART_DELAY_MS = 30000; // Delay before restarting server
|
|
42
|
+
shutdownHandler = null;
|
|
43
|
+
// Internal commissioning values (generated, not user-configurable)
|
|
44
|
+
passcode;
|
|
45
|
+
discriminator;
|
|
46
|
+
vendorId;
|
|
47
|
+
productId;
|
|
48
|
+
commissioningInfo = {};
|
|
49
|
+
serialNumber;
|
|
50
|
+
cleanupHandlers = [];
|
|
51
|
+
constructor(config = {}) {
|
|
52
|
+
this.config = config;
|
|
53
|
+
// Store the user config with defaults
|
|
54
|
+
this.config = {
|
|
55
|
+
port: config.port || 5540,
|
|
56
|
+
name: config.name || 'Homebridge Matter Bridge',
|
|
57
|
+
// Use a consistent uniqueId based on the name to ensure storage persistence
|
|
58
|
+
uniqueId: config.uniqueId || `homebridge-matter-${config.name?.replace(/[^a-z0-9]/gi, '-') || 'bridge'}`,
|
|
59
|
+
storagePath: config.storagePath,
|
|
60
|
+
mdnsInterface: config.mdnsInterface,
|
|
61
|
+
ipv4: config.ipv4 !== false, // Default to true
|
|
62
|
+
ipv6: config.ipv6 !== false, // Default to true
|
|
63
|
+
};
|
|
64
|
+
// Generate internal commissioning values
|
|
65
|
+
this.passcode = this.generateSecurePasscode();
|
|
66
|
+
this.discriminator = this.generateRandomDiscriminator();
|
|
67
|
+
this.vendorId = 0xFFF1; // Test vendor ID
|
|
68
|
+
this.productId = 0x8001; // Test product ID
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generate a secure random passcode
|
|
72
|
+
*/
|
|
73
|
+
generateSecurePasscode() {
|
|
74
|
+
let passcode;
|
|
75
|
+
const maxAttempts = 100;
|
|
76
|
+
let attempts = 0;
|
|
77
|
+
const invalidPasscodes = [
|
|
78
|
+
0,
|
|
79
|
+
11111111,
|
|
80
|
+
22222222,
|
|
81
|
+
33333333,
|
|
82
|
+
44444444,
|
|
83
|
+
55555555,
|
|
84
|
+
66666666,
|
|
85
|
+
77777777,
|
|
86
|
+
88888888,
|
|
87
|
+
99999999,
|
|
88
|
+
12345678,
|
|
89
|
+
87654321,
|
|
90
|
+
];
|
|
91
|
+
do {
|
|
92
|
+
// Use cryptographically secure random number generation
|
|
93
|
+
const randomBytes = crypto.randomBytes(4);
|
|
94
|
+
const randomValue = randomBytes.readUInt32BE(0);
|
|
95
|
+
passcode = (randomValue % 99999998) + 1;
|
|
96
|
+
attempts++;
|
|
97
|
+
if (attempts > maxAttempts) {
|
|
98
|
+
throw new Error('Failed to generate secure passcode after maximum attempts');
|
|
99
|
+
}
|
|
100
|
+
} while (invalidPasscodes.includes(passcode)
|
|
101
|
+
|| passcode.toString().padStart(8, '0').length !== 8);
|
|
102
|
+
return passcode;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Generate a random discriminator
|
|
106
|
+
*/
|
|
107
|
+
generateRandomDiscriminator() {
|
|
108
|
+
// Generate cryptographically secure random 12-bit discriminator (0-4095)
|
|
109
|
+
const randomBytes = crypto.randomBytes(2);
|
|
110
|
+
return randomBytes.readUInt16BE(0) & 0x0FFF; // Mask to 12 bits
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Start the Matter server
|
|
114
|
+
*/
|
|
115
|
+
async start() {
|
|
116
|
+
if (this.isRunning) {
|
|
117
|
+
log.warn('Matter server is already running');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
log.info('Starting Matter.js server...');
|
|
122
|
+
log.info(`Configuration: Port=${this.config.port}, Passcode=${this.passcode}, Discriminator=${this.discriminator}`);
|
|
123
|
+
// Validate and set up storage path
|
|
124
|
+
await this.setupStorage();
|
|
125
|
+
// Start network monitoring
|
|
126
|
+
networkMonitor.startMonitoring();
|
|
127
|
+
this.cleanupHandlers.push(() => networkMonitor.stopMonitoring());
|
|
128
|
+
// Start diagnostics
|
|
129
|
+
diagnostics.startDiagnostics();
|
|
130
|
+
this.cleanupHandlers.push(() => diagnostics.stopDiagnostics());
|
|
131
|
+
// Create commissioning options
|
|
132
|
+
const commissioningOptions = {
|
|
133
|
+
passcode: this.passcode,
|
|
134
|
+
discriminator: this.discriminator,
|
|
135
|
+
};
|
|
136
|
+
// Ensure we have a name for the bridge
|
|
137
|
+
const bridgeName = this.config.name || 'Homebridge Matter Bridge';
|
|
138
|
+
// Create node options with proper typing
|
|
139
|
+
const nodeOptions = {
|
|
140
|
+
id: this.config.uniqueId,
|
|
141
|
+
network: {
|
|
142
|
+
port: this.config.port,
|
|
143
|
+
ipv4: this.config.ipv4,
|
|
144
|
+
ipv6: this.config.ipv6,
|
|
145
|
+
mdnsInterface: this.config.mdnsInterface,
|
|
146
|
+
},
|
|
147
|
+
commissioning: commissioningOptions,
|
|
148
|
+
productDescription: {
|
|
149
|
+
name: bridgeName, // This should be the user-visible name
|
|
150
|
+
deviceType: AggregatorEndpoint.deviceType,
|
|
151
|
+
},
|
|
152
|
+
basicInformation: {
|
|
153
|
+
// Try setting nodeLabel to the bridge name instead of product name
|
|
154
|
+
nodeLabel: bridgeName.slice(0, 32), // Maximum 32 characters
|
|
155
|
+
vendorId: VendorId(this.vendorId),
|
|
156
|
+
vendorName: 'Homebridge'.slice(0, 32),
|
|
157
|
+
productId: this.productId,
|
|
158
|
+
productName: 'Homebridge Matter Bridge'.slice(0, 32),
|
|
159
|
+
// Set productLabel to bridge name as well
|
|
160
|
+
productLabel: bridgeName.slice(0, 64), // Maximum 64 characters
|
|
161
|
+
serialNumber: this.serialNumber = this.generateSerialNumber(),
|
|
162
|
+
hardwareVersion: 1,
|
|
163
|
+
hardwareVersionString: os.release(), // Hardware version
|
|
164
|
+
softwareVersion: 1,
|
|
165
|
+
softwareVersionString: getVersion(), // Shows as "Firmware" in Home app
|
|
166
|
+
reachable: true,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
// Create server node with proper configuration
|
|
170
|
+
this.serverNode = await ServerNode.create(nodeOptions);
|
|
171
|
+
// Create aggregator endpoint for bridge pattern
|
|
172
|
+
// The bridge name is set via the ServerNode's basicInformation
|
|
173
|
+
this.aggregator = new Endpoint(AggregatorEndpoint, {
|
|
174
|
+
id: 'homebridge-aggregator',
|
|
175
|
+
});
|
|
176
|
+
// Add aggregator to server
|
|
177
|
+
await this.serverNode.add(this.aggregator);
|
|
178
|
+
// Generate and display commissioning information
|
|
179
|
+
await this.generateCommissioningInfo();
|
|
180
|
+
// Set up graceful shutdown handler
|
|
181
|
+
this.shutdownHandler = async () => {
|
|
182
|
+
log.info('Shutting down Matter server...');
|
|
183
|
+
await this.stop();
|
|
184
|
+
};
|
|
185
|
+
// Register shutdown handlers
|
|
186
|
+
process.on('SIGINT', this.shutdownHandler);
|
|
187
|
+
process.on('SIGTERM', this.shutdownHandler);
|
|
188
|
+
// Start the server in a non-blocking way
|
|
189
|
+
this.serverNode.run().then(() => {
|
|
190
|
+
log.info('Matter server stopped normally');
|
|
191
|
+
}, (error) => {
|
|
192
|
+
log.error('Matter server stopped with error:', error);
|
|
193
|
+
errorHandler.handleError(error, 'server-runtime');
|
|
194
|
+
});
|
|
195
|
+
// Wait for server to be ready
|
|
196
|
+
await this.waitForServerReady();
|
|
197
|
+
this.isRunning = true;
|
|
198
|
+
log.info(`✅ Matter server started successfully on port ${this.config.port}`);
|
|
199
|
+
log.info('Homebridge accessories can now be added to Matter controllers');
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
log.error('Failed to start Matter server:', error);
|
|
203
|
+
await this.cleanup();
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Set up and validate storage
|
|
209
|
+
*/
|
|
210
|
+
async setupStorage() {
|
|
211
|
+
if (!this.config.storagePath) {
|
|
212
|
+
throw new Error('Storage path is required for Matter server');
|
|
213
|
+
}
|
|
214
|
+
// Resolve to absolute path and validate
|
|
215
|
+
const storagePath = path.resolve(this.config.storagePath);
|
|
216
|
+
const normalizedPath = path.normalize(storagePath);
|
|
217
|
+
// Ensure path is within allowed directories
|
|
218
|
+
const allowedBasePaths = [
|
|
219
|
+
path.resolve(os.homedir(), '.homebridge'),
|
|
220
|
+
path.resolve(process.cwd()),
|
|
221
|
+
'/var/lib/homebridge', // Common system location
|
|
222
|
+
];
|
|
223
|
+
const isAllowed = allowedBasePaths.some(basePath => normalizedPath.startsWith(basePath));
|
|
224
|
+
if (!isAllowed || normalizedPath.includes('..')) {
|
|
225
|
+
throw new Error(`Storage path not allowed: ${normalizedPath}. Must be within homebridge directories.`);
|
|
226
|
+
}
|
|
227
|
+
// Ensure the storage directory exists with proper permissions
|
|
228
|
+
try {
|
|
229
|
+
await fse.ensureDir(normalizedPath);
|
|
230
|
+
await access(normalizedPath, fs.constants.R_OK | fs.constants.W_OK);
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
throw new Error(`Storage path not accessible: ${error}`);
|
|
234
|
+
}
|
|
235
|
+
// Create Matter-specific storage directory with bridge-specific subfolder
|
|
236
|
+
const bridgeId = this.config.uniqueId?.replace(/[^a-z0-9-]/gi, '_') || 'default';
|
|
237
|
+
const matterStoragePath = path.join(normalizedPath, '.matter', bridgeId);
|
|
238
|
+
await fse.ensureDir(matterStoragePath);
|
|
239
|
+
// Configure environment to use our storage
|
|
240
|
+
const environment = Environment.default;
|
|
241
|
+
const storageService = environment.get(StorageService);
|
|
242
|
+
storageService.location = matterStoragePath;
|
|
243
|
+
log.info(`✅ Matter storage initialized at: ${matterStoragePath}`);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Generate serial number for the bridge
|
|
247
|
+
*/
|
|
248
|
+
generateSerialNumber() {
|
|
249
|
+
const timestamp = Date.now().toString(36).toUpperCase();
|
|
250
|
+
const random = crypto.randomBytes(2).toString('hex').toUpperCase();
|
|
251
|
+
return `HB-${timestamp}-${random}`;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Generate and display commissioning information
|
|
255
|
+
*/
|
|
256
|
+
async generateCommissioningInfo() {
|
|
257
|
+
const passcode = this.passcode.toString().padStart(8, '0');
|
|
258
|
+
const discriminator = this.discriminator;
|
|
259
|
+
const vendorId = this.vendorId;
|
|
260
|
+
const productId = this.productId;
|
|
261
|
+
// Use Matter.js library to generate pairing codes properly
|
|
262
|
+
// Generate 11-digit code (without vendor/product IDs) for better compatibility
|
|
263
|
+
const manualCode = ManualPairingCodeCodec.encode({
|
|
264
|
+
discriminator,
|
|
265
|
+
passcode: this.passcode,
|
|
266
|
+
// Omit vendorId and productId to generate 11-digit code instead of 21-digit
|
|
267
|
+
});
|
|
268
|
+
// Format as XXXX-XXX-XXXX for display
|
|
269
|
+
const manualPairingCode = `${manualCode.slice(0, 4)}-${manualCode.slice(4, 7)}-${manualCode.slice(7, 11)}`;
|
|
270
|
+
const qrCodePayload = QrPairingCodeCodec.encode([{
|
|
271
|
+
version: 0,
|
|
272
|
+
vendorId,
|
|
273
|
+
productId,
|
|
274
|
+
flowType: 0, // Standard commissioning flow
|
|
275
|
+
discoveryCapabilities: 4, // OnNetwork=4
|
|
276
|
+
discriminator,
|
|
277
|
+
passcode: this.passcode,
|
|
278
|
+
}]);
|
|
279
|
+
// Store commissioning info
|
|
280
|
+
this.commissioningInfo = {
|
|
281
|
+
qrCode: qrCodePayload,
|
|
282
|
+
manualPairingCode,
|
|
283
|
+
};
|
|
284
|
+
// Display commissioning information
|
|
285
|
+
log.info(`\n${'='.repeat(60)}`);
|
|
286
|
+
log.info('📱 MATTER COMMISSIONING INFORMATION');
|
|
287
|
+
log.info('='.repeat(60));
|
|
288
|
+
log.info(`Manual Pairing Code: ${manualPairingCode}`);
|
|
289
|
+
log.info(`Passcode: ${passcode}`);
|
|
290
|
+
log.info(`Discriminator: ${discriminator}`);
|
|
291
|
+
log.info('\nQR Code for commissioning:');
|
|
292
|
+
// Generate and display QR code in terminal
|
|
293
|
+
QRCode.generate(qrCodePayload, { small: true }, (qrcode) => {
|
|
294
|
+
// eslint-disable-next-line no-console
|
|
295
|
+
console.log(qrcode);
|
|
296
|
+
});
|
|
297
|
+
log.info(`${'='.repeat(60)}\n`);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Wait for the server to be ready
|
|
301
|
+
*/
|
|
302
|
+
async waitForServerReady(maxWaitTime = 5000) {
|
|
303
|
+
const startTime = Date.now();
|
|
304
|
+
while (!this.serverNode || !this.aggregator) {
|
|
305
|
+
if (Date.now() - startTime > maxWaitTime) {
|
|
306
|
+
throw new Error('Server failed to become ready within timeout');
|
|
307
|
+
}
|
|
308
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
309
|
+
}
|
|
310
|
+
// Additional small delay to ensure everything is initialized
|
|
311
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Add a Homebridge accessory as a bridged Matter device
|
|
315
|
+
*/
|
|
316
|
+
async addAccessory(accessory) {
|
|
317
|
+
if (!this.serverNode || !this.aggregator) {
|
|
318
|
+
log.error('Matter server not started - cannot add accessory');
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
// Check device limit
|
|
322
|
+
if (this.devices.size >= this.MAX_DEVICES) {
|
|
323
|
+
log.error(`Device limit reached (${this.MAX_DEVICES}), cannot add ${accessory.displayName}`);
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
if (this.devices.has(accessory.UUID)) {
|
|
327
|
+
log.debug(`Accessory ${accessory.displayName} already exists as Matter device`);
|
|
328
|
+
return this.devices.get(accessory.UUID) || null;
|
|
329
|
+
}
|
|
330
|
+
try {
|
|
331
|
+
log.info(`Adding Matter device: ${accessory.displayName}`);
|
|
332
|
+
// Create Matter device from HAP accessory
|
|
333
|
+
const matterDevice = new MatterDevice(accessory);
|
|
334
|
+
const endpoint = await matterDevice.createEndpoint();
|
|
335
|
+
if (!endpoint) {
|
|
336
|
+
log.warn(`Could not create Matter endpoint for: ${accessory.displayName}`);
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
// Add to aggregator (bridge)
|
|
340
|
+
log.debug(`Adding endpoint to aggregator for ${accessory.displayName} (UUID: ${accessory.UUID})`);
|
|
341
|
+
await this.aggregator.add(endpoint);
|
|
342
|
+
// Store for management
|
|
343
|
+
this.devices.set(accessory.UUID, matterDevice);
|
|
344
|
+
// Set up bidirectional sync
|
|
345
|
+
matterDevice.startSync();
|
|
346
|
+
log.info(`Added Matter device: ${accessory.displayName} (${matterDevice.getDeviceType()})`);
|
|
347
|
+
return matterDevice;
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
log.error(`Failed to add Matter device for ${accessory.displayName}:`, error);
|
|
351
|
+
await errorHandler.handleError(error, 'add-accessory');
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Remove a Matter device
|
|
357
|
+
*/
|
|
358
|
+
async removeAccessory(accessory) {
|
|
359
|
+
const device = this.devices.get(accessory.UUID);
|
|
360
|
+
if (!device) {
|
|
361
|
+
log.debug(`No Matter device found for: ${accessory.displayName}`);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
try {
|
|
365
|
+
// Stop sync
|
|
366
|
+
device.stopSync();
|
|
367
|
+
// Get endpoint to remove
|
|
368
|
+
const endpoint = await device.getEndpoint();
|
|
369
|
+
if (endpoint && this.aggregator) {
|
|
370
|
+
// Remove from aggregator
|
|
371
|
+
// Note: Matter.js v0.15 doesn't provide a direct API to remove endpoints
|
|
372
|
+
// from an aggregator after they're added. This is a limitation of the current API.
|
|
373
|
+
// The endpoint will be cleaned up when the server stops.
|
|
374
|
+
log.debug('Endpoint marked for removal - will be cleaned up on server restart');
|
|
375
|
+
// Track removed devices and schedule restart if threshold reached
|
|
376
|
+
this.removedDevices.add(accessory.UUID);
|
|
377
|
+
if (this.removedDevices.size >= this.MAX_REMOVED_DEVICES) {
|
|
378
|
+
log.warn(`Reached ${this.MAX_REMOVED_DEVICES} removed devices - scheduling Matter server restart in 30 seconds`);
|
|
379
|
+
this.scheduleRestart();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// Clean up device
|
|
383
|
+
await device.destroy();
|
|
384
|
+
this.devices.delete(accessory.UUID);
|
|
385
|
+
log.info(`Removed Matter device: ${accessory.displayName}`);
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
log.error(`Failed to remove Matter device for ${accessory.displayName}:`, error);
|
|
389
|
+
await errorHandler.handleError(error, 'remove-accessory');
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Schedule a server restart to clean up removed endpoints
|
|
394
|
+
*/
|
|
395
|
+
scheduleRestart() {
|
|
396
|
+
// Prevent scheduling if already restarting
|
|
397
|
+
if (this.isRestarting) {
|
|
398
|
+
log.debug('Restart already in progress, skipping schedule');
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
// Cancel any existing restart timer
|
|
402
|
+
if (this.restartTimer) {
|
|
403
|
+
clearTimeout(this.restartTimer);
|
|
404
|
+
}
|
|
405
|
+
this.restartTimer = setTimeout(async () => {
|
|
406
|
+
// Check again in case state changed
|
|
407
|
+
if (this.isRestarting) {
|
|
408
|
+
log.debug('Restart already in progress, skipping');
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
this.isRestarting = true;
|
|
412
|
+
log.info('Restarting Matter server to clean up removed endpoints...');
|
|
413
|
+
try {
|
|
414
|
+
// Save current devices
|
|
415
|
+
const currentDevices = Array.from(this.devices.values());
|
|
416
|
+
// Stop server
|
|
417
|
+
await this.stop();
|
|
418
|
+
// Clear removed devices tracking
|
|
419
|
+
this.removedDevices.clear();
|
|
420
|
+
// Wait a moment
|
|
421
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
422
|
+
// Restart server
|
|
423
|
+
await this.start();
|
|
424
|
+
// Re-add current devices
|
|
425
|
+
for (const device of currentDevices) {
|
|
426
|
+
const accessory = device.getAccessory();
|
|
427
|
+
if (accessory) {
|
|
428
|
+
await this.addAccessory(accessory);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
log.info('Matter server restarted successfully');
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
log.error('Failed to restart Matter server:', error);
|
|
435
|
+
}
|
|
436
|
+
finally {
|
|
437
|
+
this.isRestarting = false;
|
|
438
|
+
this.restartTimer = null;
|
|
439
|
+
}
|
|
440
|
+
}, this.RESTART_DELAY_MS);
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Get server information
|
|
444
|
+
*/
|
|
445
|
+
getInfo() {
|
|
446
|
+
// Record diagnostics info (async, fire and forget)
|
|
447
|
+
diagnostics.collectDiagnostics({
|
|
448
|
+
enabled: true,
|
|
449
|
+
initialized: this.serverNode !== null,
|
|
450
|
+
running: this.isRunning,
|
|
451
|
+
port: this.config.port,
|
|
452
|
+
deviceCount: this.devices.size,
|
|
453
|
+
bridgeCount: 1,
|
|
454
|
+
}).catch(error => log.debug('Failed to collect diagnostics:', error));
|
|
455
|
+
return {
|
|
456
|
+
running: this.isRunning,
|
|
457
|
+
port: this.config.port,
|
|
458
|
+
deviceCount: this.devices.size,
|
|
459
|
+
config: this.config,
|
|
460
|
+
serialNumber: this.serialNumber,
|
|
461
|
+
commissioned: this.isCommissioned(),
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Get commissioning information
|
|
466
|
+
*/
|
|
467
|
+
getCommissioningInfo() {
|
|
468
|
+
return {
|
|
469
|
+
...this.commissioningInfo,
|
|
470
|
+
commissioned: this.isCommissioned(),
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Check if the server is commissioned
|
|
475
|
+
*/
|
|
476
|
+
isCommissioned() {
|
|
477
|
+
// Type-safe check for commissioning state
|
|
478
|
+
try {
|
|
479
|
+
const serverState = this.serverNode;
|
|
480
|
+
return serverState?.state?.commissioning?.commissioned === true;
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Get all Matter devices
|
|
488
|
+
*/
|
|
489
|
+
getDevices() {
|
|
490
|
+
return this.devices;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Stop the Matter server
|
|
494
|
+
*/
|
|
495
|
+
async stop() {
|
|
496
|
+
if (!this.isRunning) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
log.info('Stopping Matter server...');
|
|
500
|
+
// Stop monitoring
|
|
501
|
+
networkMonitor.stopMonitoring();
|
|
502
|
+
diagnostics.stopDiagnostics();
|
|
503
|
+
try {
|
|
504
|
+
// Clean up all devices
|
|
505
|
+
for (const device of this.devices.values()) {
|
|
506
|
+
try {
|
|
507
|
+
device.stopSync();
|
|
508
|
+
await device.destroy();
|
|
509
|
+
}
|
|
510
|
+
catch (error) {
|
|
511
|
+
log.error('Failed to clean up device:', error);
|
|
512
|
+
await errorHandler.handleError(error, 'device-cleanup');
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
this.devices.clear();
|
|
516
|
+
// Stop server
|
|
517
|
+
if (this.serverNode) {
|
|
518
|
+
await this.serverNode.close();
|
|
519
|
+
}
|
|
520
|
+
await this.cleanup();
|
|
521
|
+
log.info('Matter server stopped');
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
log.error('Error stopping Matter server:', error);
|
|
525
|
+
await errorHandler.handleError(error, 'server-stop');
|
|
526
|
+
throw error;
|
|
527
|
+
}
|
|
528
|
+
finally {
|
|
529
|
+
this.isRunning = false;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Cleanup resources
|
|
534
|
+
*/
|
|
535
|
+
async cleanup() {
|
|
536
|
+
// Remove signal handlers
|
|
537
|
+
if (this.shutdownHandler) {
|
|
538
|
+
process.off('SIGINT', this.shutdownHandler);
|
|
539
|
+
process.off('SIGTERM', this.shutdownHandler);
|
|
540
|
+
this.shutdownHandler = null;
|
|
541
|
+
}
|
|
542
|
+
// Run all cleanup handlers
|
|
543
|
+
for (const handler of this.cleanupHandlers) {
|
|
544
|
+
try {
|
|
545
|
+
await handler();
|
|
546
|
+
}
|
|
547
|
+
catch (error) {
|
|
548
|
+
log.debug('Error during cleanup handler:', error);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
this.cleanupHandlers = [];
|
|
552
|
+
// Cancel any pending restart
|
|
553
|
+
if (this.restartTimer) {
|
|
554
|
+
clearTimeout(this.restartTimer);
|
|
555
|
+
this.restartTimer = null;
|
|
556
|
+
}
|
|
557
|
+
// Clear references
|
|
558
|
+
this.serverNode = null;
|
|
559
|
+
this.aggregator = null;
|
|
560
|
+
this.isRunning = false;
|
|
561
|
+
this.commissioningInfo = {};
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Clean up all devices
|
|
565
|
+
*/
|
|
566
|
+
async cleanupAllDevices() {
|
|
567
|
+
const cleanupPromises = [];
|
|
568
|
+
for (const [uuid, device] of this.devices.entries()) {
|
|
569
|
+
cleanupPromises.push((async () => {
|
|
570
|
+
try {
|
|
571
|
+
log.debug(`Cleaning up device: ${uuid}`);
|
|
572
|
+
device.stopSync();
|
|
573
|
+
await device.destroy();
|
|
574
|
+
}
|
|
575
|
+
catch (error) {
|
|
576
|
+
log.error(`Failed to clean up device ${uuid}:`, error);
|
|
577
|
+
}
|
|
578
|
+
})());
|
|
579
|
+
}
|
|
580
|
+
await Promise.all(cleanupPromises);
|
|
581
|
+
this.devices.clear();
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
//# sourceMappingURL=matterServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterServer.js","sourceRoot":"","sources":["../../src/matter/matterServer.ts"],"names":[],"mappings":"AAAA,mBAAmB;AAEnB;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,OAAO,EACL,QAAQ,EACR,WAAW,EACX,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,MAAM,MAAM,iBAAiB,CAAA;AAEpC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,OAAO,UAAU,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAG1D,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;AAKvC;;;GAGG;AACH,MAAM,OAAO,YAAY;IA4BM;IA3BrB,UAAU,GAAsB,IAAI,CAAA;IACpC,UAAU,GAA+C,IAAI,CAAA;IAC7D,OAAO,GAA8B,IAAI,GAAG,EAAE,CAAA;IAC9C,cAAc,GAAG,IAAI,GAAG,EAAU,CAAA,CAAC,oCAAoC;IACvE,SAAS,GAAG,KAAK,CAAA;IACjB,YAAY,GAA0B,IAAI,CAAA;IAC1C,YAAY,GAAG,KAAK,CAAA;IACX,WAAW,GAAG,IAAI,CAAA,CAAC,4BAA4B;IAC/C,mBAAmB,GAAG,EAAE,CAAA,CAAC,2CAA2C;IACpE,gBAAgB,GAAG,KAAK,CAAA,CAAC,iCAAiC;IACnE,eAAe,GAAiC,IAAI,CAAA;IAC5D,mEAAmE;IAC3D,QAAQ,CAAQ;IAChB,aAAa,CAAQ;IACrB,QAAQ,CAAQ;IAChB,SAAS,CAAQ;IAEjB,iBAAiB,GAIrB,EAAE,CAAA;IAEE,YAAY,CAAS;IAErB,eAAe,GAAsC,EAAE,CAAA;IAE/D,YAA6B,SAA6B,EAAE;QAA/B,WAAM,GAAN,MAAM,CAAyB;QAC1D,sCAAsC;QACtC,IAAI,CAAC,MAAM,GAAG;YACZ,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,0BAA0B;YAC/C,4EAA4E;YAC5E,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,qBAAqB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE;YACxG,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,kBAAkB;YAC/C,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,kBAAkB;SAChD,CAAA;QAED,yCAAyC;QACzC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAA;QAC7C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,2BAA2B,EAAE,CAAA;QACvD,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAA,CAAC,iBAAiB;QACxC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAA,CAAC,kBAAkB;IAC5C,CAAC;IAED;;OAEG;IACK,sBAAsB;QAC5B,IAAI,QAAgB,CAAA;QACpB,MAAM,WAAW,GAAG,GAAG,CAAA;QACvB,IAAI,QAAQ,GAAG,CAAC,CAAA;QAEhB,MAAM,gBAAgB,GAAG;YACvB,CAAC;YACD,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ;SACT,CAAA;QAED,GAAG,CAAC;YACF,wDAAwD;YACxD,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;YACzC,MAAM,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;YAC/C,QAAQ,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;YAEvC,QAAQ,EAAE,CAAA;YACV,IAAI,QAAQ,GAAG,WAAW,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;YAC9E,CAAC;QACH,CAAC,QACC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC;eAChC,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EACrD;QAED,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED;;OAEG;IACK,2BAA2B;QACjC,yEAAyE;QACzE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QACzC,OAAO,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAAA,CAAC,kBAAkB;IAChE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;YAC5C,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;YACxC,GAAG,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,MAAM,CAAC,IAAI,cAAc,IAAI,CAAC,QAAQ,mBAAmB,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;YAEnH,mCAAmC;YACnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;YAEzB,2BAA2B;YAC3B,cAAc,CAAC,eAAe,EAAE,CAAA;YAChC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC,CAAA;YAEhE,oBAAoB;YACpB,WAAW,CAAC,gBAAgB,EAAE,CAAA;YAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,CAAA;YAE9D,+BAA+B;YAC/B,MAAM,oBAAoB,GAAG;gBAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAA;YAED,uCAAuC;YACvC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,0BAA0B,CAAA;YAEjE,yCAAyC;YACzC,MAAM,WAAW,GAAG;gBAClB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,QAAS;gBACzB,OAAO,EAAE;oBACP,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;oBACtB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;oBACtB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;oBACtB,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa;iBACzC;gBACD,aAAa,EAAE,oBAAoB;gBACnC,kBAAkB,EAAE;oBAClB,IAAI,EAAE,UAAU,EAAE,uCAAuC;oBACzD,UAAU,EAAE,kBAAkB,CAAC,UAAU;iBAC1C;gBACD,gBAAgB,EAAE;oBAChB,mEAAmE;oBACnE,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,wBAAwB;oBAC5D,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;oBACjC,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBACrC,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,WAAW,EAAE,0BAA0B,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBACpD,0CAA0C;oBAC1C,YAAY,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,wBAAwB;oBAC/D,YAAY,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE;oBAC7D,eAAe,EAAE,CAAC;oBAClB,qBAAqB,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,mBAAmB;oBACxD,eAAe,EAAE,CAAC;oBAClB,qBAAqB,EAAE,UAAU,EAAE,EAAE,kCAAkC;oBACvE,SAAS,EAAE,IAAI;iBAChB;aACF,CAAA;YAED,+CAA+C;YAC/C,IAAI,CAAC,UAAU,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAEtD,gDAAgD;YAChD,+DAA+D;YAC/D,IAAI,CAAC,UAAU,GAAG,IAAI,QAAQ,CAAC,kBAAkB,EAAE;gBACjD,EAAE,EAAE,uBAAuB;aAC5B,CAAC,CAAA;YAEF,2BAA2B;YAC3B,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAE1C,iDAAiD;YACjD,MAAM,IAAI,CAAC,yBAAyB,EAAE,CAAA;YAEtC,mCAAmC;YACnC,IAAI,CAAC,eAAe,GAAG,KAAK,IAAI,EAAE;gBAChC,GAAG,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;gBAC1C,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;YACnB,CAAC,CAAA;YAED,6BAA6B;YAC7B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;YAC1C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;YAE3C,yCAAyC;YACzC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CACxB,GAAG,EAAE;gBACH,GAAG,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;YAC5C,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;gBACR,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAA;gBACrD,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAA;YACnD,CAAC,CACF,CAAA;YAED,8BAA8B;YAC9B,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAA;YAE/B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;YACrB,GAAG,CAAC,IAAI,CAAC,gDAAgD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;YAC5E,GAAG,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAA;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAA;YAClD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;YACpB,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;QAC/D,CAAC;QAED,wCAAwC;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QACzD,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;QAElD,4CAA4C;QAC5C,MAAM,gBAAgB,GAAG;YACvB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC;YACzC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC3B,qBAAqB,EAAE,yBAAyB;SACjD,CAAA;QAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CACjD,cAAc,CAAC,UAAU,CAAC,QAAQ,CAAC,CACpC,CAAA;QAED,IAAI,CAAC,SAAS,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,6BAA6B,cAAc,0CAA0C,CAAC,CAAA;QACxG,CAAC;QAED,8DAA8D;QAC9D,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;YACnC,MAAM,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACrE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAA;QAC1D,CAAC;QAED,0EAA0E;QAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,IAAI,SAAS,CAAA;QAChF,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAA;QACxE,MAAM,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAEtC,2CAA2C;QAC3C,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAA;QACvC,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACtD,cAAc,CAAC,QAAQ,GAAG,iBAAiB,CAAA;QAE3C,GAAG,CAAC,IAAI,CAAC,oCAAoC,iBAAiB,EAAE,CAAC,CAAA;IACnE,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;QAClE,OAAO,MAAM,SAAS,IAAI,MAAM,EAAE,CAAA;IACpC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,yBAAyB;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC1D,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAA;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAEhC,2DAA2D;QAC3D,+EAA+E;QAC/E,MAAM,UAAU,GAAG,sBAAsB,CAAC,MAAM,CAAC;YAC/C,aAAa;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,4EAA4E;SAC7E,CAAC,CAAA;QAEF,sCAAsC;QACtC,MAAM,iBAAiB,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAA;QAE1G,MAAM,aAAa,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBAC/C,OAAO,EAAE,CAAC;gBACV,QAAQ;gBACR,SAAS;gBACT,QAAQ,EAAE,CAAC,EAAE,8BAA8B;gBAC3C,qBAAqB,EAAE,CAAC,EAAE,cAAc;gBACxC,aAAa;gBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC,CAAA;QAEH,2BAA2B;QAC3B,IAAI,CAAC,iBAAiB,GAAG;YACvB,MAAM,EAAE,aAAa;YACrB,iBAAiB;SAClB,CAAA;QAED,oCAAoC;QACpC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;QAC/B,GAAG,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAA;QAC/C,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QACxB,GAAG,CAAC,IAAI,CAAC,wBAAwB,iBAAiB,EAAE,CAAC,CAAA;QACrD,GAAG,CAAC,IAAI,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAA;QACjC,GAAG,CAAC,IAAI,CAAC,kBAAkB,aAAa,EAAE,CAAC,CAAA;QAC3C,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;QAExC,2CAA2C;QAC3C,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE;YACzD,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACrB,CAAC,CAAC,CAAA;QAEF,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAAC,WAAW,GAAG,IAAI;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAE5B,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,WAAW,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;YACjE,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;QACxD,CAAC;QAED,6DAA6D;QAC7D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,SAA4B;QAC7C,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,GAAG,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAA;YAC7D,OAAO,IAAI,CAAA;QACb,CAAC;QAED,qBAAqB;QACrB,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,GAAG,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,WAAW,iBAAiB,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;YAC5F,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,GAAG,CAAC,KAAK,CAAC,aAAa,SAAS,CAAC,WAAW,kCAAkC,CAAC,CAAA;YAC/E,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;QACjD,CAAC;QAED,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,yBAAyB,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;YAE1D,0CAA0C;YAC1C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAA;YAChD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAA;YAEpD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,GAAG,CAAC,IAAI,CAAC,yCAAyC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;gBAC1E,OAAO,IAAI,CAAA;YACb,CAAC;YAED,6BAA6B;YAC7B,GAAG,CAAC,KAAK,CAAC,qCAAqC,SAAS,CAAC,WAAW,WAAW,SAAS,CAAC,IAAI,GAAG,CAAC,CAAA;YACjG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAEnC,uBAAuB;YACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;YAE9C,4BAA4B;YAC5B,YAAY,CAAC,SAAS,EAAE,CAAA;YAExB,GAAG,CAAC,IAAI,CAAC,wBAAwB,SAAS,CAAC,WAAW,KAAK,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,CAAA;YAC3F,OAAO,YAAY,CAAA;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,mCAAmC,SAAS,CAAC,WAAW,GAAG,EAAE,KAAK,CAAC,CAAA;YAC7E,MAAM,YAAY,CAAC,WAAW,CAAC,KAAc,EAAE,eAAe,CAAC,CAAA;YAC/D,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,SAA4B;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,KAAK,CAAC,+BAA+B,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;YACjE,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,YAAY;YACZ,MAAM,CAAC,QAAQ,EAAE,CAAA;YAEjB,yBAAyB;YACzB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAA;YAE3C,IAAI,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChC,yBAAyB;gBACzB,yEAAyE;gBACzE,mFAAmF;gBACnF,yDAAyD;gBACzD,GAAG,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAA;gBAE/E,kEAAkE;gBAClE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;gBAEvC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBACzD,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,mBAAmB,mEAAmE,CAAC,CAAA;oBAChH,IAAI,CAAC,eAAe,EAAE,CAAA;gBACxB,CAAC;YACH,CAAC;YAED,kBAAkB;YAClB,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;YACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YAEnC,GAAG,CAAC,IAAI,CAAC,0BAA0B,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,sCAAsC,SAAS,CAAC,WAAW,GAAG,EAAE,KAAK,CAAC,CAAA;YAChF,MAAM,YAAY,CAAC,WAAW,CAAC,KAAc,EAAE,kBAAkB,CAAC,CAAA;QACpE,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe;QACrB,2CAA2C;QAC3C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,GAAG,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAA;YAC3D,OAAM;QACR,CAAC;QAED,oCAAoC;QACpC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACjC,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YACxC,oCAAoC;YACpC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,GAAG,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAA;gBAClD,OAAM;YACR,CAAC;YAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;YACxB,GAAG,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;YAErE,IAAI,CAAC;gBACH,uBAAuB;gBACvB,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;gBAExD,cAAc;gBACd,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;gBAEjB,iCAAiC;gBACjC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;gBAE3B,gBAAgB;gBAChB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;gBAEvD,iBAAiB;gBACjB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;gBAElB,yBAAyB;gBACzB,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;oBACpC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;oBACvC,IAAI,SAAS,EAAE,CAAC;wBACd,MAAM,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;oBACpC,CAAC;gBACH,CAAC;gBAED,GAAG,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAA;YAClD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAA;YACtD,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;gBACzB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;YAC1B,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;IAC3B,CAAC;IAED;;OAEG;IACH,OAAO;QAQL,mDAAmD;QACnD,WAAW,CAAC,kBAAkB,CAAC;YAC7B,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,IAAI,CAAC,UAAU,KAAK,IAAI;YACrC,OAAO,EAAE,IAAI,CAAC,SAAS;YACvB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YAC9B,WAAW,EAAE,CAAC;SACf,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC,CAAA;QAErE,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,SAAS;YACvB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAK;YACvB,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,cAAc,EAAE;SACpC,CAAA;IACH,CAAC;IAED;;OAEG;IACH,oBAAoB;QAKlB,OAAO;YACL,GAAG,IAAI,CAAC,iBAAiB;YACzB,YAAY,EAAE,IAAI,CAAC,cAAc,EAAE;SACpC,CAAA;IACH,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,0CAA0C;QAC1C,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAI,CAAC,UAAiB,CAAA;YAC1C,OAAO,WAAW,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,KAAK,IAAI,CAAA;QACjE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;QAErC,kBAAkB;QAClB,cAAc,CAAC,cAAc,EAAE,CAAA;QAC/B,WAAW,CAAC,eAAe,EAAE,CAAA;QAE7B,IAAI,CAAC;YACH,uBAAuB;YACvB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC3C,IAAI,CAAC;oBACH,MAAM,CAAC,QAAQ,EAAE,CAAA;oBACjB,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;gBACxB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,GAAG,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAA;oBAC9C,MAAM,YAAY,CAAC,WAAW,CAAC,KAAc,EAAE,gBAAgB,CAAC,CAAA;gBAClE,CAAC;YACH,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;YAEpB,cAAc;YACd,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;YAC/B,CAAC;YAED,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;YACpB,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;YACjD,MAAM,YAAY,CAAC,WAAW,CAAC,KAAc,EAAE,aAAa,CAAC,CAAA;YAC7D,MAAM,KAAK,CAAA;QACb,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACxB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,OAAO;QACnB,yBAAyB;QACzB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;YAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;YAC5C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;QAC7B,CAAC;QAED,2BAA2B;QAC3B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,OAAO,EAAE,CAAA;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;YACnD,CAAC;QACH,CAAC;QACD,IAAI,CAAC,eAAe,GAAG,EAAE,CAAA;QAEzB,6BAA6B;QAC7B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;QAC1B,CAAC;QAED,mBAAmB;QACnB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACtB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACtB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAA;IAC7B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB;QAC7B,MAAM,eAAe,GAAoB,EAAE,CAAA;QAE3C,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,eAAe,CAAC,IAAI,CAClB,CAAC,KAAK,IAAI,EAAE;gBACV,IAAI,CAAC;oBACH,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAA;oBACxC,MAAM,CAAC,QAAQ,EAAE,CAAA;oBACjB,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;gBACxB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,GAAG,CAAC,KAAK,CAAC,6BAA6B,IAAI,GAAG,EAAE,KAAK,CAAC,CAAA;gBACxD,CAAC;YACH,CAAC,CAAC,EAAE,CACL,CAAA;QACH,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;QAClC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC;CACF"}
|