UNPKG

23.1 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 return new (P || (P = Promise))(function (resolve, reject) {
5 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 step((generator = generator.apply(thisArg, _arguments || [])).next());
9 });
10};
11Object.defineProperty(exports, "__esModule", { value: true });
12const convert_1 = require("../convert");
13/** Public: Adapts the language server protocol "textDocument/completion" to the Atom IDE UI Code-format package. */
14class CodeFormatAdapter {
15 /**
16 * Public: Determine whether this adapter can be used to adapt a language server based on the serverCapabilities
17 * matrix containing either a documentFormattingProvider or a documentRangeFormattingProvider.
18 *
19 * @param serverCapabilities The {ServerCapabilities} of the language server to consider.
20 * @returns A {Boolean} indicating this adapter can adapt the server based on the given serverCapabilities.
21 */
22 static canAdapt(serverCapabilities) {
23 return (serverCapabilities.documentRangeFormattingProvider === true ||
24 serverCapabilities.documentFormattingProvider === true);
25 }
26 /**
27 * Public: Format text in the editor using the given language server connection and an optional range. If the server
28 * does not support range formatting then range will be ignored and the entire document formatted.
29 *
30 * @param connection A {LanguageClientConnection} to the language server that will format the text.
31 * @param serverCapabilities The {ServerCapabilities} of the language server that will be used.
32 * @param editor The Atom {TextEditor} containing the text that will be formatted.
33 * @param range The optional Atom {Range} containing the subset of the text to be formatted.
34 * @returns A {Promise} of an {Array} of {Object}s containing the AutoComplete+ suggestions to display.
35 */
36 static format(connection, serverCapabilities, editor, range) {
37 if (serverCapabilities.documentRangeFormattingProvider) {
38 return CodeFormatAdapter.formatRange(connection, editor, range);
39 }
40 if (serverCapabilities.documentFormattingProvider) {
41 return CodeFormatAdapter.formatDocument(connection, editor);
42 }
43 throw new Error("Can not format document, language server does not support it");
44 }
45 /**
46 * Public: Format the entire document of an Atom {TextEditor} by using a given language server.
47 *
48 * @param connection A {LanguageClientConnection} to the language server that will format the text.
49 * @param editor The Atom {TextEditor} containing the document to be formatted.
50 * @returns A {Promise} of an {Array} of {TextEdit} objects that can be applied to the Atom TextEditor to format the document.
51 */
52 static formatDocument(connection, editor) {
53 return __awaiter(this, void 0, void 0, function* () {
54 const edits = yield connection.documentFormatting(CodeFormatAdapter.createDocumentFormattingParams(editor));
55 return convert_1.default.convertLsTextEdits(edits);
56 });
57 }
58 /**
59 * Public: Create {DocumentFormattingParams} to be sent to the language server when requesting an entire document is formatted.
60 *
61 * @param editor The Atom {TextEditor} containing the document to be formatted.
62 * @returns A {DocumentFormattingParams} containing the identity of the text document as well as options to be used in
63 * formatting the document such as tab size and tabs vs spaces.
64 */
65 static createDocumentFormattingParams(editor) {
66 return {
67 textDocument: convert_1.default.editorToTextDocumentIdentifier(editor),
68 options: CodeFormatAdapter.getFormatOptions(editor),
69 };
70 }
71 /**
72 * Public: Format a range within an Atom {TextEditor} by using a given language server.
73 *
74 * @param connection A {LanguageClientConnection} to the language server that will format the text.
75 * @param range The Atom {Range} containing the range of text that should be formatted.
76 * @param editor The Atom {TextEditor} containing the document to be formatted.
77 * @returns A {Promise} of an {Array} of {TextEdit} objects that can be applied to the Atom TextEditor to format the document.
78 */
79 static formatRange(connection, editor, range) {
80 return __awaiter(this, void 0, void 0, function* () {
81 const edits = yield connection.documentRangeFormatting(CodeFormatAdapter.createDocumentRangeFormattingParams(editor, range));
82 return convert_1.default.convertLsTextEdits(edits);
83 });
84 }
85 /**
86 * Public: Create {DocumentRangeFormattingParams} to be sent to the language server when requesting an entire document
87 * is formatted.
88 *
89 * @param editor The Atom {TextEditor} containing the document to be formatted.
90 * @param range The Atom {Range} containing the range of text that should be formatted.
91 * @returns A {DocumentRangeFormattingParams} containing the identity of the text document, the range of the text to
92 * be formatted as well as the options to be used in formatting the document such as tab size and tabs vs spaces.
93 */
94 static createDocumentRangeFormattingParams(editor, range) {
95 return {
96 textDocument: convert_1.default.editorToTextDocumentIdentifier(editor),
97 range: convert_1.default.atomRangeToLSRange(range),
98 options: CodeFormatAdapter.getFormatOptions(editor),
99 };
100 }
101 /**
102 * Public: Format on type within an Atom {TextEditor} by using a given language server.
103 *
104 * @param connection A {LanguageClientConnection} to the language server that will format the text.
105 * @param editor The Atom {TextEditor} containing the document to be formatted.
106 * @param point The {Point} at which the document to be formatted.
107 * @param character A character that triggered formatting request.
108 * @returns A {Promise} of an {Array} of {TextEdit} objects that can be applied to the Atom TextEditor to format the document.
109 */
110 static formatOnType(connection, editor, point, character) {
111 return __awaiter(this, void 0, void 0, function* () {
112 const edits = yield connection.documentOnTypeFormatting(CodeFormatAdapter.createDocumentOnTypeFormattingParams(editor, point, character));
113 return convert_1.default.convertLsTextEdits(edits);
114 });
115 }
116 /**
117 * Public: Create {DocumentOnTypeFormattingParams} to be sent to the language server when requesting an entire
118 * document is formatted.
119 *
120 * @param editor The Atom {TextEditor} containing the document to be formatted.
121 * @param point The {Point} at which the document to be formatted.
122 * @param character A character that triggered formatting request.
123 * @returns A {DocumentOnTypeFormattingParams} containing the identity of the text document, the position of the text
124 * to be formatted, the character that triggered formatting request as well as the options to be used in formatting
125 * the document such as tab size and tabs vs spaces.
126 */
127 static createDocumentOnTypeFormattingParams(editor, point, character) {
128 return {
129 textDocument: convert_1.default.editorToTextDocumentIdentifier(editor),
130 position: convert_1.default.pointToPosition(point),
131 ch: character,
132 options: CodeFormatAdapter.getFormatOptions(editor),
133 };
134 }
135 /**
136 * Public: Create {DocumentRangeFormattingParams} to be sent to the language server when requesting an entire document
137 * is formatted.
138 *
139 * @param editor The Atom {TextEditor} containing the document to be formatted.
140 * @param range The Atom {Range} containing the range of document that should be formatted.
141 * @returns The {FormattingOptions} to be used containing the keys:
142 *
143 * - `tabSize` The number of spaces a tab represents.
144 * - `insertSpaces` {True} if spaces should be used, {False} for tab characters.
145 */
146 static getFormatOptions(editor) {
147 return {
148 tabSize: editor.getTabLength(),
149 insertSpaces: editor.getSoftTabs(),
150 };
151 }
152}
153exports.default = CodeFormatAdapter;
154//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1mb3JtYXQtYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9hZGFwdGVycy9jb2RlLWZvcm1hdC1hZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQ0Esd0NBQWdDO0FBV2hDLG9IQUFvSDtBQUNwSCxNQUFxQixpQkFBaUI7SUFDcEM7Ozs7OztPQU1HO0lBQ0ksTUFBTSxDQUFDLFFBQVEsQ0FBQyxrQkFBc0M7UUFDM0QsT0FBTyxDQUNMLGtCQUFrQixDQUFDLCtCQUErQixLQUFLLElBQUk7WUFDM0Qsa0JBQWtCLENBQUMsMEJBQTBCLEtBQUssSUFBSSxDQUN2RCxDQUFBO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLE1BQU0sQ0FBQyxNQUFNLENBQ2xCLFVBQW9DLEVBQ3BDLGtCQUFzQyxFQUN0QyxNQUFrQixFQUNsQixLQUFZO1FBRVosSUFBSSxrQkFBa0IsQ0FBQywrQkFBK0IsRUFBRTtZQUN0RCxPQUFPLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFBO1NBQ2hFO1FBRUQsSUFBSSxrQkFBa0IsQ0FBQywwQkFBMEIsRUFBRTtZQUNqRCxPQUFPLGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUE7U0FDNUQ7UUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUE7SUFDakYsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLE1BQU0sQ0FBTyxjQUFjLENBQ2hDLFVBQW9DLEVBQ3BDLE1BQWtCOztZQUVsQixNQUFNLEtBQUssR0FBRyxNQUFNLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxpQkFBaUIsQ0FBQyw4QkFBOEIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO1lBQzNHLE9BQU8saUJBQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUMxQyxDQUFDO0tBQUE7SUFFRDs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsOEJBQThCLENBQUMsTUFBa0I7UUFDN0QsT0FBTztZQUNMLFlBQVksRUFBRSxpQkFBTyxDQUFDLDhCQUE4QixDQUFDLE1BQU0sQ0FBQztZQUM1RCxPQUFPLEVBQUUsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDO1NBQ3BELENBQUE7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLE1BQU0sQ0FBTyxXQUFXLENBQzdCLFVBQW9DLEVBQ3BDLE1BQWtCLEVBQ2xCLEtBQVk7O1lBRVosTUFBTSxLQUFLLEdBQUcsTUFBTSxVQUFVLENBQUMsdUJBQXVCLENBQ3BELGlCQUFpQixDQUFDLG1DQUFtQyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FDckUsQ0FBQTtZQUNELE9BQU8saUJBQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUMxQyxDQUFDO0tBQUE7SUFFRDs7Ozs7Ozs7T0FRRztJQUNJLE1BQU0sQ0FBQyxtQ0FBbUMsQ0FBQyxNQUFrQixFQUFFLEtBQVk7UUFDaEYsT0FBTztZQUNMLFlBQVksRUFBRSxpQkFBTyxDQUFDLDhCQUE4QixDQUFDLE1BQU0sQ0FBQztZQUM1RCxLQUFLLEVBQUUsaUJBQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7WUFDeEMsT0FBTyxFQUFFLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztTQUNwRCxDQUFBO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksTUFBTSxDQUFPLFlBQVksQ0FDOUIsVUFBb0MsRUFDcEMsTUFBa0IsRUFDbEIsS0FBWSxFQUNaLFNBQWlCOztZQUVqQixNQUFNLEtBQUssR0FBRyxNQUFNLFVBQVUsQ0FBQyx3QkFBd0IsQ0FDckQsaUJBQWlCLENBQUMsb0NBQW9DLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FDakYsQ0FBQTtZQUNELE9BQU8saUJBQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUMxQyxDQUFDO0tBQUE7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksTUFBTSxDQUFDLG9DQUFvQyxDQUNoRCxNQUFrQixFQUNsQixLQUFZLEVBQ1osU0FBaUI7UUFFakIsT0FBTztZQUNMLFlBQVksRUFBRSxpQkFBTyxDQUFDLDhCQUE4QixDQUFDLE1BQU0sQ0FBQztZQUM1RCxRQUFRLEVBQUUsaUJBQU8sQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDO1lBQ3hDLEVBQUUsRUFBRSxTQUFTO1lBQ2IsT0FBTyxFQUFFLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztTQUNwRCxDQUFBO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBa0I7UUFDL0MsT0FBTztZQUNMLE9BQU8sRUFBRSxNQUFNLENBQUMsWUFBWSxFQUFFO1lBQzlCLFlBQVksRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFO1NBQ25DLENBQUE7SUFDSCxDQUFDO0NBQ0Y7QUF6S0Qsb0NBeUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgKiBhcyBhdG9tSWRlIGZyb20gXCJhdG9tLWlkZS1iYXNlXCJcbmltcG9ydCBDb252ZXJ0IGZyb20gXCIuLi9jb252ZXJ0XCJcbmltcG9ydCB7XG4gIExhbmd1YWdlQ2xpZW50Q29ubmVjdGlvbixcbiAgRG9jdW1lbnRGb3JtYXR0aW5nUGFyYW1zLFxuICBEb2N1bWVudFJhbmdlRm9ybWF0dGluZ1BhcmFtcyxcbiAgRG9jdW1lbnRPblR5cGVGb3JtYXR0aW5nUGFyYW1zLFxuICBGb3JtYXR0aW5nT3B0aW9ucyxcbiAgU2VydmVyQ2FwYWJpbGl0aWVzLFxufSBmcm9tIFwiLi4vbGFuZ3VhZ2VjbGllbnRcIlxuaW1wb3J0IHsgVGV4dEVkaXRvciwgUmFuZ2UsIFBvaW50IH0gZnJvbSBcImF0b21cIlxuXG4vKiogUHVibGljOiBBZGFwdHMgdGhlIGxhbmd1YWdlIHNlcnZlciBwcm90b2NvbCBcInRleHREb2N1bWVudC9jb21wbGV0aW9uXCIgdG8gdGhlIEF0b20gSURFIFVJIENvZGUtZm9ybWF0IHBhY2thZ2UuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2RlRm9ybWF0QWRhcHRlciB7XG4gIC8qKlxuICAgKiBQdWJsaWM6IERldGVybWluZSB3aGV0aGVyIHRoaXMgYWRhcHRlciBjYW4gYmUgdXNlZCB0byBhZGFwdCBhIGxhbmd1YWdlIHNlcnZlciBiYXNlZCBvbiB0aGUgc2VydmVyQ2FwYWJpbGl0aWVzXG4gICAqIG1hdHJpeCBjb250YWluaW5nIGVpdGhlciBhIGRvY3VtZW50Rm9ybWF0dGluZ1Byb3ZpZGVyIG9yIGEgZG9jdW1lbnRSYW5nZUZvcm1hdHRpbmdQcm92aWRlci5cbiAgICpcbiAgICogQHBhcmFtIHNlcnZlckNhcGFiaWxpdGllcyBUaGUge1NlcnZlckNhcGFiaWxpdGllc30gb2YgdGhlIGxhbmd1YWdlIHNlcnZlciB0byBjb25zaWRlci5cbiAgICogQHJldHVybnMgQSB7Qm9vbGVhbn0gaW5kaWNhdGluZyB0aGlzIGFkYXB0ZXIgY2FuIGFkYXB0IHRoZSBzZXJ2ZXIgYmFzZWQgb24gdGhlIGdpdmVuIHNlcnZlckNhcGFiaWxpdGllcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY2FuQWRhcHQoc2VydmVyQ2FwYWJpbGl0aWVzOiBTZXJ2ZXJDYXBhYmlsaXRpZXMpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgc2VydmVyQ2FwYWJpbGl0aWVzLmRvY3VtZW50UmFuZ2VGb3JtYXR0aW5nUHJvdmlkZXIgPT09IHRydWUgfHxcbiAgICAgIHNlcnZlckNhcGFiaWxpdGllcy5kb2N1bWVudEZvcm1hdHRpbmdQcm92aWRlciA9PT0gdHJ1ZVxuICAgIClcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IEZvcm1hdCB0ZXh0IGluIHRoZSBlZGl0b3IgdXNpbmcgdGhlIGdpdmVuIGxhbmd1YWdlIHNlcnZlciBjb25uZWN0aW9uIGFuZCBhbiBvcHRpb25hbCByYW5nZS4gSWYgdGhlIHNlcnZlclxuICAgKiBkb2VzIG5vdCBzdXBwb3J0IHJhbmdlIGZvcm1hdHRpbmcgdGhlbiByYW5nZSB3aWxsIGJlIGlnbm9yZWQgYW5kIHRoZSBlbnRpcmUgZG9jdW1lbnQgZm9ybWF0dGVkLlxuICAgKlxuICAgKiBAcGFyYW0gY29ubmVjdGlvbiBBIHtMYW5ndWFnZUNsaWVudENvbm5lY3Rpb259IHRvIHRoZSBsYW5ndWFnZSBzZXJ2ZXIgdGhhdCB3aWxsIGZvcm1hdCB0aGUgdGV4dC5cbiAgICogQHBhcmFtIHNlcnZlckNhcGFiaWxpdGllcyBUaGUge1NlcnZlckNhcGFiaWxpdGllc30gb2YgdGhlIGxhbmd1YWdlIHNlcnZlciB0aGF0IHdpbGwgYmUgdXNlZC5cbiAgICogQHBhcmFtIGVkaXRvciBUaGUgQXRvbSB7VGV4dEVkaXRvcn0gY29udGFpbmluZyB0aGUgdGV4dCB0aGF0IHdpbGwgYmUgZm9ybWF0dGVkLlxuICAgKiBAcGFyYW0gcmFuZ2UgVGhlIG9wdGlvbmFsIEF0b20ge1JhbmdlfSBjb250YWluaW5nIHRoZSBzdWJzZXQgb2YgdGhlIHRleHQgdG8gYmUgZm9ybWF0dGVkLlxuICAgKiBAcmV0dXJucyBBIHtQcm9taXNlfSBvZiBhbiB7QXJyYXl9IG9mIHtPYmplY3R9cyBjb250YWluaW5nIHRoZSBBdXRvQ29tcGxldGUrIHN1Z2dlc3Rpb25zIHRvIGRpc3BsYXkuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZvcm1hdChcbiAgICBjb25uZWN0aW9uOiBMYW5ndWFnZUNsaWVudENvbm5lY3Rpb24sXG4gICAgc2VydmVyQ2FwYWJpbGl0aWVzOiBTZXJ2ZXJDYXBhYmlsaXRpZXMsXG4gICAgZWRpdG9yOiBUZXh0RWRpdG9yLFxuICAgIHJhbmdlOiBSYW5nZVxuICApOiBQcm9taXNlPGF0b21JZGUuVGV4dEVkaXRbXT4ge1xuICAgIGlmIChzZXJ2ZXJDYXBhYmlsaXRpZXMuZG9jdW1lbnRSYW5nZUZvcm1hdHRpbmdQcm92aWRlcikge1xuICAgICAgcmV0dXJuIENvZGVGb3JtYXRBZGFwdGVyLmZvcm1hdFJhbmdlKGNvbm5lY3Rpb24sIGVkaXRvciwgcmFuZ2UpXG4gICAgfVxuXG4gICAgaWYgKHNlcnZlckNhcGFiaWxpdGllcy5kb2N1bWVudEZvcm1hdHRpbmdQcm92aWRlcikge1xuICAgICAgcmV0dXJuIENvZGVGb3JtYXRBZGFwdGVyLmZvcm1hdERvY3VtZW50KGNvbm5lY3Rpb24sIGVkaXRvcilcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4gbm90IGZvcm1hdCBkb2N1bWVudCwgbGFuZ3VhZ2Ugc2VydmVyIGRvZXMgbm90IHN1cHBvcnQgaXRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IEZvcm1hdCB0aGUgZW50aXJlIGRvY3VtZW50IG9mIGFuIEF0b20ge1RleHRFZGl0b3J9IGJ5IHVzaW5nIGEgZ2l2ZW4gbGFuZ3VhZ2Ugc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0gY29ubmVjdGlvbiBBIHtMYW5ndWFnZUNsaWVudENvbm5lY3Rpb259IHRvIHRoZSBsYW5ndWFnZSBzZXJ2ZXIgdGhhdCB3aWxsIGZvcm1hdCB0aGUgdGV4dC5cbiAgICogQHBhcmFtIGVkaXRvciBUaGUgQXRvbSB7VGV4dEVkaXRvcn0gY29udGFpbmluZyB0aGUgZG9jdW1lbnQgdG8gYmUgZm9ybWF0dGVkLlxuICAgKiBAcmV0dXJucyBBIHtQcm9taXNlfSBvZiBhbiB7QXJyYXl9IG9mIHtUZXh0RWRpdH0gb2JqZWN0cyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIHRoZSBBdG9tIFRleHRFZGl0b3IgdG8gZm9ybWF0IHRoZSBkb2N1bWVudC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZm9ybWF0RG9jdW1lbnQoXG4gICAgY29ubmVjdGlvbjogTGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9uLFxuICAgIGVkaXRvcjogVGV4dEVkaXRvclxuICApOiBQcm9taXNlPGF0b21JZGUuVGV4dEVkaXRbXT4ge1xuICAgIGNvbnN0IGVkaXRzID0gYXdhaXQgY29ubmVjdGlvbi5kb2N1bWVudEZvcm1hdHRpbmcoQ29kZUZvcm1hdEFkYXB0ZXIuY3JlYXRlRG9jdW1lbnRGb3JtYXR0aW5nUGFyYW1zKGVkaXRvcikpXG4gICAgcmV0dXJuIENvbnZlcnQuY29udmVydExzVGV4dEVkaXRzKGVkaXRzKVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogQ3JlYXRlIHtEb2N1bWVudEZvcm1hdHRpbmdQYXJhbXN9IHRvIGJlIHNlbnQgdG8gdGhlIGxhbmd1YWdlIHNlcnZlciB3aGVuIHJlcXVlc3RpbmcgYW4gZW50aXJlIGRvY3VtZW50IGlzIGZvcm1hdHRlZC5cbiAgICpcbiAgICogQHBhcmFtIGVkaXRvciBUaGUgQXRvbSB7VGV4dEVkaXRvcn0gY29udGFpbmluZyB0aGUgZG9jdW1lbnQgdG8gYmUgZm9ybWF0dGVkLlxuICAgKiBAcmV0dXJucyBBIHtEb2N1bWVudEZvcm1hdHRpbmdQYXJhbXN9IGNvbnRhaW5pbmcgdGhlIGlkZW50aXR5IG9mIHRoZSB0ZXh0IGRvY3VtZW50IGFzIHdlbGwgYXMgb3B0aW9ucyB0byBiZSB1c2VkIGluXG4gICAqICAgZm9ybWF0dGluZyB0aGUgZG9jdW1lbnQgc3VjaCBhcyB0YWIgc2l6ZSBhbmQgdGFicyB2cyBzcGFjZXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNyZWF0ZURvY3VtZW50Rm9ybWF0dGluZ1BhcmFtcyhlZGl0b3I6IFRleHRFZGl0b3IpOiBEb2N1bWVudEZvcm1hdHRpbmdQYXJhbXMge1xuICAgIHJldHVybiB7XG4gICAgICB0ZXh0RG9jdW1lbnQ6IENvbnZlcnQuZWRpdG9yVG9UZXh0RG9jdW1lbnRJZGVudGlmaWVyKGVkaXRvciksXG4gICAgICBvcHRpb25zOiBDb2RlRm9ybWF0QWRhcHRlci5nZXRGb3JtYXRPcHRpb25zKGVkaXRvciksXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogRm9ybWF0IGEgcmFuZ2Ugd2l0aGluIGFuIEF0b20ge1RleHRFZGl0b3J9IGJ5IHVzaW5nIGEgZ2l2ZW4gbGFuZ3VhZ2Ugc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0gY29ubmVjdGlvbiBBIHtMYW5ndWFnZUNsaWVudENvbm5lY3Rpb259IHRvIHRoZSBsYW5ndWFnZSBzZXJ2ZXIgdGhhdCB3aWxsIGZvcm1hdCB0aGUgdGV4dC5cbiAgICogQHBhcmFtIHJhbmdlIFRoZSBBdG9tIHtSYW5nZX0gY29udGFpbmluZyB0aGUgcmFuZ2Ugb2YgdGV4dCB0aGF0IHNob3VsZCBiZSBmb3JtYXR0ZWQuXG4gICAqIEBwYXJhbSBlZGl0b3IgVGhlIEF0b20ge1RleHRFZGl0b3J9IGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50IHRvIGJlIGZvcm1hdHRlZC5cbiAgICogQHJldHVybnMgQSB7UHJvbWlzZX0gb2YgYW4ge0FycmF5fSBvZiB7VGV4dEVkaXR9IG9iamVjdHMgdGhhdCBjYW4gYmUgYXBwbGllZCB0byB0aGUgQXRvbSBUZXh0RWRpdG9yIHRvIGZvcm1hdCB0aGUgZG9jdW1lbnQuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGZvcm1hdFJhbmdlKFxuICAgIGNvbm5lY3Rpb246IExhbmd1YWdlQ2xpZW50Q29ubmVjdGlvbixcbiAgICBlZGl0b3I6IFRleHRFZGl0b3IsXG4gICAgcmFuZ2U6IFJhbmdlXG4gICk6IFByb21pc2U8YXRvbUlkZS5UZXh0RWRpdFtdPiB7XG4gICAgY29uc3QgZWRpdHMgPSBhd2FpdCBjb25uZWN0aW9uLmRvY3VtZW50UmFuZ2VGb3JtYXR0aW5nKFxuICAgICAgQ29kZUZvcm1hdEFkYXB0ZXIuY3JlYXRlRG9jdW1lbnRSYW5nZUZvcm1hdHRpbmdQYXJhbXMoZWRpdG9yLCByYW5nZSlcbiAgICApXG4gICAgcmV0dXJuIENvbnZlcnQuY29udmVydExzVGV4dEVkaXRzKGVkaXRzKVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogQ3JlYXRlIHtEb2N1bWVudFJhbmdlRm9ybWF0dGluZ1BhcmFtc30gdG8gYmUgc2VudCB0byB0aGUgbGFuZ3VhZ2Ugc2VydmVyIHdoZW4gcmVxdWVzdGluZyBhbiBlbnRpcmUgZG9jdW1lbnRcbiAgICogaXMgZm9ybWF0dGVkLlxuICAgKlxuICAgKiBAcGFyYW0gZWRpdG9yIFRoZSBBdG9tIHtUZXh0RWRpdG9yfSBjb250YWluaW5nIHRoZSBkb2N1bWVudCB0byBiZSBmb3JtYXR0ZWQuXG4gICAqIEBwYXJhbSByYW5nZSBUaGUgQXRvbSB7UmFuZ2V9IGNvbnRhaW5pbmcgdGhlIHJhbmdlIG9mIHRleHQgdGhhdCBzaG91bGQgYmUgZm9ybWF0dGVkLlxuICAgKiBAcmV0dXJucyBBIHtEb2N1bWVudFJhbmdlRm9ybWF0dGluZ1BhcmFtc30gY29udGFpbmluZyB0aGUgaWRlbnRpdHkgb2YgdGhlIHRleHQgZG9jdW1lbnQsIHRoZSByYW5nZSBvZiB0aGUgdGV4dCB0b1xuICAgKiAgIGJlIGZvcm1hdHRlZCBhcyB3ZWxsIGFzIHRoZSBvcHRpb25zIHRvIGJlIHVzZWQgaW4gZm9ybWF0dGluZyB0aGUgZG9jdW1lbnQgc3VjaCBhcyB0YWIgc2l6ZSBhbmQgdGFicyB2cyBzcGFjZXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNyZWF0ZURvY3VtZW50UmFuZ2VGb3JtYXR0aW5nUGFyYW1zKGVkaXRvcjogVGV4dEVkaXRvciwgcmFuZ2U6IFJhbmdlKTogRG9jdW1lbnRSYW5nZUZvcm1hdHRpbmdQYXJhbXMge1xuICAgIHJldHVybiB7XG4gICAgICB0ZXh0RG9jdW1lbnQ6IENvbnZlcnQuZWRpdG9yVG9UZXh0RG9jdW1lbnRJZGVudGlmaWVyKGVkaXRvciksXG4gICAgICByYW5nZTogQ29udmVydC5hdG9tUmFuZ2VUb0xTUmFuZ2UocmFuZ2UpLFxuICAgICAgb3B0aW9uczogQ29kZUZvcm1hdEFkYXB0ZXIuZ2V0Rm9ybWF0T3B0aW9ucyhlZGl0b3IpLFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IEZvcm1hdCBvbiB0eXBlIHdpdGhpbiBhbiBBdG9tIHtUZXh0RWRpdG9yfSBieSB1c2luZyBhIGdpdmVuIGxhbmd1YWdlIHNlcnZlci5cbiAgICpcbiAgICogQHBhcmFtIGNvbm5lY3Rpb24gQSB7TGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9ufSB0byB0aGUgbGFuZ3VhZ2Ugc2VydmVyIHRoYXQgd2lsbCBmb3JtYXQgdGhlIHRleHQuXG4gICAqIEBwYXJhbSBlZGl0b3IgVGhlIEF0b20ge1RleHRFZGl0b3J9IGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50IHRvIGJlIGZvcm1hdHRlZC5cbiAgICogQHBhcmFtIHBvaW50IFRoZSB7UG9pbnR9IGF0IHdoaWNoIHRoZSBkb2N1bWVudCB0byBiZSBmb3JtYXR0ZWQuXG4gICAqIEBwYXJhbSBjaGFyYWN0ZXIgQSBjaGFyYWN0ZXIgdGhhdCB0cmlnZ2VyZWQgZm9ybWF0dGluZyByZXF1ZXN0LlxuICAgKiBAcmV0dXJucyBBIHtQcm9taXNlfSBvZiBhbiB7QXJyYXl9IG9mIHtUZXh0RWRpdH0gb2JqZWN0cyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIHRoZSBBdG9tIFRleHRFZGl0b3IgdG8gZm9ybWF0IHRoZSBkb2N1bWVudC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZm9ybWF0T25UeXBlKFxuICAgIGNvbm5lY3Rpb246IExhbmd1YWdlQ2xpZW50Q29ubmVjdGlvbixcbiAgICBlZGl0b3I6IFRleHRFZGl0b3IsXG4gICAgcG9pbnQ6IFBvaW50LFxuICAgIGNoYXJhY3Rlcjogc3RyaW5nXG4gICk6IFByb21pc2U8YXRvbUlkZS5UZXh0RWRpdFtdPiB7XG4gICAgY29uc3QgZWRpdHMgPSBhd2FpdCBjb25uZWN0aW9uLmRvY3VtZW50T25UeXBlRm9ybWF0dGluZyhcbiAgICAgIENvZGVGb3JtYXRBZGFwdGVyLmNyZWF0ZURvY3VtZW50T25UeXBlRm9ybWF0dGluZ1BhcmFtcyhlZGl0b3IsIHBvaW50LCBjaGFyYWN0ZXIpXG4gICAgKVxuICAgIHJldHVybiBDb252ZXJ0LmNvbnZlcnRMc1RleHRFZGl0cyhlZGl0cylcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IENyZWF0ZSB7RG9jdW1lbnRPblR5cGVGb3JtYXR0aW5nUGFyYW1zfSB0byBiZSBzZW50IHRvIHRoZSBsYW5ndWFnZSBzZXJ2ZXIgd2hlbiByZXF1ZXN0aW5nIGFuIGVudGlyZVxuICAgKiBkb2N1bWVudCBpcyBmb3JtYXR0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBlZGl0b3IgVGhlIEF0b20ge1RleHRFZGl0b3J9IGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50IHRvIGJlIGZvcm1hdHRlZC5cbiAgICogQHBhcmFtIHBvaW50IFRoZSB7UG9pbnR9IGF0IHdoaWNoIHRoZSBkb2N1bWVudCB0byBiZSBmb3JtYXR0ZWQuXG4gICAqIEBwYXJhbSBjaGFyYWN0ZXIgQSBjaGFyYWN0ZXIgdGhhdCB0cmlnZ2VyZWQgZm9ybWF0dGluZyByZXF1ZXN0LlxuICAgKiBAcmV0dXJucyBBIHtEb2N1bWVudE9uVHlwZUZvcm1hdHRpbmdQYXJhbXN9IGNvbnRhaW5pbmcgdGhlIGlkZW50aXR5IG9mIHRoZSB0ZXh0IGRvY3VtZW50LCB0aGUgcG9zaXRpb24gb2YgdGhlIHRleHRcbiAgICogICB0byBiZSBmb3JtYXR0ZWQsIHRoZSBjaGFyYWN0ZXIgdGhhdCB0cmlnZ2VyZWQgZm9ybWF0dGluZyByZXF1ZXN0IGFzIHdlbGwgYXMgdGhlIG9wdGlvbnMgdG8gYmUgdXNlZCBpbiBmb3JtYXR0aW5nXG4gICAqICAgdGhlIGRvY3VtZW50IHN1Y2ggYXMgdGFiIHNpemUgYW5kIHRhYnMgdnMgc3BhY2VzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjcmVhdGVEb2N1bWVudE9uVHlwZUZvcm1hdHRpbmdQYXJhbXMoXG4gICAgZWRpdG9yOiBUZXh0RWRpdG9yLFxuICAgIHBvaW50OiBQb2ludCxcbiAgICBjaGFyYWN0ZXI6IHN0cmluZ1xuICApOiBEb2N1bWVudE9uVHlwZUZvcm1hdHRpbmdQYXJhbXMge1xuICAgIHJldHVybiB7XG4gICAgICB0ZXh0RG9jdW1lbnQ6IENvbnZlcnQuZWRpdG9yVG9UZXh0RG9jdW1lbnRJZGVudGlmaWVyKGVkaXRvciksXG4gICAgICBwb3NpdGlvbjogQ29udmVydC5wb2ludFRvUG9zaXRpb24ocG9pbnQpLFxuICAgICAgY2g6IGNoYXJhY3RlcixcbiAgICAgIG9wdGlvbnM6IENvZGVGb3JtYXRBZGFwdGVyLmdldEZvcm1hdE9wdGlvbnMoZWRpdG9yKSxcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBDcmVhdGUge0RvY3VtZW50UmFuZ2VGb3JtYXR0aW5nUGFyYW1zfSB0byBiZSBzZW50IHRvIHRoZSBsYW5ndWFnZSBzZXJ2ZXIgd2hlbiByZXF1ZXN0aW5nIGFuIGVudGlyZSBkb2N1bWVudFxuICAgKiBpcyBmb3JtYXR0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBlZGl0b3IgVGhlIEF0b20ge1RleHRFZGl0b3J9IGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50IHRvIGJlIGZvcm1hdHRlZC5cbiAgICogQHBhcmFtIHJhbmdlIFRoZSBBdG9tIHtSYW5nZX0gY29udGFpbmluZyB0aGUgcmFuZ2Ugb2YgZG9jdW1lbnQgdGhhdCBzaG91bGQgYmUgZm9ybWF0dGVkLlxuICAgKiBAcmV0dXJucyBUaGUge0Zvcm1hdHRpbmdPcHRpb25zfSB0byBiZSB1c2VkIGNvbnRhaW5pbmcgdGhlIGtleXM6XG4gICAqXG4gICAqICAgLSBgdGFiU2l6ZWAgVGhlIG51bWJlciBvZiBzcGFjZXMgYSB0YWIgcmVwcmVzZW50cy5cbiAgICogICAtIGBpbnNlcnRTcGFjZXNgIHtUcnVlfSBpZiBzcGFjZXMgc2hvdWxkIGJlIHVzZWQsIHtGYWxzZX0gZm9yIHRhYiBjaGFyYWN0ZXJzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRGb3JtYXRPcHRpb25zKGVkaXRvcjogVGV4dEVkaXRvcik6IEZvcm1hdHRpbmdPcHRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGFiU2l6ZTogZWRpdG9yLmdldFRhYkxlbmd0aCgpLFxuICAgICAgaW5zZXJ0U3BhY2VzOiBlZGl0b3IuZ2V0U29mdFRhYnMoKSxcbiAgICB9XG4gIH1cbn1cbiJdfQ==
\No newline at end of file