ts-class-to-openapi 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +368 -882
  2. package/dist/__test__/entities/additional-test-classes.d.ts +12 -0
  3. package/dist/__test__/entities/circular-reference-classes.d.ts +110 -0
  4. package/dist/__test__/entities/complex-circular-dependencies.d.ts +71 -0
  5. package/dist/__test__/entities/decorated-classes.d.ts +54 -0
  6. package/dist/__test__/entities/generic-circular-classes.d.ts +57 -0
  7. package/dist/__test__/entities/nested-classes.d.ts +70 -0
  8. package/dist/__test__/entities/pure-classes.d.ts +37 -0
  9. package/dist/__test__/entities/schema-validation-classes.d.ts +35 -0
  10. package/dist/__test__/index.d.ts +3 -9
  11. package/dist/__test__/testCases/schema-validation.test.d.ts +1 -0
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.esm.js +546 -1319
  14. package/dist/index.js +545 -1319
  15. package/dist/run.d.ts +1 -1
  16. package/dist/run.js +1131 -1343
  17. package/dist/transformer.d.ts +1 -575
  18. package/dist/transformer.fixtures.d.ts +21 -0
  19. package/dist/types.d.ts +40 -3
  20. package/package.json +16 -15
  21. package/dist/__test__/entities/address.entity.d.ts +0 -5
  22. package/dist/__test__/entities/array.entity.d.ts +0 -7
  23. package/dist/__test__/entities/broken.entity.d.ts +0 -7
  24. package/dist/__test__/entities/circular.entity.d.ts +0 -59
  25. package/dist/__test__/entities/complete.entity.d.ts +0 -16
  26. package/dist/__test__/entities/complex-generics.entity.d.ts +0 -33
  27. package/dist/__test__/entities/comprehensive-enum.entity.d.ts +0 -23
  28. package/dist/__test__/entities/enum.entity.d.ts +0 -29
  29. package/dist/__test__/entities/generic.entity.d.ts +0 -11
  30. package/dist/__test__/entities/optional-properties.entity.d.ts +0 -11
  31. package/dist/__test__/entities/plain.entity.d.ts +0 -19
  32. package/dist/__test__/entities/simple.entity.d.ts +0 -5
  33. package/dist/__test__/entities/upload.entity.d.ts +0 -8
  34. package/dist/__test__/entities/user-role-generic.entity.d.ts +0 -13
  35. package/dist/__test__/test-entities/duplicate-name.entity.d.ts +0 -5
  36. package/dist/__test__/test-entities/generic.entity.d.ts +0 -11
  37. /package/dist/__test__/{circular-reference.test.d.ts → entities/circular-reference-cases.d.ts} +0 -0
  38. /package/dist/__test__/{enum.test.d.ts → entities/deep-nested-classes.d.ts} +0 -0
  39. /package/dist/__test__/{generic-types.test.d.ts → test.d.ts} +0 -0
  40. /package/dist/__test__/{integration.test.d.ts → testCases/circular-references.test.d.ts} +0 -0
  41. /package/dist/__test__/{main.test.d.ts → testCases/debug.test.d.ts} +0 -0
  42. /package/dist/__test__/{optional-properties.test.d.ts → testCases/decorated-classes.test.d.ts} +0 -0
  43. /package/dist/__test__/{plain.test.d.ts → testCases/edge-cases.test.d.ts} +0 -0
  44. /package/dist/__test__/{ref-pattern.test.d.ts → testCases/nested-classes.test.d.ts} +0 -0
  45. /package/dist/__test__/{singleton-behavior.test.d.ts → testCases/pure-classes.test.d.ts} +0 -0
package/dist/run.js CHANGED
@@ -1,118 +1,65 @@
1
1
  'use strict';
2
2
 
3
+ var node_test = require('node:test');
4
+ var assert = require('node:assert');
3
5
  var ts = require('typescript');
4
6
  var path = require('path');
7
+ var classValidator = require('class-validator');
5
8
 
6
9
  const TS_CONFIG_DEFAULT_PATH = path.resolve(process.cwd(), 'tsconfig.json');
7
10
  const jsPrimitives = {
8
11
  String: { type: 'String', value: 'string' },
9
- Number: { type: 'Number', value: 'number', format: 'float' },
12
+ Any: { type: 'Any'},
13
+ Unknown: { type: 'Unknown'},
14
+ Number: { type: 'Number', value: 'number', format: 'double' },
10
15
  Boolean: { type: 'Boolean', value: 'boolean' },
11
- Symbol: { type: 'Symbol', value: 'symbol' },
16
+ Symbol: { type: 'Symbol', value: 'string' },
12
17
  BigInt: { type: 'BigInt', value: 'integer', format: 'int64' },
13
- null: { type: 'null', value: 'null' },
18
+ null: { type: 'null'},
14
19
  Object: { type: 'Object', value: 'object' },
15
20
  Array: { type: 'Array', value: 'array' },
16
21
  Date: { type: 'Date', value: 'string', format: 'date-time' },
17
- Function: { type: 'Function', value: 'function' },
18
- Buffer: { type: 'Buffer', value: 'string', format: 'binary' },
19
- Uint8Array: { type: 'Uint8Array', value: 'string', format: 'binary' },
22
+ Buffer: { type: 'Buffer', value: 'string'},
23
+ Uint8Array: { type: 'Uint8Array', value: 'string'},
20
24
  UploadFile: { type: 'UploadFile', value: 'string', format: 'binary' },
21
- File: { type: 'File', value: 'string', format: 'binary' },
25
+ File: { type: 'File', value: 'string'},
22
26
  };
23
27
  const validatorDecorators = {
24
- Length: { name: 'Length', type: 'string' },
25
- MinLength: { name: 'MinLength', type: 'string' },
26
- MaxLength: { name: 'MaxLength', type: 'string' },
28
+ Length: { name: 'Length'},
29
+ MinLength: { name: 'MinLength'},
30
+ MaxLength: { name: 'MaxLength'},
27
31
  IsInt: { name: 'IsInt', type: 'integer', format: 'int32' },
28
- IsNumber: { name: 'IsNumber', type: 'number', format: 'double' },
29
- IsString: { name: 'IsString', type: 'string', format: 'string' },
30
- IsPositive: { name: 'IsPositive', type: 'number' },
32
+ IsNumber: { name: 'IsNumber', type: 'number'},
33
+ IsString: { name: 'IsString', type: 'string'},
34
+ IsPositive: { name: 'IsPositive'},
31
35
  IsDate: { name: 'IsDate', type: 'string', format: 'date-time' },
32
- IsEmail: { name: 'IsEmail', type: 'string', format: 'email' },
36
+ IsEmail: { name: 'IsEmail', format: 'email' },
33
37
  IsNotEmpty: { name: 'IsNotEmpty' },
38
+ IsOptional: { name: 'IsOptional' },
34
39
  IsBoolean: { name: 'IsBoolean', type: 'boolean' },
35
- IsArray: { name: 'IsArray', type: 'array' },
40
+ IsArray: { name: 'IsArray'},
36
41
  Min: { name: 'Min' },
37
42
  Max: { name: 'Max' },
38
43
  ArrayNotEmpty: { name: 'ArrayNotEmpty' },
39
44
  ArrayMaxSize: { name: 'ArrayMaxSize' },
40
45
  ArrayMinSize: { name: 'ArrayMinSize' },
41
- IsEnum: { name: 'IsEnum', type: 'string' },
46
+ IsEnum: { name: 'IsEnum'},
42
47
  };
43
48
  const constants = {
44
49
  TS_CONFIG_DEFAULT_PATH,
45
50
  jsPrimitives,
46
- validatorDecorators,
47
- };
51
+ validatorDecorators};
48
52
 
