@codeperfect/eslint-plugin 2.3.0 → 2.5.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 (151) hide show
  1. package/dist/application/index.d.ts +1 -1
  2. package/dist/application/index.d.ts.map +1 -1
  3. package/dist/application/index.js +2 -2
  4. package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
  5. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts.map +1 -1
  6. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.js +4 -2
  7. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.d.ts.map +1 -1
  8. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.js +2 -4
  9. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.d.ts.map +1 -1
  10. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.js +4 -134
  11. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.d.ts +14 -0
  12. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.d.ts.map +1 -0
  13. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.js +154 -0
  14. package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.d.ts.map +1 -1
  15. package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.js +10 -12
  16. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.d.ts.map +1 -1
  17. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.js +4 -11
  18. package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.d.ts +14 -0
  19. package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.d.ts.map +1 -0
  20. package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.js +187 -0
  21. package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.d.ts +26 -0
  22. package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.d.ts.map +1 -0
  23. package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.js +95 -0
  24. package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.d.ts +32 -0
  25. package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.d.ts.map +1 -0
  26. package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.js +78 -0
  27. package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.d.ts +18 -0
  28. package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.d.ts.map +1 -0
  29. package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.js +45 -0
  30. package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.d.ts +34 -0
  31. package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.d.ts.map +1 -0
  32. package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.js +44 -0
  33. package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.d.ts +59 -0
  34. package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.d.ts.map +1 -0
  35. package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.js +133 -0
  36. package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.d.ts +28 -0
  37. package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.d.ts.map +1 -0
  38. package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.js +106 -0
  39. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts +21 -21
  40. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts.map +1 -1
  41. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.js +24 -587
  42. package/dist/domain/architecture/no-unused-exports/rule.js +3 -3
  43. package/dist/domain/core/no-multiple-declarators/rule-utilities.d.ts +58 -0
  44. package/dist/domain/core/no-multiple-declarators/rule-utilities.d.ts.map +1 -0
  45. package/dist/domain/core/no-multiple-declarators/rule-utilities.js +204 -0
  46. package/dist/domain/core/no-multiple-declarators/rule.d.ts.map +1 -1
  47. package/dist/domain/core/no-multiple-declarators/rule.js +9 -211
  48. package/dist/domain/core/no-multiple-declarators/types.js +2 -2
  49. package/dist/domain/core/prefer-interface-types/rule-utilities.d.ts +57 -0
  50. package/dist/domain/core/prefer-interface-types/rule-utilities.d.ts.map +1 -0
  51. package/dist/domain/core/prefer-interface-types/rule-utilities.js +105 -0
  52. package/dist/domain/core/prefer-interface-types/rule.d.ts.map +1 -1
  53. package/dist/domain/core/prefer-interface-types/rule.js +2 -104
  54. package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.d.ts +25 -0
  55. package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.d.ts.map +1 -0
  56. package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.js +64 -0
  57. package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts +2 -24
  58. package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts.map +1 -1
  59. package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +3 -65
  60. package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +2 -2
  61. package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +2 -2
  62. package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
  63. package/dist/domain/docs/no-interface-member-docs/rule.js +3 -2
  64. package/dist/domain/docs/require-example-language/examples-collect.d.ts +15 -0
  65. package/dist/domain/docs/require-example-language/examples-collect.d.ts.map +1 -0
  66. package/dist/domain/docs/require-example-language/examples-collect.js +113 -0
  67. package/dist/domain/docs/require-example-language/examples.d.ts +24 -13
  68. package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
  69. package/dist/domain/docs/require-example-language/examples.js +2 -111
  70. package/dist/domain/docs/require-example-language/fixes.js +4 -4
  71. package/dist/domain/docs/require-example-language/rule.d.ts.map +1 -1
  72. package/dist/domain/docs/require-example-language/rule.js +9 -8
  73. package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
  74. package/dist/domain/docs/require-example-language/types.js +1 -1
  75. package/dist/domain/index.d.ts +1 -1
  76. package/dist/domain/index.d.ts.map +1 -1
  77. package/dist/domain/index.js +2 -2
  78. package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts.map +1 -1
  79. package/dist/domain/testing/aaa/analyzer.analysis.helpers.js +8 -8
  80. package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts.map +1 -1
  81. package/dist/domain/testing/aaa/analyzer.assertions.helpers.js +10 -9
  82. package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts.map +1 -1
  83. package/dist/domain/testing/aaa/analyzer.assertions.operands.js +2 -5
  84. package/dist/domain/testing/aaa/analyzer.classification.helpers.js +14 -16
  85. package/dist/domain/testing/aaa/analyzer.classification.traversal.js +6 -4
  86. package/dist/domain/testing/aaa/analyzer.super.d.ts.map +1 -1
  87. package/dist/domain/testing/aaa/analyzer.super.js +10 -8
  88. package/dist/domain/testing/assert-actual-expected-names/rule.d.ts.map +1 -1
  89. package/dist/domain/testing/assert-actual-expected-names/rule.js +21 -23
  90. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.d.ts.map +1 -1
  91. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.js +1 -1
  92. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.d.ts.map +1 -1
  93. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.js +2 -160
  94. package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.d.ts +41 -0
  95. package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.d.ts.map +1 -0
  96. package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.js +161 -0
  97. package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.d.ts.map +1 -1
  98. package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.js +2 -2
  99. package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.d.ts +81 -0
  100. package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.d.ts.map +1 -0
  101. package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.js +181 -0
  102. package/dist/domain/testing/enforce-aaa-structure/rule.d.ts.map +1 -1
  103. package/dist/domain/testing/enforce-aaa-structure/rule.js +28 -217
  104. package/dist/domain/testing/index.d.ts +1 -0
  105. package/dist/domain/testing/index.d.ts.map +1 -1
  106. package/dist/domain/testing/index.js +2 -1
  107. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/index.d.ts +2 -0
  108. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/index.d.ts.map +1 -0
  109. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/index.js +2 -0
  110. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.d.ts +29 -0
  111. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.d.ts.map +1 -0
  112. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.js +200 -0
  113. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.d.ts +12 -0
  114. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.d.ts.map +1 -0
  115. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.js +151 -0
  116. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.d.ts +16 -0
  117. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.d.ts.map +1 -0
  118. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.js +109 -0
  119. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.d.ts +5 -0
  120. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.d.ts.map +1 -0
  121. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.js +35 -0
  122. package/dist/domain/testing/prefer-vi-mocked-import/fix-import-updates.d.ts.map +1 -1
  123. package/dist/domain/testing/prefer-vi-mocked-import/fix-import-updates.js +7 -4
  124. package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.d.ts.map +1 -1
  125. package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.js +7 -4
  126. package/dist/domain/testing/prefer-vi-mocked-import/fix.js +2 -2
  127. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts +18 -0
  128. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts.map +1 -0
  129. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.js +162 -0
  130. package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.d.ts.map +1 -1
  131. package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.js +5 -4
  132. package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.d.ts +29 -0
  133. package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.d.ts.map +1 -0
  134. package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.js +100 -0
  135. package/dist/domain/testing/prefer-vi-mocked-import/match.d.ts.map +1 -1
  136. package/dist/domain/testing/prefer-vi-mocked-import/match.js +5 -246
  137. package/dist/domain/testing/prefer-vi-mocked-import/rule.d.ts.map +1 -1
  138. package/dist/domain/testing/prefer-vi-mocked-import/rule.js +18 -20
  139. package/dist/domain/testing/require-act-result-capture/rule.d.ts.map +1 -1
  140. package/dist/domain/testing/require-act-result-capture/rule.js +47 -21
  141. package/dist/domain/testing/require-test-companion/rule.d.ts.map +1 -1
  142. package/dist/domain/testing/require-test-companion/rule.js +2 -4
  143. package/dist/domain/testing/single-act-statement/rule.d.ts.map +1 -1
  144. package/dist/domain/testing/single-act-statement/rule.js +20 -22
  145. package/dist/infrastructure/codeperfect-plugin.d.ts +2 -0
  146. package/dist/infrastructure/codeperfect-plugin.d.ts.map +1 -1
  147. package/dist/infrastructure/codeperfect-plugin.js +3 -2
  148. package/dist/infrastructure/presets.d.ts.map +1 -1
  149. package/dist/infrastructure/presets.js +3 -1
  150. package/package.json +58 -58
  151. package/dist/.tsbuildinfo +0 -1
