@talrace/ngx-noder 0.0.8 → 0.0.10

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 (102) hide show
  1. package/esm2022/lib/apart-components/add-link-dialog/add-link-dialog.component.mjs +21 -9
  2. package/esm2022/lib/apart-components/editor-toolbar/components/base-toolbar.component.mjs +8 -2
  3. package/esm2022/lib/apart-components/editor-toolbar/components/buttons/font/font.component.mjs +2 -2
  4. package/esm2022/lib/apart-components/editor-toolbar/components/buttons/font-size/font-size.component.mjs +3 -3
  5. package/esm2022/lib/apart-components/editor-toolbar/editor-mobile-toolbar/editor-mobile-toolbar.component.mjs +2 -2
  6. package/esm2022/lib/apart-components/editor-toolbar/shared/toolbar-styles.helper.mjs +1 -8
  7. package/esm2022/lib/editor/components/edges/edge.component.mjs +2 -2
  8. package/esm2022/lib/editor/components/edges/edges.mjs +21 -2
  9. package/esm2022/lib/editor/components/image/input-handler/image-input.handler.mjs +18 -1
  10. package/esm2022/lib/editor/components/shared/services/custom-content.service.mjs +22 -56
  11. package/esm2022/lib/editor/components/table/components/table-cell.component.mjs +6 -6
  12. package/esm2022/lib/editor/components/table/components/table.component.mjs +13 -4
  13. package/esm2022/lib/editor/components/table/models/cell-data.model.mjs +3 -4
  14. package/esm2022/lib/editor/components/table/selection/table-selection.mjs +15 -5
  15. package/esm2022/lib/editor/content/constants/editor.const.mjs +9 -1
  16. package/esm2022/lib/editor/content/display-data/display-data.mjs +839 -0
  17. package/esm2022/lib/editor/content/display-data/general-properties.model.mjs +1 -1
  18. package/esm2022/lib/editor/content/display-data/models/paragraph-info.model.mjs +8 -0
  19. package/esm2022/lib/editor/content/display-data/paragraph.mjs +5 -1
  20. package/esm2022/lib/editor/content/display-data/text-line-info.mjs +2 -1
  21. package/esm2022/lib/editor/content/display-data/toolbar-styles.interface.mjs +1 -1
  22. package/esm2022/lib/editor/content/helpers/content-style.helper.mjs +12 -30
  23. package/esm2022/lib/editor/content/helpers/display-token.helper.mjs +62 -0
  24. package/esm2022/lib/editor/content/helpers/link.helper.mjs +6 -0
  25. package/esm2022/lib/editor/display/layers/cursor.layer.mjs +9 -8
  26. package/esm2022/lib/editor/display/layers/pages.layer.mjs +5 -5
  27. package/esm2022/lib/editor/display/layers/print.text.layer.mjs +2 -2
  28. package/esm2022/lib/editor/display/layers/selection.layer.mjs +15 -9
  29. package/esm2022/lib/editor/display/layers/text.layer.mjs +29 -32
  30. package/esm2022/lib/editor/display/print/print.renderer.mjs +8 -8
  31. package/esm2022/lib/editor/display/renderer.mjs +10 -10
  32. package/esm2022/lib/editor/display/rendering.helper.mjs +2 -4
  33. package/esm2022/lib/editor/display/virtual.renderer.mjs +5 -5
  34. package/esm2022/lib/editor/execution/edit.session.mjs +211 -754
  35. package/esm2022/lib/editor/execution/editor.mjs +119 -77
  36. package/esm2022/lib/editor/execution/helpers/format-style.helper.mjs +41 -32
  37. package/esm2022/lib/editor/execution/helpers/image.helpet.mjs +12 -0
  38. package/esm2022/lib/editor/execution/helpers/paragraph.helper.mjs +11 -3
  39. package/esm2022/lib/editor/execution/regulator.service.mjs +28 -20
  40. package/esm2022/lib/editor/gadgets/numbering/numbering-paragraph-style.model.mjs +13 -0
  41. package/esm2022/lib/editor/gadgets/numbering/numbering.helper.mjs +77 -10
  42. package/esm2022/lib/editor/gadgets/search/search.mjs +6 -6
  43. package/esm2022/lib/editor/interaction/editor.service.mjs +27 -6
  44. package/esm2022/lib/editor/interaction/input.handler.mjs +8 -5
  45. package/esm2022/lib/editor/interaction/mouse.handler.mjs +2 -1
  46. package/esm2022/lib/editor/operations/helpers/format-operations.helper.mjs +32 -2
  47. package/esm2022/lib/editor/operations/helpers/link-operations.helper.mjs +67 -14
  48. package/esm2022/lib/editor/operations/operations-helper.helper.mjs +27 -20
  49. package/esm2022/lib/editor/operations/save-commands.helper.mjs +2 -2
  50. package/esm2022/lib/editor/positioning/content.helper.mjs +15 -15
  51. package/esm2022/lib/editor/positioning/line-width.helper.mjs +5 -5
  52. package/esm2022/lib/editor/positioning/position.helper.mjs +34 -32
  53. package/esm2022/lib/editor/positioning/selection.mjs +42 -32
  54. package/esm2022/lib/editor/revision.helper.mjs +4 -3
  55. package/esm2022/lib/models/generated/link.model.mjs +1 -1
  56. package/esm2022/public-api.mjs +2 -1
  57. package/fesm2022/talrace-ngx-noder.mjs +3863 -3558
  58. package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
  59. package/lib/apart-components/add-link-dialog/add-link-dialog.component.d.ts +0 -1
  60. package/lib/apart-components/editor-toolbar/shared/toolbar-styles.helper.d.ts +0 -2
  61. package/lib/editor/components/image/input-handler/image-input.handler.d.ts +3 -0
  62. package/lib/editor/components/shared/services/custom-content.service.d.ts +3 -5
  63. package/lib/editor/components/table/components/table-cell.component.d.ts +1 -1
  64. package/lib/editor/components/table/components/table.component.d.ts +1 -0
  65. package/lib/editor/components/table/models/cell-data.model.d.ts +1 -1
  66. package/lib/editor/components/table/selection/table-selection.d.ts +2 -0
  67. package/lib/editor/content/constants/editor.const.d.ts +2 -0
  68. package/lib/editor/content/display-data/display-data.d.ts +103 -0
  69. package/lib/editor/content/display-data/general-properties.model.d.ts +5 -0
  70. package/lib/editor/content/display-data/models/paragraph-info.model.d.ts +9 -0
  71. package/lib/editor/content/display-data/paragraph.d.ts +1 -0
  72. package/lib/editor/content/display-data/text-line-info.d.ts +1 -0
  73. package/lib/editor/content/display-data/toolbar-styles.interface.d.ts +1 -1
  74. package/lib/editor/content/helpers/content-style.helper.d.ts +1 -2
  75. package/lib/editor/content/helpers/display-token.helper.d.ts +6 -0
  76. package/lib/editor/content/helpers/link.helper.d.ts +4 -0
  77. package/lib/editor/display/layers/text.layer.d.ts +2 -3
  78. package/lib/editor/display/print/print.renderer.d.ts +0 -2
  79. package/lib/editor/execution/edit.session.d.ts +12 -59
  80. package/lib/editor/execution/editor.d.ts +9 -6
  81. package/lib/editor/execution/helpers/format-style.helper.d.ts +2 -2
  82. package/lib/editor/execution/helpers/image.helpet.d.ts +4 -0
  83. package/lib/editor/execution/regulator.service.d.ts +1 -1
  84. package/lib/editor/gadgets/numbering/numbering-paragraph-style.model.d.ts +6 -0
  85. package/lib/editor/gadgets/numbering/numbering.helper.d.ts +10 -3
  86. package/lib/editor/interaction/editor.service.d.ts +12 -3
  87. package/lib/editor/operations/helpers/link-operations.helper.d.ts +6 -3
  88. package/lib/editor/positioning/content.helper.d.ts +6 -5
  89. package/lib/editor/positioning/position.helper.d.ts +3 -3
  90. package/lib/editor/positioning/selection.d.ts +3 -0
  91. package/lib/models/generated/link.model.d.ts +3 -1
  92. package/package.json +8 -8
  93. package/public-api.d.ts +1 -0
  94. package/src/_ngx-noder.theme.scss +31 -2
  95. package/src/styles.scss +0 -1
  96. package/esm2022/lib/editor/content/display-data/document.mjs +0 -134
  97. package/esm2022/lib/editor/content/display-data/pages.wrap.mjs +0 -226
  98. package/esm2022/lib/editor/execution/helpers/delta.helper.mjs +0 -18
  99. package/lib/editor/content/display-data/document.d.ts +0 -56
  100. package/lib/editor/content/display-data/pages.wrap.d.ts +0 -42
  101. package/lib/editor/execution/helpers/delta.helper.d.ts +0 -6
  102. package/src/scss/_fonts.scss +0 -3
