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