@koobiq/components 18.8.0 → 18.9.1

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