@@ -1,208 +1,30 @@
1
- import { ESLintUtils } from "@typescript-eslint/utils";
2
- import path from "node:path";
3
- import * as ts from "typescript";
4
- import { isPublicApiFile, isTestFile } from "./no-unused-exports-options.js";
1
+ import { collectExportedElements as collectExportedElementsFromDeclarations } from "./no-unused-exports-declaration-utilities.js";
2
+ import { getTypeScriptProgram as getTypeScriptProgramFromServices } from "./no-unused-exports-identifier-utilities.js";
3
+ import { classifyExportUsage as classifyExportUsageFromUsages, collectCrossFileUsages as collectCrossFileUsagesFromUsages, } from "./no-unused-exports-usage-utilities.js";
5
4
  /**
6
- * Normalizes an absolute file path for safe equality checks.
7
- * @param inputPath Candidate path.
8
- * @returns Normalized absolute path suitable for cross-platform comparisons.
9
- * @example
10
- * ```typescript
11
- * const comparable = toComparableAbsolutePath("/repo/src/feature.ts");
12
- * ```
13
- */
14
- const toComparableAbsolutePath = (inputPath) => {
15
- const absolutePath = path.normalize(path.resolve(inputPath));
16
- return absolutePath.toLowerCase();
17
- };
18
- /**
19
- * Converts one unknown value into an indexable record.
20
- * @param value Candidate value.
21
- * @returns Record view when the value is object-like.
22
- * @example
23
- * ```typescript
24
- * const record = asRecord({ type: "Identifier" });
25
- * ```
26
- */
27
- const asRecord = (value) => value !== null && typeof value === "object"
28
- ? value
29
- : void 0;
30
- /**
31
- * Reads one string property from an object-like value.
32
- * @param value Candidate object.
33
- * @param key Lookup key used to read the property.
34
- * @returns String value when present.
35
- * @example
36
- * ```typescript
37
- * const name = readStringProperty({ name: "feature" }, "name");
38
- * ```
39
- */
40
- const readStringProperty = (value, key) => {
41
- const record = asRecord(value);
42
- const property = record?.[key];
43
- return typeof property === "string" ? property : void 0;
44
- };
45
- /**
46
- * Reads one array property from an object-like value.
47
- * @param value Candidate object.
48
- * @param key Lookup key used to read the property.
49
- * @returns Array value when present.
50
- * @example
51
- * ```typescript
52
- * const items = readArrayProperty({ elements: [1, 2] }, "elements");
53
- * ```
54
- */
55
- const readArrayProperty = (value, key) => {
56
- const record = asRecord(value);
57
- const property = record?.[key];
58
- return Array.isArray(property) ? property : void 0;
59
- };
60
- /**
61
- * Resolves TypeScript parser services program when available.
62
- * @param context Rule context.
63
- * @returns TypeScript program when available.
64
- * @example
65
- * ```typescript
66
- * const program = getTypeScriptProgram(context);
67
- * ```
68
- */
69
- const getTypeScriptProgram = (context) => {
70
- try {
71
- const services = ESLintUtils.getParserServices(context);
72
- return services.program;
73
- }
74
- catch {
75
- return void 0;
76
- }
77
- };
78
- /**
79
- * Collects identifier names from one variable pattern.
80
- * @param node Variable pattern candidate.
81
- * @returns Identifier names declared by the pattern.
82
- * @example
83
- * ```typescript
84
- * const names = collectPatternIdentifierNames(pattern);
85
- * ```
86
- */
87
- const collectPatternIdentifierNames = (node) => {
88
- const pattern = asRecord(node);
89
- if (pattern === void 0) {
90
- return [];
91
- }
92
- const patternType = readStringProperty(pattern, "type");
93
- if (patternType === "Identifier") {
94
- const name = readStringProperty(pattern, "name");
95
- return name === void 0 ? [] : [name];
96
- }
97
- if (patternType === "RestElement") {
98
- return collectPatternIdentifierNames(pattern["argument"]);
99
- }
100
- if (patternType === "AssignmentPattern") {
101
- return collectPatternIdentifierNames(pattern["left"]);
102
- }
103
- if (patternType === "ArrayPattern") {
104
- return (readArrayProperty(pattern, "elements") ?? []).flatMap((element) => collectPatternIdentifierNames(element));
105
- }
106
- if (patternType === "ObjectPattern") {
107
- return (readArrayProperty(pattern, "properties") ?? []).flatMap((property) => {
108
- if (readStringProperty(property, "type") === "RestElement") {
109
- return collectPatternIdentifierNames(asRecord(property)?.["argument"]);
110
- }
111
- return collectPatternIdentifierNames(asRecord(property)?.["value"]);
112
- });
113
- }
114
- return [];
115
- };
116
- /**
117
- * Reads one export specifier name.
118
- * @param specifier Export specifier candidate.
119
- * @returns Exported name when available.
120
- * @example
121
- * ```typescript
122
- * const name = getExportSpecifierName(specifier);
123
- * ```
124
- */
125
- const getExportSpecifierName = (specifier) => {
126
- const candidate = asRecord(specifier);
127
- const exportedName = readStringProperty(candidate?.["exported"], "name");
128
- if (typeof exportedName === "string") {
129
- return exportedName;
130
- }
131
- const localName = readStringProperty(candidate?.["local"], "name");
132
- return typeof localName === "string" ? localName : void 0;
133
- };
134
- /**
135
- * Reads one local export specifier name.
136
- * @param specifier Export specifier candidate.
137
- * @returns Local specifier name when available.
5
+ * Classifies one exported name based on cross-file usages.
6
+ * @param usages Collected usages.
7
+ * @returns Classification label.
138
8
  * @example
139
9
  * ```typescript
140
- * const name = getExportSpecifierLocalName(specifier);
10
+ * const classification = classifyExportUsage(usages);
141
11
  * ```
142
12
  */
143
- const getExportSpecifierLocalName = (specifier) => {
144
- const candidate = asRecord(specifier);
145
- return readStringProperty(candidate?.["local"], "name");
146
- };
13
+ const classifyExportUsage = (usages) => classifyExportUsageFromUsages(usages);
147
14
  /**
148
- * Collects top-level declaration names owned by the current module.
149
- * @param body Program body statements.
150
- * @returns Map from locally declared name to its declaration metadata.
15
+ * Collects concrete usages of one exported element across the program.
16
+ * @param program TypeScript program.
17
+ * @param sourceFilename Source filename where export is defined.
18
+ * @param state Normalized rule options.
19
+ * @param repoRoot Absolute repository root used for test-file classification.
20
+ * @param exportedElement Exported element to classify.
21
+ * @returns Concrete usages for the exported element.
151
22
  * @example
152
23
  * ```typescript
153
- * const declarations = collectLocalDeclarationNames(program.body);
24
+ * const usages = collectCrossFileUsages(program, "/repo/src/feature.ts", state, "/repo", exportedElement);
154
25
  * ```
155
26
  */
156
- const collectLocalDeclarationNames = (body) => {
157
- const declarationNames = new Map();
158
- for (const statement of body) {
159
- const declarationCandidate = statement.type === "ExportNamedDeclaration" &&
160
- statement.declaration !== null &&
161
- statement.declaration !== void 0
162
- ? statement.declaration
163
- : statement;
164
- const declarationCandidateRecord = asRecord(declarationCandidate);
165
- const declarationCandidateType = readStringProperty(declarationCandidate, "type");
166
- if (declarationCandidateRecord === void 0 ||
167
- declarationCandidateType === void 0) {
168
- continue;
169
- }
170
- if (declarationCandidateType === "FunctionDeclaration" ||
171
- declarationCandidateType === "ClassDeclaration" ||
172
- declarationCandidateType === "TSEnumDeclaration" ||
173
- declarationCandidateType === "TSInterfaceDeclaration" ||
174
- declarationCandidateType === "TSTypeAliasDeclaration") {
175
- const declarationName = readStringProperty(declarationCandidateRecord["id"], "name");
176
- if (declarationName !== void 0) {
177
- declarationNames.set(declarationName, {
178
- kind: declarationCandidateType === "TSInterfaceDeclaration" ||
179
- declarationCandidateType === "TSTypeAliasDeclaration"
180
- ? "type"
181
- : "value",
182
- node: statement,
183
- });
184
- }
185
- continue;
186
- }
187
- if (declarationCandidateType !== "VariableDeclaration") {
188
- continue;
189
- }
190
- const declarations = readArrayProperty(declarationCandidateRecord, "declarations");
191
- if (declarations === void 0) {
192
- continue;
193
- }
194
- for (const declaration of declarations) {
195
- const declarationRecord = asRecord(declaration);
196
- if (declarationRecord === void 0) {
197
- continue;
198
- }
199
- for (const name of collectPatternIdentifierNames(declarationRecord["id"])) {
200
- declarationNames.set(name, { kind: "value", node: statement });
201
- }
202
- }
203
- }
204
- return declarationNames;
205
- };
27
+ const collectCrossFileUsages = (program, sourceFilename, state, repoRoot, exportedElement) => collectCrossFileUsagesFromUsages(program, sourceFilename, state, repoRoot, exportedElement);
206
28
  /**
207
29
  * Collects exported elements from one program body.
208
30
  * @param body Program body statements.
@@ -212,401 +34,16 @@ const collectLocalDeclarationNames = (body) => {
212
34
  * const exported = collectExportedElements(program.body);
213
35
  * ```
214
36
  */
