UNPKG

41.2 kBJavaScriptView Raw
1import _ from 'lodash';
2import ts from 'typescript';
3import { heritage, modifier, overload, parametered } from './base';
4import * as declaration from './declaration';
5import * as node_ from './node';
6import * as reference from './reference';
7import * as symbol_ from './symbol';
8import * as type_ from './type_';
9import * as utils from './utils';
10export function isClassProperty(node) {
11 return ts.isPropertyDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node);
12}
13export function isClassInstanceProperty(node) {
14 return (isClassProperty(node) || ts.isParameterPropertyDeclaration(node, node.parent)) && !modifier.isStatic(node);
15}
16export function isClassInstanceMember(node) {
17 return (ts.isMethodDeclaration(node) || isClassInstanceProperty(node)) && !modifier.isStatic(node);
18}
19export function isClassStaticProperty(node) {
20 return (ts.isMethodDeclaration(node) || isClassProperty(node)) && modifier.isStatic(node);
21}
22export function isClassStaticMember(node) {
23 return (ts.isMethodDeclaration(node) || isClassProperty(node)) && modifier.isStatic(node);
24}
25export function isClassMember(node) {
26 return isClassInstanceMember(node) || isClassStaticMember(node);
27}
28export function getExtends(node) {
29 const extendsClause = heritage.getHeritageClauseByKind(node, ts.SyntaxKind.ExtendsKeyword);
30 if (extendsClause === undefined) {
31 return undefined;
32 }
33 const typeNodes = heritage.getTypeNodes(extendsClause);
34 return typeNodes.length === 0 ? undefined : typeNodes[0];
35}
36export function getExtendsOrThrow(node) {
37 return utils.throwIfNullOrUndefined(getExtends(node), 'extends expression');
38}
39export function getImplements(node) {
40 const implementsClause = heritage.getHeritageClauseByKind(node, ts.SyntaxKind.ImplementsKeyword);
41 if (implementsClause === undefined) {
42 return undefined;
43 }
44 return heritage.getTypeNodes(implementsClause);
45}
46export function getImplementsArray(node) {
47 return utils.getArray(getImplements(node));
48}
49export function getMembers(node) {
50 const members = [...node.members];
51 const implementationCtors = members.filter(ts.isConstructorDeclaration).filter((c) => overload.isImplementation(c));
52 for (const ctor of implementationCtors) {
53 let insertIndex = members.indexOf(ctor) + 1;
54 for (const param of parametered.getParameters(ctor)) {
55 if (ts.isParameterPropertyDeclaration(param, param.parent)) {
56 members.splice(insertIndex, 0, param);
57 insertIndex += 1;
58 }
59 }
60 }
61 return members.filter(isClassMember);
62}
63export function getConcreteMembers(node) {
64 return declaration.isAmbient(node)
65 ? []
66 : getMembers(node).filter((member) => {
67 if (ts.isMethodDeclaration(member)) {
68 return overload.isImplementation(member);
69 }
70 return true;
71 });
72}
73export function getInstanceProperties(node) {
74 return getMembers(node).filter(isClassInstanceProperty);
75}
76export function getInstanceMembers(node) {
77 return getMembers(node).filter(isClassInstanceMember);
78}
79export function getInstanceMethods(node) {
80 return getInstanceMembers(node).filter(ts.isMethodDeclaration);
81}
82export function getMethods(node) {
83 return getMembers(node).filter(ts.isMethodDeclaration);
84}
85export function getSetAccessors(node) {
86 return getMembers(node).filter(ts.isSetAccessor);
87}
88export function getInstanceMethod(node, name) {
89 return getInstanceMethods(node).find((method) => node_.getName(method) === name);
90}
91export function getConcreteInstanceProperties(node) {
92 return getConcreteMembers(node).filter(isClassInstanceProperty);
93}
94export function getConcreteInstanceMembers(node) {
95 return getConcreteMembers(node).filter(isClassInstanceMember);
96}
97export function getConcreteInstanceMethods(node) {
98 return getConcreteInstanceMembers(node).filter(ts.isMethodDeclaration);
99}
100export function getStaticProperties(node) {
101 return getMembers(node).filter(isClassStaticProperty);
102}
103export function getStaticMembers(node) {
104 return getMembers(node).filter(isClassStaticMember);
105}
106export function getConcreteStaticProperties(node) {
107 return getConcreteMembers(node).filter(isClassStaticProperty);
108}
109export function getConcreteStaticMembers(node) {
110 return getConcreteMembers(node).filter(isClassStaticMember);
111}
112export function getConcreteStaticMethods(node) {
113 return getConcreteStaticMembers(node).filter(ts.isMethodDeclaration);
114}
115export function getConstructors(node) {
116 return node.members.filter(ts.isConstructorDeclaration);
117}
118export function getConcreteConstructor(node) {
119 return getConstructors(node).find((ctor) => overload.isImplementation(ctor));
120}
121export function getFirstConcreteConstructor(typeChecker, node) {
122 const ctor = getConcreteConstructor(node);
123 if (ctor !== undefined) {
124 return ctor;
125 }
126 const baseClass = getBaseClass(typeChecker, node);
127 if (baseClass === undefined) {
128 return undefined;
129 }
130 return getFirstConcreteConstructor(typeChecker, baseClass);
131}
132function getDerivedClassesWorker(program, languageService, node, seen = new Set()) {
133 if (seen.has(node)) {
134 return [];
135 }
136 return reference
137 .findReferencesAsNodes(program, languageService, node)
138 .reduce((acc, ref) => {
139 const parent = node_.getParent(ref);
140 if (parent === undefined) {
141 return acc;
142 }
143 const clause = node_.getParent(parent);
144 if (clause === undefined || !ts.isHeritageClause(clause) || !heritage.isExtends(clause)) {
145 return acc;
146 }
147 const derived = node_.getFirstAncestorByKindOrThrow(clause, ts.SyntaxKind.ClassDeclaration);
148 return acc.concat(getDerivedClassesWorker(program, languageService, derived, seen));
149 }, [])
150 .concat([node]);
151}
152export function getDerivedClasses(program, languageService, node) {
153 const result = getDerivedClassesWorker(program, languageService, node);
154 return result.filter((value) => value !== node);
155}
156function getImplementorsWorker(program, languageService, node, seen = new Set()) {
157 if (seen.has(node)) {
158 return [];
159 }
160 return reference
161 .findReferencesAsNodes(program, languageService, node)
162 .reduce((acc, ref) => {
163 const parent = node_.getParent(ref);
164 if (parent === undefined) {
165 return acc;
166 }
167 const clause = node_.getParent(parent);
168 if (clause === undefined ||
169 !ts.isHeritageClause(clause) ||
170 (!heritage.isImplements(clause) && !heritage.isExtends(clause))) {
171 return acc;
172 }
173 let derived = node_.getFirstAncestorByKind(clause, ts.SyntaxKind.ClassDeclaration);
174 if (derived === undefined) {
175 derived = node_.getFirstAncestorByKindOrThrow(clause, ts.SyntaxKind.InterfaceDeclaration);
176 }
177 return acc.concat(getImplementorsWorker(program, languageService, derived, seen));
178 }, [])
179 .concat(ts.isClassDeclaration(node) ? [node] : []);
180}
181export function getImplementors(program, languageService, node) {
182 return getImplementorsWorker(program, languageService, node);
183}
184function getExtendorsWorker(program, languageService, node, seen = new Set()) {
185 if (seen.has(node)) {
186 return [];
187 }
188 return reference
189 .findReferencesAsNodes(program, languageService, node)
190 .reduce((acc, ref) => {
191 const parent = node_.getParent(ref);
192 if (parent === undefined) {
193 return acc;
194 }
195 const clause = node_.getParent(parent);
196 if (clause === undefined || !ts.isHeritageClause(clause) || !heritage.isExtends(clause)) {
197 return acc;
198 }
199 const derived = node_.getFirstAncestorByTestOrThrow(clause, ts.isClassDeclaration);
200 return acc.concat(getImplementorsWorker(program, languageService, derived, seen));
201 }, [])
202 .concat(ts.isClassDeclaration(node) ? [node] : []);
203}
204export function getExtendors(program, languageService, node) {
205 return getExtendorsWorker(program, languageService, node);
206}
207export function getBaseTypes(typeChecker, node) {
208 return type_.getBaseTypesArray(type_.getType(typeChecker, node));
209}
210export function getBaseTypesFlattened(typeChecker, node) {
211 function getBaseTypesWorker(type) {
212 if (type_.isIntersection(type)) {
213 return _.flatten(type_.getIntersectionTypesArray(type).map(getBaseTypesWorker));
214 }
215 const baseTypes = type_.getBaseTypesArray(type);
216 return [type].concat(_.flatten(baseTypes.map(getBaseTypesWorker)));
217 }
218 return _.flatten(getBaseTypes(typeChecker, node).map(getBaseTypesWorker));
219}
220export function getBaseClasses(typeChecker, node) {
221 const baseTypes = getBaseTypesFlattened(typeChecker, node);
222 return baseTypes
223 .map((type) => type_.getSymbol(type))
224 .filter(utils.notNull)
225 .map((symbol) => symbol_.getDeclarations(symbol))
226 .reduce((a, b) => a.concat(b), [])
227 .filter(ts.isClassDeclaration);
228}
229export function getBaseClass(typeChecker, node) {
230 const declarations = getBaseClasses(typeChecker, node);
231 return declarations.length === 1 ? declarations[0] : undefined;
232}
233
234//# sourceMappingURL=data:application/json;charset=utf8;base64,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IiwiZmlsZSI6Im5lby1vbmUtdHMtdXRpbHMvc3JjL2NsYXNzXy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgdHMgZnJvbSAndHlwZXNjcmlwdCc7XG5pbXBvcnQgeyBoZXJpdGFnZSwgbW9kaWZpZXIsIG92ZXJsb2FkLCBwYXJhbWV0ZXJlZCB9IGZyb20gJy4vYmFzZSc7XG5pbXBvcnQgKiBhcyBkZWNsYXJhdGlvbiBmcm9tICcuL2RlY2xhcmF0aW9uJztcbmltcG9ydCAqIGFzIG5vZGVfIGZyb20gJy4vbm9kZSc7XG5pbXBvcnQgKiBhcyByZWZlcmVuY2UgZnJvbSAnLi9yZWZlcmVuY2UnO1xuaW1wb3J0ICogYXMgc3ltYm9sXyBmcm9tICcuL3N5bWJvbCc7XG5pbXBvcnQgKiBhcyB0eXBlXyBmcm9tICcuL3R5cGVfJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgdHlwZSBDbGFzc1Byb3BlcnR5VHlwZSA9IHRzLlByb3BlcnR5RGVjbGFyYXRpb24gfCB0cy5HZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgdHMuU2V0QWNjZXNzb3JEZWNsYXJhdGlvbjtcbmV4cG9ydCBmdW5jdGlvbiBpc0NsYXNzUHJvcGVydHkobm9kZTogdHMuTm9kZSk6IG5vZGUgaXMgQ2xhc3NQcm9wZXJ0eVR5cGUge1xuICByZXR1cm4gdHMuaXNQcm9wZXJ0eURlY2xhcmF0aW9uKG5vZGUpIHx8IHRzLmlzR2V0QWNjZXNzb3JEZWNsYXJhdGlvbihub2RlKSB8fCB0cy5pc1NldEFjY2Vzc29yRGVjbGFyYXRpb24obm9kZSk7XG59XG5cbmV4cG9ydCB0eXBlIENsYXNzSW5zdGFuY2VQcm9wZXJ0eVR5cGUgPSBDbGFzc1Byb3BlcnR5VHlwZSB8IHRzLlBhcmFtZXRlclByb3BlcnR5RGVjbGFyYXRpb247XG5leHBvcnQgZnVuY3Rpb24gaXNDbGFzc0luc3RhbmNlUHJvcGVydHkobm9kZTogdHMuTm9kZSk6IG5vZGUgaXMgQ2xhc3NJbnN0YW5jZVByb3BlcnR5VHlwZSB7XG4gIHJldHVybiAoaXNDbGFzc1Byb3BlcnR5KG5vZGUpIHx8IHRzLmlzUGFyYW1ldGVyUHJvcGVydHlEZWNsYXJhdGlvbihub2RlLCBub2RlLnBhcmVudCkpICYmICFtb2RpZmllci5pc1N0YXRpYyhub2RlKTtcbn1cblxuZXhwb3J0IHR5cGUgQ2xhc3NJbnN0YW5jZU1lbWJlclR5cGUgPSB0cy5NZXRob2REZWNsYXJhdGlvbiB8IENsYXNzSW5zdGFuY2VQcm9wZXJ0eVR5cGU7XG5leHBvcnQgZnVuY3Rpb24gaXNDbGFzc0luc3RhbmNlTWVtYmVyKG5vZGU6IHRzLk5vZGUpOiBub2RlIGlzIENsYXNzSW5zdGFuY2VNZW1iZXJUeXBlIHtcbiAgcmV0dXJuICh0cy5pc01ldGhvZERlY2xhcmF0aW9uKG5vZGUpIHx8IGlzQ2xhc3NJbnN0YW5jZVByb3BlcnR5KG5vZGUpKSAmJiAhbW9kaWZpZXIuaXNTdGF0aWMobm9kZSk7XG59XG5cbmV4cG9ydCB0eXBlIENsYXNzU3RhdGljUHJvcGVydHlUeXBlID0gQ2xhc3NQcm9wZXJ0eVR5cGU7XG5leHBvcnQgZnVuY3Rpb24gaXNDbGFzc1N0YXRpY1Byb3BlcnR5KG5vZGU6IHRzLk5vZGUpOiBub2RlIGlzIENsYXNzU3RhdGljUHJvcGVydHlUeXBlIHtcbiAgcmV0dXJuICh0cy5pc01ldGhvZERlY2xhcmF0aW9uKG5vZGUpIHx8IGlzQ2xhc3NQcm9wZXJ0eShub2RlKSkgJiYgbW9kaWZpZXIuaXNTdGF0aWMobm9kZSk7XG59XG5cbmV4cG9ydCB0eXBlIENsYXNzU3RhdGljTWVtYmVyVHlwZSA9IHRzLk1ldGhvZERlY2xhcmF0aW9uIHwgQ2xhc3NTdGF0aWNQcm9wZXJ0eVR5cGU7XG5leHBvcnQgZnVuY3Rpb24gaXNDbGFzc1N0YXRpY01lbWJlcihub2RlOiB0cy5Ob2RlKTogbm9kZSBpcyBDbGFzc1N0YXRpY01lbWJlclR5cGUge1xuICByZXR1cm4gKHRzLmlzTWV0aG9kRGVjbGFyYXRpb24obm9kZSkgfHwgaXNDbGFzc1Byb3BlcnR5KG5vZGUpKSAmJiBtb2RpZmllci5pc1N0YXRpYyhub2RlKTtcbn1cblxuZXhwb3J0IHR5cGUgQ2xhc3NNZW1iZXJUeXBlID0gQ2xhc3NJbnN0YW5jZU1lbWJlclR5cGUgfCBDbGFzc1N0YXRpY01lbWJlclR5cGU7XG5leHBvcnQgZnVuY3Rpb24gaXNDbGFzc01lbWJlcihub2RlOiB0cy5Ob2RlKTogbm9kZSBpcyBDbGFzc01lbWJlclR5cGUge1xuICByZXR1cm4gaXNDbGFzc0luc3RhbmNlTWVtYmVyKG5vZGUpIHx8IGlzQ2xhc3NTdGF0aWNNZW1iZXIobm9kZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlbmRzKG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24pOiB0cy5FeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMgfCB1bmRlZmluZWQge1xuICBjb25zdCBleHRlbmRzQ2xhdXNlID0gaGVyaXRhZ2UuZ2V0SGVyaXRhZ2VDbGF1c2VCeUtpbmQobm9kZSwgdHMuU3ludGF4S2luZC5FeHRlbmRzS2V5d29yZCk7XG4gIGlmIChleHRlbmRzQ2xhdXNlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgdHlwZU5vZGVzID0gaGVyaXRhZ2UuZ2V0VHlwZU5vZGVzKGV4dGVuZHNDbGF1c2UpO1xuXG4gIHJldHVybiB0eXBlTm9kZXMubGVuZ3RoID09PSAwID8gdW5kZWZpbmVkIDogdHlwZU5vZGVzWzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5kc09yVGhyb3cobm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbik6IHRzLkV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cyB7XG4gIHJldHVybiB1dGlscy50aHJvd0lmTnVsbE9yVW5kZWZpbmVkKGdldEV4dGVuZHMobm9kZSksICdleHRlbmRzIGV4cHJlc3Npb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEltcGxlbWVudHMoXG4gIG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24sXG4pOiByZWFkb25seSB0cy5FeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHNbXSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGltcGxlbWVudHNDbGF1c2UgPSBoZXJpdGFnZS5nZXRIZXJpdGFnZUNsYXVzZUJ5S2luZChub2RlLCB0cy5TeW50YXhLaW5kLkltcGxlbWVudHNLZXl3b3JkKTtcbiAgaWYgKGltcGxlbWVudHNDbGF1c2UgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gaGVyaXRhZ2UuZ2V0VHlwZU5vZGVzKGltcGxlbWVudHNDbGF1c2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW1wbGVtZW50c0FycmF5KFxuICBub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uLFxuKTogcmVhZG9ubHkgdHMuRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzW10ge1xuICByZXR1cm4gdXRpbHMuZ2V0QXJyYXkoZ2V0SW1wbGVtZW50cyhub2RlKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNZW1iZXJzKG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24pOiByZWFkb25seSBDbGFzc01lbWJlclR5cGVbXSB7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSByZWFkb25seS1hcnJheVxuICBjb25zdCBtZW1iZXJzOiBBcnJheTx0cy5DbGFzc0VsZW1lbnQgfCB0cy5QYXJhbWV0ZXJQcm9wZXJ0eURlY2xhcmF0aW9uPiA9IFsuLi5ub2RlLm1lbWJlcnNdO1xuICBjb25zdCBpbXBsZW1lbnRhdGlvbkN0b3JzID0gbWVtYmVycy5maWx0ZXIodHMuaXNDb25zdHJ1Y3RvckRlY2xhcmF0aW9uKS5maWx0ZXIoKGMpID0+IG92ZXJsb2FkLmlzSW1wbGVtZW50YXRpb24oYykpO1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tbG9vcC1zdGF0ZW1lbnRcbiAgZm9yIChjb25zdCBjdG9yIG9mIGltcGxlbWVudGF0aW9uQ3RvcnMpIHtcbiAgICAvLyBpbnNlcnQgYWZ0ZXIgdGhlIGNvbnN0cnVjdG9yXG4gICAgbGV0IGluc2VydEluZGV4ID0gbWVtYmVycy5pbmRleE9mKGN0b3IpICsgMTtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tbG9vcC1zdGF0ZW1lbnRcbiAgICBmb3IgKGNvbnN0IHBhcmFtIG9mIHBhcmFtZXRlcmVkLmdldFBhcmFtZXRlcnMoY3RvcikpIHtcbiAgICAgIGlmICh0cy5pc1BhcmFtZXRlclByb3BlcnR5RGVjbGFyYXRpb24ocGFyYW0sIHBhcmFtLnBhcmVudCkpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFycmF5LW11dGF0aW9uXG4gICAgICAgIG1lbWJlcnMuc3BsaWNlKGluc2VydEluZGV4LCAwLCBwYXJhbSk7XG4gICAgICAgIGluc2VydEluZGV4ICs9IDE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1lbWJlcnMuZmlsdGVyKGlzQ2xhc3NNZW1iZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uY3JldGVNZW1iZXJzKG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24pOiByZWFkb25seSBDbGFzc01lbWJlclR5cGVbXSB7XG4gIHJldHVybiBkZWNsYXJhdGlvbi5pc0FtYmllbnQobm9kZSlcbiAgICA/IFtdXG4gICAgOiBnZXRNZW1iZXJzKG5vZGUpLmZpbHRlcigobWVtYmVyKSA9PiB7XG4gICAgICAgIGlmICh0cy5pc01ldGhvZERlY2xhcmF0aW9uKG1lbWJlcikpIHtcbiAgICAgICAgICByZXR1cm4gb3ZlcmxvYWQuaXNJbXBsZW1lbnRhdGlvbihtZW1iZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEluc3RhbmNlUHJvcGVydGllcyhcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbixcbik6IHJlYWRvbmx5IENsYXNzSW5zdGFuY2VQcm9wZXJ0eVR5cGVbXSB7XG4gIHJldHVybiBnZXRNZW1iZXJzKG5vZGUpLmZpbHRlcihpc0NsYXNzSW5zdGFuY2VQcm9wZXJ0eSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbnN0YW5jZU1lbWJlcnMobm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbik6IHJlYWRvbmx5IENsYXNzSW5zdGFuY2VNZW1iZXJUeXBlW10ge1xuICByZXR1cm4gZ2V0TWVtYmVycyhub2RlKS5maWx0ZXIoaXNDbGFzc0luc3RhbmNlTWVtYmVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEluc3RhbmNlTWV0aG9kcyhub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uKTogcmVhZG9ubHkgdHMuTWV0aG9kRGVjbGFyYXRpb25bXSB7XG4gIHJldHVybiBnZXRJbnN0YW5jZU1lbWJlcnMobm9kZSkuZmlsdGVyKHRzLmlzTWV0aG9kRGVjbGFyYXRpb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWV0aG9kcyhub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uKTogcmVhZG9ubHkgdHMuTWV0aG9kRGVjbGFyYXRpb25bXSB7XG4gIHJldHVybiBnZXRNZW1iZXJzKG5vZGUpLmZpbHRlcih0cy5pc01ldGhvZERlY2xhcmF0aW9uKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNldEFjY2Vzc29ycyhub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uKTogcmVhZG9ubHkgdHMuU2V0QWNjZXNzb3JEZWNsYXJhdGlvbltdIHtcbiAgcmV0dXJuIGdldE1lbWJlcnMobm9kZSkuZmlsdGVyKHRzLmlzU2V0QWNjZXNzb3IpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5zdGFuY2VNZXRob2QoXG4gIG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24sXG4gIG5hbWU6IHN0cmluZyxcbik6IHRzLk1ldGhvZERlY2xhcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIGdldEluc3RhbmNlTWV0aG9kcyhub2RlKS5maW5kKChtZXRob2QpID0+IG5vZGVfLmdldE5hbWUobWV0aG9kKSA9PT0gbmFtZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25jcmV0ZUluc3RhbmNlUHJvcGVydGllcyhcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbixcbik6IHJlYWRvbmx5IENsYXNzSW5zdGFuY2VQcm9wZXJ0eVR5cGVbXSB7XG4gIHJldHVybiBnZXRDb25jcmV0ZU1lbWJlcnMobm9kZSkuZmlsdGVyKGlzQ2xhc3NJbnN0YW5jZVByb3BlcnR5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbmNyZXRlSW5zdGFuY2VNZW1iZXJzKFxuICBub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uLFxuKTogcmVhZG9ubHkgQ2xhc3NJbnN0YW5jZU1lbWJlclR5cGVbXSB7XG4gIHJldHVybiBnZXRDb25jcmV0ZU1lbWJlcnMobm9kZSkuZmlsdGVyKGlzQ2xhc3NJbnN0YW5jZU1lbWJlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25jcmV0ZUluc3RhbmNlTWV0aG9kcyhcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbixcbik6IHJlYWRvbmx5IHRzLk1ldGhvZERlY2xhcmF0aW9uW10ge1xuICByZXR1cm4gZ2V0Q29uY3JldGVJbnN0YW5jZU1lbWJlcnMobm9kZSkuZmlsdGVyKHRzLmlzTWV0aG9kRGVjbGFyYXRpb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RhdGljUHJvcGVydGllcyhcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbixcbik6IHJlYWRvbmx5IENsYXNzU3RhdGljUHJvcGVydHlUeXBlW10ge1xuICByZXR1cm4gZ2V0TWVtYmVycyhub2RlKS5maWx0ZXIoaXNDbGFzc1N0YXRpY1Byb3BlcnR5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFN0YXRpY01lbWJlcnMobm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbik6IHJlYWRvbmx5IENsYXNzU3RhdGljTWVtYmVyVHlwZVtdIHtcbiAgcmV0dXJuIGdldE1lbWJlcnMobm9kZSkuZmlsdGVyKGlzQ2xhc3NTdGF0aWNNZW1iZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uY3JldGVTdGF0aWNQcm9wZXJ0aWVzKFxuICBub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uLFxuKTogcmVhZG9ubHkgQ2xhc3NTdGF0aWNQcm9wZXJ0eVR5cGVbXSB7XG4gIHJldHVybiBnZXRDb25jcmV0ZU1lbWJlcnMobm9kZSkuZmlsdGVyKGlzQ2xhc3NTdGF0aWNQcm9wZXJ0eSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25jcmV0ZVN0YXRpY01lbWJlcnMoXG4gIG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24sXG4pOiByZWFkb25seSBDbGFzc1N0YXRpY01lbWJlclR5cGVbXSB7XG4gIHJldHVybiBnZXRDb25jcmV0ZU1lbWJlcnMobm9kZSkuZmlsdGVyKGlzQ2xhc3NTdGF0aWNNZW1iZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uY3JldGVTdGF0aWNNZXRob2RzKFxuICBub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uLFxuKTogcmVhZG9ubHkgdHMuTWV0aG9kRGVjbGFyYXRpb25bXSB7XG4gIHJldHVybiBnZXRDb25jcmV0ZVN0YXRpY01lbWJlcnMobm9kZSkuZmlsdGVyKHRzLmlzTWV0aG9kRGVjbGFyYXRpb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uc3RydWN0b3JzKG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24pOiByZWFkb25seSB0cy5Db25zdHJ1Y3RvckRlY2xhcmF0aW9uW10ge1xuICByZXR1cm4gbm9kZS5tZW1iZXJzLmZpbHRlcih0cy5pc0NvbnN0cnVjdG9yRGVjbGFyYXRpb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uY3JldGVDb25zdHJ1Y3RvcihcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbixcbik6IHRzLkNvbnN0cnVjdG9yRGVjbGFyYXRpb24gfCB1bmRlZmluZWQge1xuICByZXR1cm4gZ2V0Q29uc3RydWN0b3JzKG5vZGUpLmZpbmQoKGN0b3IpID0+IG92ZXJsb2FkLmlzSW1wbGVtZW50YXRpb24oY3RvcikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmlyc3RDb25jcmV0ZUNvbnN0cnVjdG9yKFxuICB0eXBlQ2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gIG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24sXG4pOiB0cy5Db25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgY3RvciA9IGdldENvbmNyZXRlQ29uc3RydWN0b3Iobm9kZSk7XG4gIGlmIChjdG9yICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gY3RvcjtcbiAgfVxuXG4gIGNvbnN0IGJhc2VDbGFzcyA9IGdldEJhc2VDbGFzcyh0eXBlQ2hlY2tlciwgbm9kZSk7XG4gIGlmIChiYXNlQ2xhc3MgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gZ2V0Rmlyc3RDb25jcmV0ZUNvbnN0cnVjdG9yKHR5cGVDaGVja2VyLCBiYXNlQ2xhc3MpO1xufVxuXG5mdW5jdGlvbiBnZXREZXJpdmVkQ2xhc3Nlc1dvcmtlcihcbiAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgbGFuZ3VhZ2VTZXJ2aWNlOiB0cy5MYW5ndWFnZVNlcnZpY2UsXG4gIG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24sXG4gIHNlZW4gPSBuZXcgU2V0PHRzLkNsYXNzRGVjbGFyYXRpb24+KCksXG4pOiByZWFkb25seSB0cy5DbGFzc0RlY2xhcmF0aW9uW10ge1xuICBpZiAoc2Vlbi5oYXMobm9kZSkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gcmVmZXJlbmNlXG4gICAgLmZpbmRSZWZlcmVuY2VzQXNOb2Rlcyhwcm9ncmFtLCBsYW5ndWFnZVNlcnZpY2UsIG5vZGUpXG4gICAgLnJlZHVjZTxyZWFkb25seSB0cy5DbGFzc0RlY2xhcmF0aW9uW10+KChhY2MsIHJlZikgPT4ge1xuICAgICAgY29uc3QgcGFyZW50ID0gbm9kZV8uZ2V0UGFyZW50KHJlZikgYXMgdHMuTm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChwYXJlbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjbGF1c2UgPSBub2RlXy5nZXRQYXJlbnQocGFyZW50KSBhcyB0cy5Ob2RlIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGNsYXVzZSA9PT0gdW5kZWZpbmVkIHx8ICF0cy5pc0hlcml0YWdlQ2xhdXNlKGNsYXVzZSkgfHwgIWhlcml0YWdlLmlzRXh0ZW5kcyhjbGF1c2UpKSB7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlcml2ZWQgPSBub2RlXy5nZXRGaXJzdEFuY2VzdG9yQnlLaW5kT3JUaHJvdzx0cy5DbGFzc0RlY2xhcmF0aW9uPihjbGF1c2UsIHRzLlN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbik7XG5cbiAgICAgIHJldHVybiBhY2MuY29uY2F0KGdldERlcml2ZWRDbGFzc2VzV29ya2VyKHByb2dyYW0sIGxhbmd1YWdlU2VydmljZSwgZGVyaXZlZCwgc2VlbikpO1xuICAgIH0sIFtdKVxuICAgIC5jb25jYXQoW25vZGVdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlcml2ZWRDbGFzc2VzKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBsYW5ndWFnZVNlcnZpY2U6IHRzLkxhbmd1YWdlU2VydmljZSxcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbixcbik6IHJlYWRvbmx5IHRzLkNsYXNzRGVjbGFyYXRpb25bXSB7XG4gIGNvbnN0IHJlc3VsdCA9IGdldERlcml2ZWRDbGFzc2VzV29ya2VyKHByb2dyYW0sIGxhbmd1YWdlU2VydmljZSwgbm9kZSk7XG5cbiAgcmV0dXJuIHJlc3VsdC5maWx0ZXIoKHZhbHVlKSA9PiB2YWx1ZSAhPT0gbm9kZSk7XG59XG5cbmZ1bmN0aW9uIGdldEltcGxlbWVudG9yc1dvcmtlcihcbiAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgbGFuZ3VhZ2VTZXJ2aWNlOiB0cy5MYW5ndWFnZVNlcnZpY2UsXG4gIG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5JbnRlcmZhY2VEZWNsYXJhdGlvbixcbiAgc2VlbiA9IG5ldyBTZXQ8dHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkludGVyZmFjZURlY2xhcmF0aW9uPigpLFxuKTogcmVhZG9ubHkgdHMuQ2xhc3NEZWNsYXJhdGlvbltdIHtcbiAgaWYgKHNlZW4uaGFzKG5vZGUpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcmV0dXJuIHJlZmVyZW5jZVxuICAgIC5maW5kUmVmZXJlbmNlc0FzTm9kZXMocHJvZ3JhbSwgbGFuZ3VhZ2VTZXJ2aWNlLCBub2RlKVxuICAgIC5yZWR1Y2U8cmVhZG9ubHkgdHMuQ2xhc3NEZWNsYXJhdGlvbltdPigoYWNjLCByZWYpID0+IHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGVfLmdldFBhcmVudChyZWYpIGFzIHRzLk5vZGUgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAocGFyZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2xhdXNlID0gbm9kZV8uZ2V0UGFyZW50KHBhcmVudCkgYXMgdHMuTm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChcbiAgICAgICAgY2xhdXNlID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgIXRzLmlzSGVyaXRhZ2VDbGF1c2UoY2xhdXNlKSB8fFxuICAgICAgICAoIWhlcml0YWdlLmlzSW1wbGVtZW50cyhjbGF1c2UpICYmICFoZXJpdGFnZS5pc0V4dGVuZHMoY2xhdXNlKSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfVxuXG4gICAgICBsZXQgZGVyaXZlZDogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkludGVyZmFjZURlY2xhcmF0aW9uIHwgdW5kZWZpbmVkID0gbm9kZV8uZ2V0Rmlyc3RBbmNlc3RvckJ5S2luZDxcbiAgICAgICAgdHMuQ2xhc3NEZWNsYXJhdGlvblxuICAgICAgPihjbGF1c2UsIHRzLlN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbik7XG4gICAgICBpZiAoZGVyaXZlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGRlcml2ZWQgPSBub2RlXy5nZXRGaXJzdEFuY2VzdG9yQnlLaW5kT3JUaHJvdzx0cy5JbnRlcmZhY2VEZWNsYXJhdGlvbj4oXG4gICAgICAgICAgY2xhdXNlLFxuICAgICAgICAgIHRzLlN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24sXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhY2MuY29uY2F0KGdldEltcGxlbWVudG9yc1dvcmtlcihwcm9ncmFtLCBsYW5ndWFnZVNlcnZpY2UsIGRlcml2ZWQsIHNlZW4pKTtcbiAgICB9LCBbXSlcbiAgICAuY29uY2F0KHRzLmlzQ2xhc3NEZWNsYXJhdGlvbihub2RlKSA/IFtub2RlXSA6IFtdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEltcGxlbWVudG9ycyhcbiAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgbGFuZ3VhZ2VTZXJ2aWNlOiB0cy5MYW5ndWFnZVNlcnZpY2UsXG4gIG5vZGU6IHRzLkludGVyZmFjZURlY2xhcmF0aW9uLFxuKTogcmVhZG9ubHkgdHMuQ2xhc3NEZWNsYXJhdGlvbltdIHtcbiAgcmV0dXJuIGdldEltcGxlbWVudG9yc1dvcmtlcihwcm9ncmFtLCBsYW5ndWFnZVNlcnZpY2UsIG5vZGUpO1xufVxuXG5mdW5jdGlvbiBnZXRFeHRlbmRvcnNXb3JrZXIoXG4gIHByb2dyYW06IHRzLlByb2dyYW0sXG4gIGxhbmd1YWdlU2VydmljZTogdHMuTGFuZ3VhZ2VTZXJ2aWNlLFxuICBub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uLFxuICBzZWVuID0gbmV3IFNldDx0cy5DbGFzc0RlY2xhcmF0aW9uPigpLFxuKTogcmVhZG9ubHkgdHMuQ2xhc3NEZWNsYXJhdGlvbltdIHtcbiAgaWYgKHNlZW4uaGFzKG5vZGUpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcmV0dXJuIHJlZmVyZW5jZVxuICAgIC5maW5kUmVmZXJlbmNlc0FzTm9kZXMocHJvZ3JhbSwgbGFuZ3VhZ2VTZXJ2aWNlLCBub2RlKVxuICAgIC5yZWR1Y2U8cmVhZG9ubHkgdHMuQ2xhc3NEZWNsYXJhdGlvbltdPigoYWNjLCByZWYpID0+IHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGVfLmdldFBhcmVudChyZWYpIGFzIHRzLk5vZGUgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAocGFyZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2xhdXNlID0gbm9kZV8uZ2V0UGFyZW50KHBhcmVudCkgYXMgdHMuTm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChjbGF1c2UgPT09IHVuZGVmaW5lZCB8fCAhdHMuaXNIZXJpdGFnZUNsYXVzZShjbGF1c2UpIHx8ICFoZXJpdGFnZS5pc0V4dGVuZHMoY2xhdXNlKSkge1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZXJpdmVkOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdW5kZWZpbmVkID0gbm9kZV8uZ2V0Rmlyc3RBbmNlc3RvckJ5VGVzdE9yVGhyb3coXG4gICAgICAgIGNsYXVzZSxcbiAgICAgICAgdHMuaXNDbGFzc0RlY2xhcmF0aW9uLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGFjYy5jb25jYXQoZ2V0SW1wbGVtZW50b3JzV29ya2VyKHByb2dyYW0sIGxhbmd1YWdlU2VydmljZSwgZGVyaXZlZCwgc2VlbikpO1xuICAgIH0sIFtdKVxuICAgIC5jb25jYXQodHMuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpID8gW25vZGVdIDogW10pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5kb3JzKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBsYW5ndWFnZVNlcnZpY2U6IHRzLkxhbmd1YWdlU2VydmljZSxcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbixcbik6IHJlYWRvbmx5IHRzLkNsYXNzRGVjbGFyYXRpb25bXSB7XG4gIHJldHVybiBnZXRFeHRlbmRvcnNXb3JrZXIocHJvZ3JhbSwgbGFuZ3VhZ2VTZXJ2aWNlLCBub2RlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJhc2VUeXBlcyhcbiAgdHlwZUNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICBub2RlOiB0cy5DbGFzc0RlY2xhcmF0aW9uIHwgdHMuQ2xhc3NFeHByZXNzaW9uIHwgdHMuSW50ZXJmYWNlRGVjbGFyYXRpb24sXG4pOiByZWFkb25seSB0cy5UeXBlW10ge1xuICByZXR1cm4gdHlwZV8uZ2V0QmFzZVR5cGVzQXJyYXkodHlwZV8uZ2V0VHlwZSh0eXBlQ2hlY2tlciwgbm9kZSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QmFzZVR5cGVzRmxhdHRlbmVkKFxuICB0eXBlQ2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gIG5vZGU6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB0cy5DbGFzc0V4cHJlc3Npb24gfCB0cy5JbnRlcmZhY2VEZWNsYXJhdGlvbixcbik6IHJlYWRvbmx5IHRzLlR5cGVbXSB7XG4gIGZ1bmN0aW9uIGdldEJhc2VUeXBlc1dvcmtlcih0eXBlOiB0cy5UeXBlKTogcmVhZG9ubHkgdHMuVHlwZVtdIHtcbiAgICBpZiAodHlwZV8uaXNJbnRlcnNlY3Rpb24odHlwZSkpIHtcbiAgICAgIHJldHVybiBfLmZsYXR0ZW4odHlwZV8uZ2V0SW50ZXJzZWN0aW9uVHlwZXNBcnJheSh0eXBlKS5tYXAoZ2V0QmFzZVR5cGVzV29ya2VyKSk7XG4gICAgfVxuXG4gICAgY29uc3QgYmFzZVR5cGVzID0gdHlwZV8uZ2V0QmFzZVR5cGVzQXJyYXkodHlwZSk7XG5cbiAgICByZXR1cm4gW3R5cGVdLmNvbmNhdChfLmZsYXR0ZW4oYmFzZVR5cGVzLm1hcChnZXRCYXNlVHlwZXNXb3JrZXIpKSk7XG4gIH1cblxuICByZXR1cm4gXy5mbGF0dGVuKGdldEJhc2VUeXBlcyh0eXBlQ2hlY2tlciwgbm9kZSkubWFwKGdldEJhc2VUeXBlc1dvcmtlcikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QmFzZUNsYXNzZXMoXG4gIHR5cGVDaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbixcbik6IHJlYWRvbmx5IHRzLkNsYXNzRGVjbGFyYXRpb25bXSB7XG4gIGNvbnN0IGJhc2VUeXBlcyA9IGdldEJhc2VUeXBlc0ZsYXR0ZW5lZCh0eXBlQ2hlY2tlciwgbm9kZSk7XG5cbiAgcmV0dXJuIGJhc2VUeXBlc1xuICAgIC5tYXAoKHR5cGUpID0+IHR5cGVfLmdldFN5bWJvbCh0eXBlKSlcbiAgICAuZmlsdGVyKHV0aWxzLm5vdE51bGwpXG4gICAgLm1hcCgoc3ltYm9sKSA9PiBzeW1ib2xfLmdldERlY2xhcmF0aW9ucyhzeW1ib2wpKVxuICAgIC5yZWR1Y2U8cmVhZG9ubHkgdHMuRGVjbGFyYXRpb25bXT4oKGEsIGIpID0+IGEuY29uY2F0KGIpLCBbXSlcbiAgICAuZmlsdGVyKHRzLmlzQ2xhc3NEZWNsYXJhdGlvbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXNlQ2xhc3MoXG4gIHR5cGVDaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbiAgbm9kZTogdHMuQ2xhc3NEZWNsYXJhdGlvbiB8IHRzLkNsYXNzRXhwcmVzc2lvbixcbik6IHRzLkNsYXNzRGVjbGFyYXRpb24gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBnZXRCYXNlQ2xhc3Nlcyh0eXBlQ2hlY2tlciwgbm9kZSk7XG5cbiAgcmV0dXJuIGRlY2xhcmF0aW9ucy5sZW5ndGggPT09IDEgPyBkZWNsYXJhdGlvbnNbMF0gOiB1bmRlZmluZWQ7XG59XG4iXX0=