@koobiq/components 18.10.0 → 18.12.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 (162) hide show
  1. package/autocomplete/autocomplete-trigger.directive.d.ts +0 -1
  2. package/autocomplete/autocomplete.scss +2 -10
  3. package/button/button-tokens.scss +1 -1
  4. package/code-block/_code-block-theme.scss +35 -54
  5. package/code-block/code-block-highlight.d.ts +44 -0
  6. package/code-block/code-block-tokens.scss +7 -11
  7. package/code-block/code-block.d.ts +187 -0
  8. package/code-block/code-block.module.d.ts +2 -8
  9. package/code-block/code-block.scss +103 -127
  10. package/code-block/public-api.d.ts +3 -2
  11. package/code-block/types.d.ts +27 -0
  12. package/core/common-behaviors/error-state.d.ts +3 -3
  13. package/core/error/error-state-matcher.d.ts +3 -0
  14. package/core/locales/index.d.ts +1 -0
  15. package/core/locales/types.d.ts +11 -0
  16. package/core/pop-up/constants.d.ts +9 -0
  17. package/core/select/constants.d.ts +16 -4
  18. package/core/styles/theming/_scrollbar-theme.scss +2 -1
  19. package/esm2022/autocomplete/autocomplete-trigger.directive.mjs +7 -8
  20. package/esm2022/autocomplete/autocomplete.component.mjs +2 -2
  21. package/esm2022/button/button.component.mjs +2 -2
  22. package/esm2022/code-block/code-block-highlight.mjs +416 -0
  23. package/esm2022/code-block/code-block.mjs +395 -0
  24. package/esm2022/code-block/code-block.module.mjs +9 -30
  25. package/esm2022/code-block/public-api.mjs +4 -3
  26. package/esm2022/code-block/types.mjs +2 -0
  27. package/esm2022/core/common-behaviors/error-state.mjs +1 -1
  28. package/esm2022/core/error/error-state-matcher.mjs +15 -2
  29. package/esm2022/core/locales/en-US.mjs +1 -1
  30. package/esm2022/core/locales/es-LA.mjs +1 -1
  31. package/esm2022/core/locales/fa-IR.mjs +1 -1
  32. package/esm2022/core/locales/index.mjs +2 -1
  33. package/esm2022/core/locales/pt-BR.mjs +1 -1
  34. package/esm2022/core/locales/ru-RU.mjs +1 -1
  35. package/esm2022/core/locales/types.mjs +2 -0
  36. package/esm2022/core/locales/zh-CN.mjs +1 -1
  37. package/esm2022/core/pop-up/constants.mjs +6 -1
  38. package/esm2022/core/select/constants.mjs +17 -5
  39. package/esm2022/core/version.mjs +2 -2
  40. package/esm2022/datepicker/calendar-header.component.mjs +1 -1
  41. package/esm2022/file-upload/file-upload.mjs +40 -2
  42. package/esm2022/file-upload/multiple-file-upload.component.mjs +43 -47
  43. package/esm2022/file-upload/single-file-upload.component.mjs +41 -45
  44. package/esm2022/form-field/form-field.mjs +6 -6
  45. package/esm2022/form-field/hint.mjs +2 -2
  46. package/esm2022/form-field/password-hint.mjs +2 -2
  47. package/esm2022/loader-overlay/loader-overlay.component.mjs +6 -4
  48. package/esm2022/modal/modal.component.mjs +5 -3
  49. package/esm2022/modal/modal.service.mjs +6 -3
  50. package/esm2022/modal/modal.type.mjs +1 -1
  51. package/esm2022/modal/public-api.mjs +5 -5
  52. package/esm2022/scrollbar/scrollbar.directive.mjs +6 -3
  53. package/esm2022/select/select.component.mjs +22 -12
  54. package/esm2022/sidepanel/sidepanel-config.mjs +1 -1
  55. package/esm2022/sidepanel/sidepanel-container.component.mjs +6 -3
  56. package/esm2022/timezone/timezone-select.component.mjs +3 -1
  57. package/esm2022/toast/toast-container.component.mjs +3 -3
  58. package/esm2022/toast/toast.component.mjs +18 -9
  59. package/esm2022/toast/toast.module.mjs +14 -50
  60. package/esm2022/toast/toast.service.mjs +5 -2
  61. package/esm2022/tooltip/tooltip.component.mjs +5 -2
  62. package/esm2022/tree-select/tree-select.component.mjs +15 -40
  63. package/fesm2022/koobiq-components-autocomplete.mjs +9 -10
  64. package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
  65. package/fesm2022/koobiq-components-button.mjs +2 -2
  66. package/fesm2022/koobiq-components-button.mjs.map +1 -1
  67. package/fesm2022/koobiq-components-code-block.mjs +378 -341
  68. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  69. package/fesm2022/koobiq-components-core.mjs +36 -7
  70. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  71. package/fesm2022/koobiq-components-datepicker.mjs +1 -1
  72. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  73. package/fesm2022/koobiq-components-file-upload.mjs +107 -76
  74. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  75. package/fesm2022/koobiq-components-form-field.mjs +9 -9
  76. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  77. package/fesm2022/koobiq-components-loader-overlay.mjs +5 -3
  78. package/fesm2022/koobiq-components-loader-overlay.mjs.map +1 -1
  79. package/fesm2022/koobiq-components-modal.mjs +10 -5
  80. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  81. package/fesm2022/koobiq-components-scrollbar.mjs +5 -2
  82. package/fesm2022/koobiq-components-scrollbar.mjs.map +1 -1
  83. package/fesm2022/koobiq-components-select.mjs +21 -11
  84. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  85. package/fesm2022/koobiq-components-sidepanel.mjs +5 -2
  86. package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
  87. package/fesm2022/koobiq-components-timezone.mjs +2 -0
  88. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  89. package/fesm2022/koobiq-components-toast.mjs +138 -161
  90. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  91. package/fesm2022/koobiq-components-tooltip.mjs +4 -1
  92. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  93. package/fesm2022/koobiq-components-tree-select.mjs +14 -39
  94. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  95. package/file-upload/_file-upload-theme.scss +16 -2
  96. package/file-upload/file-upload.d.ts +29 -2
  97. package/file-upload/multiple-file-upload.component.d.ts +18 -18
  98. package/file-upload/single-file-upload.component.d.ts +17 -16
  99. package/form-field/_hint-theme.scss +1 -1
  100. package/form-field/form-field.d.ts +1 -1
  101. package/form-field/form-field.scss +0 -1
  102. package/loader-overlay/loader-overlay.component.d.ts +1 -0
  103. package/modal/modal.component.d.ts +4 -0
  104. package/modal/modal.service.d.ts +4 -0
  105. package/modal/modal.type.d.ts +6 -1
  106. package/modal/public-api.d.ts +4 -4
  107. package/package.json +4 -4
  108. package/prebuilt-themes/dark-theme.css +1 -1
  109. package/prebuilt-themes/light-theme.css +1 -1
  110. package/prebuilt-themes/theme.css +1 -1
  111. package/schematics/ng-add/index.js +3 -4
  112. package/scrollbar/scrollbar.directive.d.ts +2 -1
  113. package/select/select.component.d.ts +15 -3
  114. package/sidepanel/sidepanel-config.d.ts +2 -0
  115. package/sidepanel/sidepanel-container.component.d.ts +1 -0
  116. package/timezone/timezone-select.component.d.ts +3 -1
  117. package/toast/toast-container.component.d.ts +1 -1
  118. package/toast/toast.component.d.ts +2 -2
  119. package/toast/toast.module.d.ts +1 -7
  120. package/toast/toast.service.d.ts +1 -1
  121. package/tooltip/tooltip.component.d.ts +2 -1
  122. package/tree-select/_tree-select-theme.scss +4 -0
  123. package/tree-select/tree-select.component.d.ts +1 -12
  124. package/accordion/README.md +0 -0
  125. package/alert/README.md +0 -0
  126. package/autocomplete/README.md +0 -0
  127. package/badge/README.md +0 -0
  128. package/button/README.md +0 -0
  129. package/button-toggle/README.md +0 -0
  130. package/checkbox/README.md +0 -1
  131. package/code-block/README.md +0 -36
  132. package/code-block/actionbar.component.d.ts +0 -32
  133. package/code-block/actionbar.component.scss +0 -43
  134. package/code-block/code-block-content.d.ts +0 -28
  135. package/code-block/code-block.component.d.ts +0 -98
  136. package/code-block/code-block.types.d.ts +0 -36
  137. package/datepicker/README.md +0 -0
  138. package/divider/README.md +0 -0
  139. package/dl/README.md +0 -0
  140. package/empty-state/README.md +0 -0
  141. package/esm2022/code-block/actionbar.component.mjs +0 -90
  142. package/esm2022/code-block/code-block-content.mjs +0 -393
  143. package/esm2022/code-block/code-block.component.mjs +0 -283
  144. package/esm2022/code-block/code-block.types.mjs +0 -5
  145. package/file-upload/README.md +0 -0
  146. package/form-field/README.md +0 -0
  147. package/icon/README.md +0 -0
  148. package/link/README.md +0 -0
  149. package/list/README.md +0 -0
  150. package/loader-overlay/README.md +0 -0
  151. package/modal/README.md +0 -35
  152. package/navbar/README.md +0 -42
  153. package/popover/README.md +0 -36
  154. package/progress-bar/README.md +0 -0
  155. package/progress-spinner/README.md +0 -0
  156. package/risk-level/README.md +0 -0
  157. package/table/README.md +0 -0
  158. package/tags/README.md +0 -0
  159. package/textarea/README.md +0 -0
  160. package/timepicker/README.md +0 -0
  161. package/timezone/README.md +0 -0
  162. package/tree-select/README.md +0 -0
