1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const convert_1 = require("../convert");
|
4 | const languageclient_1 = require("../languageclient");
|
5 | /**
|
6 | * Public: Listen to diagnostics messages from the language server and publish them to the user by way of the Linter
|
7 | * Push (Indie) v2 API provided by the Base Linter package.
|
8 | */
|
9 | class LinterPushV2Adapter {
|
10 | /**
|
11 | * Public: Create a new {LinterPushV2Adapter} that will listen for diagnostics via the supplied {LanguageClientConnection}.
|
12 | *
|
13 | * @param connection A {LanguageClientConnection} to the language server that will provide diagnostics.
|
14 | */
|
15 | constructor(connection) {
|
16 | /*
|
17 | * A map from file path calculated using the LS diagnostic uri to an array of linter messages {linter.Message[]}
|
18 | */
|
19 | this._diagnosticMap = new Map();
|
20 | /**
|
21 | * A map from file path {linter.Message["location"]["file"]} to a Map of all Message keys to Diagnostics
|
22 | * ${Map<linter.Message["key"], Diagnostic>} It has to be stored separately because a {Message} object cannot hold all
|
23 | * of the information that a {Diagnostic} provides, thus we store the original {Diagnostic} object.
|
24 | */
|
25 | this._lsDiagnosticMap = new Map();
|
26 | this._indies = new Set();
|
27 | connection.onPublishDiagnostics(this.captureDiagnostics.bind(this));
|
28 | }
|
29 | /** Dispose this adapter ensuring any resources are freed and events unhooked. */
|
30 | dispose() {
|
31 | this.detachAll();
|
32 | }
|
33 | /**
|
34 | * Public: Attach this {LinterPushV2Adapter} to a given {V2IndieDelegate} registry.
|
35 | *
|
36 | * @param indie A {V2IndieDelegate} that wants to receive messages.
|
37 | */
|
38 | attach(indie) {
|
39 | this._indies.add(indie);
|
40 | this._diagnosticMap.forEach((value, key) => indie.setMessages(key, value));
|
41 | indie.onDidDestroy(() => {
|
42 | this._indies.delete(indie);
|
43 | });
|
44 | }
|
45 | /** Public: Remove all {V2IndieDelegate} registries attached to this adapter and clear them. */
|
46 | detachAll() {
|
47 | this._indies.forEach((i) => i.clearMessages());
|
48 | this._indies.clear();
|
49 | }
|
50 | /**
|
51 | * Public: Capture the diagnostics sent from a langguage server, convert them to the Linter V2 format and forward them
|
52 | * on to any attached {V2IndieDelegate}s.
|
53 | *
|
54 | * @param params The {PublishDiagnosticsParams} received from the language server that should be captured and
|
55 | * forwarded on to any attached {V2IndieDelegate}s.
|
56 | */
|
57 | captureDiagnostics(params) {
|
58 | const path = convert_1.default.uriToPath(params.uri);
|
59 | const codeMap = new Map();
|
60 | const messages = params.diagnostics.map((d) => {
|
61 | const linterMessage = lsDiagnosticToV2Message(path, d);
|
62 | codeMap.set(getMessageKey(linterMessage), d);
|
63 | return linterMessage;
|
64 | });
|
65 | this._diagnosticMap.set(path, messages);
|
66 | this._lsDiagnosticMap.set(path, codeMap);
|
67 | this._indies.forEach((i) => i.setMessages(path, messages));
|
68 | }
|
69 | /**
|
70 | * Public: Convert a single {Diagnostic} received from a language server into a single {V2Message} expected by the
|
71 | * Linter V2 API.
|
72 | *
|
73 | * @param path A string representing the path of the file the diagnostic belongs to.
|
74 | * @param diagnostics A {Diagnostic} object received from the language server.
|
75 | * @returns A {V2Message} equivalent to the {Diagnostic} object supplied by the language server.
|
76 | */
|
77 | diagnosticToV2Message(path, diagnostic) {
|
78 | return {
|
79 | location: {
|
80 | file: path,
|
81 | position: convert_1.default.lsRangeToAtomRange(diagnostic.range),
|
82 | },
|
83 | excerpt: diagnostic.message,
|
84 | linterName: diagnostic.source,
|
85 | severity: LinterPushV2Adapter.diagnosticSeverityToSeverity(diagnostic.severity || -1),
|
86 | };
|
87 | }
|
88 | /**
|
89 | * Public: get diagnostics for the given linter messages
|
90 | *
|
91 | * @param linterMessages An array of linter {V2Message}
|
92 | * @returns An array of LS {Diagnostic[]}
|
93 | */
|
94 | getLSDiagnosticsForMessages(linterMessages) {
|
95 | return linterMessages
|
96 | .map(this.getLSDiagnosticForMessage)
|
97 | // filter out undefined
|
98 | .filter((diagnostic) => diagnostic !== undefined);
|
99 | }
|
100 | /**
|
101 | * Public: Get the {Diagnostic} that is associated with the given Base Linter v2 {Message}.
|
102 | *
|
103 | * @param message The {Message} object to fetch the {Diagnostic} for.
|
104 | * @returns The associated {Diagnostic}.
|
105 | */
|
106 | getLSDiagnosticForMessage(message) {
|
107 | var _a;
|
108 | return (_a = this._lsDiagnosticMap.get(message.location.file)) === null || _a === void 0 ? void 0 : _a.get(getMessageKey(message));
|
109 | }
|
110 | /**
|
111 | * Public: Convert a diagnostic severity number obtained from the language server into the textual equivalent for a
|
112 | * Linter {V2Message}.
|
113 | *
|
114 | * @param severity A number representing the severity of the diagnostic.
|
115 | * @returns A string of 'error', 'warning' or 'info' depending on the severity.
|
116 | */
|
117 | static diagnosticSeverityToSeverity(severity) {
|
118 | switch (severity) {
|
119 | case languageclient_1.DiagnosticSeverity.Error:
|
120 | return "error";
|
121 | case languageclient_1.DiagnosticSeverity.Warning:
|
122 | return "warning";
|
123 | case languageclient_1.DiagnosticSeverity.Information:
|
124 | case languageclient_1.DiagnosticSeverity.Hint:
|
125 | default:
|
126 | return "info";
|
127 | }
|
128 | }
|
129 | }
|
130 | exports.default = LinterPushV2Adapter;
|
131 | /**
|
132 | * Public: Convert a single {Diagnostic} received from a language server into a single {Message} expected by the Linter V2 API.
|
133 | *
|
134 | * @param path A string representing the path of the file the diagnostic belongs to.
|
135 | * @param diagnostics A {Diagnostic} object received from the language server.
|
136 | * @returns A {Message} equivalent to the {Diagnostic} object supplied by the language server.
|
137 | */
|
138 | function lsDiagnosticToV2Message(path, diagnostic) {
|
139 | var _a, _b, _c;
|
140 | return {
|
141 | location: {
|
142 | file: path,
|
143 | position: convert_1.default.lsRangeToAtomRange(diagnostic.range),
|
144 | },
|
145 | reference: relatedInformationToReference(diagnostic.relatedInformation),
|
146 | url: (_a = diagnostic.codeDescription) === null || _a === void 0 ? void 0 : _a.href,
|
147 | icon: iconForLSSeverity((_b = diagnostic.severity) !== null && _b !== void 0 ? _b : languageclient_1.DiagnosticSeverity.Error),
|
148 | excerpt: diagnostic.message,
|
149 | linterName: diagnostic.source,
|
150 | severity: lsSeverityToV2MessageSeverity((_c = diagnostic.severity) !== null && _c !== void 0 ? _c : languageclient_1.DiagnosticSeverity.Error),
|
151 | // BLOCKED: on steelbrain/linter#1722
|
152 | solutions: undefined,
|
153 | };
|
154 | }
|
155 | /**
|
156 | * Convert a severity level of an LSP {Diagnostic} to that of a Base Linter v2 {Message}. Note: this conversion is lossy
|
157 | * due to the v2 Message not being able to represent hints.
|
158 | *
|
159 | * @param severity A severity level of of an LSP {Diagnostic} to be converted.
|
160 | * @returns A severity level a Base Linter v2 {Message}.
|
161 | */
|
162 | function lsSeverityToV2MessageSeverity(severity) {
|
163 | switch (severity) {
|
164 | case languageclient_1.DiagnosticSeverity.Error:
|
165 | return "error";
|
166 | case languageclient_1.DiagnosticSeverity.Warning:
|
167 | return "warning";
|
168 | case languageclient_1.DiagnosticSeverity.Information:
|
169 | case languageclient_1.DiagnosticSeverity.Hint:
|
170 | return "info";
|
171 | default:
|
172 | throw Error(`Unexpected diagnostic severity '${severity}'`);
|
173 | }
|
174 | }
|
175 | /**
|
176 | * Convert a diagnostic severity number obtained from the language server into an Octicon icon.
|
177 | *
|
178 | * @param severity A number representing the severity of the diagnostic.
|
179 | * @returns An Octicon name.
|
180 | */
|
181 | function iconForLSSeverity(severity) {
|
182 | switch (severity) {
|
183 | case languageclient_1.DiagnosticSeverity.Error:
|
184 | return "stop";
|
185 | case languageclient_1.DiagnosticSeverity.Warning:
|
186 | return "warning";
|
187 | case languageclient_1.DiagnosticSeverity.Information:
|
188 | return "info";
|
189 | case languageclient_1.DiagnosticSeverity.Hint:
|
190 | return "light-bulb";
|
191 | default:
|
192 | return undefined;
|
193 | }
|
194 | }
|
195 | /**
|
196 | * Convert the related information from a diagnostic into a reference point for a Linter {V2Message}.
|
197 | *
|
198 | * @param relatedInfo Several related information objects (only the first is used).
|
199 | * @returns A value that is suitable for using as {V2Message}.reference.
|
200 | */
|
201 | function relatedInformationToReference(relatedInfo) {
|
202 | if (relatedInfo === undefined || relatedInfo.length === 0) {
|
203 | return undefined;
|
204 | }
|
205 | const location = relatedInfo[0].location;
|
206 | return {
|
207 | file: convert_1.default.uriToPath(location.uri),
|
208 | position: convert_1.default.lsRangeToAtomRange(location.range).start,
|
209 | };
|
210 | }
|
211 | /**
|
212 | * Get a unique key for a Linter v2 Message
|
213 | *
|
214 | * @param message A {Message} object
|
215 | * @returns ${string} a unique key
|
216 | */
|
217 | function getMessageKey(message) {
|
218 | if (typeof message.key !== "string") {
|
219 | updateMessageKey(message);
|
220 | }
|
221 | return message.key; // updateMessageKey adds message.key string
|
222 | }
|
223 | /**
|
224 | * Construct an unique key for a Linter v2 Message and store it in `Message.key`
|
225 | *
|
226 | * @param message A {Message} object to serialize.
|
227 | * @returns ${string} a unique key
|
228 | */
|
229 | function updateMessageKey(message) {
|
230 | // From https://github.com/steelbrain/linter/blob/fadd462914ef0a8ed5b73a489f662a9393bdbe9f/lib/helpers.ts#L50-L64
|
231 | const { reference, location } = message;
|
232 | const nameStr = `$LINTER:${message.linterName}`;
|
233 | const locationStr = `$LOCATION:${location.file}$${location.position.start.row}$${location.position.start.column}$${location.position.end.row}$${location.position.end.column}`;
|
234 | const referenceStr = reference
|
235 | ? `$REFERENCE:${reference.file}$${reference.position ? `${reference.position.row}$${reference.position.column}` : ""}`
|
236 | : "$REFERENCE:null";
|
237 | const excerptStr = `$EXCERPT:${message.excerpt}`;
|
238 | const severityStr = `$SEVERITY:${message.severity}`;
|
239 | const iconStr = message.icon ? `$ICON:${message.icon}` : "$ICON:null";
|
240 | const urlStr = message.url ? `$URL:${message.url}` : "$URL:null";
|
241 | const descriptionStr = typeof message.description === "string" ? `$DESCRIPTION:${message.description}` : "$DESCRIPTION:null";
|
242 | message.key = `${nameStr}${locationStr}${referenceStr}${excerptStr}${severityStr}${iconStr}${urlStr}${descriptionStr}`;
|
243 | }
|
244 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGludGVyLXB1c2gtdjItYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9hZGFwdGVycy9saW50ZXItcHVzaC12Mi1hZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0Esd0NBQWdDO0FBQ2hDLHNEQU0wQjtBQUUxQjs7O0dBR0c7QUFDSCxNQUFxQixtQkFBbUI7SUFjdEM7Ozs7T0FJRztJQUNILFlBQVksVUFBb0M7UUFsQmhEOztXQUVHO1FBQ08sbUJBQWMsR0FBa0MsSUFBSSxHQUFHLEVBQUUsQ0FBQTtRQUNuRTs7OztXQUlHO1FBQ08scUJBQWdCLEdBQ3hCLElBQUksR0FBRyxFQUFFLENBQUE7UUFDRCxZQUFPLEdBQThCLElBQUksR0FBRyxFQUFFLENBQUE7UUFRdEQsVUFBVSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUNyRSxDQUFDO0lBRUQsaUZBQWlGO0lBQzFFLE9BQU87UUFDWixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUE7SUFDbEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsS0FBMkI7UUFDdkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQzFFLEtBQUssQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFO1lBQ3RCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQzVCLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVELCtGQUErRjtJQUN4RixTQUFTO1FBQ2QsSUFBSSxDQUFDLE9BQU8sQ0FB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O0FBQ3hILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBsaW50ZXIgZnJvbSBcImF0b20vbGludGVyXCJcbmltcG9ydCBDb252ZXJ0IGZyb20gXCIuLi9jb252ZXJ0XCJcbmltcG9ydCB7XG4gIERpYWdub3N0aWMsXG4gIERpYWdub3N0aWNTZXZlcml0eSxcbiAgRGlhZ25vc3RpY1JlbGF0ZWRJbmZvcm1hdGlvbixcbiAgTGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9uLFxuICBQdWJsaXNoRGlhZ25vc3RpY3NQYXJhbXMsXG59IGZyb20gXCIuLi9sYW5ndWFnZWNsaWVudFwiXG5cbi8qKlxuICogUHVibGljOiBMaXN0ZW4gdG8gZGlhZ25vc3RpY3MgbWVzc2FnZXMgZnJvbSB0aGUgbGFuZ3VhZ2Ugc2VydmVyIGFuZCBwdWJsaXNoIHRoZW0gdG8gdGhlIHVzZXIgYnkgd2F5IG9mIHRoZSBMaW50ZXJcbiAqIFB1c2ggKEluZGllKSB2MiBBUEkgcHJvdmlkZWQgYnkgdGhlIEJhc2UgTGludGVyIHBhY2thZ2UuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpbnRlclB1c2hWMkFkYXB0ZXIge1xuICAvKlxuICAgKiBBIG1hcCBmcm9tIGZpbGUgcGF0aCBjYWxjdWxhdGVkIHVzaW5nIHRoZSBMUyBkaWFnbm9zdGljIHVyaSB0byBhbiBhcnJheSBvZiBsaW50ZXIgbWVzc2FnZXMge2xpbnRlci5NZXNzYWdlW119XG4gICAqL1xuICBwcm90ZWN0ZWQgX2RpYWdub3N0aWNNYXA6IE1hcDxzdHJpbmcsIGxpbnRlci5NZXNzYWdlW10+ID0gbmV3IE1hcCgpXG4gIC8qKlxuICAgKiBBIG1hcCBmcm9tIGZpbGUgcGF0aCB7bGludGVyLk1lc3NhZ2VbXCJsb2NhdGlvblwiXVtcImZpbGVcIl19IHRvIGEgTWFwIG9mIGFsbCBNZXNzYWdlIGtleXMgdG8gRGlhZ25vc3RpY3NcbiAgICogJHtNYXA8bGludGVyLk1lc3NhZ2VbXCJrZXlcIl0sIERpYWdub3N0aWM+fSBJdCBoYXMgdG8gYmUgc3RvcmVkIHNlcGFyYXRlbHkgYmVjYXVzZSBhIHtNZXNzYWdlfSBvYmplY3QgY2Fubm90IGhvbGQgYWxsXG4gICAqIG9mIHRoZSBpbmZvcm1hdGlvbiB0aGF0IGEge0RpYWdub3N0aWN9IHByb3ZpZGVzLCB0aHVzIHdlIHN0b3JlIHRoZSBvcmlnaW5hbCB7RGlhZ25vc3RpY30gb2JqZWN0LlxuICAgKi9cbiAgcHJvdGVjdGVkIF9sc0RpYWdub3N0aWNNYXA6IE1hcDxsaW50ZXIuTWVzc2FnZVtcImxvY2F0aW9uXCJdW1wiZmlsZVwiXSwgTWFwPGxpbnRlci5NZXNzYWdlW1wia2V5XCJdLCBEaWFnbm9zdGljPj4gPVxuICAgIG5ldyBNYXAoKVxuICBwcm90ZWN0ZWQgX2luZGllczogU2V0PGxpbnRlci5JbmRpZURlbGVnYXRlPiA9IG5ldyBTZXQoKVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IENyZWF0ZSBhIG5ldyB7TGludGVyUHVzaFYyQWRhcHRlcn0gdGhhdCB3aWxsIGxpc3RlbiBmb3IgZGlhZ25vc3RpY3MgdmlhIHRoZSBzdXBwbGllZCB7TGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9ufS5cbiAgICpcbiAgICogQHBhcmFtIGNvbm5lY3Rpb24gQSB7TGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9ufSB0byB0aGUgbGFuZ3VhZ2Ugc2VydmVyIHRoYXQgd2lsbCBwcm92aWRlIGRpYWdub3N0aWNzLlxuICAgKi9cbiAgY29uc3RydWN0b3IoY29ubmVjdGlvbjogTGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9uKSB7XG4gICAgY29ubmVjdGlvbi5vblB1Ymxpc2hEaWFnbm9zdGljcyh0aGlzLmNhcHR1cmVEaWFnbm9zdGljcy5iaW5kKHRoaXMpKVxuICB9XG5cbiAgLyoqIERpc3Bvc2UgdGhpcyBhZGFwdGVyIGVuc3VyaW5nIGFueSByZXNvdXJjZXMgYXJlIGZyZWVkIGFuZCBldmVudHMgdW5ob29rZWQuICovXG4gIHB1YmxpYyBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZGV0YWNoQWxsKClcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IEF0dGFjaCB0aGlzIHtMaW50ZXJQdXNoVjJBZGFwdGVyfSB0byBhIGdpdmVuIHtWMkluZGllRGVsZWdhdGV9IHJlZ2lzdHJ5LlxuICAgKlxuICAgKiBAcGFyYW0gaW5kaWUgQSB7VjJJbmRpZURlbGVnYXRlfSB0aGF0IHdhbnRzIHRvIHJlY2VpdmUgbWVzc2FnZXMuXG4gICAqL1xuICBwdWJsaWMgYXR0YWNoKGluZGllOiBsaW50ZXIuSW5kaWVEZWxlZ2F0ZSk6IHZvaWQge1xuICAgIHRoaXMuX2luZGllcy5hZGQoaW5kaWUpXG4gICAgdGhpcy5fZGlhZ25vc3RpY01hcC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiBpbmRpZS5zZXRNZXNzYWdlcyhrZXksIHZhbHVlKSlcbiAgICBpbmRpZS5vbkRpZERlc3Ryb3koKCkgPT4ge1xuICAgICAgdGhpcy5faW5kaWVzLmRlbGV0ZShpbmRpZSlcbiAgICB9KVxuICB9XG5cbiAgLyoqIFB1YmxpYzogUmVtb3ZlIGFsbCB7VjJJbmRpZURlbGVnYXRlfSByZWdpc3RyaWVzIGF0dGFjaGVkIHRvIHRoaXMgYWRhcHRlciBhbmQgY2xlYXIgdGhlbS4gKi9cbiAgcHVibGljIGRldGFjaEFsbCgpOiB2b2lkIHtcbiAgICB0aGlzLl9pbmRpZXMuZm9yRWFjaCgoaSkgPT4gaS5jbGVhck1lc3NhZ2VzKCkpXG4gICAgdGhpcy5faW5kaWVzLmNsZWFyKClcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IENhcHR1cmUgdGhlIGRpYWdub3N0aWNzIHNlbnQgZnJvbSBhIGxhbmdndWFnZSBzZXJ2ZXIsIGNvbnZlcnQgdGhlbSB0byB0aGUgTGludGVyIFYyIGZvcm1hdCBhbmQgZm9yd2FyZCB0aGVtXG4gICAqIG9uIHRvIGFueSBhdHRhY2hlZCB7VjJJbmRpZURlbGVnYXRlfXMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgVGhlIHtQdWJsaXNoRGlhZ25vc3RpY3NQYXJhbXN9IHJlY2VpdmVkIGZyb20gdGhlIGxhbmd1YWdlIHNlcnZlciB0aGF0IHNob3VsZCBiZSBjYXB0dXJlZCBhbmRcbiAgICogICBmb3J3YXJkZWQgb24gdG8gYW55IGF0dGFjaGVkIHtWMkluZGllRGVsZWdhdGV9cy5cbiAgICovXG4gIHB1YmxpYyBjYXB0dXJlRGlhZ25vc3RpY3MocGFyYW1zOiBQdWJsaXNoRGlhZ25vc3RpY3NQYXJhbXMpOiB2b2lkIHtcbiAgICBjb25zdCBwYXRoID0gQ29udmVydC51cmlUb1BhdGgocGFyYW1zLnVyaSlcbiAgICBjb25zdCBjb2RlTWFwID0gbmV3IE1hcDxzdHJpbmcsIERpYWdub3N0aWM+KClcbiAgICBjb25zdCBtZXNzYWdlcyA9IHBhcmFtcy5kaWFnbm9zdGljcy5tYXAoKGQpID0+IHtcbiAgICAgIGNvbnN0IGxpbnRlck1lc3NhZ2UgPSBsc0RpYWdub3N0aWNUb1YyTWVzc2FnZShwYXRoLCBkKVxuICAgICAgY29kZU1hcC5zZXQoZ2V0TWVzc2FnZUtleShsaW50ZXJNZXNzYWdlKSwgZClcbiAgICAgIHJldHVybiBsaW50ZXJNZXNzYWdlXG4gICAgfSlcbiAgICB0aGlzLl9kaWFnbm9zdGljTWFwLnNldChwYXRoLCBtZXNzYWdlcylcbiAgICB0aGlzLl9sc0RpYWdub3N0aWNNYXAuc2V0KHBhdGgsIGNvZGVNYXApXG4gICAgdGhpcy5faW5kaWVzLmZvckVhY2goKGkpID0+IGkuc2V0TWVzc2FnZXMocGF0aCwgbWVzc2FnZXMpKVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogQ29udmVydCBhIHNpbmdsZSB7RGlhZ25vc3RpY30gcmVjZWl2ZWQgZnJvbSBhIGxhbmd1YWdlIHNlcnZlciBpbnRvIGEgc2luZ2xlIHtWMk1lc3NhZ2V9IGV4cGVjdGVkIGJ5IHRoZVxuICAgKiBMaW50ZXIgVjIgQVBJLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHBhdGggb2YgdGhlIGZpbGUgdGhlIGRpYWdub3N0aWMgYmVsb25ncyB0by5cbiAgICogQHBhcmFtIGRpYWdub3N0aWNzIEEge0RpYWdub3N0aWN9IG9iamVjdCByZWNlaXZlZCBmcm9tIHRoZSBsYW5ndWFnZSBzZXJ2ZXIuXG4gICAqIEByZXR1cm5zIEEge1YyTWVzc2FnZX0gZXF1aXZhbGVudCB0byB0aGUge0RpYWdub3N0aWN9IG9iamVjdCBzdXBwbGllZCBieSB0aGUgbGFuZ3VhZ2Ugc2VydmVyLlxuICAgKi9cbiAgcHVibGljIGRpYWdub3N0aWNUb1YyTWVzc2FnZShwYXRoOiBzdHJpbmcsIGRpYWdub3N0aWM6IERpYWdub3N0aWMpOiBsaW50ZXIuTWVzc2FnZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxvY2F0aW9uOiB7XG4gICAgICAgIGZpbGU6IHBhdGgsXG4gICAgICAgIHBvc2l0aW9uOiBDb252ZXJ0LmxzUmFuZ2VUb0F0b21SYW5nZShkaWFnbm9zdGljLnJhbmdlKSxcbiAgICAgIH0sXG4gICAgICBleGNlcnB0OiBkaWFnbm9zdGljLm1lc3NhZ2UsXG4gICAgICBsaW50ZXJOYW1lOiBkaWFnbm9zdGljLnNvdXJjZSxcbiAgICAgIHNldmVyaXR5OiBMaW50ZXJQdXNoVjJBZGFwdGVyLmRpYWdub3N0aWNTZXZlcml0eVRvU2V2ZXJpdHkoZGlhZ25vc3RpYy5zZXZlcml0eSB8fCAtMSksXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogZ2V0IGRpYWdub3N0aWNzIGZvciB0aGUgZ2l2ZW4gbGludGVyIG1lc3NhZ2VzXG4gICAqXG4gICAqIEBwYXJhbSBsaW50ZXJNZXNzYWdlcyBBbiBhcnJheSBvZiBsaW50ZXIge1YyTWVzc2FnZX1cbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgTFMge0RpYWdub3N0aWNbXX1cbiAgICovXG4gIHB1YmxpYyBnZXRMU0RpYWdub3N0aWNzRm9yTWVzc2FnZXMobGludGVyTWVzc2FnZXM6IGxpbnRlci5NZXNzYWdlW10pOiBEaWFnbm9zdGljW10ge1xuICAgIHJldHVybiAoXG4gICAgICBsaW50ZXJNZXNzYWdlc1xuICAgICAgICAubWFwKHRoaXMuZ2V0TFNEaWFnbm9zdGljRm9yTWVzc2FnZSlcbiAgICAgICAgLy8gZmlsdGVyIG91dCB1bmRlZmluZWRcbiAgICAgICAgLmZpbHRlcigoZGlhZ25vc3RpYykgPT4gZGlhZ25vc3RpYyAhPT0gdW5kZWZpbmVkKSBhcyBEaWFnbm9zdGljW11cbiAgICApXG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBHZXQgdGhlIHtEaWFnbm9zdGljfSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gQmFzZSBMaW50ZXIgdjIge01lc3NhZ2V9LlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUge01lc3NhZ2V9IG9iamVjdCB0byBmZXRjaCB0aGUge0RpYWdub3N0aWN9IGZvci5cbiAgICogQHJldHVybnMgVGhlIGFzc29jaWF0ZWQge0RpYWdub3N0aWN9LlxuICAgKi9cbiAgcHVibGljIGdldExTRGlhZ25vc3RpY0Zvck1lc3NhZ2UobWVzc2FnZTogbGludGVyLk1lc3NhZ2UpOiBEaWFnbm9zdGljIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fbHNEaWFnbm9zdGljTWFwLmdldChtZXNzYWdlLmxvY2F0aW9uLmZpbGUpPy5nZXQoZ2V0TWVzc2FnZUtleShtZXNzYWdlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IENvbnZlcnQgYSBkaWFnbm9zdGljIHNldmVyaXR5IG51bWJlciBvYnRhaW5lZCBmcm9tIHRoZSBsYW5ndWFnZSBzZXJ2ZXIgaW50byB0aGUgdGV4dHVhbCBlcXVpdmFsZW50IGZvciBhXG4gICAqIExpbnRlciB7VjJNZXNzYWdlfS5cbiAgICpcbiAgICogQHBhcmFtIHNldmVyaXR5IEEgbnVtYmVyIHJlcHJlc2VudGluZyB0aGUgc2V2ZXJpdHkgb2YgdGhlIGRpYWdub3N0aWMuXG4gICAqIEByZXR1cm5zIEEgc3RyaW5nIG9mICdlcnJvcicsICd3YXJuaW5nJyBvciAnaW5mbycgZGVwZW5kaW5nIG9uIHRoZSBzZXZlcml0eS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZGlhZ25vc3RpY1NldmVyaXR5VG9TZXZlcml0eShzZXZlcml0eTogbnVtYmVyKTogXCJlcnJvclwiIHwgXCJ3YXJuaW5nXCIgfCBcImluZm9cIiB7XG4gICAgc3dpdGNoIChzZXZlcml0eSkge1xuICAgICAgY2FzZSBEaWFnbm9zdGljU2V2ZXJpdHkuRXJyb3I6XG4gICAgICAgIHJldHVybiBcImVycm9yXCJcbiAgICAgIGNhc2UgRGlhZ25vc3RpY1NldmVyaXR5Lldhcm5pbmc6XG4gICAgICAgIHJldHVybiBcIndhcm5pbmdcIlxuICAgICAgY2FzZSBEaWFnbm9zdGljU2V2ZXJpdHkuSW5mb3JtYXRpb246XG4gICAgICBjYXNlIERpYWdub3N0aWNTZXZlcml0eS5IaW50OlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFwiaW5mb1wiXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUHVibGljOiBDb252ZXJ0IGEgc2luZ2xlIHtEaWFnbm9zdGljfSByZWNlaXZlZCBmcm9tIGEgbGFuZ3VhZ2Ugc2VydmVyIGludG8gYSBzaW5nbGUge01lc3NhZ2V9IGV4cGVjdGVkIGJ5IHRoZSBMaW50ZXIgVjIgQVBJLlxuICpcbiAqIEBwYXJhbSBwYXRoIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcGF0aCBvZiB0aGUgZmlsZSB0aGUgZGlhZ25vc3RpYyBiZWxvbmdzIHRvLlxuICogQHBhcmFtIGRpYWdub3N0aWNzIEEge0RpYWdub3N0aWN9IG9iamVjdCByZWNlaXZlZCBmcm9tIHRoZSBsYW5ndWFnZSBzZXJ2ZXIuXG4gKiBAcmV0dXJucyBBIHtNZXNzYWdlfSBlcXVpdmFsZW50IHRvIHRoZSB7RGlhZ25vc3RpY30gb2JqZWN0IHN1cHBsaWVkIGJ5IHRoZSBsYW5ndWFnZSBzZXJ2ZXIuXG4gKi9cbmZ1bmN0aW9uIGxzRGlhZ25vc3RpY1RvVjJNZXNzYWdlKHBhdGg6IHN0cmluZywgZGlhZ25vc3RpYzogRGlhZ25vc3RpYyk6IGxpbnRlci5NZXNzYWdlIHtcbiAgcmV0dXJuIHtcbiAgICBsb2NhdGlvbjoge1xuICAgICAgZmlsZTogcGF0aCxcbiAgICAgIHBvc2l0aW9uOiBDb252ZXJ0LmxzUmFuZ2VUb0F0b21SYW5nZShkaWFnbm9zdGljLnJhbmdlKSxcbiAgICB9LFxuICAgIHJlZmVyZW5jZTogcmVsYXRlZEluZm9ybWF0aW9uVG9SZWZlcmVuY2UoZGlhZ25vc3RpYy5yZWxhdGVkSW5mb3JtYXRpb24pLFxuICAgIHVybDogZGlhZ25vc3RpYy5jb2RlRGVzY3JpcHRpb24/LmhyZWYsXG4gICAgaWNvbjogaWNvbkZvckxTU2V2ZXJpdHkoZGlhZ25vc3RpYy5zZXZlcml0eSA/PyBEaWFnbm9zdGljU2V2ZXJpdHkuRXJyb3IpLFxuICAgIGV4Y2VycHQ6IGRpYWdub3N0aWMubWVzc2FnZSxcbiAgICBsaW50ZXJOYW1lOiBkaWFnbm9zdGljLnNvdXJjZSxcbiAgICBzZXZlcml0eTogbHNTZXZlcml0eVRvVjJNZXNzYWdlU2V2ZXJpdHkoZGlhZ25vc3RpYy5zZXZlcml0eSA/PyBEaWFnbm9zdGljU2V2ZXJpdHkuRXJyb3IpLFxuICAgIC8vIEJMT0NLRUQ6IG9uIHN0ZWVsYnJhaW4vbGludGVyIzE3MjJcbiAgICBzb2x1dGlvbnM6IHVuZGVmaW5lZCxcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnQgYSBzZXZlcml0eSBsZXZlbCBvZiBhbiBMU1Age0RpYWdub3N0aWN9IHRvIHRoYXQgb2YgYSBCYXNlIExpbnRlciB2MiB7TWVzc2FnZX0uIE5vdGU6IHRoaXMgY29udmVyc2lvbiBpcyBsb3NzeVxuICogZHVlIHRvIHRoZSB2MiBNZXNzYWdlIG5vdCBiZWluZyBhYmxlIHRvIHJlcHJlc2VudCBoaW50cy5cbiAqXG4gKiBAcGFyYW0gc2V2ZXJpdHkgQSBzZXZlcml0eSBsZXZlbCBvZiBvZiBhbiBMU1Age0RpYWdub3N0aWN9IHRvIGJlIGNvbnZlcnRlZC5cbiAqIEByZXR1cm5zIEEgc2V2ZXJpdHkgbGV2ZWwgYSBCYXNlIExpbnRlciB2MiB7TWVzc2FnZX0uXG4gKi9cbmZ1bmN0aW9uIGxzU2V2ZXJpdHlUb1YyTWVzc2FnZVNldmVyaXR5KHNldmVyaXR5OiBEaWFnbm9zdGljU2V2ZXJpdHkpOiBsaW50ZXIuTWVzc2FnZVtcInNldmVyaXR5XCJdIHtcbiAgc3dpdGNoIChzZXZlcml0eSkge1xuICAgIGNhc2UgRGlhZ25vc3RpY1NldmVyaXR5LkVycm9yOlxuICAgICAgcmV0dXJuIFwiZXJyb3JcIlxuICAgIGNhc2UgRGlhZ25vc3RpY1NldmVyaXR5Lldhcm5pbmc6XG4gICAgICByZXR1cm4gXCJ3YXJuaW5nXCJcbiAgICBjYXNlIERpYWdub3N0aWNTZXZlcml0eS5JbmZvcm1hdGlvbjpcbiAgICBjYXNlIERpYWdub3N0aWNTZXZlcml0eS5IaW50OlxuICAgICAgcmV0dXJuIFwiaW5mb1wiXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IEVycm9yKGBVbmV4cGVjdGVkIGRpYWdub3N0aWMgc2V2ZXJpdHkgJyR7c2V2ZXJpdHl9J2ApXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0IGEgZGlhZ25vc3RpYyBzZXZlcml0eSBudW1iZXIgb2J0YWluZWQgZnJvbSB0aGUgbGFuZ3VhZ2Ugc2VydmVyIGludG8gYW4gT2N0aWNvbiBpY29uLlxuICpcbiAqIEBwYXJhbSBzZXZlcml0eSBBIG51bWJlciByZXByZXNlbnRpbmcgdGhlIHNldmVyaXR5IG9mIHRoZSBkaWFnbm9zdGljLlxuICogQHJldHVybnMgQW4gT2N0aWNvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBpY29uRm9yTFNTZXZlcml0eShzZXZlcml0eTogRGlhZ25vc3RpY1NldmVyaXR5KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgc3dpdGNoIChzZXZlcml0eSkge1xuICAgIGNhc2UgRGlhZ25vc3RpY1NldmVyaXR5LkVycm9yOlxuICAgICAgcmV0dXJuIFwic3RvcFwiXG4gICAgY2FzZSBEaWFnbm9zdGljU2V2ZXJpdHkuV2FybmluZzpcbiAgICAgIHJldHVybiBcIndhcm5pbmdcIlxuICAgIGNhc2UgRGlhZ25vc3RpY1NldmVyaXR5LkluZm9ybWF0aW9uOlxuICAgICAgcmV0dXJuIFwiaW5mb1wiXG4gICAgY2FzZSBEaWFnbm9zdGljU2V2ZXJpdHkuSGludDpcbiAgICAgIHJldHVybiBcImxpZ2h0LWJ1bGJcIlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0IHRoZSByZWxhdGVkIGluZm9ybWF0aW9uIGZyb20gYSBkaWFnbm9zdGljIGludG8gYSByZWZlcmVuY2UgcG9pbnQgZm9yIGEgTGludGVyIHtWMk1lc3NhZ2V9LlxuICpcbiAqIEBwYXJhbSByZWxhdGVkSW5mbyBTZXZlcmFsIHJlbGF0ZWQgaW5mb3JtYXRpb24gb2JqZWN0cyAob25seSB0aGUgZmlyc3QgaXMgdXNlZCkuXG4gKiBAcmV0dXJucyBBIHZhbHVlIHRoYXQgaXMgc3VpdGFibGUgZm9yIHVzaW5nIGFzIHtWMk1lc3NhZ2V9LnJlZmVyZW5jZS5cbiAqL1xuZnVuY3Rpb24gcmVsYXRlZEluZm9ybWF0aW9uVG9SZWZlcmVuY2UoXG4gIHJlbGF0ZWRJbmZvOiBEaWFnbm9zdGljUmVsYXRlZEluZm9ybWF0aW9uW10gfCB1bmRlZmluZWRcbik6IGxpbnRlci5NZXNzYWdlW1wicmVmZXJlbmNlXCJdIHtcbiAgaWYgKHJlbGF0ZWRJbmZvID09PSB1bmRlZmluZWQgfHwgcmVsYXRlZEluZm8ubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgY29uc3QgbG9jYXRpb24gPSByZWxhdGVkSW5mb1swXS5sb2NhdGlvblxuICByZXR1cm4ge1xuICAgIGZpbGU6IENvbnZlcnQudXJpVG9QYXRoKGxvY2F0aW9uLnVyaSksXG4gICAgcG9zaXRpb246IENvbnZlcnQubHNSYW5nZVRvQXRvbVJhbmdlKGxvY2F0aW9uLnJhbmdlKS5zdGFydCxcbiAgfVxufVxuXG4vKipcbiAqIEdldCBhIHVuaXF1ZSBrZXkgZm9yIGEgTGludGVyIHYyIE1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0gbWVzc2FnZSBBIHtNZXNzYWdlfSBvYmplY3RcbiAqIEByZXR1cm5zICR7c3RyaW5nfSBhIHVuaXF1ZSBrZXlcbiAqL1xuZnVuY3Rpb24gZ2V0TWVzc2FnZUtleShtZXNzYWdlOiBsaW50ZXIuTWVzc2FnZSk6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgbWVzc2FnZS5rZXkgIT09IFwic3RyaW5nXCIpIHtcbiAgICB1cGRhdGVNZXNzYWdlS2V5KG1lc3NhZ2UpXG4gIH1cbiAgcmV0dXJuIG1lc3NhZ2Uua2V5IGFzIHN0cmluZyAvLyB1cGRhdGVNZXNzYWdlS2V5IGFkZHMgbWVzc2FnZS5rZXkgc3RyaW5nXG59XG5cbi8qKlxuICogQ29uc3RydWN0IGFuIHVuaXF1ZSBrZXkgZm9yIGEgTGludGVyIHYyIE1lc3NhZ2UgYW5kIHN0b3JlIGl0IGluIGBNZXNzYWdlLmtleWBcbiAqXG4gKiBAcGFyYW0gbWVzc2FnZSBBIHtNZXNzYWdlfSBvYmplY3QgdG8gc2VyaWFsaXplLlxuICogQHJldHVybnMgJHtzdHJpbmd9IGEgdW5pcXVlIGtleVxuICovXG5mdW5jdGlvbiB1cGRhdGVNZXNzYWdlS2V5KG1lc3NhZ2U6IGxpbnRlci5NZXNzYWdlKTogdm9pZCB7XG4gIC8vIEZyb20gaHR0cHM6Ly9naXRodWIuY29tL3N0ZWVsYnJhaW4vbGludGVyL2Jsb2IvZmFkZDQ2MjkxNGVmMGE4ZWQ1YjczYTQ4OWY2NjJhOTM5M2JkYmU5Zi9saWIvaGVscGVycy50cyNMNTAtTDY0XG4gIGNvbnN0IHsgcmVmZXJlbmNlLCBsb2NhdGlvbiB9ID0gbWVzc2FnZVxuICBjb25zdCBuYW1lU3RyID0gYCRMSU5URVI6JHttZXNzYWdlLmxpbnRlck5hbWV9YFxuICBjb25zdCBsb2NhdGlvblN0ciA9IGAkTE9DQVRJT046JHtsb2NhdGlvbi5maWxlfSQke2xvY2F0aW9uLnBvc2l0aW9uLnN0YXJ0LnJvd30kJHtsb2NhdGlvbi5wb3NpdGlvbi5zdGFydC5jb2x1bW59JCR7bG9jYXRpb24ucG9zaXRpb24uZW5kLnJvd30kJHtsb2NhdGlvbi5wb3NpdGlvbi5lbmQuY29sdW1ufWBcbiAgY29uc3QgcmVmZXJlbmNlU3RyID0gcmVmZXJlbmNlXG4gICAgPyBgJFJFRkVSRU5DRToke3JlZmVyZW5jZS5maWxlfSQke1xuICAgICAgICByZWZlcmVuY2UucG9zaXRpb24gPyBgJHtyZWZlcmVuY2UucG9zaXRpb24ucm93fSQke3JlZmVyZW5jZS5wb3NpdGlvbi5jb2x1bW59YCA6IFwiXCJcbiAgICAgIH1gXG4gICAgOiBcIiRSRUZFUkVOQ0U6bnVsbFwiXG4gIGNvbnN0IGV4Y2VycHRTdHIgPSBgJEVYQ0VSUFQ6JHttZXNzYWdlLmV4Y2VycHR9YFxuICBjb25zdCBzZXZlcml0eVN0ciA9IGAkU0VWRVJJVFk6JHttZXNzYWdlLnNldmVyaXR5fWBcbiAgY29uc3QgaWNvblN0ciA9IG1lc3NhZ2UuaWNvbiA/IGAkSUNPTjoke21lc3NhZ2UuaWNvbn1gIDogXCIkSUNPTjpudWxsXCJcbiAgY29uc3QgdXJsU3RyID0gbWVzc2FnZS51cmwgPyBgJFVSTDoke21lc3NhZ2UudXJsfWAgOiBcIiRVUkw6bnVsbFwiXG4gIGNvbnN0IGRlc2NyaXB0aW9uU3RyID1cbiAgICB0eXBlb2YgbWVzc2FnZS5kZXNjcmlwdGlvbiA9PT0gXCJzdHJpbmdcIiA/IGAkREVTQ1JJUFRJT046JHttZXNzYWdlLmRlc2NyaXB0aW9ufWAgOiBcIiRERVNDUklQVElPTjpudWxsXCJcbiAgbWVzc2FnZS5rZXkgPSBgJHtuYW1lU3RyfSR7bG9jYXRpb25TdHJ9JHtyZWZlcmVuY2VTdHJ9JHtleGNlcnB0U3RyfSR7c2V2ZXJpdHlTdHJ9JHtpY29uU3RyfSR7dXJsU3RyfSR7ZGVzY3JpcHRpb25TdHJ9YFxufVxuIl19 |
\ | No newline at end of file |