@flogeez/angular-tiptap-editor 3.1.3 → 3.1.4

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 (113) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +2 -2
  3. package/esm2022/flogeez-angular-tiptap-editor.mjs +5 -0
  4. package/esm2022/lib/ate-editor.provider.mjs +38 -0
  5. package/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +207 -0
  6. package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +137 -0
  7. package/esm2022/lib/components/bubble-menus/color/ate-color-bubble-menu.component.mjs +365 -0
  8. package/esm2022/lib/components/bubble-menus/image/ate-image-bubble-menu.component.mjs +309 -0
  9. package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +247 -0
  10. package/esm2022/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.mjs +126 -0
  11. package/esm2022/lib/components/bubble-menus/table/ate-table-bubble-menu.component.mjs +271 -0
  12. package/esm2022/lib/components/bubble-menus/text/ate-bubble-menu.component.mjs +272 -0
  13. package/esm2022/lib/components/color-picker/ate-color-picker.component.mjs +123 -0
  14. package/esm2022/lib/components/edit-toggle/ate-edit-toggle.component.mjs +42 -0
  15. package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +1031 -0
  16. package/esm2022/lib/components/editor/ate-block-controls.component.mjs +256 -0
  17. package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +328 -0
  18. package/esm2022/lib/components/toolbar/ate-toolbar.component.mjs +531 -0
  19. package/esm2022/lib/components/ui/ate-button.component.mjs +91 -0
  20. package/esm2022/lib/components/ui/ate-separator.component.mjs +11 -0
  21. package/esm2022/lib/config/ate-editor.config.mjs +133 -0
  22. package/esm2022/lib/config/ate-global-config.token.mjs +6 -0
  23. package/esm2022/lib/config/ate-slash-commands.config.mjs +130 -0
  24. package/esm2022/lib/directives/ate-noop-value-accessor.directive.mjs +40 -0
  25. package/esm2022/lib/directives/ate-tooltip.directive.mjs +138 -0
  26. package/esm2022/lib/extensions/ate-block-controls.extension.mjs +156 -0
  27. package/esm2022/lib/extensions/ate-link-click-behavior.extension.mjs +32 -0
  28. package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +277 -0
  29. package/esm2022/lib/extensions/ate-table.extension.mjs +27 -0
  30. package/esm2022/lib/extensions/ate-tiptap-state.extension.mjs +85 -0
  31. package/esm2022/lib/extensions/ate-upload-progress.extension.mjs +195 -0
  32. package/esm2022/lib/extensions/calculators/ate-discovery.calculator.mjs +62 -0
  33. package/esm2022/lib/extensions/calculators/ate-image.calculator.mjs +8 -0
  34. package/esm2022/lib/extensions/calculators/ate-marks.calculator.mjs +75 -0
  35. package/esm2022/lib/extensions/calculators/ate-selection.calculator.mjs +35 -0
  36. package/esm2022/lib/extensions/calculators/ate-structure.calculator.mjs +34 -0
  37. package/esm2022/lib/extensions/calculators/ate-table.calculator.mjs +38 -0
  38. package/esm2022/lib/models/ate-bubble-menu.model.mjs +53 -0
  39. package/esm2022/lib/models/ate-editor-config.model.mjs +2 -0
  40. package/esm2022/lib/models/ate-editor-state.model.mjs +90 -0
  41. package/esm2022/lib/models/ate-image.model.mjs +2 -0
  42. package/esm2022/lib/models/ate-slash-command.model.mjs +2 -0
  43. package/esm2022/lib/models/ate-toolbar.model.mjs +35 -0
  44. package/esm2022/lib/node-view/ate-angular-node-view.mjs +97 -0
  45. package/esm2022/lib/node-view/ate-injector.registry.mjs +16 -0
  46. package/esm2022/lib/node-view/ate-node-view.factory.mjs +125 -0
  47. package/esm2022/lib/node-view/ate-node-view.models.mjs +2 -0
  48. package/esm2022/lib/node-view/ate-node-view.renderer.mjs +154 -0
  49. package/esm2022/lib/node-view/ate-register-angular-component.mjs +49 -0
  50. package/esm2022/lib/services/ate-color-picker.service.mjs +194 -0
  51. package/esm2022/lib/services/ate-editor-commands.service.mjs +474 -0
  52. package/esm2022/lib/services/ate-i18n.service.mjs +422 -0
  53. package/esm2022/lib/services/ate-image.service.mjs +459 -0
  54. package/esm2022/lib/services/ate-link.service.mjs +99 -0
  55. package/esm2022/lib/utils/ate-color.utils.mjs +60 -0
  56. package/esm2022/public-api.mjs +40 -0
  57. package/fesm2022/flogeez-angular-tiptap-editor.mjs +319 -352
  58. package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
  59. package/index.d.ts +3 -1734
  60. package/lib/ate-editor.provider.d.ts +21 -0
  61. package/lib/components/bubble-menus/base/ate-base-bubble-menu.d.ts +71 -0
  62. package/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.d.ts +60 -0
  63. package/lib/components/bubble-menus/color/ate-color-bubble-menu.component.d.ts +77 -0
  64. package/lib/components/bubble-menus/image/ate-image-bubble-menu.component.d.ts +49 -0
  65. package/lib/components/bubble-menus/link/ate-link-bubble-menu.component.d.ts +55 -0
  66. package/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.d.ts +16 -0
  67. package/lib/components/bubble-menus/table/ate-table-bubble-menu.component.d.ts +25 -0
  68. package/lib/components/bubble-menus/text/ate-bubble-menu.component.d.ts +53 -0
  69. package/lib/components/color-picker/ate-color-picker.component.d.ts +54 -0
  70. package/lib/components/edit-toggle/ate-edit-toggle.component.d.ts +13 -0
  71. package/lib/components/editor/angular-tiptap-editor.component.d.ts +242 -0
  72. package/lib/components/editor/ate-block-controls.component.d.ts +44 -0
  73. package/lib/components/slash-commands/ate-slash-commands.component.d.ts +34 -0
  74. package/lib/components/toolbar/ate-toolbar.component.d.ts +47 -0
  75. package/lib/components/ui/ate-button.component.d.ts +25 -0
  76. package/lib/components/ui/ate-separator.component.d.ts +5 -0
  77. package/lib/config/ate-editor.config.d.ts +19 -0
  78. package/lib/config/ate-global-config.token.d.ts +6 -0
  79. package/lib/config/ate-slash-commands.config.d.ts +41 -0
  80. package/lib/directives/ate-noop-value-accessor.directive.d.ts +13 -0
  81. package/lib/directives/ate-tooltip.directive.d.ts +30 -0
  82. package/lib/extensions/ate-block-controls.extension.d.ts +10 -0
  83. package/lib/extensions/ate-link-click-behavior.extension.d.ts +2 -0
  84. package/lib/extensions/ate-resizable-image.extension.d.ts +27 -0
  85. package/lib/extensions/ate-table.extension.d.ts +2 -0
  86. package/lib/extensions/ate-tiptap-state.extension.d.ts +7 -0
  87. package/lib/extensions/ate-upload-progress.extension.d.ts +7 -0
  88. package/lib/extensions/calculators/ate-discovery.calculator.d.ts +7 -0
  89. package/lib/extensions/calculators/ate-image.calculator.d.ts +2 -0
  90. package/lib/extensions/calculators/ate-marks.calculator.d.ts +2 -0
  91. package/lib/extensions/calculators/ate-selection.calculator.d.ts +2 -0
  92. package/lib/extensions/calculators/ate-structure.calculator.d.ts +2 -0
  93. package/lib/extensions/calculators/ate-table.calculator.d.ts +2 -0
  94. package/lib/models/ate-bubble-menu.model.d.ts +33 -0
  95. package/lib/models/ate-editor-config.model.d.ts +113 -0
  96. package/lib/models/ate-editor-state.model.d.ts +109 -0
  97. package/lib/models/ate-image.model.d.ts +104 -0
  98. package/lib/models/ate-slash-command.model.d.ts +17 -0
  99. package/lib/models/ate-toolbar.model.d.ts +18 -0
  100. package/lib/node-view/ate-angular-node-view.d.ts +115 -0
  101. package/lib/node-view/ate-injector.registry.d.ts +3 -0
  102. package/lib/node-view/ate-node-view.factory.d.ts +10 -0
  103. package/lib/node-view/ate-node-view.models.d.ts +138 -0
  104. package/lib/node-view/ate-node-view.renderer.d.ts +23 -0
  105. package/lib/node-view/ate-register-angular-component.d.ts +35 -0
  106. package/lib/services/ate-color-picker.service.d.ts +65 -0
  107. package/lib/services/ate-editor-commands.service.d.ts +75 -0
  108. package/lib/services/ate-i18n.service.d.ts +406 -0
  109. package/lib/services/ate-image.service.d.ts +82 -0
  110. package/lib/services/ate-link.service.d.ts +42 -0
  111. package/lib/utils/ate-color.utils.d.ts +12 -0
  112. package/package.json +3 -1
  113. package/public-api.d.ts +31 -0
