@skyux/text-editor 5.0.3 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +7 -1
  2. package/bundles/skyux-text-editor.umd.js +39 -39
  3. package/documentation.json +61 -14
  4. package/esm2015/index.js +15 -0
  5. package/esm2015/index.js.map +1 -0
  6. package/esm2015/lib/modules/rich-text-display/rich-text-display.component.js +39 -0
  7. package/esm2015/lib/modules/rich-text-display/rich-text-display.component.js.map +1 -0
  8. package/esm2015/lib/modules/rich-text-display/rich-text-display.module.js +18 -0
  9. package/esm2015/lib/modules/rich-text-display/rich-text-display.module.js.map +1 -0
  10. package/esm2015/lib/modules/shared/forms-utility.js +10 -0
  11. package/esm2015/lib/modules/shared/forms-utility.js.map +1 -0
  12. package/esm2015/lib/modules/shared/sky-text-editor-resources.module.js +106 -0
  13. package/esm2015/lib/modules/shared/sky-text-editor-resources.module.js.map +1 -0
  14. package/esm2015/lib/modules/text-editor/defaults/font-list-defaults.js +42 -0
  15. package/esm2015/lib/modules/text-editor/defaults/font-list-defaults.js.map +1 -0
  16. package/esm2015/lib/modules/text-editor/defaults/font-size-list-defaults.js +7 -0
  17. package/esm2015/lib/modules/text-editor/defaults/font-size-list-defaults.js.map +1 -0
  18. package/esm2015/lib/modules/text-editor/defaults/menu-defaults.js +5 -0
  19. package/esm2015/lib/modules/text-editor/defaults/menu-defaults.js.map +1 -0
  20. package/esm2015/lib/modules/text-editor/defaults/style-state-defaults.js +15 -0
  21. package/esm2015/lib/modules/text-editor/defaults/style-state-defaults.js.map +1 -0
  22. package/esm2015/lib/modules/text-editor/defaults/toolbar-action-defaults.js +12 -0
  23. package/esm2015/lib/modules/text-editor/defaults/toolbar-action-defaults.js.map +1 -0
  24. package/esm2015/lib/modules/text-editor/menubar/text-editor-menubar.component.js +196 -0
  25. package/esm2015/lib/modules/text-editor/menubar/text-editor-menubar.component.js.map +1 -0
  26. package/esm2015/lib/modules/text-editor/services/text-editor-adapter.service.js +473 -0
  27. package/esm2015/lib/modules/text-editor/services/text-editor-adapter.service.js.map +1 -0
  28. package/esm2015/lib/modules/text-editor/services/text-editor-selection.service.js +80 -0
  29. package/esm2015/lib/modules/text-editor/services/text-editor-selection.service.js.map +1 -0
  30. package/esm2015/lib/modules/text-editor/services/text-editor.service.js +61 -0
  31. package/esm2015/lib/modules/text-editor/services/text-editor.service.js.map +1 -0
  32. package/esm2015/lib/modules/text-editor/services/text-sanitization.service.js +38 -0
  33. package/esm2015/lib/modules/text-editor/services/text-sanitization.service.js.map +1 -0
  34. package/esm2015/lib/modules/text-editor/text-editor.component.js +322 -0
  35. package/esm2015/lib/modules/text-editor/text-editor.component.js.map +1 -0
  36. package/esm2015/lib/modules/text-editor/text-editor.module.js +99 -0
  37. package/esm2015/lib/modules/text-editor/text-editor.module.js.map +1 -0
  38. package/esm2015/lib/modules/text-editor/toolbar/text-editor-toolbar.component.js +175 -0
  39. package/esm2015/lib/modules/text-editor/toolbar/text-editor-toolbar.component.js.map +1 -0
  40. package/esm2015/lib/modules/text-editor/types/editor-command.js +2 -0
  41. package/esm2015/lib/modules/text-editor/types/editor-command.js.map +1 -0
  42. package/esm2015/lib/modules/text-editor/types/editor-setting.js +2 -0
  43. package/esm2015/lib/modules/text-editor/types/editor-setting.js.map +1 -0
  44. package/esm2015/lib/modules/text-editor/types/font-state.js +2 -0
  45. package/esm2015/lib/modules/text-editor/types/font-state.js.map +1 -0
  46. package/esm2015/lib/modules/text-editor/types/menu-type.js +2 -0
  47. package/esm2015/lib/modules/text-editor/types/menu-type.js.map +1 -0
  48. package/esm2015/lib/modules/text-editor/types/style-state.js +2 -0
  49. package/esm2015/lib/modules/text-editor/types/style-state.js.map +1 -0
  50. package/esm2015/lib/modules/text-editor/types/text-editor-merge-field.js +2 -0
  51. package/esm2015/lib/modules/text-editor/types/text-editor-merge-field.js.map +1 -0
  52. package/esm2015/lib/modules/text-editor/types/toolbar-action-type.js +2 -0
  53. package/esm2015/lib/modules/text-editor/types/toolbar-action-type.js.map +1 -0
  54. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-context.js +6 -0
  55. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-context.js.map +1 -0
  56. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-result.js +2 -0
  57. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal-result.js.map +1 -0
  58. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal.component.js +121 -0
  59. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-modal.component.js.map +1 -0
  60. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-target.js +9 -0
  61. package/esm2015/lib/modules/text-editor/url-modal/text-editor-url-target.js.map +1 -0
  62. package/esm2015/skyux-text-editor.js +2 -2
  63. package/esm2015/skyux-text-editor.js.map +1 -0
  64. package/fesm2015/skyux-text-editor.js +105 -105
  65. package/fesm2015/skyux-text-editor.js.map +1 -1
  66. package/index.d.ts +12 -0
  67. package/{modules → lib/modules}/rich-text-display/rich-text-display.component.d.ts +0 -0
  68. package/{modules → lib/modules}/rich-text-display/rich-text-display.module.d.ts +0 -0
  69. package/{modules → lib/modules}/shared/forms-utility.d.ts +0 -0
  70. package/{modules → lib/modules}/shared/sky-text-editor-resources.module.d.ts +0 -0
  71. package/{modules → lib/modules}/text-editor/defaults/font-list-defaults.d.ts +0 -0
  72. package/{modules → lib/modules}/text-editor/defaults/font-size-list-defaults.d.ts +0 -0
  73. package/{modules → lib/modules}/text-editor/defaults/menu-defaults.d.ts +0 -0
  74. package/{modules → lib/modules}/text-editor/defaults/style-state-defaults.d.ts +0 -0
  75. package/{modules → lib/modules}/text-editor/defaults/toolbar-action-defaults.d.ts +0 -0
  76. package/{modules → lib/modules}/text-editor/menubar/text-editor-menubar.component.d.ts +0 -0
  77. package/{modules → lib/modules}/text-editor/services/text-editor-adapter.service.d.ts +0 -0
  78. package/{modules → lib/modules}/text-editor/services/text-editor-selection.service.d.ts +0 -0
  79. package/{modules → lib/modules}/text-editor/services/text-editor.service.d.ts +0 -0
  80. package/{modules → lib/modules}/text-editor/services/text-sanitization.service.d.ts +0 -0
  81. package/{modules → lib/modules}/text-editor/text-editor.component.d.ts +0 -0
  82. package/{modules → lib/modules}/text-editor/text-editor.module.d.ts +0 -0
  83. package/{modules → lib/modules}/text-editor/toolbar/text-editor-toolbar.component.d.ts +0 -0
  84. package/{modules → lib/modules}/text-editor/types/editor-command.d.ts +0 -0
  85. package/{modules → lib/modules}/text-editor/types/editor-setting.d.ts +0 -0
  86. package/{modules → lib/modules}/text-editor/types/font-state.d.ts +0 -0
  87. package/{modules → lib/modules}/text-editor/types/menu-type.d.ts +0 -0
  88. package/{modules → lib/modules}/text-editor/types/style-state.d.ts +0 -0
  89. package/{modules → lib/modules}/text-editor/types/text-editor-merge-field.d.ts +0 -0
  90. package/{modules → lib/modules}/text-editor/types/toolbar-action-type.d.ts +0 -0
  91. package/{modules → lib/modules}/text-editor/url-modal/text-editor-url-modal-context.d.ts +0 -0
  92. package/{modules → lib/modules}/text-editor/url-modal/text-editor-url-modal-result.d.ts +0 -0
  93. package/{modules → lib/modules}/text-editor/url-modal/text-editor-url-modal.component.d.ts +0 -0
  94. package/{modules → lib/modules}/text-editor/url-modal/text-editor-url-target.d.ts +0 -0
  95. package/package.json +27 -13
  96. package/skyux-text-editor.d.ts +1 -1
  97. package/LICENSE +0 -21
  98. package/bundles/skyux-text-editor.umd.js.map +0 -1
  99. package/esm2015/modules/rich-text-display/rich-text-display.component.js +0 -37
  100. package/esm2015/modules/rich-text-display/rich-text-display.module.js +0 -18
  101. package/esm2015/modules/shared/forms-utility.js +0 -10
  102. package/esm2015/modules/shared/sky-text-editor-resources.module.js +0 -106
  103. package/esm2015/modules/text-editor/defaults/font-list-defaults.js +0 -42
  104. package/esm2015/modules/text-editor/defaults/font-size-list-defaults.js +0 -7
  105. package/esm2015/modules/text-editor/defaults/menu-defaults.js +0 -5
  106. package/esm2015/modules/text-editor/defaults/style-state-defaults.js +0 -15
  107. package/esm2015/modules/text-editor/defaults/toolbar-action-defaults.js +0 -12
  108. package/esm2015/modules/text-editor/menubar/text-editor-menubar.component.js +0 -194
  109. package/esm2015/modules/text-editor/services/text-editor-adapter.service.js +0 -470
  110. package/esm2015/modules/text-editor/services/text-editor-selection.service.js +0 -80
  111. package/esm2015/modules/text-editor/services/text-editor.service.js +0 -61
  112. package/esm2015/modules/text-editor/services/text-sanitization.service.js +0 -38
  113. package/esm2015/modules/text-editor/text-editor.component.js +0 -317
  114. package/esm2015/modules/text-editor/text-editor.module.js +0 -99
  115. package/esm2015/modules/text-editor/toolbar/text-editor-toolbar.component.js +0 -173
  116. package/esm2015/modules/text-editor/types/editor-command.js +0 -2
  117. package/esm2015/modules/text-editor/types/editor-setting.js +0 -2
  118. package/esm2015/modules/text-editor/types/font-state.js +0 -2
  119. package/esm2015/modules/text-editor/types/menu-type.js +0 -2
  120. package/esm2015/modules/text-editor/types/style-state.js +0 -2
  121. package/esm2015/modules/text-editor/types/text-editor-merge-field.js +0 -2
  122. package/esm2015/modules/text-editor/types/toolbar-action-type.js +0 -2
  123. package/esm2015/modules/text-editor/url-modal/text-editor-url-modal-context.js +0 -6
  124. package/esm2015/modules/text-editor/url-modal/text-editor-url-modal-result.js +0 -2
  125. package/esm2015/modules/text-editor/url-modal/text-editor-url-modal.component.js +0 -119
  126. package/esm2015/modules/text-editor/url-modal/text-editor-url-target.js +0 -9
  127. package/esm2015/public-api.js +0 -15
  128. package/public-api.d.ts +0 -12