215
- const collectExportedElements = (body) => {
216
- const exportedElements = [];
217
- const localDeclarationNames = collectLocalDeclarationNames(body);
218
- for (const statement of body) {
219
- if (statement.type === "ExportDefaultDeclaration") {
220
- exportedElements.push({
221
- exportedName: "default",
222
- exportKind: "value",
223
- node: statement,
224
- });
225
- continue;
226
- }
227
- if (statement.type !== "ExportNamedDeclaration") {
228
- continue;
229
- }
230
- if (statement.source !== null && statement.source !== void 0) {
231
- continue;
232
- }
233
- if (statement.declaration !== null && statement.declaration !== void 0) {
234
- const declaration = asRecord(statement.declaration);
235
- if (readStringProperty(declaration, "type") === "VariableDeclaration") {
236
- for (const variable of readArrayProperty(declaration, "declarations") ??
237
- []) {
238
- for (const name of collectPatternIdentifierNames(asRecord(variable)?.["id"])) {
239
- exportedElements.push({
240
- exportedName: name,
241
- exportKind: "value",
242
- node: statement,
243
- });
244
- }
245
- }
246
- }
247
- else {
248
- const declarationName = readStringProperty(declaration?.["id"], "name");
249
- const declarationType = readStringProperty(declaration, "type");
250
- const exportKind = declarationType === "TSInterfaceDeclaration" ||
251
- declarationType === "TSTypeAliasDeclaration"
252
- ? "type"
253
- : "value";
254
- if (typeof declarationName === "string") {
255
- exportedElements.push({
256
- exportedName: declarationName,
257
- exportKind,
258
- node: statement,
259
- });
260
- }
261
- }
262
- continue;
263
- }
264
- for (const specifier of statement.specifiers) {
265
- const localName = getExportSpecifierLocalName(specifier);
266
- const localDeclaration = localName === void 0 ? void 0 : localDeclarationNames.get(localName);
267
- if (localDeclaration === void 0) {
268
- continue;
269
- }
270
- const exportedName = getExportSpecifierName(specifier);
271
- if (exportedName !== void 0) {
272
- const statementExportKind = readStringProperty(statement, "exportKind");
273
- const specifierExportKind = readStringProperty(specifier, "exportKind");
274
- const isTypeOnlyExport = statementExportKind === "type" || specifierExportKind === "type";
275
- exportedElements.push({
276
- exportedName,
277
- exportKind: isTypeOnlyExport ? "type" : localDeclaration.kind,
278
- node: localDeclaration.node,
279
- });
280
- }
281
- }
282
- }
283
- return exportedElements;
284
- };
285
- /**
286
- * Resolves one symbol to its canonical target.
287
- * @param symbol Candidate symbol.
288
- * @param checker TypeScript checker.
289
- * @returns Resolved canonical symbol.
290
- * @example
291
- * ```typescript
292
- * const resolved = resolveCanonicalSymbol(symbol, checker);
293
- * ```
294
- */
295
- const resolveCanonicalSymbol = (symbol, checker) => {
296
- if ((symbol.flags & ts.SymbolFlags.Alias) === 0) {
297
- return symbol;
298
- }
299
- try {
300
- return checker.getAliasedSymbol(symbol);
301
- }
302
- catch {
303
- return symbol;
304
- }
305
- };
37
+ const collectExportedElements = (body) => collectExportedElementsFromDeclarations(body);
306
38
  /**
307
- * Builds declaration-site keys for symbol identity matching.
308
- * @param symbol Symbol being compared.
309
- * @returns Declaration keys describing where this symbol is declared.
310
- * @example
311
- * ```typescript
312
- * const keys = getDeclarationKeys(symbol);
313
- * ```
314
- */
315
- const getDeclarationKeys = (symbol) => {
316
- const declarations = symbol.declarations ?? [];
317
- return new Set(declarations.map((declaration) => {
318
- const sourceFilename = declaration.getSourceFile().fileName;
319
- return `${sourceFilename}:${String(declaration.pos)}:${String(declaration.end)}`;
320
- }));
321
- };
322
- /**
323
- * Checks whether two symbols reference the same declaration site.
324
- * @param left Left-hand symbol candidate.
325
- * @param right Right-hand symbol candidate.
326
- * @returns True when both symbols identify the same declaration.
327
- * @example
328
- * ```typescript
329
- * const same = isSameSymbol(left, right);
330
- * ```
331
- */
332
- const isSameSymbol = (left, right) => {
333
- if (left === right) {
334
- return true;
335
- }
336
- const leftKeys = getDeclarationKeys(left);
337
- const rightKeys = getDeclarationKeys(right);
338
- for (const key of leftKeys) {
339
- if (rightKeys.has(key)) {
340
- return true;
341
- }
342
- }
343
- return false;
344
- };
345
- /**
346
- * Resolves one exported symbol by name from a source file.
347
- * @param program TypeScript program.
348
- * @param sourceFilename Source file path.
349
- * @param exportedName Public name exposed by the module export list.
350
- * @returns Symbol when found.
351
- * @example
352
- * ```typescript
353
- * const symbol = getExportedSymbol(program, sourceFilename, "feature");
354
- * ```
355
- */
356
- const getExportedSymbol = (program, sourceFilename, exportedName) => {
357
- const checker = program.getTypeChecker();
358
- const sourceFile = program
359
- .getSourceFiles()
360
- .find((file) => toComparableAbsolutePath(file.fileName) ===
361
- toComparableAbsolutePath(sourceFilename));
362
- if (sourceFile === void 0) {
363
- return void 0;
364
- }
365
- const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
366
- if (moduleSymbol === void 0) {
367
- return void 0;
368
- }
369
- const exportedSymbol = checker
370
- .getExportsOfModule(moduleSymbol)
371
- .find((symbol) => symbol.getName() === exportedName);
372
- if (exportedSymbol === void 0) {
373
- return void 0;
374
- }
375
- return resolveCanonicalSymbol(exportedSymbol, checker);
376
- };
377
- /**
378
- * Checks whether one source file exports the target symbol.
379
- * @param sourceFile Source file that may expose the symbol.
380
- * @param checker TypeScript checker.
381
- * @param targetSymbol Symbol being classified.
382
- * @returns True when one module export resolves to the target symbol.
383
- * @example
384
- * ```typescript
385
- * const exposed = sourceFileExportsSymbol(sourceFile, checker, targetSymbol);
386
- * ```
387
- */
388
- const sourceFileExportsSymbol = (sourceFile, checker, targetSymbol) => {
389
- const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
390
- if (moduleSymbol === void 0) {
391
- return false;
392
- }
393
- for (const exportedSymbol of checker.getExportsOfModule(moduleSymbol)) {
394
- const resolvedSymbol = resolveCanonicalSymbol(exportedSymbol, checker);
395
- if (isSameSymbol(resolvedSymbol, targetSymbol)) {
396
- return true;
397
- }
398
- }
399
- return false;
400
- };
401
- /**
402
- * Checks whether an identifier participates in one declaration/import/export site.
403
- * @param identifier Identifier node to evaluate.
404
- * @returns True when the identifier is declaration-only syntax.
405
- * @example
406
- * ```typescript
407
- * const declaration = isDeclarationOnlyIdentifier(identifier);
408
- * ```
409
- */
410
- const isDeclarationOnlyIdentifier = (identifier) => {
411
- const parent = identifier.parent;
412
- return (ts.isImportSpecifier(parent) ||
413
- ts.isImportClause(parent) ||
414
- ts.isNamespaceImport(parent) ||
415
- ts.isImportEqualsDeclaration(parent) ||
416
- ts.isExportSpecifier(parent) ||
417
- ts.isTypeAliasDeclaration(parent) ||
418
- ts.isInterfaceDeclaration(parent) ||
419
- ts.isTypeParameterDeclaration(parent) ||
420
- (ts.isVariableDeclaration(parent) && parent.name === identifier) ||
421
- (ts.isFunctionDeclaration(parent) && parent.name === identifier) ||
422
- (ts.isClassDeclaration(parent) && parent.name === identifier) ||
423
- (ts.isParameter(parent) && parent.name === identifier));
424
- };
425
- /**
426
- * Checks whether one identifier node appears under a type node.
427
- * @param identifier Candidate identifier.
428
- * @returns True when the identifier is inside type-only syntax.
429
- * @example
430
- * ```typescript
431
- * const typePosition = isTypePositionIdentifier(identifier);
432
- * ```
433
- */
434
- const isTypePositionIdentifier = (identifier) => {
435
- const visitNode = (current) => {
436
- if (ts.isTypeQueryNode(current)) {
437
- return false;
438
- }
439
- if (ts.isTypeNode(current)) {
440
- return true;
441
- }
442
- if (ts.isExpressionStatement(current) ||
443
- ts.isCallExpression(current) ||
444
- ts.isPropertyAccessExpression(current) ||
445
- ts.isElementAccessExpression(current) ||
446
- ts.isVariableDeclaration(current) ||
447
- ts.isReturnStatement(current)) {
448
- return false;
449
- }
450
- if (ts.isSourceFile(current)) {
451
- return false;
452
- }
453
- return visitNode(current.parent);
454
- };
455
- return visitNode(identifier);
456
- };
457
- /**
458
- * Checks whether one identifier is one concrete usage candidate for the export kind.
459
- * @param identifier Identifier node.
460
- * @param exportKind Whether type-only or value usage is required.
461
- * @returns True when the identifier can satisfy usage.
462
- * @example
463
- * ```typescript
464
- * const concrete = isConcreteUsageIdentifier(identifier, "value");
465
- * ```
466
- */
467
- const isConcreteUsageIdentifier = (identifier, exportKind) => {
468
- if (isDeclarationOnlyIdentifier(identifier)) {
469
- return false;
470
- }
471
- const inTypePosition = isTypePositionIdentifier(identifier);
472
- return exportKind === "type" ? inTypePosition : !inTypePosition;
473
- };
474
- /**
475
- * Appends concrete usages from one source file into the accumulator.
476
- * @param sourceFile Source file to scan.
477
- * @param checker TypeScript checker.
478
- * @param targetSymbol Export symbol being classified.
479
- * @param exportedElement Export metadata.
480
- * @param consumerIsTestFile Whether source file is a test file.
481
- * @param usages Mutable usage accumulator.
482
- * @example
483
- * ```typescript
484
- * collectConcreteUsagesFromSourceFile(sourceFile, checker, targetSymbolKey, exportedElement, false, usages);
485
- * ```
486
- */
487
- const collectConcreteUsagesFromSourceFile = (sourceFile, checker, targetSymbol, exportedElement, consumerIsTestFile, usages) => {
488
- const visitNode = (node) => {
489
- if (!ts.isIdentifier(node)) {
490
- ts.forEachChild(node, visitNode);
491
- return;
492
- }
493
- if (!isConcreteUsageIdentifier(node, exportedElement.exportKind)) {
494
- ts.forEachChild(node, visitNode);
495
- return;
496
- }
497
- const isShorthandName = ts.isShorthandPropertyAssignment(node.parent) &&
498
- node.parent.name === node;
499
- const candidateSymbol = isShorthandName
500
- ? checker.getShorthandAssignmentValueSymbol(node.parent)
501
- : checker.getSymbolAtLocation(node);
502
- if (candidateSymbol === void 0) {
503
- ts.forEachChild(node, visitNode);
504
- return;
505
- }
506
- const resolvedSymbol = resolveCanonicalSymbol(candidateSymbol, checker);
507
- if (!isSameSymbol(resolvedSymbol, targetSymbol)) {
508
- ts.forEachChild(node, visitNode);
509
- return;
510
- }
511
- usages.push({ isTestFile: consumerIsTestFile });
512
- ts.forEachChild(node, visitNode);
513
- };
514
- visitNode(sourceFile);
515
- };
516
- /**
517
- * Collects public API exposure usages for one exported symbol.
518
- * @param program TypeScript program.
519
- * @param sourceFilename Source filename where export is defined.
520
- * @param state Normalized rule options.
521
- * @param repoRoot Absolute repository root used for file classification.
522
- * @param targetSymbol Export symbol being classified.
523
- * @returns Public API exposure usages for the exported symbol.
524
- * @example
525
- * ```typescript
526
- * const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
527
- * ```
528
- */
529
- const collectPublicApiExposureUsages = (program, sourceFilename, state, repoRoot, targetSymbol) => {
530
- const checker = program.getTypeChecker();
531
- const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
532
- const normalizedRepoRoot = path.resolve(repoRoot);
533
- const usages = [];
534
- for (const sourceFile of program.getSourceFiles()) {
535
- if (sourceFile.isDeclarationFile) {
536
- continue;
537
- }
538
- const publicApiFilename = path.resolve(sourceFile.fileName);
539
- const normalizedPublicApiFilename = toComparableAbsolutePath(publicApiFilename);
540
- if (normalizedPublicApiFilename === normalizedSourceFilename) {
541
- continue;
542
- }
543
- if (!isPublicApiFile(publicApiFilename, state, normalizedRepoRoot)) {
544
- continue;
545
- }
546
- if (!sourceFileExportsSymbol(sourceFile, checker, targetSymbol)) {
547
- continue;
548
- }
549
- usages.push({
550
- isTestFile: isTestFile(publicApiFilename, state, normalizedRepoRoot),
551
- });
552
- }
553
- return usages;
554
- };
555
- /**
556
- * Collects concrete usages of one exported element across the program.
557
- * @param program TypeScript program.
558
- * @param sourceFilename Source filename where export is defined.
559
- * @param state Normalized rule options.
560
- * @param repoRoot Absolute repository root used for test-file classification.
561
- * @param exportedElement Exported element to classify.
562
- * @returns Concrete usages for the exported element.
563
- * @example
564
- * ```typescript
565
- * const usages = collectCrossFileUsages(program, "/repo/src/feature.ts", state, "/repo", exportedElement);
566
- * ```
567
- */
568
- const collectCrossFileUsages = (program, sourceFilename, state, repoRoot, exportedElement) => {
569
- const checker = program.getTypeChecker();
570
- const targetSymbol = getExportedSymbol(program, sourceFilename, exportedElement.exportedName);
571
- if (targetSymbol === void 0) {
572
- return [];
573
- }
574
- const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
575
- const normalizedRepoRoot = path.resolve(repoRoot);
576
- const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
577
- for (const sourceFile of program.getSourceFiles()) {
578
- if (sourceFile.isDeclarationFile) {
579
- continue;
580
- }
581
- const consumerFilename = path.resolve(sourceFile.fileName);
582
- const normalizedConsumerFilename = toComparableAbsolutePath(consumerFilename);
583
- if (normalizedConsumerFilename === normalizedSourceFilename) {
584
- continue;
585
- }
586
- const consumerIsTestFile = isTestFile(consumerFilename, state, normalizedRepoRoot);
587
- collectConcreteUsagesFromSourceFile(sourceFile, checker, targetSymbol, exportedElement, consumerIsTestFile, usages);
588
- }
589
- return usages;
590
- };
591
- /**
592
- * Classifies one exported name based on cross-file usages.
593
- * @param usages Collected usages.
594
- * @returns Classification label.
39
+ * Resolves TypeScript parser services program when available.
40
+ * @param context Rule context.
41
+ * @returns TypeScript program when available.
595
42
  * @example
596
43
  * ```typescript
597
- * const classification = classifyExportUsage("feature", usages);
44
+ * const program = getTypeScriptProgram(context);
598
45
  * ```
599
46
  */