@@ -0,0 +1,839 @@
1
+ import { BreakHelper } from '../../gadgets/page-break/break.helper';
2
+ import { BreakTypes } from '../../gadgets/page-break/break-types.enum';
3
+ import { ContentStyleHelper } from '../helpers/content-style.helper';
4
+ import { CursorParagraph } from '../../positioning/cursor-paragraph';
5
+ import { DEFAULT_FONT_SIZE, DEFAULT_PARAGRAPH_STYLE, NEW_LINE_MARKUP } from '../constants/editor.const';
6
+ import { DisplayToken } from './display-token.model';
7
+ import { DisplayTokenHelper } from '../helpers/display-token.helper';
8
+ import { DisplayValue } from '../constants/display-values.const';
9
+ import { EdgeType } from '../../components/edges/edge-type.enum';
10
+ import { EventEmitting } from '../../core/event-emitting';
11
+ import { FontMetrics } from '../../gadgets/font-metrics/font-metrics.helper';
12
+ import { FormatStyleHelper } from '../../execution/helpers/format-style.helper';
13
+ import { IndentModel } from './indent.model';
14
+ import { LineInfoModel } from './line-info.model';
15
+ import { NoderTableComponent } from '../../components/table/components/table.component';
16
+ import { NumberingHelper } from '../../gadgets/numbering/numbering.helper';
17
+ import { PageHelper } from '../../execution/helpers/page.helper';
18
+ import { PageType } from '../../components/edges/page-type.enum';
19
+ import { PageVerticalDataModel } from '../page-vertical-data.model';
20
+ import { Paragraph } from './paragraph';
21
+ import { ParagraphHelper } from '../../execution/helpers/paragraph.helper';
22
+ import { ParagraphInfoModel } from './models/paragraph-info.model';
23
+ import { ParagraphStyleHelper } from '../../execution/helpers/paragraph-style.helper';
24
+ import { Range } from '../../positioning/range';
25
+ import { TabHelper } from '../../components/tab/tab.helper';
26
+ export class DisplayData extends EventEmitting {
27
+ get defaultVerticalData() {
28
+ return this.pagesVerticalData.find(x => x.pageType === PageType.Default);
29
+ }
30
+ constructor(model, generalProperties, sessionId, pageMargin, pagesSpace, pageWidth, pageHeight, customComponents, customContentService, editorService) {
31
+ super();
32
+ this.model = model;
33
+ this.generalProperties = generalProperties;
34
+ this.sessionId = sessionId;
35
+ this.pageMargin = pageMargin;
36
+ this.pagesSpace = pagesSpace;
37
+ this.pageWidth = pageWidth;
38
+ this.pageHeight = pageHeight;
39
+ this.customComponents = customComponents;
40
+ this.customContentService = customContentService;
41
+ this.editorService = editorService;
42
+ this.paragraphs = [];
43
+ this.allPagesHeight = 0;
44
+ this.minHeight = 0;
45
+ this.tabTokens = [];
46
+ this.paragraphs = this.splitByParagraphs(this.model.content).map(x => new ParagraphInfoModel({ content: x }));
47
+ this.minHeight = this.pageHeight + 2 * this.pagesSpace;
48
+ this.contentWidth = this.pageWidth - this.pageMargin.left - this.pageMargin.right;
49
+ this.initPagesVerticalData();
50
+ this.processTextLinesProperties = !this.pageHeight
51
+ ? ParagraphHelper.processTextLinesPropertiesForSinglePage
52
+ : ParagraphHelper.processTextLinesProperties;
53
+ }
54
+ insertText(position, text) {
55
+ const endPoint = this.insertTextAndReturnEndCursorPosition(text, position);
56
+ return endPoint;
57
+ }
58
+ removeRange(range) {
59
+ const paragraphText = this.paragraphs[range.start.row].content.slice(0, range.start.column) +
60
+ this.paragraphs[range.end.row].content.slice(range.end.column);
61
+ const paragraphSettings = this.getParagraphSettings(range.start.row);
62
+ this.paragraphs.splice(range.start.row, range.end.row - range.start.row + 1, new ParagraphInfoModel({ content: paragraphText }));
63
+ this.paragraphs[range.start.row].paragraphSettings = paragraphSettings;
64
+ }
65
+ getParagraphContent(index) {
66
+ return this.paragraphs[index]?.content || '';
67
+ }
68
+ getAllParagraphsContent() {
69
+ return this.paragraphs.map(x => x.content);
70
+ }
71
+ getParagraphSettings(index) {
72
+ return this.paragraphs[index]?.paragraphSettings || null;
73
+ }
74
+ getParagraphsContentForRange(range) {
75
+ if (range.isSingleLine) {
76
+ const line = this.getParagraphContent(range.start.row);
77
+ const linePartInRange = line.slice(range.start.column, range.end.column);
78
+ return [linePartInRange];
79
+ }
80
+ const paragraphsContent = this.paragraphs.slice(range.start.row, range.end.row + 1).map(x => x.content);
81
+ paragraphsContent[0] = (paragraphsContent[0] || '').slice(range.start.column);
82
+ const lastIndex = paragraphsContent.length - 1;
83
+ paragraphsContent[lastIndex] = paragraphsContent[lastIndex].slice(0, range.end.column);
84
+ return paragraphsContent;
85
+ }
86
+ getTextRange(range) {
87
+ return this.getParagraphsContentForRange(range).join(NEW_LINE_MARKUP);
88
+ }
89
+ positionToIndex(position, startRow = 0) {
90
+ let index = 0;
91
+ const endRow = Math.min(position.row, this.paragraphs.length);
92
+ for (let i = startRow || 0; i < endRow; i++) {
93
+ index += this.paragraphs[i].content.length + 1;
94
+ }
95
+ return index + position.column;
96
+ }
97
+ indexToPosition(positionIndex, startRow) {
98
+ const newlineLength = NEW_LINE_MARKUP.length;
99
+ for (let lineIndex = startRow || 0; lineIndex < this.paragraphs.length; lineIndex++) {
100
+ positionIndex -= this.paragraphs[lineIndex].content.length + newlineLength;
101
+ if (positionIndex < 0) {
102
+ const column = positionIndex + this.paragraphs[lineIndex].content.length + newlineLength;
103
+ return new CursorParagraph(lineIndex, column);
104
+ }
105
+ }
106
+ const column = positionIndex + this.paragraphs[this.paragraphs.length - 1].content.length + newlineLength;
107
+ return new CursorParagraph(this.paragraphs.length - 1, column);
108
+ }
109
+ indexesToRange(startIndex, endIndex) {
110
+ const startPoint = this.indexToPosition(startIndex, 0);
111
+ const endPoint = this.indexToPosition(endIndex, 0);
112
+ return new Range(startPoint, endPoint);
113
+ }
114
+ isNewLineSymbol(index) {
115
+ const text = this.paragraphs.map(x => x.content).join(NEW_LINE_MARKUP);
116
+ return !text || !text[index] || text[index] === NEW_LINE_MARKUP;
117
+ }
118
+ getSelectedParagraphsByRange(range) {
119
+ const newlineLength = NEW_LINE_MARKUP.length;
120
+ let start = 0;
121
+ let end = 0;
122
+ let i;
123
+ const row = Math.min(range.end.row, this.paragraphs.length - 1);
124
+ for (i = 0; i < row; i++) {
125
+ if (i < range.start.row) {
126
+ start += this.paragraphs[i].content.length + newlineLength;
127
+ }
128
+ end += this.paragraphs[i].content.length + newlineLength;
129
+ }
130
+ if (i < this.paragraphs.length) {
131
+ end += this.paragraphs[i].content.length;
132
+ }
133
+ return { start, end };
134
+ }
135
+ getPositionAfterBreak(position, breakType) {
136
+ if (breakType === BreakTypes.TextWrapping) {
137
+ return position;
138
+ }
139
+ const isLastColumn = position.column === this.paragraphs[position.row].content.length;
140
+ const isLastParagraph = position.row === this.paragraphs.length - 1;
141
+ return isLastColumn && !isLastParagraph ? new CursorParagraph(position.row + 1, 0) : position;
142
+ }
143
+ getDistanceFromTop(index) {
144
+ return this.paragraphs[index]?.paragraphSettings ? this.paragraphs[index].paragraphSettings.distanceFromTop : 0;
145
+ }
146
+ getDistanceFromTopForPrint(index) {
147
+ if (!this.paragraphs[index]?.paragraphSettings) {
148
+ return 0;
149
+ }
150
+ const paragraph = this.paragraphs[index].paragraphSettings;
151
+ const pageNumber = paragraph.pageNumbers[0];
152
+ let pageBreakHeight = 0;
153
+ paragraph.textLinesInfo.forEach(linesInfo => {
154
+ if (linesInfo.isAfterPageBreak) {
155
+ pageBreakHeight = linesInfo.height;
156
+ }
157
+ });
158
+ return paragraph.distanceFromTop - pageNumber * this.pagesSpace - pageBreakHeight;
159
+ }
160
+ setParagraphSettings(row, lineInfos, numberingData) {
161
+ if (!this.paragraphs[row].paragraphSettings) {
162
+ this.paragraphs[row].paragraphSettings = new Paragraph(numberingData, lineInfos[0].offsetBefore, this.processTextLinesProperties);
163
+ }
164
+ this.paragraphs[row].paragraphSettings.numberingData = numberingData;
165
+ this.paragraphs[row].paragraphSettings.width = this.contentWidth;
166
+ this.paragraphs[row].paragraphSettings.setTextLinesInfo(lineInfos);
167
+ }
168
+ getParagraphHeight(index) {
169
+ return this.paragraphs[index]?.paragraphSettings ? this.paragraphs[index].paragraphSettings.height : 0;
170
+ }
171
+ getVisibleRange(offsetTop, scrollerHeight) {
172
+ let start = this.paragraphs.findIndex(x => offsetTop <= x.paragraphSettings?.distanceFromTop + x.paragraphSettings?.height);
173
+ if (start < 0) {
174
+ start = 0;
175
+ }
176
+ let startLineInfo = null;
177
+ const startParagraph = this.paragraphs[start];
178
+ if (startParagraph) {
179
+ const startParagraphOffsetTop = offsetTop - startParagraph.paragraphSettings.distanceFromTop;
180
+ startLineInfo = ParagraphHelper.getVisibleLineInfo(startParagraph?.paragraphSettings.textLinesInfo, startParagraphOffsetTop, 1);
181
+ }
182
+ if (!startLineInfo) {
183
+ return {
184
+ startParagraph: 0,
185
+ startLine: 0,
186
+ startScreenLine: 0,
187
+ startScreenFullLine: 0,
188
+ endParagraph: 0,
189
+ endLine: 0,
190
+ endScreenLine: 0,
191
+ endScreenFullLine: 0,
192
+ pages: [1]
193
+ };
194
+ }
195
+ let end = this.paragraphs.findIndex(x => offsetTop + scrollerHeight <= x.paragraphSettings.distanceFromTop + x.paragraphSettings.height);
196
+ if (end < 0) {
197
+ end = this.paragraphs.length - 1;
198
+ }
199
+ let endLineInfo = null;
200
+ const endParagraph = this.paragraphs[end];
201
+ if (endParagraph) {
202
+ const endParagraphOffsetTop = offsetTop + scrollerHeight - endParagraph.paragraphSettings.distanceFromTop;
203
+ endLineInfo = ParagraphHelper.getVisibleLineInfo(endParagraph.paragraphSettings?.textLinesInfo, endParagraphOffsetTop, -1);
204
+ }
205
+ const visiblePages = this.getVisiblePages(offsetTop, scrollerHeight);
206
+ return {
207
+ startParagraph: start,
208
+ startLine: startLineInfo.index,
209
+ startScreenLine: startLineInfo.screenIndex,
210
+ startScreenFullLine: startLineInfo.visibleScreenIndex,
211
+ endParagraph: end,
212
+ endLine: endLineInfo.index,
213
+ endScreenLine: endLineInfo.screenIndex,
214
+ endScreenFullLine: endLineInfo.visibleScreenIndex,
215
+ pages: visiblePages
216
+ };
217
+ }
218
+ processParagraphsProperties(startParagraphIndex) {
219
+ this.setParagraphIndexes();
220
+ const pagesInfo = { pagesVerticalData: this.pagesVerticalData, pagesSpace: this.pagesSpace };
221
+ let currentPage = startParagraphIndex === 0 ? 1 : this.paragraphs[startParagraphIndex - 1].paragraphSettings.lastPageNumber;
222
+ let pageVerticalData = PageHelper.getVerticalData(currentPage, this.pagesVerticalData);
223
+ for (let i = startParagraphIndex; i < this.paragraphs.length; i++) {
224
+ const prevParagraphInfo = this.getPreviousParagraphInfo(i);
225
+ const paragraphSettings = this.paragraphs[i].paragraphSettings;
226
+ paragraphSettings.processParagraphProperties(prevParagraphInfo, pagesInfo, this.customComponents.tables);
227
+ if (paragraphSettings.firstPageNumber !== currentPage) {
228
+ currentPage = paragraphSettings.firstPageNumber;
229
+ pageVerticalData = PageHelper.getVerticalData(paragraphSettings.firstPageNumber, this.pagesVerticalData);
230
+ }
231
+ paragraphSettings.calculateDistanceFromTop(this.pageHeight, this.pagesSpace, pageVerticalData.marginTop);
232
+ }
233
+ let pageHeight = this.pageHeight;
234
+ if (!pageHeight) {
235
+ pageHeight = this.getAllParagraphsHeight() + this.pageMargin.top + this.pageMargin.bottom;
236
+ this.minHeight = pageHeight + 2 * this.pagesSpace;
237
+ this.defaultVerticalData.contentHeight = pageHeight;
238
+ }
239
+ const lastPageNumber = this.paragraphs[this.paragraphs.length - 1].paragraphSettings.lastPageNumber;
240
+ this.allPagesHeight = lastPageNumber * (pageHeight + this.pagesSpace) + this.pagesSpace;
241
+ this.emit('pagesCountChanged', { pagesCount: lastPageNumber, pageHeight: pageHeight + 2 * this.pagesSpace });
242
+ }
243
+ getAllParagraphsHeight() {
244
+ return this.paragraphs.reduce((sum, x) => sum + x.paragraphSettings.height, 0);
245
+ }
246
+ destroy() {
247
+ this.removeAllListeners('pagesCountChanged');
248
+ }
249
+ updatePageVerticalData(edgeType, page) {
250
+ const pageVerticalData = PageHelper.getVerticalData(page, this.pagesVerticalData);
251
+ const componentHeight = this.customComponents.edges.getComponentHeight(page, edgeType);
252
+ if (edgeType === EdgeType.Header) {
253
+ pageVerticalData.marginTop = componentHeight > this.pageMargin.top ? componentHeight : this.pageMargin.top;
254
+ }
255
+ else {
256
+ pageVerticalData.marginBottom = componentHeight > this.pageMargin.bottom ? componentHeight : this.pageMargin.bottom;
257
+ }
258
+ const newContentHeight = this.pageHeight - pageVerticalData.marginTop - pageVerticalData.marginBottom;
259
+ if (newContentHeight === pageVerticalData.contentHeight) {
260
+ return;
261
+ }
262
+ pageVerticalData.contentHeight = newContentHeight;
263
+ this.processParagraphsProperties(0);
264
+ }
265
+ updateParagraphLineNumber(first) {
266
+ const count = this.paragraphs.length;
267
+ if (first === 0) {
268
+ this.paragraphs[first].lineNumber = 0;
269
+ first++;
270
+ }
271
+ for (let i = first; i < count; i++) {
272
+ this.paragraphs[i].lineNumber = this.paragraphs[i - 1].lineNumber + this.paragraphs[i - 1].nextLineIndexes.length + 1;
273
+ }
274
+ }
275
+ updateParagraphStartIndex(first) {
276
+ if (first === 0) {
277
+ this.paragraphs[first].startIndex = 0;
278
+ first++;
279
+ }
280
+ for (let i = first; i < this.paragraphs.length; i++) {
281
+ this.paragraphs[i].startIndex = this.paragraphs[i - 1].startIndex + this.getParagraphContent(i - 1).length + 1;
282
+ }
283
+ }
284
+ updateParagraphSettingsNumberingData(index) {
285
+ const paragraphSettings = this.getParagraphSettings(index);
286
+ if (paragraphSettings.numberingData.numberingId !== this.model.paragraphs[index].paragraphStyle.numberingId) {
287
+ paragraphSettings.numberingData = NumberingHelper.createDataModel(this.generalProperties.numberings, this.model.paragraphs, index, this.generalProperties.numberingInfo);
288
+ }
289
+ if (paragraphSettings.numberingData.numberingId !== null) {
290
+ const paragraphFormat = FormatStyleHelper.getFormatAtIndex(this.model.formats, this.model.paragraphs[index].insertIndex);
291
+ NumberingHelper.updateMarkerData(this.generalProperties, paragraphSettings, paragraphFormat.textStyle, this.model.paragraphs[index].paragraphStyle);
292
+ }
293
+ }
294
+ updateNextLineIndexes(firstParagraph, lastParagraph) {
295
+ this.updateParagraphStartIndex(firstParagraph);
296
+ let indexOfParagraphAfterPageBreak = this.getParagraphSettings(firstParagraph - 1)?.isEndedByPageBreak ? firstParagraph : -1;
297
+ let firstUsedTabIndex = this.model.tabs.findIndex(x => x.insertIndex >= this.paragraphs[firstParagraph].startIndex);
298
+ for (let i = firstParagraph; i <= lastParagraph; i++) {
299
+ if (!this.paragraphs[i]) {
300
+ continue;
301
+ }
302
+ this.tabTokens = [];
303
+ NumberingHelper.calculateNumberingInfo(this.model.paragraphs[i].paragraphStyle.numberingId, this.model.paragraphs[i].paragraphStyle.numberingLevel, this.getParagraphSettings(i)?.numberingData.marker, this.generalProperties.numberingInfo, this.generalProperties.numberings);
304
+ const numberingData = NumberingHelper.createDataModel(this.generalProperties.numberings, this.model.paragraphs, i, this.generalProperties.numberingInfo);
305
+ const { splits, rowInfos } = this.getSplits(this.model, i);
306
+ this.paragraphs[i].nextLineIndexes = splits;
307
+ if (indexOfParagraphAfterPageBreak === i) {
308
+ rowInfos[0].isAfterPageBreak = true;
309
+ }
310
+ indexOfParagraphAfterPageBreak = rowInfos[rowInfos.length - 1].isEndedByPageBreak ? i + 1 : -1;
311
+ this.setParagraphSettings(i, rowInfos, numberingData);
312
+ this.updateParagraphSettingsNumberingData(i);
313
+ firstUsedTabIndex = this.updateParagraphTabs(firstUsedTabIndex, i);
314
+ }
315
+ this.getParagraphSettings(lastParagraph + 1)?.setIsAfterPageBreak(indexOfParagraphAfterPageBreak > -1);
316
+ this.updateParagraphLineNumber(firstParagraph);
317
+ this.processParagraphsProperties(firstParagraph);
318
+ }
319
+ updateNumberingsDataOnChange(index) {
320
+ for (let i = index; i < this.paragraphs.length; i++) {
321
+ const paragraphStyle = this.model.paragraphs[i].paragraphStyle;
322
+ const paragraphSettings = this.getParagraphSettings(i);
323
+ if (this.model.paragraphs[i].paragraphStyle.numberingId !== null) {
324
+ NumberingHelper.calculateNumberingInfo(paragraphStyle.numberingId, paragraphStyle.numberingLevel, paragraphSettings.numberingData.marker, this.generalProperties.numberingInfo, this.generalProperties.numberings);
325
+ paragraphSettings.numberingData = NumberingHelper.createDataModel(this.generalProperties.numberings, this.model.paragraphs, i, this.generalProperties.numberingInfo);
326
+ const paragraphFormat = FormatStyleHelper.getFormatAtIndex(this.model.formats, this.model.paragraphs[i].insertIndex);
327
+ NumberingHelper.updateMarkerData(this.generalProperties, paragraphSettings, paragraphFormat.textStyle, paragraphStyle);
328
+ }
329
+ const table = this.customContentService.findComponent(this.customComponents.tables, paragraphSettings.startInsertIndex);
330
+ if (table) {
331
+ table.instance.updateCells();
332
+ }
333
+ }
334
+ if ('pageType' in this.model) {
335
+ this.editorService.updateEdges(this.sessionId);
336
+ }
337
+ }
338
+ resetAllNumberingInfo(paragraphIndex) {
339
+ for (let i = paragraphIndex; i < this.model.paragraphs.length; i++) {
340
+ const { numberingId, numberingLevel } = this.model.paragraphs[i].paragraphStyle;
341
+ if (numberingId !== null &&
342
+ this.generalProperties.numberingInfo[numberingId] &&
343
+ this.generalProperties.numberingInfo[numberingId][numberingLevel]) {
344
+ this.generalProperties.numberingInfo[numberingId][numberingLevel].visited = false;
345
+ }
346
+ }
347
+ }
348
+ resetNumberingInfoByTableCell(table) {
349
+ for (let i = 0; i < table.instance.rowMatrix.length; i++) {
350
+ for (let cell of table.instance.rowMatrix[i].cells) {
351
+ const { marker, numberingId } = cell.componentRef.instance.session.displayData.paragraphs[0].paragraphSettings.numberingData;
352
+ if (marker && numberingId) {
353
+ NumberingHelper.updateNumberingInfo(this.generalProperties.numberingInfo, marker, numberingId);
354
+ this.resetAllNumberingInfo(0);
355
+ return;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ updateParagraphTabs(tabIndex, paragraphIndex) {
361
+ const paragraphContentLength = this.getParagraphContent(paragraphIndex).length;
362
+ const paragraphLastIndex = this.paragraphs[paragraphIndex].startIndex + paragraphContentLength;
363
+ if (tabIndex === -1 ||
364
+ tabIndex >= this.customComponents.tabs.length ||
365
+ this.customComponents.tabs[tabIndex].instance.insertIndex > paragraphLastIndex) {
366
+ return tabIndex;
367
+ }
368
+ const startIndex = tabIndex;
369
+ while (this.customComponents.tabs[tabIndex] && this.customComponents.tabs[tabIndex].instance.insertIndex <= paragraphLastIndex) {
370
+ this.customComponents.tabs[tabIndex].instance.width = this.tabTokens[tabIndex - startIndex].width;
371
+ this.customComponents.tabs[tabIndex].instance.height = this.tabTokens[tabIndex - startIndex].font;
372
+ tabIndex++;
373
+ }
374
+ return tabIndex;
375
+ }
376
+ getSplits(model, paragraphIndex) {
377
+ const paragraphContent = this.getParagraphContent(paragraphIndex);
378
+ const strTokens = this.getDisplayTokens(model, paragraphContent, this.paragraphs[paragraphIndex].startIndex);
379
+ if (!strTokens.length) {
380
+ const defaultRowInfo = new LineInfoModel({
381
+ height: (DEFAULT_FONT_SIZE * 4) / 3,
382
+ width: 0,
383
+ align: DEFAULT_PARAGRAPH_STYLE.alignment,
384
+ indent: new IndentModel(DEFAULT_PARAGRAPH_STYLE.indentFirstLine, DEFAULT_PARAGRAPH_STYLE.indentHanging, DEFAULT_PARAGRAPH_STYLE.indentLeft, DEFAULT_PARAGRAPH_STYLE.indentRight),
385
+ offsetAfter: DEFAULT_PARAGRAPH_STYLE.spaceAfter,
386
+ offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
387
+ lineSpacing: DEFAULT_PARAGRAPH_STYLE.lineSpacing,
388
+ isAfterPageBreak: false,
389
+ isEndedByPageBreak: false,
390
+ backgroundColor: DEFAULT_PARAGRAPH_STYLE.backgroundColor
391
+ });
392
+ return { splits: [], rowInfos: [defaultRowInfo] };
393
+ }
394
+ const splits = [];
395
+ const rowInfos = [];
396
+ let prevToken;
397
+ let index = -1;
398
+ let initial = paragraphContent;
399
+ while (index) {
400
+ initial = initial.slice(index > 0 ? index : 0);
401
+ const tokens = strTokens.slice(paragraphContent.length - initial.length);
402
+ if (!tokens.length) {
403
+ tokens.push(...this.getEmptyDisplayTokens(model, this.paragraphs[paragraphIndex].startIndex + index));
404
+ }
405
+ let wrapLimit = this.computeWrapIndex(tokens, this.contentWidth, this.generalProperties.defaultTabWidth);
406
+ if (tokens[tokens.length - 1].isPageBreak && wrapLimit === tokens.length && this.paragraphs.length > paragraphIndex + 1) {
407
+ wrapLimit = 0;
408
+ }
409
+ const wrapSplit = tokens[wrapLimit - 1]?.breaksLine || tokens[wrapLimit - 1]?.isTable ? wrapLimit : this.computeWrapSplit(tokens, wrapLimit);
410
+ const wrapTokens = tokens.slice(0, wrapSplit || undefined);
411
+ if (wrapTokens.length) {
412
+ prevToken = wrapTokens[wrapTokens.length - 1];
413
+ }
414
+ const isAfterPageBreak = !rowInfos.length ? false : rowInfos[rowInfos.length - 1].isEndedByPageBreak;
415
+ const lineInfo = DisplayTokenHelper.getLineInfoFromToken(prevToken, wrapTokens[0], wrapTokens, isAfterPageBreak);
416
+ lineInfo.backgroundColor = model.paragraphs[paragraphIndex].paragraphStyle.backgroundColor;
417
+ rowInfos.push(lineInfo);
418
+ if (!wrapLimit) {
419
+ break;
420
+ }
421
+ index = wrapSplit;
422
+ const splitsLength = splits.length;
423
+ const splitIndex = splitsLength ? index + splits[splitsLength - 1] : index;
424
+ splits.push(splitIndex);
425
+ }
426
+ this.tabTokens.push(...strTokens.filter(x => x.isTab));
427
+ ParagraphHelper.applyParagraphIndentsToLines(rowInfos, paragraphIndex, model.paragraphs);
428
+ return { splits, rowInfos };
429
+ }
430
+ /**
431
+ * Given a string, returns an array of the display characters, including tabs and spaces and custom components.
432
+ */
433
+ getDisplayTokens(model, str, startIndex) {
434
+ if (!str.length) {
435
+ return this.getEmptyDisplayTokens(model, startIndex);
436
+ }
437
+ return this.fillLineTokens(startIndex, str, model);
438
+ }
439
+ fillLineTokens(startIndex, line, model) {
440
+ const lineInfo = this.getLineInfoByBreakModifier(model, startIndex + line.length);
441
+ const tokens = [];
442
+ let characters = [];
443
+ let format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
444
+ let prevFormat = null;
445
+ let prevCharCode = null;
446
+ let prevFontString = null;
447
+ let prevChar = null;
448
+ let fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
449
+ let symbolChange = false;
450
+ for (let i = 0; i < line.length; i++) {
451
+ const char = line[i];
452
+ const size = FontMetrics.measureCharSize(char, fontString);
453
+ const customComponent = this.getOrGenerateComponent(startIndex, char);
454
+ const breakType = BreakHelper.getBreakType(model, char, startIndex);
455
+ if (customComponent && !breakType) {
456
+ const token = this.customContentService.getTokenFromComponent(customComponent, lineInfo, DisplayValue.customContent, i === 0, size);
457
+ tokens.push(token);
458
+ prevCharCode = -1;
459
+ prevChar = '';
460
+ characters = [];
461
+ }
462
+ else {
463
+ const charCode = char.charCodeAt(0);
464
+ const displayValue = DisplayTokenHelper.getDisplayValue(charCode);
465
+ const isFirstCharacter = i === 0;
466
+ const token = new DisplayToken({
467
+ ...size,
468
+ displayValue,
469
+ align: lineInfo.align,
470
+ indentFirstLine: isFirstCharacter ? lineInfo.indent.firstLine : DEFAULT_PARAGRAPH_STYLE.indentFirstLine,
471
+ indentHanging: isFirstCharacter ? lineInfo.indent.hanging : DEFAULT_PARAGRAPH_STYLE.indentHanging,
472
+ indentLeft: lineInfo.indent.left,
473
+ indentRight: lineInfo.indent.right,
474
+ indentBefore: lineInfo.offsetBefore,
475
+ indentAfter: lineInfo.offsetAfter,
476
+ lineSpacing: lineInfo.lineSpacing,
477
+ isPageBreak: breakType === BreakTypes.Page,
478
+ isLineBreak: breakType === BreakTypes.TextWrapping,
479
+ isTab: false
480
+ });
481
+ tokens.push(token);
482
+ if (charCode !== prevCharCode ||
483
+ !prevFormat ||
484
+ !ContentStyleHelper.areSameTextStyles(format?.textStyle, prevFormat?.textStyle)) {
485
+ symbolChange = true;
486
+ }
487
+ else if (i === line.length - 1) {
488
+ characters.push(token);
489
+ symbolChange = true;
490
+ }
491
+ else {
492
+ characters.push(token);
493
+ }
494
+ if (characters.length > 1 && symbolChange) {
495
+ this.processCharSizes(prevChar, prevFontString, characters);
496
+ characters = [token];
497
+ symbolChange = false;
498
+ }
499
+ else if (symbolChange) {
500
+ characters = [token];
501
+ }
502
+ prevCharCode = charCode;
503
+ prevChar = char;
504
+ }
505
+ prevFormat = format;
506
+ prevFontString = fontString;
507
+ startIndex++;
508
+ if (startIndex > format?.endIndex) {
509
+ format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
510
+ fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
511
+ }
512
+ }
513
+ return tokens;
514
+ }
515
+ getOrGenerateComponent(charIndex, char) {
516
+ if (!this.customContentService.isSpecialMarker(char)) {
517
+ return null;
518
+ }
519
+ const existingComponent = this.customContentService.getComponent(this.customComponents, char, charIndex);
520
+ if (existingComponent) {
521
+ if (existingComponent.instance instanceof NoderTableComponent) {
522
+ existingComponent.instance.updateCells();
523
+ }
524
+ return existingComponent;
525
+ }
526
+ return this.customContentService.generateComponent(this.model, this.customComponents, this.sessionId, this.generalProperties, this.contentWidth, charIndex);
527
+ }
528
+ processCharSizes(prevChar, prevFontString, characters) {
529
+ const newSize = FontMetrics.measureCharSize(prevChar, prevFontString);
530
+ for (let item of characters) {
531
+ Object.assign(item, newSize);
532
+ }
533
+ }
534
+ getLineTokens(model, line, startIndex) {
535
+ const lineInfo = this.getLineInfoFromTextLine(startIndex + line.length);
536
+ if (!line.length) {
537
+ return this.getEmptyLineTokens(model, startIndex, lineInfo);
538
+ }
539
+ const tokens = [];
540
+ let characters = [];
541
+ let format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
542
+ let prevFormat = null;
543
+ let prevCharCode = null;
544
+ let prevFontString = null;
545
+ let prevChar = null;
546
+ let fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
547
+ let symbolChange = false;
548
+ for (let i = 0; i < line.length; i++) {
549
+ const char = line[i];
550
+ const size = FontMetrics.measureCharSize(char, fontString);
551
+ const customComponent = this.customContentService.getComponent(this.customComponents, char, startIndex);
552
+ const breakType = BreakHelper.getBreakType(model, char, startIndex);
553
+ if (customComponent && !breakType) {
554
+ const token = this.customContentService.getTokenFromComponent(customComponent, lineInfo, DisplayValue.customContent, i === 0, size);
555
+ tokens.push(token);
556
+ prevCharCode = -1;
557
+ prevChar = '';
558
+ characters = [];
559
+ }
560
+ else {
561
+ const charCode = char.charCodeAt(0);
562
+ const displayValue = DisplayTokenHelper.getDisplayValue(charCode);
563
+ const isFirstCharacter = i === 0;
564
+ const token = new DisplayToken({
565
+ ...size,
566
+ displayValue,
567
+ align: lineInfo.align,
568
+ indentFirstLine: isFirstCharacter ? lineInfo.indent.firstLine : DEFAULT_PARAGRAPH_STYLE.indentFirstLine,
569
+ indentHanging: isFirstCharacter ? lineInfo.indent.hanging : DEFAULT_PARAGRAPH_STYLE.indentHanging,
570
+ indentLeft: lineInfo.indent.left,
571
+ indentRight: lineInfo.indent.right,
572
+ indentBefore: lineInfo.offsetBefore,
573
+ indentAfter: lineInfo.offsetAfter,
574
+ lineSpacing: lineInfo.lineSpacing,
575
+ isPageBreak: breakType === BreakTypes.Page,
576
+ isLineBreak: breakType === BreakTypes.TextWrapping,
577
+ isTab: false
578
+ });
579
+ tokens.push(token);
580
+ if (charCode !== prevCharCode ||
581
+ !prevFormat ||
582
+ !ContentStyleHelper.areSameTextStyles(format?.textStyle, prevFormat?.textStyle)) {
583
+ symbolChange = true;
584
+ }
585
+ else if (i === line.length - 1) {
586
+ characters.push(token);
587
+ symbolChange = true;
588
+ }
589
+ else {
590
+ characters.push(token);
591
+ }
592
+ if (characters.length > 1 && symbolChange) {
593
+ this.processCharSizes(prevChar, prevFontString, characters);
594
+ characters = [token];
595
+ symbolChange = false;
596
+ }
597
+ else if (symbolChange) {
598
+ characters = [token];
599
+ }
600
+ prevCharCode = charCode;
601
+ prevChar = char;
602
+ }
603
+ prevFormat = format;
604
+ prevFontString = fontString;
605
+ startIndex++;
606
+ if (startIndex > format?.endIndex) {
607
+ format = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
608
+ fontString = ContentStyleHelper.getFontStylesString(format?.textStyle);
609
+ }
610
+ }
611
+ return tokens;
612
+ }
613
+ getEmptyDisplayTokens(model, startIndex) {
614
+ const lineInfo = this.getLineInfoByBreakModifier(model, startIndex);
615
+ return this.getEmptyLineTokens(model, startIndex, lineInfo);
616
+ }
617
+ getEmptyLineTokens(model, startIndex, lineInfo) {
618
+ const storedFormat = FormatStyleHelper.getFormatAtIndex(model.formats, startIndex);
619
+ if (!storedFormat) {
620
+ return [];
621
+ }
622
+ const size = FontMetrics.measureCharSize('EMPTY_LINE', ContentStyleHelper.getFontStylesString(storedFormat.textStyle));
623
+ size.width = 3;
624
+ return [
625
+ new DisplayToken({
626
+ ...size,
627
+ displayValue: DisplayValue.emptyLine,
628
+ align: lineInfo.align,
629
+ indentFirstLine: lineInfo.indent.firstLine,
630
+ indentHanging: lineInfo.indent.hanging,
631
+ indentLeft: lineInfo.indent.left,
632
+ indentRight: lineInfo.indent.right,
633
+ indentBefore: lineInfo.offsetBefore,
634
+ indentAfter: lineInfo.offsetAfter,
635
+ isPageBreak: false,
636
+ isLineBreak: false,
637
+ isTab: false,
638
+ lineSpacing: lineInfo.lineSpacing
639
+ })
640
+ ];
641
+ }
642
+ getLineInfoByBreakModifier(model, index) {
643
+ const paragraph = ParagraphStyleHelper.getParagraphAtIndex(model.paragraphs, index);
644
+ if (!paragraph) {
645
+ return new LineInfoModel({
646
+ align: DEFAULT_PARAGRAPH_STYLE.alignment,
647
+ indent: new IndentModel(DEFAULT_PARAGRAPH_STYLE.indentFirstLine, DEFAULT_PARAGRAPH_STYLE.indentHanging, DEFAULT_PARAGRAPH_STYLE.indentLeft, DEFAULT_PARAGRAPH_STYLE.indentRight),
648
+ offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
649
+ offsetAfter: DEFAULT_PARAGRAPH_STYLE.spaceAfter,
650
+ lineSpacing: DEFAULT_PARAGRAPH_STYLE.lineSpacing
651
+ });
652
+ }
653
+ const indentLeft = this.getParagraphIndentLeft(model, paragraph);
654
+ return this.getLineInfoModel(paragraph, indentLeft);
655
+ }
656
+ getParagraphIndentLeft(model, paragraph) {
657
+ const numberingId = paragraph.paragraphStyle.numberingId;
658
+ if (numberingId === null) {
659
+ return paragraph.paragraphStyle.indentLeft;
660
+ }
661
+ const level = paragraph.paragraphStyle.numberingLevel;
662
+ const paragraphIndex = model.paragraphs.indexOf(paragraph);
663
+ const levelModel = NumberingHelper.find(this.generalProperties.numberings, numberingId, level);
664
+ const paragraphFormat = FormatStyleHelper.getFormatAtIndex(model.formats, paragraph.insertIndex);
665
+ const markerTextStyle = ContentStyleHelper.combineTextStyles(levelModel.markerStyle, paragraphFormat.textStyle);
666
+ const paragraphSettings = this.getParagraphSettings(paragraphIndex);
667
+ let markerWidth = paragraphSettings?.numberingData?.width;
668
+ const marker = NumberingHelper.getMarker(levelModel, numberingId, model.paragraphs, paragraphIndex, this.generalProperties.numberingInfo);
669
+ const markerSizes = NumberingHelper.getMarkerSizes(marker, markerTextStyle);
670
+ markerWidth = markerSizes.width;
671
+ const hangingIndent = paragraph.paragraphStyle.indentHanging ? paragraph.paragraphStyle.indentHanging : levelModel.indentHanging;
672
+ let paragraphIndent = levelModel.indentLeft;
673
+ if (markerWidth >= hangingIndent) {
674
+ const markerOverflow = markerWidth - hangingIndent;
675
+ const additionalMarkerIndent = TabHelper.calculateTabWidth(levelModel.indentLeft + markerOverflow, this.generalProperties.defaultTabWidth);
676
+ paragraphIndent += markerOverflow + additionalMarkerIndent;
677
+ }
678
+ return paragraphIndent;
679
+ }
680
+ getLineInfoFromTextLine(index) {
681
+ const paragraph = ParagraphStyleHelper.getParagraphAtIndex(this.model.paragraphs, index);
682
+ const indentLeft = this.getIndentLeftFromTextLine(index);
683
+ return this.getLineInfoModel(paragraph, indentLeft);
684
+ }
685
+ getLineInfoModel(paragraph, indentLeft) {
686
+ const indentHanging = paragraph.paragraphStyle.numberingId === null ? paragraph.paragraphStyle.indentHanging : 0;
687
+ return new LineInfoModel({
688
+ align: paragraph.paragraphStyle.alignment ?? DEFAULT_PARAGRAPH_STYLE.alignment,
689
+ indent: new IndentModel(paragraph.paragraphStyle.indentFirstLine ?? DEFAULT_PARAGRAPH_STYLE.indentFirstLine, indentHanging ?? DEFAULT_PARAGRAPH_STYLE.indentHanging, indentLeft ?? DEFAULT_PARAGRAPH_STYLE.indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight),
690
+ offsetBefore: DEFAULT_PARAGRAPH_STYLE.spaceBefore,
691
+ offsetAfter: DEFAULT_PARAGRAPH_STYLE.spaceAfter,
692
+ lineSpacing: paragraph.paragraphStyle.lineSpacing ?? DEFAULT_PARAGRAPH_STYLE.lineSpacing
693
+ });
694
+ }
695
+ getIndentLeftFromTextLine(insertIndex) {
696
+ let startIndex = 0;
697
+ let endIndex = this.paragraphs.length - 1;
698
+ while (startIndex <= endIndex) {
699
+ const middleIndex = Math.round((startIndex + endIndex) / 2);
700
+ const paragraphInfo = this.paragraphs[middleIndex];
701
+ if (paragraphInfo.startIndex > insertIndex) {
702
+ startIndex = middleIndex + 1;
703
+ }
704
+ else {
705
+ endIndex = middleIndex - 1;
706
+ }
707
+ }
708
+ const textLinesInfo = this.paragraphs[startIndex]?.paragraphSettings.textLinesInfo;
709
+ return textLinesInfo ? Math.max(...textLinesInfo.map(x => x.indentLeft)) : null;
710
+ }
711
+ computeWrapSplit(tokens, wrapLimit) {
712
+ if (!tokens.length || tokens.length <= wrapLimit) {
713
+ return null;
714
+ }
715
+ // If there is a space or tab at this split position, then making
716
+ // a split is simple.
717
+ if (wrapLimit === 0 ||
718
+ tokens[wrapLimit].displayValue === DisplayValue.customContent ||
719
+ (this.isWhiteSpace(tokens[wrapLimit - 1]) && this.isWhiteSpace(tokens[wrapLimit]))) {
720
+ return wrapLimit;
721
+ }
722
+ return this.calculateSplit(wrapLimit, tokens);
723
+ }
724
+ calculateSplit(index, tokens) {
725
+ for (let i = index; i >= 0; i--) {
726
+ if (this.isWhiteSpace(tokens[i]) || tokens[i].displayValue === DisplayValue.customContent) {
727
+ return i + 1;
728
+ }
729
+ }
730
+ return index;
731
+ }
732
+ isWhiteSpace(token) {
733
+ return [DisplayValue.space, DisplayValue.emptyLine].includes(token.displayValue);
734
+ }
735
+ /**
736
+ * Computes wrap index based on max row width
737
+ */
738
+ computeWrapIndex(displayTokens, contentWidth, defaultTabWidth) {
739
+ if (!displayTokens[0]) {
740
+ return 0;
741
+ }
742
+ if (displayTokens[0].isTable || (displayTokens[0].breaksLine && displayTokens.length === 1)) {
743
+ return 1;
744
+ }
745
+ const indent = displayTokens[0].indentLeft +
746
+ displayTokens[0].indentRight +
747
+ displayTokens[0].indentFirstLine -
748
+ displayTokens[0].indentHanging || 0;
749
+ const maxRowWidth = contentWidth - indent;
750
+ let sum = 0;
751
+ for (let i = 0; i < displayTokens.length; i++) {
752
+ if (displayTokens[i].isTab) {
753
+ displayTokens[i].width = TabHelper.calculateTabWidth(sum, defaultTabWidth);
754
+ }
755
+ sum += displayTokens[i].width;
756
+ if ((i > 0 && (sum >= maxRowWidth || displayTokens[i - 1].breaksLine)) || displayTokens[i].isTable) {
757
+ return i;
758
+ }
759
+ if (displayTokens[i].isLineBreak || (i === displayTokens.length - 1 && displayTokens[i].isPageBreak)) {
760
+ return i + 1;
761
+ }
762
+ }
763
+ return 0;
764
+ }
765
+ getPreviousParagraphInfo(row) {
766
+ if (!row || !this.paragraphs.length) {
767
+ return { lastPage: 1, paragraphHeight: 0, paragraphLastLine: -1 };
768
+ }
769
+ const prevParagraph = this.paragraphs[row - 1].paragraphSettings;
770
+ return prevParagraph.getParagraphData();
771
+ }
772
+ getVisiblePages(offsetTop, containerHeight) {
773
+ const visiblePages = [];
774
+ let firstVisiblePage = offsetTop / (this.pageHeight + this.pagesSpace);
775
+ if (firstVisiblePage % 1 === 0) {
776
+ firstVisiblePage++;
777
+ }
778
+ let visiblePagesCount = containerHeight / (this.pageHeight + this.pagesSpace);
779
+ const partialPageOnScreenPercent = Math.trunc(((visiblePagesCount % 1) + (firstVisiblePage % 1)) * 100);
780
+ const pageSpaceHeightPercent = Math.trunc((this.pagesSpace / containerHeight) * 100);
781
+ if (partialPageOnScreenPercent - pageSpaceHeightPercent > 100) {
782
+ visiblePagesCount++;
783
+ }
784
+ visiblePagesCount = Math.ceil(visiblePagesCount);
785
+ firstVisiblePage = Math.ceil(firstVisiblePage);
786
+ const documentPagesCount = this.paragraphs[this.paragraphs.length - 1].paragraphSettings.lastPageNumber;
787
+ if (firstVisiblePage + visiblePagesCount - 1 > documentPagesCount) {
788
+ visiblePagesCount = documentPagesCount - firstVisiblePage + 1;
789
+ }
790
+ for (let i = 0; i < visiblePagesCount; i++) {
791
+ visiblePages.push(firstVisiblePage + i);
792
+ }
793
+ return visiblePages;
794
+ }
795
+ insertTextAndReturnEndCursorPosition(text, position) {
796
+ const left = this.paragraphs[position.row].content.slice(0, position.column);
797
+ const right = this.paragraphs[position.row].content.slice(position.column);
798
+ const insertParagraphs = this.splitByParagraphs(`${left}${text}${right}`).map(x => new ParagraphInfoModel({ content: x, nextLineIndexes: [] }));
799
+ insertParagraphs[0].paragraphSettings = this.getParagraphSettings(position.row);
800
+ this.paragraphs.splice(position.row, 1, ...insertParagraphs);
801
+ return new CursorParagraph(position.row + insertParagraphs.length - 1, insertParagraphs[insertParagraphs.length - 1].content.length - right.length);
802
+ }
803
+ splitByParagraphs(text) {
804
+ return text.split(/\r\n|\r|\n/);
805
+ }
806
+ setParagraphIndexes() {
807
+ for (let paragraph of this.paragraphs) {
808
+ paragraph.paragraphSettings.startInsertIndex = paragraph.startIndex;
809
+ }
810
+ }
811
+ initPagesVerticalData() {
812
+ if (!this.customComponents.edges ||
813
+ (!this.customComponents.edges.headersComponents.length && !this.customComponents.edges.footersComponents.length)) {
814
+ this.pagesVerticalData = [
815
+ new PageVerticalDataModel({
816
+ marginTop: this.pageMargin.top,
817
+ marginBottom: this.pageMargin.bottom,
818
+ contentHeight: this.pageHeight - this.pageMargin.top - this.pageMargin.bottom,
819
+ pageType: PageType.Default
820
+ })
821
+ ];
822
+ return;
823
+ }
824
+ const pageTypes = this.customComponents.edges.getUniquePageTypes();
825
+ this.pagesVerticalData = pageTypes.map(pageType => {
826
+ const headerHeight = this.customComponents.edges.getComponentHeightByPageType(pageType, EdgeType.Header);
827
+ const footerHeight = this.customComponents.edges.getComponentHeightByPageType(pageType, EdgeType.Footer);
828
+ const marginTop = Math.max(headerHeight, this.pageMargin.top);
829
+ const marginBottom = Math.max(footerHeight, this.pageMargin.bottom);
830
+ return new PageVerticalDataModel({
831
+ marginTop,
832
+ marginBottom,
833
+ contentHeight: this.pageHeight - marginTop - marginBottom,
834
+ pageType
835
+ });
836
+ });
837
+ }
838
+ }
839
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzcGxheS1kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW5vZGVyL3NyYy9saWIvZWRpdG9yL2NvbnRlbnQvZGlzcGxheS1kYXRhL2Rpc3BsYXktZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDcEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBRXZFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUVyRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsdUJBQXVCLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDeEcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFFakUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUU3RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUdoRixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWxELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBRXhGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQ0FBMEMsQ0FB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QkFBcUIsQ0FBQztnQkFDN0IsU0FBUztnQkFDVCxZQUFZO2dCQUNaLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsR0FBRyxZQUFZO2dCQUN6RCxRQUFRO2FBQ1gsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQmFzZU5vZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9zaGFyZWQvYWJzdHJhY3QvYmFzZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQnJlYWtIZWxwZXIgfSBmcm9tICcuLi8uLi9nYWRnZXRzL3BhZ2UtYnJlYWsvYnJlYWsuaGVscGVyJztcbmltcG9ydCB7IEJyZWFrVHlwZXMgfSBmcm9tICcuLi8uLi9nYWRnZXRzL3BhZ2UtYnJlYWsvYnJlYWstdHlwZXMuZW51bSc7XG5pbXBvcnQgeyBDb250ZW50c0ludGVyZmFjZSB9IGZyb20gJy4uL2NvbnRlbnRzLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDb250ZW50U3R5bGVIZWxwZXIgfSBmcm9tICcuLi9oZWxwZXJzL2NvbnRlbnQtc3R5bGUuaGVscGVyJztcbmltcG9ydCB7IEN1cnNvclBhcmFncmFwaCB9IGZyb20gJy4uLy4uL3Bvc2l0aW9uaW5nL2N1cnNvci1wYXJhZ3JhcGgnO1xuaW1wb3J0IHsgQ3VzdG9tQ29udGVudFNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3NoYXJlZC9zZXJ2aWNlcy9jdXN0b20tY29udGVudC5zZXJ2aWNlJztcbmltcG9ydCB7IERFRkFVTFRfRk9OVF9TSVpFLCBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRSwgTkVXX0xJTkVfTUFSS1VQIH0gZnJvbSAnLi4vY29uc3RhbnRzL2VkaXRvci5jb25zdCc7XG5pbXBvcnQgeyBEaXNwbGF5VG9rZW4gfSBmcm9tICcuL2Rpc3BsYXktdG9rZW4ubW9kZWwnO1xuaW1wb3J0IHsgRGlzcGxheVRva2VuSGVscGVyIH0gZnJvbSAnLi4vaGVscGVycy9kaXNwbGF5LXRva2VuLmhlbHBlcic7XG5pbXBvcnQgeyBEaXNwbGF5VmFsdWUgfSBmcm9tICcuLi9jb25zdGFudHMvZGlzcGxheS12YWx1ZXMuY29uc3QnO1xuaW1wb3J0IHsgRWRnZVR5cGUgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL2VkZ2VzL2VkZ2UtdHlwZS5lbnVtJztcbmltcG9ydCB7IEVkaXRvclNlcnZpY2UgfSBmcm9tICcuLi8uLi9pbnRlcmFjdGlvbi9lZGl0b3Iuc2VydmljZSc7XG5pbXBvcnQgeyBFdmVudEVtaXR0aW5nIH0gZnJvbSAnLi4vLi4vY29yZS9ldmVudC1lbWl0dGluZyc7XG5pbXBvcnQgeyBGb250TWV0cmljcyB9IGZyb20gJy4uLy4uL2dhZGdldHMvZm9udC1tZXRyaWNzL2ZvbnQtbWV0cmljcy5oZWxwZXInO1xuaW1wb3J0IHsgRm9ybWF0TW9kZWwgfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvZ2VuZXJhdGVkL2Zvcm1hdC5tb2RlbCc7XG5pbXBvcnQgeyBGb3JtYXRTdHlsZUhlbHBlciB9IGZyb20gJy4uLy4uL2V4ZWN1dGlvbi9oZWxwZXJzL2Zvcm1hdC1zdHlsZS5oZWxwZXInO1xuaW1wb3J0IHsgR2VuZXJhbFByb3BlcnRpZXNNb2RlbCB9IGZyb20gJy4vZ2VuZXJhbC1wcm9wZXJ0aWVzLm1vZGVsJztcbmltcG9ydCB7IElDdXN0b21Db21wb25lbnRzIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9zaGFyZWQvY3VzdG9tLWNvbXBvbmVudHMuaW50ZXJmYWNlJztcbmltcG9ydCB7IEluZGVudE1vZGVsIH0gZnJvbSAnLi9pbmRlbnQubW9kZWwnO1xuaW1wb3J0IHsgTGluZUluZm9Nb2RlbCB9IGZyb20gJy4vbGluZS1pbmZvLm1vZGVsJztcbmltcG9ydCB7IE1hcmdpbk1vZGVsIH0gZnJvbSAnLi4vbWFyZ2luLm1vZGVsJztcbmltcG9ydCB7IE5vZGVyVGFibGVDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3RhYmxlL2NvbXBvbmVudHMvdGFibGUuY29tcG9uZW50JztcbmltcG9ydCB7IE51bWJlcmluZ0RhdGFNb2RlbCB9IGZyb20gJy4vLi4vLi4vZ2FkZ2V0cy9udW1iZXJpbmcvbnVtYmVyaW5nLWRhdGEubW9kZWwnO1xuaW1wb3J0IHsgTnVtYmVyaW5nSGVscGVyIH0gZnJvbSAnLi4vLi4vZ2FkZ2V0cy9udW1iZXJpbmcvbnVtYmVyaW5nLmhlbHBlcic7XG5pbXBvcnQgeyBQYWdlSGVscGVyIH0gZnJvbSAnLi4vLi4vZXhlY3V0aW9uL2hlbHBlcnMvcGFnZS5oZWxwZXInO1xuaW1wb3J0IHsgUGFnZVR5cGUgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL2VkZ2VzL3BhZ2UtdHlwZS5lbnVtJztcbmltcG9ydCB7IFBhZ2VWZXJ0aWNhbERhdGFNb2RlbCB9IGZyb20gJy4uL3BhZ2UtdmVydGljYWwtZGF0YS5tb2RlbCc7XG5pbXBvcnQgeyBQYXJhZ3JhcGggfSBmcm9tICcuL3BhcmFncmFwaCc7XG5pbXBvcnQgeyBQYXJhZ3JhcGhIZWxwZXIgfSBmcm9tICcuLi8uLi9leGVjdXRpb24vaGVscGVycy9wYXJhZ3JhcGguaGVscGVyJztcbmltcG9ydCB7IFBhcmFncmFwaEluZm9Nb2RlbCB9IGZyb20gJy4vbW9kZWxzL3BhcmFncmFwaC1pbmZvLm1vZGVsJztcbmltcG9ydCB7IFBhcmFncmFwaE1vZGVsIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2dlbmVyYXRlZC9wYXJhZ3JhcGgubW9kZWwnO1xuaW1wb3J0IHsgUGFyYWdyYXBoU3R5bGVIZWxwZXIgfSBmcm9tICcuLi8uLi9leGVjdXRpb24vaGVscGVycy9wYXJhZ3JhcGgtc3R5bGUuaGVscGVyJztcbmltcG9ydCB7IFJhbmdlIH0gZnJvbSAnLi4vLi4vcG9zaXRpb25pbmcvcmFuZ2UnO1xuaW1wb3J0IHsgVGFiSGVscGVyIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy90YWIvdGFiLmhlbHBlcic7XG5pbXBvcnQgeyBWaXNpYmxlUmFuZ2UgfSBmcm9tICcuLi8uLi9kaXNwbGF5L3Zpc2libGUtcmFuZ2UuaW50ZXJmYWNlJztcblxuZXhwb3J0IGNsYXNzIERpc3BsYXlEYXRhIGV4dGVuZHMgRXZlbnRFbWl0dGluZyB7XG4gICAgcGFyYWdyYXBoczogUGFyYWdyYXBoSW5mb01vZGVsW10gPSBbXTtcblxuICAgIGNvbnRlbnRXaWR0aDogbnVtYmVyO1xuXG4gICAgYWxsUGFnZXNIZWlnaHQgPSAwO1xuXG4gICAgbWluSGVpZ2h0ID0gMDtcblxuICAgIHRhYlRva2VuczogRGlzcGxheVRva2VuW10gPSBbXTtcblxuICAgIHBhZ2VzVmVydGljYWxEYXRhOiBQYWdlVmVydGljYWxEYXRhTW9kZWxbXTtcblxuICAgIGdldCBkZWZhdWx0VmVydGljYWxEYXRhKCk6IFBhZ2VWZXJ0aWNhbERhdGFNb2RlbCB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhZ2VzVmVydGljYWxEYXRhLmZpbmQoeCA9PiB4LnBhZ2VUeXBlID09PSBQYWdlVHlwZS5EZWZhdWx0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NUZXh0TGluZXNQcm9wZXJ0aWVzOiAoXG4gICAgICAgIGN1cnJlbnRQYXJhZ3JhcGg6IFBhcmFncmFwaCxcbiAgICAgICAgcHJldlBhcmFncmFwaEluZm86IHsgbGFzdFBhZ2U6IG51bWJlcjsgcGFyYWdyYXBoSGVpZ2h0OiBudW1iZXI7IHBhcmFncmFwaExhc3RMaW5lOiBudW1iZXIgfSxcbiAgICAgICAgcGFnZXNJbmZvOiB7IHBhZ2VzVmVydGljYWxEYXRhOiBQYWdlVmVydGljYWxEYXRhTW9kZWxbXTsgcGFnZXNTcGFjZTogbnVtYmVyIH0sXG4gICAgICAgIHRhYmxlczogQ29tcG9uZW50UmVmPE5vZGVyVGFibGVDb21wb25lbnQ+W11cbiAgICApID0+IHZvaWQ7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBtb2RlbDogQ29udGVudHNJbnRlcmZhY2UsXG4gICAgICAgIHByaXZhdGUgZ2VuZXJhbFByb3BlcnRpZXM6IEdlbmVyYWxQcm9wZXJ0aWVzTW9kZWwsXG4gICAgICAgIHByaXZhdGUgc2Vzc2lvbklkOiBudW1iZXIsXG4gICAgICAgIHB1YmxpYyBwYWdlTWFyZ2luOiBNYXJnaW5Nb2RlbCxcbiAgICAgICAgcHVibGljIHBhZ2VzU3BhY2U6IG51bWJlcixcbiAgICAgICAgcHVibGljIHBhZ2VXaWR0aDogbnVtYmVyLFxuICAgICAgICBwdWJsaWMgcGFnZUhlaWdodDogbnVtYmVyLFxuICAgICAgICBwdWJsaWMgY3VzdG9tQ29tcG9uZW50czogSUN1c3RvbUNvbXBvbmVudHMsXG4gICAgICAgIHB1YmxpYyBjdXN0b21Db250ZW50U2VydmljZTogQ3VzdG9tQ29udGVudFNlcnZpY2UsXG4gICAgICAgIHB1YmxpYyBlZGl0b3JTZXJ2aWNlOiBFZGl0b3JTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucGFyYWdyYXBocyA9IHRoaXMuc3BsaXRCeVBhcmFncmFwaHModGhpcy5tb2RlbC5jb250ZW50KS5tYXAoeCA9PiBuZXcgUGFyYWdyYXBoSW5mb01vZGVsKHsgY29udGVudDogeCB9KSk7XG4gICAgICAgIHRoaXMubWluSGVpZ2h0ID0gdGhpcy5wYWdlSGVpZ2h0ICsgMiAqIHRoaXMucGFnZXNTcGFjZTtcbiAgICAgICAgdGhpcy5jb250ZW50V2lkdGggPSB0aGlzLnBhZ2VXaWR0aCAtIHRoaXMucGFnZU1hcmdpbi5sZWZ0IC0gdGhpcy5wYWdlTWFyZ2luLnJpZ2h0O1xuICAgICAgICB0aGlzLmluaXRQYWdlc1ZlcnRpY2FsRGF0YSgpO1xuICAgICAgICB0aGlzLnByb2Nlc3NUZXh0TGluZXNQcm9wZXJ0aWVzID0gIXRoaXMucGFnZUhlaWdodFxuICAgICAgICAgICAgPyBQYXJhZ3JhcGhIZWxwZXIucHJvY2Vzc1RleHRMaW5lc1Byb3BlcnRpZXNGb3JTaW5nbGVQYWdlXG4gICAgICAgICAgICA6IFBhcmFncmFwaEhlbHBlci5wcm9jZXNzVGV4dExpbmVzUHJvcGVydGllcztcbiAgICB9XG5cbiAgICBpbnNlcnRUZXh0KHBvc2l0aW9uOiBDdXJzb3JQYXJhZ3JhcGgsIHRleHQ6IHN0cmluZyk6IEN1cnNvclBhcmFncmFwaCB7XG4gICAgICAgIGNvbnN0IGVuZFBvaW50ID0gdGhpcy5pbnNlcnRUZXh0QW5kUmV0dXJuRW5kQ3Vyc29yUG9zaXRpb24odGV4dCwgcG9zaXRpb24pO1xuICAgICAgICByZXR1cm4gZW5kUG9pbnQ7XG4gICAgfVxuXG4gICAgcmVtb3ZlUmFuZ2UocmFuZ2U6IFJhbmdlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHBhcmFncmFwaFRleHQgPVxuICAgICAgICAgICAgdGhpcy5wYXJhZ3JhcGhzW3JhbmdlLnN0YXJ0LnJvd10uY29udGVudC5zbGljZSgwLCByYW5nZS5zdGFydC5jb2x1bW4pICtcbiAgICAgICAgICAgIHRoaXMucGFyYWdyYXBoc1tyYW5nZS5lbmQucm93XS5jb250ZW50LnNsaWNlKHJhbmdlLmVuZC5jb2x1bW4pO1xuICAgICAgICBjb25zdCBwYXJhZ3JhcGhTZXR0aW5ncyA9IHRoaXMuZ2V0UGFyYWdyYXBoU2V0dGluZ3MocmFuZ2Uuc3RhcnQucm93KTtcbiAgICAgICAgdGhpcy5wYXJhZ3JhcGhzLnNwbGljZShyYW5nZS5zdGFydC5yb3csIHJhbmdlLmVuZC5yb3cgLSByYW5nZS5zdGFydC5yb3cgKyAxLCBuZXcgUGFyYWdyYXBoSW5mb01vZGVsKHsgY29udGVudDogcGFyYWdyYXBoVGV4dCB9KSk7XG4gICAgICAgIHRoaXMucGFyYWdyYXBoc1tyYW5nZS5zdGFydC5yb3ddLnBhcmFncmFwaFNldHRpbmdzID0gcGFyYWdyYXBoU2V0dGluZ3M7XG4gICAgfVxuXG4gICAgZ2V0UGFyYWdyYXBoQ29udGVudChpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyYWdyYXBoc1tpbmRleF0/LmNvbnRlbnQgfHwgJyc7XG4gICAgfVxuXG4gICAgZ2V0QWxsUGFyYWdyYXBoc0NvbnRlbnQoKTogc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJhZ3JhcGhzLm1hcCh4ID0+IHguY29udGVudCk7XG4gICAgfVxuXG4gICAgZ2V0UGFyYWdyYXBoU2V0dGluZ3MoaW5kZXg6IG51bWJlcik6IFBhcmFncmFwaCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJhZ3JhcGhzW2luZGV4XT8ucGFyYWdyYXBoU2V0dGluZ3MgfHwgbnVsbDtcbiAgICB9XG5cbiAgICBnZXRQYXJhZ3JhcGhzQ29udGVudEZvclJhbmdlKHJhbmdlOiBSYW5nZSk6IHN0cmluZ1tdIHtcbiAgICAgICAgaWYgKHJhbmdlLmlzU2luZ2xlTGluZSkge1xuICAgICAgICAgICAgY29uc3QgbGluZSA9IHRoaXMuZ2V0UGFyYWdyYXBoQ29udGVudChyYW5nZS5zdGFydC5yb3cpO1xuICAgICAgICAgICAgY29uc3QgbGluZVBhcnRJblJhbmdlID0gbGluZS5zbGljZShyYW5nZS5zdGFydC5jb2x1bW4sIHJhbmdlLmVuZC5jb2x1bW4pO1xuXG4gICAgICAgICAgICByZXR1cm4gW2xpbmVQYXJ0SW5SYW5nZV07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyYWdyYXBoc0NvbnRlbnQgPSB0aGlzLnBhcmFncmFwaHMuc2xpY2UocmFuZ2Uuc3RhcnQucm93LCByYW5nZS5lbmQucm93ICsgMSkubWFwKHggPT4geC5jb250ZW50KTtcbiAgICAgICAgcGFyYWdyYXBoc0NvbnRlbnRbMF0gPSAocGFyYWdyYXBoc0NvbnRlbnRbMF0gfHwgJycpLnNsaWNlKHJhbmdlLnN0YXJ0LmNvbHVtbik7XG4gICAgICAgIGNvbnN0IGxhc3RJbmRleCA9IHBhcmFncmFwaHNDb250ZW50Lmxlbmd0aCAtIDE7XG4gICAgICAgIHBhcmFncmFwaHNDb250ZW50W2xhc3RJbmRleF0gPSBwYXJhZ3JhcGhzQ29udGVudFtsYXN0SW5kZXhdLnNsaWNlKDAsIHJhbmdlLmVuZC5jb2x1bW4pO1xuXG4gICAgICAgIHJldHVybiBwYXJhZ3JhcGhzQ29udGVudDtcbiAgICB9XG5cbiAgICBnZXRUZXh0UmFuZ2UocmFuZ2U6IFJhbmdlKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFyYWdyYXBoc0NvbnRlbnRGb3JSYW5nZShyYW5nZSkuam9pbihORVdfTElORV9NQVJLVVApO1xuICAgIH1cblxuICAgIHBvc2l0aW9uVG9JbmRleChwb3NpdGlvbjogQ3Vyc29yUGFyYWdyYXBoLCBzdGFydFJvdyA9IDApOiBudW1iZXIge1xuICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICBjb25zdCBlbmRSb3cgPSBNYXRoLm1pbihwb3NpdGlvbi5yb3csIHRoaXMucGFyYWdyYXBocy5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gc3RhcnRSb3cgfHwgMDsgaSA8IGVuZFJvdzsgaSsrKSB7XG4gICAgICAgICAgICBpbmRleCArPSB0aGlzLnBhcmFncmFwaHNbaV0uY29udGVudC5sZW5ndGggKyAxO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGluZGV4ICsgcG9zaXRpb24uY29sdW1uO1xuICAgIH1cblxuICAgIGluZGV4VG9Qb3NpdGlvbihwb3NpdGlvbkluZGV4OiBudW1iZXIsIHN0YXJ0Um93OiBudW1iZXIpOiBDdXJzb3JQYXJhZ3JhcGgge1xuICAgICAgICBjb25zdCBuZXdsaW5lTGVuZ3RoID0gTkVXX0xJTkVfTUFSS1VQLmxlbmd0aDtcbiAgICAgICAgZm9yIChsZXQgbGluZUluZGV4ID0gc3RhcnRSb3cgfHwgMDsgbGluZUluZGV4IDwgdGhpcy5wYXJhZ3JhcGhzLmxlbmd0aDsgbGluZUluZGV4KyspIHtcbiAgICAgICAgICAgIHBvc2l0aW9uSW5kZXggLT0gdGhpcy5wYXJhZ3JhcGhzW2xpbmVJbmRleF0uY29udGVudC5sZW5ndGggKyBuZXdsaW5lTGVuZ3RoO1xuICAgICAgICAgICAgaWYgKHBvc2l0aW9uSW5kZXggPCAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sdW1uID0gcG9zaXRpb25JbmRleCArIHRoaXMucGFyYWdyYXBoc1tsaW5lSW5kZXhdLmNvbnRlbnQubGVuZ3RoICsgbmV3bGluZUxlbmd0aDtcblxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ3Vyc29yUGFyYWdyYXBoKGxpbmVJbmRleCwgY29sdW1uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IHBvc2l0aW9uSW5kZXggKyB0aGlzLnBhcmFncmFwaHNbdGhpcy5wYXJhZ3JhcGhzLmxlbmd0aCAtIDFdLmNvbnRlbnQubGVuZ3RoICsgbmV3bGluZUxlbmd0aDtcblxuICAgICAgICByZXR1cm4gbmV3IEN1cnNvclBhcmFncmFwaCh0aGlzLnBhcmFncmFwaHMubGVuZ3RoIC0gMSwgY29sdW1uKTtcbiAgICB9XG5cbiAgICBpbmRleGVzVG9SYW5nZShzdGFydEluZGV4OiBudW1iZXIsIGVuZEluZGV4OiBudW1iZXIpOiBSYW5nZSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0UG9pbnQgPSB0aGlzLmluZGV4VG9Qb3NpdGlvbihzdGFydEluZGV4LCAwKTtcbiAgICAgICAgY29uc3QgZW5kUG9pbnQgPSB0aGlzLmluZGV4VG9Qb3NpdGlvbihlbmRJbmRleCwgMCk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBSYW5nZShzdGFydFBvaW50LCBlbmRQb2ludCk7XG4gICAgfVxuXG4gICAgaXNOZXdMaW5lU3ltYm9sKGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IHRoaXMucGFyYWdyYXBocy5tYXAoeCA9PiB4LmNvbnRlbnQpLmpvaW4oTkVXX0xJTkVfTUFSS1VQKTtcblxuICAgICAgICByZXR1cm4gIXRleHQgfHwgIXRleHRbaW5kZXhdIHx8IHRleHRbaW5kZXhdID09PSBORVdfTElORV9NQVJLVVA7XG4gICAgfVxuXG4gICAgZ2V0U2VsZWN0ZWRQYXJhZ3JhcGhzQnlSYW5nZShyYW5nZTogUmFuZ2UpOiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH0ge1xuICAgICAgICBjb25zdCBuZXdsaW5lTGVuZ3RoID0gTkVXX0xJTkVfTUFSS1VQLmxlbmd0aDtcbiAgICAgICAgbGV0IHN0YXJ0ID0gMDtcbiAgICAgICAgbGV0IGVuZCA9IDA7XG4gICAgICAgIGxldCBpO1xuICAgICAgICBjb25zdCByb3cgPSBNYXRoLm1pbihyYW5nZS5lbmQucm93LCB0aGlzLnBhcmFncmFwaHMubGVuZ3RoIC0gMSk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCByb3c7IGkrKykge1xuICAgICAgICAgICAgaWYgKGkgPCByYW5nZS5zdGFydC5yb3cpIHtcbiAgICAgICAgICAgICAgICBzdGFydCArPSB0aGlzLnBhcmFncmFwaHNbaV0uY29udGVudC5sZW5ndGggKyBuZXdsaW5lTGVuZ3RoO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlbmQgKz0gdGhpcy5wYXJhZ3JhcGhzW2ldLmNvbnRlbnQubGVuZ3RoICsgbmV3bGluZUxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpIDwgdGhpcy5wYXJhZ3JhcGhzLmxlbmd0aCkge1xuICAgICAgICAgICAgZW5kICs9IHRoaXMucGFyYWdyYXBoc1tpXS5jb250ZW50Lmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IHN0YXJ0LCBlbmQgfTtcbiAgICB9XG5cbiAgICBnZXRQb3NpdGlvbkFmdGVyQnJlYWsocG9zaXRpb246IEN1cnNvclBhcmFncmFwaCwgYnJlYWtUeXBlOiBCcmVha1R5cGVzKTogQ3Vyc29yUGFyYWdyYXBoIHtcbiAgICAgICAgaWYgKGJyZWFrVHlwZSA9PT0gQnJlYWtUeXBlcy5UZXh0V3JhcHBpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzTGFzdENvbHVtbiA9IHBvc2l0aW9uLmNvbHVtbiA9PT0gdGhpcy5wYXJhZ3JhcGhzW3Bvc2l0aW9uLnJvd10uY29udGVudC5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGlzTGFzdFBhcmFncmFwaCA9IHBvc2l0aW9uLnJvdyA9PT0gdGhpcy5wYXJhZ3JhcGhzLmxlbmd0aCAtIDE7XG4gICAgICAgIHJldHVybiBpc0xhc3RDb2x1bW4gJiYgIWlzTGFzdFBhcmFncmFwaCA/IG5ldyBDdXJzb3JQYXJhZ3JhcGgocG9zaXRpb24ucm93ICsgMSwgMCkgOiBwb3NpdGlvbjtcbiAgICB9XG5cbiAgICBnZXREaXN0YW5jZUZyb21Ub3AoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmFncmFwaHNbaW5kZXhdPy5wYXJhZ3JhcGhTZXR0aW5ncyA/IHRoaXMucGFyYWdyYXBoc1tpbmRleF0ucGFyYWdyYXBoU2V0dGluZ3MuZGlzdGFuY2VGcm9tVG9wIDogMDtcbiAgICB9XG5cbiAgICBnZXREaXN0YW5jZUZyb21Ub3BGb3JQcmludChpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCF0aGlzLnBhcmFncmFwaHNbaW5kZXhdPy5wYXJhZ3JhcGhTZXR0aW5ncykge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyYWdyYXBoID0gdGhpcy5wYXJhZ3JhcGhzW2luZGV4XS5wYXJhZ3JhcGhTZXR0aW5ncztcbiAgICAgICAgY29uc3QgcGFnZU51bWJlciA9IHBhcmFncmFwaC5wYWdlTnVtYmVyc1swXTtcbiAgICAgICAgbGV0IHBhZ2VCcmVha0hlaWdodCA9IDA7XG4gICAgICAgIHBhcmFncmFwaC50ZXh0TGluZXNJbmZvLmZvckVhY2gobGluZXNJbmZvID0+IHtcbiAgICAgICAgICAgIGlmIChsaW5lc0luZm8uaXNBZnRlclBhZ2VCcmVhaykge1xuICAgICAgICAgICAgICAgIHBhZ2VCcmVha0hlaWdodCA9IGxpbmVzSW5mby5oZWlnaHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGFyYWdyYXBoLmRpc3RhbmNlRnJvbVRvcCAtIHBhZ2VOdW1iZXIgKiB0aGlzLnBhZ2VzU3BhY2UgLSBwYWdlQnJlYWtIZWlnaHQ7XG4gICAgfVxuXG4gICAgc2V0UGFyYWdyYXBoU2V0dGluZ3Mocm93OiBudW1iZXIsIGxpbmVJbmZvczogTGluZUluZm9Nb2RlbFtdLCBudW1iZXJpbmdEYXRhOiBOdW1iZXJpbmdEYXRhTW9kZWwpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnBhcmFncmFwaHNbcm93XS5wYXJhZ3JhcGhTZXR0aW5ncykge1xuICAgICAgICAgICAgdGhpcy5wYXJhZ3JhcGhzW3Jvd10ucGFyYWdyYXBoU2V0dGluZ3MgPSBuZXcgUGFyYWdyYXBoKFxuICAgICAgICAgICAgICAgIG51bWJlcmluZ0RhdGEsXG4gICAgICAgICAgICAgICAgbGluZUluZm9zWzBdLm9mZnNldEJlZm9yZSxcbiAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NUZXh0TGluZXNQcm9wZXJ0aWVzXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wYXJhZ3JhcGhzW3Jvd10ucGFyYWdyYXBoU2V0dGluZ3MubnVtYmVyaW5nRGF0YSA9IG51bWJlcmluZ0RhdGE7XG4gICAgICAgIHRoaXMucGFyYWdyYXBoc1tyb3ddLnBhcmFncmFwaFNldHRpbmdzLndpZHRoID0gdGhpcy5jb250ZW50V2lkdGg7XG4gICAgICAgIHRoaXMucGFyYWdyYXBoc1tyb3ddLnBhcmFncmFwaFNldHRpbmdzLnNldFRleHRMaW5lc0luZm8obGluZUluZm9zKTtcbiAgICB9XG5cbiAgICBnZXRQYXJhZ3JhcGhIZWlnaHQoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmFncmFwaHNbaW5kZXhdPy5wYXJhZ3JhcGhTZXR0aW5ncyA/IHRoaXMucGFyYWdyYXBoc1tpbmRleF0ucGFyYWdyYXBoU2V0dGluZ3MuaGVpZ2h0IDogMDtcbiAgICB9XG5cbiAgICBnZXRWaXNpYmxlUmFuZ2Uob2Zmc2V0VG9wOiBudW1iZXIsIHNjcm9sbGVySGVpZ2h0OiBudW1iZXIpOiBWaXNpYmxlUmFuZ2Uge1xuICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnBhcmFncmFwaHMuZmluZEluZGV4KHggPT4gb2Zmc2V0VG9wIDw9IHgucGFyYWdyYXBoU2V0dGluZ3M/LmRpc3RhbmNlRnJvbVRvcCArIHgucGFyYWdyYXBoU2V0dGluZ3M/LmhlaWdodCk7XG4gICAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzdGFydExpbmVJbmZvID0gbnVsbDtcbiAgICAgICAgY29uc3Qgc3RhcnRQYXJhZ3JhcGggPSB0aGlzLnBhcmFncmFwaHNbc3RhcnRdO1xuICAgICAgICBpZiAoc3RhcnRQYXJhZ3JhcGgpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0UGFyYWdyYXBoT2Zmc2V0VG9wID0gb2Zmc2V0VG9wIC0gc3RhcnRQYXJhZ3JhcGgucGFyYWdyYXBoU2V0dGluZ3MuZGlzdGFuY2VGcm9tVG9wO1xuICAgICAgICAgICAgc3RhcnRMaW5lSW5mbyA9IFBhcmFncmFwaEhlbHBlci5nZXRWaXNpYmxlTGluZUluZm8oc3RhcnRQYXJhZ3JhcGg/LnBhcmFncmFwaFNldHRpbmdzLnRleHRMaW5lc0luZm8sIHN0YXJ0UGFyYWdyYXBoT2Zmc2V0VG9wLCAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc3RhcnRMaW5lSW5mbykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdGFydFBhcmFncmFwaDogMCxcbiAgICAgICAgICAgICAgICBzdGFydExpbmU6IDAsXG4gICAgICAgICAgICAgICAgc3RhcnRTY3JlZW5MaW5lOiAwLFxuICAgICAgICAgICAgICAgIHN0YXJ0U2NyZWVuRnVsbExpbmU6IDAsXG4gICAgICAgICAgICAgICAgZW5kUGFyYWdyYXBoOiAwLFxuICAgICAgICAgICAgICAgIGVuZExpbmU6IDAsXG4gICAgICAgICAgICAgICAgZW5kU2NyZWVuTGluZTogMCxcbiAgICAgICAgICAgICAgICBlbmRTY3JlZW5GdWxsTGluZTogMCxcbiAgICAgICAgICAgICAgICBwYWdlczogWzFdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGVuZCA9IHRoaXMucGFyYWdyYXBocy5maW5kSW5kZXgoXG4gICAgICAgICAgICB4ID0+IG9mZnNldFRvcCArIHNjcm9sbGVySGVpZ2h0IDw9IHgucGFyYWdyYXBoU2V0dGluZ3MuZGlzdGFuY2VGcm9tVG9wICsgeC5wYXJhZ3JhcGhTZXR0aW5ncy5oZWlnaHRcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGVuZCA8IDApIHtcbiAgICAgICAgICAgIGVuZCA9IHRoaXMucGFyYWdyYXBocy5sZW5ndGggLSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGVuZExpbmVJbmZvID0gbnVsbDtcbiAgICAgICAgY29uc3QgZW5kUGFyYWdyYXBoID0gdGhpcy5wYXJhZ3JhcGhzW2VuZF07XG4gICAgICAgIGlmIChlbmRQYXJhZ3JhcGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGVuZFBhcmFncmFwaE9mZnNldFRvcCA9IG9mZnNldFRvcCArIHNjcm9sbGVySGVpZ2h0IC0gZW5kUGFyYWdyYXBoLnBhcmFncmFwaFNldHRpbmdzLmRpc3RhbmNlRnJvbVRvcDtcbiAgICAgICAgICAgIGVuZExpbmVJbmZvID0gUGFyYWdyYXBoSGVscGVyLmdldFZpc2libGVMaW5lSW5mbyhlbmRQYXJhZ3JhcGgucGFyYWdyYXBoU2V0dGluZ3M/LnRleHRMaW5lc0luZm8sIGVuZFBhcmFncmFwaE9mZnNldFRvcCwgLTEpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmlzaWJsZVBhZ2VzID0gdGhpcy5nZXRWaXNpYmxlUGFnZXMob2Zmc2V0VG9wLCBzY3JvbGxlckhlaWdodCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0UGFyYWdyYXBoOiBzdGFydCxcbiAgICAgICAgICAgIHN0YXJ0TGluZTogc3RhcnRMaW5lSW5mby5pbmRleCxcbiAgICAgICAgICAgIHN0YXJ0U2NyZWVuTGluZTogc3RhcnRMaW5lSW5mby5zY3JlZW5JbmRleCxcbiAgICAgICAgICAgIHN0YXJ0U2NyZWVuRnVsbExpbmU6IHN0YXJ0TGluZUluZm8udmlzaWJsZVNjcmVlbkluZGV4LFxuICAgICAgICAgICAgZW5kUGFyYWdyYXBoOiBlbmQsXG4gICAgICAgICAgICBlbmRMaW5lOiBlbmRMaW5lSW5mby5pbmRleCxcbiAgICAgICAgICAgIGVuZFNjcmVlbkxpbmU6IGVuZExpbmVJbmZvLnNjcmVlbkluZGV4LFxuICAgICAgICAgICAgZW5kU2NyZWVuRnVsbExpbmU6IGVuZExpbmVJbmZvLnZpc2libGVTY3JlZW5JbmRleCxcbiAgICAgICAgICAgIHBhZ2VzOiB2aXNpYmxlUGFnZXNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm9jZXNzUGFyYWdyYXBoc1Byb3BlcnRpZXMoc3RhcnRQYXJhZ3JhcGhJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0UGFyYWdyYXBoSW5kZXhlcygpO1xuICAgICAgICBjb25zdCBwYWdlc0luZm8gPSB7IHBhZ2VzVmVydGljYWxEYXRhOiB0aGlzLnBhZ2VzVmVydGljYWxEYXRhLCBwYWdlc1NwYWNlOiB0aGlzLnBhZ2VzU3BhY2UgfTtcbiAgICAgICAgbGV0IGN1cnJlbnRQYWdlID0gc3RhcnRQYXJhZ3JhcGhJbmRleCA9PT0gMCA/IDEgOiB0aGlzLnBhcmFncmFwaHNbc3RhcnRQYXJhZ3JhcGhJbmRleCAtIDFdLnBhcmFncmFwaFNldHRpbmdzLmxhc3RQYWdlTnVtYmVyO1xuICAgICAgICBsZXQgcGFnZVZlcnRpY2FsRGF0YSA9IFBhZ2VIZWxwZXIuZ2V0VmVydGljYWxEYXRhKGN1cnJlbnRQYWdlLCB0aGlzLnBhZ2VzVmVydGljYWxEYXRhKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0UGFyYWdyYXBoSW5kZXg7IGkgPCB0aGlzLnBhcmFncmFwaHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZQYXJhZ3JhcGhJbmZvID0gdGhpcy5nZXRQcmV2aW91c1BhcmFncmFwaEluZm8oaSk7XG4gICAgICAgICAgICBjb25zdCBwYXJhZ3JhcGhTZXR0aW5ncyA9IHRoaXMucGFyYWdyYXBoc1tpXS5wYXJhZ3JhcGhTZXR0aW5ncztcbiAgICAgICAgICAgIHBhcmFncmFwaFNldHRpbmdzLnByb2Nlc3NQYXJhZ3JhcGhQcm9wZXJ0aWVzKHByZXZQYXJhZ3JhcGhJbmZvLCBwYWdlc0luZm8sIHRoaXMuY3VzdG9tQ29tcG9uZW50cy50YWJsZXMpO1xuICAgICAgICAgICAgaWYgKHBhcmFncmFwaFNldHRpbmdzLmZpcnN0UGFnZU51bWJlciAhPT0gY3VycmVudFBhZ2UpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UGFnZSA9IHBhcmFncmFwaFNldHRpbmdzLmZpcnN0UGFnZU51bWJlcjtcbiAgICAgICAgICAgICAgICBwYWdlVmVydGljYWxEYXRhID0gUGFnZUhlbHBlci5nZXRWZXJ0aWNhbERhdGEocGFyYWdyYXBoU2V0dGluZ3MuZmlyc3RQYWdlTnVtYmVyLCB0aGlzLnBhZ2VzVmVydGljYWxEYXRhKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcGFyYWdyYXBoU2V0dGluZ3MuY2FsY3VsYXRlRGlzdGFuY2VGcm9tVG9wKHRoaXMucGFnZUhlaWdodCwgdGhpcy5wYWdlc1NwYWNlLCBwYWdlVmVydGljYWxEYXRhLm1hcmdpblRvcCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcGFnZUhlaWdodCA9IHRoaXMucGFnZUhlaWdodDtcbiAgICAgICAgaWYgKCFwYWdlSGVpZ2h0KSB7XG4gICAgICAgICAgICBwYWdlSGVpZ2h0ID0gdGhpcy5nZXRBbGxQYXJhZ3JhcGhzSGVpZ2h0KCkgKyB0aGlzLnBhZ2VNYXJnaW4udG9wICsgdGhpcy5wYWdlTWFyZ2luLmJvdHRvbTtcbiAgICAgICAgICAgIHRoaXMubWluSGVpZ2h0ID0gcGFnZUhlaWdodCArIDIgKiB0aGlzLnBhZ2VzU3BhY2U7XG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRWZXJ0aWNhbERhdGEuY29udGVudEhlaWdodCA9IHBhZ2VIZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsYXN0UGFnZU51bWJlciA9IHRoaXMucGFyYWdyYXBoc1t0aGlzLnBhcmFncmFwaHMubGVuZ3RoIC0gMV0ucGFyYWdyYXBoU2V0dGluZ3MubGFzdFBhZ2VOdW1iZXI7XG4gICAgICAgIHRoaXMuYWxsUGFnZXNIZWlnaHQgPSBsYXN0UGFnZU51bWJlciAqIChwYWdlSGVpZ2h0ICsgdGhpcy5wYWdlc1NwYWNlKSArIHRoaXMucGFnZXNTcGFjZTtcbiAgICAgICAgdGhpcy5lbWl0KCdwYWdlc0NvdW50Q2hhbmdlZCcsIHsgcGFnZXNDb3VudDogbGFzdFBhZ2VOdW1iZXIsIHBhZ2VIZWlnaHQ6IHBhZ2VIZWlnaHQgKyAyICogdGhpcy5wYWdlc1NwYWNlIH0pO1xuICAgIH1cblxuICAgIGdldEFsbFBhcmFncmFwaHNIZWlnaHQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyYWdyYXBocy5yZWR1Y2UoKHN1bSwgeCkgPT4gc3VtICsgeC5wYXJhZ3JhcGhTZXR0aW5ncy5oZWlnaHQsIDApO1xuICAgIH1cblxuICAgIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdwYWdlc0NvdW50Q2hhbmdlZCcpO1xuICAgIH1cblxuICAgIHVwZGF0ZVBhZ2VWZXJ0aWNhbERhdGEoZWRnZVR5cGU6IEVkZ2VUeXBlLCBwYWdlOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcGFnZVZlcnRpY2FsRGF0YSA9IFBhZ2VIZWxwZXIuZ2V0VmVydGljYWxEYXRhKHBhZ2UsIHRoaXMucGFnZXNWZXJ0aWNhbERhdGEpO1xuICAgICAgICBjb25zdCBjb21wb25lbnRIZWlnaHQgPSB0aGlzLmN1c3RvbUNvbXBvbmVudHMuZWRnZXMuZ2V0Q29tcG9uZW50SGVpZ2h0KHBhZ2UsIGVkZ2VUeXBlKTtcbiAgICAgICAgaWYgKGVkZ2VUeXBlID09PSBFZGdlVHlwZS5IZWFkZXIpIHtcbiAgICAgICAgICAgIHBhZ2VWZXJ0aWNhbERhdGEubWFyZ2luVG9wID0gY29tcG9uZW50SGVpZ2h0ID4gdGhpcy5wYWdlTWFyZ2luLnRvcCA/IGNvbXBvbmVudEhlaWdodCA6IHRoaXMucGFnZU1hcmdpbi50b3A7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYWdlVmVydGljYWxEYXRhLm1hcmdpbkJvdHRvbSA9IGNvbXBvbmVudEhlaWdodCA+IHRoaXMucGFnZU1hcmdpbi5ib3R0b20gPyBjb21wb25lbnRIZWlnaHQgOiB0aGlzLnBhZ2VNYXJnaW4uYm90dG9tO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3Q29udGVudEhlaWdodCA9IHRoaXMucGFnZUhlaWdodCAtIHBhZ2VWZXJ0aWNhbERhdGEubWFyZ2luVG9wIC0gcGFnZVZlcnRpY2FsRGF0YS5tYXJnaW5Cb3R0b207XG4gICAgICAgIGlmIChuZXdDb250ZW50SGVpZ2h0ID09PSBwYWdlVmVydGljYWxEYXRhLmNvbnRlbnRIZWlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhZ2VWZXJ0aWNhbERhdGEuY29udGVudEhlaWdodCA9IG5ld0NvbnRlbnRIZWlnaHQ7XG4gICAgICAgIHRoaXMucHJvY2Vzc1BhcmFncmFwaHNQcm9wZXJ0aWVzKDApO1xuICAgIH1cblxuICAgIHVwZGF0ZVBhcmFncmFwaExpbmVOdW1iZXIoZmlyc3Q6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMucGFyYWdyYXBocy5sZW5ndGg7XG4gICAgICAgIGlmIChmaXJzdCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5wYXJhZ3JhcGhzW2ZpcnN0XS5saW5lTnVtYmVyID0gMDtcbiAgICAgICAgICAgIGZpcnN0Kys7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gZmlyc3Q7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLnBhcmFncmFwaHNbaV0ubGluZU51bWJlciA9IHRoaXMucGFyYWdyYXBoc1tpIC0gMV0ubGluZU51bWJlciArIHRoaXMucGFyYWdyYXBoc1tpIC0gMV0ubmV4dExpbmVJbmRleGVzLmxlbmd0aCArIDE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVQYXJhZ3JhcGhTdGFydEluZGV4KGZpcnN0OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgaWYgKGZpcnN0ID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLnBhcmFncmFwaHNbZmlyc3RdLnN0YXJ0SW5kZXggPSAwO1xuICAgICAgICAgICAgZmlyc3QrKztcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gZmlyc3Q7IGkgPCB0aGlzLnBhcmFncmFwaHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMucGFyYWdyYXBoc1tpXS5zdGFydEluZGV4ID0gdGhpcy5wYXJhZ3JhcGhzW2kgLSAxXS5zdGFydEluZGV4ICsgdGhpcy5nZXRQYXJhZ3JhcGhDb250ZW50KGkgLSAxKS5sZW5ndGggKyAxO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlUGFyYWdyYXBoU2V0dGluZ3NOdW1iZXJpbmdEYXRhKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcGFyYWdyYXBoU2V0dGluZ3MgPSB0aGlzLmdldFBhcmFncmFwaFNldHRpbmdzKGluZGV4KTtcbiAgICAgICAgaWYgKHBhcmFncmFwaFNldHRpbmdzLm51bWJlcmluZ0RhdGEubnVtYmVyaW5nSWQgIT09IHRoaXMubW9kZWwucGFyYWdyYXBoc1tpbmRleF0ucGFyYWdyYXBoU3R5bGUubnVtYmVyaW5nSWQpIHtcbiAgICAgICAgICAgIHBhcmFncmFwaFNldHRpbmdzLm51bWJlcmluZ0RhdGEgPSBOdW1iZXJpbmdIZWxwZXIuY3JlYXRlRGF0YU1vZGVsKFxuICAgICAgICAgICAgICAgIHRoaXMuZ2VuZXJhbFByb3BlcnRpZXMubnVtYmVyaW5ncyxcbiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLnBhcmFncmFwaHMsXG4gICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsUHJvcGVydGllcy5udW1iZXJpbmdJbmZvXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcmFncmFwaFNldHRpbmdzLm51bWJlcmluZ0RhdGEubnVtYmVyaW5nSWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFncmFwaEZvcm1hdCA9IEZvcm1hdFN0eWxlSGVscGVyLmdldEZvcm1hdEF0SW5kZXgodGhpcy5tb2RlbC5mb3JtYXRzLCB0aGlzLm1vZGVsLnBhcmFncmFwaHNbaW5kZXhdLmluc2VydEluZGV4KTtcbiAgICAgICAgICAgIE51bWJlcmluZ0hlbHBlci51cGRhdGVNYXJrZXJEYXRhKFxuICAgICAgICAgICAgICAgIHRoaXMuZ2VuZXJhbFByb3BlcnRpZXMsXG4gICAgICAgICAgICAgICAgcGFyYWdyYXBoU2V0dGluZ3MsXG4gICAgICAgICAgICAgICAgcGFyYWdyYXBoRm9ybWF0LnRleHRTdHlsZSxcbiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLnBhcmFncmFwaHNbaW5kZXhdLnBhcmFncmFwaFN0eWxlXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlTmV4dExpbmVJbmRleGVzKGZpcnN0UGFyYWdyYXBoOiBudW1iZXIsIGxhc3RQYXJhZ3JhcGg6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnVwZGF0ZVBhcmFncmFwaFN0YXJ0SW5kZXgoZmlyc3RQYXJhZ3JhcGgpO1xuICAgICAgICBsZXQgaW5kZXhPZlBhcmFncmFwaEFmdGVyUGFnZUJyZWFrID0gdGhpcy5nZXRQYXJhZ3JhcGhTZXR0aW5ncyhmaXJzdFBhcmFncmFwaCAtIDEpPy5pc0VuZGVkQnlQYWdlQnJlYWsgPyBmaXJzdFBhcmFncmFwaCA6IC0xO1xuICAgICAgICBsZXQgZmlyc3RVc2VkVGFiSW5kZXggPSB0aGlzLm1vZGVsLnRhYnMuZmluZEluZGV4KHggPT4geC5pbnNlcnRJbmRleCA+PSB0aGlzLnBhcmFncmFwaHNbZmlyc3RQYXJhZ3JhcGhdLnN0YXJ0SW5kZXgpO1xuICAgICAgICBmb3IgKGxldCBpID0gZmlyc3RQYXJhZ3JhcGg7IGkgPD0gbGFzdFBhcmFncmFwaDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucGFyYWdyYXBoc1tpXSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnRhYlRva2VucyA9IFtdO1xuICAgICAgICAgICAgTnVtYmVyaW5nSGVscGVyLmNhbGN1bGF0ZU51bWJlcmluZ0luZm8oXG4gICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5wYXJhZ3JhcGhzW2ldLnBhcmFncmFwaFN0eWxlLm51bWJlcmluZ0lkLFxuICAgICAgICAgICAgICAgIHRoaXMubW9kZWwucGFyYWdyYXBoc1tpXS5wYXJhZ3JhcGhTdHlsZS5udW1iZXJpbmdMZXZlbCxcbiAgICAgICAgICAgICAgICB0aGlzLmdldFBhcmFncmFwaFNldHRpbmdzKGkpPy5udW1iZXJpbmdEYXRhLm1hcmtlcixcbiAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYWxQcm9wZXJ0aWVzLm51bWJlcmluZ0luZm8sXG4gICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsUHJvcGVydGllcy5udW1iZXJpbmdzXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgbnVtYmVyaW5nRGF0YSA9IE51bWJlcmluZ0hlbHBlci5jcmVhdGVEYXRhTW9kZWwoXG4gICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsUHJvcGVydGllcy5udW1iZXJpbmdzLFxuICAgICAgICAgICAgICAgIHRoaXMubW9kZWwucGFyYWdyYXBocyxcbiAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgIHRoaXMuZ2VuZXJhbFByb3BlcnRpZXMubnVtYmVyaW5nSW5mb1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHsgc3BsaXRzLCByb3dJbmZvcyB9ID0gdGhpcy5nZXRTcGxpdHModGhpcy5tb2RlbCwgaSk7XG4gICAgICAgICAgICB0aGlzLnBhcmFncmFwaHNbaV0ubmV4dExpbmVJbmRleGVzID0gc3BsaXRzO1xuICAgICAgICAgICAgaWYgKGluZGV4T2ZQYXJhZ3JhcGhBZnRlclBhZ2VCcmVhayA9PT0gaSkge1xuICAgICAgICAgICAgICAgIHJvd0luZm9zWzBdLmlzQWZ0ZXJQYWdlQnJlYWsgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kZXhPZlBhcmFncmFwaEFmdGVyUGFnZUJyZWFrID0gcm93SW5mb3Nbcm93SW5mb3MubGVuZ3RoIC0gMV0uaXNFbmRlZEJ5UGFnZUJyZWFrID8gaSArIDEgOiAtMTtcbiAgICAgICAgICAgIHRoaXMuc2V0UGFyYWdyYXBoU2V0dGluZ3MoaSwgcm93SW5mb3MsIG51bWJlcmluZ0RhdGEpO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVQYXJhZ3JhcGhTZXR0aW5nc051bWJlcmluZ0RhdGEoaSk7XG4gICAgICAgICAgICBmaXJzdFVzZWRUYWJJbmRleCA9IHRoaXMudXBkYXRlUGFyYWdyYXBoVGFicyhmaXJzdFVzZWRUYWJJbmRleCwgaSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmdldFBhcmFncmFwaFNldHRpbmdzKGxhc3RQYXJhZ3JhcGggKyAxKT8uc2V0SXNBZnRlclBhZ2VCcmVhayhpbmRleE9mUGFyYWdyYXBoQWZ0ZXJQYWdlQnJlYWsgPiAtMSk7XG4gICAgICAgIHRoaXMudXBkYXRlUGFyYWdyYXBoTGluZU51bWJlcihmaXJzdFBhcmFncmFwaCk7XG4gICAgICAgIHRoaXMucHJvY2Vzc1BhcmFncmFwaHNQcm9wZXJ0aWVzKGZpcnN0UGFyYWdyYXBoKTtcbiAgICB9XG5cbiAgICB1cGRhdGVOdW1iZXJpbmdzRGF0YU9uQ2hhbmdlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpIDwgdGhpcy5wYXJhZ3JhcGhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhZ3JhcGhTdHlsZSA9IHRoaXMubW9kZWwucGFyYWdyYXBoc1tpXS5wYXJhZ3JhcGhTdHlsZTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFncmFwaFNldHRpbmdzID0gdGhpcy5nZXRQYXJhZ3JhcGhTZXR0aW5ncyhpKTtcbiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsLnBhcmFncmFwaHNbaV0ucGFyYWdyYXBoU3R5bGUubnVtYmVyaW5nSWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBOdW1iZXJpbmdIZWxwZXIuY2FsY3VsYXRlTnVtYmVyaW5nSW5mbyhcbiAgICAgICAgICAgICAgICAgICAgcGFyYWdyYXBoU3R5bGUubnVtYmVyaW5nSWQsXG4gICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaFN0eWxlLm51bWJlcmluZ0xldmVsLFxuICAgICAgICAgICAgICAgICAgICBwYXJhZ3JhcGhTZXR0aW5ncy5udW1iZXJpbmdEYXRhLm1hcmtlcixcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsUHJvcGVydGllcy5udW1iZXJpbmdJbmZvLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYWxQcm9wZXJ0aWVzLm51bWJlcmluZ3NcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHBhcmFncmFwaFNldHRpbmdzLm51bWJlcmluZ0RhdGEgPSBOdW1iZXJpbmdIZWxwZXIuY3JlYXRlRGF0YU1vZGVsKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYWxQcm9wZXJ0aWVzLm51bWJlcmluZ3MsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9kZWwucGFyYWdyYXBocyxcbiAgICAgICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsUHJvcGVydGllcy5udW1iZXJpbmdJbmZvXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhZ3JhcGhGb3JtYXQgPSBGb3JtYXRTdHlsZUhlbHBlci5nZXRGb3JtYXRBdEluZGV4KHRoaXMubW9kZWwuZm9ybWF0cywgdGhpcy5tb2RlbC5wYXJhZ3JhcGhzW2ldLmluc2VydEluZGV4KTtcbiAgICAgICAgICAgICAgICBOdW1iZXJpbmdIZWxwZXIudXBkYXRlTWFya2VyRGF0YSh0aGlzLmdlbmVyYWxQcm9wZXJ0aWVzLCBwYXJhZ3JhcGhTZXR0aW5ncywgcGFyYWdyYXBoRm9ybWF0LnRleHRTdHlsZSwgcGFyYWdyYXBoU3R5bGUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0YWJsZSA9IHRoaXMuY3VzdG9tQ29udGVudFNlcnZpY2UuZmluZENvbXBvbmVudCh0aGlzLmN1c3RvbUNvbXBvbmVudHMudGFibGVzLCBwYXJhZ3JhcGhTZXR0aW5ncy5zdGFydEluc2VydEluZGV4KTtcbiAgICAgICAgICAgIGlmICh0YWJsZSkge1xuICAgICAgICAgICAgICAgIHRhYmxlLmluc3RhbmNlLnVwZGF0ZUNlbGxzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoJ3BhZ2VUeXBlJyBpbiB0aGlzLm1vZGVsKSB7XG4gICAgICAgICAgICB0aGlzLmVkaXRvclNlcnZpY2UudXBkYXRlRWRnZXModGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRBbGxOdW1iZXJpbmdJbmZvKHBhcmFncmFwaEluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHBhcmFncmFwaEluZGV4OyBpIDwgdGhpcy5tb2RlbC5wYXJhZ3JhcGhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB7IG51bWJlcmluZ0lkLCBudW1iZXJpbmdMZXZlbCB9ID0gdGhpcy5tb2RlbC5wYXJhZ3JhcGhzW2ldLnBhcmFncmFwaFN0eWxlO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIG51bWJlcmluZ0lkICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsUHJvcGVydGllcy5udW1iZXJpbmdJbmZvW251bWJlcmluZ0lkXSAmJlxuICAgICAgICAgICAgICAgIHRoaXMuZ2VuZXJhbFByb3BlcnRpZXMubnVtYmVyaW5nSW5mb1tudW1iZXJpbmdJZF1bbnVtYmVyaW5nTGV2ZWxdXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYWxQcm9wZXJ0aWVzLm51bWJlcmluZ0luZm9bbnVtYmVyaW5nSWRdW251bWJlcmluZ0xldmVsXS52aXNpdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXNldE51bWJlcmluZ0luZm9CeVRhYmxlQ2VsbCh0YWJsZTogQ29tcG9uZW50UmVmPE5vZGVyVGFibGVDb21wb25lbnQ+KTogdm9pZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFibGUuaW5zdGFuY2Uucm93TWF0cml4Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBjZWxsIG9mIHRhYmxlLmluc3RhbmNlLnJvd01hdHJpeFtpXS5jZWxscykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgbWFya2VyLCBudW1iZXJpbmdJZCB9ID1cbiAgICAgICAgICAgICAgICAgICAgY2VsbC5jb21wb25lbnRSZWYuaW5zdGFuY2Uuc2Vzc2lvbi5kaXNwbGF5RGF0YS5wYXJhZ3JhcGhzWzBdLnBhcmFncmFwaFNldHRpbmdzLm51bWJlcmluZ0RhdGE7XG4gICAgICAgICAgICAgICAgaWYgKG1hcmtlciAmJiBudW1iZXJpbmdJZCkge1xuICAgICAgICAgICAgICAgICAgICBOdW1iZXJpbmdIZWxwZXIudXBkYXRlTnVtYmVyaW5nSW5mbyh0aGlzLmdlbmVyYWxQcm9wZXJ0aWVzLm51bWJlcmluZ0luZm8sIG1hcmtlciwgbnVtYmVyaW5nSWQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0QWxsTnVtYmVyaW5nSW5mbygwKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlUGFyYWdyYXBoVGFicyh0YWJJbmRleDogbnVtYmVyLCBwYXJhZ3JhcGhJbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgcGFyYWdyYXBoQ29udGVudExlbmd0aCA9IHRoaXMuZ2V0UGFyYWdyYXBoQ29udGVudChwYXJhZ3JhcGhJbmRleCkubGVuZ3RoO1xuICAgICAgICBjb25zdCBwYXJhZ3JhcGhMYXN0SW5kZXggPSB0aGlzLnBhcmFncmFwaHNbcGFyYWdyYXBoSW5kZXhdLnN0YXJ0SW5kZXggKyBwYXJhZ3JhcGhDb250ZW50TGVuZ3RoO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0YWJJbmRleCA9PT0gLTEgfHxcbiAgICAgICAgICAgIHRhYkluZGV4ID49IHRoaXMuY3VzdG9tQ29tcG9uZW50cy50YWJzLmxlbmd0aCB8fFxuICAgICAgICAgICAgdGhpcy5jdXN0b21Db21wb25lbnRzLnRhYnNbdGFiSW5kZXhdLmluc3RhbmNlLmluc2VydEluZGV4ID4gcGFyYWdyYXBoTGFzdEluZGV4XG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIHRhYkluZGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3RhcnRJbmRleCA9IHRhYkluZGV4O1xuICAgICAgICB3aGlsZSAodGhpcy5jdXN0b21Db21wb25lbnRzLnRhYnNbdGFiSW5kZXhdICYmIHRoaXMuY3VzdG9tQ29tcG9uZW50cy50YWJzW3RhYkluZGV4XS5pbnN0YW5jZS5pbnNlcnRJbmRleCA8PSBwYXJhZ3JhcGhMYXN0SW5kZXgpIHtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tQ29tcG9uZW50cy50YWJzW3RhYkluZGV4XS5pbnN0YW5jZS53aWR0aCA9IHRoaXMudGFiVG9rZW5zW3RhYkluZGV4IC0gc3RhcnRJbmRleF0ud2lkdGg7XG4gICAgICAgICAgICB0aGlzLmN1c3RvbUNvbXBvbmVudHMudGFic1t0YWJJbmRleF0uaW5zdGFuY2UuaGVpZ2h0ID0gdGhpcy50YWJUb2tlbnNbdGFiSW5kZXggLSBzdGFydEluZGV4XS5mb250O1xuICAgICAgICAgICAgdGFiSW5kZXgrKztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0YWJJbmRleDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNwbGl0cyhtb2RlbDogQ29udGVudHNJbnRlcmZhY2UsIHBhcmFncmFwaEluZGV4OiBudW1iZXIpOiB7IHNwbGl0czogbnVtYmVyW107IHJvd0luZm9zOiBMaW5lSW5mb01vZGVsW10gfSB7XG4gICAgICAgIGNvbnN0IHBhcmFncmFwaENvbnRlbnQgPSB0aGlzLmdldFBhcmFncmFwaENvbnRlbnQocGFyYWdyYXBoSW5kZXgpO1xuICAgICAgICBjb25zdCBzdHJUb2tlbnMgPSB0aGlzLmdldERpc3BsYXlUb2tlbnMobW9kZWwsIHBhcmFncmFwaENvbnRlbnQsIHRoaXMucGFyYWdyYXBoc1twYXJhZ3JhcGhJbmRleF0uc3RhcnRJbmRleCk7XG4gICAgICAgIGlmICghc3RyVG9rZW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgZGVmYXVsdFJvd0luZm8gPSBuZXcgTGluZUluZm9Nb2RlbCh7XG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAoREVGQVVMVF9GT05UX1NJWkUgKiA0KSAvIDMsXG4gICAgICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICAgICAgYWxpZ246IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLmFsaWdubWVudCxcbiAgICAgICAgICAgICAgICBpbmRlbnQ6IG5ldyBJbmRlbnRNb2RlbChcbiAgICAgICAgICAgICAgICAgICAgREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUuaW5kZW50Rmlyc3RMaW5lLFxuICAgICAgICAgICAgICAgICAgICBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRIYW5naW5nLFxuICAgICAgICAgICAgICAgICAgICBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRMZWZ0LFxuICAgICAgICAgICAgICAgICAgICBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRSaWdodFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgb2Zmc2V0QWZ0ZXI6IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLnNwYWNlQWZ0ZXIsXG4gICAgICAgICAgICAgICAgb2Zmc2V0QmVmb3JlOiBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5zcGFjZUJlZm9yZSxcbiAgICAgICAgICAgICAgICBsaW5lU3BhY2luZzogREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUubGluZVNwYWNpbmcsXG4gICAgICAgICAgICAgICAgaXNBZnRlclBhZ2VCcmVhazogZmFsc2UsXG4gICAgICAgICAgICAgICAgaXNFbmRlZEJ5UGFnZUJyZWFrOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLmJhY2tncm91bmRDb2xvclxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiB7IHNwbGl0czogW10sIHJvd0luZm9zOiBbZGVmYXVsdFJvd0luZm9dIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzcGxpdHM6IG51bWJlcltdID0gW107XG4gICAgICAgIGNvbnN0IHJvd0luZm9zOiBMaW5lSW5mb01vZGVsW10gPSBbXTtcblxuICAgICAgICBsZXQgcHJldlRva2VuOiBEaXNwbGF5VG9rZW47XG4gICAgICAgIGxldCBpbmRleCA9IC0xO1xuICAgICAgICBsZXQgaW5pdGlhbCA9IHBhcmFncmFwaENvbnRlbnQ7XG4gICAgICAgIHdoaWxlIChpbmRleCkge1xuICAgICAgICAgICAgaW5pdGlhbCA9IGluaXRpYWwuc2xpY2UoaW5kZXggPiAwID8gaW5kZXggOiAwKTtcbiAgICAgICAgICAgIGNvbnN0IHRva2VucyA9IHN0clRva2Vucy5zbGljZShwYXJhZ3JhcGhDb250ZW50Lmxlbmd0aCAtIGluaXRpYWwubGVuZ3RoKTtcbiAgICAgICAgICAgIGlmICghdG9rZW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRva2Vucy5wdXNoKC4uLnRoaXMuZ2V0RW1wdHlEaXNwbGF5VG9rZW5zKG1vZGVsLCB0aGlzLnBhcmFncmFwaHNbcGFyYWdyYXBoSW5kZXhdLnN0YXJ0SW5kZXggKyBpbmRleCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgd3JhcExpbWl0ID0gdGhpcy5jb21wdXRlV3JhcEluZGV4KHRva2VucywgdGhpcy5jb250ZW50V2lkdGgsIHRoaXMuZ2VuZXJhbFByb3BlcnRpZXMuZGVmYXVsdFRhYldpZHRoKTtcbiAgICAgICAgICAgIGlmICh0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdLmlzUGFnZUJyZWFrICYmIHdyYXBMaW1pdCA9PT0gdG9rZW5zLmxlbmd0aCAmJiB0aGlzLnBhcmFncmFwaHMubGVuZ3RoID4gcGFyYWdyYXBoSW5kZXggKyAxKSB7XG4gICAgICAgICAgICAgICAgd3JhcExpbWl0ID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHdyYXBTcGxpdCA9XG4gICAgICAgICAgICAgICAgdG9rZW5zW3dyYXBMaW1pdCAtIDFdPy5icmVha3NMaW5lIHx8IHRva2Vuc1t3cmFwTGltaXQgLSAxXT8uaXNUYWJsZSA/IHdyYXBMaW1pdCA6IHRoaXMuY29tcHV0ZVdyYXBTcGxpdCh0b2tlbnMsIHdyYXBMaW1pdCk7XG4gICAgICAgICAgICBjb25zdCB3cmFwVG9rZW5zID0gdG9rZW5zLnNsaWNlKDAsIHdyYXBTcGxpdCB8fCB1bmRlZmluZWQpO1xuXG4gICAgICAgICAgICBpZiAod3JhcFRva2Vucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBwcmV2VG9rZW4gPSB3cmFwVG9rZW5zW3dyYXBUb2tlbnMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlzQWZ0ZXJQYWdlQnJlYWsgPSAhcm93SW5mb3MubGVuZ3RoID8gZmFsc2UgOiByb3dJbmZvc1tyb3dJbmZvcy5sZW5ndGggLSAxXS5pc0VuZGVkQnlQYWdlQnJlYWs7XG4gICAgICAgICAgICBjb25zdCBsaW5lSW5mbyA9IERpc3BsYXlUb2tlbkhlbHBlci5nZXRMaW5lSW5mb0Zyb21Ub2tlbihwcmV2VG9rZW4sIHdyYXBUb2tlbnNbMF0sIHdyYXBUb2tlbnMsIGlzQWZ0ZXJQYWdlQnJlYWspO1xuICAgICAgICAgICAgbGluZUluZm8uYmFja2dyb3VuZENvbG9yID0gbW9kZWwucGFyYWdyYXBoc1twYXJhZ3JhcGhJbmRleF0ucGFyYWdyYXBoU3R5bGUuYmFja2dyb3VuZENvbG9yO1xuICAgICAgICAgICAgcm93SW5mb3MucHVzaChsaW5lSW5mbyk7XG5cbiAgICAgICAgICAgIGlmICghd3JhcExpbWl0KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGluZGV4ID0gd3JhcFNwbGl0O1xuICAgICAgICAgICAgY29uc3Qgc3BsaXRzTGVuZ3RoID0gc3BsaXRzLmxlbmd0aDtcbiAgICAgICAgICAgIGNvbnN0IHNwbGl0SW5kZXggPSBzcGxpdHNMZW5ndGggPyBpbmRleCArIHNwbGl0c1tzcGxpdHNMZW5ndGggLSAxXSA6IGluZGV4O1xuICAgICAgICAgICAgc3BsaXRzLnB1c2goc3BsaXRJbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRhYlRva2Vucy5wdXNoKC4uLnN0clRva2Vucy5maWx0ZXIoeCA9PiB4LmlzVGFiKSk7XG5cbiAgICAgICAgUGFyYWdyYXBoSGVscGVyLmFwcGx5UGFyYWdyYXBoSW5kZW50c1RvTGluZXMocm93SW5mb3MsIHBhcmFncmFwaEluZGV4LCBtb2RlbC5wYXJhZ3JhcGhzKTtcbiAgICAgICAgcmV0dXJuIHsgc3BsaXRzLCByb3dJbmZvcyB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdpdmVuIGEgc3RyaW5nLCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZSBkaXNwbGF5IGNoYXJhY3RlcnMsIGluY2x1ZGluZyB0YWJzIGFuZCBzcGFjZXMgYW5kIGN1c3RvbSBjb21wb25lbnRzLlxuICAgICAqL1xuICAgIGdldERpc3BsYXlUb2tlbnMobW9kZWw6IENvbnRlbnRzSW50ZXJmYWNlLCBzdHI6IHN0cmluZywgc3RhcnRJbmRleDogbnVtYmVyKTogRGlzcGxheVRva2VuW10ge1xuICAgICAgICBpZiAoIXN0ci5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVtcHR5RGlzcGxheVRva2Vucyhtb2RlbCwgc3RhcnRJbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5maWxsTGluZVRva2VucyhzdGFydEluZGV4LCBzdHIsIG1vZGVsKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZpbGxMaW5lVG9rZW5zKHN0YXJ0SW5kZXg6IG51bWJlciwgbGluZTogc3RyaW5nLCBtb2RlbDogQ29udGVudHNJbnRlcmZhY2UpOiBEaXNwbGF5VG9rZW5bXSB7XG4gICAgICAgIGNvbnN0IGxpbmVJbmZvID0gdGhpcy5nZXRMaW5lSW5mb0J5QnJlYWtNb2RpZmllcihtb2RlbCwgc3RhcnRJbmRleCArIGxpbmUubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgdG9rZW5zOiBEaXNwbGF5VG9rZW5bXSA9IFtdO1xuICAgICAgICBsZXQgY2hhcmFjdGVyczogRGlzcGxheVRva2VuW10gPSBbXTtcbiAgICAgICAgbGV0IGZvcm1hdCA9IEZvcm1hdFN0eWxlSGVscGVyLmdldEZvcm1hdEF0SW5kZXgobW9kZWwuZm9ybWF0cywgc3RhcnRJbmRleCk7XG4gICAgICAgIGxldCBwcmV2Rm9ybWF0OiBGb3JtYXRNb2RlbCA9IG51bGw7XG4gICAgICAgIGxldCBwcmV2Q2hhckNvZGU6IG51bWJlciA9IG51bGw7XG4gICAgICAgIGxldCBwcmV2Rm9udFN0cmluZzogc3RyaW5nID0gbnVsbDtcbiAgICAgICAgbGV0IHByZXZDaGFyOiBzdHJpbmcgPSBudWxsO1xuICAgICAgICBsZXQgZm9udFN0cmluZyA9IENvbnRlbnRTdHlsZUhlbHBlci5nZXRGb250U3R5bGVzU3RyaW5nKGZvcm1hdD8udGV4dFN0eWxlKTtcbiAgICAgICAgbGV0IHN5bWJvbENoYW5nZSA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGNoYXIgPSBsaW5lW2ldO1xuICAgICAgICAgICAgY29uc3Qgc2l6ZSA9IEZvbnRNZXRyaWNzLm1lYXN1cmVDaGFyU2l6ZShjaGFyLCBmb250U3RyaW5nKTtcbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbUNvbXBvbmVudCA9IHRoaXMuZ2V0T3JHZW5lcmF0ZUNvbXBvbmVudChzdGFydEluZGV4LCBjaGFyKTtcbiAgICAgICAgICAgIGNvbnN0IGJyZWFrVHlwZSA9IEJyZWFrSGVscGVyLmdldEJyZWFrVHlwZShtb2RlbCwgY2hhciwgc3RhcnRJbmRleCk7XG5cbiAgICAgICAgICAgIGlmIChjdXN0b21Db21wb25lbnQgJiYgIWJyZWFrVHlwZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuID0gdGhpcy5jdXN0b21Db250ZW50U2VydmljZS5nZXRUb2tlbkZyb21Db21wb25lbnQoXG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUNvbXBvbmVudCxcbiAgICAgICAgICAgICAgICAgICAgbGluZUluZm8sXG4gICAgICAgICAgICAgICAgICAgIERpc3BsYXlWYWx1ZS5jdXN0b21Db250ZW50LFxuICAgICAgICAgICAgICAgICAgICBpID09PSAwLFxuICAgICAgICAgICAgICAgICAgICBzaXplXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG5cbiAgICAgICAgICAgICAgICBwcmV2Q2hhckNvZGUgPSAtMTtcbiAgICAgICAgICAgICAgICBwcmV2Q2hhciA9ICcnO1xuICAgICAgICAgICAgICAgIGNoYXJhY3RlcnMgPSBbXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhckNvZGUgPSBjaGFyLmNoYXJDb2RlQXQoMCk7XG4gICAgICAgICAgICAgICAgY29uc3QgZGlzcGxheVZhbHVlID0gRGlzcGxheVRva2VuSGVscGVyLmdldERpc3BsYXlWYWx1ZShjaGFyQ29kZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgaXNGaXJzdENoYXJhY3RlciA9IGkgPT09IDA7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9rZW4gPSBuZXcgRGlzcGxheVRva2VuKHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheVZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBhbGlnbjogbGluZUluZm8uYWxpZ24sXG4gICAgICAgICAgICAgICAgICAgIGluZGVudEZpcnN0TGluZTogaXNGaXJzdENoYXJhY3RlciA/IGxpbmVJbmZvLmluZGVudC5maXJzdExpbmUgOiBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRGaXJzdExpbmUsXG4gICAgICAgICAgICAgICAgICAgIGluZGVudEhhbmdpbmc6IGlzRmlyc3RDaGFyYWN0ZXIgPyBsaW5lSW5mby5pbmRlbnQuaGFuZ2luZyA6IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLmluZGVudEhhbmdpbmcsXG4gICAgICAgICAgICAgICAgICAgIGluZGVudExlZnQ6IGxpbmVJbmZvLmluZGVudC5sZWZ0LFxuICAgICAgICAgICAgICAgICAgICBpbmRlbnRSaWdodDogbGluZUluZm8uaW5kZW50LnJpZ2h0LFxuICAgICAgICAgICAgICAgICAgICBpbmRlbnRCZWZvcmU6IGxpbmVJbmZvLm9mZnNldEJlZm9yZSxcbiAgICAgICAgICAgICAgICAgICAgaW5kZW50QWZ0ZXI6IGxpbmVJbmZvLm9mZnNldEFmdGVyLFxuICAgICAgICAgICAgICAgICAgICBsaW5lU3BhY2luZzogbGluZUluZm8ubGluZVNwYWNpbmcsXG4gICAgICAgICAgICAgICAgICAgIGlzUGFnZUJyZWFrOiBicmVha1R5cGUgPT09IEJyZWFrVHlwZXMuUGFnZSxcbiAgICAgICAgICAgICAgICAgICAgaXNMaW5lQnJlYWs6IGJyZWFrVHlwZSA9PT0gQnJlYWtUeXBlcy5UZXh0V3JhcHBpbmcsXG4gICAgICAgICAgICAgICAgICAgIGlzVGFiOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuXG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSAhPT0gcHJldkNoYXJDb2RlIHx8XG4gICAgICAgICAgICAgICAgICAgICFwcmV2Rm9ybWF0IHx8XG4gICAgICAgICAgICAgICAgICAgICFDb250ZW50U3R5bGVIZWxwZXIuYXJlU2FtZVRleHRTdHlsZXMoZm9ybWF0Py50ZXh0U3R5bGUsIHByZXZGb3JtYXQ/LnRleHRTdHlsZSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgc3ltYm9sQ2hhbmdlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPT09IGxpbmUubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzLnB1c2godG9rZW4pO1xuICAgICAgICAgICAgICAgICAgICBzeW1ib2xDaGFuZ2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGNoYXJhY3RlcnMubGVuZ3RoID4gMSAmJiBzeW1ib2xDaGFuZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ2hhclNpemVzKHByZXZDaGFyLCBwcmV2Rm9udFN0cmluZywgY2hhcmFjdGVycyk7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcnMgPSBbdG9rZW5dO1xuICAgICAgICAgICAgICAgICAgICBzeW1ib2xDaGFuZ2UgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN5bWJvbENoYW5nZSkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzID0gW3Rva2VuXTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwcmV2Q2hhckNvZGUgPSBjaGFyQ29kZTtcbiAgICAgICAgICAgICAgICBwcmV2Q2hhciA9IGNoYXI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHByZXZGb3JtYXQgPSBmb3JtYXQ7XG4gICAgICAgICAgICBwcmV2Rm9udFN0cmluZyA9IGZvbnRTdHJpbmc7XG4gICAgICAgICAgICBzdGFydEluZGV4Kys7XG5cbiAgICAgICAgICAgIGlmIChzdGFydEluZGV4ID4gZm9ybWF0Py5lbmRJbmRleCkge1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9IEZvcm1hdFN0eWxlSGVscGVyLmdldEZvcm1hdEF0SW5kZXgobW9kZWwuZm9ybWF0cywgc3RhcnRJbmRleCk7XG4gICAgICAgICAgICAgICAgZm9udFN0cmluZyA9IENvbnRlbnRTdHlsZUhlbHBlci5nZXRGb250U3R5bGVzU3RyaW5nKGZvcm1hdD8udGV4dFN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0b2tlbnM7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRPckdlbmVyYXRlQ29tcG9uZW50KGNoYXJJbmRleDogbnVtYmVyLCBjaGFyOiBzdHJpbmcpOiBDb21wb25lbnRSZWY8QmFzZU5vZGVyQ29tcG9uZW50PiB8IG51bGwge1xuICAgICAgICBpZiAoIXRoaXMuY3VzdG9tQ29udGVudFNlcnZpY2UuaXNTcGVjaWFsTWFya2VyKGNoYXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGV4aXN0aW5nQ29tcG9uZW50ID0gdGhpcy5jdXN0b21Db250ZW50U2VydmljZS5nZXRDb21wb25lbnQodGhpcy5jdXN0b21Db21wb25lbnRzLCBjaGFyLCBjaGFySW5kZXgpO1xuICAgICAgICBpZiAoZXhpc3RpbmdDb21wb25lbnQpIHtcbiAgICAgICAgICAgIGlmIChleGlzdGluZ0NvbXBvbmVudC5pbnN0YW5jZSBpbnN0YW5jZW9mIE5vZGVyVGFibGVDb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICBleGlzdGluZ0NvbXBvbmVudC5pbnN0YW5jZS51cGRhdGVDZWxscygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGV4aXN0aW5nQ29tcG9uZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuY3VzdG9tQ29udGVudFNlcnZpY2UuZ2VuZXJhdGVDb21wb25lbnQoXG4gICAgICAgICAgICB0aGlzLm1vZGVsLFxuICAgICAgICAgICAgdGhpcy5jdXN0b21Db21wb25lbnRzLFxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uSWQsXG4gICAgICAgICAgICB0aGlzLmdlbmVyYWxQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgdGhpcy5jb250ZW50V2lkdGgsXG4gICAgICAgICAgICBjaGFySW5kZXhcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NDaGFyU2l6ZXMocHJldkNoYXI6IHN0cmluZywgcHJldkZvbnRTdHJpbmc6IHN0cmluZywgY2hhcmFjdGVyczogRGlzcGxheVRva2VuW10pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbmV3U2l6ZSA9IEZvbnRNZXRyaWNzLm1lYXN1cmVDaGFyU2l6ZShwcmV2Q2hhciwgcHJldkZvbnRTdHJpbmcpO1xuICAgICAgICBmb3IgKGxldCBpdGVtIG9mIGNoYXJhY3RlcnMpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oaXRlbSwgbmV3U2l6ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRMaW5lVG9rZW5zKG1vZGVsOiBDb250ZW50c0ludGVyZmFjZSwgbGluZTogc3RyaW5nLCBzdGFydEluZGV4OiBudW1iZXIpOiBEaXNwbGF5VG9rZW5bXSB7XG4gICAgICAgIGNvbnN0IGxpbmVJbmZvID0gdGhpcy5nZXRMaW5lSW5mb0Zyb21UZXh0TGluZShzdGFydEluZGV4ICsgbGluZS5sZW5ndGgpO1xuICAgICAgICBpZiAoIWxpbmUubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbXB0eUxpbmVUb2tlbnMobW9kZWwsIHN0YXJ0SW5kZXgsIGxpbmVJbmZvKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRva2VuczogRGlzcGxheVRva2VuW10gPSBbXTtcbiAgICAgICAgbGV0IGNoYXJhY3RlcnM6IERpc3BsYXlUb2tlbltdID0gW107XG4gICAgICAgIGxldCBmb3JtYXQgPSBGb3JtYXRTdHlsZUhlbHBlci5nZXRGb3JtYXRBdEluZGV4KG1vZGVsLmZvcm1hdHMsIHN0YXJ0SW5kZXgpO1xuICAgICAgICBsZXQgcHJldkZvcm1hdDogRm9ybWF0TW9kZWwgPSBudWxsO1xuICAgICAgICBsZXQgcHJldkNoYXJDb2RlOiBudW1iZXIgPSBudWxsO1xuICAgICAgICBsZXQgcHJldkZvbnRTdHJpbmc6IHN0cmluZyA9IG51bGw7XG4gICAgICAgIGxldCBwcmV2Q2hhcjogc3RyaW5nID0gbnVsbDtcbiAgICAgICAgbGV0IGZvbnRTdHJpbmcgPSBDb250ZW50U3R5bGVIZWxwZXIuZ2V0Rm9udFN0eWxlc1N0cmluZyhmb3JtYXQ/LnRleHRTdHlsZSk7XG4gICAgICAgIGxldCBzeW1ib2xDaGFuZ2UgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBjaGFyID0gbGluZVtpXTtcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSBGb250TWV0cmljcy5tZWFzdXJlQ2hhclNpemUoY2hhciwgZm9udFN0cmluZyk7XG4gICAgICAgICAgICBjb25zdCBjdXN0b21Db21wb25lbnQgPSB0aGlzLmN1c3RvbUNvbnRlbnRTZXJ2aWNlLmdldENvbXBvbmVudCh0aGlzLmN1c3RvbUNvbXBvbmVudHMsIGNoYXIsIHN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgY29uc3QgYnJlYWtUeXBlID0gQnJlYWtIZWxwZXIuZ2V0QnJlYWtUeXBlKG1vZGVsLCBjaGFyLCBzdGFydEluZGV4KTtcblxuICAgICAgICAgICAgaWYgKGN1c3RvbUNvbXBvbmVudCAmJiAhYnJlYWtUeXBlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLmN1c3RvbUNvbnRlbnRTZXJ2aWNlLmdldFRva2VuRnJvbUNvbXBvbmVudChcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tQ29tcG9uZW50LFxuICAgICAgICAgICAgICAgICAgICBsaW5lSW5mbyxcbiAgICAgICAgICAgICAgICAgICAgRGlzcGxheVZhbHVlLmN1c3RvbUNvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgIGkgPT09IDAsXG4gICAgICAgICAgICAgICAgICAgIHNpemVcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcblxuICAgICAgICAgICAgICAgIHByZXZDaGFyQ29kZSA9IC0xO1xuICAgICAgICAgICAgICAgIHByZXZDaGFyID0gJyc7XG4gICAgICAgICAgICAgICAgY2hhcmFjdGVycyA9IFtdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFyQ29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXNwbGF5VmFsdWUgPSBEaXNwbGF5VG9rZW5IZWxwZXIuZ2V0RGlzcGxheVZhbHVlKGNoYXJDb2RlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBpc0ZpcnN0Q2hhcmFjdGVyID0gaSA9PT0gMDtcbiAgICAgICAgICAgICAgICBjb25zdCB0b2tlbiA9IG5ldyBEaXNwbGF5VG9rZW4oe1xuICAgICAgICAgICAgICAgICAgICAuLi5zaXplLFxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5VmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGFsaWduOiBsaW5lSW5mby5hbGlnbixcbiAgICAgICAgICAgICAgICAgICAgaW5kZW50Rmlyc3RMaW5lOiBpc0ZpcnN0Q2hhcmFjdGVyID8gbGluZUluZm8uaW5kZW50LmZpcnN0TGluZSA6IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLmluZGVudEZpcnN0TGluZSxcbiAgICAgICAgICAgICAgICAgICAgaW5kZW50SGFuZ2luZzogaXNGaXJzdENoYXJhY3RlciA/IGxpbmVJbmZvLmluZGVudC5oYW5naW5nIDogREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUuaW5kZW50SGFuZ2luZyxcbiAgICAgICAgICAgICAgICAgICAgaW5kZW50TGVmdDogbGluZUluZm8uaW5kZW50LmxlZnQsXG4gICAgICAgICAgICAgICAgICAgIGluZGVudFJpZ2h0OiBsaW5lSW5mby5pbmRlbnQucmlnaHQsXG4gICAgICAgICAgICAgICAgICAgIGluZGVudEJlZm9yZTogbGluZUluZm8ub2Zmc2V0QmVmb3JlLFxuICAgICAgICAgICAgICAgICAgICBpbmRlbnRBZnRlcjogbGluZUluZm8ub2Zmc2V0QWZ0ZXIsXG4gICAgICAgICAgICAgICAgICAgIGxpbmVTcGFjaW5nOiBsaW5lSW5mby5saW5lU3BhY2luZyxcbiAgICAgICAgICAgICAgICAgICAgaXNQYWdlQnJlYWs6IGJyZWFrVHlwZSA9PT0gQnJlYWtUeXBlcy5QYWdlLFxuICAgICAgICAgICAgICAgICAgICBpc0xpbmVCcmVhazogYnJlYWtUeXBlID09PSBCcmVha1R5cGVzLlRleHRXcmFwcGluZyxcbiAgICAgICAgICAgICAgICAgICAgaXNUYWI6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG5cbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlICE9PSBwcmV2Q2hhckNvZGUgfHxcbiAgICAgICAgICAgICAgICAgICAgIXByZXZGb3JtYXQgfHxcbiAgICAgICAgICAgICAgICAgICAgIUNvbnRlbnRTdHlsZUhlbHBlci5hcmVTYW1lVGV4dFN0eWxlcyhmb3JtYXQ/LnRleHRTdHlsZSwgcHJldkZvcm1hdD8udGV4dFN0eWxlKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBzeW1ib2xDaGFuZ2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA9PT0gbGluZS5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICAgICAgICAgIHN5bWJvbENoYW5nZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVycy5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoY2hhcmFjdGVycy5sZW5ndGggPiAxICYmIHN5bWJvbENoYW5nZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NDaGFyU2l6ZXMocHJldkNoYXIsIHByZXZGb250U3RyaW5nLCBjaGFyYWN0ZXJzKTtcbiAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVycyA9IFt0b2tlbl07XG4gICAgICAgICAgICAgICAgICAgIHN5bWJvbENoYW5nZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltYm9sQ2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcnMgPSBbdG9rZW5dO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHByZXZDaGFyQ29kZSA9IGNoYXJDb2RlO1xuICAgICAgICAgICAgICAgIHByZXZDaGFyID0gY2hhcjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHJldkZvcm1hdCA9IGZvcm1hdDtcbiAgICAgICAgICAgIHByZXZGb250U3RyaW5nID0gZm9udFN0cmluZztcbiAgICAgICAgICAgIHN0YXJ0SW5kZXgrKztcblxuICAgICAgICAgICAgaWYgKHN0YXJ0SW5kZXggPiBmb3JtYXQ/LmVuZEluZGV4KSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gRm9ybWF0U3R5bGVIZWxwZXIuZ2V0Rm9ybWF0QXRJbmRleChtb2RlbC5mb3JtYXRzLCBzdGFydEluZGV4KTtcbiAgICAgICAgICAgICAgICBmb250U3RyaW5nID0gQ29udGVudFN0eWxlSGVscGVyLmdldEZvbnRTdHlsZXNTdHJpbmcoZm9ybWF0Py50ZXh0U3R5bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRva2VucztcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEVtcHR5RGlzcGxheVRva2Vucyhtb2RlbDogQ29udGVudHNJbnRlcmZhY2UsIHN0YXJ0SW5kZXg6IG51bWJlcik6IERpc3BsYXlUb2tlbltdIHtcbiAgICAgICAgY29uc3QgbGluZUluZm8gPSB0aGlzLmdldExpbmVJbmZvQnlCcmVha01vZGlmaWVyKG1vZGVsLCBzdGFydEluZGV4KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RW1wdHlMaW5lVG9rZW5zKG1vZGVsLCBzdGFydEluZGV4LCBsaW5lSW5mbyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRFbXB0eUxpbmVUb2tlbnMobW9kZWw6IENvbnRlbnRzSW50ZXJmYWNlLCBzdGFydEluZGV4OiBudW1iZXIsIGxpbmVJbmZvOiBMaW5lSW5mb01vZGVsKTogRGlzcGxheVRva2VuW10ge1xuICAgICAgICBjb25zdCBzdG9yZWRGb3JtYXQgPSBGb3JtYXRTdHlsZUhlbHBlci5nZXRGb3JtYXRBdEluZGV4KG1vZGVsLmZvcm1hdHMsIHN0YXJ0SW5kZXgpO1xuICAgICAgICBpZiAoIXN0b3JlZEZvcm1hdCkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2l6ZSA9IEZvbnRNZXRyaWNzLm1lYXN1cmVDaGFyU2l6ZSgnRU1QVFlfTElORScsIENvbnRlbnRTdHlsZUhlbHBlci5nZXRGb250U3R5bGVzU3RyaW5nKHN0b3JlZEZvcm1hdC50ZXh0U3R5bGUpKTtcbiAgICAgICAgc2l6ZS53aWR0aCA9IDM7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBuZXcgRGlzcGxheVRva2VuKHtcbiAgICAgICAgICAgICAgICAuLi5zaXplLFxuICAgICAgICAgICAgICAgIGRpc3BsYXlWYWx1ZTogRGlzcGxheVZhbHVlLmVtcHR5TGluZSxcbiAgICAgICAgICAgICAgICBhbGlnbjogbGluZUluZm8uYWxpZ24sXG4gICAgICAgICAgICAgICAgaW5kZW50Rmlyc3RMaW5lOiBsaW5lSW5mby5pbmRlbnQuZmlyc3RMaW5lLFxuICAgICAgICAgICAgICAgIGluZGVudEhhbmdpbmc6IGxpbmVJbmZvLmluZGVudC5oYW5naW5nLFxuICAgICAgICAgICAgICAgIGluZGVudExlZnQ6IGxpbmVJbmZvLmluZGVudC5sZWZ0LFxuICAgICAgICAgICAgICAgIGluZGVudFJpZ2h0OiBsaW5lSW5mby5pbmRlbnQucmlnaHQsXG4gICAgICAgICAgICAgICAgaW5kZW50QmVmb3JlOiBsaW5lSW5mby5vZmZzZXRCZWZvcmUsXG4gICAgICAgICAgICAgICAgaW5kZW50QWZ0ZXI6IGxpbmVJbmZvLm9mZnNldEFmdGVyLFxuICAgICAgICAgICAgICAgIGlzUGFnZUJyZWFrOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBpc0xpbmVCcmVhazogZmFsc2UsXG4gICAgICAgICAgICAgICAgaXNUYWI6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxpbmVTcGFjaW5nOiBsaW5lSW5mby5saW5lU3BhY2luZ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldExpbmVJbmZvQnlCcmVha01vZGlmaWVyKG1vZGVsOiBDb250ZW50c0ludGVyZmFjZSwgaW5kZXg6IG51bWJlcik6IExpbmVJbmZvTW9kZWwge1xuICAgICAgICBjb25zdCBwYXJhZ3JhcGggPSBQYXJhZ3JhcGhTdHlsZUhlbHBlci5nZXRQYXJhZ3JhcGhBdEluZGV4KG1vZGVsLnBhcmFncmFwaHMsIGluZGV4KTtcbiAgICAgICAgaWYgKCFwYXJhZ3JhcGgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgTGluZUluZm9Nb2RlbCh7XG4gICAgICAgICAgICAgICAgYWxpZ246IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLmFsaWdubWVudCxcbiAgICAgICAgICAgICAgICBpbmRlbnQ6IG5ldyBJbmRlbnRNb2RlbChcbiAgICAgICAgICAgICAgICAgICAgREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUuaW5kZW50Rmlyc3RMaW5lLFxuICAgICAgICAgICAgICAgICAgICBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRIYW5naW5nLFxuICAgICAgICAgICAgICAgICAgICBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRMZWZ0LFxuICAgICAgICAgICAgICAgICAgICBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRSaWdodFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgb2Zmc2V0QmVmb3JlOiBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5zcGFjZUJlZm9yZSxcbiAgICAgICAgICAgICAgICBvZmZzZXRBZnRlcjogREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUuc3BhY2VBZnRlcixcbiAgICAgICAgICAgICAgICBsaW5lU3BhY2luZzogREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUubGluZVNwYWNpbmdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5kZW50TGVmdCA9IHRoaXMuZ2V0UGFyYWdyYXBoSW5kZW50TGVmdChtb2RlbCwgcGFyYWdyYXBoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZUluZm9Nb2RlbChwYXJhZ3JhcGgsIGluZGVudExlZnQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UGFyYWdyYXBoSW5kZW50TGVmdChtb2RlbDogQ29udGVudHNJbnRlcmZhY2UsIHBhcmFncmFwaDogUGFyYWdyYXBoTW9kZWwpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBudW1iZXJpbmdJZCA9IHBhcmFncmFwaC5wYXJhZ3JhcGhTdHlsZS5udW1iZXJpbmdJZDtcbiAgICAgICAgaWYgKG51bWJlcmluZ0lkID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyYWdyYXBoLnBhcmFncmFwaFN0eWxlLmluZGVudExlZnQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsZXZlbCA9IHBhcmFncmFwaC5wYXJhZ3JhcGhTdHlsZS5udW1iZXJpbmdMZXZlbDtcbiAgICAgICAgY29uc3QgcGFyYWdyYXBoSW5kZXggPSBtb2RlbC5wYXJhZ3JhcGhzLmluZGV4T2YocGFyYWdyYXBoKTtcbiAgICAgICAgY29uc3QgbGV2ZWxNb2RlbCA9IE51bWJlcmluZ0hlbHBlci5maW5kKHRoaXMuZ2VuZXJhbFByb3BlcnRpZXMubnVtYmVyaW5ncywgbnVtYmVyaW5nSWQsIGxldmVsKTtcbiAgICAgICAgY29uc3QgcGFyYWdyYXBoRm9ybWF0ID0gRm9ybWF0U3R5bGVIZWxwZXIuZ2V0Rm9ybWF0QXRJbmRleChtb2RlbC5mb3JtYXRzLCBwYXJhZ3JhcGguaW5zZXJ0SW5kZXgpO1xuICAgICAgICBjb25zdCBtYXJrZXJUZXh0U3R5bGUgPSBDb250ZW50U3R5bGVIZWxwZXIuY29tYmluZVRleHRTdHlsZXMobGV2ZWxNb2RlbC5tYXJrZXJTdHlsZSwgcGFyYWdyYXBoRm9ybWF0LnRleHRTdHlsZSk7XG4gICAgICAgIGNvbnN0IHBhcmFncmFwaFNldHRpbmdzID0gdGhpcy5nZXRQYXJhZ3JhcGhTZXR0aW5ncyhwYXJhZ3JhcGhJbmRleCk7XG4gICAgICAgIGxldCBtYXJrZXJXaWR0aCA9IHBhcmFncmFwaFNldHRpbmdzPy5udW1iZXJpbmdEYXRhPy53aWR0aDtcbiAgICAgICAgY29uc3QgbWFya2VyID0gTnVtYmVyaW5nSGVscGVyLmdldE1hcmtlcihcbiAgICAgICAgICAgIGxldmVsTW9kZWwsXG4gICAgICAgICAgICBudW1iZXJpbmdJZCxcbiAgICAgICAgICAgIG1vZGVsLnBhcmFncmFwaHMsXG4gICAgICAgICAgICBwYXJhZ3JhcGhJbmRleCxcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhbFByb3BlcnRpZXMubnVtYmVyaW5nSW5mb1xuICAgICAgICApO1xuICAgICAgICBjb25zdCBtYXJrZXJTaXplcyA9IE51bWJlcmluZ0hlbHBlci5nZXRNYXJrZXJTaXplcyhtYXJrZXIsIG1hcmtlclRleHRTdHlsZSk7XG4gICAgICAgIG1hcmtlcldpZHRoID0gbWFya2VyU2l6ZXMud2lkdGg7XG5cbiAgICAgICAgY29uc3QgaGFuZ2luZ0luZGVudCA9IHBhcmFncmFwaC5wYXJhZ3JhcGhTdHlsZS5pbmRlbnRIYW5naW5nID8gcGFyYWdyYXBoLnBhcmFncmFwaFN0eWxlLmluZGVudEhhbmdpbmcgOiBsZXZlbE1vZGVsLmluZGVudEhhbmdpbmc7XG4gICAgICAgIGxldCBwYXJhZ3JhcGhJbmRlbnQgPSBsZXZlbE1vZGVsLmluZGVudExlZnQ7XG4gICAgICAgIGlmIChtYXJrZXJXaWR0aCA+PSBoYW5naW5nSW5kZW50KSB7XG4gICAgICAgICAgICBjb25zdCBtYXJrZXJPdmVyZmxvdyA9IG1hcmtlcldpZHRoIC0gaGFuZ2luZ0luZGVudDtcbiAgICAgICAgICAgIGNvbnN0IGFkZGl0aW9uYWxNYXJrZXJJbmRlbnQgPSBUYWJIZWxwZXIuY2FsY3VsYXRlVGFiV2lkdGgoXG4gICAgICAgICAgICAgICAgbGV2ZWxNb2RlbC5pbmRlbnRMZWZ0ICsgbWFya2VyT3ZlcmZsb3csXG4gICAgICAgICAgICAgICAgdGhpcy5nZW5lcmFsUHJvcGVydGllcy5kZWZhdWx0VGFiV2lkdGhcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXJhZ3JhcGhJbmRlbnQgKz0gbWFya2VyT3ZlcmZsb3cgKyBhZGRpdGlvbmFsTWFya2VySW5kZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBhcmFncmFwaEluZGVudDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldExpbmVJbmZvRnJvbVRleHRMaW5lKGluZGV4OiBudW1iZXIpOiBMaW5lSW5mb01vZGVsIHtcbiAgICAgICAgY29uc3QgcGFyYWdyYXBoID0gUGFyYWdyYXBoU3R5bGVIZWxwZXIuZ2V0UGFyYWdyYXBoQXRJbmRleCh0aGlzLm1vZGVsLnBhcmFncmFwaHMsIGluZGV4KTtcbiAgICAgICAgY29uc3QgaW5kZW50TGVmdCA9IHRoaXMuZ2V0SW5kZW50TGVmdEZyb21UZXh0TGluZShpbmRleCk7XG4gICAgICAgIHJldHVybiB0aGlzLmdldExpbmVJbmZvTW9kZWwocGFyYWdyYXBoLCBpbmRlbnRMZWZ0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldExpbmVJbmZvTW9kZWwocGFyYWdyYXBoOiBQYXJhZ3JhcGhNb2RlbCwgaW5kZW50TGVmdDogbnVtYmVyKTogTGluZUluZm9Nb2RlbCB7XG4gICAgICAgIGNvbnN0IGluZGVudEhhbmdpbmcgPSBwYXJhZ3JhcGgucGFyYWdyYXBoU3R5bGUubnVtYmVyaW5nSWQgPT09IG51bGwgPyBwYXJhZ3JhcGgucGFyYWdyYXBoU3R5bGUuaW5kZW50SGFuZ2luZyA6IDA7XG4gICAgICAgIHJldHVybiBuZXcgTGluZUluZm9Nb2RlbCh7XG4gICAgICAgICAgICBhbGlnbjogcGFyYWdyYXBoLnBhcmFncmFwaFN0eWxlLmFsaWdubWVudCA/PyBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5hbGlnbm1lbnQsXG4gICAgICAgICAgICBpbmRlbnQ6IG5ldyBJbmRlbnRNb2RlbChcbiAgICAgICAgICAgICAgICBwYXJhZ3JhcGgucGFyYWdyYXBoU3R5bGUuaW5kZW50Rmlyc3RMaW5lID8/IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLmluZGVudEZpcnN0TGluZSxcbiAgICAgICAgICAgICAgICBpbmRlbnRIYW5naW5nID8/IERFRkFVTFRfUEFSQUdSQVBIX1NUWUxFLmluZGVudEhhbmdpbmcsXG4gICAgICAgICAgICAgICAgaW5kZW50TGVmdCA/PyBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRMZWZ0LFxuICAgICAgICAgICAgICAgIHBhcmFncmFwaC5wYXJhZ3JhcGhTdHlsZS5pbmRlbnRSaWdodCA/PyBERUZBVUxUX1BBUkFHUkFQSF9TVFlMRS5pbmRlbnRSaWdodFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIG9mZnNldEJlZm9yZTogREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUuc3BhY2VCZWZvcmUsXG4gICAgICAgICAgICBvZmZzZXRBZnRlcjogREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUuc3BhY2VBZnRlcixcbiAgICAgICAgICAgIGxpbmVTcGFjaW5nOiBwYXJhZ3JhcGgucGFyYWdyYXBoU3R5bGUubGluZVNwYWNpbmcgPz8gREVGQVVMVF9QQVJBR1JBUEhfU1RZTEUubGluZVNwYWNpbmdcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJbmRlbnRMZWZ0RnJvbVRleHRMaW5lKGluc2VydEluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSAwO1xuICAgICAgICBsZXQgZW5kSW5kZXggPSB0aGlzLnBhcmFncmFwaHMubGVuZ3RoIC0gMTtcbiAgICAgICAgd2hpbGUgKHN0YXJ0SW5kZXggPD0gZW5kSW5kZXgpIHtcbiAgICAgICAgICAgIGNvbnN0IG1pZGRsZUluZGV4ID0gTWF0aC5yb3VuZCgoc3RhcnRJbmRleCArIGVuZEluZGV4KSAvIDIpO1xuICAgICAgICAgICAgY29uc3QgcGFyYWdyYXBoSW5mbyA9IHRoaXMucGFyYWdyYXBoc1ttaWRkbGVJbmRleF07XG4gICAgICAgICAgICBpZiAocGFyYWdyYXBoSW5mby5zdGFydEluZGV4ID4gaW5zZXJ0SW5kZXgpIHtcbiAgICAgICAgICAgICAgICBzdGFydEluZGV4ID0gbWlkZGxlSW5kZXggKyAxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlbmRJbmRleCA9IG1pZGRsZUluZGV4IC0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRleHRMaW5lc0luZm8gPSB0aGlzLnBhcmFncmFwaHNbc3RhcnRJbmRleF0/LnBhcmFncmFwaFNldHRpbmdzLnRleHRMaW5lc0luZm87XG4gICAgICAgIHJldHVybiB0ZXh0TGluZXNJbmZvID8gTWF0aC5tYXgoLi4udGV4dExpbmVzSW5mby5tYXAoeCA9PiB4LmluZGVudExlZnQpKSA6IG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRlV3JhcFNwbGl0KHRva2VuczogRGlzcGxheVRva2VuW10sIHdyYXBMaW1pdDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgICAgIGlmICghdG9rZW5zLmxlbmd0aCB8fCB0b2tlbnMubGVuZ3RoIDw9IHdyYXBMaW1pdCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGVyZSBpcyBhIHNwYWNlIG9yIHRhYiBhdCB0aGlzIHNwbGl0IHBvc2l0aW9uLCB0aGVuIG1ha2luZ1xuICAgICAgICAvLyBhIHNwbGl0IGlzIHNpbXBsZS5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgd3JhcExpbWl0ID09PSAwIHx8XG4gICAgICAgICAgICB0b2tlbnNbd3JhcExpbWl0XS5kaXNwbGF5VmFsdWUgPT09IERpc3BsYXlWYWx1ZS5jdXN0b21Db250ZW50IHx8XG4gICAgICAgICAgICAodGhpcy5pc1doaXRlU3BhY2UodG9rZW5zW3dyYXBMaW1pdCAtIDFdKSAmJiB0aGlzLmlzV2hpdGVTcGFjZSh0b2tlbnNbd3JhcExpbWl0XSkpXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIHdyYXBMaW1pdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmNhbGN1bGF0ZVNwbGl0KHdyYXBMaW1pdCwgdG9rZW5zKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbGN1bGF0ZVNwbGl0KGluZGV4OiBudW1iZXIsIHRva2VuczogRGlzcGxheVRva2VuW10pOiBudW1iZXIge1xuICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1doaXRlU3BhY2UodG9rZW5zW2ldKSB8fCB0b2tlbnNbaV0uZGlzcGxheVZhbHVlID09PSBEaXNwbGF5VmFsdWUuY3VzdG9tQ29udGVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1doaXRlU3BhY2UodG9rZW46IERpc3BsYXlUb2tlbik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gW0Rpc3BsYXlWYWx1ZS5zcGFjZSwgRGlzcGxheVZhbHVlLmVtcHR5TGluZV0uaW5jbHVkZXModG9rZW4uZGlzcGxheVZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB3cmFwIGluZGV4IGJhc2VkIG9uIG1heCByb3cgd2lkdGhcbiAgICAgKi9cbiAgICBwcml2YXRlIGNvbXB1dGVXcmFwSW5kZXgoZGlzcGxheVRva2VuczogRGlzcGxheVRva2VuW10sIGNvbnRlbnRXaWR0aDogbnVtYmVyLCBkZWZhdWx0VGFiV2lkdGg6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGlmICghZGlzcGxheVRva2Vuc1swXSkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGlzcGxheVRva2Vuc1swXS5pc1RhYmxlIHx8IChkaXNwbGF5VG9rZW5zWzBdLmJyZWFrc0xpbmUgJiYgZGlzcGxheVRva2Vucy5sZW5ndGggPT09IDEpKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGluZGVudCA9XG4gICAgICAgICAgICBkaXNwbGF5VG9rZW5zWzBdLmluZGVudExlZnQgK1xuICAgICAgICAgICAgICAgIGRpc3BsYXlUb2tlbnNbMF0uaW5kZW50UmlnaHQgK1xuICAgICAgICAgICAgICAgIGRpc3BsYXlUb2tlbnNbMF0uaW5kZW50Rmlyc3RMaW5lIC1cbiAgICAgICAgICAgICAgICBkaXNwbGF5VG9rZW5zWzBdLmluZGVudEhhbmdpbmcgfHwgMDtcbiAgICAgICAgY29uc3QgbWF4Um93V2lkdGggPSBjb250ZW50V2lkdGggLSBpbmRlbnQ7XG4gICAgICAgIGxldCBzdW0gPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpc3BsYXlUb2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChkaXNwbGF5VG9rZW5zW2ldLmlzVGFiKSB7XG4gICAgICAgICAgICAgICAgZGlzcGxheVRva2Vuc1tpXS53aWR0aCA9IFRhYkhlbHBlci5jYWxjdWxhdGVUYWJXaWR0aChzdW0sIGRlZmF1bHRUYWJXaWR0aCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN1bSArPSBkaXNwbGF5VG9rZW5zW2ldLndpZHRoO1xuICAgICAgICAgICAgaWYgKChpID4gMCAmJiAoc3VtID49IG1heFJvd1dpZHRoIHx8IGRpc3BsYXlUb2tlbnNbaSAtIDFdLmJyZWFrc0xpbmUpKSB8fCBkaXNwbGF5VG9rZW5zW2ldLmlzVGFibGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRpc3BsYXlUb2tlbnNbaV0uaXNMaW5lQnJlYWsgfHwgKGkgPT09IGRpc3BsYXlUb2tlbnMubGVuZ3RoIC0gMSAmJiBkaXNwbGF5VG9rZW5zW2ldLmlzUGFnZUJyZWFrKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UHJldmlvdXNQYXJhZ3JhcGhJbmZvKHJvdzogbnVtYmVyKTogeyBsYXN0UGFnZTogbnVtYmVyOyBwYXJhZ3JhcGhIZWlnaHQ6IG51bWJlcjsgcGFyYWdyYXBoTGFzdExpbmU6IG51bWJlciB9IHtcbiAgICAgICAgaWYgKCFyb3cgfHwgIXRoaXMucGFyYWdyYXBocy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGxhc3RQYWdlOiAxLCBwYXJhZ3JhcGhIZWlnaHQ6IDAsIHBhcmFncmFwaExhc3RMaW5lOiAtMSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJldlBhcmFncmFwaCA9IHRoaXMucGFyYWdyYXBoc1tyb3cgLSAxXS5wYXJhZ3JhcGhTZXR0aW5ncztcbiAgICAgICAgcmV0dXJuIHByZXZQYXJhZ3JhcGguZ2V0UGFyYWdyYXBoRGF0YSgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0VmlzaWJsZVBhZ2VzKG9mZnNldFRvcDogbnVtYmVyLCBjb250YWluZXJIZWlnaHQ6IG51bWJlcik6IG51bWJlcltdIHtcbiAgICAgICAgY29uc3QgdmlzaWJsZVBhZ2VzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgICAgIGxldCBmaXJzdFZpc2libGVQYWdlID0gb2Zmc2V0VG9wIC8gKHRoaXMucGFnZUhlaWdodCArIHRoaXMucGFnZXNTcGFjZSk7XG4gICAgICAgIGlmIChmaXJzdFZpc2libGVQYWdlICUgMSA9PT0gMCkge1xuICAgICAgICAgICAgZmlyc3RWaXNpYmxlUGFnZSsrO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHZpc2libGVQYWdlc0NvdW50ID0gY29udGFpbmVySGVpZ2h0IC8gKHRoaXMucGFnZUhlaWdodCArIHRoaXMucGFnZXNTcGFjZSk7XG4gICAgICAgIGNvbnN0IHBhcnRpYWxQYWdlT25TY3JlZW5QZXJjZW50ID0gTWF0aC50cnVuYygoKHZpc2libGVQYWdlc0NvdW50ICUgMSkgKyAoZmlyc3RWaXNpYmxlUGFnZSAlIDEpKSAqIDEwMCk7XG4gICAgICAgIGNvbnN0IHBhZ2VTcGFjZUhlaWdodFBlcmNlbnQgPSBNYXRoLnRydW5jKCh0aGlzLnBhZ2VzU3BhY2UgLyBjb250YWluZXJIZWlnaHQpICogMTAwKTtcbiAgICAgICAgaWYgKHBhcnRpYWxQYWdlT25TY3JlZW5QZXJjZW50IC0gcGFnZVNwYWNlSGVpZ2h0UGVyY2VudCA+IDEwMCkge1xuICAgICAgICAgICAgdmlzaWJsZVBhZ2VzQ291bnQrKztcbiAgICAgICAgfVxuXG4gICAgICAgIHZpc2libGVQYWdlc0NvdW50ID0gTWF0aC5jZWlsKHZpc2libGVQYWdlc0NvdW50KTtcbiAgICAgICAgZmlyc3RWaXNpYmxlUGFnZSA9IE1hdGguY2VpbChmaXJzdFZpc2libGVQYWdlKTtcbiAgICAgICAgY29uc3QgZG9jdW1lbnRQYWdlc0NvdW50ID0gdGhpcy5wYXJhZ3JhcGhzW3RoaXMucGFyYWdyYXBocy5sZW5ndGggLSAxXS5wYXJhZ3JhcGhTZXR0aW5ncy5sYXN0UGFnZU51bWJlcjtcbiAgICAgICAgaWYgKGZpcnN0VmlzaWJsZVBhZ2UgKyB2aXNpYmxlUGFnZXNDb3VudCAtIDEgPiBkb2N1bWVudFBhZ2VzQ291bnQpIHtcbiAgICAgICAgICAgIHZpc2libGVQYWdlc0NvdW50ID0gZG9jdW1lbnRQYWdlc0NvdW50IC0gZmlyc3RWaXNpYmxlUGFnZSArIDE7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZpc2libGVQYWdlc0NvdW50OyBpKyspIHtcbiAgICAgICAgICAgIHZpc2libGVQYWdlcy5wdXNoKGZpcnN0VmlzaWJsZVBhZ2UgKyBpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB2aXNpYmxlUGFnZXM7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbnNlcnRUZXh0QW5kUmV0dXJuRW5kQ3Vyc29yUG9zaXRpb24odGV4dDogc3RyaW5nLCBwb3NpdGlvbjogQ3Vyc29yUGFyYWdyYXBoKTogQ3Vyc29yUGFyYWdyYXBoIHtcbiAgICAgICAgY29uc3QgbGVmdCA9IHRoaXMucGFyYWdyYXBoc1twb3NpdGlvbi5yb3ddLmNvbnRlbnQuc2xpY2UoMCwgcG9zaXRpb24uY29sdW1uKTtcbiAgICAgICAgY29uc3QgcmlnaHQgPSB0aGlzLnBhcmFncmFwaHNbcG9zaXRpb24ucm93XS5jb250ZW50LnNsaWNlKHBvc2l0aW9uLmNvbHVtbik7XG4gICAgICAgIGNvbnN0IGluc2VydFBhcmFncmFwaHMgPSB0aGlzLnNwbGl0QnlQYXJhZ3JhcGhzKGAke2xlZnR9JHt0ZXh0fSR7cmlnaHR9YCkubWFwKFxuICAgICAgICAgICAgeCA9PiBuZXcgUGFyYWdyYXBoSW5mb01vZGVsKHsgY29udGVudDogeCwgbmV4dExpbmVJbmRleGVzOiBbXSB9KVxuICAgICAgICApO1xuICAgICAgICBpbnNlcnRQYXJhZ3JhcGhzWzBdLnBhcmFncmFwaFNldHRpbmdzID0gdGhpcy5nZXRQYXJhZ3JhcGhTZXR0aW5ncyhwb3NpdGlvbi5yb3cpO1xuICAgICAgICB0aGlzLnBhcmFncmFwaHMuc3BsaWNlKHBvc2l0aW9uLnJvdywgMSwgLi4uaW5zZXJ0UGFyYWdyYXBocyk7XG4gICAgICAgIHJldHVybiBuZXcgQ3Vyc29yUGFyYWdyYXBoKFxuICAgICAgICAgICAgcG9zaXRpb24ucm93ICsgaW5zZXJ0UGFyYWdyYXBocy5sZW5ndGggLSAxLFxuICAgICAgICAgICAgaW5zZXJ0UGFyYWdyYXBoc1tpbnNlcnRQYXJhZ3JhcGhzLmxlbmd0aCAtIDFdLmNvbnRlbnQubGVuZ3RoIC0gcmlnaHQubGVuZ3RoXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzcGxpdEJ5UGFyYWdyYXBocyh0ZXh0OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiB0ZXh0LnNwbGl0KC9cXHJcXG58XFxyfFxcbi8pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0UGFyYWdyYXBoSW5kZXhlcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgcGFyYWdyYXBoIG9mIHRoaXMucGFyYWdyYXBocykge1xuICAgICAgICAgICAgcGFyYWdyYXBoLnBhcmFncmFwaFNldHRpbmdzLnN0YXJ0SW5zZXJ0SW5kZXggPSBwYXJhZ3JhcGguc3RhcnRJbmRleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFBhZ2VzVmVydGljYWxEYXRhKCk6IHZvaWQge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAhdGhpcy5jdXN0b21Db21wb25lbnRzLmVkZ2VzIHx8XG4gICAgICAgICAgICAoIXRoaXMuY3VzdG9tQ29tcG9uZW50cy5lZGdlcy5oZWFkZXJzQ29tcG9uZW50cy5sZW5ndGggJiYgIXRoaXMuY3VzdG9tQ29tcG9uZW50cy5lZGdlcy5mb290ZXJzQ29tcG9uZW50cy5sZW5ndGgpXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5wYWdlc1ZlcnRpY2FsRGF0YSA9IFtcbiAgICAgICAgICAgICAgICBuZXcgUGFnZVZlcnRpY2FsRGF0YU1vZGVsKHtcbiAgICAgICAgICAgICAgICAgICAgbWFyZ2luVG9wOiB0aGlzLnBhZ2VNYXJnaW4udG9wLFxuICAgICAgICAgICAgICAgICAgICBtYXJnaW5Cb3R0b206IHRoaXMucGFnZU1hcmdpbi5ib3R0b20sXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRIZWlnaHQ6IHRoaXMucGFnZUhlaWdodCAtIHRoaXMucGFnZU1hcmdpbi50b3AgLSB0aGlzLnBhZ2VNYXJnaW4uYm90dG9tLFxuICAgICAgICAgICAgICAgICAgICBwYWdlVHlwZTogUGFnZVR5cGUuRGVmYXVsdFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFnZVR5cGVzID0gdGhpcy5jdXN0b21Db21wb25lbnRzLmVkZ2VzLmdldFVuaXF1ZVBhZ2VUeXBlcygpO1xuICAgICAgICB0aGlzLnBhZ2VzVmVydGljYWxEYXRhID0gcGFnZVR5cGVzLm1hcChwYWdlVHlwZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBoZWFkZXJIZWlnaHQgPSB0aGlzLmN1c3RvbUNvbXBvbmVudHMuZWRnZXMuZ2V0Q29tcG9uZW50SGVpZ2h0QnlQYWdlVHlwZShwYWdlVHlwZSwgRWRnZVR5cGUuSGVhZGVyKTtcbiAgICAgICAgICAgIGNvbnN0IGZvb3RlckhlaWdodCA9IHRoaXMuY3VzdG9tQ29tcG9uZW50cy5lZGdlcy5nZXRDb21wb25lbnRIZWlnaHRCeVBhZ2VUeXBlKHBhZ2VUeXBlLCBFZGdlVHlwZS5Gb290ZXIpO1xuICAgICAgICAgICAgY29uc3QgbWFyZ2luVG9wID0gTWF0aC5tYXgoaGVhZGVySGVpZ2h0LCB0aGlzLnBhZ2VNYXJnaW4udG9wKTtcbiAgICAgICAgICAgIGNvbnN0IG1hcmdpbkJvdHRvbSA9IE1hdGgubWF4KGZvb3RlckhlaWdodCwgdGhpcy5wYWdlTWFyZ2luLmJvdHRvbSk7XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgUGFnZVZlcnRpY2FsRGF0YU1vZGVsKHtcbiAgICAgICAgICAgICAgICBtYXJnaW5Ub3AsXG4gICAgICAgICAgICAgICAgbWFyZ2luQm90dG9tLFxuICAgICAgICAgICAgICAgIGNvbnRlbnRIZWlnaHQ6IHRoaXMucGFnZUhlaWdodCAtIG1hcmdpblRvcCAtIG1hcmdpbkJvdHRvbSxcbiAgICAgICAgICAgICAgICBwYWdlVHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ==