@quantiya/codevibe-claude-plugin 1.0.10 → 1.0.12

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 (80) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +75 -245
  3. package/dist/server.js +16 -1162
  4. package/node_modules/@quantiya/codevibe-core/README.md +15 -6
  5. package/node_modules/@quantiya/codevibe-core/bin/codevibe.js +1 -1
  6. package/node_modules/@quantiya/codevibe-core/dist/index.js +216 -67
  7. package/node_modules/@quantiya/codevibe-core/package.json +12 -9
  8. package/node_modules/node-abi/abi_registry.json +7 -0
  9. package/node_modules/node-abi/package.json +1 -1
  10. package/package.json +11 -21
  11. package/dist/appsync-client.d.ts +0 -67
  12. package/dist/appsync-client.d.ts.map +0 -1
  13. package/dist/appsync-client.js +0 -858
  14. package/dist/appsync-client.js.map +0 -1
  15. package/dist/auth-cli.d.ts +0 -18
  16. package/dist/auth-cli.d.ts.map +0 -1
  17. package/dist/auth-cli.js +0 -472
  18. package/dist/auth-cli.js.map +0 -1
  19. package/dist/command-executor.d.ts +0 -20
  20. package/dist/command-executor.d.ts.map +0 -1
  21. package/dist/command-executor.js +0 -127
  22. package/dist/command-executor.js.map +0 -1
  23. package/dist/config.d.ts +0 -25
  24. package/dist/config.d.ts.map +0 -1
  25. package/dist/config.js +0 -106
  26. package/dist/config.js.map +0 -1
  27. package/dist/crypto-service.d.ts +0 -115
  28. package/dist/crypto-service.d.ts.map +0 -1
  29. package/dist/crypto-service.js +0 -278
  30. package/dist/crypto-service.js.map +0 -1
  31. package/dist/http-api.d.ts +0 -35
  32. package/dist/http-api.d.ts.map +0 -1
  33. package/dist/http-api.js +0 -334
  34. package/dist/http-api.js.map +0 -1
  35. package/dist/key-manager.d.ts +0 -87
  36. package/dist/key-manager.d.ts.map +0 -1
  37. package/dist/key-manager.js +0 -287
  38. package/dist/key-manager.js.map +0 -1
  39. package/dist/logger.d.ts +0 -2
  40. package/dist/logger.d.ts.map +0 -1
  41. package/dist/logger.js +0 -18
  42. package/dist/logger.js.map +0 -1
  43. package/dist/prompt-responder.d.ts +0 -22
  44. package/dist/prompt-responder.d.ts.map +0 -1
  45. package/dist/prompt-responder.js +0 -132
  46. package/dist/prompt-responder.js.map +0 -1
  47. package/dist/server.d.ts +0 -9
  48. package/dist/server.d.ts.map +0 -1
  49. package/dist/server.js.map +0 -1
  50. package/dist/token-storage.d.ts +0 -39
  51. package/dist/token-storage.d.ts.map +0 -1
  52. package/dist/token-storage.js +0 -169
  53. package/dist/token-storage.js.map +0 -1
  54. package/dist/types.d.ts +0 -110
  55. package/dist/types.d.ts.map +0 -1
  56. package/dist/types.js +0 -17
  57. package/dist/types.js.map +0 -1
  58. package/node_modules/@quantiya/codevibe-core/dist/appsync/appsync-client.js +0 -576
  59. package/node_modules/@quantiya/codevibe-core/dist/appsync/index.js +0 -10
  60. package/node_modules/@quantiya/codevibe-core/dist/appsync/queries.js +0 -189
  61. package/node_modules/@quantiya/codevibe-core/dist/auth/auth-cli.js +0 -217
  62. package/node_modules/@quantiya/codevibe-core/dist/auth/auth-service.js +0 -464
  63. package/node_modules/@quantiya/codevibe-core/dist/auth/fetch-helpers.js +0 -165
  64. package/node_modules/@quantiya/codevibe-core/dist/auth/index.js +0 -9
  65. package/node_modules/@quantiya/codevibe-core/dist/config/config.js +0 -123
  66. package/node_modules/@quantiya/codevibe-core/dist/config/index.js +0 -8
  67. package/node_modules/@quantiya/codevibe-core/dist/crypto/crypto-service.js +0 -284
  68. package/node_modules/@quantiya/codevibe-core/dist/crypto/index.js +0 -9
  69. package/node_modules/@quantiya/codevibe-core/dist/keychain/index.js +0 -8
  70. package/node_modules/@quantiya/codevibe-core/dist/keychain/keychain-manager.js +0 -375
  71. package/node_modules/@quantiya/codevibe-core/dist/logger/index.js +0 -8
  72. package/node_modules/@quantiya/codevibe-core/dist/logger/logger.js +0 -142
  73. package/node_modules/@quantiya/codevibe-core/dist/prompt-parser.js +0 -236
  74. package/node_modules/@quantiya/codevibe-core/dist/session/index.js +0 -7
  75. package/node_modules/@quantiya/codevibe-core/dist/session/session-resume.js +0 -151
  76. package/node_modules/@quantiya/codevibe-core/dist/types/auth.js +0 -3
  77. package/node_modules/@quantiya/codevibe-core/dist/types/encryption.js +0 -3
  78. package/node_modules/@quantiya/codevibe-core/dist/types/events.js +0 -28
  79. package/node_modules/@quantiya/codevibe-core/dist/types/index.js +0 -22
  80. package/node_modules/@quantiya/codevibe-core/dist/types/session.js +0 -22
