jsii-diff 1.35.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.
@@ -0,0 +1,508 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ComparableEnumType = exports.ComparableStructType = exports.ComparableInterfaceType = exports.ComparableClassType = exports.ComparableReferenceType = exports.ComparableType = exports.AssemblyComparison = void 0;
4
+ const spec_1 = require("@jsii/spec");
5
+ const reflect = require("jsii-reflect");
6
+ const log4js = require("log4js");
7
+ const stability_1 = require("./stability");
8
+ const type_analysis_1 = require("./type-analysis");
9
+ const types_1 = require("./types");
10
+ const util_1 = require("./util");
11
+ const validations_1 = require("./validations");
12
+ const LOG = log4js.getLogger('jsii-diff');
13
+ /**
14
+ * Root object for comparing two assemblies
15
+ *
16
+ * Tracks mismatches and used as a lookup table to convert FQNs -> ComparableType objects
17
+ */
18
+ class AssemblyComparison {
19
+ constructor(options) {
20
+ this.options = options;
21
+ this.types = new Map();
22
+ this.mismatches = new types_1.Mismatches({
23
+ defaultStability: options.defaultExperimental
24
+ ? spec_1.Stability.Experimental
25
+ : spec_1.Stability.Stable,
26
+ });
27
+ }
28
+ /**
29
+ * Load the types from two assemblies to compare
30
+ *
31
+ * Adds appropriate ComparableType<> instances.
32
+ */
33
+ load(original, updated) {
34
+ /* eslint-disable prettier/prettier */
35
+ for (const [origClass, updatedClass] of this.typePairs(original.classes, updated)) {
36
+ this.types.set(origClass.fqn, new ComparableClassType(this, origClass, updatedClass));
37
+ }
38
+ for (const [origIface, updatedIface] of this.typePairs(original.interfaces, updated)) {
39
+ if (origIface.datatype !== updatedIface.datatype) {
40
+ this.mismatches.report({
41
+ ruleKey: 'iface-type',
42
+ violator: origIface,
43
+ message: `used to be a ${types_1.describeInterfaceType(origIface.datatype)}, is now a ${types_1.describeInterfaceType(updatedIface.datatype)}.`,
44
+ });
45
+ continue;
46
+ }
47
+ this.types.set(origIface.fqn, origIface.datatype
48
+ ? new ComparableStructType(this, origIface, updatedIface)
49
+ : new ComparableInterfaceType(this, origIface, updatedIface));
50
+ }
51
+ for (const [origEnum, updatedEnum] of this.typePairs(original.enums, updated)) {
52
+ this.types.set(origEnum.fqn, new ComparableEnumType(this, origEnum, updatedEnum));
53
+ }
54
+ /* eslint-enable prettier/prettier */
55
+ }
56
+ /**
57
+ * Perform the comparison for all loaded types
58
+ */
59
+ compare() {
60
+ this.comparableTypes.forEach((t) => t.markTypeRoles());
61
+ this.comparableTypes.forEach((t) => t.compare());
62
+ }
63
+ /**
64
+ * Based on a JSII TypeReference, return all reachable ComparableType<> objects.
65
+ */
66
+ typesIn(ref) {
67
+ const ret = new Array();
68
+ for (const fqn of fqnsFrom(ref)) {
69
+ const t = this.types.get(fqn);
70
+ if (t) {
71
+ ret.push(t);
72
+ }
73
+ }
74
+ return ret;
75
+ }
76
+ /**
77
+ * All ComparableType<>s
78
+ */
79
+ get comparableTypes() {
80
+ return Array.from(this.types.values());
81
+ }
82
+ /**
83
+ * Find the matching type in the updated assembly based on all types in the original assembly
84
+ */
85
+ *typePairs(xs, updatedAssembly) {
86
+ for (const origType of xs) {
87
+ LOG.trace(origType.fqn);
88
+ const updatedType = updatedAssembly.tryFindType(origType.fqn);
89
+ if (!updatedType) {
90
+ this.mismatches.report({
91
+ ruleKey: 'removed',
92
+ violator: origType,
93
+ message: 'has been removed',
94
+ });
95
+ continue;
96
+ }
97
+ if (types_1.describeType(origType) !== types_1.describeType(updatedType)) {
98
+ this.mismatches.report({
99
+ ruleKey: 'struct-change',
100
+ violator: origType,
101
+ message: `has been turned into a ${types_1.describeType(updatedType)}`,
102
+ });
103
+ continue;
104
+ }
105
+ yield [origType, updatedType]; // Trust me I know what I'm doing
106
+ }
107
+ }
108
+ }
109
+ exports.AssemblyComparison = AssemblyComparison;
110
+ /**
111
+ * Base class for comparable types
112
+ *
113
+ * Manages notions of crawling types for other reference types, and whether
114
+ * they occur in an input/output role, and marking as such on the comparison
115
+ * object.
116
+ */
117
+ class ComparableType {
118
+ constructor(assemblyComparison, oldType, newType) {
119
+ this.assemblyComparison = assemblyComparison;
120
+ this.oldType = oldType;
121
+ this.newType = newType;
122
+ this._inputTypeReasons = new Array();
123
+ this._outputTypeReasons = new Array();
124
+ }
125
+ /**
126
+ * Does this type occur in an input role?
127
+ */
128
+ get inputType() {
129
+ return this._inputTypeReasons.length > 0;
130
+ }
131
+ /**
132
+ * Does this type occur in an output role?
133
+ */
134
+ get outputType() {
135
+ return this._outputTypeReasons.length > 0;
136
+ }
137
+ /**
138
+ * Mark this type as occuring in an input rule.
139
+ *
140
+ * All types reachable from this type will be marked as input types as well.
141
+ */
142
+ markAsInputType(...reasonFragments) {
143
+ ComparableType.recursionBreaker.do(this, () => {
144
+ this._inputTypeReasons.push(reasonFragments.join(', '));
145
+ this.forEachRoleSharingType((type, reason) => {
146
+ type.markAsInputType(reason, ...reasonFragments);
147
+ });
148
+ });
149
+ }
150
+ /**
151
+ * Mark this type as occuring in an input rule.
152
+ *
153
+ * All types reachable from this type will be marked as input types as well.
154
+ */
155
+ markAsOutputType(...reasonFragments) {
156
+ ComparableType.recursionBreaker.do(this, () => {
157
+ this._outputTypeReasons.push(reasonFragments.join(', '));
158
+ this.forEachRoleSharingType((type, reason) => {
159
+ type.markAsOutputType(reason, ...reasonFragments);
160
+ });
161
+ });
162
+ }
163
+ /**
164
+ * Describe why this type is an input type (if it is)
165
+ */
166
+ get inputTypeReason() {
167
+ return describeReasons(this._inputTypeReasons);
168
+ }
169
+ /**
170
+ * Describe why this type is an output type (if it is)
171
+ */
172
+ get outputTypeReason() {
173
+ return describeReasons(this._outputTypeReasons);
174
+ }
175
+ /**
176
+ * Should be overriden in subclasses to mark reachable types as input/output types
177
+ *
178
+ * Should only be implemented by subclasses that contain callables.
179
+ */
180
+ markTypeRoles() {
181
+ // Empty on purpose
182
+ }
183
+ /**
184
+ * Alias for the root object Mismaches object
185
+ */
186
+ get mismatches() {
187
+ return this.assemblyComparison.mismatches;
188
+ }
189
+ /**
190
+ * Should be overriden in subclasses to execute the callback on reachable types
191
+ *
192
+ * Should be overriden only for product types (structs).
193
+ */
194
+ forEachRoleSharingType(cb) {
195
+ Array.isArray(cb);
196
+ }
197
+ }
198
+ exports.ComparableType = ComparableType;
199
+ ComparableType.recursionBreaker = new util_1.RecursionBreaker();
200
+ /**
201
+ * Base class for reference types
202
+ *
203
+ * Contains shared code that applies to both class and interface types.
204
+ */
205
+ class ComparableReferenceType extends ComparableType {
206
+ /**
207
+ * Compare members of the reference types
208
+ */
209
+ compare() {
210
+ stability_1.validateStabilities(this.oldType, this.newType, this.mismatches);
211
+ validations_1.validateBaseTypeAssignability(this.oldType, this.newType, this.mismatches);
212
+ validations_1.validateSubclassableNotRemoved(this.oldType, this.newType, this.mismatches);
213
+ if (this.subclassableType) {
214
+ validations_1.validateNoNewAbstractMembers(this.oldType, this.newType, this.mismatches);
215
+ }
216
+ this.validateMethods();
217
+ this.validateProperties();
218
+ }
219
+ /**
220
+ * Mark type accesses (input/output) of methods and properties
221
+ */
222
+ markTypeRoles() {
223
+ for (const method of this.oldType.ownMethods) {
224
+ determineTypeRolesFromMethod(this.assemblyComparison, method);
225
+ }
226
+ for (const property of this.oldType.ownProperties) {
227
+ determineTypeRolesFromProperty(this.assemblyComparison, property);
228
+ }
229
+ }
230
+ /**
231
+ * Validate type signatures on all methods
232
+ */
233
+ validateMethods() {
234
+ for (const [orig, updated] of validations_1.memberPairs(this.oldType, this.oldType.allMethods, this.newType, this.mismatches)) {
235
+ if (reflect.isMethod(updated)) {
236
+ this.validateMethod(orig, updated);
237
+ }
238
+ }
239
+ }
240
+ /**
241
+ * Validate type signature changes on the given method
242
+ */
243
+ validateMethod(original, updated) {
244
+ validations_1.validateStaticSame(original, updated, this.mismatches);
245
+ validations_1.validateAsyncSame(original, updated, this.mismatches);
246
+ if (this.subclassableType) {
247
+ validations_1.validateReturnTypeSame(original, updated, this.mismatches.withMotivation('type is @subclassable'));
248
+ }
249
+ else {
250
+ validations_1.validateReturnTypeNotWeakened(original, updated, this.mismatches);
251
+ }
252
+ this.validateCallable(original, updated);
253
+ }
254
+ /**
255
+ * Validate type signature changes on the given callable (method or initializer)
256
+ */
257
+ validateCallable(original, updated) {
258
+ stability_1.validateStabilities(original, updated, this.mismatches);
259
+ validations_1.validateNotMadeNonVariadic(original, updated, this.mismatches);
260
+ // Check that every original parameter can still be mapped to a parameter in the updated method
261
+ validations_1.validateExistingParams(original, updated, this.mismatches, (oldParam, newParam) => {
262
+ if (this.subclassableType) {
263
+ validations_1.validateParameterTypeSame(original, oldParam, newParam, this.mismatches.withMotivation('type is @subclassable'));
264
+ }
265
+ else {
266
+ validations_1.validateParameterTypeWeakened(original, oldParam, newParam, this.mismatches);
267
+ }
268
+ });
269
+ validations_1.validateNoNewRequiredParams(original, updated, this.mismatches);
270
+ }
271
+ /**
272
+ * Validate type signature changes on all properties
273
+ */
274
+ validateProperties() {
275
+ for (const [orig, updated] of validations_1.memberPairs(this.oldType, this.oldType.allProperties, this.newType, this.mismatches)) {
276
+ if (reflect.isProperty(updated)) {
277
+ this.validateProperty(orig, updated);
278
+ }
279
+ }
280
+ }
281
+ /**
282
+ * Validate type signature changes on the given property
283
+ */
284
+ validateProperty(original, updated) {
285
+ stability_1.validateStabilities(original, updated, this.mismatches);
286
+ validations_1.validateStaticSame(original, updated, this.mismatches);
287
+ validations_1.validateNotMadeImmutable(original, updated, this.mismatches);
288
+ if (this.subclassableType) {
289
+ // Hello C# my old friend
290
+ validations_1.validatePropertyTypeSame(original, updated, this.mismatches.withMotivation('type is @subclassable'));
291
+ }
292
+ else if (!original.immutable) {
293
+ // If the type can be read, it can't be weakened (can't change Dog to Animal, consumers might be counting on a Dog).
294
+ // If the type can be written, it can't be strengthened (can't change Animal to Dog, consumers might be sending a Cat).
295
+ // => it must remain the same
296
+ validations_1.validatePropertyTypeSame(original, updated, this.mismatches.withMotivation('mutable property cannot change type'));
297
+ }
298
+ else {
299
+ validations_1.validatePropertyTypeNotWeakened(original, updated, this.mismatches);
300
+ }
301
+ }
302
+ /**
303
+ * Whether the current reference type has been marked as subclassable
304
+ */
305
+ get subclassableType() {
306
+ return validations_1.subclassableType(this.oldType);
307
+ }
308
+ }
309
+ exports.ComparableReferenceType = ComparableReferenceType;
310
+ class ComparableClassType extends ComparableReferenceType {
311
+ /**
312
+ * Perform the reference type comparison and include class-specific checks
313
+ */
314
+ compare() {
315
+ super.compare();
316
+ validations_1.validateNotMadeAbstract(this.oldType, this.newType, this.mismatches);
317
+ // JSII assembler has already taken care of inheritance here
318
+ if (this.oldType.initializer && this.newType.initializer) {
319
+ validations_1.validateMethodCompatible(this.oldType.initializer, this.newType.initializer, this.mismatches);
320
+ }
321
+ }
322
+ /**
323
+ * Type role marking -- include the initializer
324
+ */
325
+ markTypeRoles() {
326
+ if (this.oldType.initializer) {
327
+ determineTypeRolesFromMethod(this.assemblyComparison, this.oldType.initializer);
328
+ }
329
+ super.markTypeRoles();
330
+ }
331
+ }
332
+ exports.ComparableClassType = ComparableClassType;
333
+ /**
334
+ * Interface type comparison
335
+ *
336
+ * (Actually just plain reference type comparison)
337
+ */
338
+ class ComparableInterfaceType extends ComparableReferenceType {
339
+ }
340
+ exports.ComparableInterfaceType = ComparableInterfaceType;
341
+ /**
342
+ * Struct type comparison
343
+ *
344
+ * Most notably: does no-strengthening/no-weakening checks based on whether
345
+ * structs appear in input/output positions.
346
+ */
347
+ class ComparableStructType extends ComparableType {
348
+ compare() {
349
+ stability_1.validateStabilities(this.oldType, this.newType, this.mismatches);
350
+ validations_1.validateBaseTypeAssignability(this.oldType, this.newType, this.mismatches);
351
+ this.validateNoPropertiesRemoved();
352
+ if (this.inputType) {
353
+ // If the struct is written, it can't be strengthened (ex: can't change an optional property to required)
354
+ this.validateNotStrengthened(this.mismatches.withMotivation(this.inputTypeReason));
355
+ }
356
+ if (this.outputType) {
357
+ // If the struct is read, it can't be weakened (ex: can't change a required property to optional)
358
+ this.validateNotWeakened(this.mismatches.withMotivation(this.outputTypeReason));
359
+ }
360
+ }
361
+ /**
362
+ * Every type of every property should have the same in/out classification as the outer type
363
+ */
364
+ forEachRoleSharingType(cb) {
365
+ for (const prop of this.oldType.allProperties) {
366
+ for (const t of this.assemblyComparison.typesIn(prop.type)) {
367
+ cb(t, `type of property ${prop.name}`);
368
+ }
369
+ }
370
+ }
371
+ /**
372
+ * Check that all properties are still present
373
+ *
374
+ * This is because for all non-structurally typed languages it is not allowed
375
+ * to specify members which aren't actually present in the type.
376
+ */
377
+ validateNoPropertiesRemoved() {
378
+ // A single run of memberPairs() with nothing else will do this check.
379
+ Array.from(validations_1.memberPairs(this.oldType, this.oldType.allProperties, this.newType, this.mismatches));
380
+ }
381
+ /**
382
+ * Check that the current type is not weakened
383
+ */
384
+ validateNotWeakened(mismatches) {
385
+ const ana = this.isStructuralSuperType(this.oldType, this.newType);
386
+ if (!ana.success) {
387
+ mismatches.report({
388
+ ruleKey: 'weakened',
389
+ violator: this.oldType,
390
+ message: ana.reasons.join(', '),
391
+ });
392
+ }
393
+ }
394
+ /**
395
+ * Check that the current type is not strengthened
396
+ */
397
+ validateNotStrengthened(mismatches) {
398
+ const ana = this.isStructuralSuperType(this.newType, this.oldType);
399
+ if (!ana.success) {
400
+ mismatches.report({
401
+ ruleKey: 'strengthened',
402
+ violator: this.oldType,
403
+ message: ana.reasons.join(', '),
404
+ });
405
+ }
406
+ }
407
+ isStructuralSuperType(a, b) {
408
+ try {
409
+ return type_analysis_1.isStructuralSuperType(a, b, this.newType.system);
410
+ }
411
+ catch (e) {
412
+ // We might get an exception if the type is supposed to come from a different
413
+ // assembly and the lookup fails.
414
+ return { success: false, reasons: [e.message] };
415
+ }
416
+ }
417
+ }
418
+ exports.ComparableStructType = ComparableStructType;
419
+ /**
420
+ * Comparison for enums
421
+ */
422
+ class ComparableEnumType extends ComparableType {
423
+ /**
424
+ * Perform comparisons on enum members
425
+ */
426
+ compare() {
427
+ stability_1.validateStabilities(this.oldType, this.newType, this.mismatches);
428
+ validations_1.validateExistingMembers(this.oldType, this.newType, this.mismatches, (oldMember, newMember) => {
429
+ stability_1.validateStabilities(oldMember, newMember, this.mismatches);
430
+ });
431
+ }
432
+ }
433
+ exports.ComparableEnumType = ComparableEnumType;
434
+ /**
435
+ * Determines input/output roles of types used in this method
436
+ *
437
+ * - Argument types are treated as IN types
438
+ * - Return type is treated as OUT type
439
+ */
440
+ function determineTypeRolesFromMethod(comparison, method) {
441
+ var _a;
442
+ if (reflect.isMethod(method)) {
443
+ for (const t of comparison.typesIn(method.returns.type)) {
444
+ t.markAsOutputType(`returned from ${types_1.apiElementIdentifier(method)}`);
445
+ }
446
+ }
447
+ for (const param of (_a = method.parameters) !== null && _a !== void 0 ? _a : []) {
448
+ for (const t of comparison.typesIn(param.type)) {
449
+ t.markAsInputType(`input to ${types_1.apiElementIdentifier(method)}`);
450
+ }
451
+ }
452
+ }
453
+ /**
454
+ * Determines input/output roles of types used in this property
455
+ *
456
+ * - Property type is treated as OUT type
457
+ * - If mutable, property type is also treated as IN type
458
+ *
459
+ * In effect, a property is treated as the following methods:
460
+ *
461
+ * - property(): T;
462
+ * - setProperty(: T); <- only if mutable
463
+ */
464
+ function determineTypeRolesFromProperty(comparison, property) {
465
+ for (const t of comparison.typesIn(property.type)) {
466
+ t.markAsOutputType(`type of ${types_1.apiElementIdentifier(property)}`);
467
+ }
468
+ if (!property.immutable) {
469
+ for (const t of comparison.typesIn(property.type)) {
470
+ t.markAsInputType(`type of mutable ${types_1.apiElementIdentifier(property)}`);
471
+ }
472
+ }
473
+ }
474
+ /**
475
+ * Return all the FQNs from a type reference
476
+ *
477
+ * In the simple case, a simple FQN, but the type might
478
+ * be a union or complex type as well.
479
+ */
480
+ function fqnsFrom(ref) {
481
+ const ret = new Array();
482
+ recurse(ref);
483
+ return ret;
484
+ function recurse(type) {
485
+ if (type.mapOfType) {
486
+ recurse(type.mapOfType);
487
+ }
488
+ else if (type.arrayOfType) {
489
+ recurse(type.arrayOfType);
490
+ }
491
+ else if (type.unionOfTypes) {
492
+ type.unionOfTypes.forEach(recurse);
493
+ }
494
+ else if (type.fqn) {
495
+ ret.push(type.fqn);
496
+ }
497
+ }
498
+ }
499
+ function describeReasons(reasons) {
500
+ if (reasons.length === 0) {
501
+ return '';
502
+ }
503
+ if (reasons.length === 1) {
504
+ return reasons[0];
505
+ }
506
+ return `${reasons[0]} (...and ${reasons.length - 1} more...)`;
507
+ }
508
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1jb21wYXJpc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidHlwZS1jb21wYXJpc29uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFDQUF1QztBQUN2Qyx3Q0FBd0M7QUFDeEMsaUNBQWlDO0FBRWpDLDJDQUFrRDtBQUNsRCxtREFBa0U7QUFDbEUsbUNBT2lCO0FBQ2pCLGlDQUEwQztBQUMxQywrQ0FxQnVCO0FBRXZCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7QUFFMUM7Ozs7R0FJRztBQUNILE1BQWEsa0JBQWtCO0lBSTdCLFlBQW1DLE9BQTBCO1FBQTFCLFlBQU8sR0FBUCxPQUFPLENBQW1CO1FBRjVDLFVBQUssR0FBRyxJQUFJLEdBQUcsRUFBK0IsQ0FBQztRQUc5RCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksa0JBQVUsQ0FBQztZQUMvQixnQkFBZ0IsRUFBRSxPQUFPLENBQUMsbUJBQW1CO2dCQUMzQyxDQUFDLENBQUMsZ0JBQVMsQ0FBQyxZQUFZO2dCQUN4QixDQUFDLENBQUMsZ0JBQVMsQ0FBQyxNQUFNO1NBQ3JCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksSUFBSSxDQUFDLFFBQTBCLEVBQUUsT0FBeUI7UUFDL0Qsc0NBQXNDO1FBQ3RDLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUU7WUFDakYsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxJQUFJLG1CQUFtQixDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztTQUN2RjtRQUVELEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFD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QUFXLEVBQUU7WUFDM0IsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUMzQjthQUFNLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNwQzthQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNuQixHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNwQjtJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsT0FBaUI7SUFDeEMsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUN4QixPQUFPLEVBQUUsQ0FBQztLQUNYO0lBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUN4QixPQUFPLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNuQjtJQUNELE9BQU8sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLFlBQVksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLFdBQVcsQ0FBQztBQUNoRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3RhYmlsaXR5IH0gZnJvbSAnQGpzaWkvc3BlYyc7XG5pbXBvcnQgKiBhcyByZWZsZWN0IGZyb20gJ2pzaWktcmVmbGVjdCc7XG5pbXBvcnQgKiBhcyBsb2c0anMgZnJvbSAnbG9nNGpzJztcblxuaW1wb3J0IHsgdmFsaWRhdGVTdGFiaWxpdGllcyB9IGZyb20gJy4vc3RhYmlsaXR5JztcbmltcG9ydCB7IGlzU3RydWN0dXJhbFN1cGVyVHlwZSwgQW5hbHlzaXMgfSBmcm9tICcuL3R5cGUtYW5hbHlzaXMnO1xuaW1wb3J0IHtcbiAgZGVzY3JpYmVJbnRlcmZhY2VUeXBlLFxuICBkZXNjcmliZVR5cGUsXG4gIENvbXBhcmlzb25PcHRpb25zLFxuICBNaXNtYXRjaGVzLFxuICBhcGlFbGVtZW50SWRlbnRpZmllcixcbiAgSVJlcG9ydCxcbn0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBSZWN1cnNpb25CcmVha2VyIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7XG4gIHZhbGlkYXRlQmFzZVR5cGVBc3NpZ25hYmlsaXR5LFxuICB2YWxpZGF0ZU5vdE1hZGVBYnN0cmFjdCxcbiAgdmFsaWRhdGVTdWJjbGFzc2FibGVOb3RSZW1vdmVkLFxuICB2YWxpZGF0ZU5vTmV3QWJzdHJhY3RNZW1iZXJzLFxuICBzdWJjbGFzc2FibGVUeXBlLFxuICB2YWxpZGF0ZU1ldGhvZENvbXBhdGlibGUsXG4gIG1lbWJlclBhaXJzLFxuICB2YWxpZGF0ZVN0YXRpY1NhbWUsXG4gIHZhbGlkYXRlQXN5bmNTYW1lLFxuICB2YWxpZGF0ZVJldHVyblR5cGVOb3RXZWFrZW5lZCxcbiAgdmFsaWRhdGVOb3RNYWRlTm9uVmFyaWFkaWMsXG4gIHZhbGlkYXRlUmV0dXJuVHlwZVNhbWUsXG4gIHZhbGlkYXRlRXhpc3RpbmdQYXJhbXMsXG4gIHZhbGlkYXRlTm9OZXdSZXF1aXJlZFBhcmFtcyxcbiAgdmFsaWRhdGVQYXJhbWV0ZXJUeXBlV2Vha2VuZWQsXG4gIHZhbGlkYXRlUGFyYW1ldGVyVHlwZVNhbWUsXG4gIHZhbGlkYXRlTm90TWFkZUltbXV0YWJsZSxcbiAgdmFsaWRhdGVQcm9wZXJ0eVR5cGVOb3RXZWFrZW5lZCxcbiAgdmFsaWRhdGVQcm9wZXJ0eVR5cGVTYW1lLFxuICB2YWxpZGF0ZUV4aXN0aW5nTWVtYmVycyxcbn0gZnJvbSAnLi92YWxpZGF0aW9ucyc7XG5cbmNvbnN0IExPRyA9IGxvZzRqcy5nZXRMb2dnZXIoJ2pzaWktZGlmZicpO1xuXG4vKipcbiAqIFJvb3Qgb2JqZWN0IGZvciBjb21wYXJpbmcgdHdvIGFzc2VtYmxpZXNcbiAqXG4gKiBUcmFja3MgbWlzbWF0Y2hlcyBhbmQgdXNlZCBhcyBhIGxvb2t1cCB0YWJsZSB0byBjb252ZXJ0IEZRTnMgLT4gQ29tcGFyYWJsZVR5cGUgb2JqZWN0c1xuICovXG5leHBvcnQgY2xhc3MgQXNzZW1ibHlDb21wYXJpc29uIHtcbiAgcHVibGljIHJlYWRvbmx5IG1pc21hdGNoZXM6IE1pc21hdGNoZXM7XG4gIHByaXZhdGUgcmVhZG9ubHkgdHlwZXMgPSBuZXcgTWFwPHN0cmluZywgQ29tcGFyYWJsZVR5cGU8YW55Pj4oKTtcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IG9wdGlvbnM6IENvbXBhcmlzb25PcHRpb25zKSB7XG4gICAgdGhpcy5taXNtYXRjaGVzID0gbmV3IE1pc21hdGNoZXMoe1xuICAgICAgZGVmYXVsdFN0YWJpbGl0eTogb3B0aW9ucy5kZWZhdWx0RXhwZXJpbWVudGFsXG4gICAgICAgID8gU3RhYmlsaXR5LkV4cGVyaW1lbnRhbFxuICAgICAgICA6IFN0YWJpbGl0eS5TdGFibGUsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCB0aGUgdHlwZXMgZnJvbSB0d28gYXNzZW1ibGllcyB0byBjb21wYXJlXG4gICAqXG4gICAqIEFkZHMgYXBwcm9wcmlhdGUgQ29tcGFyYWJsZVR5cGU8PiBpbnN0YW5jZXMuXG4gICAqL1xuICBwdWJsaWMgbG9hZChvcmlnaW5hbDogcmVmbGVjdC5Bc3NlbWJseSwgdXBkYXRlZDogcmVmbGVjdC5Bc3NlbWJseSkge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIHByZXR0aWVyL3ByZXR0aWVyICovXG4gICAgZm9yIChjb25zdCBbb3JpZ0NsYXNzLCB1cGRhdGVkQ2xhc3NdIG9mIHRoaXMudHlwZVBhaXJzKG9yaWdpbmFsLmNsYXNzZXMsIHVwZGF0ZWQpKSB7XG4gICAgICB0aGlzLnR5cGVzLnNldChvcmlnQ2xhc3MuZnFuLCBuZXcgQ29tcGFyYWJsZUNsYXNzVHlwZSh0aGlzLCBvcmlnQ2xhc3MsIHVwZGF0ZWRDbGFzcykpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW29yaWdJZmFjZSwgdXBkYXRlZElmYWNlXSBvZiB0aGlzLnR5cGVQYWlycyhvcmlnaW5hbC5pbnRlcmZhY2VzLCB1cGRhdGVkKSkge1xuICAgICAgaWYgKG9yaWdJZmFjZS5kYXRhdHlwZSAhPT0gdXBkYXRlZElmYWNlLmRhdGF0eXBlKSB7XG4gICAgICAgIHRoaXMubWlzbWF0Y2hlcy5yZXBvcnQoe1xuICAgICAgICAgIHJ1bGVLZXk6ICdpZmFjZS10eXBlJyxcbiAgICAgICAgICB2aW9sYXRvcjogb3JpZ0lmYWNlLFxuICAgICAgICAgIG1lc3NhZ2U6IGB1c2VkIHRvIGJlIGEgJHtkZXNjcmliZUludGVyZmFjZVR5cGUoXG4gICAgICAgICAgICBvcmlnSWZhY2UuZGF0YXR5cGUsXG4gICAgICAgICAgKX0sIGlzIG5vdyBhICR7ZGVzY3JpYmVJbnRlcmZhY2VUeXBlKHVwZGF0ZWRJZmFjZS5kYXRhdHlwZSl9LmAsXG4gICAgICAgIH0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy50eXBlcy5zZXQob3JpZ0lmYWNlLmZxbiwgb3JpZ0lmYWNlLmRhdGF0eXBlXG4gICAgICAgID8gbmV3IENvbXBhcmFibGVTdHJ1Y3RUeXBlKHRoaXMsIG9yaWdJZmFjZSwgdXBkYXRlZElmYWNlKVxuICAgICAgICA6IG5ldyBDb21wYXJhYmxlSW50ZXJmYWNlVHlwZSh0aGlzLCBvcmlnSWZhY2UsIHVwZGF0ZWRJZmFjZSkpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW29yaWdFbnVtLCB1cGRhdGVkRW51bV0gb2YgdGhpcy50eXBlUGFpcnMob3JpZ2luYWwuZW51bXMsIHVwZGF0ZWQpKSB7XG4gICAgICB0aGlzLnR5cGVzLnNldChvcmlnRW51bS5mcW4sIG5ldyBDb21wYXJhYmxlRW51bVR5cGUodGhpcywgb3JpZ0VudW0sIHVwZGF0ZWRFbnVtKSk7XG4gICAgfVxuICAgIC8qIGVzbGludC1lbmFibGUgcHJldHRpZXIvcHJldHRpZXIgKi9cbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIHRoZSBjb21wYXJpc29uIGZvciBhbGwgbG9hZGVkIHR5cGVzXG4gICAqL1xuICBwdWJsaWMgY29tcGFyZSgpIHtcbiAgICB0aGlzLmNvbXBhcmFibGVUeXBlcy5mb3JFYWNoKCh0KSA9PiB0Lm1hcmtUeXBlUm9sZXMoKSk7XG4gICAgdGhpcy5jb21wYXJhYmxlVHlwZXMuZm9yRWFjaCgodCkgPT4gdC5jb21wYXJlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJhc2VkIG9uIGEgSlNJSSBUeXBlUmVmZXJlbmNlLCByZXR1cm4gYWxsIHJlYWNoYWJsZSBDb21wYXJhYmxlVHlwZTw+IG9iamVjdHMuXG4gICAqL1xuICBwdWJsaWMgdHlwZXNJbihyZWY6IHJlZmxlY3QuVHlwZVJlZmVyZW5jZSk6IEFycmF5PENvbXBhcmFibGVUeXBlPGFueT4+IHtcbiAgICBjb25zdCByZXQgPSBuZXcgQXJyYXk8Q29tcGFyYWJsZVR5cGU8YW55Pj4oKTtcblxuICAgIGZvciAoY29uc3QgZnFuIG9mIGZxbnNGcm9tKHJlZikpIHtcbiAgICAgIGNvbnN0IHQgPSB0aGlzLnR5cGVzLmdldChmcW4pO1xuICAgICAgaWYgKHQpIHtcbiAgICAgICAgcmV0LnB1c2godCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvKipcbiAgICogQWxsIENvbXBhcmFibGVUeXBlPD5zXG4gICAqL1xuICBwcml2YXRlIGdldCBjb21wYXJhYmxlVHlwZXMoKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy50eXBlcy52YWx1ZXMoKSk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCB0aGUgbWF0Y2hpbmcgdHlwZSBpbiB0aGUgdXBkYXRlZCBhc3NlbWJseSBiYXNlZCBvbiBhbGwgdHlwZXMgaW4gdGhlIG9yaWdpbmFsIGFzc2VtYmx5XG4gICAqL1xuICBwcml2YXRlICp0eXBlUGFpcnM8VCBleHRlbmRzIHJlZmxlY3QuVHlwZT4oXG4gICAgeHM6IHJlYWRvbmx5IFRbXSxcbiAgICB1cGRhdGVkQXNzZW1ibHk6IHJlZmxlY3QuQXNzZW1ibHksXG4gICk6IEl0ZXJhYmxlSXRlcmF0b3I8W1QsIFRdPiB7XG4gICAgZm9yIChjb25zdCBvcmlnVHlwZSBvZiB4cykge1xuICAgICAgTE9HLnRyYWNlKG9yaWdUeXBlLmZxbik7XG5cbiAgICAgIGNvbnN0IHVwZGF0ZWRUeXBlID0gdXBkYXRlZEFzc2VtYmx5LnRyeUZpbmRUeXBlKG9yaWdUeXBlLmZxbik7XG4gICAgICBpZiAoIXVwZGF0ZWRUeXBlKSB7XG4gICAgICAgIHRoaXMubWlzbWF0Y2hlcy5yZXBvcnQoe1xuICAgICAgICAgIHJ1bGVLZXk6ICdyZW1vdmVkJyxcbiAgICAgICAgICB2aW9sYXRvcjogb3JpZ1R5cGUsXG4gICAgICAgICAgbWVzc2FnZTogJ2hhcyBiZWVuIHJlbW92ZWQnLFxuICAgICAgICB9KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChkZXNjcmliZVR5cGUob3JpZ1R5cGUpICE9PSBkZXNjcmliZVR5cGUodXBkYXRlZFR5cGUpKSB7XG4gICAgICAgIHRoaXMubWlzbWF0Y2hlcy5yZXBvcnQoe1xuICAgICAgICAgIHJ1bGVLZXk6ICdzdHJ1Y3QtY2hhbmdlJyxcbiAgICAgICAgICB2aW9sYXRvcjogb3JpZ1R5cGUsXG4gICAgICAgICAgbWVzc2FnZTogYGhhcyBiZWVuIHR1cm5lZCBpbnRvIGEgJHtkZXNjcmliZVR5cGUodXBkYXRlZFR5cGUpfWAsXG4gICAgICAgIH0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgeWllbGQgW29yaWdUeXBlLCB1cGRhdGVkVHlwZSBhcyBUXTsgLy8gVHJ1c3QgbWUgSSBrbm93IHdoYXQgSSdtIGRvaW5nXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgY29tcGFyYWJsZSB0eXBlc1xuICpcbiAqIE1hbmFnZXMgbm90aW9ucyBvZiBjcmF3bGluZyB0eXBlcyBmb3Igb3RoZXIgcmVmZXJlbmNlIHR5cGVzLCBhbmQgd2hldGhlclxuICogdGhleSBvY2N1ciBpbiBhbiBpbnB1dC9vdXRwdXQgcm9sZSwgYW5kIG1hcmtpbmcgYXMgc3VjaCBvbiB0aGUgY29tcGFyaXNvblxuICogb2JqZWN0LlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ29tcGFyYWJsZVR5cGU8VD4ge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSByZWN1cnNpb25CcmVha2VyID0gbmV3IFJlY3Vyc2lvbkJyZWFrZXIoKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9pbnB1dFR5cGVSZWFzb25zID0gbmV3IEFycmF5PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfb3V0cHV0VHlwZVJlYXNvbnMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXNzZW1ibHlDb21wYXJpc29uOiBBc3NlbWJseUNvbXBhcmlzb24sXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IG9sZFR5cGU6IFQsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IG5ld1R5cGU6IFQsXG4gICkge31cblxuICAvKipcbiAgICogRG9lcyB0aGlzIHR5cGUgb2NjdXIgaW4gYW4gaW5wdXQgcm9sZT9cbiAgICovXG4gIHB1YmxpYyBnZXQgaW5wdXRUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLl9pbnB1dFR5cGVSZWFzb25zLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogRG9lcyB0aGlzIHR5cGUgb2NjdXIgaW4gYW4gb3V0cHV0IHJvbGU/XG4gICAqL1xuICBwdWJsaWMgZ2V0IG91dHB1dFR5cGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX291dHB1dFR5cGVSZWFzb25zLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcbiAgICogTWFyayB0aGlzIHR5cGUgYXMgb2NjdXJpbmcgaW4gYW4gaW5wdXQgcnVsZS5cbiAgICpcbiAgICogQWxsIHR5cGVzIHJlYWNoYWJsZSBmcm9tIHRoaXMgdHlwZSB3aWxsIGJlIG1hcmtlZCBhcyBpbnB1dCB0eXBlcyBhcyB3ZWxsLlxuICAgKi9cbiAgcHVibGljIG1hcmtBc0lucHV0VHlwZSguLi5yZWFzb25GcmFnbWVudHM6IHN0cmluZ1tdKSB7XG4gICAgQ29tcGFyYWJsZVR5cGUucmVjdXJzaW9uQnJlYWtlci5kbyh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9pbnB1dFR5cGVSZWFzb25zLnB1c2gocmVhc29uRnJhZ21lbnRzLmpvaW4oJywgJykpO1xuICAgICAgdGhpcy5mb3JFYWNoUm9sZVNoYXJpbmdUeXBlKCh0eXBlLCByZWFzb24pID0+IHtcbiAgICAgICAgdHlwZS5tYXJrQXNJbnB1dFR5cGUocmVhc29uLCAuLi5yZWFzb25GcmFnbWVudHMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWFyayB0aGlzIHR5cGUgYXMgb2NjdXJpbmcgaW4gYW4gaW5wdXQgcnVsZS5cbiAgICpcbiAgICogQWxsIHR5cGVzIHJlYWNoYWJsZSBmcm9tIHRoaXMgdHlwZSB3aWxsIGJlIG1hcmtlZCBhcyBpbnB1dCB0eXBlcyBhcyB3ZWxsLlxuICAgKi9cbiAgcHVibGljIG1hcmtBc091dHB1dFR5cGUoLi4ucmVhc29uRnJhZ21lbnRzOiBzdHJpbmdbXSkge1xuICAgIENvbXBhcmFibGVUeXBlLnJlY3Vyc2lvbkJyZWFrZXIuZG8odGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fb3V0cHV0VHlwZVJlYXNvbnMucHVzaChyZWFzb25GcmFnbWVudHMuam9pbignLCAnKSk7XG4gICAgICB0aGlzLmZvckVhY2hSb2xlU2hhcmluZ1R5cGUoKHR5cGUsIHJlYXNvbikgPT4ge1xuICAgICAgICB0eXBlLm1hcmtBc091dHB1dFR5cGUocmVhc29uLCAuLi5yZWFzb25GcmFnbWVudHMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVzY3JpYmUgd2h5IHRoaXMgdHlwZSBpcyBhbiBpbnB1dCB0eXBlIChpZiBpdCBpcylcbiAgICovXG4gIHB1YmxpYyBnZXQgaW5wdXRUeXBlUmVhc29uKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGRlc2NyaWJlUmVhc29ucyh0aGlzLl9pbnB1dFR5cGVSZWFzb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXNjcmliZSB3aHkgdGhpcyB0eXBlIGlzIGFuIG91dHB1dCB0eXBlIChpZiBpdCBpcylcbiAgICovXG4gIHB1YmxpYyBnZXQgb3V0cHV0VHlwZVJlYXNvbigpOiBzdHJpbmcge1xuICAgIHJldHVybiBkZXNjcmliZVJlYXNvbnModGhpcy5fb3V0cHV0VHlwZVJlYXNvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3VsZCBiZSBvdmVycmlkZW4gaW4gc3ViY2xhc3NlcyB0byBtYXJrIHJlYWNoYWJsZSB0eXBlcyBhcyBpbnB1dC9vdXRwdXQgdHlwZXNcbiAgICpcbiAgICogU2hvdWxkIG9ubHkgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3NlcyB0aGF0IGNvbnRhaW4gY2FsbGFibGVzLlxuICAgKi9cbiAgcHVibGljIG1hcmtUeXBlUm9sZXMoKSB7XG4gICAgLy8gRW1wdHkgb24gcHVycG9zZVxuICB9XG5cbiAgLyoqXG4gICAqIFNob3VsZCBiZSBvdmVycmlkZGVuIGluIHN1YmNsYXNzZXMgdG8gcGVyZm9ybSB0aGUgY29tcGFyaXNvblxuICAgKlxuICAgKiBJbnB1dC9vdXRwdXQgbWFya2luZyB3aWxsIGFscmVhZHkgaGF2ZSBiZWVuIHBlcmZvcm1lZCBiZWZvcmUgdGhpcyBpcyBjYWxsZWQuXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgY29tcGFyZSgpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBBbGlhcyBmb3IgdGhlIHJvb3Qgb2JqZWN0IE1pc21hY2hlcyBvYmplY3RcbiAgICovXG4gIHByb3RlY3RlZCBnZXQgbWlzbWF0Y2hlcygpIHtcbiAgICByZXR1cm4gdGhpcy5hc3NlbWJseUNvbXBhcmlzb24ubWlzbWF0Y2hlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTaG91bGQgYmUgb3ZlcnJpZGVuIGluIHN1YmNsYXNzZXMgdG8gZXhlY3V0ZSB0aGUgY2FsbGJhY2sgb24gcmVhY2hhYmxlIHR5cGVzXG4gICAqXG4gICAqIFNob3VsZCBiZSBvdmVycmlkZW4gb25seSBmb3IgcHJvZHVjdCB0eXBlcyAoc3RydWN0cykuXG4gICAqL1xuICBwcm90ZWN0ZWQgZm9yRWFjaFJvbGVTaGFyaW5nVHlwZShcbiAgICBjYjogKHQ6IENvbXBhcmFibGVUeXBlPGFueT4sIHJlYXNvbjogc3RyaW5nKSA9PiB2b2lkLFxuICApIHtcbiAgICBBcnJheS5pc0FycmF5KGNiKTtcbiAgfVxufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHJlZmVyZW5jZSB0eXBlc1xuICpcbiAqIENvbnRhaW5zIHNoYXJlZCBjb2RlIHRoYXQgYXBwbGllcyB0byBib3RoIGNsYXNzIGFuZCBpbnRlcmZhY2UgdHlwZXMuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDb21wYXJhYmxlUmVmZXJlbmNlVHlwZTxcbiAgVCBleHRlbmRzIHJlZmxlY3QuUmVmZXJlbmNlVHlwZSxcbj4gZXh0ZW5kcyBDb21wYXJhYmxlVHlwZTxUPiB7XG4gIC8qKlxuICAgKiBDb21wYXJlIG1lbWJlcnMgb2YgdGhlIHJlZmVyZW5jZSB0eXBlc1xuICAgKi9cbiAgcHVibGljIGNvbXBhcmUoKSB7XG4gICAgdmFsaWRhdGVTdGFiaWxpdGllcyh0aGlzLm9sZFR5cGUsIHRoaXMubmV3VHlwZSwgdGhpcy5taXNtYXRjaGVzKTtcbiAgICB2YWxpZGF0ZUJhc2VUeXBlQXNzaWduYWJpbGl0eSh0aGlzLm9sZFR5cGUsIHRoaXMubmV3VHlwZSwgdGhpcy5taXNtYXRjaGVzKTtcblxuICAgIHZhbGlkYXRlU3ViY2xhc3NhYmxlTm90UmVtb3ZlZCh0aGlzLm9sZFR5cGUsIHRoaXMubmV3VHlwZSwgdGhpcy5taXNtYXRjaGVzKTtcbiAgICBpZiAodGhpcy5zdWJjbGFzc2FibGVUeXBlKSB7XG4gICAgICB2YWxpZGF0ZU5vTmV3QWJzdHJhY3RNZW1iZXJzKHRoaXMub2xkVHlwZSwgdGhpcy5uZXdUeXBlLCB0aGlzLm1pc21hdGNoZXMpO1xuICAgIH1cblxuICAgIHRoaXMudmFsaWRhdGVNZXRob2RzKCk7XG4gICAgdGhpcy52YWxpZGF0ZVByb3BlcnRpZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrIHR5cGUgYWNjZXNzZXMgKGlucHV0L291dHB1dCkgb2YgbWV0aG9kcyBhbmQgcHJvcGVydGllc1xuICAgKi9cbiAgcHVibGljIG1hcmtUeXBlUm9sZXMoKSB7XG4gICAgZm9yIChjb25zdCBtZXRob2Qgb2YgdGhpcy5vbGRUeXBlLm93bk1ldGhvZHMpIHtcbiAgICAgIGRldGVybWluZVR5cGVSb2xlc0Zyb21NZXRob2QodGhpcy5hc3NlbWJseUNvbXBhcmlzb24sIG1ldGhvZCk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcHJvcGVydHkgb2YgdGhpcy5vbGRUeXBlLm93blByb3BlcnRpZXMpIHtcbiAgICAgIGRldGVybWluZVR5cGVSb2xlc0Zyb21Qcm9wZXJ0eSh0aGlzLmFzc2VtYmx5Q29tcGFyaXNvbiwgcHJvcGVydHkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0eXBlIHNpZ25hdHVyZXMgb24gYWxsIG1ldGhvZHNcbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZU1ldGhvZHMoKSB7XG4gICAgZm9yIChjb25zdCBbb3JpZywgdXBkYXRlZF0gb2YgbWVtYmVyUGFpcnMoXG4gICAgICB0aGlzLm9sZFR5cGUsXG4gICAgICB0aGlzLm9sZFR5cGUuYWxsTWV0aG9kcyxcbiAgICAgIHRoaXMubmV3VHlwZSxcbiAgICAgIHRoaXMubWlzbWF0Y2hlcyxcbiAgICApKSB7XG4gICAgICBpZiAocmVmbGVjdC5pc01ldGhvZCh1cGRhdGVkKSkge1xuICAgICAgICB0aGlzLnZhbGlkYXRlTWV0aG9kKG9yaWcsIHVwZGF0ZWQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0eXBlIHNpZ25hdHVyZSBjaGFuZ2VzIG9uIHRoZSBnaXZlbiBtZXRob2RcbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZU1ldGhvZChvcmlnaW5hbDogcmVmbGVjdC5NZXRob2QsIHVwZGF0ZWQ6IHJlZmxlY3QuTWV0aG9kKSB7XG4gICAgdmFsaWRhdGVTdGF0aWNTYW1lKG9yaWdpbmFsLCB1cGRhdGVkLCB0aGlzLm1pc21hdGNoZXMpO1xuICAgIHZhbGlkYXRlQXN5bmNTYW1lKG9yaWdpbmFsLCB1cGRhdGVkLCB0aGlzLm1pc21hdGNoZXMpO1xuXG4gICAgaWYgKHRoaXMuc3ViY2xhc3NhYmxlVHlwZSkge1xuICAgICAgdmFsaWRhdGVSZXR1cm5UeXBlU2FtZShcbiAgICAgICAgb3JpZ2luYWwsXG4gICAgICAgIHVwZGF0ZWQsXG4gICAgICAgIHRoaXMubWlzbWF0Y2hlcy53aXRoTW90aXZhdGlvbigndHlwZSBpcyBAc3ViY2xhc3NhYmxlJyksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWxpZGF0ZVJldHVyblR5cGVOb3RXZWFrZW5lZChvcmlnaW5hbCwgdXBkYXRlZCwgdGhpcy5taXNtYXRjaGVzKTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlQ2FsbGFibGUob3JpZ2luYWwsIHVwZGF0ZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHR5cGUgc2lnbmF0dXJlIGNoYW5nZXMgb24gdGhlIGdpdmVuIGNhbGxhYmxlIChtZXRob2Qgb3IgaW5pdGlhbGl6ZXIpXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVDYWxsYWJsZTxUIGV4dGVuZHMgcmVmbGVjdC5NZXRob2QgfCByZWZsZWN0LkluaXRpYWxpemVyPihcbiAgICBvcmlnaW5hbDogVCxcbiAgICB1cGRhdGVkOiBULFxuICApIHtcbiAgICB2YWxpZGF0ZVN0YWJpbGl0aWVzKG9yaWdpbmFsLCB1cGRhdGVkLCB0aGlzLm1pc21hdGNoZXMpO1xuICAgIHZhbGlkYXRlTm90TWFkZU5vblZhcmlhZGljKG9yaWdpbmFsLCB1cGRhdGVkLCB0aGlzLm1pc21hdGNoZXMpO1xuXG4gICAgLy8gQ2hlY2sgdGhhdCBldmVyeSBvcmlnaW5hbCBwYXJhbWV0ZXIgY2FuIHN0aWxsIGJlIG1hcHBlZCB0byBhIHBhcmFtZXRlciBpbiB0aGUgdXBkYXRlZCBtZXRob2RcbiAgICB2YWxpZGF0ZUV4aXN0aW5nUGFyYW1zKFxuICAgICAgb3JpZ2luYWwsXG4gICAgICB1cGRhdGVkLFxuICAgICAgdGhpcy5taXNtYXRjaGVzLFxuICAgICAgKG9sZFBhcmFtLCBuZXdQYXJhbSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5zdWJjbGFzc2FibGVUeXBlKSB7XG4gICAgICAgICAgdmFsaWRhdGVQYXJhbWV0ZXJUeXBlU2FtZShcbiAgICAgICAgICAgIG9yaWdpbmFsLFxuICAgICAgICAgICAgb2xkUGFyYW0sXG4gICAgICAgICAgICBuZXdQYXJhbSxcbiAgICAgICAgICAgIHRoaXMubWlzbWF0Y2hlcy53aXRoTW90aXZhdGlvbigndHlwZSBpcyBAc3ViY2xhc3NhYmxlJyksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWxpZGF0ZVBhcmFtZXRlclR5cGVXZWFrZW5lZChcbiAgICAgICAgICAgIG9yaWdpbmFsLFxuICAgICAgICAgICAgb2xkUGFyYW0sXG4gICAgICAgICAgICBuZXdQYXJhbSxcbiAgICAgICAgICAgIHRoaXMubWlzbWF0Y2hlcyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG5cbiAgICB2YWxpZGF0ZU5vTmV3UmVxdWlyZWRQYXJhbXMob3JpZ2luYWwsIHVwZGF0ZWQsIHRoaXMubWlzbWF0Y2hlcyk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdHlwZSBzaWduYXR1cmUgY2hhbmdlcyBvbiBhbGwgcHJvcGVydGllc1xuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlUHJvcGVydGllcygpIHtcbiAgICBmb3IgKGNvbnN0IFtvcmlnLCB1cGRhdGVkXSBvZiBtZW1iZXJQYWlycyhcbiAgICAgIHRoaXMub2xkVHlwZSxcbiAgICAgIHRoaXMub2xkVHlwZS5hbGxQcm9wZXJ0aWVzLFxuICAgICAgdGhpcy5uZXdUeXBlLFxuICAgICAgdGhpcy5taXNtYXRjaGVzLFxuICAgICkpIHtcbiAgICAgIGlmIChyZWZsZWN0LmlzUHJvcGVydHkodXBkYXRlZCkpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVByb3BlcnR5KG9yaWcsIHVwZGF0ZWQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0eXBlIHNpZ25hdHVyZSBjaGFuZ2VzIG9uIHRoZSBnaXZlbiBwcm9wZXJ0eVxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbGlkYXRlUHJvcGVydHkoXG4gICAgb3JpZ2luYWw6IHJlZmxlY3QuUHJvcGVydHksXG4gICAgdXBkYXRlZDogcmVmbGVjdC5Qcm9wZXJ0eSxcbiAgKSB7XG4gICAgdmFsaWRhdGVTdGFiaWxpdGllcyhvcmlnaW5hbCwgdXBkYXRlZCwgdGhpcy5taXNtYXRjaGVzKTtcbiAgICB2YWxpZGF0ZVN0YXRpY1NhbWUob3JpZ2luYWwsIHVwZGF0ZWQsIHRoaXMubWlzbWF0Y2hlcyk7XG4gICAgdmFsaWRhdGVOb3RNYWRlSW1tdXRhYmxlKG9yaWdpbmFsLCB1cGRhdGVkLCB0aGlzLm1pc21hdGNoZXMpO1xuXG4gICAgaWYgKHRoaXMuc3ViY2xhc3NhYmxlVHlwZSkge1xuICAgICAgLy8gSGVsbG8gQyMgbXkgb2xkIGZyaWVuZFxuICAgICAgdmFsaWRhdGVQcm9wZXJ0eVR5cGVTYW1lKFxuICAgICAgICBvcmlnaW5hbCxcbiAgICAgICAgdXBkYXRlZCxcbiAgICAgICAgdGhpcy5taXNtYXRjaGVzLndpdGhNb3RpdmF0aW9uKCd0eXBlIGlzIEBzdWJjbGFzc2FibGUnKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICghb3JpZ2luYWwuaW1tdXRhYmxlKSB7XG4gICAgICAvLyBJZiB0aGUgdHlwZSBjYW4gYmUgcmVhZCwgaXQgY2FuJ3QgYmUgd2Vha2VuZWQgKGNhbid0IGNoYW5nZSBEb2cgdG8gQW5pbWFsLCBjb25zdW1lcnMgbWlnaHQgYmUgY291bnRpbmcgb24gYSBEb2cpLlxuICAgICAgLy8gSWYgdGhlIHR5cGUgY2FuIGJlIHdyaXR0ZW4sIGl0IGNhbid0IGJlIHN0cmVuZ3RoZW5lZCAoY2FuJ3QgY2hhbmdlIEFuaW1hbCB0byBEb2csIGNvbnN1bWVycyBtaWdodCBiZSBzZW5kaW5nIGEgQ2F0KS5cbiAgICAgIC8vID0+IGl0IG11c3QgcmVtYWluIHRoZSBzYW1lXG4gICAgICB2YWxpZGF0ZVByb3BlcnR5VHlwZVNhbWUoXG4gICAgICAgIG9yaWdpbmFsLFxuICAgICAgICB1cGRhdGVkLFxuICAgICAgICB0aGlzLm1pc21hdGNoZXMud2l0aE1vdGl2YXRpb24oJ211dGFibGUgcHJvcGVydHkgY2Fubm90IGNoYW5nZSB0eXBlJyksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWxpZGF0ZVByb3BlcnR5VHlwZU5vdFdlYWtlbmVkKG9yaWdpbmFsLCB1cGRhdGVkLCB0aGlzLm1pc21hdGNoZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBjdXJyZW50IHJlZmVyZW5jZSB0eXBlIGhhcyBiZWVuIG1hcmtlZCBhcyBzdWJjbGFzc2FibGVcbiAgICovXG4gIHByaXZhdGUgZ2V0IHN1YmNsYXNzYWJsZVR5cGUoKSB7XG4gICAgcmV0dXJuIHN1YmNsYXNzYWJsZVR5cGUodGhpcy5vbGRUeXBlKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29tcGFyYWJsZUNsYXNzVHlwZSBleHRlbmRzIENvbXBhcmFibGVSZWZlcmVuY2VUeXBlPHJlZmxlY3QuQ2xhc3NUeXBlPiB7XG4gIC8qKlxuICAgKiBQZXJmb3JtIHRoZSByZWZlcmVuY2UgdHlwZSBjb21wYXJpc29uIGFuZCBpbmNsdWRlIGNsYXNzLXNwZWNpZmljIGNoZWNrc1xuICAgKi9cbiAgcHVibGljIGNvbXBhcmUoKSB7XG4gICAgc3VwZXIuY29tcGFyZSgpO1xuXG4gICAgdmFsaWRhdGVOb3RNYWRlQWJzdHJhY3QodGhpcy5vbGRUeXBlLCB0aGlzLm5ld1R5cGUsIHRoaXMubWlzbWF0Y2hlcyk7XG5cbiAgICAvLyBKU0lJIGFzc2VtYmxlciBoYXMgYWxyZWFkeSB0YWtlbiBjYXJlIG9mIGluaGVyaXRhbmNlIGhlcmVcbiAgICBpZiAodGhpcy5vbGRUeXBlLmluaXRpYWxpemVyICYmIHRoaXMubmV3VHlwZS5pbml0aWFsaXplcikge1xuICAgICAgdmFsaWRhdGVNZXRob2RDb21wYXRpYmxlKFxuICAgICAgICB0aGlzLm9sZFR5cGUuaW5pdGlhbGl6ZXIsXG4gICAgICAgIHRoaXMubmV3VHlwZS5pbml0aWFsaXplcixcbiAgICAgICAgdGhpcy5taXNtYXRjaGVzLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHlwZSByb2xlIG1hcmtpbmcgLS0gaW5jbHVkZSB0aGUgaW5pdGlhbGl6ZXJcbiAgICovXG4gIHB1YmxpYyBtYXJrVHlwZVJvbGVzKCkge1xuICAgIGlmICh0aGlzLm9sZFR5cGUuaW5pdGlhbGl6ZXIpIHtcbiAgICAgIGRldGVybWluZVR5cGVSb2xlc0Zyb21NZXRob2QoXG4gICAgICAgIHRoaXMuYXNzZW1ibHlDb21wYXJpc29uLFxuICAgICAgICB0aGlzLm9sZFR5cGUuaW5pdGlhbGl6ZXIsXG4gICAgICApO1xuICAgIH1cbiAgICBzdXBlci5tYXJrVHlwZVJvbGVzKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbnRlcmZhY2UgdHlwZSBjb21wYXJpc29uXG4gKlxuICogKEFjdHVhbGx5IGp1c3QgcGxhaW4gcmVmZXJlbmNlIHR5cGUgY29tcGFyaXNvbilcbiAqL1xuZXhwb3J0IGNsYXNzIENvbXBhcmFibGVJbnRlcmZhY2VUeXBlIGV4dGVuZHMgQ29tcGFyYWJsZVJlZmVyZW5jZVR5cGU8cmVmbGVjdC5JbnRlcmZhY2VUeXBlPiB7fVxuXG4vKipcbiAqIFN0cnVjdCB0eXBlIGNvbXBhcmlzb25cbiAqXG4gKiBNb3N0IG5vdGFibHk6IGRvZXMgbm8tc3RyZW5ndGhlbmluZy9uby13ZWFrZW5pbmcgY2hlY2tzIGJhc2VkIG9uIHdoZXRoZXJcbiAqIHN0cnVjdHMgYXBwZWFyIGluIGlucHV0L291dHB1dCBwb3NpdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb21wYXJhYmxlU3RydWN0VHlwZSBleHRlbmRzIENvbXBhcmFibGVUeXBlPHJlZmxlY3QuSW50ZXJmYWNlVHlwZT4ge1xuICBwdWJsaWMgY29tcGFyZSgpIHtcbiAgICB2YWxpZGF0ZVN0YWJpbGl0aWVzKHRoaXMub2xkVHlwZSwgdGhpcy5uZXdUeXBlLCB0aGlzLm1pc21hdGNoZXMpO1xuICAgIHZhbGlkYXRlQmFzZVR5cGVBc3NpZ25hYmlsaXR5KHRoaXMub2xkVHlwZSwgdGhpcy5uZXdUeXBlLCB0aGlzLm1pc21hdGNoZXMpO1xuICAgIHRoaXMudmFsaWRhdGVOb1Byb3BlcnRpZXNSZW1vdmVkKCk7XG5cbiAgICBpZiAodGhpcy5pbnB1dFR5cGUpIHtcbiAgICAgIC8vIElmIHRoZSBzdHJ1Y3QgaXMgd3JpdHRlbiwgaXQgY2FuJ3QgYmUgc3RyZW5ndGhlbmVkIChleDogY2FuJ3QgY2hhbmdlIGFuIG9wdGlvbmFsIHByb3BlcnR5IHRvIHJlcXVpcmVkKVxuICAgICAgdGhpcy52YWxpZGF0ZU5vdFN0cmVuZ3RoZW5lZChcbiAgICAgICAgdGhpcy5taXNtYXRjaGVzLndpdGhNb3RpdmF0aW9uKHRoaXMuaW5wdXRUeXBlUmVhc29uKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3V0cHV0VHlwZSkge1xuICAgICAgLy8gSWYgdGhlIHN0cnVjdCBpcyByZWFkLCBpdCBjYW4ndCBiZSB3ZWFrZW5lZCAoZXg6IGNhbid0IGNoYW5nZSBhIHJlcXVpcmVkIHByb3BlcnR5IHRvIG9wdGlvbmFsKVxuICAgICAgdGhpcy52YWxpZGF0ZU5vdFdlYWtlbmVkKFxuICAgICAgICB0aGlzLm1pc21hdGNoZXMud2l0aE1vdGl2YXRpb24odGhpcy5vdXRwdXRUeXBlUmVhc29uKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV2ZXJ5IHR5cGUgb2YgZXZlcnkgcHJvcGVydHkgc2hvdWxkIGhhdmUgdGhlIHNhbWUgaW4vb3V0IGNsYXNzaWZpY2F0aW9uIGFzIHRoZSBvdXRlciB0eXBlXG4gICAqL1xuICBwcm90ZWN0ZWQgZm9yRWFjaFJvbGVTaGFyaW5nVHlwZShcbiAgICBjYjogKHQ6IENvbXBhcmFibGVUeXBlPGFueT4sIHJlYXNvbjogc3RyaW5nKSA9PiB2b2lkLFxuICApIHtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgdGhpcy5vbGRUeXBlLmFsbFByb3BlcnRpZXMpIHtcbiAgICAgIGZvciAoY29uc3QgdCBvZiB0aGlzLmFzc2VtYmx5Q29tcGFyaXNvbi50eXBlc0luKHByb3AudHlwZSkpIHtcbiAgICAgICAgY2IodCwgYHR5cGUgb2YgcHJvcGVydHkgJHtwcm9wLm5hbWV9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHRoYXQgYWxsIHByb3BlcnRpZXMgYXJlIHN0aWxsIHByZXNlbnRcbiAgICpcbiAgICogVGhpcyBpcyBiZWNhdXNlIGZvciBhbGwgbm9uLXN0cnVjdHVyYWxseSB0eXBlZCBsYW5ndWFnZXMgaXQgaXMgbm90IGFsbG93ZWRcbiAgICogdG8gc3BlY2lmeSBtZW1iZXJzIHdoaWNoIGFyZW4ndCBhY3R1YWxseSBwcmVzZW50IGluIHRoZSB0eXBlLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZU5vUHJvcGVydGllc1JlbW92ZWQoKSB7XG4gICAgLy8gQSBzaW5nbGUgcnVuIG9mIG1lbWJlclBhaXJzKCkgd2l0aCBub3RoaW5nIGVsc2Ugd2lsbCBkbyB0aGlzIGNoZWNrLlxuICAgIEFycmF5LmZyb20oXG4gICAgICBtZW1iZXJQYWlycyhcbiAgICAgICAgdGhpcy5vbGRUeXBlLFxuICAgICAgICB0aGlzLm9sZFR5cGUuYWxsUHJvcGVydGllcyxcbiAgICAgICAgdGhpcy5uZXdUeXBlLFxuICAgICAgICB0aGlzLm1pc21hdGNoZXMsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhhdCB0aGUgY3VycmVudCB0eXBlIGlzIG5vdCB3ZWFrZW5lZFxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZU5vdFdlYWtlbmVkKG1pc21hdGNoZXM6IElSZXBvcnQpIHtcbiAgICBjb25zdCBhbmEgPSB0aGlzLmlzU3RydWN0dXJhbFN1cGVyVHlwZSh0aGlzLm9sZFR5cGUsIHRoaXMubmV3VHlwZSk7XG4gICAgaWYgKCFhbmEuc3VjY2Vzcykge1xuICAgICAgbWlzbWF0Y2hlcy5yZXBvcnQoe1xuICAgICAgICBydWxlS2V5OiAnd2Vha2VuZWQnLFxuICAgICAgICB2aW9sYXRvcjogdGhpcy5vbGRUeXBlLFxuICAgICAgICBtZXNzYWdlOiBhbmEucmVhc29ucy5qb2luKCcsICcpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHRoYXQgdGhlIGN1cnJlbnQgdHlwZSBpcyBub3Qgc3RyZW5ndGhlbmVkXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlTm90U3RyZW5ndGhlbmVkKG1pc21hdGNoZXM6IElSZXBvcnQpIHtcbiAgICBjb25zdCBhbmEgPSB0aGlzLmlzU3RydWN0dXJhbFN1cGVyVHlwZSh0aGlzLm5ld1R5cGUsIHRoaXMub2xkVHlwZSk7XG4gICAgaWYgKCFhbmEuc3VjY2Vzcykge1xuICAgICAgbWlzbWF0Y2hlcy5yZXBvcnQoe1xuICAgICAgICBydWxlS2V5OiAnc3RyZW5ndGhlbmVkJyxcbiAgICAgICAgdmlvbGF0b3I6IHRoaXMub2xkVHlwZSxcbiAgICAgICAgbWVzc2FnZTogYW5hLnJlYXNvbnMuam9pbignLCAnKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNTdHJ1Y3R1cmFsU3VwZXJUeXBlKFxuICAgIGE6IHJlZmxlY3QuSW50ZXJmYWNlVHlwZSxcbiAgICBiOiByZWZsZWN0LkludGVyZmFjZVR5cGUsXG4gICk6IEFuYWx5c2lzIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGlzU3RydWN0dXJhbFN1cGVyVHlwZShhLCBiLCB0aGlzLm5ld1R5cGUuc3lzdGVtKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBXZSBtaWdodCBnZXQgYW4gZXhjZXB0aW9uIGlmIHRoZSB0eXBlIGlzIHN1cHBvc2VkIHRvIGNvbWUgZnJvbSBhIGRpZmZlcmVudFxuICAgICAgLy8gYXNzZW1ibHkgYW5kIHRoZSBsb29rdXAgZmFpbHMuXG4gICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSwgcmVhc29uczogW2UubWVzc2FnZV0gfTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDb21wYXJpc29uIGZvciBlbnVtc1xuICovXG5leHBvcnQgY2xhc3MgQ29tcGFyYWJsZUVudW1UeXBlIGV4dGVuZHMgQ29tcGFyYWJsZVR5cGU8cmVmbGVjdC5FbnVtVHlwZT4ge1xuICAvKipcbiAgICogUGVyZm9ybSBjb21wYXJpc29ucyBvbiBlbnVtIG1lbWJlcnNcbiAgICovXG4gIHB1YmxpYyBjb21wYXJlKCkge1xuICAgIHZhbGlkYXRlU3RhYmlsaXRpZXModGhpcy5vbGRUeXBlLCB0aGlzLm5ld1R5cGUsIHRoaXMubWlzbWF0Y2hlcyk7XG5cbiAgICB2YWxpZGF0ZUV4aXN0aW5nTWVtYmVycyhcbiAgICAgIHRoaXMub2xkVHlwZSxcbiAgICAgIHRoaXMubmV3VHlwZSxcbiAgICAgIHRoaXMubWlzbWF0Y2hlcyxcbiAgICAgIChvbGRNZW1iZXIsIG5ld01lbWJlcikgPT4ge1xuICAgICAgICB2YWxpZGF0ZVN0YWJpbGl0aWVzKG9sZE1lbWJlciwgbmV3TWVtYmVyLCB0aGlzLm1pc21hdGNoZXMpO1xuICAgICAgfSxcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyBpbnB1dC9vdXRwdXQgcm9sZXMgb2YgdHlwZXMgdXNlZCBpbiB0aGlzIG1ldGhvZFxuICpcbiAqIC0gQXJndW1lbnQgdHlwZXMgYXJlIHRyZWF0ZWQgYXMgSU4gdHlwZXNcbiAqIC0gUmV0dXJuIHR5cGUgaXMgdHJlYXRlZCBhcyBPVVQgdHlwZVxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVUeXBlUm9sZXNGcm9tTWV0aG9kKFxuICBjb21wYXJpc29uOiBBc3NlbWJseUNvbXBhcmlzb24sXG4gIG1ldGhvZDogcmVmbGVjdC5NZXRob2QgfCByZWZsZWN0LkluaXRpYWxpemVyLFxuKSB7XG4gIGlmIChyZWZsZWN0LmlzTWV0aG9kKG1ldGhvZCkpIHtcbiAgICBmb3IgKGNvbnN0IHQgb2YgY29tcGFyaXNvbi50eXBlc0luKG1ldGhvZC5yZXR1cm5zLnR5cGUpKSB7XG4gICAgICB0Lm1hcmtBc091dHB1dFR5cGUoYHJldHVybmVkIGZyb20gJHthcGlFbGVtZW50SWRlbnRpZmllcihtZXRob2QpfWApO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgcGFyYW0gb2YgbWV0aG9kLnBhcmFtZXRlcnMgPz8gW10pIHtcbiAgICBmb3IgKGNvbnN0IHQgb2YgY29tcGFyaXNvbi50eXBlc0luKHBhcmFtLnR5cGUpKSB7XG4gICAgICB0Lm1hcmtBc0lucHV0VHlwZShgaW5wdXQgdG8gJHthcGlFbGVtZW50SWRlbnRpZmllcihtZXRob2QpfWApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIERldGVybWluZXMgaW5wdXQvb3V0cHV0IHJvbGVzIG9mIHR5cGVzIHVzZWQgaW4gdGhpcyBwcm9wZXJ0eVxuICpcbiAqIC0gUHJvcGVydHkgdHlwZSBpcyB0cmVhdGVkIGFzIE9VVCB0eXBlXG4gKiAtIElmIG11dGFibGUsIHByb3BlcnR5IHR5cGUgaXMgYWxzbyB0cmVhdGVkIGFzIElOIHR5cGVcbiAqXG4gKiBJbiBlZmZlY3QsIGEgcHJvcGVydHkgaXMgdHJlYXRlZCBhcyB0aGUgZm9sbG93aW5nIG1ldGhvZHM6XG4gKlxuICogLSBwcm9wZXJ0eSgpOiBUO1xuICogLSBzZXRQcm9wZXJ0eSg6IFQpOyAgPC0gb25seSBpZiBtdXRhYmxlXG4gKi9cbmZ1bmN0aW9uIGRldGVybWluZVR5cGVSb2xlc0Zyb21Qcm9wZXJ0eShcbiAgY29tcGFyaXNvbjogQXNzZW1ibHlDb21wYXJpc29uLFxuICBwcm9wZXJ0eTogcmVmbGVjdC5Qcm9wZXJ0eSxcbikge1xuICBmb3IgKGNvbnN0IHQgb2YgY29tcGFyaXNvbi50eXBlc0luKHByb3BlcnR5LnR5cGUpKSB7XG4gICAgdC5tYXJrQXNPdXRwdXRUeXBlKGB0eXBlIG9mICR7YXBpRWxlbWVudElkZW50aWZpZXIocHJvcGVydHkpfWApO1xuICB9XG4gIGlmICghcHJvcGVydHkuaW1tdXRhYmxlKSB7XG4gICAgZm9yIChjb25zdCB0IG9mIGNvbXBhcmlzb24udHlwZXNJbihwcm9wZXJ0eS50eXBlKSkge1xuICAgICAgdC5tYXJrQXNJbnB1dFR5cGUoYHR5cGUgb2YgbXV0YWJsZSAke2FwaUVsZW1lbnRJZGVudGlmaWVyKHByb3BlcnR5KX1gKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gYWxsIHRoZSBGUU5zIGZyb20gYSB0eXBlIHJlZmVyZW5jZVxuICpcbiAqIEluIHRoZSBzaW1wbGUgY2FzZSwgYSBzaW1wbGUgRlFOLCBidXQgdGhlIHR5cGUgbWlnaHRcbiAqIGJlIGEgdW5pb24gb3IgY29tcGxleCB0eXBlIGFzIHdlbGwuXG4gKi9cbmZ1bmN0aW9uIGZxbnNGcm9tKHJlZjogcmVmbGVjdC5UeXBlUmVmZXJlbmNlKSB7XG4gIGNvbnN0IHJldCA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG4gIHJlY3Vyc2UocmVmKTtcbiAgcmV0dXJuIHJldDtcblxuICBmdW5jdGlvbiByZWN1cnNlKHR5cGU6IHJlZmxlY3QuVHlwZVJlZmVyZW5jZSkge1xuICAgIGlmICh0eXBlLm1hcE9mVHlwZSkge1xuICAgICAgcmVjdXJzZSh0eXBlLm1hcE9mVHlwZSk7XG4gICAgfSBlbHNlIGlmICh0eXBlLmFycmF5T2ZUeXBlKSB7XG4gICAgICByZWN1cnNlKHR5cGUuYXJyYXlPZlR5cGUpO1xuICAgIH0gZWxzZSBpZiAodHlwZS51bmlvbk9mVHlwZXMpIHtcbiAgICAgIHR5cGUudW5pb25PZlR5cGVzLmZvckVhY2gocmVjdXJzZSk7XG4gICAgfSBlbHNlIGlmICh0eXBlLmZxbikge1xuICAgICAgcmV0LnB1c2godHlwZS5mcW4pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkZXNjcmliZVJlYXNvbnMocmVhc29uczogc3RyaW5nW10pIHtcbiAgaWYgKHJlYXNvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGlmIChyZWFzb25zLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiByZWFzb25zWzBdO1xuICB9XG4gIHJldHVybiBgJHtyZWFzb25zWzBdfSAoLi4uYW5kICR7cmVhc29ucy5sZW5ndGggLSAxfSBtb3JlLi4uKWA7XG59XG4iXX0=
package/lib/types.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { Stability } from '@jsii/spec';
2
+ import * as reflect from 'jsii-reflect';
3
+ export interface ComparisonOptions {
4
+ /**
5
+ * Whether to treat API elements as experimental if unmarked.
6
+ *
7
+ * @default Treat as stable
8
+ */
9
+ defaultExperimental?: boolean;
10
+ }
11
+ export interface ComparisonContext extends ComparisonOptions {
12
+ /**
13
+ * Where to report errors
14
+ */
15
+ mismatches: Mismatches;
16
+ }
17
+ export interface ApiMismatch {
18
+ message: string;
19
+ violationKey: string;
20
+ stability: Stability;
21
+ }
22
+ export declare type ApiElement = reflect.Type | reflect.TypeMember | reflect.EnumMember;
23
+ export interface ReportOptions {
24
+ ruleKey: string;
25
+ violator: ApiElement;
26
+ message: string;
27
+ }
28
+ export interface IReport {
29
+ report(options: ReportOptions): void;
30
+ withMotivation(reason: string): IReport;
31
+ }
32
+ export declare class Mismatches implements IReport {
33
+ readonly mismatches: ApiMismatch[];
34
+ private readonly defaultStability;
35
+ constructor(opts: {
36
+ defaultStability: Stability;
37
+ });
38
+ report(options: ReportOptions): void;
39
+ messages(): Generator<string, void, unknown>;
40
+ get count(): number;
41
+ filter(pred: (x: ApiMismatch) => boolean): Mismatches;
42
+ withMotivation(motivation: string): IReport;
43
+ }
44
+ export declare function apiElementIdentifier(apiElement: ApiElement): string;
45
+ export declare function describeType(type: reflect.Type): "ENUM" | "CLASS" | "IFACE" | "TYPE";
46
+ export declare function describeInterfaceType(dataType: boolean): "struct" | "regular interface";