@@ -0,0 +1,416 @@
1
+ import { DOCUMENT } from '@angular/common';
2
+ import { booleanAttribute, Directive, ElementRef, inject, InjectionToken, Input, numberAttribute, Renderer2, SecurityContext } from '@angular/core';
3
+ import { DomSanitizer } from '@angular/platform-browser';
4
+ import hljs from 'highlight.js';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * Fallback language for code block if language is not supported/specified.
8
+ *
9
+ * List of supported languages:
10
+ * @link https://highlightjs.readthedocs.io/en/stable/supported-languages.html
11
+ */
12
+ export const KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE = new InjectionToken('KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE', { factory: () => 'plaintext' });
13
+ /** Utility provider for `KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE`. */
14
+ export const kbqCodeBlockFallbackFileLanguageProvider = (language) => ({
15
+ provide: KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE,
16
+ useValue: language
17
+ });
18
+ /** Directive which applies syntax highlighting to the code block content. */
19
+ export class KbqCodeBlockHighlight {
20
+ /** The code file. */
21
+ set file({ language, content }) {
22
+ const window = this.getWindow();
23
+ if (!window)
24
+ return;
25
+ if (!language || !hljs.getLanguage(language)) {
26
+ console.warn(`[KbqCodeBlock] Unknown language: "${language}". Setting to "${this.fallbackFileLanguage}".`);
27
+ language = this.fallbackFileLanguage;
28
+ }
29
+ const { value: highlightedHTML, language: highlightedLanguage, illegal, relevance } = hljs.highlight(content, {
30
+ language: language
31
+ });
32
+ if (illegal) {
33
+ console.warn('[KbqCodeBlock] Content contains illegal characters.');
34
+ }
35
+ if (relevance === 0) {
36
+ console.warn('[KbqCodeBlock] Content does not match the specified programming language.');
37
+ }
38
+ const safeHTML = this.domSanitizer.sanitize(SecurityContext.HTML, highlightedHTML);
39
+ const highlightedHTMLWithLineNumbers = window['hljs'].lineNumbersValue(safeHTML, {
40
+ startFrom: this.startFrom,
41
+ singleLine: this.singleLine
42
+ });
43
+ this.renderer.setAttribute(this.nativeElement, 'data-language', highlightedLanguage);
44
+ this.renderer.setProperty(this.nativeElement, 'innerHTML', highlightedHTMLWithLineNumbers);
45
+ }
46
+ constructor() {
47
+ this.nativeElement = inject(ElementRef).nativeElement;
48
+ this.document = inject(DOCUMENT);
49
+ this.renderer = inject(Renderer2);
50
+ this.domSanitizer = inject(DomSanitizer);
51
+ this.fallbackFileLanguage = inject(KBQ_CODE_BLOCK_FALLBACK_FILE_LANGUAGE);
52
+ /** The starting line number. */
53
+ this.startFrom = 1;
54
+ /** Whether to display line numbers for single line code block. */
55
+ this.singleLine = false;
56
+ this.initLineNumbersPlugin();
57
+ }
58
+ /** Use defaultView of injected document if available or fallback to global window reference */
59
+ getWindow() {
60
+ return this.document?.defaultView || window;
61
+ }
62
+ /**
63
+ * Initialize the HighlightJS line numbers plugin. This method is called once when
64
+ * the component is constructed.
65
+ */
66
+ initLineNumbersPlugin() {
67
+ const window = this.getWindow();
68
+ if (!window)
69
+ return;
70
+ window['hljs'] = hljs;
71
+ this.highlightJSLineNumbersPlugin(this.document, window);
72
+ }
73
+ /**
74
+ * This method is not intended for editing.
75
+ * Changes may lead to unpredictable behavior.
76
+ * Source code: https://github.com/wcoder/highlightjs-line-numbers.js/blob/v2.9.0/src/highlightjs-line-numbers.js
77
+ */
78
+ highlightJSLineNumbersPlugin(d, w) {
79
+ 'use strict';
80
+ if (!w)
81
+ return;
82
+ const TABLE_NAME = 'hljs-ln', LINE_NAME = 'hljs-ln-line', CODE_BLOCK_NAME = 'hljs-ln-code', NUMBERS_BLOCK_NAME = 'hljs-ln-numbers', NUMBER_LINE_NAME = 'hljs-ln-n', DATA_ATTR_NAME = 'data-line-number', BREAK_LINE_REGEXP = /\r\n|\r|\n/g;
83
+ if (w['hljs']) {
84
+ w['hljs'].initLineNumbersOnLoad = initLineNumbersOnLoad;
85
+ w['hljs'].lineNumbersBlock = lineNumbersBlock;
86
+ w['hljs'].lineNumbersBlockSync = lineNumbersBlockSync;
87
+ w['hljs'].lineNumbersValue = lineNumbersValue;
88
+ addStyles();
89
+ }
90
+ else {
91
+ console.error('highlight.js not detected!');
92
+ }
93
+ function isHljsLnCodeDescendant(domElt) {
94
+ let curElt = domElt;
95
+ while (curElt) {
96
+ if (curElt.className && curElt.className.indexOf('hljs-ln-code') !== -1) {
97
+ return true;
98
+ }
99
+ curElt = curElt.parentNode;
100
+ }
101
+ return false;
102
+ }
103
+ function getHljsLnTable(hljsLnDomElt) {
104
+ let curElt = hljsLnDomElt;
105
+ while (curElt.nodeName !== 'TABLE') {
106
+ curElt = curElt.parentNode;
107
+ }
108
+ return curElt;
109
+ }
110
+ // Function to workaround a copy issue with Microsoft Edge.
111
+ // Due to hljs-ln wrapping the lines of code inside a <table> element,
112
+ // itself wrapped inside a <pre> element, window.getSelection().toString()
113
+ // does not contain any line breaks. So we need to get them back using the
114
+ // rendered code in the DOM as reference.
115
+ function edgeGetSelectedCodeLines(selection) {
116
+ // current selected text without line breaks
117
+ const selectionText = selection.toString();
118
+ // get the <td> element wrapping the first line of selected code
119
+ let tdAnchor = selection.anchorNode;
120
+ while (tdAnchor.nodeName !== 'TD') {
121
+ tdAnchor = tdAnchor.parentNode;
122
+ }
123
+ // get the <td> element wrapping the last line of selected code
124
+ let tdFocus = selection.focusNode;
125
+ while (tdFocus.nodeName !== 'TD') {
126
+ tdFocus = tdFocus.parentNode;
127
+ }
128
+ // extract line numbers
129
+ let firstLineNumber = parseInt(tdAnchor.dataset.lineNumber);
130
+ let lastLineNumber = parseInt(tdFocus.dataset.lineNumber);
131
+ // multi-lines copied case
132
+ if (firstLineNumber != lastLineNumber) {
133
+ let firstLineText = tdAnchor.textContent;
134
+ let lastLineText = tdFocus.textContent;
135
+ // if the selection was made backward, swap values
136
+ if (firstLineNumber > lastLineNumber) {
137
+ let tmp = firstLineNumber;
138
+ firstLineNumber = lastLineNumber;
139
+ lastLineNumber = tmp;
140
+ tmp = firstLineText;
141
+ firstLineText = lastLineText;
142
+ lastLineText = tmp;
143
+ }
144
+ // discard not copied characters in first line
145
+ while (selectionText.indexOf(firstLineText) !== 0) {
146
+ firstLineText = firstLineText.slice(1);
147
+ }
148
+ // discard not copied characters in last line
149
+ while (selectionText.lastIndexOf(lastLineText) === -1) {
150
+ lastLineText = lastLineText.slice(0, -1);
151
+ }
152
+ // reconstruct and return the real copied text
153
+ let selectedText = firstLineText;
154
+ const hljsLnTable = getHljsLnTable(tdAnchor);
155
+ for (let i = firstLineNumber + 1; i < lastLineNumber; ++i) {
156
+ const codeLineSel = format('.{0}[{1}="{2}"]', [CODE_BLOCK_NAME, DATA_ATTR_NAME, i]);
157
+ const codeLineElt = hljsLnTable.querySelector(codeLineSel);
158
+ selectedText += '\n' + codeLineElt.textContent;
159
+ }
160
+ selectedText += '\n' + lastLineText;
161
+ return selectedText;
162
+ // single copied line case
163
+ }
164
+ else {
165
+ return selectionText;
166
+ }
167
+ }
168
+ // ensure consistent code copy/paste behavior across all browsers
169
+ // (see https://github.com/wcoder/highlightjs-line-numbers.js/issues/51)
170
+ d.addEventListener('copy', function (e) {
171
+ // get current selection
172
+ const selection = w.getSelection();
173
+ // override behavior when one wants to copy line of codes
174
+ if (isHljsLnCodeDescendant(selection.anchorNode)) {
175
+ let selectionText;
176
+ // workaround an issue with Microsoft Edge as copied line breaks
177
+ // are removed otherwise from the selection string
178
+ if (w.navigator.userAgent.indexOf('Edge') !== -1) {
179
+ selectionText = edgeGetSelectedCodeLines(selection);
180
+ }
181
+ else {
182
+ // other browsers can directly use the selection string
183
+ selectionText = selection.toString();
184
+ }
185
+ e.clipboardData.setData('text/plain', selectionText);
186
+ e.preventDefault();
187
+ }
188
+ });
189
+ function addStyles() {
190
+ const css = d.createElement('style');
191
+ css.type = 'text/css';
192
+ css.innerHTML = format('.{0}{border-collapse:collapse}' + '.{0} td{padding:0}' + '.{1}:before{content:attr({2})}', [
193
+ TABLE_NAME,
194
+ NUMBER_LINE_NAME,
195
+ DATA_ATTR_NAME
196
+ ]);
197
+ d.getElementsByTagName('head')[0].appendChild(css);
198
+ }
199
+ function initLineNumbersOnLoad(options) {
200
+ if (d.readyState === 'interactive' || d.readyState === 'complete') {
201
+ documentReady(options);
202
+ }
203
+ else {
204
+ w.addEventListener('DOMContentLoaded', function () {
205
+ documentReady(options);
206
+ });
207
+ }
208
+ }
209
+ function documentReady(options) {
210
+ try {
211
+ const blocks = d.querySelectorAll('code.hljs,code.nohighlight');
212
+ for (const i in blocks) {
213
+ if (blocks.hasOwnProperty(i)) {
214
+ if (!isPluginDisabledForBlock(blocks[i])) {
215
+ lineNumbersBlock(blocks[i], options);
216
+ }
217
+ }
218
+ }
219
+ }
220
+ catch (e) {
221
+ console.error('LineNumbers error: ', e);
222
+ }
223
+ }
224
+ function isPluginDisabledForBlock(element) {
225
+ return element.classList.contains('nohljsln');
226
+ }
227
+ function lineNumbersBlock(element, options) {
228
+ if (typeof element !== 'object')
229
+ return;
230
+ async(function () {
231
+ element.innerHTML = lineNumbersInternal(element, options);
232
+ });
233
+ }
234
+ function lineNumbersBlockSync(element, options) {
235
+ if (typeof element !== 'object')
236
+ return;
237
+ element.innerHTML = lineNumbersInternal(element, options);
238
+ }
239
+ function lineNumbersValue(value, options) {
240
+ if (typeof value !== 'string')
241
+ return;
242
+ const element = d.createElement('code');
243
+ element.innerHTML = value;
244
+ return lineNumbersInternal(element, options);
245
+ }
246
+ function lineNumbersInternal(element, options) {
247
+ const internalOptions = mapOptions(element, options);
248
+ duplicateMultilineNodes(element);
249
+ return addLineNumbersBlockFor(element.innerHTML, internalOptions);
250
+ }
251
+ function addLineNumbersBlockFor(inputHtml, options) {
252
+ const lines = getLines(inputHtml);
253
+ // if last line contains only carriage return remove it
254
+ if (lines[lines.length - 1].trim() === '') {
255
+ lines.pop();
256
+ }
257
+ if (lines.length > 1 || options.singleLine) {
258
+ let html = '';
259
+ for (let i = 0, l = lines.length; i < l; i++) {
260
+ html += format('<tr>' +
261
+ '<td class="{0} {1}" {3}="{5}">' +
262
+ '<div class="{2}" {3}="{5}"></div>' +
263
+ '</td>' +
264
+ '<td class="{0} {4}" {3}="{5}">' +
265
+ '{6}' +
266
+ '</td>' +
267
+ '</tr>', [
268
+ LINE_NAME,
269
+ NUMBERS_BLOCK_NAME,
270
+ NUMBER_LINE_NAME,
271
+ DATA_ATTR_NAME,
272
+ CODE_BLOCK_NAME,
273
+ i + options.startFrom,
274
+ lines[i].length > 0 ? lines[i] : ' '
275
+ ]);
276
+ }
277
+ return format('<table class="{0}">{1}</table>', [TABLE_NAME, html]);
278
+ }
279
+ return inputHtml;
280
+ }
281
+ /**
282
+ * @param {HTMLElement} element Code block.
283
+ * @param {Object} options External API options.
284
+ * @returns {Object} Internal API options.
285
+ */
286
+ function mapOptions(element, options) {
287
+ options = options || {};
288
+ return {
289
+ singleLine: getSingleLineOption(options),
290
+ startFrom: getStartFromOption(element, options)
291
+ };
292
+ }
293
+ function getSingleLineOption(options) {
294
+ const defaultValue = false;
295
+ if (options.singleLine) {
296
+ return options.singleLine;
297
+ }
298
+ return defaultValue;
299
+ }
300
+ function getStartFromOption(element, options) {
301
+ const defaultValue = 1;
302
+ let startFrom = defaultValue;
303
+ if (isFinite(options.startFrom)) {
304
+ startFrom = options.startFrom;
305
+ }
306
+ // can be overridden because local option is priority
307
+ const value = getAttribute(element, 'data-ln-start-from');
308
+ if (value !== null) {
309
+ startFrom = toNumber(value, defaultValue);
310
+ }
311
+ return startFrom;
312
+ }
313
+ /**
314
+ * Recursive method for fix multi-line elements implementation in highlight.js
315
+ * Doing deep passage on child nodes.
316
+ * @param {HTMLElement} element
317
+ */
318
+ function duplicateMultilineNodes(element) {
319
+ const nodes = element.childNodes;
320
+ for (const node in nodes) {
321
+ if (nodes.hasOwnProperty(node)) {
322
+ const child = nodes[node];
323
+ if (getLinesCount(child.textContent) > 0) {
324
+ if (child.childNodes.length > 0) {
325
+ duplicateMultilineNodes(child);
326
+ }
327
+ else {
328
+ duplicateMultilineNode(child.parentNode);
329
+ }
330
+ }
331
+ }
332
+ }
333
+ }
334
+ /**
335
+ * Method for fix multi-line elements implementation in highlight.js
336
+ * @param {HTMLElement} element
337
+ */
338
+ function duplicateMultilineNode(element) {
339
+ const className = element.className;
340
+ if (!/hljs-/.test(className))
341
+ return;
342
+ const lines = getLines(element.innerHTML);
343
+ let result = '';
344
+ for (let i = 0; i < lines.length; i++) {
345
+ const lineText = lines[i].length > 0 ? lines[i] : ' ';
346
+ result += format('<span class="{0}">{1}</span>\n', [className, lineText]);
347
+ }
348
+ element.innerHTML = result.trim();
349
+ }
350
+ function getLines(text) {
351
+ if (text.length === 0)
352
+ return [];
353
+ return text.split(BREAK_LINE_REGEXP);
354
+ }
355
+ function getLinesCount(text) {
356
+ return (text.trim().match(BREAK_LINE_REGEXP) || []).length;
357
+ }
358
+ ///
359
+ /// HELPERS
360
+ ///
361
+ function async(func) {
362
+ w.setTimeout(func, 0);
363
+ }
364
+ /**
365
+ * {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript}
366
+ * @param {string} format
367
+ * @param {array} args
368
+ */
369
+ function format(format, args) {
370
+ return format.replace(/\{(\d+)\}/g, function (m, n) {
371
+ return args[n] !== undefined ? args[n] : m;
372
+ });
373
+ }
374
+ /**
375
+ * @param {HTMLElement} element Code block.
376
+ * @param {String} attrName Attribute name.
377
+ * @returns {String} Attribute value or empty.
378
+ */
379
+ function getAttribute(element, attrName) {
380
+ return element.hasAttribute(attrName) ? element.getAttribute(attrName) : null;
381
+ }
382
+ /**
383
+ * @param {String} str Source string.
384
+ * @param {Number} fallback Fallback value.
385
+ * @returns Parsed number or fallback value.
386
+ */
387
+ function toNumber(str, fallback) {
388
+ if (!str)
389
+ return fallback;
390
+ const number = Number(str);
391
+ return isFinite(number) ? number : fallback;
392
+ }
393
+ }
394
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: KbqCodeBlockHighlight, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
395
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.6", type: KbqCodeBlockHighlight, isStandalone: true, selector: "code[kbqCodeBlockHighlight]", inputs: { file: "file", startFrom: ["startFrom", "startFrom", numberAttribute], singleLine: ["singleLine", "singleLine", booleanAttribute] }, host: { classAttribute: "hljs" }, ngImport: i0 }); }
396
+ }
397
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: KbqCodeBlockHighlight, decorators: [{
398
+ type: Directive,
399
+ args: [{
400
+ standalone: true,
401
+ selector: 'code[kbqCodeBlockHighlight]',
402
+ host: {
403
+ class: 'hljs'
404
+ }
405
+ }]
406
+ }], ctorParameters: () => [], propDecorators: { file: [{
407
+ type: Input,
408
+ args: [{ required: true }]
409
+ }], startFrom: [{
410
+ type: Input,
411
+ args: [{ transform: numberAttribute }]
412
+ }], singleLine: [{
413
+ type: Input,
414
+ args: [{ transform: booleanAttribute }]
415
+ }] } });
416
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1ibG9jay1oaWdobGlnaHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21wb25lbnRzL2NvZGUtYmxvY2svY29kZS1ibG9jay1oaWdobGlnaHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFDSCxnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sY0FBYyxFQUNkLEtBQUssRUFDTCxlQUFlLEVBRWYsU0FBUyxFQUNULGVBQWUsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sSUFBSSxNQUFNLGNBQWMsQ0FBQzs7QUFHaEM7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxxQ0FBcUMsR0FBRyxJQUFJLGNBQWMsQ0FDbkUsdUNBQXVDLEVBQ3ZDLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUNqQyxDQUFDO0FBRUYsb0VBQW9FO0FBQ3BFLE1BQU0sQ0FBQyxNQUFNLHdDQUF3QyxHQUFHLENBQUMsUUFBZ0IsRUFBWSxFQUFFLENBQUMsQ0FBQztJQUNyRixPQUFPLEVBQUUscUNBQXFDO0lBQzlDLFFBQVEsRUFBRSxRQUFRO0NBQ3JCLENBQUMsQ0FBQztBQUVILDZFQUE2RTtBQVE3RSxNQUFNLE9BQU8scUJBQXFCO0lBTzlCLHFCQUFxQjtJQUNyQixJQUNJLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQW9CO1FBQzVDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVoQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFFcEIsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUMzQyxPQUFPLENBQUMsSUFBSSxDQUFDLHFDQUFxQyxRQUFRLGtCQUFrQixJQUFJLENBQUMsb0JBQW9CLElBQUksQ0FBQyxDQUFDO1lBQzNHLFFBQVEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUM7UUFDekMsQ0FBQztRQUVELE1BQU0sRUFDRixLQUFLLEVBQUUsZUFBZSxFQUN0QixRQUFRLEVBQUUsbUJBQW1CLEVBQzdCLE9BQU8sRUFDUCxTQUFTLEVBQ1osR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRTtZQUN4QixRQUFRLEVBQUUsUUFBUztTQUN0QixDQUFDLENBQUM7UUFFSCxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1YsT0FBTyxDQUFDLElBQUksQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxJQUFJLFNBQVMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQixPQUFPLENBQUMsSUFBSSxDQUFDLDJFQUEyRSxDQUFDLENBQUM7UUFDOUYsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDbkYsTUFBTSw4QkFBOEIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFO1lBQzdFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxlQUFlLEVBQUUsbUJBQW9CLENBQUMsQ0FBQztRQUN0RixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSw4QkFBOEIsQ0FBQyxDQUFDO0lBQy9GLENBQUM7SUFRRDtRQW5EaUIsa0JBQWEsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsYUFBYSxDQUFDO1FBQ2pELGFBQVEsR0FBRyxNQUFNLENBQVcsUUFBUSxDQUFDLENBQUM7UUFDdEMsYUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QixpQkFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwQyx5QkFBb0IsR0FBRyxNQUFNLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQXlDdEYsZ0NBQWdDO1FBQ08sY0FBUyxHQUFXLENBQUMsQ0FBQztRQUU3RCxrRUFBa0U7UUFDMUIsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUdoRSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsK0ZBQStGO0lBQ3ZGLFNBQVM7UUFDYixPQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxJQUFJLE1BQU0sQ0FBQztJQUNoRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0sscUJBQXFCO1FBQ3pCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVoQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFFcEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLDRCQUE0QixDQUFDLENBQVcsRUFBRSxDQUFTO1FBQ3ZELFlBQVksQ0FBQztRQUViLElBQUksQ0FBQyxDQUFDO1lBQUUsT0FBTztRQUVmLE1BQU0sVUFBVSxHQUFHLFNBQVMsRUFDeEIsU0FBUyxHQUFHLGNBQWMsRUFDMUIsZUFBZSxHQUFHLGNBQWMsRUFDaEMsa0JBQWtCLEdBQUcsaUJBQWlCLEVBQ3RDLGdCQUFnQixHQUFHLFdBQVcsRUFDOUIsY0FBYyxHQUFHLGtCQUFrQixFQUNuQyxpQkFBaUIsR0FBRyxhQUFhLENBQUM7UUFFdEMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUNaLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxxQkFBcUIsR0FBRyxxQkFBcUIsQ0FBQztZQUN4RCxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7WUFDOUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLG9CQUFvQixHQUFHLG9CQUFvQixDQUFDO1lBQ3RELENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztZQUU5QyxTQUFTLEVBQUUsQ0FBQztRQUNoQixDQUFDO2FBQU0sQ0FBQztZQUNKLE9BQU8sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBRUQsU0FBUyxzQkFBc0IsQ0FBQyxNQUFNO1lBQ2xDLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQztZQUNwQixPQUFPLE1BQU0sRUFBRSxDQUFDO2dCQUNaLElBQUksTUFBTSxDQUFDLFNBQVMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUN0RSxPQUFPLElBQUksQ0FBQztnQkFDaEIsQ0FBQztnQkFDRCxNQUFNLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQztZQUMvQixDQUFDO1lBQ0QsT0FBTyxLQUFLLENBQUM7UUFDakIsQ0FBQztRQUVELFNBQVMsY0FBYyxDQUFDLFlBQVk7WUFDaEMsSUFBSSxNQUFNLEdBQUcsWUFBWSxDQUFDO1lBQzFCLE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztnQkFDakMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDL0IsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDO1FBQ2xCLENBQUM7UUFFRCwyREFBMkQ7UUFDM0Qsc0VBQXNFO1FBQ3RFLDBFQUEwRTtRQUMxRSwwRUFBMEU7UUFDMUUseUNBQXlDO1FBQ3pDLFNBQVMsd0JBQXdCLENBQUMsU0FBUztZQUN2Qyw0Q0FBNEM7WUFDNUMsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBRTNDLGdFQUFnRTtZQUNoRSxJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDO1lBQ3BDLE9BQU8sUUFBUSxDQUFDLFFBQVEsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUM7WUFDbkMsQ0FBQztZQUVELCtEQUErRDtZQUMvRCxJQUFJLE9BQU8sR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO1lBQ2xDLE9BQU8sT0FBTyxDQUFDLFFBQVEsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDL0IsT0FBTyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7WUFDakMsQ0FBQztZQUVELHVCQUF1QjtZQUN2QixJQUFJLGVBQWUsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM1RCxJQUFJLGNBQWMsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUUxRCwwQkFBMEI7WUFDMUIsSUFBSSxlQUFlLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ3BDLElBQUksYUFBYSxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUM7Z0JBQ3pDLElBQUksWUFBWSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7Z0JBRXZDLGtEQUFrRDtnQkFDbEQsSUFBSSxlQUFlLEdBQUcsY0FBYyxFQUFFLENBQUM7b0JBQ25DLElBQUksR0FBRyxHQUFHLGVBQWUsQ0FBQztvQkFDMUIsZUFBZSxHQUFHLGNBQWMsQ0FBQztvQkFDakMsY0FBYyxHQUFHLEdBQUcsQ0FBQztvQkFDckIsR0FBRyxHQUFHLGFBQWEsQ0FBQztvQkFDcEIsYUFBYSxHQUFHLFlBQVksQ0FBQztvQkFDN0IsWUFBWSxHQUFHLEdBQUcsQ0FBQztnQkFDdkIsQ0FBQztnQkFFRCw4Q0FBOEM7Z0JBQzlDLE9BQU8sYUFBYSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDaEQsYUFBYSxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNDLENBQUM7Z0JBRUQsNkNBQTZDO2dCQUM3QyxPQUFPLGFBQWEsQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDcEQsWUFBWSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLENBQUM7Z0JBRUQsOENBQThDO2dCQUM5QyxJQUFJLFlBQVksR0FBRyxhQUFhLENBQUM7Z0JBQ2pDLE1BQU0sV0FBVyxHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDN0MsS0FBSyxJQUFJLENBQUMsR0FBRyxlQUFlLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFDeEQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUMsZUFBZSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNwRixNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUMzRCxZQUFZLElBQUksSUFBSSxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUM7Z0JBQ25ELENBQUM7Z0JBQ0QsWUFBWSxJQUFJLElBQUksR0FBRyxZQUFZLENBQUM7Z0JBQ3BDLE9BQU8sWUFBWSxDQUFDO2dCQUNwQiwwQkFBMEI7WUFDOUIsQ0FBQztpQkFBTSxDQUFDO2dCQUNKLE9BQU8sYUFBYSxDQUFDO1lBQ3pCLENBQUM7UUFDTCxDQUFDO1FBRUQsaUVBQWlFO1FBQ2pFLHdFQUF3RTtRQUN4RSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQztZQUNsQyx3QkFBd0I7WUFDeEIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLFlBQVksRUFBRyxDQUFDO1lBQ3BDLHlEQUF5RDtZQUN6RCxJQUFJLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUMvQyxJQUFJLGFBQWEsQ0FBQztnQkFDbEIsZ0VBQWdFO2dCQUNoRSxrREFBa0Q7Z0JBQ2xELElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQy9DLGFBQWEsR0FBRyx3QkFBd0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDeEQsQ0FBQztxQkFBTSxDQUFDO29CQUNKLHVEQUF1RDtvQkFDdkQsYUFBYSxHQUFHLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDekMsQ0FBQztnQkFDRCxDQUFDLENBQUMsYUFBYyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsYUFBYSxDQUFDLENBQUM7Z0JBQ3RELENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxTQUFTLFNBQVM7WUFDZCxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO1lBQ3RCLEdBQUcsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUNsQixnQ0FBZ0MsR0FBRyxvQkFBb0IsR0FBRyxnQ0FBZ0MsRUFDMUY7Z0JBQ0ksVUFBVTtnQkFDVixnQkFBZ0I7Z0JBQ2hCLGNBQWM7YUFDakIsQ0FDSixDQUFDO1lBQ0YsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBRUQsU0FBUyxxQkFBcUIsQ0FBQyxPQUFPO1lBQ2xDLElBQUksQ0FBQyxDQUFDLFVBQVUsS0FBSyxhQUFhLElBQUksQ0FBQyxDQUFDLFVBQVUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDaEUsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzNCLENBQUM7aUJBQU0sQ0FBQztnQkFDSixDQUFDLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLEVBQUU7b0JBQ25DLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDUCxDQUFDO1FBQ0wsQ0FBQztRQUVELFNBQVMsYUFBYSxDQUFDLE9BQU87WUFDMUIsSUFBSSxDQUFDO2dCQUNELE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO2dCQUVoRSxLQUFLLE1BQU0sQ0FBQyxJQUFJLE1BQU0sRUFBRSxDQUFDO29CQUNyQixJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzt3QkFDM0IsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ3ZDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFDekMsQ0FBQztvQkFDTCxDQUFDO2dCQUNMLENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDVCxPQUFPLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVDLENBQUM7UUFDTCxDQUFDO1FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxPQUFPO1lBQ3JDLE9BQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUVELFNBQVMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU87WUFDdEMsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRO2dCQUFFLE9BQU87WUFFeEMsS0FBSyxDQUFDO2dCQUNGLE9BQU8sQ0FBQyxTQUFTLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzlELENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztRQUVELFNBQVMsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE9BQU87WUFDMUMsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRO2dCQUFFLE9BQU87WUFFeEMsT0FBTyxDQUFDLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUVELFNBQVMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLE9BQU87WUFDcEMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO2dCQUFFLE9BQU87WUFFdEMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4QyxPQUFPLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUUxQixPQUFPLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTztZQUN6QyxNQUFNLGVBQWUsR0FBRyxVQUFVLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBRXJELHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRWpDLE9BQU8sc0JBQXNCLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBRUQsU0FBUyxzQkFBc0IsQ0FBQyxTQUFTLEVBQUUsT0FBTztZQUM5QyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFbEMsdURBQXVEO1lBQ3ZELElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUM7Z0JBQ3hDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNoQixDQUFDO1lBRUQsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3pDLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztnQkFFZCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQzNDLElBQUksSUFBSSxNQUFNLENBQ1YsTUFBTTt3QkFDRixnQ0FBZ0M7d0JBQ2hDLG1DQUFtQzt3QkFDbkMsT0FBTzt3QkFDUCxnQ0FBZ0M7d0JBQ2hDLEtBQUs7d0JBQ0wsT0FBTzt3QkFDUCxPQUFPLEVBQ1g7d0JBQ0ksU0FBUzt3QkFDVCxrQkFBa0I7d0JBQ2xCLGdCQUFnQjt3QkFDaEIsY0FBYzt3QkFDZCxlQUFlO3dCQUNmLENBQUMsR0FBRyxPQUFPLENBQUMsU0FBUzt3QkFDckIsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRztxQkFDdkMsQ0FDSixDQUFDO2dCQUNOLENBQUM7Z0JBRUQsT0FBTyxNQUFNLENBQUMsZ0NBQWdDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUN4RSxDQUFDO1lBRUQsT0FBTyxTQUFTLENBQUM7UUFDckIsQ0FBQztRQUVEOzs7O1dBSUc7UUFDSCxTQUFTLFVBQVUsQ0FBQyxPQUFPLEVBQUUsT0FBTztZQUNoQyxPQUFPLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUN4QixPQUFPO2dCQUNILFVBQVUsRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLENBQUM7Z0JBQ3hDLFNBQVMsRUFBRSxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDO2FBQ2xELENBQUM7UUFDTixDQUFDO1FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxPQUFPO1lBQ2hDLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQztZQUMzQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDckIsT0FBTyxPQUFPLENBQUMsVUFBVSxDQUFDO1lBQzlCLENBQUM7WUFDRCxPQUFPLFlBQVksQ0FBQztRQUN4QixDQUFDO1FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsT0FBTztZQUN4QyxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUM7WUFDdkIsSUFBSSxTQUFTLEdBQUcsWUFBWSxDQUFDO1lBRTdCLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUM5QixTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQztZQUNsQyxDQUFDO1lBRUQscURBQXFEO1lBQ3JELE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxPQUFPLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztZQUMxRCxJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDakIsU0FBUyxHQUFHLFFBQVEsQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDOUMsQ0FBQztZQUVELE9BQU8sU0FBUyxDQUFDO1FBQ3JCLENBQUM7UUFFRDs7OztXQUlHO1FBQ0gsU0FBUyx1QkFBdUIsQ0FBQyxPQUFPO1lBQ3BDLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7WUFDakMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQzdCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDMUIsSUFBSSxhQUFhLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO3dCQUN2QyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDOzRCQUM5Qix1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDbkMsQ0FBQzs2QkFBTSxDQUFDOzRCQUNKLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQzt3QkFDN0MsQ0FBQztvQkFDTCxDQUFDO2dCQUNMLENBQUM7WUFDTCxDQUFDO1FBQ0wsQ0FBQztRQUVEOzs7V0FHRztRQUNILFNBQVMsc0JBQXNCLENBQUMsT0FBTztZQUNuQyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDO1lBRXBDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztnQkFBRSxPQUFPO1lBRXJDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFMUMsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO1lBRWhCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDdEQsTUFBTSxJQUFJLE1BQU0sQ0FBQyxnQ0FBZ0MsRUFBRSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzlFLENBQUM7WUFFRCxPQUFPLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0QyxDQUFDO1FBRUQsU0FBUyxRQUFRLENBQUMsSUFBSTtZQUNsQixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFBRSxPQUFPLEVBQUUsQ0FBQztZQUNqQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBRUQsU0FBUyxhQUFhLENBQUMsSUFBSTtZQUN2QixPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUMvRCxDQUFDO1FBRUQsR0FBRztRQUNILFdBQVc7UUFDWCxHQUFHO1FBRUgsU0FBUyxLQUFLLENBQUMsSUFBSTtZQUNmLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFFRDs7OztXQUlHO1FBQ0gsU0FBUyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUk7WUFDeEIsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUM5QyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9DLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztRQUVEOzs7O1dBSUc7UUFDSCxTQUFTLFlBQVksQ0FBQyxPQUFPLEVBQUUsUUFBUTtZQUNuQyxPQUFPLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNsRixDQUFDO1FBRUQ7Ozs7V0FJRztRQUNILFNBQVMsUUFBUSxDQUFDLEdBQUcsRUFBRSxRQUFRO1lBQzNCLElBQUksQ0FBQyxHQUFHO2dCQUFFLE9BQU8sUUFBUSxDQUFDO1lBQzFCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQixPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7UUFDaEQsQ0FBQztJQUNMLENBQUM7aUlBbGNRLHFCQUFxQjtxSEFBckIscUJBQXFCLDZIQStDVixlQUFlLDRDQUdmLGdCQUFnQjs7MkZBbEQzQixxQkFBcUI7a0JBUGpDLFNBQVM7bUJBQUM7b0JBQ1AsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLFFBQVEsRUFBRSw2QkFBNkI7b0JBQ3ZDLElBQUksRUFBRTt3QkFDRixLQUFLLEVBQUUsTUFBTTtxQkFDaEI7aUJBQ0o7d0RBVU8sSUFBSTtzQkFEUCxLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkF1Q2MsU0FBUztzQkFBL0MsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUU7Z0JBR0csVUFBVTtzQkFBakQsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgICBEaXJlY3RpdmUsXG4gICAgRWxlbWVudFJlZixcbiAgICBpbmplY3QsXG4gICAgSW5qZWN0aW9uVG9rZW4sXG4gICAgSW5wdXQsXG4gICAgbnVtYmVyQXR0cmlidXRlLFxuICAgIFByb3ZpZGVyLFxuICAgIFJlbmRlcmVyMixcbiAgICBTZWN1cml0eUNvbnRleHRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCBobGpzIGZyb20gJ2hpZ2hsaWdodC5qcyc7XG5pbXBvcnQgeyBLYnFDb2RlQmxvY2tGaWxlIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogRmFsbGJhY2sgbGFuZ3VhZ2UgZm9yIGNvZGUgYmxvY2sgaWYgbGFuZ3VhZ2UgaXMgbm90IHN1cHBvcnRlZC9zcGVjaWZpZWQuXG4gKlxuICogTGlzdCBvZiBzdXBwb3J0ZWQgbGFuZ3VhZ2VzOlxuICogQGxpbmsgaHR0cHM6Ly9oaWdobGlnaHRqcy5yZWFkdGhlZG9jcy5pby9lbi9zdGFibGUvc3VwcG9ydGVkLWxhbmd1YWdlcy5odG1sXG4gKi9cbmV4cG9ydCBjb25zdCBLQlFfQ09ERV9CTE9DS19GQUxMQkFDS19GSUxFX0xBTkdVQUdFID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZz4oXG4gICAgJ0tCUV9DT0RFX0JMT0NLX0ZBTExCQUNLX0ZJTEVfTEFOR1VBR0UnLFxuICAgIHsgZmFjdG9yeTogKCkgPT4gJ3BsYWludGV4dCcgfVxuKTtcblxuLyoqIFV0aWxpdHkgcHJvdmlkZXIgZm9yIGBLQlFfQ09ERV9CTE9DS19GQUxMQkFDS19GSUxFX0xBTkdVQUdFYC4gKi9cbmV4cG9ydCBjb25zdCBrYnFDb2RlQmxvY2tGYWxsYmFja0ZpbGVMYW5ndWFnZVByb3ZpZGVyID0gKGxhbmd1YWdlOiBzdHJpbmcpOiBQcm92aWRlciA9PiAoe1xuICAgIHByb3ZpZGU6IEtCUV9DT0RFX0JMT0NLX0ZBTExCQUNLX0ZJTEVfTEFOR1VBR0UsXG4gICAgdXNlVmFsdWU6IGxhbmd1YWdlXG59KTtcblxuLyoqIERpcmVjdGl2ZSB3aGljaCBhcHBsaWVzIHN5bnRheCBoaWdobGlnaHRpbmcgdG8gdGhlIGNvZGUgYmxvY2sgY29udGVudC4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdjb2RlW2ticUNvZGVCbG9ja0hpZ2hsaWdodF0nLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgY2xhc3M6ICdobGpzJ1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgS2JxQ29kZUJsb2NrSGlnaGxpZ2h0IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5hdGl2ZUVsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZikubmF0aXZlRWxlbWVudDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRvY3VtZW50ID0gaW5qZWN0PERvY3VtZW50PihET0NVTUVOVCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSByZW5kZXJlciA9IGluamVjdChSZW5kZXJlcjIpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZG9tU2FuaXRpemVyID0gaW5qZWN0KERvbVNhbml0aXplcik7XG4gICAgcHJpdmF0ZSByZWFkb25seSBmYWxsYmFja0ZpbGVMYW5ndWFnZSA9IGluamVjdChLQlFfQ09ERV9CTE9DS19GQUxMQkFDS19GSUxFX0xBTkdVQUdFKTtcblxuICAgIC8qKiBUaGUgY29kZSBmaWxlLiAqL1xuICAgIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pXG4gICAgc2V0IGZpbGUoeyBsYW5ndWFnZSwgY29udGVudCB9OiBLYnFDb2RlQmxvY2tGaWxlKSB7XG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuZ2V0V2luZG93KCk7XG5cbiAgICAgICAgaWYgKCF3aW5kb3cpIHJldHVybjtcblxuICAgICAgICBpZiAoIWxhbmd1YWdlIHx8ICFobGpzLmdldExhbmd1YWdlKGxhbmd1YWdlKSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBbS2JxQ29kZUJsb2NrXSBVbmtub3duIGxhbmd1YWdlOiBcIiR7bGFuZ3VhZ2V9XCIuIFNldHRpbmcgdG8gXCIke3RoaXMuZmFsbGJhY2tGaWxlTGFuZ3VhZ2V9XCIuYCk7XG4gICAgICAgICAgICBsYW5ndWFnZSA9IHRoaXMuZmFsbGJhY2tGaWxlTGFuZ3VhZ2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICB2YWx1ZTogaGlnaGxpZ2h0ZWRIVE1MLFxuICAgICAgICAgICAgbGFuZ3VhZ2U6IGhpZ2hsaWdodGVkTGFuZ3VhZ2UsXG4gICAgICAgICAgICBpbGxlZ2FsLFxuICAgICAgICAgICAgcmVsZXZhbmNlXG4gICAgICAgIH0gPSBobGpzLmhpZ2hsaWdodChjb250ZW50LCB7XG4gICAgICAgICAgICBsYW5ndWFnZTogbGFuZ3VhZ2UhXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChpbGxlZ2FsKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tLYnFDb2RlQmxvY2tdIENvbnRlbnQgY29udGFpbnMgaWxsZWdhbCBjaGFyYWN0ZXJzLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlbGV2YW5jZSA9PT0gMCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdbS2JxQ29kZUJsb2NrXSBDb250ZW50IGRvZXMgbm90IG1hdGNoIHRoZSBzcGVjaWZpZWQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzYWZlSFRNTCA9IHRoaXMuZG9tU2FuaXRpemVyLnNhbml0aXplKFNlY3VyaXR5Q29udGV4dC5IVE1MLCBoaWdobGlnaHRlZEhUTUwpO1xuICAgICAgICBjb25zdCBoaWdobGlnaHRlZEhUTUxXaXRoTGluZU51bWJlcnMgPSB3aW5kb3dbJ2hsanMnXS5saW5lTnVtYmVyc1ZhbHVlKHNhZmVIVE1MLCB7XG4gICAgICAgICAgICBzdGFydEZyb206IHRoaXMuc3RhcnRGcm9tLFxuICAgICAgICAgICAgc2luZ2xlTGluZTogdGhpcy5zaW5nbGVMaW5lXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMubmF0aXZlRWxlbWVudCwgJ2RhdGEtbGFuZ3VhZ2UnLCBoaWdobGlnaHRlZExhbmd1YWdlISk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0UHJvcGVydHkodGhpcy5uYXRpdmVFbGVtZW50LCAnaW5uZXJIVE1MJywgaGlnaGxpZ2h0ZWRIVE1MV2l0aExpbmVOdW1iZXJzKTtcbiAgICB9XG5cbiAgICAvKiogVGhlIHN0YXJ0aW5nIGxpbmUgbnVtYmVyLiAqL1xuICAgIEBJbnB1dCh7IHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlIH0pIHN0YXJ0RnJvbTogbnVtYmVyID0gMTtcblxuICAgIC8qKiBXaGV0aGVyIHRvIGRpc3BsYXkgbGluZSBudW1iZXJzIGZvciBzaW5nbGUgbGluZSBjb2RlIGJsb2NrLiAqL1xuICAgIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBzaW5nbGVMaW5lOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5pbml0TGluZU51bWJlcnNQbHVnaW4oKTtcbiAgICB9XG5cbiAgICAvKiogVXNlIGRlZmF1bHRWaWV3IG9mIGluamVjdGVkIGRvY3VtZW50IGlmIGF2YWlsYWJsZSBvciBmYWxsYmFjayB0byBnbG9iYWwgd2luZG93IHJlZmVyZW5jZSAqL1xuICAgIHByaXZhdGUgZ2V0V2luZG93KCk6IFdpbmRvdyB7XG4gICAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50Py5kZWZhdWx0VmlldyB8fCB3aW5kb3c7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSB0aGUgSGlnaGxpZ2h0SlMgbGluZSBudW1iZXJzIHBsdWdpbi4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIG9uY2Ugd2hlblxuICAgICAqIHRoZSBjb21wb25lbnQgaXMgY29uc3RydWN0ZWQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBpbml0TGluZU51bWJlcnNQbHVnaW4oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuZ2V0V2luZG93KCk7XG5cbiAgICAgICAgaWYgKCF3aW5kb3cpIHJldHVybjtcblxuICAgICAgICB3aW5kb3dbJ2hsanMnXSA9IGhsanM7XG4gICAgICAgIHRoaXMuaGlnaGxpZ2h0SlNMaW5lTnVtYmVyc1BsdWdpbih0aGlzLmRvY3VtZW50LCB3aW5kb3cpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBpbnRlbmRlZCBmb3IgZWRpdGluZy5cbiAgICAgKiBDaGFuZ2VzIG1heSBsZWFkIHRvIHVucHJlZGljdGFibGUgYmVoYXZpb3IuXG4gICAgICogU291cmNlIGNvZGU6IGh0dHBzOi8vZ2l0aHViLmNvbS93Y29kZXIvaGlnaGxpZ2h0anMtbGluZS1udW1iZXJzLmpzL2Jsb2IvdjIuOS4wL3NyYy9oaWdobGlnaHRqcy1saW5lLW51bWJlcnMuanNcbiAgICAgKi9cbiAgICBwcml2YXRlIGhpZ2hsaWdodEpTTGluZU51bWJlcnNQbHVnaW4oZDogRG9jdW1lbnQsIHc6IFdpbmRvdyk6IHZvaWQge1xuICAgICAgICAndXNlIHN0cmljdCc7XG5cbiAgICAgICAgaWYgKCF3KSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgVEFCTEVfTkFNRSA9ICdobGpzLWxuJyxcbiAgICAgICAgICAgIExJTkVfTkFNRSA9ICdobGpzLWxuLWxpbmUnLFxuICAgICAgICAgICAgQ09ERV9CTE9DS19OQU1FID0gJ2hsanMtbG4tY29kZScsXG4gICAgICAgICAgICBOVU1CRVJTX0JMT0NLX05BTUUgPSAnaGxqcy1sbi1udW1iZXJzJyxcbiAgICAgICAgICAgIE5VTUJFUl9MSU5FX05BTUUgPSAnaGxqcy1sbi1uJyxcbiAgICAgICAgICAgIERBVEFfQVRUUl9OQU1FID0gJ2RhdGEtbGluZS1udW1iZXInLFxuICAgICAgICAgICAgQlJFQUtfTElORV9SRUdFWFAgPSAvXFxyXFxufFxccnxcXG4vZztcblxuICAgICAgICBpZiAod1snaGxqcyddKSB7XG4gICAgICAgICAgICB3WydobGpzJ10uaW5pdExpbmVOdW1iZXJzT25Mb2FkID0gaW5pdExpbmVOdW1iZXJzT25Mb2FkO1xuICAgICAgICAgICAgd1snaGxqcyddLmxpbmVOdW1iZXJzQmxvY2sgPSBsaW5lTnVtYmVyc0Jsb2NrO1xuICAgICAgICAgICAgd1snaGxqcyddLmxpbmVOdW1iZXJzQmxvY2tTeW5jID0gbGluZU51bWJlcnNCbG9ja1N5bmM7XG4gICAgICAgICAgICB3WydobGpzJ10ubGluZU51bWJlcnNWYWx1ZSA9IGxpbmVOdW1iZXJzVmFsdWU7XG5cbiAgICAgICAgICAgIGFkZFN0eWxlcygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignaGlnaGxpZ2h0LmpzIG5vdCBkZXRlY3RlZCEnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGlzSGxqc0xuQ29kZURlc2NlbmRhbnQoZG9tRWx0KSB7XG4gICAgICAgICAgICBsZXQgY3VyRWx0ID0gZG9tRWx0O1xuICAgICAgICAgICAgd2hpbGUgKGN1ckVsdCkge1xuICAgICAgICAgICAgICAgIGlmIChjdXJFbHQuY2xhc3NOYW1lICYmIGN1ckVsdC5jbGFzc05hbWUuaW5kZXhPZignaGxqcy1sbi1jb2RlJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjdXJFbHQgPSBjdXJFbHQucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldEhsanNMblRhYmxlKGhsanNMbkRvbUVsdCkge1xuICAgICAgICAgICAgbGV0IGN1ckVsdCA9IGhsanNMbkRvbUVsdDtcbiAgICAgICAgICAgIHdoaWxlIChjdXJFbHQubm9kZU5hbWUgIT09ICdUQUJMRScpIHtcbiAgICAgICAgICAgICAgICBjdXJFbHQgPSBjdXJFbHQucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjdXJFbHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGdW5jdGlvbiB0byB3b3JrYXJvdW5kIGEgY29weSBpc3N1ZSB3aXRoIE1pY3Jvc29mdCBFZGdlLlxuICAgICAgICAvLyBEdWUgdG8gaGxqcy1sbiB3cmFwcGluZyB0aGUgbGluZXMgb2YgY29kZSBpbnNpZGUgYSA8dGFibGU+IGVsZW1lbnQsXG4gICAgICAgIC8vIGl0c2VsZiB3cmFwcGVkIGluc2lkZSBhIDxwcmU+IGVsZW1lbnQsIHdpbmRvdy5nZXRTZWxlY3Rpb24oKS50b1N0cmluZygpXG4gICAgICAgIC8vIGRvZXMgbm90IGNvbnRhaW4gYW55IGxpbmUgYnJlYWtzLiBTbyB3ZSBuZWVkIHRvIGdldCB0aGVtIGJhY2sgdXNpbmcgdGhlXG4gICAgICAgIC8vIHJlbmRlcmVkIGNvZGUgaW4gdGhlIERPTSBhcyByZWZlcmVuY2UuXG4gICAgICAgIGZ1bmN0aW9uIGVkZ2VHZXRTZWxlY3RlZENvZGVMaW5lcyhzZWxlY3Rpb24pIHtcbiAgICAgICAgICAgIC8vIGN1cnJlbnQgc2VsZWN0ZWQgdGV4dCB3aXRob3V0IGxpbmUgYnJlYWtzXG4gICAgICAgICAgICBjb25zdCBzZWxlY3Rpb25UZXh0ID0gc2VsZWN0aW9uLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgICAgIC8vIGdldCB0aGUgPHRkPiBlbGVtZW50IHdyYXBwaW5nIHRoZSBmaXJzdCBsaW5lIG9mIHNlbGVjdGVkIGNvZGVcbiAgICAgICAgICAgIGxldCB0ZEFuY2hvciA9IHNlbGVjdGlvbi5hbmNob3JOb2RlO1xuICAgICAgICAgICAgd2hpbGUgKHRkQW5jaG9yLm5vZGVOYW1lICE9PSAnVEQnKSB7XG4gICAgICAgICAgICAgICAgdGRBbmNob3IgPSB0ZEFuY2hvci5wYXJlbnROb2RlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBnZXQgdGhlIDx0ZD4gZWxlbWVudCB3cmFwcGluZyB0aGUgbGFzdCBsaW5lIG9mIHNlbGVjdGVkIGNvZGVcbiAgICAgICAgICAgIGxldCB0ZEZvY3VzID0gc2VsZWN0aW9uLmZvY3VzTm9kZTtcbiAgICAgICAgICAgIHdoaWxlICh0ZEZvY3VzLm5vZGVOYW1lICE9PSAnVEQnKSB7XG4gICAgICAgICAgICAgICAgdGRGb2N1cyA9IHRkRm9jdXMucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZXh0cmFjdCBsaW5lIG51bWJlcnNcbiAgICAgICAgICAgIGxldCBmaXJzdExpbmVOdW1iZXIgPSBwYXJzZUludCh0ZEFuY2hvci5kYXRhc2V0LmxpbmVOdW1iZXIpO1xuICAgICAgICAgICAgbGV0IGxhc3RMaW5lTnVtYmVyID0gcGFyc2VJbnQodGRGb2N1cy5kYXRhc2V0LmxpbmVOdW1iZXIpO1xuXG4gICAgICAgICAgICAvLyBtdWx0aS1saW5lcyBjb3BpZWQgY2FzZVxuICAgICAgICAgICAgaWYgKGZpcnN0TGluZU51bWJlciAhPSBsYXN0TGluZU51bWJlcikge1xuICAgICAgICAgICAgICAgIGxldCBmaXJzdExpbmVUZXh0ID0gdGRBbmNob3IudGV4dENvbnRlbnQ7XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RMaW5lVGV4dCA9IHRkRm9jdXMudGV4dENvbnRlbnQ7XG5cbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgc2VsZWN0aW9uIHdhcyBtYWRlIGJhY2t3YXJkLCBzd2FwIHZhbHVlc1xuICAgICAgICAgICAgICAgIGlmIChmaXJzdExpbmVOdW1iZXIgPiBsYXN0TGluZU51bWJlcikge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG1wID0gZmlyc3RMaW5lTnVtYmVyO1xuICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmVOdW1iZXIgPSBsYXN0TGluZU51bWJlcjtcbiAgICAgICAgICAgICAgICAgICAgbGFzdExpbmVOdW1iZXIgPSB0bXA7XG4gICAgICAgICAgICAgICAgICAgIHRtcCA9IGZpcnN0TGluZVRleHQ7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0TGluZVRleHQgPSBsYXN0TGluZVRleHQ7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RMaW5lVGV4dCA9IHRtcDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBkaXNjYXJkIG5vdCBjb3BpZWQgY2hhcmFjdGVycyBpbiBmaXJzdCBsaW5lXG4gICAgICAgICAgICAgICAgd2hpbGUgKHNlbGVjdGlvblRleHQuaW5kZXhPZihmaXJzdExpbmVUZXh0KSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmVUZXh0ID0gZmlyc3RMaW5lVGV4dC5zbGljZSgxKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBkaXNjYXJkIG5vdCBjb3BpZWQgY2hhcmFjdGVycyBpbiBsYXN0IGxpbmVcbiAgICAgICAgICAgICAgICB3aGlsZSAoc2VsZWN0aW9uVGV4dC5sYXN0SW5kZXhPZihsYXN0TGluZVRleHQpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBsYXN0TGluZVRleHQgPSBsYXN0TGluZVRleHQuc2xpY2UoMCwgLTEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIHJlY29uc3RydWN0IGFuZCByZXR1cm4gdGhlIHJlYWwgY29waWVkIHRleHRcbiAgICAgICAgICAgICAgICBsZXQgc2VsZWN0ZWRUZXh0ID0gZmlyc3RMaW5lVGV4dDtcbiAgICAgICAgICAgICAgICBjb25zdCBobGpzTG5UYWJsZSA9IGdldEhsanNMblRhYmxlKHRkQW5jaG9yKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gZmlyc3RMaW5lTnVtYmVyICsgMTsgaSA8IGxhc3RMaW5lTnVtYmVyOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29kZUxpbmVTZWwgPSBmb3JtYXQoJy57MH1bezF9PVwiezJ9XCJdJywgW0NPREVfQkxPQ0tfTkFNRSwgREFUQV9BVFRSX05BTUUsIGldKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29kZUxpbmVFbHQgPSBobGpzTG5UYWJsZS5xdWVyeVNlbGVjdG9yKGNvZGVMaW5lU2VsKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRUZXh0ICs9ICdcXG4nICsgY29kZUxpbmVFbHQudGV4dENvbnRlbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNlbGVjdGVkVGV4dCArPSAnXFxuJyArIGxhc3RMaW5lVGV4dDtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0ZWRUZXh0O1xuICAgICAgICAgICAgICAgIC8vIHNpbmdsZSBjb3BpZWQgbGluZSBjYXNlXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3Rpb25UZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZW5zdXJlIGNvbnNpc3RlbnQgY29kZSBjb3B5L3Bhc3RlIGJlaGF2aW9yIGFjcm9zcyBhbGwgYnJvd3NlcnNcbiAgICAgICAgLy8gKHNlZSBodHRwczovL2dpdGh1Yi5jb20vd2NvZGVyL2hpZ2hsaWdodGpzLWxpbmUtbnVtYmVycy5qcy9pc3N1ZXMvNTEpXG4gICAgICAgIGQuYWRkRXZlbnRMaXN0ZW5lcignY29weScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAvLyBnZXQgY3VycmVudCBzZWxlY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHcuZ2V0U2VsZWN0aW9uKCkhO1xuICAgICAgICAgICAgLy8gb3ZlcnJpZGUgYmVoYXZpb3Igd2hlbiBvbmUgd2FudHMgdG8gY29weSBsaW5lIG9mIGNvZGVzXG4gICAgICAgICAgICBpZiAoaXNIbGpzTG5Db2RlRGVzY2VuZGFudChzZWxlY3Rpb24uYW5jaG9yTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgc2VsZWN0aW9uVGV4dDtcbiAgICAgICAgICAgICAgICAvLyB3b3JrYXJvdW5kIGFuIGlzc3VlIHdpdGggTWljcm9zb2Z0IEVkZ2UgYXMgY29waWVkIGxpbmUgYnJlYWtzXG4gICAgICAgICAgICAgICAgLy8gYXJlIHJlbW92ZWQgb3RoZXJ3aXNlIGZyb20gdGhlIHNlbGVjdGlvbiBzdHJpbmdcbiAgICAgICAgICAgICAgICBpZiAody5uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0VkZ2UnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uVGV4dCA9IGVkZ2VHZXRTZWxlY3RlZENvZGVMaW5lcyhzZWxlY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyIGJyb3dzZXJzIGNhbiBkaXJlY3RseSB1c2UgdGhlIHNlbGVjdGlvbiBzdHJpbmdcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uVGV4dCA9IHNlbGVjdGlvbi50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlLmNsaXBib2FyZERhdGEhLnNldERhdGEoJ3RleHQvcGxhaW4nLCBzZWxlY3Rpb25UZXh0KTtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZ1bmN0aW9uIGFkZFN0eWxlcygpIHtcbiAgICAgICAgICAgIGNvbnN0IGNzcyA9IGQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgICAgIGNzcy50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgICAgIGNzcy5pbm5lckhUTUwgPSBmb3JtYXQoXG4gICAgICAgICAgICAgICAgJy57MH17Ym9yZGVyLWNvbGxhcHNlOmNvbGxhcHNlfScgKyAnLnswfSB0ZHtwYWRkaW5nOjB9JyArICcuezF9OmJlZm9yZXtjb250ZW50OmF0dHIoezJ9KX0nLFxuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgVEFCTEVfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgTlVNQkVSX0xJTkVfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgREFUQV9BVFRSX05BTUVcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLmFwcGVuZENoaWxkKGNzcyk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpbml0TGluZU51bWJlcnNPbkxvYWQob3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKGQucmVhZHlTdGF0ZSA9PT0gJ2ludGVyYWN0aXZlJyB8fCBkLnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudFJlYWR5KG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB3LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50UmVhZHkob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBkb2N1bWVudFJlYWR5KG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYmxvY2tzID0gZC5xdWVyeVNlbGVjdG9yQWxsKCdjb2RlLmhsanMsY29kZS5ub2hpZ2hsaWdodCcpO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpIGluIGJsb2Nrcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tzLmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzUGx1Z2luRGlzYWJsZWRGb3JCbG9jayhibG9ja3NbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZU51bWJlcnNCbG9jayhibG9ja3NbaV0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0xpbmVOdW1iZXJzIGVycm9yOiAnLCBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGlzUGx1Z2luRGlzYWJsZWRGb3JCbG9jayhlbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ25vaGxqc2xuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBsaW5lTnVtYmVyc0Jsb2NrKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZWxlbWVudCAhPT0gJ29iamVjdCcpIHJldHVybjtcblxuICAgICAgICAgICAgYXN5bmMoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gbGluZU51bWJlcnNJbnRlcm5hbChlbGVtZW50LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gbGluZU51bWJlcnNCbG9ja1N5bmMoZWxlbWVudCwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbGVtZW50ICE9PSAnb2JqZWN0JykgcmV0dXJuO1xuXG4gICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IGxpbmVOdW1iZXJzSW50ZXJuYWwoZWxlbWVudCwgb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBsaW5lTnVtYmVyc1ZhbHVlKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gZC5jcmVhdGVFbGVtZW50KCdjb2RlJyk7XG4gICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHZhbHVlO1xuXG4gICAgICAgICAgICByZXR1cm4gbGluZU51bWJlcnNJbnRlcm5hbChlbGVtZW50LCBvcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGxpbmVOdW1iZXJzSW50ZXJuYWwoZWxlbWVudCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxPcHRpb25zID0gbWFwT3B0aW9ucyhlbGVtZW50LCBvcHRpb25zKTtcblxuICAgICAgICAgICAgZHVwbGljYXRlTXVsdGlsaW5lTm9kZXMoZWxlbWVudCk7XG5cbiAgICAgICAgICAgIHJldHVybiBhZGRMaW5lTnVtYmVyc0Jsb2NrRm9yKGVsZW1lbnQuaW5uZXJIVE1MLCBpbnRlcm5hbE9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gYWRkTGluZU51bWJlcnNCbG9ja0ZvcihpbnB1dEh0bWwsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVzID0gZ2V0TGluZXMoaW5wdXRIdG1sKTtcblxuICAgICAgICAgICAgLy8gaWYgbGFzdCBsaW5lIGNvbnRhaW5zIG9ubHkgY2FycmlhZ2UgcmV0dXJuIHJlbW92ZSBpdFxuICAgICAgICAgICAgaWYgKGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICBsaW5lcy5wb3AoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA+IDEgfHwgb3B0aW9ucy5zaW5nbGVMaW5lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGh0bWwgPSAnJztcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gbGluZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gZm9ybWF0KFxuICAgICAgICAgICAgICAgICAgICAgICAgJzx0cj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHRkIGNsYXNzPVwiezB9IHsxfVwiIHszfT1cIns1fVwiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiezJ9XCIgezN9PVwiezV9XCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvdGQ+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzx0ZCBjbGFzcz1cInswfSB7NH1cIiB7M309XCJ7NX1cIj4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnezZ9JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvdGQ+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvdHI+JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMSU5FX05BTUUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVNQkVSU19CTE9DS19OQU1FLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTUJFUl9MSU5FX05BTUUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgREFUQV9BVFRSX05BTUUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERV9CTE9DS19OQU1FLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKyBvcHRpb25zLnN0YXJ0RnJvbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lc1tpXS5sZW5ndGggPiAwID8gbGluZXNbaV0gOiAnICdcbiAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZm9ybWF0KCc8dGFibGUgY2xhc3M9XCJ7MH1cIj57MX08L3RhYmxlPicsIFtUQUJMRV9OQU1FLCBodG1sXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBpbnB1dEh0bWw7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudCBDb2RlIGJsb2NrLlxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBFeHRlcm5hbCBBUEkgb3B0aW9ucy5cbiAgICAgICAgICogQHJldHVybnMge09iamVjdH0gSW50ZXJuYWwgQVBJIG9wdGlvbnMuXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBtYXBPcHRpb25zKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzaW5nbGVMaW5lOiBnZXRTaW5nbGVMaW5lT3B0aW9uKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgIHN0YXJ0RnJvbTogZ2V0U3RhcnRGcm9tT3B0aW9uKGVsZW1lbnQsIG9wdGlvbnMpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0U2luZ2xlTGluZU9wdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNpbmdsZUxpbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5zaW5nbGVMaW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldFN0YXJ0RnJvbU9wdGlvbihlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSAxO1xuICAgICAgICAgICAgbGV0IHN0YXJ0RnJvbSA9IGRlZmF1bHRWYWx1ZTtcblxuICAgICAgICAgICAgaWYgKGlzRmluaXRlKG9wdGlvbnMuc3RhcnRGcm9tKSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0RnJvbSA9IG9wdGlvbnMuc3RhcnRGcm9tO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjYW4gYmUgb3ZlcnJpZGRlbiBiZWNhdXNlIGxvY2FsIG9wdGlvbiBpcyBwcmlvcml0eVxuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ2RhdGEtbG4tc3RhcnQtZnJvbScpO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgc3RhcnRGcm9tID0gdG9OdW1iZXIodmFsdWUsIGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBzdGFydEZyb207XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogUmVjdXJzaXZlIG1ldGhvZCBmb3IgZml4IG11bHRpLWxpbmUgZWxlbWVudHMgaW1wbGVtZW50YXRpb24gaW4gaGlnaGxpZ2h0LmpzXG4gICAgICAgICAqIERvaW5nIGRlZXAgcGFzc2FnZSBvbiBjaGlsZCBub2Rlcy5cbiAgICAgICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZHVwbGljYXRlTXVsdGlsaW5lTm9kZXMoZWxlbWVudCkge1xuICAgICAgICAgICAgY29uc3Qgbm9kZXMgPSBlbGVtZW50LmNoaWxkTm9kZXM7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgaW4gbm9kZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZXMuaGFzT3duUHJvcGVydHkobm9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGQgPSBub2Rlc1tub2RlXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGdldExpbmVzQ291bnQoY2hpbGQudGV4dENvbnRlbnQpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLmNoaWxkTm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cGxpY2F0ZU11bHRpbGluZU5vZGVzKGNoaWxkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVwbGljYXRlTXVsdGlsaW5lTm9kZShjaGlsZC5wYXJlbnROb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNZXRob2QgZm9yIGZpeCBtdWx0aS1saW5lIGVsZW1lbnRzIGltcGxlbWVudGF0aW9uIGluIGhpZ2hsaWdodC5qc1xuICAgICAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBkdXBsaWNhdGVNdWx0aWxpbmVOb2RlKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGVsZW1lbnQuY2xhc3NOYW1lO1xuXG4gICAgICAgICAgICBpZiAoIS9obGpzLS8udGVzdChjbGFzc05hbWUpKSByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0IGxpbmVzID0gZ2V0TGluZXMoZWxlbWVudC5pbm5lckhUTUwpO1xuXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gJyc7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lVGV4dCA9IGxpbmVzW2ldLmxlbmd0aCA+IDAgPyBsaW5lc1tpXSA6ICcgJztcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gZm9ybWF0KCc8c3BhbiBjbGFzcz1cInswfVwiPnsxfTwvc3Bhbj5cXG4nLCBbY2xhc3NOYW1lLCBsaW5lVGV4dF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IHJlc3VsdC50cmltKCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBnZXRMaW5lcyh0ZXh0KSB7XG4gICAgICAgICAgICBpZiAodGV4dC5sZW5ndGggPT09IDApIHJldHVybiBbXTtcbiAgICAgICAgICAgIHJldHVybiB0ZXh0LnNwbGl0KEJSRUFLX0xJTkVfUkVHRVhQKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldExpbmVzQ291bnQodGV4dCkge1xuICAgICAgICAgICAgcmV0dXJuICh0ZXh0LnRyaW0oKS5tYXRjaChCUkVBS19MSU5FX1JFR0VYUCkgfHwgW10pLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vL1xuICAgICAgICAvLy8gSEVMUEVSU1xuICAgICAgICAvLy9cblxuICAgICAgICBmdW5jdGlvbiBhc3luYyhmdW5jKSB7XG4gICAgICAgICAgICB3LnNldFRpbWVvdXQoZnVuYywgMCk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICoge0BsaW5rIGh0dHBzOi8vd2NvZGVyLmdpdGh1Yi5pby9ub3Rlcy9zdHJpbmctZm9ybWF0LWZvci1zdHJpbmctZm9ybWF0aW5nLWluLWphdmFzY3JpcHR9XG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXRcbiAgICAgICAgICogQHBhcmFtIHthcnJheX0gYXJnc1xuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZm9ybWF0KGZvcm1hdCwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdC5yZXBsYWNlKC9cXHsoXFxkKylcXH0vZywgZnVuY3Rpb24gKG0sIG4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJnc1tuXSAhPT0gdW5kZWZpbmVkID8gYXJnc1tuXSA6IG07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50IENvZGUgYmxvY2suXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBhdHRyTmFtZSBBdHRyaWJ1dGUgbmFtZS5cbiAgICAgICAgICogQHJldHVybnMge1N0cmluZ30gQXR0cmlidXRlIHZhbHVlIG9yIGVtcHR5LlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZ2V0QXR0cmlidXRlKGVsZW1lbnQsIGF0dHJOYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudC5oYXNBdHRyaWJ1dGUoYXR0ck5hbWUpID8gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0ck5hbWUpIDogbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFNvdXJjZSBzdHJpbmcuXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBmYWxsYmFjayBGYWxsYmFjayB2YWx1ZS5cbiAgICAgICAgICogQHJldHVybnMgUGFyc2VkIG51bWJlciBvciBmYWxsYmFjayB2YWx1ZS5cbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIHRvTnVtYmVyKHN0ciwgZmFsbGJhY2spIHtcbiAgICAgICAgICAgIGlmICghc3RyKSByZXR1cm4gZmFsbGJhY2s7XG4gICAgICAgICAgICBjb25zdCBudW1iZXIgPSBOdW1iZXIoc3RyKTtcbiAgICAgICAgICAgIHJldHVybiBpc0Zpbml0ZShudW1iZXIpID8gbnVtYmVyIDogZmFsbGJhY2s7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=