@@ -0,0 +1,277 @@
1
+ import { Node, mergeAttributes, nodeInputRule } from "@tiptap/core";
2
+ export const AteResizableImage = Node.create({
3
+ name: "resizableImage",
4
+ addOptions() {
5
+ return {
6
+ inline: false,
7
+ allowBase64: false,
8
+ HTMLAttributes: {},
9
+ };
10
+ },
11
+ inline() {
12
+ return this.options.inline;
13
+ },
14
+ group() {
15
+ return this.options.inline ? "inline" : "block";
16
+ },
17
+ draggable: true,
18
+ addAttributes() {
19
+ return {
20
+ src: {
21
+ default: null,
22
+ },
23
+ alt: {
24
+ default: null,
25
+ },
26
+ title: {
27
+ default: null,
28
+ },
29
+ width: {
30
+ default: null,
31
+ parseHTML: element => {
32
+ const width = element.getAttribute("width");
33
+ return width ? parseInt(width, 10) : null;
34
+ },
35
+ renderHTML: attributes => {
36
+ if (!attributes["width"]) {
37
+ return {};
38
+ }
39
+ return {
40
+ width: attributes["width"],
41
+ };
42
+ },
43
+ },
44
+ height: {
45
+ default: null,
46
+ parseHTML: element => {
47
+ const height = element.getAttribute("height");
48
+ return height ? parseInt(height, 10) : null;
49
+ },
50
+ renderHTML: attributes => {
51
+ if (!attributes["height"]) {
52
+ return {};
53
+ }
54
+ return {
55
+ height: attributes["height"],
56
+ };
57
+ },
58
+ },
59
+ };
60
+ },
61
+ parseHTML() {
62
+ return [
63
+ {
64
+ tag: "img[src]",
65
+ },
66
+ ];
67
+ },
68
+ renderHTML({ HTMLAttributes }) {
69
+ return ["img", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
70
+ },
71
+ addCommands() {
72
+ return {
73
+ setResizableImage: options => ({ commands }) => {
74
+ return commands.insertContent({
75
+ type: this.name,
76
+ attrs: options,
77
+ }, {
78
+ updateSelection: true,
79
+ });
80
+ },
81
+ updateResizableImage: options => ({ commands }) => {
82
+ return commands.updateAttributes(this.name, options);
83
+ },
84
+ };
85
+ },
86
+ addInputRules() {
87
+ return [
88
+ nodeInputRule({
89
+ find: /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/,
90
+ type: this.type,
91
+ getAttributes: match => {
92
+ const [, alt, src, title] = match;
93
+ return { src, alt, title };
94
+ },
95
+ }),
96
+ ];
97
+ },
98
+ addNodeView() {
99
+ return ({ node, getPos, editor }) => {
100
+ const wrapper = document.createElement("div");
101
+ wrapper.className = "resizable-image-wrapper";
102
+ wrapper.style.display = "block";
103
+ if (node.attrs["textAlign"]) {
104
+ wrapper.style.textAlign = node.attrs["textAlign"];
105
+ wrapper.setAttribute("data-align", node.attrs["textAlign"]);
106
+ }
107
+ const container = document.createElement("div");
108
+ container.className = "resizable-image-container";
109
+ container.style.position = "relative";
110
+ container.style.display = "inline-block";
111
+ const img = document.createElement("img");
112
+ img.src = node.attrs["src"];
113
+ img.alt = node.attrs["alt"] || "";
114
+ img.title = node.attrs["title"] || "";
115
+ img.className = "ate-image";
116
+ img.style.display = "inline-block"; // Ensure it respects container text-align
117
+ if (node.attrs["width"]) {
118
+ img.width = node.attrs["width"];
119
+ }
120
+ if (node.attrs["height"]) {
121
+ img.height = node.attrs["height"];
122
+ }
123
+ wrapper.appendChild(container);
124
+ container.appendChild(img);
125
+ // Allow selection in read-only mode to show bubble menu/download
126
+ img.addEventListener("click", e => {
127
+ if (!editor.isEditable) {
128
+ e.preventDefault();
129
+ e.stopPropagation();
130
+ const pos = getPos();
131
+ if (typeof pos === "number") {
132
+ editor.commands.setNodeSelection(pos);
133
+ editor.view.focus();
134
+ }
135
+ }
136
+ });
137
+ // Add modern resize controls
138
+ const resizeControls = document.createElement("div");
139
+ resizeControls.className = "resize-controls";
140
+ // Create 2 handles (sides only) for a minimalist UI
141
+ const handles = ["w", "e"];
142
+ handles.forEach(direction => {
143
+ const handle = document.createElement("div");
144
+ handle.className = `resize-handle resize-handle-${direction}`;
145
+ handle.setAttribute("data-direction", direction);
146
+ resizeControls.appendChild(handle);
147
+ });
148
+ // Attach controls to container
149
+ container.appendChild(resizeControls);
150
+ // Variables for resizing
151
+ let isResizing = false;
152
+ let startX = 0;
153
+ let startWidth = 0;
154
+ let startHeight = 0;
155
+ let aspectRatio = 1;
156
+ // Calculate aspect ratio
157
+ img.onload = () => {
158
+ aspectRatio = img.naturalWidth / img.naturalHeight;
159
+ };
160
+ // Resizing logic
161
+ const handleMouseDown = (e, direction) => {
162
+ e.preventDefault();
163
+ e.stopPropagation();
164
+ isResizing = true;
165
+ startX = e.clientX;
166
+ // Use current image dimensions instead of initial ones
167
+ startWidth =
168
+ parseInt(img.getAttribute("width") || "0") || node.attrs["width"] || img.naturalWidth;
169
+ startHeight =
170
+ parseInt(img.getAttribute("height") || "0") || node.attrs["height"] || img.naturalHeight;
171
+ // Add resizing class to body
172
+ document.body.classList.add("resizing");
173
+ const handleMouseMove = (e) => {
174
+ if (!isResizing) {
175
+ return;
176
+ }
177
+ const deltaX = e.clientX - startX;
178
+ let newWidth = startWidth;
179
+ let newHeight = startHeight;
180
+ // Resize according to direction
181
+ switch (direction) {
182
+ case "e":
183
+ newWidth = startWidth + deltaX;
184
+ newHeight = newWidth / aspectRatio;
185
+ break;
186
+ case "w":
187
+ newWidth = startWidth - deltaX;
188
+ newHeight = newWidth / aspectRatio;
189
+ break;
190
+ }
191
+ // Limits
192
+ newWidth = Math.max(50, Math.min(2000, newWidth));
193
+ newHeight = Math.max(50, Math.min(2000, newHeight));
194
+ // Update image attributes directly
195
+ img.setAttribute("width", Math.round(newWidth).toString());
196
+ img.setAttribute("height", Math.round(newHeight).toString());
197
+ };
198
+ const handleMouseUp = () => {
199
+ isResizing = false;
200
+ document.body.classList.remove("resizing");
201
+ // Update Tiptap node with new dimensions at the specific position
202
+ const pos = typeof getPos === "function" ? getPos() : undefined;
203
+ if (typeof pos === "number") {
204
+ const finalWidth = parseInt(img.getAttribute("width") || "0");
205
+ const finalHeight = parseInt(img.getAttribute("height") || "0");
206
+ if (finalWidth && finalHeight) {
207
+ editor.view.dispatch(editor.view.state.tr.setNodeMarkup(pos, undefined, {
208
+ ...node.attrs,
209
+ width: finalWidth,
210
+ height: finalHeight,
211
+ }));
212
+ }
213
+ }
214
+ document.removeEventListener("mousemove", handleMouseMove);
215
+ document.removeEventListener("mouseup", handleMouseUp);
216
+ };
217
+ document.addEventListener("mousemove", handleMouseMove);
218
+ document.addEventListener("mouseup", handleMouseUp);
219
+ };
220
+ // Add events to handles
221
+ resizeControls.addEventListener("mousedown", e => {
222
+ const target = e.target;
223
+ if (target.classList.contains("resize-handle")) {
224
+ const direction = target.getAttribute("data-direction");
225
+ if (direction) {
226
+ handleMouseDown(e, direction);
227
+ }
228
+ }
229
+ });
230
+ // Proper selection management via ProseMirror lifecycle
231
+ const selectNode = () => {
232
+ wrapper.classList.add("selected");
233
+ container.classList.add("selected");
234
+ img.classList.add("selected");
235
+ };
236
+ const deselectNode = () => {
237
+ wrapper.classList.remove("selected");
238
+ container.classList.remove("selected");
239
+ img.classList.remove("selected");
240
+ };
241
+ return {
242
+ dom: wrapper,
243
+ selectNode,
244
+ deselectNode,
245
+ update: updatedNode => {
246
+ if (updatedNode.type.name !== "resizableImage") {
247
+ return false;
248
+ }
249
+ img.src = updatedNode.attrs["src"];
250
+ img.alt = updatedNode.attrs["alt"] || "";
251
+ img.title = updatedNode.attrs["title"] || "";
252
+ if (updatedNode.attrs["width"]) {
253
+ img.width = updatedNode.attrs["width"];
254
+ }
255
+ if (updatedNode.attrs["height"]) {
256
+ img.height = updatedNode.attrs["height"];
257
+ }
258
+ if (updatedNode.attrs["textAlign"]) {
259
+ wrapper.style.textAlign = updatedNode.attrs["textAlign"];
260
+ wrapper.setAttribute("data-align", updatedNode.attrs["textAlign"]);
261
+ }
262
+ else {
263
+ wrapper.style.textAlign = "";
264
+ wrapper.removeAttribute("data-align");
265
+ }
266
+ return true;
267
+ },
268
+ stopEvent: (event) => {
269
+ const target = event.target;
270
+ return !!target.closest(".resize-controls");
271
+ },
272
+ ignoreMutation: () => true,
273
+ };
274
+ };
275
+ },
276
+ });
277
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXJlc2l6YWJsZS1pbWFnZS5leHRlbnNpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXRpcHRhcC1lZGl0b3Ivc3JjL2xpYi9leHRlbnNpb25zL2F0ZS1yZXNpemFibGUtaW1hZ2UuZXh0ZW5zaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQTZCcEUsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBMkI7SUFDckUsSUFBSSxFQUFFLGdCQUFnQjtJQUV0QixVQUFVO1FBQ1IsT0FBTztZQUNMLE1BQU0sRUFBRSxLQUFLO1lBQ2IsV0FBVyxFQUFFLEtBQUs7WUFDbEIsY0FBYyxFQUFFLEVBQUU7U0FDbkIsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNO1FBQ0osT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUM3QixDQUFDO0lBRUQsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ2xELENBQUM7SUFFRCxTQUFTLEVBQUUsSUFBSTtJQUVmLGFBQWE7UUFDWCxPQUFPO1lBQ0wsR0FBRyxFQUFFO2dCQUNILE9BQU8sRUFBRSxJQUFJO2FBQ2Q7WUFDRCxHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxFQUFFLElBQUk7YUFDZDtZQUNELEtBQUssRUFBRTtnQkFDTCxPQUFPLEVBQUUsSUFBSTthQUNkO1lBQ0QsS0FBSyxFQUFFO2dCQUNMLE9BQU8sRUFBRSxJQUFJO2dCQUNiLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRTtvQkFDbkIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFD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QVksQ0FBQyxDQUFDO29CQUN4QyxDQUFDO29CQUVELE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUM7Z0JBQ0QsU0FBUyxFQUFFLENBQUMsS0FBWSxFQUFFLEVBQUU7b0JBQzFCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFxQixDQUFDO29CQUMzQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7Z0JBQzlDLENBQUM7Z0JBQ0QsY0FBYyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUk7YUFDM0IsQ0FBQztRQUNKLENBQUMsQ0FBQztJQUNKLENBQUM7Q0FDRixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOb2RlLCBtZXJnZUF0dHJpYnV0ZXMsIG5vZGVJbnB1dFJ1bGUgfSBmcm9tIFwiQHRpcHRhcC9jb3JlXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXRlUmVzaXphYmxlSW1hZ2VPcHRpb25zIHtcbiAgaW5saW5lOiBib29sZWFuO1xuICBhbGxvd0Jhc2U2NDogYm9vbGVhbjtcbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG5kZWNsYXJlIG1vZHVsZSBcIkB0aXB0YXAvY29yZVwiIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICByZXNpemFibGVJbWFnZToge1xuICAgICAgc2V0UmVzaXphYmxlSW1hZ2U6IChvcHRpb25zOiB7XG4gICAgICAgIHNyYzogc3RyaW5nO1xuICAgICAgICBhbHQ/OiBzdHJpbmc7XG4gICAgICAgIHRpdGxlPzogc3RyaW5nO1xuICAgICAgICB3aWR0aD86IG51bWJlcjtcbiAgICAgICAgaGVpZ2h0PzogbnVtYmVyO1xuICAgICAgfSkgPT4gUmV0dXJuVHlwZTtcbiAgICAgIHVwZGF0ZVJlc2l6YWJsZUltYWdlOiAob3B0aW9uczoge1xuICAgICAgICBzcmM/OiBzdHJpbmc7XG4gICAgICAgIGFsdD86IHN0cmluZztcbiAgICAgICAgdGl0bGU/OiBzdHJpbmc7XG4gICAgICAgIHdpZHRoPzogbnVtYmVyO1xuICAgICAgICBoZWlnaHQ/OiBudW1iZXI7XG4gICAgICB9KSA9PiBSZXR1cm5UeXBlO1xuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IEF0ZVJlc2l6YWJsZUltYWdlID0gTm9kZS5jcmVhdGU8QXRlUmVzaXphYmxlSW1hZ2VPcHRpb25zPih7XG4gIG5hbWU6IFwicmVzaXphYmxlSW1hZ2VcIixcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpbmxpbmU6IGZhbHNlLFxuICAgICAgYWxsb3dCYXNlNjQ6IGZhbHNlLFxuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgIH07XG4gIH0sXG5cbiAgaW5saW5lKCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuaW5saW5lO1xuICB9LFxuXG4gIGdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuaW5saW5lID8gXCJpbmxpbmVcIiA6IFwiYmxvY2tcIjtcbiAgfSxcblxuICBkcmFnZ2FibGU6IHRydWUsXG5cbiAgYWRkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3JjOiB7XG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgYWx0OiB7XG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdGl0bGU6IHtcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB3aWR0aDoge1xuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IHdpZHRoID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiKTtcbiAgICAgICAgICByZXR1cm4gd2lkdGggPyBwYXJzZUludCh3aWR0aCwgMTApIDogbnVsbDtcbiAgICAgICAgfSxcbiAgICAgICAgcmVuZGVySFRNTDogYXR0cmlidXRlcyA9PiB7XG4gICAgICAgICAgaWYgKCFhdHRyaWJ1dGVzW1wid2lkdGhcIl0pIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHdpZHRoOiBhdHRyaWJ1dGVzW1wid2lkdGhcIl0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgICAgcGFyc2VIVE1MOiBlbGVtZW50ID0+IHtcbiAgICAgICAgICBjb25zdCBoZWlnaHQgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShcImhlaWdodFwiKTtcbiAgICAgICAgICByZXR1cm4gaGVpZ2h0ID8gcGFyc2VJbnQoaGVpZ2h0LCAxMCkgOiBudWxsO1xuICAgICAgICB9LFxuICAgICAgICByZW5kZXJIVE1MOiBhdHRyaWJ1dGVzID0+IHtcbiAgICAgICAgICBpZiAoIWF0dHJpYnV0ZXNbXCJoZWlnaHRcIl0pIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhlaWdodDogYXR0cmlidXRlc1tcImhlaWdodFwiXSxcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9LFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB0YWc6IFwiaW1nW3NyY11cIixcbiAgICAgIH0sXG4gICAgXTtcbiAgfSxcblxuICByZW5kZXJIVE1MKHsgSFRNTEF0dHJpYnV0ZXMgfSkge1xuICAgIHJldHVybiBbXCJpbWdcIiwgbWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpXTtcbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0UmVzaXphYmxlSW1hZ2U6XG4gICAgICAgIG9wdGlvbnMgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy5pbnNlcnRDb250ZW50KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICAgIGF0dHJzOiBvcHRpb25zLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdXBkYXRlU2VsZWN0aW9uOiB0cnVlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICB1cGRhdGVSZXNpemFibGVJbWFnZTpcbiAgICAgICAgb3B0aW9ucyA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnVwZGF0ZUF0dHJpYnV0ZXModGhpcy5uYW1lLCBvcHRpb25zKTtcbiAgICAgICAgfSxcbiAgICB9O1xuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5vZGVJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiAvIVxcWyguK3w6PyldXFwoKFxcUyspKD86KD86XFxzKylbXCInXShcXFMrKVtcIiddKT9cXCkvLFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICAgIGdldEF0dHJpYnV0ZXM6IG1hdGNoID0+IHtcbiAgICAgICAgICBjb25zdCBbLCBhbHQsIHNyYywgdGl0bGVdID0gbWF0Y2g7XG4gICAgICAgICAgcmV0dXJuIHsgc3JjLCBhbHQsIHRpdGxlIH07XG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdO1xuICB9LFxuXG4gIGFkZE5vZGVWaWV3KCkge1xuICAgIHJldHVybiAoeyBub2RlLCBnZXRQb3MsIGVkaXRvciB9KSA9PiB7XG4gICAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIHdyYXBwZXIuY2xhc3NOYW1lID0gXCJyZXNpemFibGUtaW1hZ2Utd3JhcHBlclwiO1xuICAgICAgd3JhcHBlci5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgaWYgKG5vZGUuYXR0cnNbXCJ0ZXh0QWxpZ25cIl0pIHtcbiAgICAgICAgd3JhcHBlci5zdHlsZS50ZXh0QWxpZ24gPSBub2RlLmF0dHJzW1widGV4dEFsaWduXCJdO1xuICAgICAgICB3cmFwcGVyLnNldEF0dHJpYnV0ZShcImRhdGEtYWxpZ25cIiwgbm9kZS5hdHRyc1tcInRleHRBbGlnblwiXSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBjb250YWluZXIuY2xhc3NOYW1lID0gXCJyZXNpemFibGUtaW1hZ2UtY29udGFpbmVyXCI7XG4gICAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG4gICAgICBjb250YWluZXIuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCI7XG5cbiAgICAgIGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIik7XG4gICAgICBpbWcuc3JjID0gbm9kZS5hdHRyc1tcInNyY1wiXTtcbiAgICAgIGltZy5hbHQgPSBub2RlLmF0dHJzW1wiYWx0XCJdIHx8IFwiXCI7XG4gICAgICBpbWcudGl0bGUgPSBub2RlLmF0dHJzW1widGl0bGVcIl0gfHwgXCJcIjtcbiAgICAgIGltZy5jbGFzc05hbWUgPSBcImF0ZS1pbWFnZVwiO1xuICAgICAgaW1nLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiOyAvLyBFbnN1cmUgaXQgcmVzcGVjdHMgY29udGFpbmVyIHRleHQtYWxpZ25cblxuICAgICAgaWYgKG5vZGUuYXR0cnNbXCJ3aWR0aFwiXSkge1xuICAgICAgICBpbWcud2lkdGggPSBub2RlLmF0dHJzW1wid2lkdGhcIl07XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5hdHRyc1tcImhlaWdodFwiXSkge1xuICAgICAgICBpbWcuaGVpZ2h0ID0gbm9kZS5hdHRyc1tcImhlaWdodFwiXTtcbiAgICAgIH1cblxuICAgICAgd3JhcHBlci5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGltZyk7XG5cbiAgICAgIC8vIEFsbG93IHNlbGVjdGlvbiBpbiByZWFkLW9ubHkgbW9kZSB0byBzaG93IGJ1YmJsZSBtZW51L2Rvd25sb2FkXG4gICAgICBpbWcuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGUgPT4ge1xuICAgICAgICBpZiAoIWVkaXRvci5pc0VkaXRhYmxlKSB7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgY29uc3QgcG9zID0gZ2V0UG9zKCk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb3MgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGVkaXRvci5jb21tYW5kcy5zZXROb2RlU2VsZWN0aW9uKHBvcyk7XG4gICAgICAgICAgICBlZGl0b3Iudmlldy5mb2N1cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIEFkZCBtb2Rlcm4gcmVzaXplIGNvbnRyb2xzXG4gICAgICBjb25zdCByZXNpemVDb250cm9scyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICByZXNpemVDb250cm9scy5jbGFzc05hbWUgPSBcInJlc2l6ZS1jb250cm9sc1wiO1xuXG4gICAgICAvLyBDcmVhdGUgMiBoYW5kbGVzIChzaWRlcyBvbmx5KSBmb3IgYSBtaW5pbWFsaXN0IFVJXG4gICAgICBjb25zdCBoYW5kbGVzID0gW1wid1wiLCBcImVcIl07XG4gICAgICBoYW5kbGVzLmZvckVhY2goZGlyZWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgaGFuZGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgaGFuZGxlLmNsYXNzTmFtZSA9IGByZXNpemUtaGFuZGxlIHJlc2l6ZS1oYW5kbGUtJHtkaXJlY3Rpb259YDtcbiAgICAgICAgaGFuZGxlLnNldEF0dHJpYnV0ZShcImRhdGEtZGlyZWN0aW9uXCIsIGRpcmVjdGlvbik7XG4gICAgICAgIHJlc2l6ZUNvbnRyb2xzLmFwcGVuZENoaWxkKGhhbmRsZSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gQXR0YWNoIGNvbnRyb2xzIHRvIGNvbnRhaW5lclxuICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHJlc2l6ZUNvbnRyb2xzKTtcblxuICAgICAgLy8gVmFyaWFibGVzIGZvciByZXNpemluZ1xuICAgICAgbGV0IGlzUmVzaXppbmcgPSBmYWxzZTtcbiAgICAgIGxldCBzdGFydFggPSAwO1xuICAgICAgbGV0IHN0YXJ0V2lkdGggPSAwO1xuICAgICAgbGV0IHN0YXJ0SGVpZ2h0ID0gMDtcbiAgICAgIGxldCBhc3BlY3RSYXRpbyA9IDE7XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBhc3BlY3QgcmF0aW9cbiAgICAgIGltZy5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIGFzcGVjdFJhdGlvID0gaW1nLm5hdHVyYWxXaWR0aCAvIGltZy5uYXR1cmFsSGVpZ2h0O1xuICAgICAgfTtcblxuICAgICAgLy8gUmVzaXppbmcgbG9naWNcbiAgICAgIGNvbnN0IGhhbmRsZU1vdXNlRG93biA9IChlOiBNb3VzZUV2ZW50LCBkaXJlY3Rpb246IHN0cmluZykgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgaXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgIHN0YXJ0WCA9IGUuY2xpZW50WDtcblxuICAgICAgICAvLyBVc2UgY3VycmVudCBpbWFnZSBkaW1lbnNpb25zIGluc3RlYWQgb2YgaW5pdGlhbCBvbmVzXG4gICAgICAgIHN0YXJ0V2lkdGggPVxuICAgICAgICAgIHBhcnNlSW50KGltZy5nZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiKSB8fCBcIjBcIikgfHwgbm9kZS5hdHRyc1tcIndpZHRoXCJdIHx8IGltZy5uYXR1cmFsV2lkdGg7XG4gICAgICAgIHN0YXJ0SGVpZ2h0ID1cbiAgICAgICAgICBwYXJzZUludChpbWcuZ2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIpIHx8IFwiMFwiKSB8fCBub2RlLmF0dHJzW1wiaGVpZ2h0XCJdIHx8IGltZy5uYXR1cmFsSGVpZ2h0O1xuXG4gICAgICAgIC8vIEFkZCByZXNpemluZyBjbGFzcyB0byBib2R5XG4gICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChcInJlc2l6aW5nXCIpO1xuXG4gICAgICAgIGNvbnN0IGhhbmRsZU1vdXNlTW92ZSA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgaWYgKCFpc1Jlc2l6aW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZGVsdGFYID0gZS5jbGllbnRYIC0gc3RhcnRYO1xuXG4gICAgICAgICAgbGV0IG5ld1dpZHRoID0gc3RhcnRXaWR0aDtcbiAgICAgICAgICBsZXQgbmV3SGVpZ2h0ID0gc3RhcnRIZWlnaHQ7XG5cbiAgICAgICAgICAvLyBSZXNpemUgYWNjb3JkaW5nIHRvIGRpcmVjdGlvblxuICAgICAgICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICAgICAgICBjYXNlIFwiZVwiOlxuICAgICAgICAgICAgICBuZXdXaWR0aCA9IHN0YXJ0V2lkdGggKyBkZWx0YVg7XG4gICAgICAgICAgICAgIG5ld0hlaWdodCA9IG5ld1dpZHRoIC8gYXNwZWN0UmF0aW87XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIndcIjpcbiAgICAgICAgICAgICAgbmV3V2lkdGggPSBzdGFydFdpZHRoIC0gZGVsdGFYO1xuICAgICAgICAgICAgICBuZXdIZWlnaHQgPSBuZXdXaWR0aCAvIGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBMaW1pdHNcbiAgICAgICAgICBuZXdXaWR0aCA9IE1hdGgubWF4KDUwLCBNYXRoLm1pbigyMDAwLCBuZXdXaWR0aCkpO1xuICAgICAgICAgIG5ld0hlaWdodCA9IE1hdGgubWF4KDUwLCBNYXRoLm1pbigyMDAwLCBuZXdIZWlnaHQpKTtcblxuICAgICAgICAgIC8vIFVwZGF0ZSBpbWFnZSBhdHRyaWJ1dGVzIGRpcmVjdGx5XG4gICAgICAgICAgaW1nLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIE1hdGgucm91bmQobmV3V2lkdGgpLnRvU3RyaW5nKCkpO1xuICAgICAgICAgIGltZy5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgTWF0aC5yb3VuZChuZXdIZWlnaHQpLnRvU3RyaW5nKCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGhhbmRsZU1vdXNlVXAgPSAoKSA9PiB7XG4gICAgICAgICAgaXNSZXNpemluZyA9IGZhbHNlO1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcInJlc2l6aW5nXCIpO1xuXG4gICAgICAgICAgLy8gVXBkYXRlIFRpcHRhcCBub2RlIHdpdGggbmV3IGRpbWVuc2lvbnMgYXQgdGhlIHNwZWNpZmljIHBvc2l0aW9uXG4gICAgICAgICAgY29uc3QgcG9zID0gdHlwZW9mIGdldFBvcyA9PT0gXCJmdW5jdGlvblwiID8gZ2V0UG9zKCkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb3MgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbmFsV2lkdGggPSBwYXJzZUludChpbWcuZ2V0QXR0cmlidXRlKFwid2lkdGhcIikgfHwgXCIwXCIpO1xuICAgICAgICAgICAgY29uc3QgZmluYWxIZWlnaHQgPSBwYXJzZUludChpbWcuZ2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIpIHx8IFwiMFwiKTtcblxuICAgICAgICAgICAgaWYgKGZpbmFsV2lkdGggJiYgZmluYWxIZWlnaHQpIHtcbiAgICAgICAgICAgICAgZWRpdG9yLnZpZXcuZGlzcGF0Y2goXG4gICAgICAgICAgICAgICAgZWRpdG9yLnZpZXcuc3RhdGUudHIuc2V0Tm9kZU1hcmt1cChwb3MsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgICAgICAgLi4ubm9kZS5hdHRycyxcbiAgICAgICAgICAgICAgICAgIHdpZHRoOiBmaW5hbFdpZHRoLFxuICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBmaW5hbEhlaWdodCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgaGFuZGxlTW91c2VNb3ZlKTtcbiAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBoYW5kbGVNb3VzZVVwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIGhhbmRsZU1vdXNlTW92ZSk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIGhhbmRsZU1vdXNlVXApO1xuICAgICAgfTtcblxuICAgICAgLy8gQWRkIGV2ZW50cyB0byBoYW5kbGVzXG4gICAgICByZXNpemVDb250cm9scy5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIGUgPT4ge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKHRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoXCJyZXNpemUtaGFuZGxlXCIpKSB7XG4gICAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gdGFyZ2V0LmdldEF0dHJpYnV0ZShcImRhdGEtZGlyZWN0aW9uXCIpO1xuICAgICAgICAgIGlmIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgIGhhbmRsZU1vdXNlRG93bihlLCBkaXJlY3Rpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFByb3BlciBzZWxlY3Rpb24gbWFuYWdlbWVudCB2aWEgUHJvc2VNaXJyb3IgbGlmZWN5Y2xlXG4gICAgICBjb25zdCBzZWxlY3ROb2RlID0gKCkgPT4ge1xuICAgICAgICB3cmFwcGVyLmNsYXNzTGlzdC5hZGQoXCJzZWxlY3RlZFwiKTtcbiAgICAgICAgY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoXCJzZWxlY3RlZFwiKTtcbiAgICAgICAgaW1nLmNsYXNzTGlzdC5hZGQoXCJzZWxlY3RlZFwiKTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGRlc2VsZWN0Tm9kZSA9ICgpID0+IHtcbiAgICAgICAgd3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIik7XG4gICAgICAgIGNvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIik7XG4gICAgICAgIGltZy5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIik7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkb206IHdyYXBwZXIsXG4gICAgICAgIHNlbGVjdE5vZGUsXG4gICAgICAgIGRlc2VsZWN0Tm9kZSxcbiAgICAgICAgdXBkYXRlOiB1cGRhdGVkTm9kZSA9PiB7XG4gICAgICAgICAgaWYgKHVwZGF0ZWROb2RlLnR5cGUubmFtZSAhPT0gXCJyZXNpemFibGVJbWFnZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW1nLnNyYyA9IHVwZGF0ZWROb2RlLmF0dHJzW1wic3JjXCJdO1xuICAgICAgICAgIGltZy5hbHQgPSB1cGRhdGVkTm9kZS5hdHRyc1tcImFsdFwiXSB8fCBcIlwiO1xuICAgICAgICAgIGltZy50aXRsZSA9IHVwZGF0ZWROb2RlLmF0dHJzW1widGl0bGVcIl0gfHwgXCJcIjtcblxuICAgICAgICAgIGlmICh1cGRhdGVkTm9kZS5hdHRyc1tcIndpZHRoXCJdKSB7XG4gICAgICAgICAgICBpbWcud2lkdGggPSB1cGRhdGVkTm9kZS5hdHRyc1tcIndpZHRoXCJdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodXBkYXRlZE5vZGUuYXR0cnNbXCJoZWlnaHRcIl0pIHtcbiAgICAgICAgICAgIGltZy5oZWlnaHQgPSB1cGRhdGVkTm9kZS5hdHRyc1tcImhlaWdodFwiXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodXBkYXRlZE5vZGUuYXR0cnNbXCJ0ZXh0QWxpZ25cIl0pIHtcbiAgICAgICAgICAgIHdyYXBwZXIuc3R5bGUudGV4dEFsaWduID0gdXBkYXRlZE5vZGUuYXR0cnNbXCJ0ZXh0QWxpZ25cIl07XG4gICAgICAgICAgICB3cmFwcGVyLnNldEF0dHJpYnV0ZShcImRhdGEtYWxpZ25cIiwgdXBkYXRlZE5vZGUuYXR0cnNbXCJ0ZXh0QWxpZ25cIl0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3cmFwcGVyLnN0eWxlLnRleHRBbGlnbiA9IFwiXCI7XG4gICAgICAgICAgICB3cmFwcGVyLnJlbW92ZUF0dHJpYnV0ZShcImRhdGEtYWxpZ25cIik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3BFdmVudDogKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICByZXR1cm4gISF0YXJnZXQuY2xvc2VzdChcIi5yZXNpemUtY29udHJvbHNcIik7XG4gICAgICAgIH0sXG4gICAgICAgIGlnbm9yZU11dGF0aW9uOiAoKSA9PiB0cnVlLFxuICAgICAgfTtcbiAgICB9O1xuICB9LFxufSk7XG4iXX0=
@@ -0,0 +1,27 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Table, TableRow, TableCell, TableHeader } from "@tiptap/extension-table";
3
+ export const AteTableExtension = Extension.create({
4
+ name: "tableExtension",
5
+ addExtensions() {
6
+ return [
7
+ Table.configure({
8
+ resizable: true,
9
+ handleWidth: 5,
10
+ cellMinWidth: 100,
11
+ allowTableNodeSelection: true,
12
+ }),
13
+ TableRow,
14
+ TableHeader.configure({
15
+ HTMLAttributes: {
16
+ class: "table-header",
17
+ },
18
+ }),
19
+ TableCell.configure({
20
+ HTMLAttributes: {
21
+ class: "table-cell",
22
+ },
23
+ }),
24
+ ];
25
+ },
26
+ });
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXRhYmxlLmV4dGVuc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2V4dGVuc2lvbnMvYXRlLXRhYmxlLmV4dGVuc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVsRixNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQ2hELElBQUksRUFBRSxnQkFBZ0I7SUFFdEIsYUFBYTtRQUNYLE9BQU87WUFDTCxLQUFLLENBQUMsU0FBUyxDQUFDO2dCQUNkLFNBQVMsRUFBRSxJQUFJO2dCQUNmLFdBQVcsRUFBRSxDQUFDO2dCQUNkLFlBQVksRUFBRSxHQUFHO2dCQUNqQix1QkFBdUIsRUFBRSxJQUFJO2FBQzlCLENBQUM7WUFDRixRQUFRO1lBQ1IsV0FBVyxDQUFDLFNBQVMsQ0FBQztnQkFDcEIsY0FBYyxFQUFFO29CQUNkLEtBQUssRUFBRSxjQUFjO2lCQUN0QjthQUNGLENBQUM7WUFDRixTQUFTLENBQUMsU0FBUyxDQUFDO2dCQUNsQixjQUFjLEVBQUU7b0JBQ2QsS0FBSyxFQUFFLFlBQVk7aUJBQ3BCO2FBQ0YsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSBcIkB0aXB0YXAvY29yZVwiO1xuaW1wb3J0IHsgVGFibGUsIFRhYmxlUm93LCBUYWJsZUNlbGwsIFRhYmxlSGVhZGVyIH0gZnJvbSBcIkB0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlXCI7XG5cbmV4cG9ydCBjb25zdCBBdGVUYWJsZUV4dGVuc2lvbiA9IEV4dGVuc2lvbi5jcmVhdGUoe1xuICBuYW1lOiBcInRhYmxlRXh0ZW5zaW9uXCIsXG5cbiAgYWRkRXh0ZW5zaW9ucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgVGFibGUuY29uZmlndXJlKHtcbiAgICAgICAgcmVzaXphYmxlOiB0cnVlLFxuICAgICAgICBoYW5kbGVXaWR0aDogNSxcbiAgICAgICAgY2VsbE1pbldpZHRoOiAxMDAsXG4gICAgICAgIGFsbG93VGFibGVOb2RlU2VsZWN0aW9uOiB0cnVlLFxuICAgICAgfSksXG4gICAgICBUYWJsZVJvdyxcbiAgICAgIFRhYmxlSGVhZGVyLmNvbmZpZ3VyZSh7XG4gICAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgY2xhc3M6IFwidGFibGUtaGVhZGVyXCIsXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIFRhYmxlQ2VsbC5jb25maWd1cmUoe1xuICAgICAgICBIVE1MQXR0cmlidXRlczoge1xuICAgICAgICAgIGNsYXNzOiBcInRhYmxlLWNlbGxcIixcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF07XG4gIH0sXG59KTtcbiJdfQ==
@@ -0,0 +1,85 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
3
+ import { ATE_INITIAL_EDITOR_STATE, } from "../models/ate-editor-state.model";
4
+ /**
5
+ * High-performance flat property merger.
6
+ * Processes sub-objects (marks, can, nodes) property by property.
7
+ */
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ function fastMerge(target, source) {
10
+ if (!source) {
11
+ return;
12
+ }
13
+ for (const key in source) {
14
+ const sourceVal = source[key];
15
+ // If the value is an object (marks, can, nodes, selection)
16
+ if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal)) {
17
+ if (!target[key]) {
18
+ target[key] = {};
19
+ }
20
+ // Merge internal properties
21
+ for (const subKey in sourceVal) {
22
+ const subVal = sourceVal[subKey];
23
+ // TRUE priority rule for boolean state categories
24
+ if (typeof subVal === "boolean" && (key === "marks" || key === "can" || key === "nodes")) {
25
+ target[key][subKey] = target[key][subKey] || subVal;
26
+ }
27
+ else {
28
+ target[key][subKey] = subVal;
29
+ }
30
+ }
31
+ }
32
+ else {
33
+ // Simple value (isFocused, isEditable)
34
+ target[key] = sourceVal;
35
+ }
36
+ }
37
+ }
38
+ function createFreshSnapshot() {
39
+ return JSON.parse(JSON.stringify(ATE_INITIAL_EDITOR_STATE));
40
+ }
41
+ export const AteTiptapStateExtension = Extension.create({
42
+ name: "ateTiptapState",
43
+ addOptions() {
44
+ return {
45
+ onUpdate: undefined,
46
+ calculators: [],
47
+ };
48
+ },
49
+ addProseMirrorPlugins() {
50
+ return [
51
+ new Plugin({
52
+ key: new PluginKey("tiptapState"),
53
+ view: () => ({
54
+ update: _view => {
55
+ const { editor } = this;
56
+ if (!editor) {
57
+ return;
58
+ }
59
+ const snapshot = createFreshSnapshot();
60
+ const calcs = this.options.calculators;
61
+ for (const calculator of calcs) {
62
+ try {
63
+ const partial = calculator(editor);
64
+ fastMerge(snapshot, partial);
65
+ }
66
+ catch (e) {
67
+ console.error("TiptapStateExtension: Calculator error", e);
68
+ }
69
+ }
70
+ if (this.options.onUpdate) {
71
+ this.options.onUpdate(snapshot);
72
+ }
73
+ },
74
+ }),
75
+ }),
76
+ ];
77
+ },
78
+ onFocus() {
79
+ this.editor.view.dispatch(this.editor.state.tr.setMeta("tiptapStateForceUpdate", true));
80
+ },
81
+ onBlur() {
82
+ this.editor.view.dispatch(this.editor.state.tr.setMeta("tiptapStateForceUpdate", true));
83
+ },
84
+ });
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXRpcHRhcC1zdGF0ZS5leHRlbnNpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXRpcHRhcC1lZGl0b3Ivc3JjL2xpYi9leHRlbnNpb25zL2F0ZS10aXB0YXAtc3RhdGUuZXh0ZW5zaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRCxPQUFPLEVBRUwsd0JBQXdCLEdBRXpCLE1BQU0sa0NBQWtDLENBQUM7QUFPMUM7OztHQUdHO0FBQ0gsOERBQThEO0FBQzlELFNBQVMsU0FBUyxDQUFDLE1BQVcsRUFBRSxNQUFXO0lBQ3pDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE9BQU87SUFDVCxDQUFDO0lBRUQsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUN6QixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFOUIsMkRBQTJEO1FBQzNELElBQUksU0FBUyxLQUFLLElBQUksSUFBSSxPQUFPLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDckYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNqQixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ25CLENBQUM7WUFFRCw0QkFBNEI7WUFDNUIsS0FBSyxNQUFNLE1BQU0sSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNqQyxrREFBa0Q7Z0JBQ2xELElBQUksT0FBTyxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsR0FBRyxLQUFLLE9BQU8sSUFBSSxHQUFHLEtBQUssS0FBSyxJQUFJLEdBQUcsS0FBSyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUN6RixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQztnQkFDdEQsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUM7Z0JBQy9CLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTix1Q0FBdUM7WUFDdkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLG1CQUFtQjtJQUMxQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7QUFDOUQsQ0FBQztBQUVELE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQXdCO0lBQzdFLElBQUksRUFBRSxnQkFBZ0I7SUFFdEIsVUFBVTtRQUNSLE9BQU87WUFDTCxRQUFRLEVBQUUsU0FBUztZQUNuQixXQUFXLEVBQUUsRUFBRTtTQUNoQixDQUFDO0lBQ0osQ0FBQztJQUVELHFCQUFxQjtRQUNuQixPQUFPO1lBQ0wsSUFBSSxNQUFNLENBQUM7Z0JBQ1QsR0FBRyxFQUFFLElBQUksU0FBUyxDQUFDLGFBQWEsQ0FBQztnQkFDakMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7b0JBQ1gsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUFFO3dCQUNkLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUM7d0JBQ3hCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzs0QkFDWixPQUFPO3dCQUNULENBQUM7d0JBRUQsTUFBTSxRQUFRLEdBQUcsbUJBQW1CLEVBQUUsQ0FBQzt3QkFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7d0JBRXZDLEtBQUssTUFBTSxVQUFVLElBQUksS0FBSyxFQUFFLENBQUM7NEJBQy9CLElBQUksQ0FBQztnQ0FDSCxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7Z0NBQ25DLFNBQVMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7NEJBQy9CLENBQUM7NEJBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQ0FDWCxPQUFPLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxFQUFFLENBQUMsQ0FBQyxDQUFDOzRCQUM3RCxDQUFDO3dCQUNILENBQUM7d0JBRUQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDOzRCQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDbEMsQ0FBQztvQkFDSCxDQUFDO2lCQUNGLENBQUM7YUFDSCxDQUFDO1NBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLHdCQUF3QixFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDMUYsQ0FBQztDQUNGLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gXCJAdGlwdGFwL2NvcmVcIjtcbmltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5IH0gZnJvbSBcIkB0aXB0YXAvcG0vc3RhdGVcIjtcbmltcG9ydCB7XG4gIEF0ZUVkaXRvclN0YXRlU25hcHNob3QsXG4gIEFURV9JTklUSUFMX0VESVRPUl9TVEFURSxcbiAgQXRlU3RhdGVDYWxjdWxhdG9yLFxufSBmcm9tIFwiLi4vbW9kZWxzL2F0ZS1lZGl0b3Itc3RhdGUubW9kZWxcIjtcblxuZXhwb3J0IGludGVyZmFjZSBBdGVUaXB0YXBTdGF0ZU9wdGlvbnMge1xuICBvblVwZGF0ZT86IChzdGF0ZTogQXRlRWRpdG9yU3RhdGVTbmFwc2hvdCkgPT4gdm9pZDtcbiAgY2FsY3VsYXRvcnM6IEF0ZVN0YXRlQ2FsY3VsYXRvcltdO1xufVxuXG4vKipcbiAqIEhpZ2gtcGVyZm9ybWFuY2UgZmxhdCBwcm9wZXJ0eSBtZXJnZXIuXG4gKiBQcm9jZXNzZXMgc3ViLW9iamVjdHMgKG1hcmtzLCBjYW4sIG5vZGVzKSBwcm9wZXJ0eSBieSBwcm9wZXJ0eS5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbmZ1bmN0aW9uIGZhc3RNZXJnZSh0YXJnZXQ6IGFueSwgc291cmNlOiBhbnkpIHtcbiAgaWYgKCFzb3VyY2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcbiAgICBjb25zdCBzb3VyY2VWYWwgPSBzb3VyY2Vba2V5XTtcblxuICAgIC8vIElmIHRoZSB2YWx1ZSBpcyBhbiBvYmplY3QgKG1hcmtzLCBjYW4sIG5vZGVzLCBzZWxlY3Rpb24pXG4gICAgaWYgKHNvdXJjZVZhbCAhPT0gbnVsbCAmJiB0eXBlb2Ygc291cmNlVmFsID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHNvdXJjZVZhbCkpIHtcbiAgICAgIGlmICghdGFyZ2V0W2tleV0pIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSB7fTtcbiAgICAgIH1cblxuICAgICAgLy8gTWVyZ2UgaW50ZXJuYWwgcHJvcGVydGllc1xuICAgICAgZm9yIChjb25zdCBzdWJLZXkgaW4gc291cmNlVmFsKSB7XG4gICAgICAgIGNvbnN0IHN1YlZhbCA9IHNvdXJjZVZhbFtzdWJLZXldO1xuICAgICAgICAvLyBUUlVFIHByaW9yaXR5IHJ1bGUgZm9yIGJvb2xlYW4gc3RhdGUgY2F0ZWdvcmllc1xuICAgICAgICBpZiAodHlwZW9mIHN1YlZhbCA9PT0gXCJib29sZWFuXCIgJiYgKGtleSA9PT0gXCJtYXJrc1wiIHx8IGtleSA9PT0gXCJjYW5cIiB8fCBrZXkgPT09IFwibm9kZXNcIikpIHtcbiAgICAgICAgICB0YXJnZXRba2V5XVtzdWJLZXldID0gdGFyZ2V0W2tleV1bc3ViS2V5XSB8fCBzdWJWYWw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGFyZ2V0W2tleV1bc3ViS2V5XSA9IHN1YlZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTaW1wbGUgdmFsdWUgKGlzRm9jdXNlZCwgaXNFZGl0YWJsZSlcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlVmFsO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVGcmVzaFNuYXBzaG90KCk6IEF0ZUVkaXRvclN0YXRlU25hcHNob3Qge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShBVEVfSU5JVElBTF9FRElUT1JfU1RBVEUpKTtcbn1cblxuZXhwb3J0IGNvbnN0IEF0ZVRpcHRhcFN0YXRlRXh0ZW5zaW9uID0gRXh0ZW5zaW9uLmNyZWF0ZTxBdGVUaXB0YXBTdGF0ZU9wdGlvbnM+KHtcbiAgbmFtZTogXCJhdGVUaXB0YXBTdGF0ZVwiLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9uVXBkYXRlOiB1bmRlZmluZWQsXG4gICAgICBjYWxjdWxhdG9yczogW10sXG4gICAgfTtcbiAgfSxcblxuICBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoXCJ0aXB0YXBTdGF0ZVwiKSxcbiAgICAgICAgdmlldzogKCkgPT4gKHtcbiAgICAgICAgICB1cGRhdGU6IF92aWV3ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzO1xuICAgICAgICAgICAgaWYgKCFlZGl0b3IpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGNyZWF0ZUZyZXNoU25hcHNob3QoKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbGNzID0gdGhpcy5vcHRpb25zLmNhbGN1bGF0b3JzO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNhbGN1bGF0b3Igb2YgY2FsY3MpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsID0gY2FsY3VsYXRvcihlZGl0b3IpO1xuICAgICAgICAgICAgICAgIGZhc3RNZXJnZShzbmFwc2hvdCwgcGFydGlhbCk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiVGlwdGFwU3RhdGVFeHRlbnNpb246IENhbGN1bGF0b3IgZXJyb3JcIiwgZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5vblVwZGF0ZSkge1xuICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMub25VcGRhdGUoc25hcHNob3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSksXG4gICAgXTtcbiAgfSxcblxuICBvbkZvY3VzKCkge1xuICAgIHRoaXMuZWRpdG9yLnZpZXcuZGlzcGF0Y2godGhpcy5lZGl0b3Iuc3RhdGUudHIuc2V0TWV0YShcInRpcHRhcFN0YXRlRm9yY2VVcGRhdGVcIiwgdHJ1ZSkpO1xuICB9LFxuXG4gIG9uQmx1cigpIHtcbiAgICB0aGlzLmVkaXRvci52aWV3LmRpc3BhdGNoKHRoaXMuZWRpdG9yLnN0YXRlLnRyLnNldE1ldGEoXCJ0aXB0YXBTdGF0ZUZvcmNlVXBkYXRlXCIsIHRydWUpKTtcbiAgfSxcbn0pO1xuIl19