1 | /**
|
2 | * @license
|
3 | * Copyright Google LLC All Rights Reserved.
|
4 | *
|
5 | * Use of this source code is governed by an MIT-style license that can be
|
6 | * found in the LICENSE file at https://angular.io/license
|
7 | */
|
8 | (function (factory) {
|
9 | if (typeof module === "object" && typeof module.exports === "object") {
|
10 | var v = factory(require, exports);
|
11 | if (v !== undefined) module.exports = v;
|
12 | }
|
13 | else if (typeof define === "function" && define.amd) {
|
14 | define("@angular/language-service/src/ts_utils", ["require", "exports", "tslib", "typescript/lib/tsserverlibrary"], factory);
|
15 | }
|
16 | })(function (require, exports) {
|
17 | ;
|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
19 | exports.getClassDeclFromDecoratorProp = exports.getClassDeclOfInlineTemplateNode = exports.getPropertyAssignmentFromValue = exports.findTightestNode = exports.findPropertyValueOfType = exports.getDirectiveClassLike = void 0;
|
20 | var tslib_1 = require("tslib");
|
21 | var ts = require("typescript/lib/tsserverlibrary");
|
22 | /**
|
23 | * Return metadata about `node` if it looks like an Angular directive class.
|
24 | * In this case, potential matches are `@NgModule`, `@Component`, `@Directive`,
|
25 | * `@Pipe`, etc.
|
26 | * These class declarations all share some common attributes, namely their
|
27 | * decorator takes exactly one parameter and the parameter must be an object
|
28 | * literal.
|
29 | *
|
30 | * For example,
|
31 | * v---------- `decoratorId`
|
32 | * @NgModule({ <
|
33 | * declarations: [], < classDecln-al
|
34 | * }) <
|
35 | * class AppModule {} <
|
36 | * ^----- `classId`
|
37 | *
|
38 | * @param node Potential node that represents an Angular directive.
|
39 | */
|
40 | function getDirectiveClassLike(node) {
|
41 | var e_1, _a;
|
42 | if (!ts.isClassDeclaration(node) || !node.name || !node.decorators) {
|
43 | return;
|
44 | }
|
45 | try {
|
46 | for (var _b = tslib_1.__values(node.decorators), _c = _b.next(); !_c.done; _c = _b.next()) {
|
47 | var d = _c.value;
|
48 | var expr = d.expression;
|
49 | if (!ts.isCallExpression(expr) || expr.arguments.length !== 1 ||
|
50 | !ts.isIdentifier(expr.expression)) {
|
51 | continue;
|
52 | }
|
53 | var arg = expr.arguments[0];
|
54 | if (ts.isObjectLiteralExpression(arg)) {
|
55 | return {
|
56 | decoratorId: expr.expression,
|
57 | classId: node.name,
|
58 | };
|
59 | }
|
60 | }
|
61 | }
|
62 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
63 | finally {
|
64 | try {
|
65 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
66 | }
|
67 | finally { if (e_1) throw e_1.error; }
|
68 | }
|
69 | }
|
70 | exports.getDirectiveClassLike = getDirectiveClassLike;
|
71 | /**
|
72 | * Finds the value of a property assignment that is nested in a TypeScript node and is of a certain
|
73 | * type T.
|
74 | *
|
75 | * @param startNode node to start searching for nested property assignment from
|
76 | * @param propName property assignment name
|
77 | * @param predicate function to verify that a node is of type T.
|
78 | * @return node property assignment value of type T, or undefined if none is found
|
79 | */
|
80 | function findPropertyValueOfType(startNode, propName, predicate) {
|
81 | if (ts.isPropertyAssignment(startNode) && startNode.name.getText() === propName) {
|
82 | var initializer = startNode.initializer;
|
83 | if (predicate(initializer))
|
84 | return initializer;
|
85 | }
|
86 | return startNode.forEachChild(function (c) { return findPropertyValueOfType(c, propName, predicate); });
|
87 | }
|
88 | exports.findPropertyValueOfType = findPropertyValueOfType;
|
89 | /**
|
90 | * Return the node that most tightly encompass the specified `position`.
|
91 | * @param node
|
92 | * @param position
|
93 | */
|
94 | function findTightestNode(node, position) {
|
95 | if (node.getStart() <= position && position < node.getEnd()) {
|
96 | return node.forEachChild(function (c) { return findTightestNode(c, position); }) || node;
|
97 | }
|
98 | }
|
99 | exports.findTightestNode = findTightestNode;
|
100 | /**
|
101 | * Returns a property assignment from the assignment value if the property name
|
102 | * matches the specified `key`, or `undefined` if there is no match.
|
103 | */
|
104 | function getPropertyAssignmentFromValue(value, key) {
|
105 | var propAssignment = value.parent;
|
106 | if (!propAssignment || !ts.isPropertyAssignment(propAssignment) ||
|
107 | propAssignment.name.getText() !== key) {
|
108 | return;
|
109 | }
|
110 | return propAssignment;
|
111 | }
|
112 | exports.getPropertyAssignmentFromValue = getPropertyAssignmentFromValue;
|
113 | /**
|
114 | * Given the node which is the string of the inline template for a component, returns the
|
115 | * `ts.ClassDeclaration` for the component.
|
116 | */
|
117 | function getClassDeclOfInlineTemplateNode(templateStringNode) {
|
118 | if (!ts.isStringLiteralLike(templateStringNode)) {
|
119 | return;
|
120 | }
|
121 | var tmplAsgn = getPropertyAssignmentFromValue(templateStringNode, 'template');
|
122 | if (!tmplAsgn) {
|
123 | return;
|
124 | }
|
125 | return getClassDeclFromDecoratorProp(tmplAsgn);
|
126 | }
|
127 | exports.getClassDeclOfInlineTemplateNode = getClassDeclOfInlineTemplateNode;
|
128 | /**
|
129 | * Given a decorator property assignment, return the ClassDeclaration node that corresponds to the
|
130 | * directive class the property applies to.
|
131 | * If the property assignment is not on a class decorator, no declaration is returned.
|
132 | *
|
133 | * For example,
|
134 | *
|
135 | * @Component({
|
136 | * template: '<div></div>'
|
137 | * ^^^^^^^^^^^^^^^^^^^^^^^---- property assignment
|
138 | * })
|
139 | * class AppComponent {}
|
140 | * ^---- class declaration node
|
141 | *
|
142 | * @param propAsgnNode property assignment
|
143 | */
|
144 | function getClassDeclFromDecoratorProp(propAsgnNode) {
|
145 | if (!propAsgnNode.parent || !ts.isObjectLiteralExpression(propAsgnNode.parent)) {
|
146 | return;
|
147 | }
|
148 | var objLitExprNode = propAsgnNode.parent;
|
149 | if (!objLitExprNode.parent || !ts.isCallExpression(objLitExprNode.parent)) {
|
150 | return;
|
151 | }
|
152 | var callExprNode = objLitExprNode.parent;
|
153 | if (!callExprNode.parent || !ts.isDecorator(callExprNode.parent)) {
|
154 | return;
|
155 | }
|
156 | var decorator = callExprNode.parent;
|
157 | if (!decorator.parent || !ts.isClassDeclaration(decorator.parent)) {
|
158 | return;
|
159 | }
|
160 | var classDeclNode = decorator.parent;
|
161 | return classDeclNode;
|
162 | }
|
163 | exports.getClassDeclFromDecoratorProp = getClassDeclFromDecoratorProp;
|
164 | });
|
165 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNfdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9sYW5ndWFnZS1zZXJ2aWNlL3NyYy90c191dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7O0lBRUgsbURBQXFEO0lBT3JEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNILFNBQWdCLHFCQUFxQixDQUFDLElBQWE7O1FBQ2pELElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNsRSxPQUFPO1NBQ1I7O1lBQ0QsS0FBZ0IsSUFBQSxLQUFBLGlCQUFBLElBQUksQ0FBQyxVQUFVLENBQUEsZ0JBQUEsNEJBQUU7Z0JBQTVCLElBQU0sQ0FBQyxXQUFBO2dCQUNWLElBQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDekQsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRTtvQkFDckMsU0FBUztpQkFDVjtnQkFDRCxJQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM5QixJQUFJLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDckMsT0FBTzt3QkFDTCxXQUFXLEVBQUUsSUFBSSxDQUFDLFVBQVU7d0JBQzVCLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSTtxQkFDbkIsQ0FBQztpQkFDSDthQUNGOzs7Ozs7Ozs7SUFDSCxDQUFDO0lBbEJELHNEQWtCQztJQUVEOzs7Ozs7OztPQVFH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QUMsTUFBTSxDQUFDO1FBQ3ZDLE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7SUFuQkQsc0VBbUJDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCAqIGFzIHRzIGZyb20gJ3R5cGVzY3JpcHQvbGliL3Rzc2VydmVybGlicmFyeSc7XG5cbmludGVyZmFjZSBEaXJlY3RpdmVDbGFzc0xpa2Uge1xuICBkZWNvcmF0b3JJZDogdHMuSWRlbnRpZmllcjsgIC8vIGRlY29yYXRvciBpZGVudGlmaWVyLCBsaWtlIEBDb21wb25lbnRcbiAgY2xhc3NJZDogdHMuSWRlbnRpZmllcjtcbn1cblxuLyoqXG4gKiBSZXR1cm4gbWV0YWRhdGEgYWJvdXQgYG5vZGVgIGlmIGl0IGxvb2tzIGxpa2UgYW4gQW5ndWxhciBkaXJlY3RpdmUgY2xhc3MuXG4gKiBJbiB0aGlzIGNhc2UsIHBvdGVudGlhbCBtYXRjaGVzIGFyZSBgQE5nTW9kdWxlYCwgYEBDb21wb25lbnRgLCBgQERpcmVjdGl2ZWAsXG4gKiBgQFBpcGVgLCBldGMuXG4gKiBUaGVzZSBjbGFzcyBkZWNsYXJhdGlvbnMgYWxsIHNoYXJlIHNvbWUgY29tbW9uIGF0dHJpYnV0ZXMsIG5hbWVseSB0aGVpclxuICogZGVjb3JhdG9yIHRha2VzIGV4YWN0bHkgb25lIHBhcmFtZXRlciBhbmQgdGhlIHBhcmFtZXRlciBtdXN0IGJlIGFuIG9iamVjdFxuICogbGl0ZXJhbC5cbiAqXG4gKiBGb3IgZXhhbXBsZSxcbiAqICAgICB2LS0tLS0tLS0tLSBgZGVjb3JhdG9ySWRgXG4gKiBATmdNb2R1bGUoeyAgICAgICAgICAgPFxuICogICBkZWNsYXJhdGlvbnM6IFtdLCAgIDwgY2xhc3NEZWNsbi1hbFxuICogfSkgICAgICAgICAgICAgICAgICAgIDxcbiAqIGNsYXNzIEFwcE1vZHVsZSB7fSAgICA8XG4gKiAgICAgICAgICBeLS0tLS0gYGNsYXNzSWRgXG4gKlxuICogQHBhcmFtIG5vZGUgUG90ZW50aWFsIG5vZGUgdGhhdCByZXByZXNlbnRzIGFuIEFuZ3VsYXIgZGlyZWN0aXZlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGlyZWN0aXZlQ2xhc3NMaWtlKG5vZGU6IHRzLk5vZGUpOiBEaXJlY3RpdmVDbGFzc0xpa2V8dW5kZWZpbmVkIHtcbiAgaWYgKCF0cy5pc0NsYXNzRGVjbGFyYXRpb24obm9kZSkgfHwgIW5vZGUubmFtZSB8fCAhbm9kZS5kZWNvcmF0b3JzKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAoY29uc3QgZCBvZiBub2RlLmRlY29yYXRvcnMpIHtcbiAgICBjb25zdCBleHByID0gZC5leHByZXNzaW9uO1xuICAgIGlmICghdHMuaXNDYWxsRXhwcmVzc2lvbihleHByKSB8fCBleHByLmFyZ3VtZW50cy5sZW5ndGggIT09IDEgfHxcbiAgICAgICAgIXRzLmlzSWRlbnRpZmllcihleHByLmV4cHJlc3Npb24pKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgYXJnID0gZXhwci5hcmd1bWVudHNbMF07XG4gICAgaWYgKHRzLmlzT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb24oYXJnKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGVjb3JhdG9ySWQ6IGV4cHIuZXhwcmVzc2lvbixcbiAgICAgICAgY2xhc3NJZDogbm9kZS5uYW1lLFxuICAgICAgfTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBGaW5kcyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBhc3NpZ25tZW50IHRoYXQgaXMgbmVzdGVkIGluIGEgVHlwZVNjcmlwdCBub2RlIGFuZCBpcyBvZiBhIGNlcnRhaW5cbiAqIHR5cGUgVC5cbiAqXG4gKiBAcGFyYW0gc3RhcnROb2RlIG5vZGUgdG8gc3RhcnQgc2VhcmNoaW5nIGZvciBuZXN0ZWQgcHJvcGVydHkgYXNzaWdubWVudCBmcm9tXG4gKiBAcGFyYW0gcHJvcE5hbWUgcHJvcGVydHkgYXNzaWdubWVudCBuYW1lXG4gKiBAcGFyYW0gcHJlZGljYXRlIGZ1bmN0aW9uIHRvIHZlcmlmeSB0aGF0IGEgbm9kZSBpcyBvZiB0eXBlIFQuXG4gKiBAcmV0dXJuIG5vZGUgcHJvcGVydHkgYXNzaWdubWVudCB2YWx1ZSBvZiB0eXBlIFQsIG9yIHVuZGVmaW5lZCBpZiBub25lIGlzIGZvdW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kUHJvcGVydHlWYWx1ZU9mVHlwZTxUIGV4dGVuZHMgdHMuTm9kZT4oXG4gICAgc3RhcnROb2RlOiB0cy5Ob2RlLCBwcm9wTmFtZTogc3RyaW5nLCBwcmVkaWNhdGU6IChub2RlOiB0cy5Ob2RlKSA9PiBub2RlIGlzIFQpOiBUfHVuZGVmaW5lZCB7XG4gIGlmICh0cy5pc1Byb3BlcnR5QXNzaWdubWVudChzdGFydE5vZGUpICYmIHN0YXJ0Tm9kZS5uYW1lLmdldFRleHQoKSA9PT0gcHJvcE5hbWUpIHtcbiAgICBjb25zdCB7aW5pdGlhbGl6ZXJ9ID0gc3RhcnROb2RlO1xuICAgIGlmIChwcmVkaWNhdGUoaW5pdGlhbGl6ZXIpKSByZXR1cm4gaW5pdGlhbGl6ZXI7XG4gIH1cbiAgcmV0dXJuIHN0YXJ0Tm9kZS5mb3JFYWNoQ2hpbGQoYyA9PiBmaW5kUHJvcGVydHlWYWx1ZU9mVHlwZShjLCBwcm9wTmFtZSwgcHJlZGljYXRlKSk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBub2RlIHRoYXQgbW9zdCB0aWdodGx5IGVuY29tcGFzcyB0aGUgc3BlY2lmaWVkIGBwb3NpdGlvbmAuXG4gKiBAcGFyYW0gbm9kZVxuICogQHBhcmFtIHBvc2l0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kVGlnaHRlc3ROb2RlKG5vZGU6IHRzLk5vZGUsIHBvc2l0aW9uOiBudW1iZXIpOiB0cy5Ob2RlfHVuZGVmaW5lZCB7XG4gIGlmIChub2RlLmdldFN0YXJ0KCkgPD0gcG9zaXRpb24gJiYgcG9zaXRpb24gPCBub2RlLmdldEVuZCgpKSB7XG4gICAgcmV0dXJuIG5vZGUuZm9yRWFjaENoaWxkKGMgPT4gZmluZFRpZ2h0ZXN0Tm9kZShjLCBwb3NpdGlvbikpIHx8IG5vZGU7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgcHJvcGVydHkgYXNzaWdubWVudCBmcm9tIHRoZSBhc3NpZ25tZW50IHZhbHVlIGlmIHRoZSBwcm9wZXJ0eSBuYW1lXG4gKiBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgYGtleWAsIG9yIGB1bmRlZmluZWRgIGlmIHRoZXJlIGlzIG5vIG1hdGNoLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJvcGVydHlBc3NpZ25tZW50RnJvbVZhbHVlKHZhbHVlOiB0cy5Ob2RlLCBrZXk6IHN0cmluZyk6IHRzLlByb3BlcnR5QXNzaWdubWVudHxcbiAgICB1bmRlZmluZWQge1xuICBjb25zdCBwcm9wQXNzaWdubWVudCA9IHZhbHVlLnBhcmVudDtcbiAgaWYgKCFwcm9wQXNzaWdubWVudCB8fCAhdHMuaXNQcm9wZXJ0eUFzc2lnbm1lbnQocHJvcEFzc2lnbm1lbnQpIHx8XG4gICAgICBwcm9wQXNzaWdubWVudC5uYW1lLmdldFRleHQoKSAhPT0ga2V5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiBwcm9wQXNzaWdubWVudDtcbn1cblxuLyoqXG4gKiBHaXZlbiB0aGUgbm9kZSB3aGljaCBpcyB0aGUgc3RyaW5nIG9mIHRoZSBpbmxpbmUgdGVtcGxhdGUgZm9yIGEgY29tcG9uZW50LCByZXR1cm5zIHRoZVxuICogYHRzLkNsYXNzRGVjbGFyYXRpb25gIGZvciB0aGUgY29tcG9uZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xhc3NEZWNsT2ZJbmxpbmVUZW1wbGF0ZU5vZGUodGVtcGxhdGVTdHJpbmdOb2RlOiB0cy5Ob2RlKTogdHMuQ2xhc3NEZWNsYXJhdGlvbnxcbiAgICB1bmRlZmluZWQge1xuICBpZiAoIXRzLmlzU3RyaW5nTGl0ZXJhbExpa2UodGVtcGxhdGVTdHJpbmdOb2RlKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCB0bXBsQXNnbiA9IGdldFByb3BlcnR5QXNzaWdubWVudEZyb21WYWx1ZSh0ZW1wbGF0ZVN0cmluZ05vZGUsICd0ZW1wbGF0ZScpO1xuICBpZiAoIXRtcGxBc2duKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiBnZXRDbGFzc0RlY2xGcm9tRGVjb3JhdG9yUHJvcCh0bXBsQXNnbik7XG59XG5cbi8qKlxuICogR2l2ZW4gYSBkZWNvcmF0b3IgcHJvcGVydHkgYXNzaWdubWVudCwgcmV0dXJuIHRoZSBDbGFzc0RlY2xhcmF0aW9uIG5vZGUgdGhhdCBjb3JyZXNwb25kcyB0byB0aGVcbiAqIGRpcmVjdGl2ZSBjbGFzcyB0aGUgcHJvcGVydHkgYXBwbGllcyB0by5cbiAqIElmIHRoZSBwcm9wZXJ0eSBhc3NpZ25tZW50IGlzIG5vdCBvbiBhIGNsYXNzIGRlY29yYXRvciwgbm8gZGVjbGFyYXRpb24gaXMgcmV0dXJuZWQuXG4gKlxuICogRm9yIGV4YW1wbGUsXG4gKlxuICogQENvbXBvbmVudCh7XG4gKiAgIHRlbXBsYXRlOiAnPGRpdj48L2Rpdj4nXG4gKiAgIF5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eLS0tLSBwcm9wZXJ0eSBhc3NpZ25tZW50XG4gKiB9KVxuICogY2xhc3MgQXBwQ29tcG9uZW50IHt9XG4gKiAgICAgICAgICAgXi0tLS0gY2xhc3MgZGVjbGFyYXRpb24gbm9kZVxuICpcbiAqIEBwYXJhbSBwcm9wQXNnbk5vZGUgcHJvcGVydHkgYXNzaWdubWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xhc3NEZWNsRnJvbURlY29yYXRvclByb3AocHJvcEFzZ25Ob2RlOiB0cy5Qcm9wZXJ0eUFzc2lnbm1lbnQpOlxuICAgIHRzLkNsYXNzRGVjbGFyYXRpb258dW5kZWZpbmVkIHtcbiAgaWYgKCFwcm9wQXNnbk5vZGUucGFyZW50IHx8ICF0cy5pc09iamVjdExpdGVyYWxFeHByZXNzaW9uKHByb3BBc2duTm9kZS5wYXJlbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IG9iakxpdEV4cHJOb2RlID0gcHJvcEFzZ25Ob2RlLnBhcmVudDtcbiAgaWYgKCFvYmpMaXRFeHByTm9kZS5wYXJlbnQgfHwgIXRzLmlzQ2FsbEV4cHJlc3Npb24ob2JqTGl0RXhwck5vZGUucGFyZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBjYWxsRXhwck5vZGUgPSBvYmpMaXRFeHByTm9kZS5wYXJlbnQ7XG4gIGlmICghY2FsbEV4cHJOb2RlLnBhcmVudCB8fCAhdHMuaXNEZWNvcmF0b3IoY2FsbEV4cHJOb2RlLnBhcmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgZGVjb3JhdG9yID0gY2FsbEV4cHJOb2RlLnBhcmVudDtcbiAgaWYgKCFkZWNvcmF0b3IucGFyZW50IHx8ICF0cy5pc0NsYXNzRGVjbGFyYXRpb24oZGVjb3JhdG9yLnBhcmVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgY2xhc3NEZWNsTm9kZSA9IGRlY29yYXRvci5wYXJlbnQ7XG4gIHJldHVybiBjbGFzc0RlY2xOb2RlO1xufVxuIl19 |
\ | No newline at end of file |