600
- const classifyExportUsage = (usages) => {
601
- if (usages.length === 0) {
602
- return "unused";
603
- }
604
- for (const usage of usages) {
605
- if (!usage.isTestFile) {
606
- return "production";
607
- }
608
- }
609
- return "test-only";
610
- };
47
+ const getTypeScriptProgram = (context) => getTypeScriptProgramFromServices(context);
611
48
  export { classifyExportUsage, collectCrossFileUsages, collectExportedElements, getTypeScriptProgram, };
612
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLWV4cG9ydHMvbm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RCxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFTakMsT0FBTyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQVcxRTs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxTQUFpQixFQUFVLEVBQUU7SUFDN0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFFN0QsT0FBTyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQWMsRUFBdUMsRUFBRSxDQUN2RSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7SUFDekMsQ0FBQyxDQUFFLEtBQWlDO0lBQ3BDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUViOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sa0JBQWtCLEdBQUcsQ0FDekIsS0FBYyxFQUNkLEdBQVcsRUFDUyxFQUFFO0lBQ3RCLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixNQUFNLFFBQVEsR0FBRyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMvQixPQUFPLE9BQU8sUUFBUSxLQUFLLFFB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O0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUMxQixNQUFxQixFQUNrQixFQUFFO0lBQ3pDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN4QixPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sWUFBWSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDO0FBRUYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixzQkFBc0IsRUFDdEIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixHQUNyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBU1QsIFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5cbmltcG9ydCB7IEVTTGludFV0aWxzIH0gZnJvbSBcIkB0eXBlc2NyaXB0LWVzbGludC91dGlsc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuaW1wb3J0IHR5cGUge1xuICBFeHBvcnRlZEVsZW1lbnQsXG4gIEV4cG9ydEtpbmQsXG4gIEV4cG9ydFVzYWdlLFxuICBOb1VudXNlZEV4cG9ydHNTdGF0ZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuaW1wb3J0IHsgaXNQdWJsaWNBcGlGaWxlLCBpc1Rlc3RGaWxlIH0gZnJvbSBcIi4vbm8tdW51c2VkLWV4cG9ydHMtb3B0aW9uc1wiO1xuXG4vKiogTG9jYWwgdG9wLWxldmVsIGRlY2xhcmF0aW9uIGRpc2NvdmVyZWQgd2hlbiBjb2xsZWN0aW5nIGV4cG9ydCBzb3VyY2VzLiAqL1xuaW50ZXJmYWNlIExvY2FsRGVjbGFyYXRpb24ge1xuICAvKiogRXhwb3J0IGtpbmQgaW1wbGllZCBieSB0aGUgZGVjbGFyYXRpb24uICovXG4gIGtpbmQ6IEV4cG9ydEtpbmQ7XG5cbiAgLyoqIERlY2xhcmF0aW9uIHN0YXRlbWVudCB1c2VkIGZvciBkaWFnbm9zdGljcy4gKi9cbiAgbm9kZTogQVNULlByb2dyYW1bXCJib2R5XCJdW251bWJlcl07XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhbiBhYnNvbHV0ZSBmaWxlIHBhdGggZm9yIHNhZmUgZXF1YWxpdHkgY2hlY2tzLlxuICogQHBhcmFtIGlucHV0UGF0aCBDYW5kaWRhdGUgcGF0aC5cbiAqIEByZXR1cm5zIE5vcm1hbGl6ZWQgYWJzb2x1dGUgcGF0aCBzdWl0YWJsZSBmb3IgY3Jvc3MtcGxhdGZvcm0gY29tcGFyaXNvbnMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY29tcGFyYWJsZSA9IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChcIi9yZXBvL3NyYy9mZWF0dXJlLnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aCA9IChpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKHBhdGgucmVzb2x2ZShpbnB1dFBhdGgpKTtcblxuICByZXR1cm4gYWJzb2x1dGVQYXRoLnRvTG93ZXJDYXNlKCk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIG9uZSB1bmtub3duIHZhbHVlIGludG8gYW4gaW5kZXhhYmxlIHJlY29yZC5cbiAqIEBwYXJhbSB2YWx1ZSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyBSZWNvcmQgdmlldyB3aGVuIHRoZSB2YWx1ZSBpcyBvYmplY3QtbGlrZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh7IHR5cGU6IFwiSWRlbnRpZmllclwiIH0pO1xuICogYGBgXG4gKi9cbmNvbnN0IGFzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQgPT5cbiAgdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiXG4gICAgPyAodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pXG4gICAgOiB2b2lkIDA7XG5cbi8qKlxuICogUmVhZHMgb25lIHN0cmluZyBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIFN0cmluZyB2YWx1ZSB3aGVuIHByZXNlbnQuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eSh7IG5hbWU6IFwiZmVhdHVyZVwiIH0sIFwibmFtZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCByZWFkU3RyaW5nUHJvcGVydHkgPSAoXG4gIHZhbHVlOiB1bmtub3duLFxuICBrZXk6IHN0cmluZyxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHJlY29yZCA9IGFzUmVjb3JkKHZhbHVlKTtcbiAgY29uc3QgcHJvcGVydHkgPSByZWNvcmQ/LltrZXldO1xuICByZXR1cm4gdHlwZW9mIHByb3BlcnR5ID09PSBcInN0cmluZ1wiID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBhcnJheSBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIEFycmF5IHZhbHVlIHdoZW4gcHJlc2VudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBpdGVtcyA9IHJlYWRBcnJheVByb3BlcnR5KHsgZWxlbWVudHM6IFsxLCAyXSB9LCBcImVsZW1lbnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHJlYWRBcnJheVByb3BlcnR5ID0gKFxuICB2YWx1ZTogdW5rbm93bixcbiAga2V5OiBzdHJpbmcsXG4pOiB1bmRlZmluZWQgfCB1bmtub3duW10gPT4ge1xuICBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh2YWx1ZSk7XG4gIGNvbnN0IHByb3BlcnR5ID0gcmVjb3JkPy5ba2V5XTtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkocHJvcGVydHkpID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlc29sdmVzIFR5cGVTY3JpcHQgcGFyc2VyIHNlcnZpY2VzIHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAcGFyYW0gY29udGV4dCBSdWxlIGNvbnRleHQuXG4gKiBAcmV0dXJucyBUeXBlU2NyaXB0IHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcHJvZ3JhbSA9IGdldFR5cGVTY3JpcHRQcm9ncmFtKGNvbnRleHQpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldFR5cGVTY3JpcHRQcm9ncmFtID0gKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuKTogdHMuUHJvZ3JhbSB8IHVuZGVmaW5lZCA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2VydmljZXMgPSBFU0xpbnRVdGlscy5nZXRQYXJzZXJTZXJ2aWNlcyhjb250ZXh0IGFzIG5ldmVyKTtcbiAgICByZXR1cm4gc2VydmljZXMucHJvZ3JhbTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBpZGVudGlmaWVyIG5hbWVzIGZyb20gb25lIHZhcmlhYmxlIHBhdHRlcm4uXG4gKiBAcGFyYW0gbm9kZSBWYXJpYWJsZSBwYXR0ZXJuIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIElkZW50aWZpZXIgbmFtZXMgZGVjbGFyZWQgYnkgdGhlIHBhdHRlcm4uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZXMgPSBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhwYXR0ZXJuKTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyA9IChub2RlOiB1bmtub3duKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBwYXR0ZXJuID0gYXNSZWNvcmQobm9kZSk7XG5cbiAgaWYgKHBhdHRlcm4gPT09IHZvaWQgMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHBhdHRlcm5UeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KHBhdHRlcm4sIFwidHlwZVwiKTtcblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eShwYXR0ZXJuLCBcIm5hbWVcIik7XG4gICAgcmV0dXJuIG5hbWUgPT09IHZvaWQgMCA/IFtdIDogW25hbWVdO1xuICB9XG5cbiAgaWYgKHBhdHRlcm5UeXBlID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMocGF0dGVybltcImFyZ3VtZW50XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBc3NpZ25tZW50UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKHBhdHRlcm5bXCJsZWZ0XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBcnJheVBhdHRlcm5cIikge1xuICAgIHJldHVybiAocmVhZEFycmF5UHJvcGVydHkocGF0dGVybiwgXCJlbGVtZW50c1wiKSA/PyBbXSkuZmxhdE1hcCgoZWxlbWVudCkgPT5cbiAgICAgIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKGVsZW1lbnQpLFxuICAgICk7XG4gIH1cblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiT2JqZWN0UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIChyZWFkQXJyYXlQcm9wZXJ0eShwYXR0ZXJuLCBcInByb3BlcnRpZXNcIikgPz8gW10pLmZsYXRNYXAoXG4gICAgICAocHJvcGVydHkpID0+IHtcbiAgICAgICAgaWYgKHJlYWRTdHJpbmdQcm9wZXJ0eShwcm9wZXJ0eSwgXCJ0eXBlXCIpID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoXG4gICAgICAgICAgICBhc1JlY29yZChwcm9wZXJ0eSk/LltcImFyZ3VtZW50XCJdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoYXNSZWNvcmQocHJvcGVydHkpPy5bXCJ2YWx1ZVwiXSk7XG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gW107XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBleHBvcnQgc3BlY2lmaWVyIG5hbWUuXG4gKiBAcGFyYW0gc3BlY2lmaWVyIEV4cG9ydCBzcGVjaWZpZXIgY2FuZGlkYXRlLlxuICogQHJldHVybnMgRXhwb3J0ZWQgbmFtZSB3aGVuIGF2YWlsYWJsZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBuYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTmFtZShzcGVjaWZpZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldEV4cG9ydFNwZWNpZmllck5hbWUgPSAoc3BlY2lmaWVyOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2FuZGlkYXRlID0gYXNSZWNvcmQoc3BlY2lmaWVyKTtcbiAgY29uc3QgZXhwb3J0ZWROYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGNhbmRpZGF0ZT8uW1wiZXhwb3J0ZWRcIl0sIFwibmFtZVwiKTtcblxuICBpZiAodHlwZW9mIGV4cG9ydGVkTmFtZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBleHBvcnRlZE5hbWU7XG4gIH1cblxuICBjb25zdCBsb2NhbE5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoY2FuZGlkYXRlPy5bXCJsb2NhbFwiXSwgXCJuYW1lXCIpO1xuXG4gIHJldHVybiB0eXBlb2YgbG9jYWxOYW1lID09PSBcInN0cmluZ1wiID8gbG9jYWxOYW1lIDogdm9pZCAwO1xufTtcblxuLyoqXG4gKiBSZWFkcyBvbmUgbG9jYWwgZXhwb3J0IHNwZWNpZmllciBuYW1lLlxuICogQHBhcmFtIHNwZWNpZmllciBFeHBvcnQgc3BlY2lmaWVyIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIExvY2FsIHNwZWNpZmllciBuYW1lIHdoZW4gYXZhaWxhYmxlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IG5hbWUgPSBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUoc3BlY2lmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUgPSAoXG4gIHNwZWNpZmllcjogdW5rbm93bixcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IGFzUmVjb3JkKHNwZWNpZmllcik7XG5cbiAgcmV0dXJuIHJlYWRTdHJpbmdQcm9wZXJ0eShjYW5kaWRhdGU/LltcImxvY2FsXCJdLCBcIm5hbWVcIik7XG59O1xuXG4vKipcbiAqIENvbGxlY3RzIHRvcC1sZXZlbCBkZWNsYXJhdGlvbiBuYW1lcyBvd25lZCBieSB0aGUgY3VycmVudCBtb2R1bGUuXG4gKiBAcGFyYW0gYm9keSBQcm9ncmFtIGJvZHkgc3RhdGVtZW50cy5cbiAqIEByZXR1cm5zIE1hcCBmcm9tIGxvY2FsbHkgZGVjbGFyZWQgbmFtZSB0byBpdHMgZGVjbGFyYXRpb24gbWV0YWRhdGEuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZGVjbGFyYXRpb25zID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhwcm9ncmFtLmJvZHkpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RMb2NhbERlY2xhcmF0aW9uTmFtZXMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IE1hcDxzdHJpbmcsIExvY2FsRGVjbGFyYXRpb24+ID0+IHtcbiAgY29uc3QgZGVjbGFyYXRpb25OYW1lcyA9IG5ldyBNYXA8c3RyaW5nLCBMb2NhbERlY2xhcmF0aW9uPigpO1xuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJvZHkpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbkNhbmRpZGF0ZSA9XG4gICAgICBzdGF0ZW1lbnQudHlwZSA9PT0gXCJFeHBvcnROYW1lZERlY2xhcmF0aW9uXCIgJiZcbiAgICAgIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gbnVsbCAmJlxuICAgICAgc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSB2b2lkIDBcbiAgICAgICAgPyBzdGF0ZW1lbnQuZGVjbGFyYXRpb25cbiAgICAgICAgOiBzdGF0ZW1lbnQ7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPSBhc1JlY29yZChkZWNsYXJhdGlvbkNhbmRpZGF0ZSk7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGUsXG4gICAgICBcInR5cGVcIixcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPT09IHZvaWQgMCB8fFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID09PSB2b2lkIDBcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJUU0VudW1EZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbk5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoXG4gICAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlUmVjb3JkW1wiaWRcIl0sXG4gICAgICAgIFwibmFtZVwiLFxuICAgICAgKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGRlY2xhcmF0aW9uTmFtZXMuc2V0KGRlY2xhcmF0aW9uTmFtZSwge1xuICAgICAgICAgIGtpbmQ6XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgICAgOiBcInZhbHVlXCIsXG4gICAgICAgICAgbm9kZTogc3RhdGVtZW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSAhPT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY2xhcmF0aW9ucyA9IHJlYWRBcnJheVByb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQsXG4gICAgICBcImRlY2xhcmF0aW9uc1wiLFxuICAgICk7XG5cbiAgICBpZiAoZGVjbGFyYXRpb25zID09PSB2b2lkIDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgZGVjbGFyYXRpb25zKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvblJlY29yZCA9IGFzUmVjb3JkKGRlY2xhcmF0aW9uKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uUmVjb3JkID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgZGVjbGFyYXRpb25SZWNvcmRbXCJpZFwiXSxcbiAgICAgICkpIHtcbiAgICAgICAgZGVjbGFyYXRpb25OYW1lcy5zZXQobmFtZSwgeyBraW5kOiBcInZhbHVlXCIsIG5vZGU6IHN0YXRlbWVudCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGVjbGFyYXRpb25OYW1lcztcbn07XG5cbi8qKlxuICogQ29sbGVjdHMgZXhwb3J0ZWQgZWxlbWVudHMgZnJvbSBvbmUgcHJvZ3JhbSBib2R5LlxuICogQHBhcmFtIGJvZHkgUHJvZ3JhbSBib2R5IHN0YXRlbWVudHMuXG4gKiBAcmV0dXJucyBFeHBvcnRlZCBlbGVtZW50cyBpbiBkZWNsYXJhdGlvbiBvcmRlci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBleHBvcnRlZCA9IGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzKHByb2dyYW0uYm9keSk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdEV4cG9ydGVkRWxlbWVudHMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IEV4cG9ydGVkRWxlbWVudFtdID0+IHtcbiAgY29uc3QgZXhwb3J0ZWRFbGVtZW50czogRXhwb3J0ZWRFbGVtZW50W10gPSBbXTtcbiAgY29uc3QgbG9jYWxEZWNsYXJhdGlvbk5hbWVzID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhib2R5KTtcblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBib2R5KSB7XG4gICAgaWYgKHN0YXRlbWVudC50eXBlID09PSBcIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvblwiKSB7XG4gICAgICBleHBvcnRlZEVsZW1lbnRzLnB1c2goe1xuICAgICAgICBleHBvcnRlZE5hbWU6IFwiZGVmYXVsdFwiLFxuICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC50eXBlICE9PSBcIkV4cG9ydE5hbWVkRGVjbGFyYXRpb25cIikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC5zb3VyY2UgIT09IG51bGwgJiYgc3RhdGVtZW50LnNvdXJjZSAhPT0gdm9pZCAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSBudWxsICYmIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gdm9pZCAwKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGFzUmVjb3JkKHN0YXRlbWVudC5kZWNsYXJhdGlvbik7XG5cbiAgICAgIGlmIChyZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKSA9PT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiByZWFkQXJyYXlQcm9wZXJ0eShkZWNsYXJhdGlvbiwgXCJkZWNsYXJhdGlvbnNcIikgPz9cbiAgICAgICAgICBbXSkge1xuICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgICAgIGFzUmVjb3JkKHZhcmlhYmxlKT8uW1wiaWRcIl0sXG4gICAgICAgICAgKSkge1xuICAgICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgZXhwb3J0ZWROYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZGVjbGFyYXRpb25OYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGRlY2xhcmF0aW9uPy5bXCJpZFwiXSwgXCJuYW1lXCIpO1xuICAgICAgICBjb25zdCBkZWNsYXJhdGlvblR5cGUgPSByZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKTtcbiAgICAgICAgY29uc3QgZXhwb3J0S2luZDogRXhwb3J0S2luZCA9XG4gICAgICAgICAgZGVjbGFyYXRpb25UeXBlID09PSBcIlRTSW50ZXJmYWNlRGVjbGFyYXRpb25cIiB8fFxuICAgICAgICAgIGRlY2xhcmF0aW9uVHlwZSA9PT0gXCJUU1R5cGVBbGlhc0RlY2xhcmF0aW9uXCJcbiAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgIDogXCJ2YWx1ZVwiO1xuXG4gICAgICAgIGlmICh0eXBlb2YgZGVjbGFyYXRpb25OYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIGV4cG9ydGVkTmFtZTogZGVjbGFyYXRpb25OYW1lLFxuICAgICAgICAgICAgZXhwb3J0S2luZCxcbiAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNwZWNpZmllciBvZiBzdGF0ZW1lbnQuc3BlY2lmaWVycykge1xuICAgICAgY29uc3QgbG9jYWxOYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTG9jYWxOYW1lKHNwZWNpZmllcik7XG4gICAgICBjb25zdCBsb2NhbERlY2xhcmF0aW9uID1cbiAgICAgICAgbG9jYWxOYW1lID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsb2NhbERlY2xhcmF0aW9uTmFtZXMuZ2V0KGxvY2FsTmFtZSk7XG5cbiAgICAgIGlmIChsb2NhbERlY2xhcmF0aW9uID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cG9ydGVkTmFtZSA9IGdldEV4cG9ydFNwZWNpZmllck5hbWUoc3BlY2lmaWVyKTtcblxuICAgICAgaWYgKGV4cG9ydGVkTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IHN0YXRlbWVudEV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3RhdGVtZW50LCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IHNwZWNpZmllckV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3BlY2lmaWVyLCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IGlzVHlwZU9ubHlFeHBvcnQgPVxuICAgICAgICAgIHN0YXRlbWVudEV4cG9ydEtpbmQgPT09IFwidHlwZVwiIHx8IHNwZWNpZmllckV4cG9ydEtpbmQgPT09IFwidHlwZVwiO1xuXG4gICAgICAgIGV4cG9ydGVkRWxlbWVudHMucHVzaCh7XG4gICAgICAgICAgZXhwb3J0ZWROYW1lLFxuICAgICAgICAgIGV4cG9ydEtpbmQ6IGlzVHlwZU9ubHlFeHBvcnQgPyBcInR5cGVcIiA6IGxvY2FsRGVjbGFyYXRpb24ua2luZCxcbiAgICAgICAgICBub2RlOiBsb2NhbERlY2xhcmF0aW9uLm5vZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHBvcnRlZEVsZW1lbnRzO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgc3ltYm9sIHRvIGl0cyBjYW5vbmljYWwgdGFyZ2V0LlxuICogQHBhcmFtIHN5bWJvbCBDYW5kaWRhdGUgc3ltYm9sLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHJldHVybnMgUmVzb2x2ZWQgY2Fub25pY2FsIHN5bWJvbC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVDYW5vbmljYWxTeW1ib2woc3ltYm9sLCBjaGVja2VyKTtcbiAqIGBgYFxuICovXG5jb25zdCByZXNvbHZlQ2Fub25pY2FsU3ltYm9sID0gKFxuICBzeW1ib2w6IHRzLlN5bWJvbCxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiB0cy5TeW1ib2wgPT4ge1xuICBpZiAoKHN5bWJvbC5mbGFncyAmIHRzLlN5bWJvbEZsYWdzLkFsaWFzKSA9PT0gMCkge1xuICAgIHJldHVybiBzeW1ib2w7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBjaGVja2VyLmdldEFsaWFzZWRTeW1ib2woc3ltYm9sKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHN5bWJvbDtcbiAgfVxufTtcblxuLyoqXG4gKiBCdWlsZHMgZGVjbGFyYXRpb24tc2l0ZSBrZXlzIGZvciBzeW1ib2wgaWRlbnRpdHkgbWF0Y2hpbmcuXG4gKiBAcGFyYW0gc3ltYm9sIFN5bWJvbCBiZWluZyBjb21wYXJlZC5cbiAqIEByZXR1cm5zIERlY2xhcmF0aW9uIGtleXMgZGVzY3JpYmluZyB3aGVyZSB0aGlzIHN5bWJvbCBpcyBkZWNsYXJlZC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBrZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKHN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RGVjbGFyYXRpb25LZXlzID0gKHN5bWJvbDogdHMuU3ltYm9sKTogU2V0PHN0cmluZz4gPT4ge1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBzeW1ib2wuZGVjbGFyYXRpb25zID8/IFtdO1xuXG4gIHJldHVybiBuZXcgU2V0KFxuICAgIGRlY2xhcmF0aW9ucy5tYXAoKGRlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VGaWxlbmFtZSA9IGRlY2xhcmF0aW9uLmdldFNvdXJjZUZpbGUoKS5maWxlTmFtZTtcbiAgICAgIHJldHVybiBgJHtzb3VyY2VGaWxlbmFtZX06JHtTdHJpbmcoZGVjbGFyYXRpb24ucG9zKX06JHtTdHJpbmcoZGVjbGFyYXRpb24uZW5kKX1gO1xuICAgIH0pLFxuICApO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0d28gc3ltYm9scyByZWZlcmVuY2UgdGhlIHNhbWUgZGVjbGFyYXRpb24gc2l0ZS5cbiAqIEBwYXJhbSBsZWZ0IExlZnQtaGFuZCBzeW1ib2wgY2FuZGlkYXRlLlxuICogQHBhcmFtIHJpZ2h0IFJpZ2h0LWhhbmQgc3ltYm9sIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiBib3RoIHN5bWJvbHMgaWRlbnRpZnkgdGhlIHNhbWUgZGVjbGFyYXRpb24uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc2FtZSA9IGlzU2FtZVN5bWJvbChsZWZ0LCByaWdodCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgaXNTYW1lU3ltYm9sID0gKGxlZnQ6IHRzLlN5bWJvbCwgcmlnaHQ6IHRzLlN5bWJvbCk6IGJvb2xlYW4gPT4ge1xuICBpZiAobGVmdCA9PT0gcmlnaHQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGNvbnN0IGxlZnRLZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKGxlZnQpO1xuICBjb25zdCByaWdodEtleXMgPSBnZXREZWNsYXJhdGlvbktleXMocmlnaHQpO1xuXG4gIGZvciAoY29uc3Qga2V5IG9mIGxlZnRLZXlzKSB7XG4gICAgaWYgKHJpZ2h0S2V5cy5oYXMoa2V5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgZXhwb3J0ZWQgc3ltYm9sIGJ5IG5hbWUgZnJvbSBhIHNvdXJjZSBmaWxlLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcGFyYW0gZXhwb3J0ZWROYW1lIFB1YmxpYyBuYW1lIGV4cG9zZWQgYnkgdGhlIG1vZHVsZSBleHBvcnQgbGlzdC5cbiAqIEByZXR1cm5zIFN5bWJvbCB3aGVuIGZvdW5kLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKHByb2dyYW0sIHNvdXJjZUZpbGVuYW1lLCBcImZlYXR1cmVcIik7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RXhwb3J0ZWRTeW1ib2wgPSAoXG4gIHByb2dyYW06IHRzLlByb2dyYW0sXG4gIHNvdXJjZUZpbGVuYW1lOiBzdHJpbmcsXG4gIGV4cG9ydGVkTmFtZTogc3RyaW5nLFxuKTogdHMuU3ltYm9sIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2hlY2tlciA9IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKTtcbiAgY29uc3Qgc291cmNlRmlsZSA9IHByb2dyYW1cbiAgICAuZ2V0U291cmNlRmlsZXMoKVxuICAgIC5maW5kKFxuICAgICAgKGZpbGUpID0+XG4gICAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChmaWxlLmZpbGVOYW1lKSA9PT1cbiAgICAgICAgdG9Db21wYXJhYmxlQWJzb2x1dGVQYXRoKHNvdXJjZUZpbGVuYW1lKSxcbiAgICApO1xuXG4gIGlmIChzb3VyY2VGaWxlID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG5cbiAgY29uc3QgbW9kdWxlU3ltYm9sID0gY2hlY2tlci5nZXRTeW1ib2xBdExvY2F0aW9uKHNvdXJjZUZpbGUpO1xuXG4gIGlmIChtb2R1bGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cblxuICBjb25zdCBleHBvcnRlZFN5bWJvbCA9IGNoZWNrZXJcbiAgICAuZ2V0RXhwb3J0c09mTW9kdWxlKG1vZHVsZVN5bWJvbClcbiAgICAuZmluZCgoc3ltYm9sKSA9PiBzeW1ib2wuZ2V0TmFtZSgpID09PSBleHBvcnRlZE5hbWUpO1xuXG4gIGlmIChleHBvcnRlZFN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgb25lIHNvdXJjZSBmaWxlIGV4cG9ydHMgdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0aGF0IG1heSBleHBvc2UgdGhlIHN5bWJvbC5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgY2hlY2tlci5cbiAqIEBwYXJhbSB0YXJnZXRTeW1ib2wgU3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gb25lIG1vZHVsZSBleHBvcnQgcmVzb2x2ZXMgdG8gdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZXhwb3NlZCA9IHNvdXJjZUZpbGVFeHBvcnRzU3ltYm9sKHNvdXJjZUZpbGUsIGNoZWNrZXIsIHRhcmdldFN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3Qgc291cmNlRmlsZUV4cG9ydHNTeW1ib2wgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBtb2R1bGVTeW1ib2wgPSBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24oc291cmNlRmlsZSk7XG5cbiAgaWYgKG1vZHVsZVN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yIChjb25zdCBleHBvcnRlZFN5bWJvbCBvZiBjaGVja2VyLmdldEV4cG9ydHNPZk1vZHVsZShtb2R1bGVTeW1ib2wpKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcblxuICAgIGlmIChpc1NhbWVTeW1ib2wocmVzb2x2ZWRTeW1ib2wsIHRhcmdldFN5bWJvbCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYW4gaWRlbnRpZmllciBwYXJ0aWNpcGF0ZXMgaW4gb25lIGRlY2xhcmF0aW9uL2ltcG9ydC9leHBvcnQgc2l0ZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIElkZW50aWZpZXIgbm9kZSB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBpcyBkZWNsYXJhdGlvbi1vbmx5IHN5bnRheC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBkZWNsYXJhdGlvbiA9IGlzRGVjbGFyYXRpb25Pbmx5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBwYXJlbnQgPSBpZGVudGlmaWVyLnBhcmVudDtcblxuICByZXR1cm4gKFxuICAgIHRzLmlzSW1wb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc0ltcG9ydENsYXVzZShwYXJlbnQpIHx8XG4gICAgdHMuaXNOYW1lc3BhY2VJbXBvcnQocGFyZW50KSB8fFxuICAgIHRzLmlzSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24ocGFyZW50KSB8fFxuICAgIHRzLmlzRXhwb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVBbGlhc0RlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc0ludGVyZmFjZURlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbihwYXJlbnQpIHx8XG4gICAgKHRzLmlzVmFyaWFibGVEZWNsYXJhdGlvbihwYXJlbnQpICYmIHBhcmVudC5uYW1lID09PSBpZGVudGlmaWVyKSB8fFxuICAgICh0cy5pc0Z1bmN0aW9uRGVjbGFyYXRpb24ocGFyZW50KSAmJiBwYXJlbnQubmFtZSA9PT0gaWRlbnRpZmllcikgfHxcbiAgICAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpIHx8XG4gICAgKHRzLmlzUGFyYW1ldGVyKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIG9uZSBpZGVudGlmaWVyIG5vZGUgYXBwZWFycyB1bmRlciBhIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIENhbmRpZGF0ZSBpZGVudGlmaWVyLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBpZGVudGlmaWVyIGlzIGluc2lkZSB0eXBlLW9ubHkgc3ludGF4LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc1R5cGVQb3NpdGlvbklkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCB2aXNpdE5vZGUgPSAoY3VycmVudDogdHMuTm9kZSk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0cy5pc1R5cGVRdWVyeU5vZGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodHMuaXNUeXBlTm9kZShjdXJyZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHMuaXNFeHByZXNzaW9uU3RhdGVtZW50KGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc0NhbGxFeHByZXNzaW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1Byb3BlcnR5QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNFbGVtZW50QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNWYXJpYWJsZURlY2xhcmF0aW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1JldHVyblN0YXRlbWVudChjdXJyZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0cy5pc1NvdXJjZUZpbGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmlzaXROb2RlKGN1cnJlbnQucGFyZW50KTtcbiAgfTtcblxuICByZXR1cm4gdmlzaXROb2RlKGlkZW50aWZpZXIpO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBvbmUgaWRlbnRpZmllciBpcyBvbmUgY29uY3JldGUgdXNhZ2UgY2FuZGlkYXRlIGZvciB0aGUgZXhwb3J0IGtpbmQuXG4gKiBAcGFyYW0gaWRlbnRpZmllciBJZGVudGlmaWVyIG5vZGUuXG4gKiBAcGFyYW0gZXhwb3J0S2luZCBXaGV0aGVyIHR5cGUtb25seSBvciB2YWx1ZSB1c2FnZSBpcyByZXF1aXJlZC5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBjYW4gc2F0aXNmeSB1c2FnZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBjb25jcmV0ZSA9IGlzQ29uY3JldGVVc2FnZUlkZW50aWZpZXIoaWRlbnRpZmllciwgXCJ2YWx1ZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0NvbmNyZXRlVXNhZ2VJZGVudGlmaWVyID0gKFxuICBpZGVudGlmaWVyOiB0cy5JZGVudGlmaWVyLFxuICBleHBvcnRLaW5kOiBFeHBvcnRLaW5kLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIoaWRlbnRpZmllcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBpblR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcblxuICByZXR1cm4gZXhwb3J0S2luZCA9PT0gXCJ0eXBlXCIgPyBpblR5cGVQb3NpdGlvbiA6ICFpblR5cGVQb3NpdGlvbjtcbn07XG5cbi8qKlxuICogQXBwZW5kcyBjb25jcmV0ZSB1c2FnZXMgZnJvbSBvbmUgc291cmNlIGZpbGUgaW50byB0aGUgYWNjdW11bGF0b3IuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0byBzY2FuLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHBhcmFtIHRhcmdldFN5bWJvbCBFeHBvcnQgc3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcGFyYW0gZXhwb3J0ZWRFbGVtZW50IEV4cG9ydCBtZXRhZGF0YS5cbiAqIEBwYXJhbSBjb25zdW1lcklzVGVzdEZpbGUgV2hldGhlciBzb3VyY2UgZmlsZSBpcyBhIHRlc3QgZmlsZS5cbiAqIEBwYXJhbSB1c2FnZXMgTXV0YWJsZSB1c2FnZSBhY2N1bXVsYXRvci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShzb3VyY2VGaWxlLCBjaGVja2VyLCB0YXJnZXRTeW1ib2xLZXksIGV4cG9ydGVkRWxlbWVudCwgZmFsc2UsIHVzYWdlcyk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdENvbmNyZXRlVXNhZ2VzRnJvbVNvdXJjZUZpbGUgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbiAgZXhwb3J0ZWRFbGVtZW50OiBFeHBvcnRlZEVsZW1lbnQsXG4gIGNvbnN1bWVySXNUZXN0RmlsZTogYm9vbGVhbixcbiAgdXNhZ2VzOiBFeHBvcnRVc2FnZVtdLFxuKTogdm9pZCA9PiB7XG4gIGNvbnN0IHZpc2l0Tm9kZSA9IChub2RlOiB0cy5Ob2RlKTogdm9pZCA9PiB7XG4gICAgaWYgKCF0cy5pc0lkZW50aWZpZXIobm9kZSkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaXNDb25jcmV0ZVVzYWdlSWRlbnRpZmllcihub2RlLCBleHBvcnRlZEVsZW1lbnQuZXhwb3J0S2luZCkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlzU2hvcnRoYW5kTmFtZSA9XG4gICAgICB0cy5pc1Nob3J0aGFuZFByb3BlcnR5QXNzaWdubWVudChub2RlLnBhcmVudCkgJiZcbiAgICAgIG5vZGUucGFyZW50Lm5hbWUgPT09IG5vZGU7XG5cbiAgICBjb25zdCBjYW5kaWRhdGVTeW1ib2wgPSBpc1Nob3J0aGFuZE5hbWVcbiAgICAgID8gY2hlY2tlci5nZXRTaG9ydGhhbmRBc3NpZ25tZW50VmFsdWVTeW1ib2wobm9kZS5wYXJlbnQpXG4gICAgICA6IGNoZWNrZXIuZ2V0U3ltYm9sQXRMb2NhdGlvbihub2RlKTtcblxuICAgIGlmIChjYW5kaWRhdGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGNhbmRpZGF0ZVN5bWJvbCwgY2hlY2tlcik7XG5cbiAgICBpZiAoIWlzU2FtZVN5bWJvbChyZXNvbHZlZFN5bWJvbCwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goeyBpc1Rlc3RGaWxlOiBjb25zdW1lcklzVGVzdEZpbGUgfSk7XG4gICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gIH07XG5cbiAgdmlzaXROb2RlKHNvdXJjZUZpbGUpO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBwdWJsaWMgQVBJIGV4cG9zdXJlIHVzYWdlcyBmb3Igb25lIGV4cG9ydGVkIHN5bWJvbC5cbiAqIEBwYXJhbSBwcm9ncmFtIFR5cGVTY3JpcHQgcHJvZ3JhbS5cbiAqIEBwYXJhbSBzb3VyY2VGaWxlbmFtZSBTb3VyY2UgZmlsZW5hbWUgd2hlcmUgZXhwb3J0IGlzIGRlZmluZWQuXG4gKiBAcGFyYW0gc3RhdGUgTm9ybWFsaXplZCBydWxlIG9wdGlvbnMuXG4gKiBAcGFyYW0gcmVwb1Jvb3QgQWJzb2x1dGUgcmVwb3NpdG9yeSByb290IHVzZWQgZm9yIGZpbGUgY2xhc3NpZmljYXRpb24uXG4gKiBAcGFyYW0gdGFyZ2V0U3ltYm9sIEV4cG9ydCBzeW1ib2wgYmVpbmcgY2xhc3NpZmllZC5cbiAqIEByZXR1cm5zIFB1YmxpYyBBUEkgZXhwb3N1cmUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgc3ltYm9sLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzYWdlcyA9IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyhwcm9ncmFtLCBzb3VyY2VGaWxlbmFtZSwgc3RhdGUsIHJlcG9Sb290LCB0YXJnZXRTeW1ib2wpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyA9IChcbiAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgc291cmNlRmlsZW5hbWU6IHN0cmluZyxcbiAgc3RhdGU6IE5vVW51c2VkRXhwb3J0c1N0YXRlLFxuICByZXBvUm9vdDogc3RyaW5nLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IEV4cG9ydFVzYWdlW10gPT4ge1xuICBjb25zdCBjaGVja2VyID0gcHJvZ3JhbS5nZXRUeXBlQ2hlY2tlcigpO1xuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHNvdXJjZUZpbGUgb2YgcHJvZ3JhbS5nZXRTb3VyY2VGaWxlcygpKSB7XG4gICAgaWYgKHNvdXJjZUZpbGUuaXNEZWNsYXJhdGlvbkZpbGUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHB1YmxpY0FwaUZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9XG4gICAgICB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgocHVibGljQXBpRmlsZW5hbWUpO1xuXG4gICAgaWYgKG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoIWlzUHVibGljQXBpRmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICghc291cmNlRmlsZUV4cG9ydHNTeW1ib2woc291cmNlRmlsZSwgY2hlY2tlciwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goe1xuICAgICAgaXNUZXN0RmlsZTogaXNUZXN0RmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCksXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBjb25jcmV0ZSB1c2FnZXMgb2Ygb25lIGV4cG9ydGVkIGVsZW1lbnQgYWNyb3NzIHRoZSBwcm9ncmFtLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlbmFtZSB3aGVyZSBleHBvcnQgaXMgZGVmaW5lZC5cbiAqIEBwYXJhbSBzdGF0ZSBOb3JtYWxpemVkIHJ1bGUgb3B0aW9ucy5cbiAqIEBwYXJhbSByZXBvUm9vdCBBYnNvbHV0ZSByZXBvc2l0b3J5IHJvb3QgdXNlZCBmb3IgdGVzdC1maWxlIGNsYXNzaWZpY2F0aW9uLlxuICogQHBhcmFtIGV4cG9ydGVkRWxlbWVudCBFeHBvcnRlZCBlbGVtZW50IHRvIGNsYXNzaWZ5LlxuICogQHJldHVybnMgQ29uY3JldGUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgZWxlbWVudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB1c2FnZXMgPSBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzKHByb2dyYW0sIFwiL3JlcG8vc3JjL2ZlYXR1cmUudHNcIiwgc3RhdGUsIFwiL3JlcG9cIiwgZXhwb3J0ZWRFbGVtZW50KTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzID0gKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBzb3VyY2VGaWxlbmFtZTogc3RyaW5nLFxuICBzdGF0ZTogTm9VbnVzZWRFeHBvcnRzU3RhdGUsXG4gIHJlcG9Sb290OiBzdHJpbmcsXG4gIGV4cG9ydGVkRWxlbWVudDogRXhwb3J0ZWRFbGVtZW50LFxuKTogRXhwb3J0VXNhZ2VbXSA9PiB7XG4gIGNvbnN0IGNoZWNrZXIgPSBwcm9ncmFtLmdldFR5cGVDaGVja2VyKCk7XG4gIGNvbnN0IHRhcmdldFN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKFxuICAgIHByb2dyYW0sXG4gICAgc291cmNlRmlsZW5hbWUsXG4gICAgZXhwb3J0ZWRFbGVtZW50LmV4cG9ydGVkTmFtZSxcbiAgKTtcblxuICBpZiAodGFyZ2V0U3ltYm9sID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBjb2xsZWN0UHVibGljQXBpRXhwb3N1cmVVc2FnZXMoXG4gICAgcHJvZ3JhbSxcbiAgICBzb3VyY2VGaWxlbmFtZSxcbiAgICBzdGF0ZSxcbiAgICByZXBvUm9vdCxcbiAgICB0YXJnZXRTeW1ib2wsXG4gICk7XG5cbiAgZm9yIChjb25zdCBzb3VyY2VGaWxlIG9mIHByb2dyYW0uZ2V0U291cmNlRmlsZXMoKSkge1xuICAgIGlmIChzb3VyY2VGaWxlLmlzRGVjbGFyYXRpb25GaWxlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lckZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRDb25zdW1lckZpbGVuYW1lID1cbiAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChjb25zdW1lckZpbGVuYW1lKTtcblxuICAgIGlmIChub3JtYWxpemVkQ29uc3VtZXJGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lcklzVGVzdEZpbGUgPSBpc1Rlc3RGaWxlKFxuICAgICAgY29uc3VtZXJGaWxlbmFtZSxcbiAgICAgIHN0YXRlLFxuICAgICAgbm9ybWFsaXplZFJlcG9Sb290LFxuICAgICk7XG5cbiAgICBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShcbiAgICAgIHNvdXJjZUZpbGUsXG4gICAgICBjaGVja2VyLFxuICAgICAgdGFyZ2V0U3ltYm9sLFxuICAgICAgZXhwb3J0ZWRFbGVtZW50LFxuICAgICAgY29uc3VtZXJJc1Rlc3RGaWxlLFxuICAgICAgdXNhZ2VzLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDbGFzc2lmaWVzIG9uZSBleHBvcnRlZCBuYW1lIGJhc2VkIG9uIGNyb3NzLWZpbGUgdXNhZ2VzLlxuICogQHBhcmFtIHVzYWdlcyBDb2xsZWN0ZWQgdXNhZ2VzLlxuICogQHJldHVybnMgQ2xhc3NpZmljYXRpb24gbGFiZWwuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xhc3NpZmljYXRpb24gPSBjbGFzc2lmeUV4cG9ydFVzYWdlKFwiZmVhdHVyZVwiLCB1c2FnZXMpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNsYXNzaWZ5RXhwb3J0VXNhZ2UgPSAoXG4gIHVzYWdlczogRXhwb3J0VXNhZ2VbXSxcbik6IFwicHJvZHVjdGlvblwiIHwgXCJ0ZXN0LW9ubHlcIiB8IFwidW51c2VkXCIgPT4ge1xuICBpZiAodXNhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBcInVudXNlZFwiO1xuICB9XG5cbiAgZm9yIChjb25zdCB1c2FnZSBvZiB1c2FnZXMpIHtcbiAgICBpZiAoIXVzYWdlLmlzVGVzdEZpbGUpIHtcbiAgICAgIHJldHVybiBcInByb2R1Y3Rpb25cIjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gXCJ0ZXN0LW9ubHlcIjtcbn07XG5cbmV4cG9ydCB7XG4gIGNsYXNzaWZ5RXhwb3J0VXNhZ2UsXG4gIGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXMsXG4gIGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzLFxuICBnZXRUeXBlU2NyaXB0UHJvZ3JhbSxcbn07XG4iXX0=
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLWV4cG9ydHMvbm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE9BQU8sRUFBRSx1QkFBdUIsSUFBSSx1Q0FBdUMsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQy9ILE9BQU8sRUFBRSxvQkFBb0IsSUFBSSxnQ0FBZ0MsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBQ3BILE9BQU8sRUFDTCxtQkFBbUIsSUFBSSw2QkFBNkIsRUFDcEQsc0JBQXNCLElBQUksZ0NBQWdDLEdBQzNELE1BQU0scUNBQXFDLENBQUM7QUFFN0M7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLG1CQUFtQixHQUFHLENBQzFCLE1BQXFCLEVBQ2tCLEVBQUUsQ0FDekMsNkJBQTZCLENBQUMsTUFBTSxDQUFDLENBQUM7QUFFeEM7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxzQkFBc0IsR0FBRyxDQUM3QixPQUFtQixFQUNuQixjQUFzQixFQUN0QixLQUEyQixFQUMzQixRQUFnQixFQUNoQixlQUFnQyxFQUNqQixFQUFFLENBQ2pCLGdDQUFnQyxDQUM5QixPQUFPLEVBQ1AsY0FBYyxFQUNkLEtBQUssRUFDTCxRQUFRLEVBQ1IsZUFBZSxDQUNoQixDQUFDO0FBRUo7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLHVCQUF1QixHQUFHLENBQzlCLElBQXlCLEVBQ04sRUFBRSxDQUFDLHVDQUF1QyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRXRFOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxvQkFBb0IsR0FBRyxDQUMzQixPQUF5QixFQUNELEVBQUUsQ0FBQyxnQ0FBZ0MsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUV2RSxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLHNCQUFzQixFQUN0Qix1QkFBdUIsRUFDdkIsb0JBQW9CLEdBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEFTVCwgUnVsZSB9IGZyb20gXCJlc2xpbnRcIjtcbmltcG9ydCB0eXBlICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuaW1wb3J0IHR5cGUge1xuICBFeHBvcnRlZEVsZW1lbnQsXG4gIEV4cG9ydFVzYWdlLFxuICBOb1VudXNlZEV4cG9ydHNTdGF0ZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuaW1wb3J0IHsgY29sbGVjdEV4cG9ydGVkRWxlbWVudHMgYXMgY29sbGVjdEV4cG9ydGVkRWxlbWVudHNGcm9tRGVjbGFyYXRpb25zIH0gZnJvbSBcIi4vbm8tdW51c2VkLWV4cG9ydHMtZGVjbGFyYXRpb24tdXRpbGl0aWVzXCI7XG5pbXBvcnQgeyBnZXRUeXBlU2NyaXB0UHJvZ3JhbSBhcyBnZXRUeXBlU2NyaXB0UHJvZ3JhbUZyb21TZXJ2aWNlcyB9IGZyb20gXCIuL25vLXVudXNlZC1leHBvcnRzLWlkZW50aWZpZXItdXRpbGl0aWVzXCI7XG5pbXBvcnQge1xuICBjbGFzc2lmeUV4cG9ydFVzYWdlIGFzIGNsYXNzaWZ5RXhwb3J0VXNhZ2VGcm9tVXNhZ2VzLFxuICBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzIGFzIGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXNGcm9tVXNhZ2VzLFxufSBmcm9tIFwiLi9uby11bnVzZWQtZXhwb3J0cy11c2FnZS11dGlsaXRpZXNcIjtcblxuLyoqXG4gKiBDbGFzc2lmaWVzIG9uZSBleHBvcnRlZCBuYW1lIGJhc2VkIG9uIGNyb3NzLWZpbGUgdXNhZ2VzLlxuICogQHBhcmFtIHVzYWdlcyBDb2xsZWN0ZWQgdXNhZ2VzLlxuICogQHJldHVybnMgQ2xhc3NpZmljYXRpb24gbGFiZWwuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xhc3NpZmljYXRpb24gPSBjbGFzc2lmeUV4cG9ydFVzYWdlKHVzYWdlcyk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY2xhc3NpZnlFeHBvcnRVc2FnZSA9IChcbiAgdXNhZ2VzOiBFeHBvcnRVc2FnZVtdLFxuKTogXCJwcm9kdWN0aW9uXCIgfCBcInRlc3Qtb25seVwiIHwgXCJ1bnVzZWRcIiA9PlxuICBjbGFzc2lmeUV4cG9ydFVzYWdlRnJvbVVzYWdlcyh1c2FnZXMpO1xuXG4vKipcbiAqIENvbGxlY3RzIGNvbmNyZXRlIHVzYWdlcyBvZiBvbmUgZXhwb3J0ZWQgZWxlbWVudCBhY3Jvc3MgdGhlIHByb2dyYW0uXG4gKiBAcGFyYW0gcHJvZ3JhbSBUeXBlU2NyaXB0IHByb2dyYW0uXG4gKiBAcGFyYW0gc291cmNlRmlsZW5hbWUgU291cmNlIGZpbGVuYW1lIHdoZXJlIGV4cG9ydCBpcyBkZWZpbmVkLlxuICogQHBhcmFtIHN0YXRlIE5vcm1hbGl6ZWQgcnVsZSBvcHRpb25zLlxuICogQHBhcmFtIHJlcG9Sb290IEFic29sdXRlIHJlcG9zaXRvcnkgcm9vdCB1c2VkIGZvciB0ZXN0LWZpbGUgY2xhc3NpZmljYXRpb24uXG4gKiBAcGFyYW0gZXhwb3J0ZWRFbGVtZW50IEV4cG9ydGVkIGVsZW1lbnQgdG8gY2xhc3NpZnkuXG4gKiBAcmV0dXJucyBDb25jcmV0ZSB1c2FnZXMgZm9yIHRoZSBleHBvcnRlZCBlbGVtZW50LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzYWdlcyA9IGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXMocHJvZ3JhbSwgXCIvcmVwby9zcmMvZmVhdHVyZS50c1wiLCBzdGF0ZSwgXCIvcmVwb1wiLCBleHBvcnRlZEVsZW1lbnQpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXMgPSAoXG4gIHByb2dyYW06IHRzLlByb2dyYW0sXG4gIHNvdXJjZUZpbGVuYW1lOiBzdHJpbmcsXG4gIHN0YXRlOiBOb1VudXNlZEV4cG9ydHNTdGF0ZSxcbiAgcmVwb1Jvb3Q6IHN0cmluZyxcbiAgZXhwb3J0ZWRFbGVtZW50OiBFeHBvcnRlZEVsZW1lbnQsXG4pOiBFeHBvcnRVc2FnZVtdID0+XG4gIGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXNGcm9tVXNhZ2VzKFxuICAgIHByb2dyYW0sXG4gICAgc291cmNlRmlsZW5hbWUsXG4gICAgc3RhdGUsXG4gICAgcmVwb1Jvb3QsXG4gICAgZXhwb3J0ZWRFbGVtZW50LFxuICApO1xuXG4vKipcbiAqIENvbGxlY3RzIGV4cG9ydGVkIGVsZW1lbnRzIGZyb20gb25lIHByb2dyYW0gYm9keS5cbiAqIEBwYXJhbSBib2R5IFByb2dyYW0gYm9keSBzdGF0ZW1lbnRzLlxuICogQHJldHVybnMgRXhwb3J0ZWQgZWxlbWVudHMgaW4gZGVjbGFyYXRpb24gb3JkZXIuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZXhwb3J0ZWQgPSBjb2xsZWN0RXhwb3J0ZWRFbGVtZW50cyhwcm9ncmFtLmJvZHkpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzID0gKFxuICBib2R5OiBBU1QuUHJvZ3JhbVtcImJvZHlcIl0sXG4pOiBFeHBvcnRlZEVsZW1lbnRbXSA9PiBjb2xsZWN0RXhwb3J0ZWRFbGVtZW50c0Zyb21EZWNsYXJhdGlvbnMoYm9keSk7XG5cbi8qKlxuICogUmVzb2x2ZXMgVHlwZVNjcmlwdCBwYXJzZXIgc2VydmljZXMgcHJvZ3JhbSB3aGVuIGF2YWlsYWJsZS5cbiAqIEBwYXJhbSBjb250ZXh0IFJ1bGUgY29udGV4dC5cbiAqIEByZXR1cm5zIFR5cGVTY3JpcHQgcHJvZ3JhbSB3aGVuIGF2YWlsYWJsZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBwcm9ncmFtID0gZ2V0VHlwZVNjcmlwdFByb2dyYW0oY29udGV4dCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0VHlwZVNjcmlwdFByb2dyYW0gPSAoXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsXG4pOiB0cy5Qcm9ncmFtIHwgdW5kZWZpbmVkID0+IGdldFR5cGVTY3JpcHRQcm9ncmFtRnJvbVNlcnZpY2VzKGNvbnRleHQpO1xuXG5leHBvcnQge1xuICBjbGFzc2lmeUV4cG9ydFVzYWdlLFxuICBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzLFxuICBjb2xsZWN0RXhwb3J0ZWRFbGVtZW50cyxcbiAgZ2V0VHlwZVNjcmlwdFByb2dyYW0sXG59O1xuIl19