49
- /**
50
- * Transforms class-validator decorated classes into OpenAPI schema objects.
51
- * Analyzes TypeScript source files directly using the TypeScript compiler API.
52
- * Implemented as a singleton for performance optimization.
53
- *
54
- * @example
55
- * ```typescript
56
- * const transformer = SchemaTransformer.getInstance();
57
- * const schema = transformer.transform(User);
58
- * console.log(schema);
59
- * ```
60
- *
61
- * @public
62
- */
63
53
  class SchemaTransformer {
64
- /**
65
- * Singleton instance
66
- * @private
67
- */
68
54
  static instance = null;
69
- /**
70
- * TypeScript program instance for analyzing source files.
71
- * @private
72
- */
73
55
  program;
74
- /**
75
- * TypeScript type checker for resolving types.
76
- * @private
77
- */
78
56
  checker;
79
- /**
80
- * Cache for storing transformed class schemas to avoid reprocessing.
81
- * Key format: "fileName:className" for uniqueness across different files.
82
- * @private
83
- */
84
57
  classCache = new Map();
85
- /**
86
- * Maximum number of entries to keep in cache before cleanup
87
- * @private
88
- */
89
58
  maxCacheSize;
90
- /**
91
- * Whether to automatically clean up cache
92
- * @private
93
- */
94
59
  autoCleanup;
95
- /**
96
- * Set of file paths that have been loaded to avoid redundant processing
97
- * @private
98
- */
99
60
  loadedFiles = new Set();
100
- /**
101
- * Set of class names currently being processed to prevent circular references
102
- * Key format: "fileName:className" for uniqueness across different files
103
- * @private
104
- */
105
61
  processingClasses = new Set();
106
- /**
107
- * Private constructor for singleton pattern.
108
- *
109
- * @param tsConfigPath - Optional path to a specific TypeScript config file
110
- * @param options - Configuration options for memory management
111
- * @throws {Error} When TypeScript configuration cannot be loaded
112
- * @private
113
- */
114
62
  constructor(tsConfigPath = constants.TS_CONFIG_DEFAULT_PATH, options = {}) {
115
- // Initialize configuration with defaults
116
63
  this.maxCacheSize = options.maxCacheSize ?? 100;
117
64
  this.autoCleanup = options.autoCleanup ?? true;
118
65
  const { config, error } = ts.readConfigFile(tsConfigPath || 'tsconfig.json', ts.sys.readFile);
@@ -124,495 +71,42 @@ class SchemaTransformer {
124
71
  this.program = ts.createProgram(fileNames, tsOptions);
125
72
  this.checker = this.program.getTypeChecker();
126
73
  }
127
- /**
128
- * Generates a unique cache key using file name and class name.
129
- *
130
- * @param fileName - The source file name
131
- * @param className - The class name
132
- * @returns Unique cache key in format "fileName:className"
133
- * @private
134
- */
135
- getCacheKey(fileName, className) {
136
- return `${fileName}:${className}`;
137
- }
138
- /**
139
- * Cleans up cache when it exceeds maximum size to prevent memory leaks.
140
- * Removes oldest entries using LRU strategy.
141
- * @private
142
- */
143
- cleanupCache() {
144
- if (!this.autoCleanup || this.classCache.size <= this.maxCacheSize) {
145
- return;
74
+ getPropertiesByClassDeclaration(classNode, visitedDeclarations = new Set()) {
75
+ if (visitedDeclarations.has(classNode)) {
76
+ return [];
146
77
  }
147
- const entries = Array.from(this.classCache.entries());
148
- const toDelete = entries.slice(0, Math.floor(this.maxCacheSize / 2));
149
- for (const [key] of toDelete) {
150
- this.classCache.delete(key);
151
- }
152
- // Force garbage collection hint
153
- if (global.gc) {
154
- global.gc();
155
- }
156
- }
157
- /**
158
- * Transforms a class by its name into an OpenAPI schema object.
159
- * Considers the context of the calling file to resolve ambiguous class names.
160
- * Includes circular reference detection to prevent infinite recursion.
161
- *
162
- * @param className - The name of the class to transform
163
- * @param contextFilePath - Optional path to context file for resolving class ambiguity
164
- * @returns Object containing the class name and its corresponding JSON schema
165
- * @throws {Error} When the specified class cannot be found
166
- * @private
167
- */
168
- transformByName(className, contextFilePath) {
169
- // Get all relevant source files (not declaration files and not in node_modules)
170
- const sourceFiles = this.program.getSourceFiles().filter(sf => {
171
- if (sf.isDeclarationFile)
172
- return false;
173
- if (sf.fileName.includes('.d.ts'))
174
- return false;
175
- if (sf.fileName.includes('node_modules'))
176
- return false;
177
- // Mark file as loaded for memory tracking
178
- this.loadedFiles.add(sf.fileName);
179
- return true;
180
- });
181
- // If we have a context file, try to find the class in that file first
182
- if (contextFilePath) {
183
- const contextSourceFile = this.program.getSourceFile(contextFilePath);
184
- if (contextSourceFile) {
185
- const classNode = this.findClassByName(contextSourceFile, className);
186
- if (classNode) {
187
- const cacheKey = this.getCacheKey(contextSourceFile.fileName, className);
188
- // Check cache first
189
- if (this.classCache.has(cacheKey)) {
190
- return this.classCache.get(cacheKey);
191
- }
192
- // Check for circular reference before processing
193
- if (this.processingClasses.has(cacheKey)) {
194
- // Return a $ref reference to break circular dependency (OpenAPI 3.1 style)
195
- return {
196
- name: className,
197
- schema: {
198
- $ref: `#/components/schemas/${className}`,
199
- description: `Reference to ${className} (circular reference detected)`,
200
- },
201
- };
202
- }
203
- // Mark this class as being processed
204
- this.processingClasses.add(cacheKey);
205
- try {
206
- const result = this.transformClass(classNode, contextSourceFile);
207
- this.classCache.set(cacheKey, result);
208
- this.cleanupCache();
209
- return result;
210
- }
211
- finally {
212
- // Always remove from processing set when done
213
- this.processingClasses.delete(cacheKey);
214
- }
215
- }
216
- }
217
- }
218
- // Fallback to searching all files, but prioritize files that are more likely to be relevant
219
- const prioritizedFiles = this.prioritizeSourceFiles(sourceFiles, contextFilePath);
220
- for (const sourceFile of prioritizedFiles) {
221
- const classNode = this.findClassByName(sourceFile, className);
222
- if (classNode && sourceFile?.fileName) {
223
- const cacheKey = this.getCacheKey(sourceFile.fileName, className);
224
- // Check cache first using fileName:className as key
225
- if (this.classCache.has(cacheKey)) {
226
- return this.classCache.get(cacheKey);
227
- }
228
- // Check for circular reference before processing
229
- if (this.processingClasses.has(cacheKey)) {
230
- // Return a $ref reference to break circular dependency (OpenAPI 3.1 style)
231
- return {
232
- name: className,
233
- schema: {
234
- $ref: `#/components/schemas/${className}`,
235
- description: `Reference to ${className} (circular reference detected)`,
236
- },
237
- };
238
- }
239
- // Mark this class as being processed
240
- this.processingClasses.add(cacheKey);
241
- try {
242
- const result = this.transformClass(classNode, sourceFile);
243
- // Cache using fileName:className as key for uniqueness
244
- this.classCache.set(cacheKey, result);
245
- // Clean up cache if it gets too large
246
- this.cleanupCache();
247
- return result;
78
+ visitedDeclarations.add(classNode);
79
+ // if no heritage clauses, get properties directly from class
80
+ if (!classNode.heritageClauses) {
81
+ return this.getPropertiesByClassMembers(classNode.members, classNode);
82
+ } // use heritage clauses to get properties from base classes
83
+ else {
84
+ const heritageClause = classNode.heritageClauses[0];
85
+ if (heritageClause &&
86
+ heritageClause.token === ts.SyntaxKind.ExtendsKeyword) {
87
+ const type = heritageClause.types[0];
88
+ let properties = [];
89
+ let baseProperties = [];
90
+ if (!type)
91
+ return [];
92
+ const symbol = this.checker.getSymbolAtLocation(type.expression);
93
+ if (!symbol)
94
+ return [];
95
+ const declaration = symbol.declarations?.[0];
96
+ if (declaration && ts.isClassDeclaration(declaration)) {
97
+ baseProperties = this.getPropertiesByClassDeclaration(declaration, visitedDeclarations);
248
98
  }
249
- finally {
250
- // Always remove from processing set when done
251
- this.processingClasses.delete(cacheKey);
252
- }
253
- }
254
- }
255
- throw new Error(`Class ${className} not found`);
256
- }
257
- /**
258
- * Prioritizes source files based on context to resolve class name conflicts.
259
- * Gives priority to files in the same directory or with similar names.
260
- *
261
- * @param sourceFiles - Array of source files to prioritize
262
- * @param contextFilePath - Optional path to context file for prioritization
263
- * @returns Prioritized array of source files
264
- * @private
265
- */
266
- prioritizeSourceFiles(sourceFiles, contextFilePath) {
267
- if (!contextFilePath) {
268
- return sourceFiles;
269
- }
270
- const contextDir = contextFilePath.substring(0, contextFilePath.lastIndexOf('/'));
271
- return sourceFiles.sort((a, b) => {
272
- const aDir = a.fileName.substring(0, a.fileName.lastIndexOf('/'));
273
- const bDir = b.fileName.substring(0, b.fileName.lastIndexOf('/'));
274
- // Prioritize files in the same directory as context
275
- const aInSameDir = aDir === contextDir ? 1 : 0;
276
- const bInSameDir = bDir === contextDir ? 1 : 0;
277
- if (aInSameDir !== bInSameDir) {
278
- return bInSameDir - aInSameDir; // Higher priority first
279
- }
280
- // Prioritize non-test files over test files
281
- const aIsTest = a.fileName.includes('test') || a.fileName.includes('spec') ? 0 : 1;
282
- const bIsTest = b.fileName.includes('test') || b.fileName.includes('spec') ? 0 : 1;
283
- if (aIsTest !== bIsTest) {
284
- return bIsTest - aIsTest; // Non-test files first
285
- }
286
- return 0;
287
- });
288
- }
289
- /**
290
- * Gets the singleton instance of SchemaTransformer.
291
- *
292
- * @param tsConfigPath - Optional path to a specific TypeScript config file (only used on first call)
293
- * @param options - Configuration options for memory management (only used on first call)
294
- * @returns The singleton instance
295
- *
296
- * @example
297
- * ```typescript
298
- * const transformer = SchemaTransformer.getInstance();
299
- * ```
300
- *
301
- * @example
302
- * ```typescript
303
- * // With memory optimization options
304
- * const transformer = SchemaTransformer.getInstance('./tsconfig.json', {
305
- * maxCacheSize: 50,
306
- * autoCleanup: true
307
- * });
308
- * ```
309
- *
310
- * @public
311
- */
312
- /**
313
- * Clears the current singleton instance. Useful for testing or when you need
314
- * to create a new instance with different configuration.
315
- * @private
316
- */
317
- static clearInstance() {
318
- SchemaTransformer.instance = undefined;
319
- }
320
- /**
321
- * Flag to prevent recursive disposal calls
322
- * @private
323
- */
324
- static disposingInProgress = false;
325
- /**
326
- * Completely disposes of the current singleton instance and releases all resources.
327
- * This is a static method that can be called without having an instance reference.
328
- * Ensures complete memory cleanup regardless of the current state.
329
- *
330
- * @example
331
- * ```typescript
332
- * SchemaTransformer.disposeInstance();
333
- * // All resources released, next getInstance() will create fresh instance
334
- * ```
335
- *
336
- * @public
337
- */
338
- static disposeInstance() {
339
- // Prevent recursive disposal calls
340
- if (SchemaTransformer.disposingInProgress) {
341
- return;
342
- }
343
- SchemaTransformer.disposingInProgress = true;
344
- try {
345
- if (SchemaTransformer.instance) {
346
- SchemaTransformer.instance.dispose();
99
+ properties = this.getPropertiesByClassMembers(classNode.members, classNode);
100
+ return baseProperties.concat(properties);
347
101
  }
348
- }
349
- catch (error) {
350
- // Log any disposal errors but continue with cleanup
351
- console.warn('Warning during static disposal:', error);
352
- }
353
- finally {
354
- // Always ensure the static instance is cleared
355
- SchemaTransformer.instance = undefined;
356
- SchemaTransformer.disposingInProgress = false;
357
- // Force garbage collection for cleanup
358
- if (global.gc) {
359
- global.gc();
360
- }
361
- }
362
- }
363
- /**
364
- * @deprecated Use disposeInstance() instead for better clarity
365
- * @private
366
- */
367
- static dispose() {
368
- SchemaTransformer.disposeInstance();
369
- }
370
- static getInstance(tsConfigPath, options) {
371
- if (!SchemaTransformer.instance || SchemaTransformer.isInstanceDisposed()) {
372
- SchemaTransformer.instance = new SchemaTransformer(tsConfigPath, options);
373
- }
374
- return SchemaTransformer.instance;
375
- }
376
- /**
377
- * Internal method to check if current instance is disposed
378
- * @private
379
- */
380
- static isInstanceDisposed() {
381
- return SchemaTransformer.instance
382
- ? SchemaTransformer.instance.isDisposed()
383
- : true;
384
- }
385
- /**
386
- * Transforms a class using the singleton instance
387
- * @param cls - The class constructor function to transform
388
- * @param options - Optional configuration for memory management (only used if no instance exists)
389
- * @returns Object containing the class name and its corresponding JSON schema
390
- * @public
391
- */
392
- static transformClass(cls, options) {
393
- // Use the singleton instance instead of creating a temporary one
394
- const transformer = SchemaTransformer.getInstance(undefined, options);
395
- return transformer.transform(cls);
396
- }
397
- /**
398
- * Transforms a class constructor function into an OpenAPI schema object.
399
- *
400
- * @param cls - The class constructor function to transform
401
- * @returns Object containing the class name and its corresponding JSON schema
402
- *
403
- * @example
404
- * ```typescript
405
- * import { User } from './entities/user.js';
406
- * const transformer = SchemaTransformer.getInstance();
407
- * const schema = transformer.transform(User);
408
- * ```
409
- *
410
- * @public
411
- */
412
- transform(cls) {
413
- return this.transformByName(cls.name);
414
- }
415
- /**
416
- * Clears all cached schemas and loaded file references to free memory.
417
- * Useful for long-running applications or when processing many different classes.
418
- *
419
- * @example
420
- * ```typescript
421
- * const transformer = SchemaTransformer.getInstance();
422
- * // After processing many classes...
423
- * transformer.clearCache();
424
- * ```
425
- *
426
- * @public
427
- */
428
- clearCache() {
429
- this.classCache.clear();
430
- this.loadedFiles.clear();
431
- this.processingClasses.clear();
432
- // Force garbage collection hint if available
433
- if (global.gc) {
434
- global.gc();
435
- }
436
- }
437
- /**
438
- * Completely disposes of the transformer instance and releases all resources.
439
- * This includes clearing all caches, releasing TypeScript program resources,
440
- * and resetting the singleton instance.
441
- *
442
- * After calling this method, you need to call getInstance() again to get a new instance.
443
- *
444
- * @example
445
- * ```typescript
446
- * const transformer = SchemaTransformer.getInstance();
447
- * // ... use transformer
448
- * transformer.dispose();
449
- * // transformer is now unusable, need to get new instance
450
- * const newTransformer = SchemaTransformer.getInstance();
451
- * ```
452
- *
453
- * @private
454
- */
455
- dispose() {
456
- try {
457
- // Clear all caches and sets completely
458
- this.classCache.clear();
459
- this.loadedFiles.clear();
460
- this.processingClasses.clear();
461
- // Release TypeScript program resources
462
- // While TypeScript doesn't provide explicit disposal methods,
463
- // we can help garbage collection by clearing all references
464
- // Clear all references to TypeScript objects
465
- // @ts-ignore - We're intentionally setting these to null for cleanup
466
- this.program = null;
467
- // @ts-ignore - We're intentionally setting these to null for cleanup
468
- this.checker = null;
469
- }
470
- catch (error) {
471
- // If there's any error during disposal, log it but continue
472
- console.warn('Warning during transformer disposal:', error);
473
- }
474
- finally {
475
- // Force garbage collection for cleanup
476
- if (global.gc) {
477
- global.gc();
102
+ else {
103
+ return this.getPropertiesByClassMembers(classNode.members, classNode);
478
104
  }
479
105
  }
480
106
  }
481
- /**
482
- * Completely resets the transformer by disposing current instance and creating a new one.
483
- * This is useful when you need a fresh start with different TypeScript configuration
484
- * or want to ensure all resources are properly released and recreated.
485
- *
486
- * @param tsConfigPath - Optional path to a specific TypeScript config file for the new instance
487
- * @param options - Configuration options for memory management for the new instance
488
- * @returns A fresh SchemaTransformer instance
489
- *
490
- * @example
491
- * ```typescript
492
- * const transformer = SchemaTransformer.getInstance();
493
- * // ... use transformer
494
- * const freshTransformer = transformer.reset('./new-tsconfig.json');
495
- * ```
496
- *
497
- * @private
498
- */
499
- reset(tsConfigPath, options) {
500
- // Dispose current instance using static method to properly clear instance reference
501
- SchemaTransformer.disposeInstance();
502
- // Create and return new instance
503
- return SchemaTransformer.getInstance(tsConfigPath, options);
504
- }
505
- /**
506
- * Gets memory usage statistics for monitoring and debugging.
507
- *
508
- * @returns Object containing cache size, loaded files count, and processing status
509
- *
510
- * @example
511
- * ```typescript
512
- * const transformer = SchemaTransformer.getInstance();
513
- * const stats = transformer.getMemoryStats();
514
- * console.log(`Cache entries: ${stats.cacheSize}, Files loaded: ${stats.loadedFiles}`);
515
- * console.log(`Currently processing: ${stats.currentlyProcessing} classes`);
516
- * ```
517
- *
518
- * @private
519
- */
520
- getMemoryStats() {
521
- return {
522
- cacheSize: this.classCache?.size || 0,
523
- loadedFiles: this.loadedFiles?.size || 0,
524
- currentlyProcessing: this.processingClasses?.size || 0,
525
- maxCacheSize: this.maxCacheSize || 0,
526
- autoCleanup: this.autoCleanup || false,
527
- isDisposed: !this.program || !this.checker,
528
- };
529
- }
530
- /**
531
- * Checks if the transformer instance has been disposed and is no longer usable.
532
- *
533
- * @returns True if the instance has been disposed
534
- *
535
- * @example
536
- * ```typescript
537
- * const transformer = SchemaTransformer.getInstance();
538
- * transformer.dispose();
539
- * console.log(transformer.isDisposed()); // true
540
- * ```
541
- *
542
- * @private
543
- */
544
- isDisposed() {
545
- return (!this.program ||
546
- !this.checker ||
547
- !this.classCache ||
548
- !this.loadedFiles ||
549
- !this.processingClasses);
550
- }
551
- /**
552
- * Static method to check if there's an active singleton instance.
553
- *
554
- * @returns True if there's an active instance, false if disposed or never created
555
- *
556
- * @example
557
- * ```typescript
558
- * console.log(SchemaTransformer.hasActiveInstance()); // false
559
- * const transformer = SchemaTransformer.getInstance();
560
- * console.log(SchemaTransformer.hasActiveInstance()); // true
561
- * SchemaTransformer.dispose();
562
- * console.log(SchemaTransformer.hasActiveInstance()); // false
563
- * ```
564
- *
565
- * @private
566
- */
567
- static hasActiveInstance() {
568
- return (SchemaTransformer.instance !== null &&
569
- SchemaTransformer.instance !== undefined &&
570
- !SchemaTransformer.isInstanceDisposed());
571
- }
572
- /**
573
- * Finds a class declaration by name within a source file.
574
- *
575
- * @param sourceFile - The TypeScript source file to search in
576
- * @param className - The name of the class to find
577
- * @returns The class declaration node if found, undefined otherwise
578
- * @private
579
- */
580
- findClassByName(sourceFile, className) {
581
- let result;
582
- const visit = (node) => {
583
- if (ts.isClassDeclaration(node) && node.name?.text === className) {
584
- result = node;
585
- return;
586
- }
587
- ts.forEachChild(node, visit);
588
- };
589
- visit(sourceFile);
590
- return result;
591
- }
592
- /**
593
- * Transforms a TypeScript class declaration into a schema object.
594
- *
595
- * @param classNode - The TypeScript class declaration node
596
- * @param sourceFile - The source file containing the class (for context)
597
- * @returns Object containing class name and generated schema
598
- * @private
599
- */
600
- transformClass(classNode, sourceFile) {
601
- const className = classNode.name?.text || 'Unknown';
602
- const properties = this.extractProperties(classNode);
603
- const schema = this.generateSchema(properties, sourceFile?.fileName);
604
- return { name: className, schema };
605
- }
606
- /**
607
- * Extracts property information from a class declaration.
608
- *
609
- * @param classNode - The TypeScript class declaration node
610
- * @returns Array of property information including names, types, decorators, and optional status
611
- * @private
612
- */
613
- extractProperties(classNode) {
107
+ getPropertiesByClassMembers(members, parentClassNode) {
614
108
  const properties = [];
615
- for (const member of classNode.members) {
109
+ for (const member of members) {
616
110
  if (ts.isPropertyDeclaration(member) &&
617
111
  member.name &&
618
112
  ts.isIdentifier(member.name)) {
@@ -620,272 +114,53 @@ class SchemaTransformer {
620
114
  const type = this.getPropertyType(member);
621
115
  const decorators = this.extractDecorators(member);
622
116
  const isOptional = !!member.questionToken;
623
- properties.push({
117
+ const isGeneric = this.isPropertyTypeGeneric(member);
118
+ const isPrimitive = this.isPrimitiveType(type);
119
+ const isClassType = this.isClassType(member);
120
+ const isArray = this.isArrayProperty(member);
121
+ const property = {
624
122
  name: propertyName,
625
123
  type,
626
124
  decorators,
627
125
  isOptional,
628
- });
126
+ isGeneric,
127
+ originalProperty: member,
128
+ isPrimitive,
129
+ isClassType,
130
+ isArray,
131
+ isRef: false,
132
+ };
133
+ // Check for self-referencing properties to mark as $ref
134
+ if (property.isClassType) {
135
+ const declaration = this.getDeclarationProperty(property);
136
+ if (parentClassNode) {
137
+ if (declaration &&
138
+ declaration.name &&
139
+ this.checker.getSymbolAtLocation(declaration.name) ===
140
+ this.checker.getSymbolAtLocation(parentClassNode.name)) {
141
+ property.isRef = true;
142
+ }
143
+ }
144
+ else {
145
+ debugger;
146
+ }
147
+ }
148
+ properties.push(property);
629
149
  }
630
150
  }
631
151
  return properties;
632
152
  }
633
- /**
634
- * Gets the TypeScript type of a property as a string.
635
- *
636
- * @param property - The property declaration to analyze
637
- * @returns String representation of the property's type
638
- * @private
639
- */
640
153
  getPropertyType(property) {
641
154
  if (property.type) {
642
155
  return this.getTypeNodeToString(property.type);
643
156
  }
644
157
  const type = this.checker.getTypeAtLocation(property);
645
- return this.checker.typeToString(type);
158
+ return this.getStringFromType(type);
646
159
  }
647
- /**
648
- * Resolves generic types by analyzing the type alias and its arguments.
649
- * For example, User<Role> where User is a type alias will be resolved to its structure.
650
- *
651
- * @param typeNode - The TypeScript type reference node with generic arguments
652
- * @returns String representation of the resolved type or schema
653
- * @private
654
- */
655
- resolveGenericType(typeNode) {
656
- const typeName = typeNode.typeName.text;
657
- const typeArguments = typeNode.typeArguments;
658
- if (!typeArguments || typeArguments.length === 0) {
659
- return typeName;
660
- }
661
- // Try to resolve the type using the TypeScript type checker
662
- const type = this.checker.getTypeAtLocation(typeNode);
663
- const resolvedType = this.checker.typeToString(type);
664
- // If we can resolve it to a meaningful structure, use that
665
- if (resolvedType &&
666
- resolvedType !== typeName &&
667
- !resolvedType.includes('any')) {
668
- // For type aliases like User<Role>, we want to create a synthetic type name
669
- // that represents the resolved structure
670
- const typeArgNames = typeArguments.map(arg => {
671
- if (ts.isTypeReferenceNode(arg) && ts.isIdentifier(arg.typeName)) {
672
- return arg.typeName.text;
673
- }
674
- return this.getTypeNodeToString(arg);
675
- });
676
- return `${typeName}_${typeArgNames.join('_')}`;
677
- }
678
- return typeName;
679
- }
680
- /**
681
- * Checks if a type string represents a resolved generic type.
682
- *
683
- * @param type - The type string to check
684
- * @returns True if it's a resolved generic type
685
- * @private
686
- */
687
- isResolvedGenericType(type) {
688
- // Simple heuristic: resolved generic types contain underscores and
689
- // the parts after underscore should be known types
690
- const parts = type.split('_');
691
- return (parts.length > 1 &&
692
- parts
693
- .slice(1)
694
- .every(part => this.isKnownType(part) || this.isPrimitiveType(part)));
695
- }
696
- /**
697
- * Checks if a type is a known class or interface.
698
- *
699
- * @param typeName - The type name to check
700
- * @returns True if it's a known type
701
- * @private
702
- */
703
- isKnownType(typeName) {
704
- // First check if it's a primitive type to avoid unnecessary lookups
705
- if (this.isPrimitiveType(typeName)) {
706
- return true;
707
- }
708
- try {
709
- // Use a more conservative approach - check if we can find the class
710
- // without actually transforming it to avoid side effects
711
- const found = this.findClassInProject(typeName);
712
- return found !== null;
713
- }
714
- catch {
715
- return false;
716
- }
717
- }
718
- /**
719
- * Finds a class by name in the project without transforming it.
720
- *
721
- * @param className - The class name to find
722
- * @returns True if found, false otherwise
723
- * @private
724
- */
725
- findClassInProject(className) {
726
- const sourceFiles = this.program.getSourceFiles().filter(sf => {
727
- if (sf.isDeclarationFile)
728
- return false;
729
- if (sf.fileName.includes('.d.ts'))
730
- return false;
731
- if (sf.fileName.includes('node_modules'))
732
- return false;
733
- return true;
734
- });
735
- for (const sourceFile of sourceFiles) {
736
- const found = this.findClassByName(sourceFile, className);
737
- if (found)
738
- return true;
739
- }
740
- return false;
741
- }
742
- /**
743
- * Checks if a type is a primitive type.
744
- *
745
- * @param typeName - The type name to check
746
- * @returns True if it's a primitive type
747
- * @private
748
- */
749
- isPrimitiveType(typeName) {
750
- const lowerTypeName = typeName.toLowerCase();
751
- // Check against all primitive types from constants
752
- const primitiveTypes = [
753
- constants.jsPrimitives.String.type.toLowerCase(),
754
- constants.jsPrimitives.Number.type.toLowerCase(),
755
- constants.jsPrimitives.Boolean.type.toLowerCase(),
756
- constants.jsPrimitives.Date.type.toLowerCase(),
757
- constants.jsPrimitives.Buffer.type.toLowerCase(),
758
- constants.jsPrimitives.Uint8Array.type.toLowerCase(),
759
- constants.jsPrimitives.File.type.toLowerCase(),
760
- constants.jsPrimitives.UploadFile.type.toLowerCase(),
761
- constants.jsPrimitives.BigInt.type.toLowerCase(),
762
- ];
763
- return primitiveTypes.includes(lowerTypeName);
764
- }
765
- /**
766
- * Resolves a generic type schema by analyzing the type alias structure.
767
- *
768
- * @param resolvedTypeName - The resolved generic type name (e.g., User_Role)
769
- * @returns OpenAPI schema for the resolved generic type
770
- * @private
771
- */
772
- resolveGenericTypeSchema(resolvedTypeName) {
773
- const parts = resolvedTypeName.split('_');
774
- const baseTypeName = parts[0];
775
- const typeArgNames = parts.slice(1);
776
- if (!baseTypeName) {
777
- return null;
778
- }
779
- // Find the original type alias declaration
780
- const typeAliasSymbol = this.findTypeAliasDeclaration(baseTypeName);
781
- if (!typeAliasSymbol) {
782
- return null;
783
- }
784
- // Create a schema based on the type alias structure, substituting type parameters
785
- return this.createSchemaFromTypeAlias(typeAliasSymbol, typeArgNames);
786
- }
787
- /**
788
- * Finds a type alias declaration by name.
789
- *
790
- * @param typeName - The type alias name to find
791
- * @returns The type alias declaration node or null
792
- * @private
793
- */
794
- findTypeAliasDeclaration(typeName) {
795
- for (const sourceFile of this.program.getSourceFiles()) {
796
- if (sourceFile.isDeclarationFile)
797
- continue;
798
- const findTypeAlias = (node) => {
799
- if (ts.isTypeAliasDeclaration(node) && node.name.text === typeName) {
800
- return node;
801
- }
802
- return ts.forEachChild(node, findTypeAlias) || null;
803
- };
804
- const result = findTypeAlias(sourceFile);
805
- if (result)
806
- return result;
807
- }
808
- return null;
809
- }
810
- /**
811
- * Creates a schema from a type alias declaration, substituting type parameters.
812
- *
813
- * @param typeAlias - The type alias declaration
814
- * @param typeArgNames - The concrete type arguments
815
- * @returns OpenAPI schema for the type alias
816
- * @private
817
- */
818
- createSchemaFromTypeAlias(typeAlias, typeArgNames) {
819
- const typeNode = typeAlias.type;
820
- if (ts.isTypeLiteralNode(typeNode)) {
821
- const schema = {
822
- type: 'object',
823
- properties: {},
824
- required: [],
825
- };
826
- for (const member of typeNode.members) {
827
- if (ts.isPropertySignature(member) &&
828
- member.name &&
829
- ts.isIdentifier(member.name)) {
830
- const propertyName = member.name.text;
831
- const isOptional = !!member.questionToken;
832
- if (member.type) {
833
- const propertyType = this.resolveTypeParameterInTypeAlias(member.type, typeAlias.typeParameters, typeArgNames);
834
- const { type, format, nestedSchema } = this.mapTypeToSchema(propertyType);
835
- if (nestedSchema) {
836
- schema.properties[propertyName] = nestedSchema;
837
- }
838
- else {
839
- schema.properties[propertyName] = { type };
840
- if (format)
841
- schema.properties[propertyName].format = format;
842
- }
843
- if (!isOptional) {
844
- schema.required.push(propertyName);
845
- }
846
- }
847
- }
848
- }
849
- return schema;
850
- }
851
- return null;
852
- }
853
- /**
854
- * Resolves type parameters in a type alias to concrete types.
855
- *
856
- * @param typeNode - The type node to resolve
857
- * @param typeParameters - The type parameters of the type alias
858
- * @param typeArgNames - The concrete type arguments
859
- * @returns The resolved type string
860
- * @private
861
- */
862
- resolveTypeParameterInTypeAlias(typeNode, typeParameters, typeArgNames) {
863
- if (ts.isTypeReferenceNode(typeNode) &&
864
- ts.isIdentifier(typeNode.typeName)) {
865
- const typeName = typeNode.typeName.text;
866
- // Check if this is a type parameter
867
- if (typeParameters) {
868
- const paramIndex = typeParameters.findIndex(param => param.name.text === typeName);
869
- if (paramIndex !== -1 && paramIndex < typeArgNames.length) {
870
- const resolvedType = typeArgNames[paramIndex];
871
- return resolvedType || typeName;
872
- }
873
- }
874
- return typeName;
875
- }
876
- return this.getTypeNodeToString(typeNode);
877
- }
878
- /**
879
- * Converts a TypeScript type node to its string representation.
880
- *
881
- * @param typeNode - The TypeScript type node to convert
882
- * @returns String representation of the type
883
- * @private
884
- */
885
160
  getTypeNodeToString(typeNode) {
886
161
  if (ts.isTypeReferenceNode(typeNode) &&
887
162
  ts.isIdentifier(typeNode.typeName)) {
888
- if (typeNode.typeName.text.toLowerCase().includes('uploadfile')) {
163
+ if (typeNode.typeName.text.toLowerCase() === 'uploadfile') {
889
164
  return 'UploadFile';
890
165
  }
891
166
  if (typeNode.typeArguments && typeNode.typeArguments.length > 0) {
@@ -893,12 +168,9 @@ class SchemaTransformer {
893
168
  if (firstTypeArg &&
894
169
  ts.isTypeReferenceNode(firstTypeArg) &&
895
170
  ts.isIdentifier(firstTypeArg.typeName)) {
896
- if (firstTypeArg.typeName.text.toLowerCase().includes('uploadfile')) {
171
+ if (firstTypeArg.typeName.text.toLowerCase() === 'uploadfile') {
897
172
  return 'UploadFile';
898
173
  }
899
- if (typeNode.typeName.text === 'BaseDto') {
900
- return firstTypeArg.typeName.text;
901
- }
902
174
  }
903
175
  return this.resolveGenericType(typeNode);
904
176
  }
@@ -937,13 +209,24 @@ class SchemaTransformer {
937
209
  return typeText;
938
210
  }
939
211
  }
940
- /**
941
- * Extracts decorator information from a property declaration.
942
- *
943
- * @param member - The property declaration to analyze
944
- * @returns Array of decorator information including names and arguments
945
- * @private
946
- */
212
+ resolveGenericType(typeNode) {
213
+ const typeName = typeNode.typeName.text;
214
+ const typeArguments = typeNode.typeArguments;
215
+ if (!typeArguments || typeArguments.length === 0) {
216
+ return typeName;
217
+ }
218
+ const type = this.checker.getTypeAtLocation(typeNode);
219
+ const resolvedType = this.getStringFromType(type);
220
+ if (resolvedType &&
221
+ resolvedType !== typeName &&
222
+ !resolvedType.includes('any')) {
223
+ return resolvedType;
224
+ }
225
+ return typeName;
226
+ }
227
+ getStringFromType(type) {
228
+ return this.checker.typeToString(type);
229
+ }
947
230
  extractDecorators(member) {
948
231
  const decorators = [];
949
232
  if (member.modifiers) {
@@ -962,26 +245,12 @@ class SchemaTransformer {
962
245
  }
963
246
  return decorators;
964
247
  }
965
- /**
966
- * Gets the name of a decorator from a call expression.
967
- *
968
- * @param callExpression - The decorator call expression
969
- * @returns The decorator name or "unknown" if not identifiable
970
- * @private
971
- */
972
248
  getDecoratorName(callExpression) {
973
249
  if (ts.isIdentifier(callExpression.expression)) {
974
250
  return callExpression.expression.text;
975
251
  }
976
252
  return 'unknown';
977
253
  }
978
- /**
979
- * Extracts arguments from a decorator call expression.
980
- *
981
- * @param callExpression - The decorator call expression
982
- * @returns Array of parsed decorator arguments
983
- * @private
984
- */
985
254
  getDecoratorArguments(callExpression) {
986
255
  return callExpression.arguments.map(arg => {
987
256
  if (ts.isNumericLiteral(arg))
@@ -995,606 +264,1125 @@ class SchemaTransformer {
995
264
  return arg.getText();
996
265
  });
997
266
  }
998
- /**
999
- * Generates an OpenAPI schema from extracted property information.
1000
- *
1001
- * @param properties - Array of property information to process
1002
- * @param contextFilePath - Optional context file path for resolving class references
1003
- * @returns Complete OpenAPI schema object with properties and validation rules
1004
- * @private
1005
- */
1006
- generateSchema(properties, contextFilePath) {
1007
- const schema = {
267
+ isPropertyTypeGeneric(property) {
268
+ if (property.type && this.isGenericTypeFromNode(property.type)) {
269
+ return true;
270
+ }
271
+ try {
272
+ const type = this.checker.getTypeAtLocation(property);
273
+ return this.isGenericTypeFromSymbol(type);
274
+ }
275
+ catch (error) {
276
+ console.warn('Error analyzing property type for generics:', error);
277
+ return false;
278
+ }
279
+ }
280
+ isGenericTypeFromNode(typeNode) {
281
+ if (ts.isTypeReferenceNode(typeNode) && typeNode.typeArguments) {
282
+ return typeNode.typeArguments.length > 0;
283
+ }
284
+ // Check for mapped types (e.g., { [K in keyof T]: T[K] })
285
+ if (ts.isMappedTypeNode(typeNode)) {
286
+ return true;
287
+ }
288
+ // Check for conditional types (e.g., T extends U ? X : Y)
289
+ if (ts.isConditionalTypeNode(typeNode)) {
290
+ return true;
291
+ }
292
+ // Check for indexed access types (e.g., T[K])
293
+ if (ts.isIndexedAccessTypeNode(typeNode)) {
294
+ return true;
295
+ }
296
+ // Check for type operators like keyof, typeof
297
+ if (ts.isTypeOperatorNode(typeNode)) {
298
+ return true;
299
+ }
300
+ return false;
301
+ }
302
+ isGenericTypeFromSymbol(type) {
303
+ // First check if it's a simple array type - these should NOT be considered generic
304
+ if (this.isSimpleArrayType(type)) {
305
+ return false;
306
+ }
307
+ // Check if the type has type parameters
308
+ if (type.aliasTypeArguments && type.aliasTypeArguments.length > 0) {
309
+ return true;
310
+ }
311
+ // Check if it's a type reference with type arguments
312
+ // But exclude simple arrays which internally use Array<T> representation
313
+ if (type.typeArguments && type.typeArguments.length > 0) {
314
+ const symbol = type.getSymbol();
315
+ if (symbol && symbol.getName() === 'Array') {
316
+ // This is Array<T> - only consider it generic if T itself is a utility type
317
+ const elementType = type.typeArguments[0];
318
+ if (elementType) {
319
+ return this.isUtilityTypeFromType(elementType);
320
+ }
321
+ return false;
322
+ }
323
+ const elementType = type.typeArguments[0];
324
+ return this.isUtilityTypeFromType(elementType);
325
+ }
326
+ // Check type flags for generic indicators
327
+ if (type.flags & ts.TypeFlags.TypeParameter) {
328
+ return true;
329
+ }
330
+ if (type.flags & ts.TypeFlags.Conditional) {
331
+ return true;
332
+ }
333
+ if (type.flags & ts.TypeFlags.Index) {
334
+ return true;
335
+ }
336
+ if (type.flags & ts.TypeFlags.IndexedAccess) {
337
+ return true;
338
+ }
339
+ // Check if the type symbol indicates a generic type
340
+ const symbol = type.getSymbol();
341
+ if (symbol && symbol.declarations) {
342
+ for (const declaration of symbol.declarations) {
343
+ // Check for type alias declarations with type parameters
344
+ if (ts.isTypeAliasDeclaration(declaration) &&
345
+ declaration.typeParameters) {
346
+ return true;
347
+ }
348
+ // Check for interface declarations with type parameters
349
+ if (ts.isInterfaceDeclaration(declaration) &&
350
+ declaration.typeParameters) {
351
+ return true;
352
+ }
353
+ // Check for class declarations with type parameters
354
+ if (ts.isClassDeclaration(declaration) && declaration.typeParameters) {
355
+ return true;
356
+ }
357
+ }
358
+ }
359
+ return false;
360
+ }
361
+ isUtilityTypeFromType(type) {
362
+ if (!type.aliasSymbol)
363
+ return false;
364
+ const aliasName = type.aliasSymbol.getName();
365
+ const utilityTypes = [
366
+ 'Partial',
367
+ 'Required',
368
+ 'Readonly',
369
+ 'Pick',
370
+ 'Omit',
371
+ 'Record',
372
+ 'Exclude',
373
+ 'Extract',
374
+ 'NonNullable',
375
+ ];
376
+ return utilityTypes.includes(aliasName);
377
+ }
378
+ isSimpleArrayType(type) {
379
+ const symbol = type.getSymbol();
380
+ if (!symbol || symbol.getName() !== 'Array') {
381
+ return false;
382
+ }
383
+ // Check if this is Array<T> where T is a simple, non-generic type
384
+ if (type.typeArguments &&
385
+ type.typeArguments.length === 1) {
386
+ const elementType = type.typeArguments[0];
387
+ if (!elementType)
388
+ return false;
389
+ // If the element type is a utility type, then this array should be considered generic
390
+ if (this.isUtilityTypeFromType(elementType)) {
391
+ return false;
392
+ }
393
+ // If the element type itself has generic parameters, this array is generic
394
+ if (elementType.typeArguments &&
395
+ elementType.typeArguments.length > 0) {
396
+ return false;
397
+ }
398
+ return true;
399
+ }
400
+ return false;
401
+ }
402
+ isPrimitiveType(typeName) {
403
+ const lowerTypeName = typeName.toLowerCase();
404
+ // Check against all primitive types from constants
405
+ const primitiveTypes = [
406
+ constants.jsPrimitives.String.type.toLowerCase(),
407
+ constants.jsPrimitives.Number.type.toLowerCase(),
408
+ constants.jsPrimitives.Boolean.type.toLowerCase(),
409
+ constants.jsPrimitives.Date.type.toLowerCase(),
410
+ constants.jsPrimitives.Buffer.type.toLowerCase(),
411
+ constants.jsPrimitives.Uint8Array.type.toLowerCase(),
412
+ constants.jsPrimitives.File.type.toLowerCase(),
413
+ constants.jsPrimitives.UploadFile.type.toLowerCase(),
414
+ constants.jsPrimitives.BigInt.type.toLowerCase(),
415
+ constants.jsPrimitives.Symbol.type.toLowerCase(),
416
+ constants.jsPrimitives.null.type.toLowerCase(),
417
+ constants.jsPrimitives.Object.type.toLowerCase(),
418
+ constants.jsPrimitives.Array.type.toLowerCase(),
419
+ constants.jsPrimitives.Any.type.toLowerCase(),
420
+ constants.jsPrimitives.Unknown.type.toLowerCase(),
421
+ ];
422
+ const primitivesArray = primitiveTypes.map(t => t.concat('[]'));
423
+ return (primitiveTypes.includes(lowerTypeName) ||
424
+ primitivesArray.includes(lowerTypeName));
425
+ }
426
+ static getInstance(tsConfigPath, options) {
427
+ if (!SchemaTransformer.instance) {
428
+ SchemaTransformer.instance = new SchemaTransformer(tsConfigPath, options);
429
+ }
430
+ return SchemaTransformer.instance;
431
+ }
432
+ getSourceFileByClassName(className, sourceOptions) {
433
+ let sourceFiles = [];
434
+ if (sourceOptions?.isExternal) {
435
+ sourceFiles = this.program.getSourceFiles().filter(sf => {
436
+ return (sf.fileName.includes(sourceOptions.packageName) &&
437
+ (!sourceOptions.filePath || sf.fileName === sourceOptions.filePath));
438
+ });
439
+ }
440
+ else {
441
+ sourceFiles = this.program.getSourceFiles().filter(sf => {
442
+ if (sf.isDeclarationFile)
443
+ return false;
444
+ if (sf.fileName.includes('.d.ts'))
445
+ return false;
446
+ if (sf.fileName.includes('node_modules'))
447
+ return false;
448
+ return true;
449
+ });
450
+ }
451
+ for (const sourceFile of sourceFiles) {
452
+ let node;
453
+ const found = sourceFile.statements.some(stmt => {
454
+ node = stmt;
455
+ return (ts.isClassDeclaration(stmt) &&
456
+ stmt.name &&
457
+ stmt.name.text === className);
458
+ });
459
+ if (found) {
460
+ return { sourceFile, node: node };
461
+ }
462
+ }
463
+ }
464
+ isClassType(propertyDeclaration) {
465
+ // If there's no explicit type annotation, we can't determine reliably
466
+ if (!propertyDeclaration.type) {
467
+ return false;
468
+ }
469
+ // Check if the original property type is an array type
470
+ if (this.isArrayProperty(propertyDeclaration) &&
471
+ ts.isTypeReferenceNode(propertyDeclaration.type
472
+ .elementType)) {
473
+ const type = this.checker.getTypeAtLocation(propertyDeclaration.type.elementType);
474
+ const symbol = type.getSymbol();
475
+ if (symbol && symbol.declarations) {
476
+ return symbol.declarations.some(decl => ts.isClassDeclaration(decl));
477
+ }
478
+ }
479
+ else if (ts.isTypeReferenceNode(propertyDeclaration.type)) {
480
+ const type = this.checker.getTypeAtLocation(propertyDeclaration.type);
481
+ const symbol = type.getSymbol();
482
+ if (symbol && symbol.declarations) {
483
+ return symbol.declarations.some(decl => ts.isClassDeclaration(decl));
484
+ }
485
+ }
486
+ return false;
487
+ }
488
+ getDeclarationProperty(property) {
489
+ if (!property.originalProperty.type) {
490
+ return undefined;
491
+ }
492
+ if (ts.isArrayTypeNode(property.originalProperty.type) &&
493
+ ts.isTypeReferenceNode(property.originalProperty.type.elementType)) {
494
+ const type = this.checker.getTypeAtLocation(property.originalProperty.type.elementType);
495
+ const symbol = type.getSymbol();
496
+ if (symbol && symbol.declarations) {
497
+ return symbol.declarations[0];
498
+ }
499
+ }
500
+ else if (ts.isTypeReferenceNode(property.originalProperty.type)) {
501
+ const type = this.checker.getTypeAtLocation(property.originalProperty.type);
502
+ const symbol = type.getSymbol();
503
+ if (symbol && symbol.declarations) {
504
+ return symbol.declarations[0];
505
+ }
506
+ }
507
+ return undefined;
508
+ }
509
+ isArrayProperty(propertyDeclaration) {
510
+ if (!propertyDeclaration.type) {
511
+ return false;
512
+ }
513
+ return ts.isArrayTypeNode(propertyDeclaration.type);
514
+ }
515
+ getSchemaFromProperties({ properties, visitedClass, transformedSchema, classDeclaration, }) {
516
+ let schema = {};
517
+ const required = [];
518
+ for (const property of properties) {
519
+ schema[property.name] = this.getSchemaFromProperty({
520
+ property,
521
+ visitedClass,
522
+ transformedSchema,
523
+ classDeclaration,
524
+ });
525
+ // this.applyDecorators(property, schema as SchemaType)
526
+ if (!property.isOptional) {
527
+ required.push(property.name);
528
+ }
529
+ }
530
+ return {
1008
531
  type: 'object',
1009
- properties: {},
1010
- required: [],
532
+ properties: schema,
533
+ required: required.length ? required : undefined,
1011
534
  };
1012
- for (const property of properties) {
1013
- const { type, format, nestedSchema } = this.mapTypeToSchema(property.type, contextFilePath);
1014
- if (nestedSchema) {
1015
- schema.properties[property.name] = nestedSchema;
1016
- // Skip decorator application for $ref schemas
1017
- if (this.isRefSchema(nestedSchema)) {
1018
- continue;
535
+ }
536
+ getSchemaFromProperty({ property, visitedClass, transformedSchema, classDeclaration, }) {
537
+ let schema = {};
538
+ if (property.isPrimitive) {
539
+ schema = this.getSchemaFromPrimitive(property);
540
+ }
541
+ else if (property.isClassType) {
542
+ const declaration = this.getDeclarationProperty(property);
543
+ if (property.isRef && classDeclaration.name) {
544
+ // Self-referencing property, handle as a reference to avoid infinite recursion
545
+ if (property.isArray) {
546
+ schema.type = 'array';
547
+ schema.items = {
548
+ $ref: `#/components/schemas/${classDeclaration.name.text}`,
549
+ };
550
+ }
551
+ else {
552
+ schema = {
553
+ $ref: `#/components/schemas/${classDeclaration.name.text}`,
554
+ };
1019
555
  }
1020
556
  }
1021
557
  else {
1022
- schema.properties[property.name] = { type };
1023
- if (format)
1024
- schema.properties[property.name].format = format;
1025
- }
1026
- // Apply decorators if present
1027
- this.applyDecorators(property.decorators, schema, property.name);
1028
- // If no decorators are present, apply type-based format specifications
1029
- if (property.decorators.length === 0) {
1030
- this.applyTypeBasedFormats(property, schema);
558
+ schema = this.getSchemaFromClass({
559
+ isArray: property.isArray,
560
+ visitedClass,
561
+ transformedSchema,
562
+ declaration,
563
+ });
1031
564
  }
1032
- // Determine if property should be required based on decorators and optional status
1033
- this.determineRequiredStatus(property, schema);
1034
565
  }
566
+ else {
567
+ schema = { type: 'object', properties: {}, additionalProperties: true };
568
+ }
569
+ this.applyDecorators(property, schema);
1035
570
  return schema;
1036
571
  }
1037
- /**
1038
- * Maps TypeScript types to OpenAPI schema types and formats.
1039
- * Handles primitive types, arrays, and nested objects recursively.
1040
- *
1041
- * @param type - The TypeScript type string to map
1042
- * @param contextFilePath - Optional context file path for resolving class references
1043
- * @returns Object containing OpenAPI type, optional format, and nested schema
1044
- * @private
1045
- */
1046
- mapTypeToSchema(type, contextFilePath) {
1047
- // Handle arrays
1048
- if (type.endsWith('[]')) {
1049
- const elementType = type.slice(0, -2);
1050
- const elementSchema = this.mapTypeToSchema(elementType, contextFilePath);
1051
- const items = elementSchema.nestedSchema || {
1052
- type: elementSchema.type,
1053
- };
1054
- if (elementSchema.format)
1055
- items.format = elementSchema.format;
1056
- return {
1057
- type: 'array',
1058
- nestedSchema: {
1059
- type: 'array',
1060
- items,
1061
- properties: {},
1062
- required: [],
1063
- },
1064
- };
572
+ getSchemaFromClass({ transformedSchema = new Map(), visitedClass = new Set(), declaration, isArray, }) {
573
+ let schema = { type: 'object' };
574
+ if (!declaration ||
575
+ !ts.isClassDeclaration(declaration) ||
576
+ !declaration.name) {
577
+ return { type: 'object' };
1065
578
  }
1066
- if (type.toLocaleLowerCase().includes('uploadfile'))
1067
- type = 'UploadFile';
1068
- // Handle primitives
1069
- switch (type.toLowerCase()) {
1070
- case constants.jsPrimitives.String.type.toLowerCase():
1071
- return { type: constants.jsPrimitives.String.value };
1072
- case constants.jsPrimitives.Number.type.toLowerCase():
1073
- return { type: constants.jsPrimitives.Number.value };
1074
- case constants.jsPrimitives.Boolean.type.toLowerCase():
1075
- return { type: constants.jsPrimitives.Boolean.value };
1076
- case constants.jsPrimitives.Date.type.toLowerCase():
1077
- return {
1078
- type: constants.jsPrimitives.Date.value,
1079
- format: constants.jsPrimitives.Date.format,
1080
- };
1081
- case constants.jsPrimitives.Buffer.type.toLowerCase():
1082
- case constants.jsPrimitives.Uint8Array.type.toLowerCase():
1083
- case constants.jsPrimitives.File.type.toLowerCase():
1084
- return {
1085
- type: constants.jsPrimitives.Buffer.value,
1086
- format: constants.jsPrimitives.Buffer.format,
579
+ if (visitedClass.has(declaration)) {
580
+ if (isArray) {
581
+ schema.type = 'array';
582
+ schema.items = {
583
+ $ref: `#/components/schemas/${declaration.name.text}`,
1087
584
  };
1088
- case constants.jsPrimitives.UploadFile.type.toLowerCase():
1089
- return {
1090
- type: constants.jsPrimitives.UploadFile.value,
1091
- format: constants.jsPrimitives.UploadFile.format,
585
+ }
586
+ else {
587
+ schema = {
588
+ $ref: `#/components/schemas/${declaration.name.text}`,
1092
589
  };
1093
- default:
1094
- // Check if it's a resolved generic type (e.g., User_Role)
1095
- if (type.includes('_') && this.isResolvedGenericType(type)) {
1096
- try {
1097
- const genericSchema = this.resolveGenericTypeSchema(type);
1098
- if (genericSchema) {
1099
- return {
1100
- type: constants.jsPrimitives.Object.value,
1101
- nestedSchema: genericSchema,
1102
- };
1103
- }
1104
- }
1105
- catch (error) {
1106
- console.warn(`Failed to resolve generic type ${type}:`, error);
1107
- }
1108
- }
1109
- // Handle nested objects
1110
- try {
1111
- const nestedResult = this.transformByName(type, contextFilePath);
1112
- // Check if it's a $ref schema (circular reference)
1113
- if (nestedResult.schema.$ref) {
1114
- return {
1115
- type: constants.jsPrimitives.Object.value,
1116
- nestedSchema: nestedResult.schema,
1117
- };
1118
- }
1119
- return {
1120
- type: constants.jsPrimitives.Object.value,
1121
- nestedSchema: nestedResult.schema,
1122
- };
1123
- }
1124
- catch {
1125
- return { type: constants.jsPrimitives.Object.value };
1126
- }
590
+ }
591
+ return schema;
1127
592
  }
593
+ visitedClass.add(declaration);
594
+ const properties = this.getPropertiesByClassDeclaration(declaration);
595
+ let transformerProps = this.getSchemaFromProperties({
596
+ properties,
597
+ visitedClass,
598
+ transformedSchema: transformedSchema,
599
+ classDeclaration: declaration,
600
+ });
601
+ if (isArray) {
602
+ schema.type = 'array';
603
+ schema.items = {
604
+ type: transformerProps.type,
605
+ properties: transformerProps.properties,
606
+ required: transformerProps.required,
607
+ };
608
+ }
609
+ else {
610
+ schema.type = transformerProps.type;
611
+ schema.properties = transformerProps.properties;
612
+ schema.required = transformerProps.required;
613
+ }
614
+ transformedSchema.set(declaration.name.text, schema);
615
+ return schema;
1128
616
  }
1129
- /**
1130
- * Checks if a schema is a $ref schema (circular reference).
1131
- *
1132
- * @param schema - The schema to check
1133
- * @returns True if it's a $ref schema
1134
- * @private
1135
- */
1136
- isRefSchema(schema) {
1137
- return '$ref' in schema;
1138
- }
1139
- /**
1140
- * Applies class-validator decorators to schema properties.
1141
- * Maps validation decorators to their corresponding OpenAPI schema constraints.
1142
- *
1143
- * @param decorators - Array of decorator information to apply
1144
- * @param schema - The schema object to modify
1145
- * @param propertyName - Name of the property being processed
1146
- * @private
1147
- */
1148
- applyDecorators(decorators, schema, propertyName) {
1149
- // Skip applying decorators to $ref schemas
1150
- if (this.isRefSchema(schema)) {
1151
- return;
617
+ getSchemaFromPrimitive(property) {
618
+ const propertySchema = { type: 'object' };
619
+ const propertyType = property.type.toLowerCase().replace('[]', '').trim();
620
+ switch (propertyType) {
621
+ case constants.jsPrimitives.String.value:
622
+ propertySchema.type = constants.jsPrimitives.String.value;
623
+ break;
624
+ case constants.jsPrimitives.Number.value:
625
+ propertySchema.type = constants.jsPrimitives.Number.value;
626
+ propertySchema.format = constants.jsPrimitives.Number.format;
627
+ break;
628
+ case constants.jsPrimitives.BigInt.type.toLocaleLowerCase():
629
+ propertySchema.type = constants.jsPrimitives.BigInt.value;
630
+ propertySchema.format = constants.jsPrimitives.BigInt.format;
631
+ break;
632
+ case constants.jsPrimitives.Date.type.toLocaleLowerCase():
633
+ propertySchema.type = constants.jsPrimitives.Date.value;
634
+ propertySchema.format = constants.jsPrimitives.Date.format;
635
+ break;
636
+ case constants.jsPrimitives.Buffer.value:
637
+ case constants.jsPrimitives.Uint8Array.value:
638
+ case constants.jsPrimitives.File.value:
639
+ case constants.jsPrimitives.UploadFile.value:
640
+ propertySchema.type = constants.jsPrimitives.UploadFile.value;
641
+ propertySchema.format = constants.jsPrimitives.UploadFile.format;
642
+ break;
643
+ case constants.jsPrimitives.Array.value:
644
+ propertySchema.type = constants.jsPrimitives.Array.value;
645
+ break;
646
+ case constants.jsPrimitives.Boolean.value:
647
+ propertySchema.type = constants.jsPrimitives.Boolean.value;
648
+ break;
649
+ case constants.jsPrimitives.Symbol.type.toLocaleLowerCase():
650
+ propertySchema.type = constants.jsPrimitives.Symbol.value;
651
+ break;
652
+ case constants.jsPrimitives.Object.value:
653
+ propertySchema.type = constants.jsPrimitives.Object.value;
654
+ break;
655
+ default:
656
+ propertySchema.type = constants.jsPrimitives.String.value;
657
+ }
658
+ if (property.isArray) {
659
+ propertySchema.type = `array`;
660
+ propertySchema.items = { type: propertyType };
1152
661
  }
1153
- const isArrayType = schema.properties[propertyName].type ===
1154
- constants.jsPrimitives.Array.value;
1155
- for (const decorator of decorators) {
662
+ return propertySchema;
663
+ }
664
+ //Todo: implement properly
665
+ applyEnumDecorator(decorator, schema) { }
666
+ applyDecorators(property, schema) {
667
+ for (const decorator of property.decorators) {
1156
668
  const decoratorName = decorator.name;
1157
669
  switch (decoratorName) {
1158
670
  case constants.validatorDecorators.IsString.name:
1159
- if (!isArrayType) {
1160
- schema.properties[propertyName].type =
1161
- constants.validatorDecorators.IsString.type;
671
+ if (!property.isArray) {
672
+ schema.type = constants.validatorDecorators.IsString.type;
1162
673
  }
1163
- else if (schema.properties[propertyName].items) {
1164
- schema.properties[propertyName].items.type =
1165
- constants.validatorDecorators.IsString.type;
674
+ else if (schema.items) {
675
+ schema.items.type = constants.validatorDecorators.IsString.type;
1166
676
  }
1167
677
  break;
1168
678
  case constants.validatorDecorators.IsInt.name:
1169
- if (!isArrayType) {
1170
- schema.properties[propertyName].type =
1171
- constants.validatorDecorators.IsInt.type;
1172
- schema.properties[propertyName].format =
1173
- constants.validatorDecorators.IsInt.format;
679
+ if (!property.isArray) {
680
+ schema.type = constants.validatorDecorators.IsInt.type;
681
+ schema.format = constants.validatorDecorators.IsInt.format;
1174
682
  }
1175
- else if (schema.properties[propertyName].items) {
1176
- schema.properties[propertyName].items.type =
1177
- constants.validatorDecorators.IsInt.type;
1178
- schema.properties[propertyName].items.format =
1179
- constants.validatorDecorators.IsInt.format;
683
+ else if (schema.items) {
684
+ schema.items.type = constants.validatorDecorators.IsInt.type;
685
+ schema.items.format = constants.validatorDecorators.IsInt.format;
1180
686
  }
1181
687
  break;
1182
688
  case constants.validatorDecorators.IsNumber.name:
1183
- if (!isArrayType) {
1184
- schema.properties[propertyName].type =
1185
- constants.validatorDecorators.IsNumber.type;
689
+ if (!property.isArray) {
690
+ schema.type = constants.validatorDecorators.IsNumber.type;
1186
691
  }
1187
- else if (schema.properties[propertyName].items) {
1188
- schema.properties[propertyName].items.type =
1189
- constants.validatorDecorators.IsNumber.type;
692
+ else if (schema.items) {
693
+ schema.items.type = constants.validatorDecorators.IsNumber.type;
1190
694
  }
1191
695
  break;
1192
696
  case constants.validatorDecorators.IsBoolean.name:
1193
- if (!isArrayType) {
1194
- schema.properties[propertyName].type =
1195
- constants.validatorDecorators.IsBoolean.type;
697
+ if (!property.isArray) {
698
+ schema.type = constants.validatorDecorators.IsBoolean.type;
1196
699
  }
1197
- else if (schema.properties[propertyName].items) {
1198
- schema.properties[propertyName].items.type =
1199
- constants.validatorDecorators.IsBoolean.type;
700
+ else if (schema.items) {
701
+ schema.items.type = constants.validatorDecorators.IsBoolean.type;
1200
702
  }
1201
703
  break;
1202
704
  case constants.validatorDecorators.IsEmail.name:
1203
- if (!isArrayType) {
1204
- schema.properties[propertyName].format =
1205
- constants.validatorDecorators.IsEmail.format;
705
+ if (!property.isArray) {
706
+ schema.format = constants.validatorDecorators.IsEmail.format;
1206
707
  }
1207
- else if (schema.properties[propertyName].items) {
1208
- schema.properties[propertyName].items.format =
1209
- constants.validatorDecorators.IsEmail.format;
708
+ else if (schema.items) {
709
+ schema.items.format = constants.validatorDecorators.IsEmail.format;
1210
710
  }
1211
711
  break;
1212
712
  case constants.validatorDecorators.IsDate.name:
1213
- if (!isArrayType) {
1214
- schema.properties[propertyName].type =
1215
- constants.validatorDecorators.IsDate.type;
1216
- schema.properties[propertyName].format =
1217
- constants.validatorDecorators.IsDate.format;
713
+ if (!property.isArray) {
714
+ schema.type = constants.validatorDecorators.IsDate.type;
715
+ schema.format = constants.validatorDecorators.IsDate.format;
1218
716
  }
1219
- else if (schema.properties[propertyName].items) {
1220
- schema.properties[propertyName].items.type =
1221
- constants.validatorDecorators.IsDate.type;
1222
- schema.properties[propertyName].items.format =
1223
- constants.validatorDecorators.IsDate.format;
717
+ else if (schema.items) {
718
+ schema.items.type = constants.validatorDecorators.IsDate.type;
719
+ schema.items.format = constants.validatorDecorators.IsDate.format;
1224
720
  }
1225
721
  break;
1226
722
  case constants.validatorDecorators.IsNotEmpty.name:
1227
- if (!schema.required.includes(propertyName)) {
1228
- schema.required.push(propertyName);
1229
- }
723
+ property.isOptional = false;
724
+ break;
725
+ case constants.validatorDecorators.IsOptional.name:
726
+ property.isOptional = true;
1230
727
  break;
1231
728
  case constants.validatorDecorators.MinLength.name:
1232
- schema.properties[propertyName].minLength = decorator.arguments[0];
729
+ schema.minLength = decorator.arguments[0];
1233
730
  break;
1234
731
  case constants.validatorDecorators.MaxLength.name:
1235
- schema.properties[propertyName].maxLength = decorator.arguments[0];
732
+ schema.maxLength = decorator.arguments[0];
1236
733
  break;
1237
734
  case constants.validatorDecorators.Length.name:
1238
- schema.properties[propertyName].minLength = decorator.arguments[0];
735
+ schema.minLength = decorator.arguments[0];
1239
736
  if (decorator.arguments[1]) {
1240
- schema.properties[propertyName].maxLength = decorator.arguments[1];
737
+ schema.maxLength = decorator.arguments[1];
1241
738
  }
1242
739
  break;
1243
740
  case constants.validatorDecorators.Min.name:
1244
- schema.properties[propertyName].minimum = decorator.arguments[0];
741
+ schema.minimum = decorator.arguments[0];
1245
742
  break;
1246
743
  case constants.validatorDecorators.Max.name:
1247
- schema.properties[propertyName].maximum = decorator.arguments[0];
744
+ schema.maximum = decorator.arguments[0];
1248
745
  break;
1249
746
  case constants.validatorDecorators.IsPositive.name:
1250
- schema.properties[propertyName].minimum = 0;
747
+ schema.minimum = 0;
1251
748
  break;
1252
749
  case constants.validatorDecorators.IsArray.name:
1253
- schema.properties[propertyName].type =
1254
- constants.jsPrimitives.Array.value;
750
+ schema.type = constants.jsPrimitives.Array.value;
1255
751
  break;
1256
752
  case constants.validatorDecorators.ArrayNotEmpty.name:
1257
- schema.properties[propertyName].minItems = 1;
1258
- if (!schema.required.includes(propertyName)) {
1259
- schema.required.push(propertyName);
1260
- }
753
+ schema.minItems = 1;
754
+ property.isOptional = false;
1261
755
  break;
1262
756
  case constants.validatorDecorators.ArrayMinSize.name:
1263
- schema.properties[propertyName].minItems = decorator.arguments[0];
757
+ schema.minItems = decorator.arguments[0];
1264
758
  break;
1265
759
  case constants.validatorDecorators.ArrayMaxSize.name:
1266
- schema.properties[propertyName].maxItems = decorator.arguments[0];
760
+ schema.maxItems = decorator.arguments[0];
1267
761
  break;
1268
762
  case constants.validatorDecorators.IsEnum.name:
1269
- this.applyEnumDecorator(decorator, schema, propertyName, isArrayType);
763
+ this.applyEnumDecorator(decorator, schema);
1270
764
  break;
1271
765
  }
1272
766
  }
1273
767
  }
1274
- /**
1275
- * Applies the @IsEnum decorator to a property, handling both primitive values and object enums.
1276
- * Supports arrays of enum values as well.
1277
- *
1278
- * @param decorator - The IsEnum decorator information
1279
- * @param schema - The schema object to modify
1280
- * @param propertyName - The name of the property
1281
- * @param isArrayType - Whether the property is an array type
1282
- * @private
1283
- */
1284
- applyEnumDecorator(decorator, schema, propertyName, isArrayType) {
1285
- if (!decorator.arguments || decorator.arguments.length === 0) {
1286
- return;
1287
- }
1288
- const enumArg = decorator.arguments[0];
1289
- let enumValues = [];
1290
- // Handle different enum argument types
1291
- if (typeof enumArg === 'string') {
1292
- // This is likely a reference to an enum type name
1293
- // We need to try to resolve this to actual enum values
1294
- enumValues = this.resolveEnumValues(enumArg);
1295
- }
1296
- else if (typeof enumArg === 'object' && enumArg !== null) {
1297
- // Object enum - extract values
1298
- if (Array.isArray(enumArg)) {
1299
- // Already an array of values
1300
- enumValues = enumArg;
1301
- }
1302
- else {
1303
- // Enum object - get all values
1304
- enumValues = Object.values(enumArg);
1305
- }
1306
- }
1307
- // If we couldn't resolve enum values, fall back to string type without enum constraint
1308
- if (enumValues.length === 0) {
1309
- if (!isArrayType) {
1310
- schema.properties[propertyName].type = 'string';
1311
- }
1312
- else if (schema.properties[propertyName].items) {
1313
- schema.properties[propertyName].items.type = 'string';
1314
- }
1315
- return;
1316
- }
1317
- // Determine the type based on enum values
1318
- let enumType = 'string';
1319
- if (enumValues.length > 0) {
1320
- const firstValue = enumValues[0];
1321
- if (typeof firstValue === 'number') {
1322
- enumType = 'number';
1323
- }
1324
- else if (typeof firstValue === 'boolean') {
1325
- enumType = 'boolean';
1326
- }
1327
- }
1328
- // Apply enum to schema
1329
- if (!isArrayType) {
1330
- schema.properties[propertyName].type = enumType;
1331
- schema.properties[propertyName].enum = enumValues;
1332
- }
1333
- else if (schema.properties[propertyName].items) {
1334
- schema.properties[propertyName].items.type = enumType;
1335
- schema.properties[propertyName].items.enum = enumValues;
1336
- }
1337
- }
1338
- /**
1339
- * Attempts to resolve enum values from an enum type name.
1340
- * This searches through the TypeScript AST to find the enum declaration
1341
- * and extract its values.
1342
- *
1343
- * @param enumTypeName - The name of the enum type
1344
- * @returns Array of enum values if found, empty array otherwise
1345
- * @private
1346
- */
1347
- resolveEnumValues(enumTypeName) {
1348
- // Search for enum declarations in source files
1349
- for (const sourceFile of this.program.getSourceFiles()) {
1350
- if (sourceFile.isDeclarationFile)
1351
- continue;
1352
- if (sourceFile.fileName.includes('node_modules'))
1353
- continue;
1354
- const enumValues = this.findEnumValues(sourceFile, enumTypeName);
1355
- if (enumValues.length > 0) {
1356
- return enumValues;
1357
- }
768
+ transform(cls, sourceOptions) {
769
+ let schema = { type: 'object', properties: {} };
770
+ const result = this.getSourceFileByClassName(cls.name, sourceOptions);
771
+ if (!result?.sourceFile) {
772
+ console.warn(`Class ${cls.name} not found in any source file.`);
773
+ return { name: cls.name, schema: {} };
1358
774
  }
1359
- return [];
1360
- }
1361
- /**
1362
- * Finds enum values in a specific source file.
1363
- *
1364
- * @param sourceFile - The source file to search
1365
- * @param enumTypeName - The name of the enum to find
1366
- * @returns Array of enum values if found, empty array otherwise
1367
- * @private
1368
- */
1369
- findEnumValues(sourceFile, enumTypeName) {
1370
- let enumValues = [];
1371
- const visit = (node) => {
1372
- // Handle TypeScript enum declarations
1373
- if (ts.isEnumDeclaration(node) && node.name?.text === enumTypeName) {
1374
- enumValues = this.extractEnumValues(node);
1375
- return;
1376
- }
1377
- // Handle const object declarations (like const Status = { ... } as const)
1378
- if (ts.isVariableStatement(node)) {
1379
- for (const declaration of node.declarationList.declarations) {
1380
- if (ts.isVariableDeclaration(declaration) &&
1381
- ts.isIdentifier(declaration.name) &&
1382
- declaration.name.text === enumTypeName &&
1383
- declaration.initializer) {
1384
- let initializer = declaration.initializer;
1385
- // Handle "as const" assertions
1386
- if (ts.isAsExpression(initializer) && initializer.expression) {
1387
- initializer = initializer.expression;
1388
- }
1389
- enumValues = this.extractObjectEnumValues(initializer);
1390
- return;
1391
- }
1392
- }
1393
- }
1394
- ts.forEachChild(node, visit);
1395
- };
1396
- visit(sourceFile);
1397
- return enumValues;
1398
- }
1399
- /**
1400
- * Extracts values from a TypeScript enum declaration.
1401
- *
1402
- * @param enumNode - The enum declaration node
1403
- * @returns Array of enum values
1404
- * @private
1405
- */
1406
- extractEnumValues(enumNode) {
1407
- const values = [];
1408
- for (const member of enumNode.members) {
1409
- if (member.initializer) {
1410
- // Handle initialized enum members
1411
- if (ts.isStringLiteral(member.initializer)) {
1412
- values.push(member.initializer.text);
1413
- }
1414
- else if (ts.isNumericLiteral(member.initializer)) {
1415
- values.push(Number(member.initializer.text));
1416
- }
1417
- }
1418
- else {
1419
- // Handle auto-incremented numeric enums
1420
- if (values.length === 0) {
1421
- values.push(0);
1422
- }
1423
- else {
1424
- const lastValue = values[values.length - 1];
1425
- if (typeof lastValue === 'number') {
1426
- values.push(lastValue + 1);
1427
- }
1428
- }
1429
- }
1430
- }
1431
- return values;
1432
- }
1433
- /**
1434
- * Extracts values from object literal enum (const object as const).
1435
- *
1436
- * @param initializer - The object literal initializer
1437
- * @returns Array of enum values
1438
- * @private
1439
- */
1440
- extractObjectEnumValues(initializer) {
1441
- const values = [];
1442
- if (ts.isObjectLiteralExpression(initializer)) {
1443
- for (const property of initializer.properties) {
1444
- if (ts.isPropertyAssignment(property) && property.initializer) {
1445
- if (ts.isStringLiteral(property.initializer)) {
1446
- values.push(property.initializer.text);
1447
- }
1448
- else if (ts.isNumericLiteral(property.initializer)) {
1449
- values.push(Number(property.initializer.text));
1450
- }
1451
- }
1452
- }
1453
- }
1454
- return values;
1455
- }
1456
- /**
1457
- * Applies sensible default behaviors for properties without class-validator decorators.
1458
- * This allows the schema generator to work with plain TypeScript classes.
1459
- *
1460
- * @param property - The property information
1461
- * @param schema - The schema object to modify
1462
- * @private
1463
- */
1464
- /**
1465
- * Applies OpenAPI format specifications based on TypeScript types.
1466
- * This method is called when no decorators are present to set appropriate
1467
- * format values for primitive types according to OpenAPI specification.
1468
- *
1469
- * @param property - The property information containing type details
1470
- * @param schema - The schema object to modify
1471
- * @private
1472
- */
1473
- applyTypeBasedFormats(property, schema) {
1474
- // Skip applying type-based formats to $ref schemas
1475
- if (this.isRefSchema(schema)) {
1476
- return;
1477
- }
1478
- const propertyName = property.name;
1479
- const propertyType = property.type.toLowerCase();
1480
- const propertySchema = schema.properties[propertyName];
1481
- switch (propertyType) {
1482
- case constants.jsPrimitives.Number.value:
1483
- propertySchema.format = constants.jsPrimitives.Number.format;
1484
- break;
1485
- case constants.jsPrimitives.BigInt.value:
1486
- propertySchema.format = constants.jsPrimitives.BigInt.format;
1487
- break;
1488
- case constants.jsPrimitives.Date.value:
1489
- propertySchema.format = constants.jsPrimitives.Date.format;
1490
- break;
1491
- case constants.jsPrimitives.Buffer.value:
1492
- case constants.jsPrimitives.Uint8Array.value:
1493
- case constants.jsPrimitives.File.value:
1494
- case constants.jsPrimitives.UploadFile.value:
1495
- propertySchema.format = constants.jsPrimitives.UploadFile.format;
1496
- break;
1497
- }
1498
- }
1499
- /**
1500
- * Determines if a property should be required based on decorators and optional status.
1501
- *
1502
- * Logic:
1503
- * - If property has IsNotEmpty or ArrayNotEmpty decorator, it's required (handled in applyDecorators)
1504
- * - Otherwise, the property is not required (preserving original behavior)
1505
- * - The isOptional information is stored for future use and documentation
1506
- *
1507
- * @param property - The property information
1508
- * @param schema - The schema object to modify
1509
- * @private
1510
- */
1511
- determineRequiredStatus(property, schema) {
1512
- // Skip determining required status for $ref schemas
1513
- if (this.isRefSchema(schema)) {
1514
- return;
1515
- }
1516
- const propertyName = property.name;
1517
- // Check if already marked as required by IsNotEmpty or ArrayNotEmpty decorator
1518
- const isAlreadyRequired = schema.required.includes(propertyName);
1519
- // If already required by decorators, don't change it
1520
- if (isAlreadyRequired) {
1521
- return;
1522
- }
1523
- // If property is optional (has ?), it should not be required unless explicitly marked
1524
- if (property.isOptional) {
1525
- return;
1526
- }
1527
- // If property is not optional and not already required, make it required
1528
- schema.required.push(propertyName);
775
+ const properties = this.getPropertiesByClassDeclaration(result.node);
776
+ schema = this.getSchemaFromProperties({
777
+ properties,
778
+ classDeclaration: result.node,
779
+ });
780
+ return { name: cls.name, schema };
1529
781
  }
1530
782
  }
783
+ function transform(cls, options) {
784
+ // Use the singleton instance instead of creating a temporary one
785
+ const transformer = SchemaTransformer.getInstance(undefined, options);
786
+ return transformer.transform(cls, options?.sourceOptions);
787
+ }
788
+
1531
789
  /**
1532
- * Convenience function to transform a class using the singleton instance.
1533
- *
1534
- * @param cls - The class constructor function to transform
1535
- * @param options - Optional configuration for memory management
1536
- * @returns Object containing the class name and its corresponding JSON schema
1537
- *
1538
- * @example
1539
- * ```typescript
1540
- * import { transform } from 'class-validator-to-open-api'
1541
- * import { User } from './entities/user.js'
1542
- *
1543
- * const schema = transform(User)
1544
- * console.log(schema)
1545
- * ```
1546
- *
1547
- * @example
1548
- * ```typescript
1549
- * // With memory optimization
1550
- * const schema = transform(User, { maxCacheSize: 50, autoCleanup: true })
1551
- * ```
1552
- *
1553
- * @public
790
+ * Pure TypeScript class without any decorators
791
+ * Used to test basic type inference and transformation
1554
792
  */
1555
- function transform(cls, options) {
1556
- return SchemaTransformer.transformClass(cls, options);
793
+ class PureUser {
794
+ id;
795
+ name;
796
+ email;
797
+ age;
798
+ isActive;
799
+ tags;
800
+ metadata;
801
+ createdAt;
802
+ phone;
803
+ bio;
804
+ }
805
+ /**
806
+ * Pure TypeScript class with primitive types only
807
+ */
808
+ class SimplePerson {
809
+ firstName;
810
+ lastName;
811
+ age;
812
+ isEmployed;
813
+ }
814
+ /**
815
+ * Pure TypeScript class with arrays
816
+ */
817
+ class Product {
818
+ id;
819
+ name;
820
+ price;
821
+ categories;
822
+ scores;
823
+ isAvailable;
824
+ description;
1557
825
  }
1558
826
 
1559
- class FileTest {
1560
- avatar;
1561
- files;
827
+ /**
828
+ * Additional test classes for pure TypeScript classes tests
829
+ * These classes are used in the pure-classes.test.ts file
830
+ */
831
+ class OptionalOnlyClass {
832
+ optionalProp;
833
+ anotherOptional;
1562
834
  }
1563
- // New test classes without decorators
1564
- class PlainUser {
835
+ class UnionTypeClass {
836
+ stringOrNumber;
837
+ optionalUnion;
838
+ }
839
+
840
+ /**
841
+ * Test cases for pure TypeScript classes (without decorators)
842
+ */
843
+ node_test.describe('Pure TypeScript Classes', () => {
844
+ node_test.test('should transform PureUser class correctly', () => {
845
+ const result = transform(PureUser);
846
+ const schema = result.schema;
847
+ assert.strictEqual(schema.type, 'object');
848
+ assert.ok(schema.properties);
849
+ // Check basic properties
850
+ assert.strictEqual(schema.properties.id.type, 'number');
851
+ assert.strictEqual(schema.properties.name.type, 'string');
852
+ assert.strictEqual(schema.properties.email.type, 'string');
853
+ assert.strictEqual(schema.properties.age.type, 'number');
854
+ assert.strictEqual(schema.properties.isActive.type, 'boolean');
855
+ // Check array properties
856
+ assert.strictEqual(schema.properties.tags.type, 'array');
857
+ assert.strictEqual(schema.properties.tags.items.type, 'string');
858
+ // Check required fields (all non-optional fields should be required)
859
+ const expectedRequired = [
860
+ 'id',
861
+ 'name',
862
+ 'email',
863
+ 'age',
864
+ 'isActive',
865
+ 'tags',
866
+ 'metadata',
867
+ 'createdAt',
868
+ ];
869
+ assert.deepStrictEqual(schema.required?.sort(), expectedRequired.sort());
870
+ });
871
+ node_test.test('should transform SimplePerson class correctly', () => {
872
+ const result = transform(SimplePerson);
873
+ const schema = result.schema;
874
+ assert.strictEqual(schema.type, 'object');
875
+ assert.ok(schema.properties);
876
+ assert.strictEqual(schema.properties.firstName.type, 'string');
877
+ assert.strictEqual(schema.properties.lastName.type, 'string');
878
+ assert.strictEqual(schema.properties.age.type, 'number');
879
+ assert.strictEqual(schema.properties.isEmployed.type, 'boolean');
880
+ assert.deepStrictEqual(schema.required?.sort(), ['firstName', 'lastName', 'age', 'isEmployed'].sort());
881
+ });
882
+ node_test.test('should transform Product class correctly', () => {
883
+ const result = transform(Product);
884
+ const schema = result.schema;
885
+ assert.strictEqual(schema.type, 'object');
886
+ assert.ok(schema.properties);
887
+ // Check basic properties
888
+ assert.strictEqual(schema.properties.id.type, 'number');
889
+ assert.strictEqual(schema.properties.name.type, 'string');
890
+ assert.strictEqual(schema.properties.price.type, 'number');
891
+ assert.strictEqual(schema.properties.isAvailable.type, 'boolean');
892
+ // Check array property
893
+ assert.strictEqual(schema.properties.categories.type, 'array');
894
+ assert.strictEqual(schema.properties.categories.items.type, 'string');
895
+ assert.strictEqual(schema.properties.scores.type, 'array');
896
+ assert.strictEqual(schema.properties.scores.items.type, 'number');
897
+ // Check optional fields are not in required
898
+ const requiredFields = schema.required || [];
899
+ assert.ok(!requiredFields.includes('description'));
900
+ });
901
+ node_test.test('should handle class with only optional properties', () => {
902
+ const result = transform(OptionalOnlyClass);
903
+ const schema = result.schema;
904
+ assert.strictEqual(schema.type, 'object');
905
+ assert.ok(schema.properties);
906
+ assert.strictEqual(schema.properties.optionalProp.type, 'string');
907
+ assert.strictEqual(schema.properties.anotherOptional.type, 'number');
908
+ // Should have no required fields
909
+ assert.ok(!schema.required || schema.required.length === 0);
910
+ });
911
+ node_test.test('should handle union types', () => {
912
+ const result = transform(UnionTypeClass);
913
+ const schema = result.schema;
914
+ assert.strictEqual(schema.type, 'object');
915
+ assert.ok(schema.properties);
916
+ // Union types should be handled appropriately
917
+ assert.ok(schema.properties.stringOrNumber);
918
+ assert.ok(schema.properties.optionalUnion);
919
+ });
920
+ });
921
+
922
+ /******************************************************************************
923
+ Copyright (c) Microsoft Corporation.
924
+
925
+ Permission to use, copy, modify, and/or distribute this software for any
926
+ purpose with or without fee is hereby granted.
927
+
928
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
929
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
930
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
931
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
932
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
933
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
934
+ PERFORMANCE OF THIS SOFTWARE.
935
+ ***************************************************************************** */
936
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
937
+
938
+
939
+ function __decorate(decorators, target, key, desc) {
940
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
941
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
942
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
943
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
944
+ }
945
+
946
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
947
+ var e = new Error(message);
948
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
949
+ };
950
+
951
+ var UserStatus;
952
+ (function (UserStatus) {
953
+ UserStatus["ACTIVE"] = "active";
954
+ UserStatus["INACTIVE"] = "inactive";
955
+ UserStatus["PENDING"] = "pending";
956
+ UserStatus["SUSPENDED"] = "suspended";
957
+ })(UserStatus || (UserStatus = {}));
958
+ var Priority;
959
+ (function (Priority) {
960
+ Priority[Priority["LOW"] = 1] = "LOW";
961
+ Priority[Priority["MEDIUM"] = 2] = "MEDIUM";
962
+ Priority[Priority["HIGH"] = 3] = "HIGH";
963
+ Priority[Priority["CRITICAL"] = 4] = "CRITICAL";
964
+ })(Priority || (Priority = {}));
965
+ class DecoratedAddress {
966
+ street;
967
+ city;
968
+ state;
969
+ zipCode;
970
+ country;
971
+ }
972
+ __decorate([
973
+ classValidator.IsString(),
974
+ classValidator.Length(5, 100)
975
+ ], DecoratedAddress.prototype, "street", void 0);
976
+ __decorate([
977
+ classValidator.IsString(),
978
+ classValidator.Length(2, 50)
979
+ ], DecoratedAddress.prototype, "city", void 0);
980
+ __decorate([
981
+ classValidator.IsString(),
982
+ classValidator.Length(2, 50)
983
+ ], DecoratedAddress.prototype, "state", void 0);
984
+ __decorate([
985
+ classValidator.IsString(),
986
+ classValidator.Matches(/^\d{5}(-\d{4})?$/)
987
+ ], DecoratedAddress.prototype, "zipCode", void 0);
988
+ __decorate([
989
+ classValidator.IsString(),
990
+ classValidator.Length(2, 50)
991
+ ], DecoratedAddress.prototype, "country", void 0);
992
+ class DecoratedUser {
1565
993
  id;
1566
994
  name;
1567
995
  email;
1568
996
  age;
997
+ status;
1569
998
  isActive;
1570
999
  tags;
1000
+ address;
1571
1001
  createdAt;
1572
- profile;
1002
+ updatedAt;
1573
1003
  }
1574
- class UserProfile {
1575
- bio;
1576
- avatar;
1004
+ __decorate([
1005
+ classValidator.IsNumber(),
1006
+ classValidator.IsPositive()
1007
+ ], DecoratedUser.prototype, "id", void 0);
1008
+ __decorate([
1009
+ classValidator.IsString(),
1010
+ classValidator.Length(2, 50)
1011
+ ], DecoratedUser.prototype, "name", void 0);
1012
+ __decorate([
1013
+ classValidator.IsEmail()
1014
+ ], DecoratedUser.prototype, "email", void 0);
1015
+ __decorate([
1016
+ classValidator.IsNumber(),
1017
+ classValidator.Min(18),
1018
+ classValidator.Max(120)
1019
+ ], DecoratedUser.prototype, "age", void 0);
1020
+ __decorate([
1021
+ classValidator.IsEnum(UserStatus)
1022
+ ], DecoratedUser.prototype, "status", void 0);
1023
+ __decorate([
1024
+ classValidator.IsBoolean(),
1025
+ classValidator.IsOptional()
1026
+ ], DecoratedUser.prototype, "isActive", void 0);
1027
+ __decorate([
1028
+ classValidator.IsArray(),
1029
+ classValidator.IsString({ each: true })
1030
+ ], DecoratedUser.prototype, "tags", void 0);
1031
+ __decorate([
1032
+ classValidator.ValidateNested()
1033
+ ], DecoratedUser.prototype, "address", void 0);
1034
+ __decorate([
1035
+ classValidator.IsDate()
1036
+ ], DecoratedUser.prototype, "createdAt", void 0);
1037
+ __decorate([
1038
+ classValidator.IsOptional(),
1039
+ classValidator.IsDate()
1040
+ ], DecoratedUser.prototype, "updatedAt", void 0);
1041
+ class DecoratedProduct {
1042
+ id;
1043
+ name;
1044
+ description;
1045
+ price;
1046
+ currency;
1047
+ categories;
1048
+ inStock;
1049
+ quantity;
1050
+ images;
1577
1051
  }
1578
- console.log('Testing original class:');
1579
- const result = transform(FileTest);
1580
- console.log(JSON.stringify(result, null, 2));
1581
- console.log('\n--- NEW FUNCTIONALITY ---');
1582
- console.log('Testing class WITHOUT decorators:');
1583
- try {
1584
- const plainUserResult = transform(PlainUser);
1585
- console.log('✅ Success! Generated schema for plain class:');
1586
- console.log(JSON.stringify(plainUserResult, null, 2));
1052
+ __decorate([
1053
+ classValidator.IsNumber(),
1054
+ classValidator.IsPositive()
1055
+ ], DecoratedProduct.prototype, "id", void 0);
1056
+ __decorate([
1057
+ classValidator.IsString(),
1058
+ classValidator.Length(3, 100)
1059
+ ], DecoratedProduct.prototype, "name", void 0);
1060
+ __decorate([
1061
+ classValidator.IsString(),
1062
+ classValidator.Length(10, 500)
1063
+ ], DecoratedProduct.prototype, "description", void 0);
1064
+ __decorate([
1065
+ classValidator.IsNumber(),
1066
+ classValidator.Min(0)
1067
+ ], DecoratedProduct.prototype, "price", void 0);
1068
+ __decorate([
1069
+ classValidator.IsString(),
1070
+ classValidator.Length(3, 20)
1071
+ ], DecoratedProduct.prototype, "currency", void 0);
1072
+ __decorate([
1073
+ classValidator.IsArray(),
1074
+ classValidator.IsString({ each: true })
1075
+ ], DecoratedProduct.prototype, "categories", void 0);
1076
+ __decorate([
1077
+ classValidator.IsBoolean()
1078
+ ], DecoratedProduct.prototype, "inStock", void 0);
1079
+ __decorate([
1080
+ classValidator.IsOptional(),
1081
+ classValidator.IsNumber(),
1082
+ classValidator.Min(0)
1083
+ ], DecoratedProduct.prototype, "quantity", void 0);
1084
+ __decorate([
1085
+ classValidator.IsOptional(),
1086
+ classValidator.IsArray(),
1087
+ classValidator.IsString({ each: true })
1088
+ ], DecoratedProduct.prototype, "images", void 0);
1089
+ class DecoratedTask {
1090
+ id;
1091
+ title;
1092
+ description;
1093
+ priority;
1094
+ completed;
1095
+ dueDate;
1096
+ assignedTo;
1097
+ tags;
1098
+ createdAt;
1099
+ completedAt;
1587
1100
  }
1588
- catch (error) {
1589
- console.error('❌ Error:', error instanceof Error ? error.message : String(error));
1101
+ __decorate([
1102
+ classValidator.IsNumber(),
1103
+ classValidator.IsPositive()
1104
+ ], DecoratedTask.prototype, "id", void 0);
1105
+ __decorate([
1106
+ classValidator.IsString(),
1107
+ classValidator.Length(5, 100)
1108
+ ], DecoratedTask.prototype, "title", void 0);
1109
+ __decorate([
1110
+ classValidator.IsString(),
1111
+ classValidator.Length(10, 1000)
1112
+ ], DecoratedTask.prototype, "description", void 0);
1113
+ __decorate([
1114
+ classValidator.IsEnum(Priority)
1115
+ ], DecoratedTask.prototype, "priority", void 0);
1116
+ __decorate([
1117
+ classValidator.IsBoolean()
1118
+ ], DecoratedTask.prototype, "completed", void 0);
1119
+ __decorate([
1120
+ classValidator.IsDate()
1121
+ ], DecoratedTask.prototype, "dueDate", void 0);
1122
+ __decorate([
1123
+ classValidator.IsOptional(),
1124
+ classValidator.ValidateNested()
1125
+ ], DecoratedTask.prototype, "assignedTo", void 0);
1126
+ __decorate([
1127
+ classValidator.IsArray(),
1128
+ classValidator.IsString({ each: true }),
1129
+ classValidator.IsOptional()
1130
+ ], DecoratedTask.prototype, "tags", void 0);
1131
+ __decorate([
1132
+ classValidator.IsDate()
1133
+ ], DecoratedTask.prototype, "createdAt", void 0);
1134
+ __decorate([
1135
+ classValidator.IsOptional(),
1136
+ classValidator.IsDate()
1137
+ ], DecoratedTask.prototype, "completedAt", void 0);
1138
+
1139
+ /**
1140
+ * Test cases for decorated classes using class-validator
1141
+ */
1142
+ node_test.describe('Decorated Classes with class-validator', () => {
1143
+ node_test.test('should transform DecoratedAddress with validation constraints', () => {
1144
+ const result = transform(DecoratedAddress);
1145
+ const schema = result.schema;
1146
+ assert.strictEqual(schema.type, 'object');
1147
+ assert.ok(schema.properties);
1148
+ assert.strictEqual(schema.properties.street.minLength, 5);
1149
+ assert.strictEqual(schema.properties.street.maxLength, 100);
1150
+ assert.strictEqual(schema.properties.city.minLength, 2);
1151
+ assert.strictEqual(schema.properties.city.maxLength, 50);
1152
+ assert.strictEqual(schema.properties.state.minLength, 2);
1153
+ assert.strictEqual(schema.properties.state.maxLength, 50);
1154
+ assert.strictEqual(schema.properties.country.minLength, 2);
1155
+ assert.strictEqual(schema.properties.country.maxLength, 50);
1156
+ assert.strictEqual(schema.properties.zipCode.type, 'string');
1157
+ });
1158
+ node_test.test('should transform DecoratedUser with comprehensive validation', () => {
1159
+ const result = transform(DecoratedUser);
1160
+ const schema = result.schema;
1161
+ assert.strictEqual(schema.type, 'object');
1162
+ assert.ok(schema.properties);
1163
+ assert.strictEqual(schema.properties.email.format, 'email');
1164
+ assert.strictEqual(schema.properties.age.minimum, 18);
1165
+ assert.strictEqual(schema.properties.age.maximum, 120);
1166
+ assert.strictEqual(schema.properties.id.minimum, 0);
1167
+ assert.strictEqual(schema.properties.name.minLength, 2);
1168
+ assert.strictEqual(schema.properties.name.maxLength, 50);
1169
+ assert.ok(schema.properties.status);
1170
+ assert.strictEqual(schema.properties.tags.type, 'array');
1171
+ assert.strictEqual(schema.properties.tags.items.type, 'string');
1172
+ assert.strictEqual(schema.properties.address.type, 'object');
1173
+ assert.strictEqual(schema.properties.createdAt.type, 'string');
1174
+ assert.strictEqual(schema.properties.createdAt.format, 'date-time');
1175
+ const requiredFields = schema.required || [];
1176
+ assert.ok(!requiredFields.includes('isActive'));
1177
+ assert.ok(!requiredFields.includes('updatedAt'));
1178
+ });
1179
+ node_test.test('should transform DecoratedProduct with validation constraints', () => {
1180
+ const result = transform(DecoratedProduct);
1181
+ const schema = result.schema;
1182
+ assert.strictEqual(schema.type, 'object');
1183
+ assert.ok(schema.properties);
1184
+ assert.strictEqual(schema.properties.id.minimum, 0);
1185
+ assert.strictEqual(schema.properties.price.minimum, 0);
1186
+ // Check string length constraints
1187
+ assert.strictEqual(schema.properties.name.minLength, 3);
1188
+ assert.strictEqual(schema.properties.name.maxLength, 100);
1189
+ assert.strictEqual(schema.properties.description.minLength, 10);
1190
+ assert.strictEqual(schema.properties.description.maxLength, 500);
1191
+ assert.strictEqual(schema.properties.currency.minLength, 3);
1192
+ assert.strictEqual(schema.properties.currency.maxLength, 20);
1193
+ assert.strictEqual(schema.properties.categories.type, 'array');
1194
+ assert.strictEqual(schema.properties.categories.items.type, 'string');
1195
+ assert.strictEqual(schema.properties.inStock.type, 'boolean');
1196
+ const requiredFields = schema.required || [];
1197
+ assert.ok(!requiredFields.includes('quantity'));
1198
+ assert.ok(!requiredFields.includes('images'));
1199
+ });
1200
+ node_test.test('should transform DecoratedTask with enum and nested validation', () => {
1201
+ const result = transform(DecoratedTask);
1202
+ const schema = result.schema;
1203
+ assert.strictEqual(schema.type, 'object');
1204
+ assert.ok(schema.properties);
1205
+ // Check string length constraints
1206
+ assert.strictEqual(schema.properties.title.minLength, 5);
1207
+ assert.strictEqual(schema.properties.title.maxLength, 100);
1208
+ assert.strictEqual(schema.properties.description.minLength, 10);
1209
+ assert.strictEqual(schema.properties.description.maxLength, 1000);
1210
+ assert.ok(schema.properties.priority);
1211
+ assert.strictEqual(schema.properties.completed.type, 'boolean');
1212
+ assert.strictEqual(schema.properties.assignedTo?.type, 'object');
1213
+ assert.strictEqual(schema.properties.dueDate.type, 'string');
1214
+ assert.strictEqual(schema.properties.dueDate.format, 'date-time');
1215
+ assert.strictEqual(schema.properties.createdAt.type, 'string');
1216
+ assert.strictEqual(schema.properties.createdAt.format, 'date-time');
1217
+ const requiredFields = schema.required || [];
1218
+ assert.ok(!requiredFields.includes('assignedTo'));
1219
+ assert.ok(!requiredFields.includes('tags'));
1220
+ assert.ok(!requiredFields.includes('completedAt'));
1221
+ });
1222
+ /* Las pruebas de enums se omiten ya que el decorador @IsEnum no está implementado aún */
1223
+ });
1224
+
1225
+ /**
1226
+ * Nested TypeScript classes to test object relationships
1227
+ */
1228
+ class Address {
1229
+ street;
1230
+ city;
1231
+ state;
1232
+ zipCode;
1233
+ country;
1234
+ }
1235
+ class Role {
1236
+ id;
1237
+ name;
1238
+ permissions;
1239
+ level;
1240
+ }
1241
+ class Company {
1242
+ name;
1243
+ industry;
1244
+ foundedYear;
1245
+ employees;
1246
+ }
1247
+ class NestedUser {
1248
+ id;
1249
+ name;
1250
+ email;
1251
+ address;
1252
+ roles;
1253
+ company;
1254
+ alternativeAddresses;
1255
+ emergencyContact;
1256
+ }
1257
+ /**
1258
+ * Deep nesting example
1259
+ */
1260
+ class Department {
1261
+ id;
1262
+ name;
1263
+ budget;
1590
1264
  }
1591
- console.log('\nTesting nested class WITHOUT decorators:');
1592
- try {
1593
- const profileResult = transform(UserProfile);
1594
- console.log('✅ Success! Generated schema for nested class:');
1595
- console.log(JSON.stringify(profileResult, null, 2));
1265
+ class Team {
1266
+ id;
1267
+ name;
1268
+ department;
1269
+ members;
1270
+ }
1271
+ class TeamMember {
1272
+ id;
1273
+ name;
1274
+ email;
1275
+ role;
1276
+ startDate;
1596
1277
  }
1597
- catch (error) {
1598
- console.error('❌ Error:', error instanceof Error ? error.message : String(error));
1278
+ class Organization {
1279
+ id;
1280
+ name;
1281
+ teams;
1282
+ headquarters;
1283
+ subsidiaries;
1599
1284
  }
1600
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLmpzIiwic291cmNlcyI6WyIuLi9zcmMvdHJhbnNmb3JtZXIuZml4dHVyZXMudHMiLCIuLi9zcmMvdHJhbnNmb3JtZXIudHMiLCIuLi9zcmMvcnVuLnRzIl0sInNvdXJjZXNDb250ZW50IjpbbnVsbCxudWxsLG51bGxdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVdBLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsZUFBZSxDQUFDO0FBRTNFLE1BQU0sWUFBWSxHQUFHO0lBQ25CLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRTtBQUMzQyxJQUFBLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFO0lBQzVELE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRTtJQUM5QyxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUU7QUFDM0MsSUFBQSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRTtJQUM3RCxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUU7SUFDckMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO0lBQzNDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtBQUN4QyxJQUFBLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO0lBQzVELFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRTtBQUNqRCxJQUFBLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO0FBQzdELElBQUEsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7QUFDckUsSUFBQSxVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtBQUNyRSxJQUFBLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO0NBQzFEO0FBRUQsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7SUFDMUMsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO0lBQ2hELFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtBQUNoRCxJQUFBLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFO0FBQzFELElBQUEsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7QUFDaEUsSUFBQSxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtJQUNoRSxVQUFVLEVBQUUsRUFBRSxJQUFJLEVB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
1285
+
1286
+ /**
1287
+ * Test cases for nested TypeScript classes (complex object relationships)
1288
+ */
1289
+ node_test.describe('Nested TypeScript Classes', () => {
1290
+ node_test.test('should transform Address class correctly', () => {
1291
+ const result = transform(Address);
1292
+ const schema = result.schema;
1293
+ assert.strictEqual(schema.type, 'object');
1294
+ assert.ok(schema.properties);
1295
+ const expectedProperties = ['street', 'city', 'state', 'zipCode', 'country'];
1296
+ expectedProperties.forEach(prop => {
1297
+ assert.ok(schema.properties[prop]);
1298
+ assert.strictEqual(schema.properties[prop].type, 'string');
1299
+ });
1300
+ assert.deepStrictEqual(schema.required?.sort(), expectedProperties.sort());
1301
+ });
1302
+ node_test.test('should transform Role class correctly', () => {
1303
+ const result = transform(Role);
1304
+ const schema = result.schema;
1305
+ assert.strictEqual(schema.type, 'object');
1306
+ assert.ok(schema.properties);
1307
+ assert.strictEqual(schema.properties.id.type, 'number');
1308
+ assert.strictEqual(schema.properties.name.type, 'string');
1309
+ assert.strictEqual(schema.properties.permissions.type, 'array');
1310
+ assert.strictEqual(schema.properties.permissions.items.type, 'string');
1311
+ assert.strictEqual(schema.properties.level.type, 'number');
1312
+ });
1313
+ node_test.test('should transform Company class correctly', () => {
1314
+ const result = transform(Company);
1315
+ const schema = result.schema;
1316
+ assert.strictEqual(schema.type, 'object');
1317
+ assert.ok(schema.properties);
1318
+ assert.strictEqual(schema.properties.name.type, 'string');
1319
+ assert.strictEqual(schema.properties.industry.type, 'string');
1320
+ assert.strictEqual(schema.properties.foundedYear.type, 'number');
1321
+ assert.strictEqual(schema.properties.employees.type, 'number');
1322
+ });
1323
+ node_test.test('should transform NestedUser class correctly', () => {
1324
+ const result = transform(NestedUser);
1325
+ const schema = result.schema;
1326
+ assert.strictEqual(schema.type, 'object');
1327
+ assert.ok(schema.properties);
1328
+ // Check nested object property
1329
+ assert.strictEqual(schema.properties.address.type, 'object');
1330
+ assert.ok(schema.properties.address.properties);
1331
+ // Check array of objects
1332
+ assert.strictEqual(schema.properties.roles.type, 'array');
1333
+ assert.strictEqual(schema.properties.roles.items.type, 'object');
1334
+ // Check company nested object
1335
+ assert.strictEqual(schema.properties.company.type, 'object');
1336
+ assert.ok(schema.properties.company.properties);
1337
+ // Check array of nested objects
1338
+ assert.strictEqual(schema.properties.alternativeAddresses.type, 'array');
1339
+ assert.strictEqual(schema.properties.alternativeAddresses.items.type, 'object');
1340
+ // Check optional nested object
1341
+ const requiredFields = schema.required || [];
1342
+ assert.ok(!requiredFields.includes('emergencyContact'));
1343
+ });
1344
+ node_test.test('should transform Organization class with deep nesting correctly', () => {
1345
+ const result = transform(Organization);
1346
+ const schema = result.schema;
1347
+ assert.strictEqual(schema.type, 'object');
1348
+ assert.ok(schema.properties);
1349
+ // Check teams array with nested objects
1350
+ assert.strictEqual(schema.properties.teams.type, 'array');
1351
+ assert.strictEqual(schema.properties.teams.items.type, 'object');
1352
+ // Check headquarters nested object
1353
+ assert.strictEqual(schema.properties.headquarters.type, 'object');
1354
+ // Check subsidiaries array with inline objects
1355
+ assert.strictEqual(schema.properties.subsidiaries.type, 'array');
1356
+ assert.strictEqual(schema.properties.subsidiaries.items.type, 'object');
1357
+ });
1358
+ node_test.test('should transform Team class with multiple nested levels', () => {
1359
+ const result = transform(Team);
1360
+ const schema = result.schema;
1361
+ assert.strictEqual(schema.type, 'object');
1362
+ assert.ok(schema.properties);
1363
+ // Check nested department
1364
+ assert.strictEqual(schema.properties.department.type, 'object');
1365
+ // Check array of team members
1366
+ assert.strictEqual(schema.properties.members.type, 'array');
1367
+ assert.strictEqual(schema.properties.members.items.type, 'object');
1368
+ });
1369
+ node_test.test('should transform TeamMember class correctly', () => {
1370
+ const result = transform(TeamMember);
1371
+ const schema = result.schema;
1372
+ assert.strictEqual(schema.type, 'object');
1373
+ assert.ok(schema.properties);
1374
+ // Check Date type transformation
1375
+ assert.strictEqual(schema.properties.startDate.type, 'string');
1376
+ assert.strictEqual(schema.properties.startDate.format, 'date-time');
1377
+ });
1378
+ node_test.test('should transform Department class correctly', () => {
1379
+ const result = transform(Department);
1380
+ const schema = result.schema;
1381
+ assert.strictEqual(schema.type, 'object');
1382
+ assert.ok(schema.properties);
1383
+ assert.strictEqual(schema.properties.id.type, 'number');
1384
+ assert.strictEqual(schema.properties.name.type, 'string');
1385
+ assert.strictEqual(schema.properties.budget.type, 'number');
1386
+ });
1387
+ });
1388
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLmpzIiwic291cmNlcyI6WyIuLi9zcmMvdHJhbnNmb3JtZXIuZml4dHVyZXMudHMiLCIuLi9zcmMvdHJhbnNmb3JtZXIudHMiLCIuLi9zcmMvX190ZXN0X18vZW50aXRpZXMvcHVyZS1jbGFzc2VzLnRzIiwiLi4vc3JjL19fdGVzdF9fL2VudGl0aWVzL2FkZGl0aW9uYWwtdGVzdC1jbGFzc2VzLnRzIiwiLi4vc3JjL19fdGVzdF9fL3Rlc3RDYXNlcy9wdXJlLWNsYXNzZXMudGVzdC50cyIsIi4uL25vZGVfbW9kdWxlcy8ucG5wbS9Acm9sbHVwK3BsdWdpbi10eXBlc2NyaXB0QDEyLjEuNF9yb2xsdXBANC40Ni4yX3RzbGliQDIuOC4xX3R5cGVzY3JpcHRANS4wLjIvbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIi4uL3NyYy9fX3Rlc3RfXy9lbnRpdGllcy9kZWNvcmF0ZWQtY2xhc3Nlcy50cyIsIi4uL3NyYy9fX3Rlc3RfXy90ZXN0Q2FzZXMvZGVjb3JhdGVkLWNsYXNzZXMudGVzdC50cyIsIi4uL3NyYy9fX3Rlc3RfXy9lbnRpdGllcy9uZXN0ZWQtY2xhc3Nlcy50cyIsIi4uL3NyYy9fX3Rlc3RfXy90ZXN0Q2FzZXMvbmVzdGVkLWNsYXNzZXMudGVzdC50cyJdLCJzb3VyY2VzQ29udGVudCI6W251bGwsbnVsbCxudWxsLG51bGwsbnVsbCwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCwgSXRlcmF0b3IgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGcgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgSXRlcmF0b3IgPT09IFwiZnVuY3Rpb25cIiA/IEl0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpO1xyXG4gICAgcmV0dXJuIGcubmV4dCA9IHZlcmIoMCksIGdbXCJ0aHJvd1wiXSA9IHZlcmIoMSksIGdbXCJyZXR1cm5cIl0gPSB2ZXJiKDIpLCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBBc3luY0l0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBBc3luY0l0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpLCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIsIGF3YWl0UmV0dXJuKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gYXdhaXRSZXR1cm4oZikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGYsIHJlamVjdCk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpZiAoZ1tuXSkgeyBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyBpZiAoZikgaVtuXSA9IGYoaVtuXSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbnZhciBvd25LZXlzID0gZnVuY3Rpb24obykge1xyXG4gICAgb3duS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIHx8IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgdmFyIGFyID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgayBpbiBvKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIGspKSBhclthci5sZW5ndGhdID0gaztcclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIG93bktleXMobyk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayA9IG93bktleXMobW9kKSwgaSA9IDA7IGkgPCBrLmxlbmd0aDsgaSsrKSBpZiAoa1tpXSAhPT0gXCJkZWZhdWx0XCIpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwga1tpXSk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xyXG4gICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB2b2lkIDApIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkLlwiKTtcclxuICAgICAgICB2YXIgZGlzcG9zZSwgaW5uZXI7XHJcbiAgICAgICAgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmFzeW5jRGlzcG9zZV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgaWYgKCFTeW1ib2wuZGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5kaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcclxuICAgICAgICAgICAgaWYgKGFzeW5jKSBpbm5lciA9IGRpc3Bvc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG5vdCBkaXNwb3NhYmxlLlwiKTtcclxuICAgICAgICBpZiAoaW5uZXIpIGRpc3Bvc2UgPSBmdW5jdGlvbigpIHsgdHJ5IHsgaW5uZXIuY2FsbCh0aGlzKTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7IH0gfTtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IHZhbHVlOiB2YWx1ZSwgZGlzcG9zZTogZGlzcG9zZSwgYXN5bmM6IGFzeW5jIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoYXN5bmMpIHtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IGFzeW5jOiB0cnVlIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG5cclxufVxyXG5cclxudmFyIF9TdXBwcmVzc2VkRXJyb3IgPSB0eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcclxuICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XHJcbiAgICBmdW5jdGlvbiBmYWlsKGUpIHtcclxuICAgICAgICBlbnYuZXJyb3IgPSBlbnYuaGFzRXJyb3IgPyBuZXcgX1N1cHByZXNzZWRFcnJvcihlLCBlbnYuZXJyb3IsIFwiQW4gZXJyb3Igd2FzIHN1cHByZXNzZWQgZHVyaW5nIGRpc3Bvc2FsLlwiKSA6IGU7XHJcbiAgICAgICAgZW52Lmhhc0Vycm9yID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHZhciByLCBzID0gMDtcclxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XHJcbiAgICAgICAgd2hpbGUgKHIgPSBlbnYuc3RhY2sucG9wKCkpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmICghci5hc3luYyAmJiBzID09PSAxKSByZXR1cm4gcyA9IDAsIGVudi5zdGFjay5wdXNoKHIpLCBQcm9taXNlLnJlc29sdmUoKS50aGVuKG5leHQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHIuZGlzcG9zZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByLmRpc3Bvc2UuY2FsbChyLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoci5hc3luYykgcmV0dXJuIHMgfD0gMiwgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBzIHw9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGZhaWwoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHMgPT09IDEpIHJldHVybiBlbnYuaGFzRXJyb3IgPyBQcm9taXNlLnJlamVjdChlbnYuZXJyb3IpIDogUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgaWYgKGVudi5oYXNFcnJvcikgdGhyb3cgZW52LmVycm9yO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5leHQoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uKHBhdGgsIHByZXNlcnZlSnN4KSB7XHJcbiAgICBpZiAodHlwZW9mIHBhdGggPT09IFwic3RyaW5nXCIgJiYgL15cXC5cXC4/XFwvLy50ZXN0KHBhdGgpKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwuKHRzeCkkfCgoPzpcXC5kKT8pKCg/OlxcLlteLi9dKz8pPylcXC4oW2NtXT8pdHMkL2ksIGZ1bmN0aW9uIChtLCB0c3gsIGQsIGV4dCwgY20pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRzeCA/IHByZXNlcnZlSnN4ID8gXCIuanN4XCIgOiBcIi5qc1wiIDogZCAmJiAoIWV4dCB8fCAhY20pID8gbSA6IChkICsgZXh0ICsgXCIuXCIgKyBjbS50b0xvd2VyQ2FzZSgpICsgXCJqc1wiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXRoO1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICBfX2V4dGVuZHM6IF9fZXh0ZW5kcyxcclxuICAgIF9fYXNzaWduOiBfX2Fzc2lnbixcclxuICAgIF9fcmVzdDogX19yZXN0LFxyXG4gICAgX19kZWNvcmF0ZTogX19kZWNvcmF0ZSxcclxuICAgIF9fcGFyYW06IF9fcGFyYW0sXHJcbiAgICBfX2VzRGVjb3JhdGU6IF9fZXNEZWNvcmF0ZSxcclxuICAgIF9fcnVuSW5pdGlhbGl6ZXJzOiBfX3J1bkluaXRpYWxpemVycyxcclxuICAgIF9fcHJvcEtleTogX19wcm9wS2V5LFxyXG4gICAgX19zZXRGdW5jdGlvbk5hbWU6IF9fc2V0RnVuY3Rpb25OYW1lLFxyXG4gICAgX19tZXRhZGF0YTogX19tZXRhZGF0YSxcclxuICAgIF9fYXdhaXRlcjogX19hd2FpdGVyLFxyXG4gICAgX19nZW5lcmF0b3I6IF9fZ2VuZXJhdG9yLFxyXG4gICAgX19jcmVhdGVCaW5kaW5nOiBfX2NyZWF0ZUJpbmRpbmcsXHJcbiAgICBfX2V4cG9ydFN0YXI6IF9fZXhwb3J0U3RhcixcclxuICAgIF9fdmFsdWVzOiBfX3ZhbHVlcyxcclxuICAgIF9fcmVhZDogX19yZWFkLFxyXG4gICAgX19zcHJlYWQ6IF9fc3ByZWFkLFxyXG4gICAgX19zcHJlYWRBcnJheXM6IF9fc3ByZWFkQXJyYXlzLFxyXG4gICAgX19zcHJlYWRBcnJheTogX19zcHJlYWRBcnJheSxcclxuICAgIF9fYXdhaXQ6IF9fYXdhaXQsXHJcbiAgICBfX2FzeW5jR2VuZXJhdG9yOiBfX2FzeW5jR2VuZXJhdG9yLFxyXG4gICAgX19hc3luY0RlbGVnYXRvcjogX19hc3luY0RlbGVnYXRvcixcclxuICAgIF9fYXN5bmNWYWx1ZXM6IF9fYXN5bmNWYWx1ZXMsXHJcbiAgICBfX21ha2VUZW1wbGF0ZU9iamVjdDogX19tYWtlVGVtcGxhdGVPYmplY3QsXHJcbiAgICBfX2ltcG9ydFN0YXI6IF9faW1wb3J0U3RhcixcclxuICAgIF9faW1wb3J0RGVmYXVsdDogX19pbXBvcnREZWZhdWx0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldDogX19jbGFzc1ByaXZhdGVGaWVsZEdldCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkSW46IF9fY2xhc3NQcml2YXRlRmllbGRJbixcclxuICAgIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlOiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZSxcclxuICAgIF9fZGlzcG9zZVJlc291cmNlczogX19kaXNwb3NlUmVzb3VyY2VzLFxyXG4gICAgX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb246IF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uLFxyXG59O1xyXG4iLG51bGwsbnVsbCxudWxsLG51bGxdLCJuYW1lcyI6WyJkZXNjcmliZSIsInRlc3QiLCJJc1N0cmluZyIsIkxlbmd0aCIsIk1hdGNoZXMiLCJJc051bWJlciIsIklzUG9zaXRpdmUiLCJJc0VtYWlsIiwiTWluIiwiTWF4IiwiSXNFbnVtIiwiSXNCb29sZWFuIiwiSXNPcHRpb25hbCIsIklzQXJyYXkiLCJWYWxpZGF0ZU5lc3RlZCIsIklzRGF0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFXQSxNQUFNLHNCQUFzQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLGVBQWUsQ0FBQztBQUUzRSxNQUFNLFlBQVksR0FBRztJQUNuQixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUU7SUFDM0MsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQXNCLENBQUU7SUFDckMsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQTBCLENBQUU7QUFDN0MsSUFBQSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtJQUM3RCxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUU7SUFDOUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO0FBQzNDLElBQUEsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUU7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QUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFFbkQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7QUFDdkQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7UUFFeEQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztBQUVuQyxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQztBQUN4RCxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFFL0QsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFFNUQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDOUQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUM7QUFFbkUsUUFBQSxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsUUFBUSxJQUFJLEVBQUU7UUFDNUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDL0MsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDbEQsSUFBQSxDQUFDLENBQUM7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LEVBQUUsRUFBRSxDQUFDO0FBQy9ELFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDO1FBRWpFLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7QUFFckMsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUM7QUFFL0QsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUM7QUFFaEUsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDNUQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUM7QUFFakUsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDOUQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUM7QUFFbkUsUUFBQSxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsUUFBUSxJQUFJLEVBQUU7UUFDNUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDakQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDcEQsSUFBQSxDQUFDLENBQUM7O0FBR0osQ0FBQyxDQUFDOztBQ3JJRjs7QUFFRztNQUVVLE9BQU8sQ0FBQTtBQUNsQixJQUFBLE1BQU07QUFDTixJQUFBLElBQUk7QUFDSixJQUFBLEtBQUs7QUFDTCxJQUFBLE9BQU87QUFDUCxJQUFBLE9BQU87QUFDUjtNQUVZLElBQUksQ0FBQTtBQUNmLElBQUEsRUFBRTtBQUNGLElBQUEsSUFBSTtBQUNKLElBQUEsV0FBVztBQUNYLElBQUEsS0FBSztBQUNOO01BRVksT0FBTyxDQUFBO0FBQ2xCLElBQUEsSUFBSTtBQUNKLElBQUEsUUFBUTtBQUNSLElBQUEsV0FBVztBQUNYLElBQUEsU0FBUztBQUNWO01BUVksVUFBVSxDQUFBO0FBQ3JCLElBQUEsRUFBRTtBQUNGLElBQUEsSUFBSTtBQUNKLElBQUEsS0FBSztBQUNMLElBQUEsT0FBTztBQUNQLElBQUEsS0FBSztBQUNMLElBQUEsT0FBTztBQUNQLElBQUEsb0JBQW9CO0FBQ3BCLElBQUEsZ0JBQWdCO0FBQ2pCO0FBRUQ7O0FBRUc7TUFDVSxVQUFVLENBQUE7QUFDckIsSUFBQSxFQUFFO0FBQ0YsSUFBQSxJQUFJO0FBQ0osSUFBQSxNQUFNO0FBQ1A7TUFFWSxJQUFJLENBQUE7QUFDZixJQUFBLEVBQUU7QUFDRixJQUFBLElBQUk7QUFDSixJQUFBLFVBQVU7QUFDVixJQUFBLE9BQU87QUFDUjtNQUVZLFVBQVUsQ0FBQTtBQUNyQixJQUFBLEVBQUU7QUFDRixJQUFBLElBQUk7QUFDSixJQUFBLEtBQUs7QUFDTCxJQUFBLElBQUk7QUFDSixJQUFBLFNBQVM7QUFDVjtNQVFZLFlBQVksQ0FBQTtBQUN2QixJQUFBLEVBQUU7QUFDRixJQUFBLElBQUk7QUFDSixJQUFBLEtBQUs7QUFDTCxJQUFBLFlBQVk7QUFDWixJQUFBLFlBQVk7QUFDYjs7QUMvRUQ7O0FBRUc7QUFlSEQsa0JBQVEsQ0FBQywyQkFBMkIsRUFBRSxNQUFLO0FBQ3pDLElBQUFDLGNBQUksQ0FBQywwQ0FBMEMsRUFBRSxNQUFLO0FBQ3BELFFBQUEsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQztBQUNqQyxRQUFBLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNO1FBRTVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7QUFFNUIsUUFBQSxNQUFNLGtCQUFrQixHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQztBQUM1RSxRQUFBLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUc7WUFDaEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xDLFlBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDNUQsUUFBQSxDQUFDLENBQUM7QUFFRixRQUFBLE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUM1RSxJQUFBLENBQUMsQ0FBQztBQUVGLElBQUFBLGNBQUksQ0FBQyx1Q0FBdUMsRUFBRSxNQUFLO0FBQ2pELFFBQUEsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztBQUM5QixRQUFBLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNO1FBRTVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7QUFFNUIsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDdkQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7QUFDL0QsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDO0FBQ3RFLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDO0FBQzVELElBQUEsQ0FBQyxDQUFDO0FBRUYsSUFBQUEsY0FBSSxDQUFDLDBDQUEwQyxFQUFFLE1BQUs7QUFDcEQsUUFBQSxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDO0FBQ2pDLFFBQUEsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU07UUFFNUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUN6QyxRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztBQUU1QixRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUN6RCxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUM3RCxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUNoRSxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUNoRSxJQUFBLENBQUMsQ0FBQztBQUVGLElBQUFBLGNBQUksQ0FBQyw2Q0FBNkMsRUFBRSxNQUFLO0FBQ3ZELFFBQUEsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQztBQUNwQyxRQUFBLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNO1FBRTVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7O0FBRzVCLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDO1FBQzVELE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDOztBQUcvQyxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQztBQUN6RCxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7O0FBR2hFLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDO1FBQzVELE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDOztBQUcvQyxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDO0FBQ3hFLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FDaEIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUNqRCxRQUFRLENBQ1Q7O0FBR0QsUUFBQSxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsUUFBUSxJQUFJLEVBQUU7UUFDNUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUN6RCxJQUFBLENBQUMsQ0FBQztBQUVGLElBQUFBLGNBQUksQ0FBQyxpRUFBaUUsRUFBRSxNQUFLO0FBQzNFLFFBQUEsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLFlBQVksQ0FBQztBQUN0QyxRQUFBLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNO1FBRTVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7O0FBRzVCLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDO0FBQ3pELFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQzs7QUFHaEUsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7O0FBR2pFLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDO0FBQ2hFLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUN6RSxJQUFBLENBQUMsQ0FBQztBQUVGLElBQUFBLGNBQUksQ0FBQyx5REFBeUQsRUFBRSxNQUFLO0FBQ25FLFFBQUEsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztBQUM5QixRQUFBLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNO1FBRTVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7O0FBRzVCLFFBQUEsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDOztBQUcvRCxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQztBQUMzRCxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDcEUsSUFBQSxDQUFDLENBQUM7QUFFRixJQUFBQSxjQUFJLENBQUMsNkNBQTZDLEVBQUUsTUFBSztBQUN2RCxRQUFBLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUM7QUFDcEMsUUFBQSxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTTtRQUU1QixNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDO0FBQ3pDLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDOztBQUc1QixRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQztBQUM5RCxRQUFBLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQztBQUNyRSxJQUFBLENBQUMsQ0FBQztBQUVGLElBQUFBLGNBQUksQ0FBQyw2Q0FBNkMsRUFBRSxNQUFLO0FBQ3ZELFFBQUEsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQztBQUNwQyxRQUFBLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNO1FBRTVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7QUFFNUIsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDdkQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDekQsUUFBQSxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDN0QsSUFBQSxDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7OyIsInhfZ29vZ2xlX2lnbm9yZUxpc3QiOls1XX0=