@@ -1,375 +0,0 @@
1
- "use strict";
2
- //
3
- // keychain-manager.ts
4
- // CodeVibe Core
5
- //
6
- // Manages device encryption keys and OAuth tokens using native keychain
7
- // Uses keytar for cross-platform keychain access:
8
- // - macOS: Keychain
9
- // - Linux: libsecret
10
- // - Windows: Credential Manager
11
- //
12
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- var desc = Object.getOwnPropertyDescriptor(m, k);
15
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
- desc = { enumerable: true, get: function() { return m[k]; } };
17
- }
18
- Object.defineProperty(o, k2, desc);
19
- }) : (function(o, m, k, k2) {
20
- if (k2 === undefined) k2 = k;
21
- o[k2] = m[k];
22
- }));
23
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
- Object.defineProperty(o, "default", { enumerable: true, value: v });
25
- }) : function(o, v) {
26
- o["default"] = v;
27
- });
28
- var __importStar = (this && this.__importStar) || (function () {
29
- var ownKeys = function(o) {
30
- ownKeys = Object.getOwnPropertyNames || function (o) {
31
- var ar = [];
32
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
- return ar;
34
- };
35
- return ownKeys(o);
36
- };
37
- return function (mod) {
38
- if (mod && mod.__esModule) return mod;
39
- var result = {};
40
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
- __setModuleDefault(result, mod);
42
- return result;
43
- };
44
- })();
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.keychainManager = exports.KeychainManager = exports.KeychainError = void 0;
47
- const os = __importStar(require("os"));
48
- const uuid_1 = require("uuid");
49
- const keytar = __importStar(require("keytar"));
50
- const crypto_1 = require("../crypto");
51
- const config_1 = require("../config");
52
- const logger_1 = require("../logger");
53
- /**
54
- * Error class for keychain operations
55
- */
56
- class KeychainError extends Error {
57
- constructor(message) {
58
- super(message);
59
- this.name = 'KeychainError';
60
- }
61
- }
62
- exports.KeychainError = KeychainError;
63
- // Keychain account names
64
- const DEVICE_IDENTITY_ACCOUNT = 'device-identity';
65
- const TOKEN_ACCOUNT_PREFIX = 'tokens-'; // tokens-development, tokens-production
66
- /**
67
- * Manages device identity and OAuth tokens using native keychain
68
- */
69
- class KeychainManager {
70
- constructor() {
71
- this.deviceIdentity = null;
72
- this.sessionKeyCache = new Map();
73
- this.isRegistered = false;
74
- this._serviceName = null;
75
- // Service name is lazy-loaded to avoid calling getConfig() before config is initialized
76
- }
77
- /**
78
- * Get the keychain service name (lazy-loaded from config)
79
- */
80
- get serviceName() {
81
- if (!this._serviceName) {
82
- this._serviceName = (0, config_1.getConfig)().keychain.serviceName;
83
- }
84
- return this._serviceName;
85
- }
86
- static getInstance() {
87
- if (!KeychainManager.instance) {
88
- KeychainManager.instance = new KeychainManager();
89
- }
90
- return KeychainManager.instance;
91
- }
92
- // MARK: - Device Identity Management
93
- /**
94
- * Get the device identity from keychain
95
- */
96
- async getDeviceIdentity() {
97
- if (this.deviceIdentity) {
98
- return this.deviceIdentity;
99
- }
100
- try {
101
- const data = await keytar.getPassword(this.serviceName, DEVICE_IDENTITY_ACCOUNT);
102
- if (!data) {
103
- return null;
104
- }
105
- this.deviceIdentity = JSON.parse(data);
106
- logger_1.logger.info(`[KeychainManager] Loaded device identity: ${this.deviceIdentity.deviceId}`);
107
- return this.deviceIdentity;
108
- }
109
- catch (error) {
110
- logger_1.logger.error(`[KeychainManager] Failed to load device identity: ${error}`);
111
- return null;
112
- }
113
- }
114
- /**
115
- * Set the device identity in keychain
116
- */
117
- async setDeviceIdentity(identity) {
118
- try {
119
- await keytar.setPassword(this.serviceName, DEVICE_IDENTITY_ACCOUNT, JSON.stringify(identity));
120
- this.deviceIdentity = identity;
121
- logger_1.logger.info(`[KeychainManager] Saved device identity: ${identity.deviceId}`);
122
- }
123
- catch (error) {
124
- logger_1.logger.error(`[KeychainManager] Failed to save device identity: ${error}`);
125
- throw new KeychainError(`Failed to save device identity: ${error}`);
126
- }
127
- }
128
- /**
129
- * Get or create device identity
130
- */
131
- async getOrCreateDeviceIdentity() {
132
- let identity = await this.getDeviceIdentity();
133
- if (identity) {
134
- return identity;
135
- }
136
- // Generate new device identity
137
- const keyPair = crypto_1.cryptoService.generateKeyPair();
138
- identity = {
139
- deviceId: (0, uuid_1.v4)().toUpperCase(),
140
- privateKey: keyPair.privateKey,
141
- publicKey: keyPair.publicKey,
142
- createdAt: new Date().toISOString(),
143
- };
144
- await this.setDeviceIdentity(identity);
145
- logger_1.logger.info(`[KeychainManager] Generated new device identity: ${identity.deviceId}`);
146
- return identity;
147
- }
148
- /**
149
- * Get device ID (creates identity if needed)
150
- */
151
- async getDeviceId() {
152
- const identity = await this.getOrCreateDeviceIdentity();
153
- return identity.deviceId;
154
- }
155
- /**
156
- * Get device public key (creates identity if needed)
157
- */
158
- async getDevicePublicKey() {
159
- const identity = await this.getOrCreateDeviceIdentity();
160
- return identity.publicKey;
161
- }
162
- /**
163
- * Get device private key (creates identity if needed)
164
- */
165
- async getDevicePrivateKey() {
166
- const identity = await this.getOrCreateDeviceIdentity();
167
- return identity.privateKey;
168
- }
169
- /**
170
- * Check if device identity exists
171
- */
172
- async hasDeviceIdentity() {
173
- const identity = await this.getDeviceIdentity();
174
- return identity !== null;
175
- }
176
- /**
177
- * Delete device identity (reset device)
178
- */
179
- async deleteDeviceIdentity() {
180
- try {
181
- await keytar.deletePassword(this.serviceName, DEVICE_IDENTITY_ACCOUNT);
182
- this.deviceIdentity = null;
183
- this.sessionKeyCache.clear();
184
- this.isRegistered = false;
185
- logger_1.logger.info('[KeychainManager] Deleted device identity');
186
- }
187
- catch (error) {
188
- logger_1.logger.error(`[KeychainManager] Failed to delete device identity: ${error}`);
189
- throw new KeychainError(`Failed to delete device identity: ${error}`);
190
- }
191
- }
192
- // MARK: - Token Management
193
- /**
194
- * Get token account name for environment
195
- */
196
- getTokenAccount(environment) {
197
- return `${TOKEN_ACCOUNT_PREFIX}${environment}`;
198
- }
199
- /**
200
- * Get OAuth tokens for environment
201
- */
202
- async getTokens(environment = 'production') {
203
- try {
204
- const data = await keytar.getPassword(this.serviceName, this.getTokenAccount(environment));
205
- if (!data) {
206
- return null;
207
- }
208
- const tokens = JSON.parse(data);
209
- logger_1.logger.debug(`[KeychainManager] Loaded tokens for ${environment}`);
210
- return tokens;
211
- }
212
- catch (error) {
213
- logger_1.logger.error(`[KeychainManager] Failed to load tokens: ${error}`);
214
- return null;
215
- }
216
- }
217
- /**
218
- * Save OAuth tokens for environment
219
- */
220
- async setTokens(tokens, environment = 'production') {
221
- try {
222
- await keytar.setPassword(this.serviceName, this.getTokenAccount(environment), JSON.stringify(tokens));
223
- logger_1.logger.info(`[KeychainManager] Saved tokens for ${environment}`, {
224
- userId: tokens.userId,
225
- email: tokens.email,
226
- });
227
- }
228
- catch (error) {
229
- logger_1.logger.error(`[KeychainManager] Failed to save tokens: ${error}`);
230
- throw new KeychainError(`Failed to save tokens: ${error}`);
231
- }
232
- }
233
- /**
234
- * Delete OAuth tokens for environment
235
- */
236
- async deleteTokens(environment = 'production') {
237
- try {
238
- const deleted = await keytar.deletePassword(this.serviceName, this.getTokenAccount(environment));
239
- if (deleted) {
240
- logger_1.logger.info(`[KeychainManager] Deleted tokens for ${environment}`);
241
- }
242
- return deleted;
243
- }
244
- catch (error) {
245
- logger_1.logger.error(`[KeychainManager] Failed to delete tokens: ${error}`);
246
- return false;
247
- }
248
- }
249
- /**
250
- * Check if token is expired
251
- */
252
- isTokenExpired(tokens) {
253
- const bufferMs = 5 * 60 * 1000; // 5 minutes buffer
254
- return Date.now() >= (tokens.expiresAt - bufferMs);
255
- }
256
- // MARK: - Session Key Management
257
- /**
258
- * Get session key for a session, decrypting from encryptedKeys if needed
259
- */
260
- async getSessionKey(sessionId, encryptedKeys) {
261
- // Check cache first
262
- const cachedKey = this.sessionKeyCache.get(sessionId);
263
- if (cachedKey) {
264
- return cachedKey;
265
- }
266
- // Try to decrypt from encrypted keys
267
- if (!encryptedKeys || encryptedKeys.length === 0) {
268
- return null;
269
- }
270
- const deviceId = await this.getDeviceId();
271
- const ourEncryptedKey = encryptedKeys.find((k) => k.deviceId === deviceId);
272
- if (!ourEncryptedKey) {
273
- logger_1.logger.warn(`[KeychainManager] Device ${deviceId} not found in encryptedKeys`);
274
- return null;
275
- }
276
- // Get our private key
277
- const privateKey = await this.getDevicePrivateKey();
278
- // Decrypt session key
279
- const sessionKey = crypto_1.cryptoService.decryptSessionKey(ourEncryptedKey, privateKey);
280
- // Cache for future use
281
- this.sessionKeyCache.set(sessionId, sessionKey);
282
- logger_1.logger.info(`[KeychainManager] Decrypted and cached session key for ${sessionId}`);
283
- return sessionKey;
284
- }
285
- /**
286
- * Generate and encrypt a new session key for all devices
287
- */
288
- createSessionKey(devicePublicKeys) {
289
- // Generate random session key
290
- const sessionKey = crypto_1.cryptoService.generateSessionKey();
291
- // Encrypt for each device
292
- const encryptedKeys = devicePublicKeys.map((device) => {
293
- const encrypted = crypto_1.cryptoService.encryptSessionKey(sessionKey, device.publicKey);
294
- return {
295
- deviceId: device.deviceId,
296
- encryptedKey: encrypted.encryptedKey,
297
- ephemeralPublicKey: encrypted.ephemeralPublicKey,
298
- };
299
- });
300
- logger_1.logger.info(`[KeychainManager] Created session key for ${devicePublicKeys.length} devices`);
301
- return { sessionKey, encryptedKeys };
302
- }
303
- /**
304
- * Cache a session key
305
- */
306
- cacheSessionKey(sessionId, sessionKey) {
307
- this.sessionKeyCache.set(sessionId, sessionKey);
308
- }
309
- /**
310
- * Clear cached session key
311
- */
312
- clearSessionKey(sessionId) {
313
- this.sessionKeyCache.delete(sessionId);
314
- }
315
- /**
316
- * Clear all cached session keys
317
- */
318
- clearAllSessionKeys() {
319
- this.sessionKeyCache.clear();
320
- }
321
- // MARK: - Registration Status
322
- /**
323
- * Get registration status
324
- */
325
- getIsRegistered() {
326
- return this.isRegistered;
327
- }
328
- /**
329
- * Set registration status
330
- */
331
- setIsRegistered(registered) {
332
- this.isRegistered = registered;
333
- }
334
- // MARK: - Device Info
335
- /**
336
- * Get device name for registration
337
- */
338
- getDeviceName() {
339
- return os.hostname() || 'CLI Client';
340
- }
341
- /**
342
- * Get platform for registration
343
- */
344
- getDevicePlatform() {
345
- const platform = os.platform();
346
- if (platform === 'darwin') {
347
- return 'MACOS';
348
- }
349
- else if (platform === 'linux') {
350
- return 'LINUX';
351
- }
352
- else if (platform === 'win32') {
353
- return 'WINDOWS';
354
- }
355
- return 'CLI';
356
- }
357
- // MARK: - Full Reset
358
- /**
359
- * Clear all data (device identity + all tokens)
360
- */
361
- async clearAllData() {
362
- await this.deleteDeviceIdentity();
363
- await this.deleteTokens('development');
364
- await this.deleteTokens('production');
365
- this.sessionKeyCache.clear();
366
- this.isRegistered = false;
367
- logger_1.logger.info('[KeychainManager] Cleared all data');
368
- }
369
- }
370
- exports.KeychainManager = KeychainManager;
371
- /**
372
- * Export singleton instance
373
- */
374
- exports.keychainManager = KeychainManager.getInstance();
375
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Y2hhaW4tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9rZXljaGFpbi9rZXljaGFpbi1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxFQUFFO0FBQ0Ysc0JBQXNCO0FBQ3RCLGdCQUFnQjtBQUNoQixFQUFFO0FBQ0Ysd0VBQXdFO0FBQ3hFLGtEQUFrRDtBQUNsRCxvQkFBb0I7QUFDcEIscUJBQXFCO0FBQ3JCLGdDQUFnQztBQUNoQyxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFRix1Q0FBeUI7QUFDekIsK0JBQW9DO0FBQ3BDLCtDQUFpQztBQUVqQyxzQ0FBMEM7QUFDMUMsc0NBQXNDO0FBQ3RDLHNDQUFtQztBQUVuQzs7R0FFRztBQUNILE1BQWEsYUFBYyxTQUFRLEtBQUs7SUFDdEMsWUFBWSxPQUFlO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDO0lBQzlCLENBQUM7Q0FDRjtBQUxELHNDQUtDO0FBRUQseUJBQXlCO0FBQ3pCLE1BQU0sdUJBQXVCLEdBQUcsaUJBQWlCLENBQUM7QUFDbEQsTUFBTSxvQkFBb0IsR0FBRyxTQUFTLENBQUMsQ0FBQyx3Q0FBd0M7QUFFaEY7O0dBRUc7QUFDSCxNQUFhLGVBQWU7SUFPMUI7UUFMUSxtQkFBYyxHQUEwQixJQUFJLENBQUM7UUFDN0Msb0JBQWUsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNqRCxpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUM5QixpQkFBWSxHQUFrQixJQUFJLENBQUM7UUFHekMsd0ZBQXdGO0lBQzFGLENBQUM7SUFFRDs7T0FFRztJQUNILElBQVksV0FBVztRQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBQSxrQkFBUyxHQUFFLENBQUMsUUFB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LGlCQUFpQjtRQUNmLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMvQixJQUFJLFFBQVEsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMxQixPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDO2FBQU0sSUFBSSxRQUFRLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDaEMsT0FBTyxPQUFPLENBQUM7UUFDakIsQ0FBQzthQUFNLElBQUksUUFBUSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ2hDLE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxxQkFBcUI7SUFFckI7O09BRUc7SUFDSCxLQUFLLENBQUMsWUFBWTtRQUNoQixNQUFNLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN2QyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixlQUFNLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztDQUNGO0FBbldELDBDQW1XQztBQUVEOztHQUVHO0FBQ1UsUUFBQSxlQUFlLEdBQUcsZUFBZSxDQUFDLFdBQVcsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIGtleWNoYWluLW1hbmFnZXIudHNcbi8vIENvZGVWaWJlIENvcmVcbi8vXG4vLyBNYW5hZ2VzIGRldmljZSBlbmNyeXB0aW9uIGtleXMgYW5kIE9BdXRoIHRva2VucyB1c2luZyBuYXRpdmUga2V5Y2hhaW5cbi8vIFVzZXMga2V5dGFyIGZvciBjcm9zcy1wbGF0Zm9ybSBrZXljaGFpbiBhY2Nlc3M6XG4vLyAtIG1hY09TOiBLZXljaGFpblxuLy8gLSBMaW51eDogbGlic2VjcmV0XG4vLyAtIFdpbmRvd3M6IENyZWRlbnRpYWwgTWFuYWdlclxuLy9cblxuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgKiBhcyBrZXl0YXIgZnJvbSAna2V5dGFyJztcbmltcG9ydCB7IERldmljZUlkZW50aXR5LCBUb2tlbkRhdGEsIEVuY3J5cHRlZFNlc3Npb25LZXkgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBjcnlwdG9TZXJ2aWNlIH0gZnJvbSAnLi4vY3J5cHRvJztcbmltcG9ydCB7IGdldENvbmZpZyB9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuXG4vKipcbiAqIEVycm9yIGNsYXNzIGZvciBrZXljaGFpbiBvcGVyYXRpb25zXG4gKi9cbmV4cG9ydCBjbGFzcyBLZXljaGFpbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSAnS2V5Y2hhaW5FcnJvcic7XG4gIH1cbn1cblxuLy8gS2V5Y2hhaW4gYWNjb3VudCBuYW1lc1xuY29uc3QgREVWSUNFX0lERU5USVRZX0FDQ09VTlQgPSAnZGV2aWNlLWlkZW50aXR5JztcbmNvbnN0IFRPS0VOX0FDQ09VTlRfUFJFRklYID0gJ3Rva2Vucy0nOyAvLyB0b2tlbnMtZGV2ZWxvcG1lbnQsIHRva2Vucy1wcm9kdWN0aW9uXG5cbi8qKlxuICogTWFuYWdlcyBkZXZpY2UgaWRlbnRpdHkgYW5kIE9BdXRoIHRva2VucyB1c2luZyBuYXRpdmUga2V5Y2hhaW5cbiAqL1xuZXhwb3J0IGNsYXNzIEtleWNoYWluTWFuYWdlciB7XG4gIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBLZXljaGFpbk1hbmFnZXI7XG4gIHByaXZhdGUgZGV2aWNlSWRlbnRpdHk6IERldmljZUlkZW50aXR5IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2Vzc2lvbktleUNhY2hlOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIGlzUmVnaXN0ZXJlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBwcml2YXRlIF9zZXJ2aWNlTmFtZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBTZXJ2aWNlIG5hbWUgaXMgbGF6eS1sb2FkZWQgdG8gYXZvaWQgY2FsbGluZyBnZXRDb25maWcoKSBiZWZvcmUgY29uZmlnIGlzIGluaXRpYWxpemVkXG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBrZXljaGFpbiBzZXJ2aWNlIG5hbWUgKGxhenktbG9hZGVkIGZyb20gY29uZmlnKVxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgc2VydmljZU5hbWUoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuX3NlcnZpY2VOYW1lKSB7XG4gICAgICB0aGlzLl9zZXJ2aWNlTmFtZSA9IGdldENvbmZpZygpLmtleWNoYWluLnNlcnZpY2VOYW1lO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2VydmljZU5hbWU7XG4gIH1cblxuICBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogS2V5Y2hhaW5NYW5hZ2VyIHtcbiAgICBpZiAoIUtleWNoYWluTWFuYWdlci5pbnN0YW5jZSkge1xuICAgICAgS2V5Y2hhaW5NYW5hZ2VyLmluc3RhbmNlID0gbmV3IEtleWNoYWluTWFuYWdlcigpO1xuICAgIH1cbiAgICByZXR1cm4gS2V5Y2hhaW5NYW5hZ2VyLmluc3RhbmNlO1xuICB9XG5cbiAgLy8gTUFSSzogLSBEZXZpY2UgSWRlbnRpdHkgTWFuYWdlbWVudFxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGRldmljZSBpZGVudGl0eSBmcm9tIGtleWNoYWluXG4gICAqL1xuICBhc3luYyBnZXREZXZpY2VJZGVudGl0eSgpOiBQcm9taXNlPERldmljZUlkZW50aXR5IHwgbnVsbD4ge1xuICAgIGlmICh0aGlzLmRldmljZUlkZW50aXR5KSB7XG4gICAgICByZXR1cm4gdGhpcy5kZXZpY2VJZGVudGl0eTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGtleXRhci5nZXRQYXNzd29yZCh0aGlzLnNlcnZpY2VOYW1lLCBERVZJQ0VfSURFTlRJVFlfQUNDT1VOVCk7XG4gICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZGV2aWNlSWRlbnRpdHkgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgbG9nZ2VyLmluZm8oYFtLZXljaGFpbk1hbmFnZXJdIExvYWRlZCBkZXZpY2UgaWRlbnRpdHk6ICR7dGhpcy5kZXZpY2VJZGVudGl0eSEuZGV2aWNlSWR9YCk7XG4gICAgICByZXR1cm4gdGhpcy5kZXZpY2VJZGVudGl0eTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBbS2V5Y2hhaW5NYW5hZ2VyXSBGYWlsZWQgdG8gbG9hZCBkZXZpY2UgaWRlbnRpdHk6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBkZXZpY2UgaWRlbnRpdHkgaW4ga2V5Y2hhaW5cbiAgICovXG4gIGFzeW5jIHNldERldmljZUlkZW50aXR5KGlkZW50aXR5OiBEZXZpY2VJZGVudGl0eSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBrZXl0YXIuc2V0UGFzc3dvcmQoXG4gICAgICAgIHRoaXMuc2VydmljZU5hbWUsXG4gICAgICAgIERFVklDRV9JREVOVElUWV9BQ0NPVU5ULFxuICAgICAgICBKU09OLnN0cmluZ2lmeShpZGVudGl0eSlcbiAgICAgICk7XG4gICAgICB0aGlzLmRldmljZUlkZW50aXR5ID0gaWRlbnRpdHk7XG4gICAgICBsb2dnZXIuaW5mbyhgW0tleWNoYWluTWFuYWdlcl0gU2F2ZWQgZGV2aWNlIGlkZW50aXR5OiAke2lkZW50aXR5LmRldmljZUlkfWApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFtLZXljaGFpbk1hbmFnZXJdIEZhaWxlZCB0byBzYXZlIGRldmljZSBpZGVudGl0eTogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBLZXljaGFpbkVycm9yKGBGYWlsZWQgdG8gc2F2ZSBkZXZpY2UgaWRlbnRpdHk6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBvciBjcmVhdGUgZGV2aWNlIGlkZW50aXR5XG4gICAqL1xuICBhc3luYyBnZXRPckNyZWF0ZURldmljZUlkZW50aXR5KCk6IFByb21pc2U8RGV2aWNlSWRlbnRpdHk+IHtcbiAgICBsZXQgaWRlbnRpdHkgPSBhd2FpdCB0aGlzLmdldERldmljZUlkZW50aXR5KCk7XG4gICAgaWYgKGlkZW50aXR5KSB7XG4gICAgICByZXR1cm4gaWRlbnRpdHk7XG4gICAgfVxuXG4gICAgLy8gR2VuZXJhdGUgbmV3IGRldmljZSBpZGVudGl0eVxuICAgIGNvbnN0IGtleVBhaXIgPSBjcnlwdG9TZXJ2aWNlLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgIGlkZW50aXR5ID0ge1xuICAgICAgZGV2aWNlSWQ6IHV1aWR2NCgpLnRvVXBwZXJDYXNlKCksXG4gICAgICBwcml2YXRlS2V5OiBrZXlQYWlyLnByaXZhdGVLZXksXG4gICAgICBwdWJsaWNLZXk6IGtleVBhaXIucHVibGljS2V5LFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgfTtcblxuICAgIGF3YWl0IHRoaXMuc2V0RGV2aWNlSWRlbnRpdHkoaWRlbnRpdHkpO1xuICAgIGxvZ2dlci5pbmZvKGBbS2V5Y2hhaW5NYW5hZ2VyXSBHZW5lcmF0ZWQgbmV3IGRldmljZSBpZGVudGl0eTogJHtpZGVudGl0eS5kZXZpY2VJZH1gKTtcbiAgICByZXR1cm4gaWRlbnRpdHk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGRldmljZSBJRCAoY3JlYXRlcyBpZGVudGl0eSBpZiBuZWVkZWQpXG4gICAqL1xuICBhc3luYyBnZXREZXZpY2VJZCgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGlkZW50aXR5ID0gYXdhaXQgdGhpcy5nZXRPckNyZWF0ZURldmljZUlkZW50aXR5KCk7XG4gICAgcmV0dXJuIGlkZW50aXR5LmRldmljZUlkO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBkZXZpY2UgcHVibGljIGtleSAoY3JlYXRlcyBpZGVudGl0eSBpZiBuZWVkZWQpXG4gICAqL1xuICBhc3luYyBnZXREZXZpY2VQdWJsaWNLZXkoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBpZGVudGl0eSA9IGF3YWl0IHRoaXMuZ2V0T3JDcmVhdGVEZXZpY2VJZGVudGl0eSgpO1xuICAgIHJldHVybiBpZGVudGl0eS5wdWJsaWNLZXk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGRldmljZSBwcml2YXRlIGtleSAoY3JlYXRlcyBpZGVudGl0eSBpZiBuZWVkZWQpXG4gICAqL1xuICBhc3luYyBnZXREZXZpY2VQcml2YXRlS2V5KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgaWRlbnRpdHkgPSBhd2FpdCB0aGlzLmdldE9yQ3JlYXRlRGV2aWNlSWRlbnRpdHkoKTtcbiAgICByZXR1cm4gaWRlbnRpdHkucHJpdmF0ZUtleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBkZXZpY2UgaWRlbnRpdHkgZXhpc3RzXG4gICAqL1xuICBhc3luYyBoYXNEZXZpY2VJZGVudGl0eSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBpZGVudGl0eSA9IGF3YWl0IHRoaXMuZ2V0RGV2aWNlSWRlbnRpdHkoKTtcbiAgICByZXR1cm4gaWRlbnRpdHkgIT09IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGRldmljZSBpZGVudGl0eSAocmVzZXQgZGV2aWNlKVxuICAgKi9cbiAgYXN5bmMgZGVsZXRlRGV2aWNlSWRlbnRpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGtleXRhci5kZWxldGVQYXNzd29yZCh0aGlzLnNlcnZpY2VOYW1lLCBERVZJQ0VfSURFTlRJVFlfQUNDT1VOVCk7XG4gICAgICB0aGlzLmRldmljZUlkZW50aXR5ID0gbnVsbDtcbiAgICAgIHRoaXMuc2Vzc2lvbktleUNhY2hlLmNsZWFyKCk7XG4gICAgICB0aGlzLmlzUmVnaXN0ZXJlZCA9IGZhbHNlO1xuICAgICAgbG9nZ2VyLmluZm8oJ1tLZXljaGFpbk1hbmFnZXJdIERlbGV0ZWQgZGV2aWNlIGlkZW50aXR5Jyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgW0tleWNoYWluTWFuYWdlcl0gRmFpbGVkIHRvIGRlbGV0ZSBkZXZpY2UgaWRlbnRpdHk6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgS2V5Y2hhaW5FcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBkZXZpY2UgaWRlbnRpdHk6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgLy8gTUFSSzogLSBUb2tlbiBNYW5hZ2VtZW50XG5cbiAgLyoqXG4gICAqIEdldCB0b2tlbiBhY2NvdW50IG5hbWUgZm9yIGVudmlyb25tZW50XG4gICAqL1xuICBwcml2YXRlIGdldFRva2VuQWNjb3VudChlbnZpcm9ubWVudDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7VE9LRU5fQUNDT1VOVF9QUkVGSVh9JHtlbnZpcm9ubWVudH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBPQXV0aCB0b2tlbnMgZm9yIGVudmlyb25tZW50XG4gICAqL1xuICBhc3luYyBnZXRUb2tlbnMoZW52aXJvbm1lbnQ6IHN0cmluZyA9ICdwcm9kdWN0aW9uJyk6IFByb21pc2U8VG9rZW5EYXRhIHwgbnVsbD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQga2V5dGFyLmdldFBhc3N3b3JkKHRoaXMuc2VydmljZU5hbWUsIHRoaXMuZ2V0VG9rZW5BY2NvdW50KGVudmlyb25tZW50KSk7XG4gICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRva2VuczogVG9rZW5EYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgW0tleWNoYWluTWFuYWdlcl0gTG9hZGVkIHRva2VucyBmb3IgJHtlbnZpcm9ubWVudH1gKTtcbiAgICAgIHJldHVybiB0b2tlbnM7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgW0tleWNoYWluTWFuYWdlcl0gRmFpbGVkIHRvIGxvYWQgdG9rZW5zOiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNhdmUgT0F1dGggdG9rZW5zIGZvciBlbnZpcm9ubWVudFxuICAgKi9cbiAgYXN5bmMgc2V0VG9rZW5zKHRva2VuczogVG9rZW5EYXRhLCBlbnZpcm9ubWVudDogc3RyaW5nID0gJ3Byb2R1Y3Rpb24nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGtleXRhci5zZXRQYXNzd29yZChcbiAgICAgICAgdGhpcy5zZXJ2aWNlTmFtZSxcbiAgICAgICAgdGhpcy5nZXRUb2tlbkFjY291bnQoZW52aXJvbm1lbnQpLFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh0b2tlbnMpXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmluZm8oYFtLZXljaGFpbk1hbmFnZXJdIFNhdmVkIHRva2VucyBmb3IgJHtlbnZpcm9ubWVudH1gLCB7XG4gICAgICAgIHVzZXJJZDogdG9rZW5zLnVzZXJJZCxcbiAgICAgICAgZW1haWw6IHRva2Vucy5lbWFpbCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFtLZXljaGFpbk1hbmFnZXJdIEZhaWxlZCB0byBzYXZlIHRva2VuczogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBLZXljaGFpbkVycm9yKGBGYWlsZWQgdG8gc2F2ZSB0b2tlbnM6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBPQXV0aCB0b2tlbnMgZm9yIGVudmlyb25tZW50XG4gICAqL1xuICBhc3luYyBkZWxldGVUb2tlbnMoZW52aXJvbm1lbnQ6IHN0cmluZyA9ICdwcm9kdWN0aW9uJyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWxldGVkID0gYXdhaXQga2V5dGFyLmRlbGV0ZVBhc3N3b3JkKHRoaXMuc2VydmljZU5hbWUsIHRoaXMuZ2V0VG9rZW5BY2NvdW50KGVudmlyb25tZW50KSk7XG4gICAgICBpZiAoZGVsZXRlZCkge1xuICAgICAgICBsb2dnZXIuaW5mbyhgW0tleWNoYWluTWFuYWdlcl0gRGVsZXRlZCB0b2tlbnMgZm9yICR7ZW52aXJvbm1lbnR9YCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVsZXRlZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBbS2V5Y2hhaW5NYW5hZ2VyXSBGYWlsZWQgdG8gZGVsZXRlIHRva2VuczogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdG9rZW4gaXMgZXhwaXJlZFxuICAgKi9cbiAgaXNUb2tlbkV4cGlyZWQodG9rZW5zOiBUb2tlbkRhdGEpOiBib29sZWFuIHtcbiAgICBjb25zdCBidWZmZXJNcyA9IDUgKiA2MCAqIDEwMDA7IC8vIDUgbWludXRlcyBidWZmZXJcbiAgICByZXR1cm4gRGF0ZS5ub3coKSA+PSAodG9rZW5zLmV4cGlyZXNBdCAtIGJ1ZmZlck1zKTtcbiAgfVxuXG4gIC8vIE1BUks6IC0gU2Vzc2lvbiBLZXkgTWFuYWdlbWVudFxuXG4gIC8qKlxuICAgKiBHZXQgc2Vzc2lvbiBrZXkgZm9yIGEgc2Vzc2lvbiwgZGVjcnlwdGluZyBmcm9tIGVuY3J5cHRlZEtleXMgaWYgbmVlZGVkXG4gICAqL1xuICBhc3luYyBnZXRTZXNzaW9uS2V5KFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIGVuY3J5cHRlZEtleXM/OiBFbmNyeXB0ZWRTZXNzaW9uS2V5W11cbiAgKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgLy8gQ2hlY2sgY2FjaGUgZmlyc3RcbiAgICBjb25zdCBjYWNoZWRLZXkgPSB0aGlzLnNlc3Npb25LZXlDYWNoZS5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoY2FjaGVkS2V5KSB7XG4gICAgICByZXR1cm4gY2FjaGVkS2V5O1xuICAgIH1cblxuICAgIC8vIFRyeSB0byBkZWNyeXB0IGZyb20gZW5jcnlwdGVkIGtleXNcbiAgICBpZiAoIWVuY3J5cHRlZEtleXMgfHwgZW5jcnlwdGVkS2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGRldmljZUlkID0gYXdhaXQgdGhpcy5nZXREZXZpY2VJZCgpO1xuICAgIGNvbnN0IG91ckVuY3J5cHRlZEtleSA9IGVuY3J5cHRlZEtleXMuZmluZCgoaykgPT4gay5kZXZpY2VJZCA9PT0gZGV2aWNlSWQpO1xuICAgIGlmICghb3VyRW5jcnlwdGVkS2V5KSB7XG4gICAgICBsb2dnZXIud2FybihgW0tleWNoYWluTWFuYWdlcl0gRGV2aWNlICR7ZGV2aWNlSWR9IG5vdCBmb3VuZCBpbiBlbmNyeXB0ZWRLZXlzYCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBHZXQgb3VyIHByaXZhdGUga2V5XG4gICAgY29uc3QgcHJpdmF0ZUtleSA9IGF3YWl0IHRoaXMuZ2V0RGV2aWNlUHJpdmF0ZUtleSgpO1xuXG4gICAgLy8gRGVjcnlwdCBzZXNzaW9uIGtleVxuICAgIGNvbnN0IHNlc3Npb25LZXkgPSBjcnlwdG9TZXJ2aWNlLmRlY3J5cHRTZXNzaW9uS2V5KG91ckVuY3J5cHRlZEtleSwgcHJpdmF0ZUtleSk7XG5cbiAgICAvLyBDYWNoZSBmb3IgZnV0dXJlIHVzZVxuICAgIHRoaXMuc2Vzc2lvbktleUNhY2hlLnNldChzZXNzaW9uSWQsIHNlc3Npb25LZXkpO1xuICAgIGxvZ2dlci5pbmZvKGBbS2V5Y2hhaW5NYW5hZ2VyXSBEZWNyeXB0ZWQgYW5kIGNhY2hlZCBzZXNzaW9uIGtleSBmb3IgJHtzZXNzaW9uSWR9YCk7XG5cbiAgICByZXR1cm4gc2Vzc2lvbktleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhbmQgZW5jcnlwdCBhIG5ldyBzZXNzaW9uIGtleSBmb3IgYWxsIGRldmljZXNcbiAgICovXG4gIGNyZWF0ZVNlc3Npb25LZXkoXG4gICAgZGV2aWNlUHVibGljS2V5czogQXJyYXk8eyBkZXZpY2VJZDogc3RyaW5nOyBwdWJsaWNLZXk6IHN0cmluZyB9PlxuICApOiB7IHNlc3Npb25LZXk6IHN0cmluZzsgZW5jcnlwdGVkS2V5czogRW5jcnlwdGVkU2Vzc2lvbktleVtdIH0ge1xuICAgIC8vIEdlbmVyYXRlIHJhbmRvbSBzZXNzaW9uIGtleVxuICAgIGNvbnN0IHNlc3Npb25LZXkgPSBjcnlwdG9TZXJ2aWNlLmdlbmVyYXRlU2Vzc2lvbktleSgpO1xuXG4gICAgLy8gRW5jcnlwdCBmb3IgZWFjaCBkZXZpY2VcbiAgICBjb25zdCBlbmNyeXB0ZWRLZXlzOiBFbmNyeXB0ZWRTZXNzaW9uS2V5W10gPSBkZXZpY2VQdWJsaWNLZXlzLm1hcCgoZGV2aWNlKSA9PiB7XG4gICAgICBjb25zdCBlbmNyeXB0ZWQgPSBjcnlwdG9TZXJ2aWNlLmVuY3J5cHRTZXNzaW9uS2V5KFxuICAgICAgICBzZXNzaW9uS2V5LFxuICAgICAgICBkZXZpY2UucHVibGljS2V5XG4gICAgICApO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkZXZpY2VJZDogZGV2aWNlLmRldmljZUlkLFxuICAgICAgICBlbmNyeXB0ZWRLZXk6IGVuY3J5cHRlZC5lbmNyeXB0ZWRLZXksXG4gICAgICAgIGVwaGVtZXJhbFB1YmxpY0tleTogZW5jcnlwdGVkLmVwaGVtZXJhbFB1YmxpY0tleSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBsb2dnZXIuaW5mbyhgW0tleWNoYWluTWFuYWdlcl0gQ3JlYXRlZCBzZXNzaW9uIGtleSBmb3IgJHtkZXZpY2VQdWJsaWNLZXlzLmxlbmd0aH0gZGV2aWNlc2ApO1xuICAgIHJldHVybiB7IHNlc3Npb25LZXksIGVuY3J5cHRlZEtleXMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWNoZSBhIHNlc3Npb24ga2V5XG4gICAqL1xuICBjYWNoZVNlc3Npb25LZXkoc2Vzc2lvbklkOiBzdHJpbmcsIHNlc3Npb25LZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbktleUNhY2hlLnNldChzZXNzaW9uSWQsIHNlc3Npb25LZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGNhY2hlZCBzZXNzaW9uIGtleVxuICAgKi9cbiAgY2xlYXJTZXNzaW9uS2V5KHNlc3Npb25JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uS2V5Q2FjaGUuZGVsZXRlKHNlc3Npb25JZCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIGNhY2hlZCBzZXNzaW9uIGtleXNcbiAgICovXG4gIGNsZWFyQWxsU2Vzc2lvbktleXMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uS2V5Q2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIC8vIE1BUks6IC0gUmVnaXN0cmF0aW9uIFN0YXR1c1xuXG4gIC8qKlxuICAgKiBHZXQgcmVnaXN0cmF0aW9uIHN0YXR1c1xuICAgKi9cbiAgZ2V0SXNSZWdpc3RlcmVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzUmVnaXN0ZXJlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgcmVnaXN0cmF0aW9uIHN0YXR1c1xuICAgKi9cbiAgc2V0SXNSZWdpc3RlcmVkKHJlZ2lzdGVyZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmlzUmVnaXN0ZXJlZCA9IHJlZ2lzdGVyZWQ7XG4gIH1cblxuICAvLyBNQVJLOiAtIERldmljZSBJbmZvXG5cbiAgLyoqXG4gICAqIEdldCBkZXZpY2UgbmFtZSBmb3IgcmVnaXN0cmF0aW9uXG4gICAqL1xuICBnZXREZXZpY2VOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG9zLmhvc3RuYW1lKCkgfHwgJ0NMSSBDbGllbnQnO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwbGF0Zm9ybSBmb3IgcmVnaXN0cmF0aW9uXG4gICAqL1xuICBnZXREZXZpY2VQbGF0Zm9ybSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBsYXRmb3JtID0gb3MucGxhdGZvcm0oKTtcbiAgICBpZiAocGxhdGZvcm0gPT09ICdkYXJ3aW4nKSB7XG4gICAgICByZXR1cm4gJ01BQ09TJztcbiAgICB9IGVsc2UgaWYgKHBsYXRmb3JtID09PSAnbGludXgnKSB7XG4gICAgICByZXR1cm4gJ0xJTlVYJztcbiAgICB9IGVsc2UgaWYgKHBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgICByZXR1cm4gJ1dJTkRPV1MnO1xuICAgIH1cbiAgICByZXR1cm4gJ0NMSSc7XG4gIH1cblxuICAvLyBNQVJLOiAtIEZ1bGwgUmVzZXRcblxuICAvKipcbiAgICogQ2xlYXIgYWxsIGRhdGEgKGRldmljZSBpZGVudGl0eSArIGFsbCB0b2tlbnMpXG4gICAqL1xuICBhc3luYyBjbGVhckFsbERhdGEoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5kZWxldGVEZXZpY2VJZGVudGl0eSgpO1xuICAgIGF3YWl0IHRoaXMuZGVsZXRlVG9rZW5zKCdkZXZlbG9wbWVudCcpO1xuICAgIGF3YWl0IHRoaXMuZGVsZXRlVG9rZW5zKCdwcm9kdWN0aW9uJyk7XG4gICAgdGhpcy5zZXNzaW9uS2V5Q2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLmlzUmVnaXN0ZXJlZCA9IGZhbHNlO1xuICAgIGxvZ2dlci5pbmZvKCdbS2V5Y2hhaW5NYW5hZ2VyXSBDbGVhcmVkIGFsbCBkYXRhJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBFeHBvcnQgc2luZ2xldG9uIGluc3RhbmNlXG4gKi9cbmV4cG9ydCBjb25zdCBrZXljaGFpbk1hbmFnZXIgPSBLZXljaGFpbk1hbmFnZXIuZ2V0SW5zdGFuY2UoKTtcbiJdfQ==
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createLogger = exports.logger = exports.Logger = void 0;
4
- var logger_1 = require("./logger");
5
- Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
6
- Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
7
- Object.defineProperty(exports, "createLogger", { enumerable: true, get: function () { return logger_1.createLogger; } });
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbG9nZ2VyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUF3RDtBQUEvQyxnR0FBQSxNQUFNLE9BQUE7QUFBRSxnR0FBQSxNQUFNLE9BQUE7QUFBRSxzR0FBQSxZQUFZLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBMb2dnZXIsIGxvZ2dlciwgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuIl19
@@ -1,142 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.logger = exports.Logger = void 0;
37
- exports.createLogger = createLogger;
38
- const fs = __importStar(require("fs"));
39
- const path = __importStar(require("path"));
40
- const os = __importStar(require("os"));
41
- const LOG_LEVELS = {
42
- debug: 0,
43
- info: 1,
44
- warn: 2,
45
- error: 3,
46
- };
47
- /**
48
- * Simple logger for CodeVibe plugins
49
- */
50
- class Logger {
51
- constructor(options) {
52
- this.name = options.name;
53
- this.logFile = options.logFile;
54
- this.level = options.level || 'info';
55
- this.enableConsole = options.console ?? false;
56
- if (this.logFile) {
57
- this.ensureLogDir();
58
- }
59
- }
60
- ensureLogDir() {
61
- if (this.logFile) {
62
- const dir = path.dirname(this.logFile);
63
- if (!fs.existsSync(dir)) {
64
- fs.mkdirSync(dir, { recursive: true });
65
- }
66
- }
67
- }
68
- shouldLog(level) {
69
- return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
70
- }
71
- formatMessage(level, message, data) {
72
- const timestamp = new Date().toISOString();
73
- const levelStr = level.toUpperCase().padEnd(5);
74
- let msg = `[${timestamp}] [${levelStr}] [${this.name}] ${message}`;
75
- if (data !== undefined) {
76
- if (typeof data === 'object') {
77
- msg += ` ${JSON.stringify(data)}`;
78
- }
79
- else {
80
- msg += ` ${data}`;
81
- }
82
- }
83
- return msg;
84
- }
85
- log(level, message, data) {
86
- if (!this.shouldLog(level)) {
87
- return;
88
- }
89
- const formatted = this.formatMessage(level, message, data);
90
- if (this.logFile) {
91
- try {
92
- fs.appendFileSync(this.logFile, formatted + '\n');
93
- }
94
- catch (error) {
95
- // Ignore log write errors
96
- }
97
- }
98
- if (this.enableConsole) {
99
- switch (level) {
100
- case 'error':
101
- console.error(formatted);
102
- break;
103
- case 'warn':
104
- console.warn(formatted);
105
- break;
106
- default:
107
- console.log(formatted);
108
- }
109
- }
110
- }
111
- debug(message, data) {
112
- this.log('debug', message, data);
113
- }
114
- info(message, data) {
115
- this.log('info', message, data);
116
- }
117
- warn(message, data) {
118
- this.log('warn', message, data);
119
- }
120
- error(message, data) {
121
- this.log('error', message, data);
122
- }
123
- setLevel(level) {
124
- this.level = level;
125
- }
126
- }
127
- exports.Logger = Logger;
128
- /**
129
- * Create a logger with custom options
130
- */
131
- function createLogger(options) {
132
- return new Logger(options);
133
- }
134
- /**
135
- * Default shared logger instance
136
- */
137
- exports.logger = new Logger({
138
- name: 'codevibe-core',
139
- logFile: path.join(os.tmpdir(), 'codevibe-core.log'),
140
- level: 'info',
141
- });
142
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZ2dlci9sb2dnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMEhBLG9DQUVDO0FBNUhELHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFDN0IsdUNBQXlCO0FBV3pCLE1BQU0sVUFBVSxHQUE2QjtJQUMzQyxLQUFLLEVBQUUsQ0FBQztJQUNSLElBQUksRUFBRSxDQUFDO0lBQ1AsSUFBSSxFQUFFLENBQUM7SUFDUCxLQUFLLEVBQUUsQ0FBQztDQUNULENBQUM7QUFFRjs7R0FFRztBQUNILE1BQWEsTUFBTTtJQU1qQixZQUFZLE9BQXNCO1FBQ2hDLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDL0IsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQztRQUNyQyxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDO1FBRTlDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDeEIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN6QyxDQUFDO1FB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QUMsT0FBc0I7SUFDakQsT0FBTyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM3QixDQUFDO0FBRUQ7O0dBRUc7QUFDVSxRQUFBLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQztJQUMvQixJQUFJLEVBQUUsZUFBZTtJQUNyQixPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsbUJBQW1CLENBQUM7SUFDcEQsS0FBSyxFQUFFLE1BQU07Q0FDZCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuXG5leHBvcnQgdHlwZSBMb2dMZXZlbCA9ICdkZWJ1ZycgfCAnaW5mbycgfCAnd2FybicgfCAnZXJyb3InO1xuXG5pbnRlcmZhY2UgTG9nZ2VyT3B0aW9ucyB7XG4gIG5hbWU6IHN0cmluZztcbiAgbG9nRmlsZT86IHN0cmluZztcbiAgbGV2ZWw/OiBMb2dMZXZlbDtcbiAgY29uc29sZT86IGJvb2xlYW47XG59XG5cbmNvbnN0IExPR19MRVZFTFM6IFJlY29yZDxMb2dMZXZlbCwgbnVtYmVyPiA9IHtcbiAgZGVidWc6IDAsXG4gIGluZm86IDEsXG4gIHdhcm46IDIsXG4gIGVycm9yOiAzLFxufTtcblxuLyoqXG4gKiBTaW1wbGUgbG9nZ2VyIGZvciBDb2RlVmliZSBwbHVnaW5zXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnZXIge1xuICBwcml2YXRlIG5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSBsb2dGaWxlPzogc3RyaW5nO1xuICBwcml2YXRlIGxldmVsOiBMb2dMZXZlbDtcbiAgcHJpdmF0ZSBlbmFibGVDb25zb2xlOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IExvZ2dlck9wdGlvbnMpIHtcbiAgICB0aGlzLm5hbWUgPSBvcHRpb25zLm5hbWU7XG4gICAgdGhpcy5sb2dGaWxlID0gb3B0aW9ucy5sb2dGaWxlO1xuICAgIHRoaXMubGV2ZWwgPSBvcHRpb25zLmxldmVsIHx8ICdpbmZvJztcbiAgICB0aGlzLmVuYWJsZUNvbnNvbGUgPSBvcHRpb25zLmNvbnNvbGUgPz8gZmFsc2U7XG5cbiAgICBpZiAodGhpcy5sb2dGaWxlKSB7XG4gICAgICB0aGlzLmVuc3VyZUxvZ0RpcigpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlTG9nRGlyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxvZ0ZpbGUpIHtcbiAgICAgIGNvbnN0IGRpciA9IHBhdGguZGlybmFtZSh0aGlzLmxvZ0ZpbGUpO1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGRpcikpIHtcbiAgICAgICAgZnMubWtkaXJTeW5jKGRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzaG91bGRMb2cobGV2ZWw6IExvZ0xldmVsKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIExPR19MRVZFTFNbbGV2ZWxdID49IExPR19MRVZFTFNbdGhpcy5sZXZlbF07XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdE1lc3NhZ2UobGV2ZWw6IExvZ0xldmVsLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiBzdHJpbmcge1xuICAgIGNvbnN0IHRpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICBjb25zdCBsZXZlbFN0ciA9IGxldmVsLnRvVXBwZXJDYXNlKCkucGFkRW5kKDUpO1xuICAgIGxldCBtc2cgPSBgWyR7dGltZXN0YW1wfV0gWyR7bGV2ZWxTdHJ9XSBbJHt0aGlzLm5hbWV9XSAke21lc3NhZ2V9YDtcblxuICAgIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgbXNnICs9IGAgJHtKU09OLnN0cmluZ2lmeShkYXRhKX1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXNnICs9IGAgJHtkYXRhfWA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1zZztcbiAgfVxuXG4gIHByaXZhdGUgbG9nKGxldmVsOiBMb2dMZXZlbCwgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogYW55KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3VsZExvZyhsZXZlbCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLmZvcm1hdE1lc3NhZ2UobGV2ZWwsIG1lc3NhZ2UsIGRhdGEpO1xuXG4gICAgaWYgKHRoaXMubG9nRmlsZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZnMuYXBwZW5kRmlsZVN5bmModGhpcy5sb2dGaWxlLCBmb3JtYXR0ZWQgKyAnXFxuJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBJZ25vcmUgbG9nIHdyaXRlIGVycm9yc1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmVuYWJsZUNvbnNvbGUpIHtcbiAgICAgIHN3aXRjaCAobGV2ZWwpIHtcbiAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZm9ybWF0dGVkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnd2Fybic6XG4gICAgICAgICAgY29uc29sZS53YXJuKGZvcm1hdHRlZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgY29uc29sZS5sb2coZm9ybWF0dGVkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBkZWJ1ZyhtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmxvZygnZGVidWcnLCBtZXNzYWdlLCBkYXRhKTtcbiAgfVxuXG4gIGluZm8obWVzc2FnZTogc3RyaW5nLCBkYXRhPzogYW55KTogdm9pZCB7XG4gICAgdGhpcy5sb2coJ2luZm8nLCBtZXNzYWdlLCBkYXRhKTtcbiAgfVxuXG4gIHdhcm4obWVzc2FnZTogc3RyaW5nLCBkYXRhPzogYW55KTogdm9pZCB7XG4gICAgdGhpcy5sb2coJ3dhcm4nLCBtZXNzYWdlLCBkYXRhKTtcbiAgfVxuXG4gIGVycm9yKG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IGFueSk6IHZvaWQge1xuICAgIHRoaXMubG9nKCdlcnJvcicsIG1lc3NhZ2UsIGRhdGEpO1xuICB9XG5cbiAgc2V0TGV2ZWwobGV2ZWw6IExvZ0xldmVsKTogdm9pZCB7XG4gICAgdGhpcy5sZXZlbCA9IGxldmVsO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgbG9nZ2VyIHdpdGggY3VzdG9tIG9wdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihvcHRpb25zOiBMb2dnZXJPcHRpb25zKTogTG9nZ2VyIHtcbiAgcmV0dXJuIG5ldyBMb2dnZXIob3B0aW9ucyk7XG59XG5cbi8qKlxuICogRGVmYXVsdCBzaGFyZWQgbG9nZ2VyIGluc3RhbmNlXG4gKi9cbmV4cG9ydCBjb25zdCBsb2dnZXIgPSBuZXcgTG9nZ2VyKHtcbiAgbmFtZTogJ2NvZGV2aWJlLWNvcmUnLFxuICBsb2dGaWxlOiBwYXRoLmpvaW4ob3MudG1wZGlyKCksICdjb2RldmliZS1jb3JlLmxvZycpLFxuICBsZXZlbDogJ2luZm8nLFxufSk7XG4iXX0=