@@ -1,470 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { Subject } from 'rxjs';
3
- import { STYLE_STATE_DEFAULTS } from '../defaults/style-state-defaults';
4
- import { UrlTarget } from '../url-modal/text-editor-url-target';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "./text-editor-selection.service";
7
- import * as i2 from "./text-editor.service";
8
- import * as i3 from "@skyux/core";
9
- /**
10
- * @internal
11
- */
12
- export class SkyTextEditorAdapterService {
13
- constructor(selectionService, textEditorService, windowService) {
14
- this.selectionService = selectionService;
15
- this.textEditorService = textEditorService;
16
- this.windowService = windowService;
17
- }
18
- get editors() {
19
- return this.textEditorService.editors;
20
- }
21
- /**
22
- * Creates a text editor inside the supplied iframe element.
23
- */
24
- addEditor(id, iframeElement, styleState, placeholder) {
25
- /* istanbul ignore else */
26
- if (!(id in this.editors)) {
27
- this.editors[id] = this.createObservers(id, iframeElement);
28
- const documentEl = this.getIframeDocumentEl(id);
29
- const styleEl = documentEl.createElement('style');
30
- styleEl.innerHTML = `.editor:empty:before {
31
- content: attr(data-placeholder);
32
- font-family: "Blackbaud Sans", Arial, sans-serif;
33
- color: #686c73;
34
- font-weight: 400;
35
- font-size: 15px;
36
- font-style: italic;
37
- }`;
38
- documentEl.head.appendChild(styleEl);
39
- const style = Object.assign(Object.assign({}, STYLE_STATE_DEFAULTS), styleState);
40
- const bodyStyle = `background-color: ${style.backColor};
41
- color: ${style.fontColor};
42
- font-family: ${style.font};
43
- font-size: ${style.fontSize}px`;
44
- documentEl.querySelector('html').setAttribute('lang', 'en');
45
- documentEl.body.setAttribute('contenteditable', 'true');
46
- documentEl.body.setAttribute('id', id);
47
- documentEl.body.setAttribute('role', 'main');
48
- documentEl.body.setAttribute('class', 'editor');
49
- documentEl.body.setAttribute('style', bodyStyle);
50
- documentEl.body.setAttribute('data-placeholder', placeholder || '');
51
- }
52
- }
53
- disableEditor(id, focusableChildren, textEditorNativeElement) {
54
- this.setEditorDisabled(id, focusableChildren, textEditorNativeElement, true);
55
- }
56
- enableEditor(id, focusableChildren, textEditorNativeElement) {
57
- this.setEditorDisabled(id, focusableChildren, textEditorNativeElement, false);
58
- }
59
- /**
60
- * Executes a command on the text editor with the corresponding id.
61
- */
62
- execCommand(id, editorCommand) {
63
- /* istanbul ignore else */
64
- if (id in this.editors) {
65
- const documentEl = this.getIframeDocumentEl(id);
66
- /* istanbul ignore else */
67
- if (this.editorSelected(id)) {
68
- const commandIsSupportedAndEnabled = documentEl.execCommand(editorCommand.command, false, editorCommand.value);
69
- // IE11 doesn't support insertHTML
70
- /* istanbul ignore next */
71
- if (editorCommand.command.toLowerCase() === 'inserthtml' &&
72
- !commandIsSupportedAndEnabled) {
73
- this.insertHtmlInIE11(id, editorCommand.value);
74
- }
75
- this.focusEditor(id);
76
- this.editors[id].commandChangeObservable.next();
77
- }
78
- }
79
- }
80
- getCurrentSelection(id) {
81
- return this.selectionService.getCurrentSelection(this.getIframeDocumentEl(id));
82
- }
83
- /**
84
- * Returns a data URI using the provided text string.
85
- * Used to display a merge field inside a string of text.
86
- */
87
- getMergeFieldDataURI(text) {
88
- const documentEl = this.windowService.nativeWindow.document;
89
- let textToUse = text;
90
- if (text.length > 18) {
91
- textToUse = text.substr(0, 15) + '...';
92
- }
93
- const canvasElement = documentEl.createElement('canvas');
94
- canvasElement.setAttribute('height', '20');
95
- canvasElement.setAttribute('width', '100');
96
- canvasElement.style.backgroundColor = 'tan';
97
- canvasElement.style.border = '1px solid #000000';
98
- canvasElement.style.borderRadius = '5px';
99
- const context = canvasElement.getContext('2d');
100
- context.font = '12px Arial';
101
- context.textAlign = 'center';
102
- context.fillText(textToUse, 50, 15);
103
- context.globalCompositeOperation = 'destination-over';
104
- context.fillStyle = '#00FFFF';
105
- context.fillRect(0, 0, 100, 20);
106
- context.globalCompositeOperation = 'source-over';
107
- context.lineWidth = 2;
108
- context.strokeStyle = '#FF0000';
109
- context.strokeRect(0, 0, 100, 20);
110
- const result = canvasElement.toDataURL('image/png', 1.0);
111
- return result;
112
- }
113
- getStyleState(id) {
114
- const documentEl = this.getIframeDocumentEl(id);
115
- /* istanbul ignore else */
116
- if (this.editorSelected(id)) {
117
- return {
118
- backColor: this.getColor(documentEl, 'BackColor'),
119
- fontColor: this.getColor(documentEl, 'ForeColor'),
120
- fontSize: parseInt(this.getFontSize(id), undefined),
121
- font: documentEl.queryCommandValue('fontname'),
122
- boldState: documentEl.queryCommandState('Bold'),
123
- italicState: documentEl.queryCommandState('Italic'),
124
- underlineState: documentEl.queryCommandState('Underline'),
125
- linkState: this.hasLink(id),
126
- };
127
- }
128
- /* istanbul ignore next */
129
- return {};
130
- }
131
- getEditorInnerHtml(id) {
132
- const documentEl = this.getIframeDocumentEl(id);
133
- if (documentEl) {
134
- return this.replaceHtmlCodes(documentEl.body.innerHTML);
135
- }
136
- return '';
137
- }
138
- setEditorInnerHtml(id, value) {
139
- const documentEl = this.getIframeDocumentEl(id);
140
- const editorContent = documentEl.body;
141
- /* istanbul ignore else */
142
- if (editorContent.innerHTML !== value) {
143
- editorContent.innerHTML = value;
144
- }
145
- }
146
- focusEditor(id) {
147
- /* istanbul ignore else */
148
- if (id in this.editors) {
149
- const windowEl = this.getContentWindowEl(id);
150
- const iframeDocumentEl = this.getIframeDocumentEl(id);
151
- const currentSelection = this.selectionService.getCurrentSelectionRange(iframeDocumentEl, windowEl);
152
- const cursorIsNotActiveAndHasReset = currentSelection &&
153
- currentSelection.startOffset === 0 &&
154
- currentSelection.endOffset === 0;
155
- if (!this.editorSelected(id) || cursorIsNotActiveAndHasReset) {
156
- // focus the end of the editor
157
- const documentEl = this.windowService.nativeWindow.document;
158
- const editor = iframeDocumentEl.body;
159
- const range = documentEl.createRange();
160
- this.editors[id].iframeElementRef.focus();
161
- editor.focus();
162
- /* istanbul ignore else */
163
- if (windowEl.getSelection && documentEl.createRange) {
164
- range.selectNodeContents(editor);
165
- range.collapse(false);
166
- const sel = windowEl.getSelection();
167
- sel.removeAllRanges();
168
- sel.addRange(range);
169
- }
170
- else {
171
- // IE only
172
- const textRange = editor.createTextRange();
173
- textRange.moveToElementText(editor);
174
- textRange.collapse(false);
175
- textRange.select();
176
- }
177
- }
178
- else {
179
- // Cursor may not be active, restore it
180
- this.editors[id].iframeElementRef.focus();
181
- iframeDocumentEl.body.focus();
182
- }
183
- }
184
- }
185
- getLink(editorId) {
186
- let link = undefined;
187
- const anchorEl = this.getSelectedAnchorTag(editorId);
188
- if (anchorEl && anchorEl.href) {
189
- link = {
190
- target: anchorEl.getAttribute('target') === '_blank'
191
- ? UrlTarget.NewWindow
192
- : UrlTarget.None,
193
- url: anchorEl.href,
194
- };
195
- }
196
- return link;
197
- }
198
- getSelectedAnchorTag(editorId) {
199
- const selectedEl = this.getCurrentSelectionParentElement(editorId);
200
- return this.getParent(selectedEl, 'a');
201
- }
202
- saveSelection(id) {
203
- return this.selectionService.getCurrentSelectionRange(this.getIframeDocumentEl(id), this.getContentWindowEl(id));
204
- }
205
- selectElement(id, element) {
206
- this.selectionService.selectElement(this.getIframeDocumentEl(id), this.getContentWindowEl(id), element);
207
- }
208
- setPlaceholder(id, placeholder) {
209
- const documentEl = this.getIframeDocumentEl(id);
210
- documentEl.body.setAttribute('data-placeholder', placeholder || '');
211
- }
212
- setFontSize(id, fontSize) {
213
- const doc = this.getIframeDocumentEl(id);
214
- this.execCommand(id, { command: 'fontSize', value: 1 });
215
- const fontElements = Array.from(doc.querySelectorAll('font[size="1"]'));
216
- for (let element of fontElements) {
217
- element.removeAttribute('size');
218
- element.style.fontSize = fontSize + 'px';
219
- }
220
- this.cleanUpBlankStyleTags(doc);
221
- this.focusEditor(id);
222
- this.editors[id].commandChangeObservable.next();
223
- }
224
- removeObservers(setting) {
225
- /* istanbul ignore next */
226
- const documentEl = setting.iframeElementRef.contentWindow
227
- ? setting.iframeElementRef.contentWindow.document
228
- : setting.iframeElementRef.contentDocument;
229
- setting.selectionChangeObservable.complete();
230
- setting.clickObservable.complete();
231
- setting.commandChangeObservable.complete();
232
- documentEl.removeEventListener('selectionchange', setting.selectionListener);
233
- documentEl.removeEventListener('input', setting.selectionListener);
234
- documentEl.removeEventListener('mousedown', setting.clickListener);
235
- documentEl.body.removeEventListener('paste', setting.pasteListener);
236
- }
237
- getContentWindowEl(id) {
238
- return this.editors[id].iframeElementRef.contentWindow;
239
- }
240
- getChildSelectedAnchorTags(editorId) {
241
- const selectedRange = this.getCurrentSelection(editorId).getRangeAt(0);
242
- if (selectedRange.toString().length <= 0) {
243
- return [];
244
- }
245
- const parentElement = this.getCurrentSelectionParentElement(editorId);
246
- let childElements = [];
247
- /* istanbul ignore else */
248
- if (parentElement) {
249
- childElements = Array.from(parentElement.querySelectorAll('a'));
250
- }
251
- /* istanbul ignore next */
252
- return childElements.filter((element) => {
253
- // IE specific
254
- if (!selectedRange.intersectsNode) {
255
- if (!element || !element.href) {
256
- return false;
257
- }
258
- const tempRange = document.createRange();
259
- tempRange.selectNodeContents(element);
260
- return ((selectedRange.compareBoundaryPoints(Range.START_TO_START, tempRange) !== -1 &&
261
- selectedRange.compareBoundaryPoints(Range.START_TO_END, tempRange) !== 1) ||
262
- (selectedRange.compareBoundaryPoints(Range.END_TO_START, tempRange) !== -1 &&
263
- selectedRange.compareBoundaryPoints(Range.END_TO_END, tempRange) !==
264
- 1));
265
- }
266
- // Normal non-IE
267
- return (!!element && !!element.href && selectedRange.intersectsNode(element));
268
- });
269
- }
270
- getIframeDocumentEl(id) {
271
- /* istanbul ignore next */
272
- if (!(id in this.editors)) {
273
- return undefined;
274
- }
275
- const contentWindowEl = this.getContentWindowEl(id);
276
- /* istanbul ignore else */
277
- if (contentWindowEl) {
278
- return contentWindowEl.document;
279
- }
280
- /* istanbul ignore next */
281
- return this.editors[id].iframeElementRef.contentDocument;
282
- }
283
- getFontSize(id) {
284
- let fontSize = STYLE_STATE_DEFAULTS.fontSize.toString();
285
- const selection = this.getCurrentSelection(id);
286
- /* istanbul ignore else */
287
- if (selection &&
288
- selection.anchorNode &&
289
- selection.anchorNode.parentElement) {
290
- let element = selection.anchorNode;
291
- if (element.nodeType !== 1) {
292
- element = element.parentElement;
293
- }
294
- const computedStyle = window.getComputedStyle(element);
295
- /* istanbul ignore else */
296
- if (computedStyle) {
297
- fontSize = computedStyle.getPropertyValue('font-size');
298
- }
299
- }
300
- return fontSize;
301
- }
302
- createObservers(id, element) {
303
- /* istanbul ignore next */
304
- const documentEl = element.contentWindow
305
- ? element.contentWindow.document
306
- : element.contentDocument;
307
- // Firefox bug where we need to open/close to cancel load so it doesn't overwrite attrs
308
- documentEl.open();
309
- documentEl.close();
310
- const selectionObservable = new Subject();
311
- const selectionListener = () => selectionObservable.next();
312
- const clickObservable = new Subject();
313
- const clickListener = () => clickObservable.next();
314
- const pasteListener = this.getPasteOverride(id);
315
- const blurObservable = new Subject();
316
- const blurListener = () => blurObservable.next();
317
- const inputObservable = new Subject();
318
- const inputListener = () => inputObservable.next();
319
- documentEl.addEventListener('selectionchange', selectionListener);
320
- documentEl.addEventListener('input', inputListener);
321
- documentEl.addEventListener('mousedown', clickListener);
322
- documentEl.body.addEventListener('paste', pasteListener);
323
- documentEl.body.addEventListener('blur', blurListener);
324
- return {
325
- blurObservable: blurObservable,
326
- clickObservable: clickObservable,
327
- commandChangeObservable: new Subject(),
328
- iframeElementRef: element,
329
- inputObservable: inputObservable,
330
- selectionChangeObservable: selectionObservable,
331
- blurListener: blurListener,
332
- clickListener: clickListener,
333
- inputListener: inputListener,
334
- pasteListener: pasteListener,
335
- selectionListener: selectionListener,
336
- };
337
- }
338
- /* istanbul ignore next */
339
- getPasteOverride(id) {
340
- return (e) => {
341
- e.preventDefault();
342
- const text = e.clipboardData.getData('text/plain');
343
- this.execCommand(id, { command: 'insertHTML', value: text });
344
- };
345
- }
346
- getCurrentSelectionParentElement(id) {
347
- return this.selectionService.getCurrentSelectionParentElement(this.getIframeDocumentEl(id));
348
- }
349
- getColor(documentEl, selector) {
350
- const commandValue = documentEl.queryCommandValue(selector);
351
- // Edge is weird and returns numbers
352
- /* istanbul ignore if */
353
- if (typeof commandValue === 'number') {
354
- /* istanbul ignore next */
355
- // tslint:disable-next-line: no-bitwise
356
- return ('rgb(' +
357
- (commandValue & 0xff) +
358
- ', ' +
359
- // tslint:disable-next-line: no-bitwise
360
- ((commandValue & 0xff00) >> 8) +
361
- ', ' +
362
- // tslint:disable-next-line: no-bitwise
363
- ((commandValue & 0xff0000) >> 16) +
364
- ')');
365
- }
366
- // Firefox uses 'Transparent' instead of a color value
367
- /* istanbul ignore next */
368
- if (commandValue.toString().toLowerCase() === 'transparent') {
369
- return STYLE_STATE_DEFAULTS.backColor;
370
- }
371
- return commandValue;
372
- }
373
- hasLink(editorId) {
374
- const anchorEl = this.getSelectedAnchorTag(editorId);
375
- const childAnchorEls = this.getChildSelectedAnchorTags(editorId);
376
- /* istanbul ignore next */
377
- return childAnchorEls.length > 0 || (!!anchorEl && !!anchorEl.href);
378
- }
379
- getParent(element, tag) {
380
- let currentNode = element;
381
- while (currentNode && currentNode.tagName.toUpperCase() !== 'BODY') {
382
- if (currentNode.tagName.toUpperCase() === tag.toUpperCase()) {
383
- return currentNode;
384
- }
385
- currentNode = currentNode.parentElement;
386
- }
387
- return undefined;
388
- }
389
- editorSelected(id) {
390
- const documentEl = this.getIframeDocumentEl(id);
391
- return this.selectionService.isElementSelected(documentEl, documentEl.body);
392
- }
393
- /* istanbul ignore next */
394
- insertHtmlInIE11(id, html) {
395
- const documentEl = this.getIframeDocumentEl(id);
396
- const windowEl = this.getContentWindowEl(id);
397
- const sel = windowEl.getSelection();
398
- if (sel.getRangeAt && sel.rangeCount) {
399
- let range = sel.getRangeAt(0);
400
- range.deleteContents();
401
- const el = documentEl.createElement('div');
402
- el.innerHTML = html;
403
- let frag = documentEl.createDocumentFragment(), node, lastNode;
404
- while (el.firstChild) {
405
- node = el.firstChild;
406
- lastNode = frag.appendChild(node);
407
- }
408
- range.insertNode(frag);
409
- // Preserve the selection
410
- if (lastNode) {
411
- range = range.cloneRange();
412
- range.setStartAfter(lastNode);
413
- range.collapse(true);
414
- sel.removeAllRanges();
415
- sel.addRange(range);
416
- }
417
- }
418
- }
419
- cleanUpBlankStyleTags(doc) {
420
- const orphanElements = Array.from(doc.querySelectorAll('font,span,*[style=""]'));
421
- for (let element of orphanElements) {
422
- if (!element.getAttribute('style')) {
423
- element.removeAttribute('style');
424
- }
425
- }
426
- const removableElements = orphanElements.filter((element) => {
427
- const tagName = element.tagName.toUpperCase();
428
- return ((tagName === 'FONT' || tagName === 'SPAN') &&
429
- (element.attributes.length === 0 || !element.hasChildNodes));
430
- });
431
- for (let element of removableElements) {
432
- const parent = element.parentNode;
433
- /* istanbul ignore else */
434
- if (parent) {
435
- while (element.firstChild) {
436
- parent.insertBefore(element.firstChild, element);
437
- }
438
- parent.removeChild(element);
439
- }
440
- }
441
- }
442
- // Certain values are encoded in html and need to be decoded
443
- replaceHtmlCodes(str) {
444
- return str
445
- .replace(/&nbsp;/, String.fromCharCode(160))
446
- .replace(/&lt;/g, '<')
447
- .replace(/&gt;/g, '>')
448
- .replace(/&amp;/g, '&');
449
- }
450
- setEditorDisabled(id, focusableChildren, textEditorNativeElement, disabled) {
451
- textEditorNativeElement.style.pointerEvents = disabled ? 'none' : 'auto';
452
- textEditorNativeElement.setAttribute('aria-disabled', disabled ? 'true' : 'false');
453
- /* istanbul ignore else */
454
- if (focusableChildren.length > 0) {
455
- focusableChildren.forEach((aFocusableChild) => {
456
- aFocusableChild.tabIndex = disabled ? -1 : 0;
457
- });
458
- }
459
- this.getIframeDocumentEl(id).body.setAttribute('contenteditable', disabled ? 'false' : 'true');
460
- }
461
- }
462
- SkyTextEditorAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: SkyTextEditorAdapterService, deps: [{ token: i1.SkyTextEditorSelectionService }, { token: i2.SkyTextEditorService }, { token: i3.SkyAppWindowRef }], target: i0.ɵɵFactoryTarget.Injectable });
463
- SkyTextEditorAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: SkyTextEditorAdapterService, providedIn: 'root' });
464
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: SkyTextEditorAdapterService, decorators: [{
465
- type: Injectable,
466
- args: [{
467
- providedIn: 'root',
468
- }]
469
- }], ctorParameters: function () { return [{ type: i1.SkyTextEditorSelectionService }, { type: i2.SkyTextEditorService }, { type: i3.SkyAppWindowRef }]; } });
470
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1lZGl0b3ItYWRhcHRlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGV4dC1lZGl0b3Ivc3JjL21vZHVsZXMvdGV4dC1lZGl0b3Ivc2VydmljZXMvdGV4dC1lZGl0b3ItYWRhcHRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFJM0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvQixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQVV4RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUNBQXFDLENBQUM7Ozs7O0FBTWhFOztHQUVHO0FBSUgsTUFBTSxPQUFPLDJCQUEyQjtJQUt0QyxZQUNVLGdCQUErQyxFQUMvQyxpQkFBdUMsRUFDdkMsYUFBOEI7UUFGOUIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUErQjtRQUMvQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQXNCO1FBQ3ZDLGtCQUFhLEdBQWIsYUFBYSxDQUFpQjtJQUNyQyxDQUFDO0lBUkosSUFBWSxPQUFPO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQztJQUN4QyxDQUFDO0lBUUQ7O09BRUc7SUFDSSxTQUFTLENBQ2QsRUFBVSxFQUNWLGFBQWdDLEVBQ2hDLFVBQW1DLEVBQ25DLFdBQW9CO1FBRXBCLDBCQUEwQjtRQUMxQixJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3pCLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFFM0QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUs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QkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFNreUFwcFdpbmRvd1JlZiB9IGZyb20gJ0Bza3l1eC9jb3JlJztcblxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBTVFlMRV9TVEFURV9ERUZBVUxUUyB9IGZyb20gJy4uL2RlZmF1bHRzL3N0eWxlLXN0YXRlLWRlZmF1bHRzJztcblxuaW1wb3J0IHsgRWRpdG9yQ29tbWFuZCB9IGZyb20gJy4uL3R5cGVzL2VkaXRvci1jb21tYW5kJztcblxuaW1wb3J0IHsgRWRpdG9yU2V0dGluZyB9IGZyb20gJy4uL3R5cGVzL2VkaXRvci1zZXR0aW5nJztcblxuaW1wb3J0IHsgU2t5VGV4dEVkaXRvclN0eWxlU3RhdGUgfSBmcm9tICcuLi90eXBlcy9zdHlsZS1zdGF0ZSc7XG5cbmltcG9ydCB7IFVybE1vZGFsUmVzdWx0IH0gZnJvbSAnLi4vdXJsLW1vZGFsL3RleHQtZWRpdG9yLXVybC1tb2RhbC1yZXN1bHQnO1xuXG5pbXBvcnQgeyBVcmxUYXJnZXQgfSBmcm9tICcuLi91cmwtbW9kYWwvdGV4dC1lZGl0b3ItdXJsLXRhcmdldCc7XG5cbmltcG9ydCB7IFNreVRleHRFZGl0b3JTZXJ2aWNlIH0gZnJvbSAnLi90ZXh0LWVkaXRvci5zZXJ2aWNlJztcblxuaW1wb3J0IHsgU2t5VGV4dEVkaXRvclNlbGVjdGlvblNlcnZpY2UgfSBmcm9tICcuL3RleHQtZWRpdG9yLXNlbGVjdGlvbi5zZXJ2aWNlJztcblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFNreVRleHRFZGl0b3JBZGFwdGVyU2VydmljZSB7XG4gIHByaXZhdGUgZ2V0IGVkaXRvcnMoKTogeyBba2V5OiBzdHJpbmddOiBFZGl0b3JTZXR0aW5nIH0ge1xuICAgIHJldHVybiB0aGlzLnRleHRFZGl0b3JTZXJ2aWNlLmVkaXRvcnM7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHNlbGVjdGlvblNlcnZpY2U6IFNreVRleHRFZGl0b3JTZWxlY3Rpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgdGV4dEVkaXRvclNlcnZpY2U6IFNreVRleHRFZGl0b3JTZXJ2aWNlLFxuICAgIHByaXZhdGUgd2luZG93U2VydmljZTogU2t5QXBwV2luZG93UmVmXG4gICkge31cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHRleHQgZWRpdG9yIGluc2lkZSB0aGUgc3VwcGxpZWQgaWZyYW1lIGVsZW1lbnQuXG4gICAqL1xuICBwdWJsaWMgYWRkRWRpdG9yKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgaWZyYW1lRWxlbWVudDogSFRNTElGcmFtZUVsZW1lbnQsXG4gICAgc3R5bGVTdGF0ZTogU2t5VGV4dEVkaXRvclN0eWxlU3RhdGUsXG4gICAgcGxhY2Vob2xkZXI/OiBzdHJpbmdcbiAgKTogdm9pZCB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoIShpZCBpbiB0aGlzLmVkaXRvcnMpKSB7XG4gICAgICB0aGlzLmVkaXRvcnNbaWRdID0gdGhpcy5jcmVhdGVPYnNlcnZlcnMoaWQsIGlmcmFtZUVsZW1lbnQpO1xuXG4gICAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcblxuICAgICAgY29uc3Qgc3R5bGVFbCA9IGRvY3VtZW50RWwuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgIHN0eWxlRWwuaW5uZXJIVE1MID0gYC5lZGl0b3I6ZW1wdHk6YmVmb3JlIHtcbiAgICAgICAgY29udGVudDogYXR0cihkYXRhLXBsYWNlaG9sZGVyKTtcbiAgICAgICAgZm9udC1mYW1pbHk6IFwiQmxhY2tiYXVkIFNhbnNcIiwgQXJpYWwsIHNhbnMtc2VyaWY7XG4gICAgICAgIGNvbG9yOiAjNjg2YzczO1xuICAgICAgICBmb250LXdlaWdodDogNDAwO1xuICAgICAgICBmb250LXNpemU6IDE1cHg7XG4gICAgICAgIGZvbnQtc3R5bGU6IGl0YWxpYztcbiAgICAgIH1gO1xuICAgICAgZG9jdW1lbnRFbC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlRWwpO1xuXG4gICAgICBjb25zdCBzdHlsZTogU2t5VGV4dEVkaXRvclN0eWxlU3RhdGUgPSB7XG4gICAgICAgIC4uLlNUWUxFX1NUQVRFX0RFRkFVTFRTLFxuICAgICAgICAuLi5zdHlsZVN0YXRlLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGJvZHlTdHlsZSA9IGBiYWNrZ3JvdW5kLWNvbG9yOiAke3N0eWxlLmJhY2tDb2xvcn07XG4gICAgICAgIGNvbG9yOiAke3N0eWxlLmZvbnRDb2xvcn07XG4gICAgICAgIGZvbnQtZmFtaWx5OiAke3N0eWxlLmZvbnR9O1xuICAgICAgICBmb250LXNpemU6ICR7c3R5bGUuZm9udFNpemV9cHhgO1xuICAgICAgZG9jdW1lbnRFbC5xdWVyeVNlbGVjdG9yKCdodG1sJykuc2V0QXR0cmlidXRlKCdsYW5nJywgJ2VuJyk7XG4gICAgICBkb2N1bWVudEVsLmJvZHkuc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCAndHJ1ZScpO1xuICAgICAgZG9jdW1lbnRFbC5ib2R5LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XG4gICAgICBkb2N1bWVudEVsLmJvZHkuc2V0QXR0cmlidXRlKCdyb2xlJywgJ21haW4nKTtcbiAgICAgIGRvY3VtZW50RWwuYm9keS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2VkaXRvcicpO1xuICAgICAgZG9jdW1lbnRFbC5ib2R5LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBib2R5U3R5bGUpO1xuICAgICAgZG9jdW1lbnRFbC5ib2R5LnNldEF0dHJpYnV0ZSgnZGF0YS1wbGFjZWhvbGRlcicsIHBsYWNlaG9sZGVyIHx8ICcnKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZGlzYWJsZUVkaXRvcihcbiAgICBpZDogc3RyaW5nLFxuICAgIGZvY3VzYWJsZUNoaWxkcmVuOiBIVE1MRWxlbWVudFtdLFxuICAgIHRleHRFZGl0b3JOYXRpdmVFbGVtZW50OiBhbnlcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5zZXRFZGl0b3JEaXNhYmxlZChcbiAgICAgIGlkLFxuICAgICAgZm9jdXNhYmxlQ2hpbGRyZW4sXG4gICAgICB0ZXh0RWRpdG9yTmF0aXZlRWxlbWVudCxcbiAgICAgIHRydWVcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGVuYWJsZUVkaXRvcihcbiAgICBpZDogc3RyaW5nLFxuICAgIGZvY3VzYWJsZUNoaWxkcmVuOiBIVE1MRWxlbWVudFtdLFxuICAgIHRleHRFZGl0b3JOYXRpdmVFbGVtZW50OiBhbnlcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5zZXRFZGl0b3JEaXNhYmxlZChcbiAgICAgIGlkLFxuICAgICAgZm9jdXNhYmxlQ2hpbGRyZW4sXG4gICAgICB0ZXh0RWRpdG9yTmF0aXZlRWxlbWVudCxcbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBhIGNvbW1hbmQgb24gdGhlIHRleHQgZWRpdG9yIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgaWQuXG4gICAqL1xuICBwdWJsaWMgZXhlY0NvbW1hbmQoaWQ6IHN0cmluZywgZWRpdG9yQ29tbWFuZDogRWRpdG9yQ29tbWFuZCk6IHZvaWQge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKGlkIGluIHRoaXMuZWRpdG9ycykge1xuICAgICAgY29uc3QgZG9jdW1lbnRFbCA9IHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZCk7XG5cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAodGhpcy5lZGl0b3JTZWxlY3RlZChpZCkpIHtcbiAgICAgICAgY29uc3QgY29tbWFuZElzU3VwcG9ydGVkQW5kRW5hYmxlZCA9IGRvY3VtZW50RWwuZXhlY0NvbW1hbmQoXG4gICAgICAgICAgZWRpdG9yQ29tbWFuZC5jb21tYW5kLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgIGVkaXRvckNvbW1hbmQudmFsdWVcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBJRTExIGRvZXNuJ3Qgc3VwcG9ydCBpbnNlcnRIVE1MXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGlmIChcbiAgICAgICAgICBlZGl0b3JDb21tYW5kLmNvbW1hbmQudG9Mb3dlckNhc2UoKSA9PT0gJ2luc2VydGh0bWwnICYmXG4gICAgICAgICAgIWNvbW1hbmRJc1N1cHBvcnRlZEFuZEVuYWJsZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5pbnNlcnRIdG1sSW5JRTExKGlkLCBlZGl0b3JDb21tYW5kLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9jdXNFZGl0b3IoaWQpO1xuICAgICAgICB0aGlzLmVkaXRvcnNbaWRdLmNvbW1hbmRDaGFuZ2VPYnNlcnZhYmxlLm5leHQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0Q3VycmVudFNlbGVjdGlvbihpZDogc3RyaW5nKTogU2VsZWN0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmdldEN1cnJlbnRTZWxlY3Rpb24oXG4gICAgICB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgZGF0YSBVUkkgdXNpbmcgdGhlIHByb3ZpZGVkIHRleHQgc3RyaW5nLlxuICAgKiBVc2VkIHRvIGRpc3BsYXkgYSBtZXJnZSBmaWVsZCBpbnNpZGUgYSBzdHJpbmcgb2YgdGV4dC5cbiAgICovXG4gIHB1YmxpYyBnZXRNZXJnZUZpZWxkRGF0YVVSSSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRvY3VtZW50RWwgPSB0aGlzLndpbmRvd1NlcnZpY2UubmF0aXZlV2luZG93LmRvY3VtZW50O1xuICAgIGxldCB0ZXh0VG9Vc2UgPSB0ZXh0O1xuICAgIGlmICh0ZXh0Lmxlbmd0aCA+IDE4KSB7XG4gICAgICB0ZXh0VG9Vc2UgPSB0ZXh0LnN1YnN0cigwLCAxNSkgKyAnLi4uJztcbiAgICB9XG5cbiAgICBjb25zdCBjYW52YXNFbGVtZW50ID0gZG9jdW1lbnRFbC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjYW52YXNFbGVtZW50LnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgJzIwJyk7XG4gICAgY2FudmFzRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgJzEwMCcpO1xuICAgIGNhbnZhc0VsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gJ3Rhbic7XG4gICAgY2FudmFzRWxlbWVudC5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkICMwMDAwMDAnO1xuICAgIGNhbnZhc0VsZW1lbnQuc3R5bGUuYm9yZGVyUmFkaXVzID0gJzVweCc7XG5cbiAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzRWxlbWVudC5nZXRDb250ZXh0KCcyZCcpO1xuICAgIGNvbnRleHQuZm9udCA9ICcxMnB4IEFyaWFsJztcbiAgICBjb250ZXh0LnRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgIGNvbnRleHQuZmlsbFRleHQodGV4dFRvVXNlLCA1MCwgMTUpO1xuXG4gICAgY29udGV4dC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnZGVzdGluYXRpb24tb3Zlcic7XG4gICAgY29udGV4dC5maWxsU3R5bGUgPSAnIzAwRkZGRic7XG4gICAgY29udGV4dC5maWxsUmVjdCgwLCAwLCAxMDAsIDIwKTtcblxuICAgIGNvbnRleHQuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ3NvdXJjZS1vdmVyJztcbiAgICBjb250ZXh0LmxpbmVXaWR0aCA9IDI7XG4gICAgY29udGV4dC5zdHJva2VTdHlsZSA9ICcjRkYwMDAwJztcbiAgICBjb250ZXh0LnN0cm9rZVJlY3QoMCwgMCwgMTAwLCAyMCk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBjYW52YXNFbGVtZW50LnRvRGF0YVVSTCgnaW1hZ2UvcG5nJywgMS4wKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHVibGljIGdldFN0eWxlU3RhdGUoaWQ6IHN0cmluZyk6IFBhcnRpYWw8U2t5VGV4dEVkaXRvclN0eWxlU3RhdGU+IHtcbiAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHRoaXMuZWRpdG9yU2VsZWN0ZWQoaWQpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBiYWNrQ29sb3I6IHRoaXMuZ2V0Q29sb3IoZG9jdW1lbnRFbCwgJ0JhY2tDb2xvcicpLFxuICAgICAgICBmb250Q29sb3I6IHRoaXMuZ2V0Q29sb3IoZG9jdW1lbnRFbCwgJ0ZvcmVDb2xvcicpLFxuICAgICAgICBmb250U2l6ZTogcGFyc2VJbnQodGhpcy5nZXRGb250U2l6ZShpZCksIHVuZGVmaW5lZCksXG4gICAgICAgIGZvbnQ6IGRvY3VtZW50RWwucXVlcnlDb21tYW5kVmFsdWUoJ2ZvbnRuYW1lJyksXG4gICAgICAgIGJvbGRTdGF0ZTogZG9jdW1lbnRFbC5xdWVyeUNvbW1hbmRTdGF0ZSgnQm9sZCcpLFxuICAgICAgICBpdGFsaWNTdGF0ZTogZG9jdW1lbnRFbC5xdWVyeUNvbW1hbmRTdGF0ZSgnSXRhbGljJyksXG4gICAgICAgIHVuZGVybGluZVN0YXRlOiBkb2N1bWVudEVsLnF1ZXJ5Q29tbWFuZFN0YXRlKCdVbmRlcmxpbmUnKSxcbiAgICAgICAgbGlua1N0YXRlOiB0aGlzLmhhc0xpbmsoaWQpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRFZGl0b3JJbm5lckh0bWwoaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgZG9jdW1lbnRFbCA9IHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZCk7XG4gICAgaWYgKGRvY3VtZW50RWwpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VIdG1sQ29kZXMoZG9jdW1lbnRFbC5ib2R5LmlubmVySFRNTCk7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHB1YmxpYyBzZXRFZGl0b3JJbm5lckh0bWwoaWQ6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGRvY3VtZW50RWwgPSB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpO1xuICAgIGNvbnN0IGVkaXRvckNvbnRlbnQgPSBkb2N1bWVudEVsLmJvZHk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoZWRpdG9yQ29udGVudC5pbm5lckhUTUwgIT09IHZhbHVlKSB7XG4gICAgICBlZGl0b3JDb250ZW50LmlubmVySFRNTCA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBmb2N1c0VkaXRvcihpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoaWQgaW4gdGhpcy5lZGl0b3JzKSB7XG4gICAgICBjb25zdCB3aW5kb3dFbCA9IHRoaXMuZ2V0Q29udGVudFdpbmRvd0VsKGlkKTtcbiAgICAgIGNvbnN0IGlmcmFtZURvY3VtZW50RWwgPSB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpO1xuICAgICAgY29uc3QgY3VycmVudFNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRDdXJyZW50U2VsZWN0aW9uUmFuZ2UoXG4gICAgICAgIGlmcmFtZURvY3VtZW50RWwsXG4gICAgICAgIHdpbmRvd0VsXG4gICAgICApO1xuICAgICAgY29uc3QgY3Vyc29ySXNOb3RBY3RpdmVBbmRIYXNSZXNldCA9XG4gICAgICAgIGN1cnJlbnRTZWxlY3Rpb24gJiZcbiAgICAgICAgY3VycmVudFNlbGVjdGlvbi5zdGFydE9mZnNldCA9PT0gMCAmJlxuICAgICAgICBjdXJyZW50U2VsZWN0aW9uLmVuZE9mZnNldCA9PT0gMDtcblxuICAgICAgaWYgKCF0aGlzLmVkaXRvclNlbGVjdGVkKGlkKSB8fCBjdXJzb3JJc05vdEFjdGl2ZUFuZEhhc1Jlc2V0KSB7XG4gICAgICAgIC8vIGZvY3VzIHRoZSBlbmQgb2YgdGhlIGVkaXRvclxuICAgICAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy53aW5kb3dTZXJ2aWNlLm5hdGl2ZVdpbmRvdy5kb2N1bWVudDtcbiAgICAgICAgY29uc3QgZWRpdG9yOiBhbnkgPSBpZnJhbWVEb2N1bWVudEVsLmJvZHk7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gZG9jdW1lbnRFbC5jcmVhdGVSYW5nZSgpO1xuXG4gICAgICAgIHRoaXMuZWRpdG9yc1tpZF0uaWZyYW1lRWxlbWVudFJlZi5mb2N1cygpO1xuICAgICAgICBlZGl0b3IuZm9jdXMoKTtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgaWYgKHdpbmRvd0VsLmdldFNlbGVjdGlvbiAmJiBkb2N1bWVudEVsLmNyZWF0ZVJhbmdlKSB7XG4gICAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKGVkaXRvcik7XG4gICAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuICAgICAgICAgIGNvbnN0IHNlbCA9IHdpbmRvd0VsLmdldFNlbGVjdGlvbigpO1xuICAgICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIElFIG9ubHlcbiAgICAgICAgICBjb25zdCB0ZXh0UmFuZ2UgPSBlZGl0b3IuY3JlYXRlVGV4dFJhbmdlKCk7XG4gICAgICAgICAgdGV4dFJhbmdlLm1vdmVUb0VsZW1lbnRUZXh0KGVkaXRvcik7XG4gICAgICAgICAgdGV4dFJhbmdlLmNvbGxhcHNlKGZhbHNlKTtcbiAgICAgICAgICB0ZXh0UmFuZ2Uuc2VsZWN0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEN1cnNvciBtYXkgbm90IGJlIGFjdGl2ZSwgcmVzdG9yZSBpdFxuICAgICAgICB0aGlzLmVkaXRvcnNbaWRdLmlmcmFtZUVsZW1lbnRSZWYuZm9jdXMoKTtcbiAgICAgICAgaWZyYW1lRG9jdW1lbnRFbC5ib2R5LmZvY3VzKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldExpbmsoZWRpdG9ySWQ6IHN0cmluZyk6IFVybE1vZGFsUmVzdWx0IHtcbiAgICBsZXQgbGluazogVXJsTW9kYWxSZXN1bHQgPSB1bmRlZmluZWQ7XG4gICAgY29uc3QgYW5jaG9yRWwgPSB0aGlzLmdldFNlbGVjdGVkQW5jaG9yVGFnKGVkaXRvcklkKTtcbiAgICBpZiAoYW5jaG9yRWwgJiYgYW5jaG9yRWwuaHJlZikge1xuICAgICAgbGluayA9IHtcbiAgICAgICAgdGFyZ2V0OlxuICAgICAgICAgIGFuY2hvckVsLmdldEF0dHJpYnV0ZSgndGFyZ2V0JykgPT09ICdfYmxhbmsnXG4gICAgICAgICAgICA/IFVybFRhcmdldC5OZXdXaW5kb3dcbiAgICAgICAgICAgIDogVXJsVGFyZ2V0Lk5vbmUsXG4gICAgICAgIHVybDogYW5jaG9yRWwuaHJlZixcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbms7XG4gIH1cblxuICBwdWJsaWMgZ2V0U2VsZWN0ZWRBbmNob3JUYWcoZWRpdG9ySWQ6IHN0cmluZyk6IEhUTUxBbmNob3JFbGVtZW50IHtcbiAgICBjb25zdCBzZWxlY3RlZEVsID0gdGhpcy5nZXRDdXJyZW50U2VsZWN0aW9uUGFyZW50RWxlbWVudChlZGl0b3JJZCk7XG5cbiAgICByZXR1cm4gdGhpcy5nZXRQYXJlbnQoc2VsZWN0ZWRFbCwgJ2EnKSBhcyBIVE1MQW5jaG9yRWxlbWVudDtcbiAgfVxuXG4gIHB1YmxpYyBzYXZlU2VsZWN0aW9uKGlkOiBzdHJpbmcpOiBSYW5nZSB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRDdXJyZW50U2VsZWN0aW9uUmFuZ2UoXG4gICAgICB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpLFxuICAgICAgdGhpcy5nZXRDb250ZW50V2luZG93RWwoaWQpXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBzZWxlY3RFbGVtZW50KGlkOiBzdHJpbmcsIGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnNlbGVjdEVsZW1lbnQoXG4gICAgICB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpLFxuICAgICAgdGhpcy5nZXRDb250ZW50V2luZG93RWwoaWQpLFxuICAgICAgZWxlbWVudFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc2V0UGxhY2Vob2xkZXIoaWQ6IHN0cmluZywgcGxhY2Vob2xkZXI/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcbiAgICBkb2N1bWVudEVsLmJvZHkuc2V0QXR0cmlidXRlKCdkYXRhLXBsYWNlaG9sZGVyJywgcGxhY2Vob2xkZXIgfHwgJycpO1xuICB9XG5cbiAgcHVibGljIHNldEZvbnRTaXplKGlkOiBzdHJpbmcsIGZvbnRTaXplOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBkb2MgPSB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpO1xuICAgIHRoaXMuZXhlY0NvbW1hbmQoaWQsIHsgY29tbWFuZDogJ2ZvbnRTaXplJywgdmFsdWU6IDEgfSk7XG4gICAgY29uc3QgZm9udEVsZW1lbnRzOiBIVE1MRWxlbWVudFtdID0gQXJyYXkuZnJvbShcbiAgICAgIGRvYy5xdWVyeVNlbGVjdG9yQWxsKCdmb250W3NpemU9XCIxXCJdJylcbiAgICApO1xuICAgIGZvciAobGV0IGVsZW1lbnQgb2YgZm9udEVsZW1lbnRzKSB7XG4gICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnc2l6ZScpO1xuICAgICAgZWxlbWVudC5zdHlsZS5mb250U2l6ZSA9IGZvbnRTaXplICsgJ3B4JztcbiAgICB9XG4gICAgdGhpcy5jbGVhblVwQmxhbmtTdHlsZVRhZ3MoZG9jKTtcblxuICAgIHRoaXMuZm9jdXNFZGl0b3IoaWQpO1xuICAgIHRoaXMuZWRpdG9yc1tpZF0uY29tbWFuZENoYW5nZU9ic2VydmFibGUubmV4dCgpO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZU9ic2VydmVycyhzZXR0aW5nOiBFZGl0b3JTZXR0aW5nKTogdm9pZCB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBjb25zdCBkb2N1bWVudEVsID0gc2V0dGluZy5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnRXaW5kb3dcbiAgICAgID8gc2V0dGluZy5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnRcbiAgICAgIDogc2V0dGluZy5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnREb2N1bWVudDtcbiAgICBzZXR0aW5nLnNlbGVjdGlvbkNoYW5nZU9ic2VydmFibGUuY29tcGxldGUoKTtcbiAgICBzZXR0aW5nLmNsaWNrT2JzZXJ2YWJsZS5jb21wbGV0ZSgpO1xuICAgIHNldHRpbmcuY29tbWFuZENoYW5nZU9ic2VydmFibGUuY29tcGxldGUoKTtcbiAgICBkb2N1bWVudEVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAnc2VsZWN0aW9uY2hhbmdlJyxcbiAgICAgIHNldHRpbmcuc2VsZWN0aW9uTGlzdGVuZXJcbiAgICApO1xuICAgIGRvY3VtZW50RWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBzZXR0aW5nLnNlbGVjdGlvbkxpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHNldHRpbmcuY2xpY2tMaXN0ZW5lcik7XG4gICAgZG9jdW1lbnRFbC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Bhc3RlJywgc2V0dGluZy5wYXN0ZUxpc3RlbmVyKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29udGVudFdpbmRvd0VsKGlkOiBzdHJpbmcpOiBXaW5kb3cge1xuICAgIHJldHVybiB0aGlzLmVkaXRvcnNbaWRdLmlmcmFtZUVsZW1lbnRSZWYuY29udGVudFdpbmRvdztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2hpbGRTZWxlY3RlZEFuY2hvclRhZ3MoZWRpdG9ySWQ6IHN0cmluZyk6IEVsZW1lbnRbXSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRSYW5nZSA9IHRoaXMuZ2V0Q3VycmVudFNlbGVjdGlvbihlZGl0b3JJZCkuZ2V0UmFuZ2VBdCgwKTtcbiAgICBpZiAoc2VsZWN0ZWRSYW5nZS50b1N0cmluZygpLmxlbmd0aCA8PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgcGFyZW50RWxlbWVudCA9IHRoaXMuZ2V0Q3VycmVudFNlbGVjdGlvblBhcmVudEVsZW1lbnQoZWRpdG9ySWQpO1xuXG4gICAgbGV0IGNoaWxkRWxlbWVudHMgPSBbXTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChwYXJlbnRFbGVtZW50KSB7XG4gICAgICBjaGlsZEVsZW1lbnRzID0gQXJyYXkuZnJvbShwYXJlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2EnKSk7XG4gICAgfVxuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gY2hpbGRFbGVtZW50cy5maWx0ZXIoKGVsZW1lbnQpID0+IHtcbiAgICAgIC8vIElFIHNwZWNpZmljXG4gICAgICBpZiAoIXNlbGVjdGVkUmFuZ2UuaW50ZXJzZWN0c05vZGUpIHtcbiAgICAgICAgaWYgKCFlbGVtZW50IHx8ICFlbGVtZW50LmhyZWYpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGVtcFJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgdGVtcFJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAoc2VsZWN0ZWRSYW5nZS5jb21wYXJlQm91bmRhcnlQb2ludHMoXG4gICAgICAgICAgICBSYW5nZS5TVEFSVF9UT19TVEFSVCxcbiAgICAgICAgICAgIHRlbXBSYW5nZVxuICAgICAgICAgICkgIT09IC0xICYmXG4gICAgICAgICAgICBzZWxlY3RlZFJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhcbiAgICAgICAgICAgICAgUmFuZ2UuU1RBUlRfVE9fRU5ELFxuICAgICAgICAgICAgICB0ZW1wUmFuZ2VcbiAgICAgICAgICAgICkgIT09IDEpIHx8XG4gICAgICAgICAgKHNlbGVjdGVkUmFuZ2UuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKFxuICAgICAgICAgICAgUmFuZ2UuRU5EX1RPX1NUQVJULFxuICAgICAgICAgICAgdGVtcFJhbmdlXG4gICAgICAgICAgKSAhPT0gLTEgJiZcbiAgICAgICAgICAgIHNlbGVjdGVkUmFuZ2UuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKFJhbmdlLkVORF9UT19FTkQsIHRlbXBSYW5nZSkgIT09XG4gICAgICAgICAgICAgIDEpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIE5vcm1hbCBub24tSUVcbiAgICAgIHJldHVybiAoXG4gICAgICAgICEhZWxlbWVudCAmJiAhIWVsZW1lbnQuaHJlZiAmJiBzZWxlY3RlZFJhbmdlLmludGVyc2VjdHNOb2RlKGVsZW1lbnQpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRJZnJhbWVEb2N1bWVudEVsKGlkOiBzdHJpbmcpOiBEb2N1bWVudCB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoIShpZCBpbiB0aGlzLmVkaXRvcnMpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRlbnRXaW5kb3dFbCA9IHRoaXMuZ2V0Q29udGVudFdpbmRvd0VsKGlkKTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChjb250ZW50V2luZG93RWwpIHtcbiAgICAgIHJldHVybiBjb250ZW50V2luZG93RWwuZG9jdW1lbnQ7XG4gICAgfVxuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gdGhpcy5lZGl0b3JzW2lkXS5pZnJhbWVFbGVtZW50UmVmLmNvbnRlbnREb2N1bWVudDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Rm9udFNpemUoaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IGZvbnRTaXplID0gU1RZTEVfU1RBVEVfREVGQVVMVFMuZm9udFNpemUudG9TdHJpbmcoKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLmdldEN1cnJlbnRTZWxlY3Rpb24oaWQpO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKFxuICAgICAgc2VsZWN0aW9uICYmXG4gICAgICBzZWxlY3Rpb24uYW5jaG9yTm9kZSAmJlxuICAgICAgc2VsZWN0aW9uLmFuY2hvck5vZGUucGFyZW50RWxlbWVudFxuICAgICkge1xuICAgICAgbGV0IGVsZW1lbnQgPSBzZWxlY3Rpb24uYW5jaG9yTm9kZTtcbiAgICAgIGlmIChlbGVtZW50Lm5vZGVUeXBlICE9PSAxKSB7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ7XG4gICAgICB9XG4gICAgICBjb25zdCBjb21wdXRlZFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCBhcyBFbGVtZW50KTtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAoY29tcHV0ZWRTdHlsZSkge1xuICAgICAgICBmb250U2l6ZSA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnZm9udC1zaXplJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmb250U2l6ZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlT2JzZXJ2ZXJzKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgZWxlbWVudDogSFRNTElGcmFtZUVsZW1lbnRcbiAgKTogRWRpdG9yU2V0dGluZyB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBjb25zdCBkb2N1bWVudEVsID0gZWxlbWVudC5jb250ZW50V2luZG93XG4gICAgICA/IGVsZW1lbnQuY29udGVudFdpbmRvdy5kb2N1bWVudFxuICAgICAgOiBlbGVtZW50LmNvbnRlbnREb2N1bWVudDtcblxuICAgIC8vIEZpcmVmb3ggYnVnIHdoZXJlIHdlIG5lZWQgdG8gb3Blbi9jbG9zZSB0byBjYW5jZWwgbG9hZCBzbyBpdCBkb2Vzbid0IG92ZXJ3cml0ZSBhdHRyc1xuICAgIGRvY3VtZW50RWwub3BlbigpO1xuICAgIGRvY3VtZW50RWwuY2xvc2UoKTtcblxuICAgIGNvbnN0IHNlbGVjdGlvbk9ic2VydmFibGUgPSBuZXcgU3ViamVjdCgpO1xuICAgIGNvbnN0IHNlbGVjdGlvbkxpc3RlbmVyID0gKCkgPT4gc2VsZWN0aW9uT2JzZXJ2YWJsZS5uZXh0KCk7XG4gICAgY29uc3QgY2xpY2tPYnNlcnZhYmxlID0gbmV3IFN1YmplY3QoKTtcbiAgICBjb25zdCBjbGlja0xpc3RlbmVyID0gKCkgPT4gY2xpY2tPYnNlcnZhYmxlLm5leHQoKTtcbiAgICBjb25zdCBwYXN0ZUxpc3RlbmVyID0gdGhpcy5nZXRQYXN0ZU92ZXJyaWRlKGlkKTtcbiAgICBjb25zdCBibHVyT2JzZXJ2YWJsZSA9IG5ldyBTdWJqZWN0KCk7XG4gICAgY29uc3QgYmx1ckxpc3RlbmVyID0gKCkgPT4gYmx1ck9ic2VydmFibGUubmV4dCgpO1xuICAgIGNvbnN0IGlucHV0T2JzZXJ2YWJsZSA9IG5ldyBTdWJqZWN0KCk7XG4gICAgY29uc3QgaW5wdXRMaXN0ZW5lciA9ICgpID0+IGlucHV0T2JzZXJ2YWJsZS5uZXh0KCk7XG5cbiAgICBkb2N1bWVudEVsLmFkZEV2ZW50TGlzdGVuZXIoJ3NlbGVjdGlvbmNoYW5nZScsIHNlbGVjdGlvbkxpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgaW5wdXRMaXN0ZW5lcik7XG4gICAgZG9jdW1lbnRFbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBjbGlja0xpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLmJvZHkuYWRkRXZlbnRMaXN0ZW5lcigncGFzdGUnLCBwYXN0ZUxpc3RlbmVyKTtcbiAgICBkb2N1bWVudEVsLmJvZHkuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIGJsdXJMaXN0ZW5lcik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJsdXJPYnNlcnZhYmxlOiBibHVyT2JzZXJ2YWJsZSxcbiAgICAgIGNsaWNrT2JzZXJ2YWJsZTogY2xpY2tPYnNlcnZhYmxlLFxuICAgICAgY29tbWFuZENoYW5nZU9ic2VydmFibGU6IG5ldyBTdWJqZWN0KCksXG4gICAgICBpZnJhbWVFbGVtZW50UmVmOiBlbGVtZW50LFxuICAgICAgaW5wdXRPYnNlcnZhYmxlOiBpbnB1dE9ic2VydmFibGUsXG4gICAgICBzZWxlY3Rpb25DaGFuZ2VPYnNlcnZhYmxlOiBzZWxlY3Rpb25PYnNlcnZhYmxlLFxuICAgICAgYmx1ckxpc3RlbmVyOiBibHVyTGlzdGVuZXIsXG4gICAgICBjbGlja0xpc3RlbmVyOiBjbGlja0xpc3RlbmVyLFxuICAgICAgaW5wdXRMaXN0ZW5lcjogaW5wdXRMaXN0ZW5lcixcbiAgICAgIHBhc3RlTGlzdGVuZXI6IHBhc3RlTGlzdGVuZXIsXG4gICAgICBzZWxlY3Rpb25MaXN0ZW5lcjogc2VsZWN0aW9uTGlzdGVuZXIsXG4gICAgfTtcbiAgfVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHByaXZhdGUgZ2V0UGFzdGVPdmVycmlkZShpZDogc3RyaW5nKTogKGU6IENsaXBib2FyZEV2ZW50KSA9PiB2b2lkIHtcbiAgICByZXR1cm4gKGU6IENsaXBib2FyZEV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBjb25zdCB0ZXh0ID0gZS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKTtcbiAgICAgIHRoaXMuZXhlY0NvbW1hbmQoaWQsIHsgY29tbWFuZDogJ2luc2VydEhUTUwnLCB2YWx1ZTogdGV4dCB9KTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDdXJyZW50U2VsZWN0aW9uUGFyZW50RWxlbWVudChpZDogc3RyaW5nKTogRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXRDdXJyZW50U2VsZWN0aW9uUGFyZW50RWxlbWVudChcbiAgICAgIHRoaXMuZ2V0SWZyYW1lRG9jdW1lbnRFbChpZClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2xvcihkb2N1bWVudEVsOiBEb2N1bWVudCwgc2VsZWN0b3I6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29tbWFuZFZhbHVlID0gZG9jdW1lbnRFbC5xdWVyeUNvbW1hbmRWYWx1ZShzZWxlY3Rvcik7XG5cbiAgICAvLyBFZGdlIGlzIHdlaXJkIGFuZCByZXR1cm5zIG51bWJlcnNcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodHlwZW9mIGNvbW1hbmRWYWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWJpdHdpc2VcbiAgICAgIHJldHVybiAoXG4gICAgICAgICdyZ2IoJyArXG4gICAgICAgIChjb21tYW5kVmFsdWUgJiAweGZmKSArXG4gICAgICAgICcsICcgK1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWJpdHdpc2VcbiAgICAgICAgKChjb21tYW5kVmFsdWUgJiAweGZmMDApID4+IDgpICtcbiAgICAgICAgJywgJyArXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYml0d2lzZVxuICAgICAgICAoKGNvbW1hbmRWYWx1ZSAmIDB4ZmYwMDAwKSA+PiAxNikgK1xuICAgICAgICAnKSdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gRmlyZWZveCB1c2VzICdUcmFuc3BhcmVudCcgaW5zdGVhZCBvZiBhIGNvbG9yIHZhbHVlXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoY29tbWFuZFZhbHVlLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RyYW5zcGFyZW50Jykge1xuICAgICAgcmV0dXJuIFNUWUxFX1NUQVRFX0RFRkFVTFRTLmJhY2tDb2xvcjtcbiAgICB9XG4gICAgcmV0dXJuIGNvbW1hbmRWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgaGFzTGluayhlZGl0b3JJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYW5jaG9yRWwgPSB0aGlzLmdldFNlbGVjdGVkQW5jaG9yVGFnKGVkaXRvcklkKTtcbiAgICBjb25zdCBjaGlsZEFuY2hvckVscyA9IHRoaXMuZ2V0Q2hpbGRTZWxlY3RlZEFuY2hvclRhZ3MoZWRpdG9ySWQpO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgcmV0dXJuIGNoaWxkQW5jaG9yRWxzLmxlbmd0aCA+IDAgfHwgKCEhYW5jaG9yRWwgJiYgISFhbmNob3JFbC5ocmVmKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UGFyZW50KGVsZW1lbnQ6IEVsZW1lbnQsIHRhZzogc3RyaW5nKTogRWxlbWVudCB7XG4gICAgbGV0IGN1cnJlbnROb2RlID0gZWxlbWVudDtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgY3VycmVudE5vZGUudGFnTmFtZS50b1VwcGVyQ2FzZSgpICE9PSAnQk9EWScpIHtcbiAgICAgIGlmIChjdXJyZW50Tm9kZS50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09IHRhZy50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50Tm9kZTtcbiAgICAgIH1cbiAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUucGFyZW50RWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZWRpdG9yU2VsZWN0ZWQoaWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRvY3VtZW50RWwgPSB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpO1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGlvblNlcnZpY2UuaXNFbGVtZW50U2VsZWN0ZWQoZG9jdW1lbnRFbCwgZG9jdW1lbnRFbC5ib2R5KTtcbiAgfVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHByaXZhdGUgaW5zZXJ0SHRtbEluSUUxMShpZDogc3RyaW5nLCBodG1sOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkb2N1bWVudEVsID0gdGhpcy5nZXRJZnJhbWVEb2N1bWVudEVsKGlkKTtcbiAgICBjb25zdCB3aW5kb3dFbCA9IHRoaXMuZ2V0Q29udGVudFdpbmRvd0VsKGlkKTtcbiAgICBjb25zdCBzZWwgPSB3aW5kb3dFbC5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoc2VsLmdldFJhbmdlQXQgJiYgc2VsLnJhbmdlQ291bnQpIHtcbiAgICAgIGxldCByYW5nZSA9IHNlbC5nZXRSYW5nZUF0KDApO1xuICAgICAgcmFuZ2UuZGVsZXRlQ29udGVudHMoKTtcblxuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudEVsLmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgZWwuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIGxldCBmcmFnID0gZG9jdW1lbnRFbC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG4gICAgICAgIG5vZGUsXG4gICAgICAgIGxhc3ROb2RlO1xuICAgICAgd2hpbGUgKGVsLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgbm9kZSA9IGVsLmZpcnN0Q2hpbGQ7XG4gICAgICAgIGxhc3ROb2RlID0gZnJhZy5hcHBlbmRDaGlsZChub2RlKTtcbiAgICAgIH1cbiAgICAgIHJhbmdlLmluc2VydE5vZGUoZnJhZyk7XG5cbiAgICAgIC8vIFByZXNlcnZlIHRoZSBzZWxlY3Rpb25cbiAgICAgIGlmIChsYXN0Tm9kZSkge1xuICAgICAgICByYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKTtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnRBZnRlcihsYXN0Tm9kZSk7XG4gICAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjbGVhblVwQmxhbmtTdHlsZVRhZ3MoZG9jOiBEb2N1bWVudCk6IHZvaWQge1xuICAgIGNvbnN0IG9ycGhhbkVsZW1lbnRzOiBIVE1MRWxlbWVudFtdID0gQXJyYXkuZnJvbShcbiAgICAgIGRvYy5xdWVyeVNlbGVjdG9yQWxsKCdmb250LHNwYW4sKltzdHlsZT1cIlwiXScpXG4gICAgKTtcbiAgICBmb3IgKGxldCBlbGVtZW50IG9mIG9ycGhhbkVsZW1lbnRzKSB7XG4gICAgICBpZiAoIWVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzdHlsZScpKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCByZW1vdmFibGVFbGVtZW50cyA9IG9ycGhhbkVsZW1lbnRzLmZpbHRlcigoZWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgdGFnTmFtZSA9IGVsZW1lbnQudGFnTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgKHRhZ05hbWUgPT09ICdGT05UJyB8fCB0YWdOYW1lID09PSAnU1BBTicpICYmXG4gICAgICAgIChlbGVtZW50LmF0dHJpYnV0ZXMubGVuZ3RoID09PSAwIHx8ICFlbGVtZW50Lmhhc0NoaWxkTm9kZXMpXG4gICAgICApO1xuICAgIH0pO1xuICAgIGZvciAobGV0IGVsZW1lbnQgb2YgcmVtb3ZhYmxlRWxlbWVudHMpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAocGFyZW50KSB7XG4gICAgICAgIHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGVsZW1lbnQuZmlyc3RDaGlsZCwgZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIENlcnRhaW4gdmFsdWVzIGFyZSBlbmNvZGVkIGluIGh0bWwgYW5kIG5lZWQgdG8gYmUgZGVjb2RlZFxuICBwcml2YXRlIHJlcGxhY2VIdG1sQ29kZXMoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBzdHJcbiAgICAgIC5yZXBsYWNlKC8mbmJzcDsvLCBTdHJpbmcuZnJvbUNoYXJDb2RlKDE2MCkpXG4gICAgICAucmVwbGFjZSgvJmx0Oy9nLCAnPCcpXG4gICAgICAucmVwbGFjZSgvJmd0Oy9nLCAnPicpXG4gICAgICAucmVwbGFjZSgvJmFtcDsvZywgJyYnKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0RWRpdG9yRGlzYWJsZWQoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBmb2N1c2FibGVDaGlsZHJlbjogSFRNTEVsZW1lbnRbXSxcbiAgICB0ZXh0RWRpdG9yTmF0aXZlRWxlbWVudDogYW55LFxuICAgIGRpc2FibGVkOiBib29sZWFuXG4gICk6IHZvaWQge1xuICAgIHRleHRFZGl0b3JOYXRpdmVFbGVtZW50LnN0eWxlLnBvaW50ZXJFdmVudHMgPSBkaXNhYmxlZCA/ICdub25lJyA6ICdhdXRvJztcbiAgICB0ZXh0RWRpdG9yTmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXG4gICAgICAnYXJpYS1kaXNhYmxlZCcsXG4gICAgICBkaXNhYmxlZCA/ICd0cnVlJyA6ICdmYWxzZSdcbiAgICApO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKGZvY3VzYWJsZUNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvY3VzYWJsZUNoaWxkcmVuLmZvckVhY2goKGFGb2N1c2FibGVDaGlsZCkgPT4ge1xuICAgICAgICBhRm9jdXNhYmxlQ2hpbGQudGFiSW5kZXggPSBkaXNhYmxlZCA/IC0xIDogMDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmdldElmcmFtZURvY3VtZW50RWwoaWQpLmJvZHkuc2V0QXR0cmlidXRlKFxuICAgICAgJ2NvbnRlbnRlZGl0YWJsZScsXG4gICAgICBkaXNhYmxlZCA/ICdmYWxzZScgOiAndHJ1ZSdcbiAgICApO1xuICB9XG59XG4iXX0=