@copilotkitnext/angular 0.0.1 → 0.0.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 (171) hide show
  1. package/README.md +248 -0
  2. package/dist/README.md +248 -0
  3. package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
  4. package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
  5. package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
  6. package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
  7. package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
  8. package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
  9. package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
  10. package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
  11. package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
  12. package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
  13. package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
  14. package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
  15. package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
  16. package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
  17. package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
  18. package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
  19. package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
  20. package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
  21. package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
  22. package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
  23. package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
  24. package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
  25. package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
  26. package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
  27. package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
  28. package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
  29. package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
  30. package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
  31. package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
  32. package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
  33. package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
  34. package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
  35. package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
  36. package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
  37. package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
  38. package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
  39. package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
  40. package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
  41. package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
  42. package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
  43. package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
  44. package/dist/esm2022/core/copilotkit.service.mjs +430 -0
  45. package/dist/esm2022/core/copilotkit.types.mjs +12 -0
  46. package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
  47. package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
  48. package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
  49. package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
  50. package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +130 -0
  51. package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +266 -0
  52. package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
  53. package/dist/esm2022/index.mjs +70 -0
  54. package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
  55. package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
  56. package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
  57. package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
  58. package/dist/esm2022/lib/utils.mjs +10 -0
  59. package/dist/esm2022/services/resize-observer.service.mjs +152 -0
  60. package/dist/esm2022/services/scroll-position.service.mjs +124 -0
  61. package/dist/esm2022/types/frontend-tool.mjs +2 -0
  62. package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
  63. package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
  64. package/dist/esm2022/utils/agent.utils.mjs +204 -0
  65. package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
  66. package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
  67. package/dist/esm2022/utils/frontend-tool.utils.mjs +228 -0
  68. package/dist/esm2022/utils/human-in-the-loop.utils.mjs +296 -0
  69. package/dist/fesm2022/copilotkitnext-angular.mjs +163 -164
  70. package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
  71. package/dist/styles.css +0 -27
  72. package/package.json +23 -20
  73. package/vitest.config.mts +32 -21
  74. package/.turbo/turbo-build.log +0 -39
  75. package/.turbo/turbo-check-types.log +0 -0
  76. package/.turbo/turbo-test.log +0 -71
  77. package/README-agent-context.md +0 -310
  78. package/ng-package.json +0 -19
  79. package/slots.md +0 -331
  80. package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
  81. package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
  82. package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
  83. package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
  84. package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
  85. package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
  86. package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
  87. package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
  88. package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
  89. package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
  90. package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
  91. package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
  92. package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
  93. package/src/components/chat/copilot-chat-input.component.ts +0 -512
  94. package/src/components/chat/copilot-chat-input.types.ts +0 -148
  95. package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
  96. package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
  97. package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
  98. package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
  99. package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
  100. package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
  101. package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
  102. package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
  103. package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
  104. package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
  105. package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
  106. package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
  107. package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
  108. package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
  109. package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
  110. package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
  111. package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
  112. package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
  113. package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
  114. package/src/components/chat/copilot-chat-view.component.ts +0 -420
  115. package/src/components/chat/copilot-chat-view.types.ts +0 -52
  116. package/src/components/chat/copilot-chat.component.ts +0 -232
  117. package/src/components/copilotkit-tool-render.component.ts +0 -169
  118. package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
  119. package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
  120. package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
  121. package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
  122. package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
  123. package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
  124. package/src/core/copilotkit.providers.ts +0 -59
  125. package/src/core/copilotkit.service.ts +0 -542
  126. package/src/core/copilotkit.types.ts +0 -132
  127. package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
  128. package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
  129. package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
  130. package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
  131. package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
  132. package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
  133. package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
  134. package/src/directives/copilotkit-agent-context.directive.ts +0 -138
  135. package/src/directives/copilotkit-agent.directive.ts +0 -225
  136. package/src/directives/copilotkit-chat-config.directive.ts +0 -241
  137. package/src/directives/copilotkit-config.directive.ts +0 -81
  138. package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
  139. package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
  140. package/src/directives/stick-to-bottom.directive.ts +0 -204
  141. package/src/index.ts +0 -105
  142. package/src/lib/directives/tooltip.directive.ts +0 -292
  143. package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
  144. package/src/lib/slots/copilot-slot.component.ts +0 -135
  145. package/src/lib/slots/index.ts +0 -3
  146. package/src/lib/slots/slot.types.ts +0 -64
  147. package/src/lib/slots/slot.utils.ts +0 -289
  148. package/src/lib/utils.ts +0 -10
  149. package/src/public-api.ts +0 -1
  150. package/src/services/resize-observer.service.ts +0 -181
  151. package/src/services/scroll-position.service.ts +0 -169
  152. package/src/styles/globals.css +0 -266
  153. package/src/styles/index.css +0 -3
  154. package/src/test-setup.ts +0 -15
  155. package/src/testing/index.ts +0 -3
  156. package/src/testing/testing.utils.ts +0 -248
  157. package/src/types/frontend-tool.ts +0 -44
  158. package/src/types/human-in-the-loop.ts +0 -52
  159. package/src/utils/__tests__/agent.utils.spec.ts +0 -234
  160. package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
  161. package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
  162. package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
  163. package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
  164. package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
  165. package/src/utils/agent-context.utils.ts +0 -133
  166. package/src/utils/agent.utils.ts +0 -239
  167. package/src/utils/chat-config.utils.ts +0 -221
  168. package/src/utils/copilotkit.utils.ts +0 -20
  169. package/src/utils/frontend-tool.utils.ts +0 -266
  170. package/src/utils/human-in-the-loop.utils.ts +0 -359
  171. package/tsconfig.spec.json +0 -12
@@ -0,0 +1,296 @@
1
+ import { DestroyRef, inject, signal } from '@angular/core';
2
+ import { CopilotKitService } from '../core/copilotkit.service';
3
+ import { ToolCallStatus } from '../core/copilotkit.types';
4
+ /**
5
+ * Registers a human-in-the-loop tool that requires user interaction.
6
+ * Must be called within an injection context.
7
+ * Automatically cleans up when the component/service is destroyed.
8
+ *
9
+ * @param tool - The human-in-the-loop tool configuration
10
+ * @returns The tool ID
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * export class ApprovalComponent {
15
+ * toolId = registerHumanInTheLoop({
16
+ * name: 'requireApproval',
17
+ * description: 'Requires user approval',
18
+ * args: z.object({ action: z.string() }),
19
+ * render: ApprovalDialogComponent
20
+ * });
21
+ * }
22
+ * ```
23
+ */
24
+ export function registerHumanInTheLoop(tool) {
25
+ const service = inject(CopilotKitService);
26
+ const destroyRef = inject(DestroyRef);
27
+ // Create state management
28
+ const statusSignal = signal(ToolCallStatus.InProgress);
29
+ let resolvePromise = null;
30
+ // Create respond function
31
+ const respond = async (result) => {
32
+ if (resolvePromise) {
33
+ resolvePromise(result);
34
+ statusSignal.set(ToolCallStatus.Complete);
35
+ resolvePromise = null;
36
+ }
37
+ };
38
+ // Create handler that returns a Promise
39
+ const handler = async (_args) => {
40
+ return new Promise((resolve) => {
41
+ statusSignal.set(ToolCallStatus.Executing);
42
+ resolvePromise = resolve;
43
+ });
44
+ };
45
+ // Create enhanced render function
46
+ const enhancedRender = createEnhancedRender(tool.render, statusSignal, respond);
47
+ // Create the frontend tool
48
+ const frontendTool = {
49
+ ...tool,
50
+ handler,
51
+ render: enhancedRender
52
+ };
53
+ // Add the tool (returns void, so we use the tool name as ID)
54
+ service.copilotkit.addTool(frontendTool);
55
+ const toolId = frontendTool.name;
56
+ // Register tool render if provided
57
+ if (frontendTool.render && tool.parameters) {
58
+ service.registerToolRender(frontendTool.name, {
59
+ name: frontendTool.name,
60
+ args: tool.parameters,
61
+ render: frontendTool.render
62
+ });
63
+ }
64
+ // Cleanup on destroy
65
+ destroyRef.onDestroy(() => {
66
+ service.copilotkit.removeTool(toolId);
67
+ if (frontendTool.render) {
68
+ service.unregisterToolRender(frontendTool.name);
69
+ }
70
+ });
71
+ return toolId;
72
+ }
73
+ /**
74
+ * Adds a human-in-the-loop tool with explicit service parameter.
75
+ * Returns a cleanup function.
76
+ *
77
+ * @param service - The CopilotKitService instance
78
+ * @param tool - The human-in-the-loop tool configuration
79
+ * @returns Cleanup function to remove the tool
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * export class MyComponent implements OnInit, OnDestroy {
84
+ * private cleanup?: () => void;
85
+ *
86
+ * constructor(private copilotkit: CopilotKitService) {}
87
+ *
88
+ * ngOnInit() {
89
+ * this.cleanup = addHumanInTheLoop(this.copilotkit, {
90
+ * name: 'requireApproval',
91
+ * description: 'Requires user approval',
92
+ * args: z.object({ action: z.string() }),
93
+ * render: ApprovalDialogComponent
94
+ * });
95
+ * }
96
+ *
97
+ * ngOnDestroy() {
98
+ * this.cleanup?.();
99
+ * }
100
+ * }
101
+ * ```
102
+ */
103
+ export function addHumanInTheLoop(service, tool) {
104
+ // Create state management
105
+ const statusSignal = signal(ToolCallStatus.InProgress);
106
+ let resolvePromise = null;
107
+ // Create respond function
108
+ const respond = async (result) => {
109
+ if (resolvePromise) {
110
+ resolvePromise(result);
111
+ statusSignal.set(ToolCallStatus.Complete);
112
+ resolvePromise = null;
113
+ }
114
+ };
115
+ // Create handler that returns a Promise
116
+ const handler = async (_args) => {
117
+ return new Promise((resolve) => {
118
+ statusSignal.set(ToolCallStatus.Executing);
119
+ resolvePromise = resolve;
120
+ });
121
+ };
122
+ // Create enhanced render function
123
+ const enhancedRender = createEnhancedRender(tool.render, statusSignal, respond);
124
+ // Create the frontend tool
125
+ const frontendTool = {
126
+ ...tool,
127
+ handler,
128
+ render: enhancedRender
129
+ };
130
+ // Add the tool (returns void, so we use the tool name as ID)
131
+ service.copilotkit.addTool(frontendTool);
132
+ const toolId = frontendTool.name;
133
+ // Register tool render if provided
134
+ if (frontendTool.render && tool.parameters) {
135
+ service.registerToolRender(frontendTool.name, {
136
+ name: frontendTool.name,
137
+ args: tool.parameters,
138
+ render: frontendTool.render
139
+ });
140
+ }
141
+ // Return cleanup function
142
+ return () => {
143
+ service.copilotkit.removeTool(toolId);
144
+ if (frontendTool.render) {
145
+ service.unregisterToolRender(frontendTool.name);
146
+ }
147
+ };
148
+ }
149
+ /**
150
+ * Creates a human-in-the-loop tool with dynamic update capabilities.
151
+ *
152
+ * @param service - The CopilotKitService instance
153
+ * @param tool - The human-in-the-loop tool configuration
154
+ * @returns Object with status signal, update and destroy methods
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * export class MyComponent {
159
+ * humanInTheLoop = createHumanInTheLoop(this.copilotkit, {
160
+ * name: 'requireApproval',
161
+ * description: 'Requires user approval',
162
+ * args: z.object({ action: z.string() }),
163
+ * render: ApprovalDialogComponent
164
+ * });
165
+ *
166
+ * updateDescription(newDesc: string) {
167
+ * this.humanInTheLoop.update({ description: newDesc });
168
+ * }
169
+ *
170
+ * ngOnDestroy() {
171
+ * this.humanInTheLoop.destroy();
172
+ * }
173
+ * }
174
+ * ```
175
+ */
176
+ export function createHumanInTheLoop(service, tool) {
177
+ // Create state management
178
+ const statusSignal = signal(ToolCallStatus.InProgress);
179
+ let currentTool = { ...tool };
180
+ let toolId = '';
181
+ let resolvePromise = null;
182
+ // Create respond function
183
+ const respond = async (result) => {
184
+ if (resolvePromise) {
185
+ resolvePromise(result);
186
+ statusSignal.set(ToolCallStatus.Complete);
187
+ resolvePromise = null;
188
+ }
189
+ };
190
+ // Create handler that returns a Promise
191
+ const handler = async (_args) => {
192
+ return new Promise((resolve) => {
193
+ statusSignal.set(ToolCallStatus.Executing);
194
+ resolvePromise = resolve;
195
+ });
196
+ };
197
+ // Function to add the tool
198
+ const addTool = () => {
199
+ // Create enhanced render function
200
+ const enhancedRender = createEnhancedRender(currentTool.render, statusSignal, respond);
201
+ // Create the frontend tool
202
+ const frontendTool = {
203
+ ...currentTool,
204
+ handler,
205
+ render: enhancedRender
206
+ };
207
+ // Add tool (returns void, so we use the tool name as ID)
208
+ service.copilotkit.addTool(frontendTool);
209
+ toolId = frontendTool.name;
210
+ // Register tool render if provided
211
+ if (frontendTool.render && currentTool.parameters) {
212
+ service.registerToolRender(frontendTool.name, {
213
+ name: frontendTool.name,
214
+ args: currentTool.parameters,
215
+ render: frontendTool.render
216
+ });
217
+ }
218
+ };
219
+ // Initialize the tool
220
+ addTool();
221
+ return {
222
+ status: statusSignal.asReadonly(),
223
+ toolId,
224
+ update: (updates) => {
225
+ // Remove old tool
226
+ service.copilotkit.removeTool(toolId);
227
+ if (currentTool.render) {
228
+ service.unregisterToolRender(currentTool.name);
229
+ }
230
+ // Update tool configuration
231
+ currentTool = { ...currentTool, ...updates };
232
+ // Re-add with new configuration
233
+ addTool();
234
+ },
235
+ destroy: () => {
236
+ service.copilotkit.removeTool(toolId);
237
+ if (currentTool.render) {
238
+ service.unregisterToolRender(currentTool.name);
239
+ }
240
+ }
241
+ };
242
+ }
243
+ /**
244
+ * Creates an enhanced render function that injects the respond function
245
+ * when the status is 'executing'.
246
+ */
247
+ function createEnhancedRender(originalRender, _statusSignal, _respond) {
248
+ // For component classes, we need to create a wrapper
249
+ if (isComponentClass(originalRender)) {
250
+ // Return a wrapper component factory
251
+ // This is complex in Angular and would require dynamic component creation
252
+ // For now, we'll return the original and rely on prop injection
253
+ return originalRender;
254
+ }
255
+ // For templates, we can't easily wrap them
256
+ // The template context will be enhanced in the render component
257
+ return originalRender;
258
+ }
259
+ /**
260
+ * Helper function to check if a value is a component class
261
+ */
262
+ function isComponentClass(value) {
263
+ return typeof value === 'function' && value.prototype;
264
+ }
265
+ /**
266
+ * Enhanced component wrapper for human-in-the-loop.
267
+ * This would be used internally by the tool render component to inject
268
+ * the respond function based on status.
269
+ *
270
+ * @internal
271
+ */
272
+ export function enhancePropsForHumanInTheLoop(props, status, respond) {
273
+ if (status === ToolCallStatus.Executing && respond) {
274
+ return {
275
+ ...props,
276
+ status: ToolCallStatus.Executing,
277
+ respond
278
+ };
279
+ }
280
+ if (status === ToolCallStatus.Complete) {
281
+ return {
282
+ ...props,
283
+ status: ToolCallStatus.Complete,
284
+ result: typeof props.result === 'string' ? props.result : '',
285
+ respond: undefined
286
+ };
287
+ }
288
+ // InProgress
289
+ return {
290
+ ...props,
291
+ status: ToolCallStatus.InProgress,
292
+ result: undefined,
293
+ respond: undefined
294
+ };
295
+ }
296
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVtYW4taW4tdGhlLWxvb3AudXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvaHVtYW4taW4tdGhlLWxvb3AudXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFVBQVUsRUFDVixNQUFNLEVBQ04sTUFBTSxFQUlQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9ELE9BQU8sRUFFTCxjQUFjLEVBSWYsTUFBTSwwQkFBMEIsQ0FBQztBQUVsQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FDcEMsSUFBOEI7SUFFOUIsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDMUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRXRDLDBCQUEwQjtJQUMxQixNQUFNLFlBQVksR0FBRyxNQUFNLENBQWlCLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN2RSxJQUFJLGNBQWMsR0FBdUMsSUFBSSxDQUFDO0lBRTlELDBCQUEwQjtJQUMxQixNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsTUFBZSxFQUFpQixFQUFFO1FBQ3ZELElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZCLFlBQVksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLHdDQUF3QztJQUN4QyxNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBUSxFQUFvQixFQUFFO1FBQ25ELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM3QixZQUFZLENBQUMsR0FB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QzNDLEtBQTZCLEVBQzdCLE1BQXNCLEVBQ3RCLE9BQTRDO0lBRTVDLElBQUksTUFBTSxLQUFLLGNBQWMsQ0FBQyxTQUFTLElBQUksT0FBTyxFQUFFLENBQUM7UUFDbkQsT0FBTztZQUNMLEdBQUcsS0FBSztZQUNSLE1BQU0sRUFBRSxjQUFjLENBQUMsU0FBUztZQUNoQyxPQUFPO1NBQ2tCLENBQUM7SUFDOUIsQ0FBQztJQUVELElBQUksTUFBTSxLQUFLLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN2QyxPQUFPO1lBQ0wsR0FBRyxLQUFLO1lBQ1IsTUFBTSxFQUFFLGNBQWMsQ0FBQyxRQUFRO1lBQy9CLE1BQU0sRUFBRSxPQUFPLEtBQUssQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQzVELE9BQU8sRUFBRSxTQUFTO1NBQ08sQ0FBQztJQUM5QixDQUFDO0lBRUQsYUFBYTtJQUNiLE9BQU87UUFDTCxHQUFHLEtBQUs7UUFDUixNQUFNLEVBQUUsY0FBYyxDQUFDLFVBQVU7UUFDakMsTUFBTSxFQUFFLFNBQVM7UUFDakIsT0FBTyxFQUFFLFNBQVM7S0FDTyxDQUFDO0FBQzlCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBcbiAgRGVzdHJveVJlZiwgXG4gIGluamVjdCwgXG4gIHNpZ25hbCwgXG4gIFNpZ25hbCxcbiAgVHlwZSxcbiAgVGVtcGxhdGVSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb3BpbG90S2l0U2VydmljZSB9IGZyb20gJy4uL2NvcmUvY29waWxvdGtpdC5zZXJ2aWNlJztcbmltcG9ydCB7IFxuICBBbmd1bGFySHVtYW5JblRoZUxvb3AsIFxuICBUb29sQ2FsbFN0YXR1cyxcbiAgSHVtYW5JblRoZUxvb3BTdGF0ZSxcbiAgSHVtYW5JblRoZUxvb3BQcm9wcyxcbiAgQW5ndWxhckZyb250ZW5kVG9vbFxufSBmcm9tICcuLi9jb3JlL2NvcGlsb3RraXQudHlwZXMnO1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGh1bWFuLWluLXRoZS1sb29wIHRvb2wgdGhhdCByZXF1aXJlcyB1c2VyIGludGVyYWN0aW9uLlxuICogTXVzdCBiZSBjYWxsZWQgd2l0aGluIGFuIGluamVjdGlvbiBjb250ZXh0LlxuICogQXV0b21hdGljYWxseSBjbGVhbnMgdXAgd2hlbiB0aGUgY29tcG9uZW50L3NlcnZpY2UgaXMgZGVzdHJveWVkLlxuICogXG4gKiBAcGFyYW0gdG9vbCAtIFRoZSBodW1hbi1pbi10aGUtbG9vcCB0b29sIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIFRoZSB0b29sIElEXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBleHBvcnQgY2xhc3MgQXBwcm92YWxDb21wb25lbnQge1xuICogICB0b29sSWQgPSByZWdpc3Rlckh1bWFuSW5UaGVMb29wKHtcbiAqICAgICBuYW1lOiAncmVxdWlyZUFwcHJvdmFsJyxcbiAqICAgICBkZXNjcmlwdGlvbjogJ1JlcXVpcmVzIHVzZXIgYXBwcm92YWwnLFxuICogICAgIGFyZ3M6IHoub2JqZWN0KHsgYWN0aW9uOiB6LnN0cmluZygpIH0pLFxuICogICAgIHJlbmRlcjogQXBwcm92YWxEaWFsb2dDb21wb25lbnRcbiAqICAgfSk7XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVySHVtYW5JblRoZUxvb3A8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBSZWNvcmQ8c3RyaW5nLCBhbnk+PihcbiAgdG9vbDogQW5ndWxhckh1bWFuSW5UaGVMb29wPFQ+XG4pOiBzdHJpbmcge1xuICBjb25zdCBzZXJ2aWNlID0gaW5qZWN0KENvcGlsb3RLaXRTZXJ2aWNlKTtcbiAgY29uc3QgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgXG4gIC8vIENyZWF0ZSBzdGF0ZSBtYW5hZ2VtZW50XG4gIGNvbnN0IHN0YXR1c1NpZ25hbCA9IHNpZ25hbDxUb29sQ2FsbFN0YXR1cz4oVG9vbENhbGxTdGF0dXMuSW5Qcm9ncmVzcyk7XG4gIGxldCByZXNvbHZlUHJvbWlzZTogKChyZXN1bHQ6IHVua25vd24pID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIFxuICAvLyBDcmVhdGUgcmVzcG9uZCBmdW5jdGlvblxuICBjb25zdCByZXNwb25kID0gYXN5bmMgKHJlc3VsdDogdW5rbm93bik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmIChyZXNvbHZlUHJvbWlzZSkge1xuICAgICAgcmVzb2x2ZVByb21pc2UocmVzdWx0KTtcbiAgICAgIHN0YXR1c1NpZ25hbC5zZXQoVG9vbENhbGxTdGF0dXMuQ29tcGxldGUpO1xuICAgICAgcmVzb2x2ZVByb21pc2UgPSBudWxsO1xuICAgIH1cbiAgfTtcbiAgXG4gIC8vIENyZWF0ZSBoYW5kbGVyIHRoYXQgcmV0dXJucyBhIFByb21pc2VcbiAgY29uc3QgaGFuZGxlciA9IGFzeW5jIChfYXJnczogVCk6IFByb21pc2U8dW5rbm93bj4gPT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgc3RhdHVzU2lnbmFsLnNldChUb29sQ2FsbFN0YXR1cy5FeGVjdXRpbmcpO1xuICAgICAgcmVzb2x2ZVByb21pc2UgPSByZXNvbHZlO1xuICAgIH0pO1xuICB9O1xuICBcbiAgLy8gQ3JlYXRlIGVuaGFuY2VkIHJlbmRlciBmdW5jdGlvblxuICBjb25zdCBlbmhhbmNlZFJlbmRlciA9IGNyZWF0ZUVuaGFuY2VkUmVuZGVyKHRvb2wucmVuZGVyLCBzdGF0dXNTaWduYWwsIHJlc3BvbmQpO1xuICBcbiAgLy8gQ3JlYXRlIHRoZSBmcm9udGVuZCB0b29sXG4gIGNvbnN0IGZyb250ZW5kVG9vbDogQW5ndWxhckZyb250ZW5kVG9vbDxUPiA9IHtcbiAgICAuLi50b29sLFxuICAgIGhhbmRsZXIsXG4gICAgcmVuZGVyOiBlbmhhbmNlZFJlbmRlclxuICB9O1xuICBcbiAgLy8gQWRkIHRoZSB0b29sIChyZXR1cm5zIHZvaWQsIHNvIHdlIHVzZSB0aGUgdG9vbCBuYW1lIGFzIElEKVxuICBzZXJ2aWNlLmNvcGlsb3RraXQuYWRkVG9vbChmcm9udGVuZFRvb2wpO1xuICBjb25zdCB0b29sSWQgPSBmcm9udGVuZFRvb2wubmFtZTtcbiAgXG4gIC8vIFJlZ2lzdGVyIHRvb2wgcmVuZGVyIGlmIHByb3ZpZGVkXG4gIGlmIChmcm9udGVuZFRvb2wucmVuZGVyICYmIHRvb2wucGFyYW1ldGVycykge1xuICAgIHNlcnZpY2UucmVnaXN0ZXJUb29sUmVuZGVyKGZyb250ZW5kVG9vbC5uYW1lLCB7XG4gICAgICBuYW1lOiBmcm9udGVuZFRvb2wubmFtZSxcbiAgICAgIGFyZ3M6IHRvb2wucGFyYW1ldGVycyxcbiAgICAgIHJlbmRlcjogZnJvbnRlbmRUb29sLnJlbmRlclxuICAgIH0pO1xuICB9XG4gIFxuICAvLyBDbGVhbnVwIG9uIGRlc3Ryb3lcbiAgZGVzdHJveVJlZi5vbkRlc3Ryb3koKCkgPT4ge1xuICAgIHNlcnZpY2UuY29waWxvdGtpdC5yZW1vdmVUb29sKHRvb2xJZCk7XG4gICAgaWYgKGZyb250ZW5kVG9vbC5yZW5kZXIpIHtcbiAgICAgIHNlcnZpY2UudW5yZWdpc3RlclRvb2xSZW5kZXIoZnJvbnRlbmRUb29sLm5hbWUpO1xuICAgIH1cbiAgfSk7XG4gIFxuICByZXR1cm4gdG9vbElkO1xufVxuXG4vKipcbiAqIEFkZHMgYSBodW1hbi1pbi10aGUtbG9vcCB0b29sIHdpdGggZXhwbGljaXQgc2VydmljZSBwYXJhbWV0ZXIuXG4gKiBSZXR1cm5zIGEgY2xlYW51cCBmdW5jdGlvbi5cbiAqIFxuICogQHBhcmFtIHNlcnZpY2UgLSBUaGUgQ29waWxvdEtpdFNlcnZpY2UgaW5zdGFuY2VcbiAqIEBwYXJhbSB0b29sIC0gVGhlIGh1bWFuLWluLXRoZS1sb29wIHRvb2wgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgQ2xlYW51cCBmdW5jdGlvbiB0byByZW1vdmUgdGhlIHRvb2xcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGV4cG9ydCBjbGFzcyBNeUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAqICAgcHJpdmF0ZSBjbGVhbnVwPzogKCkgPT4gdm9pZDtcbiAqICAgXG4gKiAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY29waWxvdGtpdDogQ29waWxvdEtpdFNlcnZpY2UpIHt9XG4gKiAgIFxuICogICBuZ09uSW5pdCgpIHtcbiAqICAgICB0aGlzLmNsZWFudXAgPSBhZGRIdW1hbkluVGhlTG9vcCh0aGlzLmNvcGlsb3RraXQsIHtcbiAqICAgICAgIG5hbWU6ICdyZXF1aXJlQXBwcm92YWwnLFxuICogICAgICAgZGVzY3JpcHRpb246ICdSZXF1aXJlcyB1c2VyIGFwcHJvdmFsJyxcbiAqICAgICAgIGFyZ3M6IHoub2JqZWN0KHsgYWN0aW9uOiB6LnN0cmluZygpIH0pLFxuICogICAgICAgcmVuZGVyOiBBcHByb3ZhbERpYWxvZ0NvbXBvbmVudFxuICogICAgIH0pO1xuICogICB9XG4gKiAgIFxuICogICBuZ09uRGVzdHJveSgpIHtcbiAqICAgICB0aGlzLmNsZWFudXA/LigpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZEh1bWFuSW5UaGVMb29wPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIHNlcnZpY2U6IENvcGlsb3RLaXRTZXJ2aWNlLFxuICB0b29sOiBBbmd1bGFySHVtYW5JblRoZUxvb3A8VD5cbik6ICgpID0+IHZvaWQge1xuICAvLyBDcmVhdGUgc3RhdGUgbWFuYWdlbWVudFxuICBjb25zdCBzdGF0dXNTaWduYWwgPSBzaWduYWw8VG9vbENhbGxTdGF0dXM+KFRvb2xDYWxsU3RhdHVzLkluUHJvZ3Jlc3MpO1xuICBsZXQgcmVzb2x2ZVByb21pc2U6ICgocmVzdWx0OiB1bmtub3duKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBcbiAgLy8gQ3JlYXRlIHJlc3BvbmQgZnVuY3Rpb25cbiAgY29uc3QgcmVzcG9uZCA9IGFzeW5jIChyZXN1bHQ6IHVua25vd24pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAocmVzb2x2ZVByb21pc2UpIHtcbiAgICAgIHJlc29sdmVQcm9taXNlKHJlc3VsdCk7XG4gICAgICBzdGF0dXNTaWduYWwuc2V0KFRvb2xDYWxsU3RhdHVzLkNvbXBsZXRlKTtcbiAgICAgIHJlc29sdmVQcm9taXNlID0gbnVsbDtcbiAgICB9XG4gIH07XG4gIFxuICAvLyBDcmVhdGUgaGFuZGxlciB0aGF0IHJldHVybnMgYSBQcm9taXNlXG4gIGNvbnN0IGhhbmRsZXIgPSBhc3luYyAoX2FyZ3M6IFQpOiBQcm9taXNlPHVua25vd24+ID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHN0YXR1c1NpZ25hbC5zZXQoVG9vbENhbGxTdGF0dXMuRXhlY3V0aW5nKTtcbiAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICB9KTtcbiAgfTtcbiAgXG4gIC8vIENyZWF0ZSBlbmhhbmNlZCByZW5kZXIgZnVuY3Rpb25cbiAgY29uc3QgZW5oYW5jZWRSZW5kZXIgPSBjcmVhdGVFbmhhbmNlZFJlbmRlcih0b29sLnJlbmRlciwgc3RhdHVzU2lnbmFsLCByZXNwb25kKTtcbiAgXG4gIC8vIENyZWF0ZSB0aGUgZnJvbnRlbmQgdG9vbFxuICBjb25zdCBmcm9udGVuZFRvb2w6IEFuZ3VsYXJGcm9udGVuZFRvb2w8VD4gPSB7XG4gICAgLi4udG9vbCxcbiAgICBoYW5kbGVyLFxuICAgIHJlbmRlcjogZW5oYW5jZWRSZW5kZXJcbiAgfTtcbiAgXG4gIC8vIEFkZCB0aGUgdG9vbCAocmV0dXJucyB2b2lkLCBzbyB3ZSB1c2UgdGhlIHRvb2wgbmFtZSBhcyBJRClcbiAgc2VydmljZS5jb3BpbG90a2l0LmFkZFRvb2woZnJvbnRlbmRUb29sKTtcbiAgY29uc3QgdG9vbElkID0gZnJvbnRlbmRUb29sLm5hbWU7XG4gIFxuICAvLyBSZWdpc3RlciB0b29sIHJlbmRlciBpZiBwcm92aWRlZFxuICBpZiAoZnJvbnRlbmRUb29sLnJlbmRlciAmJiB0b29sLnBhcmFtZXRlcnMpIHtcbiAgICBzZXJ2aWNlLnJlZ2lzdGVyVG9vbFJlbmRlcihmcm9udGVuZFRvb2wubmFtZSwge1xuICAgICAgbmFtZTogZnJvbnRlbmRUb29sLm5hbWUsXG4gICAgICBhcmdzOiB0b29sLnBhcmFtZXRlcnMsXG4gICAgICByZW5kZXI6IGZyb250ZW5kVG9vbC5yZW5kZXJcbiAgICB9KTtcbiAgfVxuICBcbiAgLy8gUmV0dXJuIGNsZWFudXAgZnVuY3Rpb25cbiAgcmV0dXJuICgpID0+IHtcbiAgICBzZXJ2aWNlLmNvcGlsb3RraXQucmVtb3ZlVG9vbCh0b29sSWQpO1xuICAgIGlmIChmcm9udGVuZFRvb2wucmVuZGVyKSB7XG4gICAgICBzZXJ2aWNlLnVucmVnaXN0ZXJUb29sUmVuZGVyKGZyb250ZW5kVG9vbC5uYW1lKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGh1bWFuLWluLXRoZS1sb29wIHRvb2wgd2l0aCBkeW5hbWljIHVwZGF0ZSBjYXBhYmlsaXRpZXMuXG4gKiBcbiAqIEBwYXJhbSBzZXJ2aWNlIC0gVGhlIENvcGlsb3RLaXRTZXJ2aWNlIGluc3RhbmNlXG4gKiBAcGFyYW0gdG9vbCAtIFRoZSBodW1hbi1pbi10aGUtbG9vcCB0b29sIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIE9iamVjdCB3aXRoIHN0YXR1cyBzaWduYWwsIHVwZGF0ZSBhbmQgZGVzdHJveSBtZXRob2RzXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBleHBvcnQgY2xhc3MgTXlDb21wb25lbnQge1xuICogICBodW1hbkluVGhlTG9vcCA9IGNyZWF0ZUh1bWFuSW5UaGVMb29wKHRoaXMuY29waWxvdGtpdCwge1xuICogICAgIG5hbWU6ICdyZXF1aXJlQXBwcm92YWwnLFxuICogICAgIGRlc2NyaXB0aW9uOiAnUmVxdWlyZXMgdXNlciBhcHByb3ZhbCcsXG4gKiAgICAgYXJnczogei5vYmplY3QoeyBhY3Rpb246IHouc3RyaW5nKCkgfSksXG4gKiAgICAgcmVuZGVyOiBBcHByb3ZhbERpYWxvZ0NvbXBvbmVudFxuICogICB9KTtcbiAqICAgXG4gKiAgIHVwZGF0ZURlc2NyaXB0aW9uKG5ld0Rlc2M6IHN0cmluZykge1xuICogICAgIHRoaXMuaHVtYW5JblRoZUxvb3AudXBkYXRlKHsgZGVzY3JpcHRpb246IG5ld0Rlc2MgfSk7XG4gKiAgIH1cbiAqICAgXG4gKiAgIG5nT25EZXN0cm95KCkge1xuICogICAgIHRoaXMuaHVtYW5JblRoZUxvb3AuZGVzdHJveSgpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUh1bWFuSW5UaGVMb29wPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gIHNlcnZpY2U6IENvcGlsb3RLaXRTZXJ2aWNlLFxuICB0b29sOiBBbmd1bGFySHVtYW5JblRoZUxvb3A8VD5cbik6IEh1bWFuSW5UaGVMb29wU3RhdGUgJiB7IHVwZGF0ZTogKHVwZGF0ZXM6IFBhcnRpYWw8QW5ndWxhckh1bWFuSW5UaGVMb29wPFQ+PikgPT4gdm9pZCB9IHtcbiAgLy8gQ3JlYXRlIHN0YXRlIG1hbmFnZW1lbnRcbiAgY29uc3Qgc3RhdHVzU2lnbmFsID0gc2lnbmFsPFRvb2xDYWxsU3RhdHVzPihUb29sQ2FsbFN0YXR1cy5JblByb2dyZXNzKTtcbiAgbGV0IGN1cnJlbnRUb29sID0geyAuLi50b29sIH07XG4gIGxldCB0b29sSWQ6IHN0cmluZyA9ICcnO1xuICBsZXQgcmVzb2x2ZVByb21pc2U6ICgocmVzdWx0OiB1bmtub3duKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBcbiAgLy8gQ3JlYXRlIHJlc3BvbmQgZnVuY3Rpb25cbiAgY29uc3QgcmVzcG9uZCA9IGFzeW5jIChyZXN1bHQ6IHVua25vd24pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAocmVzb2x2ZVByb21pc2UpIHtcbiAgICAgIHJlc29sdmVQcm9taXNlKHJlc3VsdCk7XG4gICAgICBzdGF0dXNTaWduYWwuc2V0KFRvb2xDYWxsU3RhdHVzLkNvbXBsZXRlKTtcbiAgICAgIHJlc29sdmVQcm9taXNlID0gbnVsbDtcbiAgICB9XG4gIH07XG4gIFxuICAvLyBDcmVhdGUgaGFuZGxlciB0aGF0IHJldHVybnMgYSBQcm9taXNlXG4gIGNvbnN0IGhhbmRsZXIgPSBhc3luYyAoX2FyZ3M6IFQpOiBQcm9taXNlPHVua25vd24+ID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHN0YXR1c1NpZ25hbC5zZXQoVG9vbENhbGxTdGF0dXMuRXhlY3V0aW5nKTtcbiAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICB9KTtcbiAgfTtcbiAgXG4gIC8vIEZ1bmN0aW9uIHRvIGFkZCB0aGUgdG9vbFxuICBjb25zdCBhZGRUb29sID0gKCkgPT4ge1xuICAgIC8vIENyZWF0ZSBlbmhhbmNlZCByZW5kZXIgZnVuY3Rpb25cbiAgICBjb25zdCBlbmhhbmNlZFJlbmRlciA9IGNyZWF0ZUVuaGFuY2VkUmVuZGVyKGN1cnJlbnRUb29sLnJlbmRlciwgc3RhdHVzU2lnbmFsLCByZXNwb25kKTtcbiAgICBcbiAgICAvLyBDcmVhdGUgdGhlIGZyb250ZW5kIHRvb2xcbiAgICBjb25zdCBmcm9udGVuZFRvb2w6IEFuZ3VsYXJGcm9udGVuZFRvb2w8VD4gPSB7XG4gICAgICAuLi5jdXJyZW50VG9vbCxcbiAgICAgIGhhbmRsZXIsXG4gICAgICByZW5kZXI6IGVuaGFuY2VkUmVuZGVyXG4gICAgfTtcbiAgICBcbiAgICAvLyBBZGQgdG9vbCAocmV0dXJucyB2b2lkLCBzbyB3ZSB1c2UgdGhlIHRvb2wgbmFtZSBhcyBJRClcbiAgICBzZXJ2aWNlLmNvcGlsb3RraXQuYWRkVG9vbChmcm9udGVuZFRvb2wpO1xuICAgIHRvb2xJZCA9IGZyb250ZW5kVG9vbC5uYW1lO1xuICAgIFxuICAgIC8vIFJlZ2lzdGVyIHRvb2wgcmVuZGVyIGlmIHByb3ZpZGVkXG4gICAgaWYgKGZyb250ZW5kVG9vbC5yZW5kZXIgJiYgY3VycmVudFRvb2wucGFyYW1ldGVycykge1xuICAgICAgc2VydmljZS5yZWdpc3RlclRvb2xSZW5kZXIoZnJvbnRlbmRUb29sLm5hbWUsIHtcbiAgICAgICAgbmFtZTogZnJvbnRlbmRUb29sLm5hbWUsXG4gICAgICAgIGFyZ3M6IGN1cnJlbnRUb29sLnBhcmFtZXRlcnMsXG4gICAgICAgIHJlbmRlcjogZnJvbnRlbmRUb29sLnJlbmRlclxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuICBcbiAgLy8gSW5pdGlhbGl6ZSB0aGUgdG9vbFxuICBhZGRUb29sKCk7XG4gIFxuICByZXR1cm4ge1xuICAgIHN0YXR1czogc3RhdHVzU2lnbmFsLmFzUmVhZG9ubHkoKSxcbiAgICB0b29sSWQsXG4gICAgdXBkYXRlOiAodXBkYXRlczogUGFydGlhbDxBbmd1bGFySHVtYW5JblRoZUxvb3A8VD4+KSA9PiB7XG4gICAgICAvLyBSZW1vdmUgb2xkIHRvb2xcbiAgICAgIHNlcnZpY2UuY29waWxvdGtpdC5yZW1vdmVUb29sKHRvb2xJZCk7XG4gICAgICBpZiAoY3VycmVudFRvb2wucmVuZGVyKSB7XG4gICAgICAgIHNlcnZpY2UudW5yZWdpc3RlclRvb2xSZW5kZXIoY3VycmVudFRvb2wubmFtZSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSB0b29sIGNvbmZpZ3VyYXRpb25cbiAgICAgIGN1cnJlbnRUb29sID0geyAuLi5jdXJyZW50VG9vbCwgLi4udXBkYXRlcyB9O1xuICAgICAgXG4gICAgICAvLyBSZS1hZGQgd2l0aCBuZXcgY29uZmlndXJhdGlvblxuICAgICAgYWRkVG9vbCgpO1xuICAgIH0sXG4gICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgc2VydmljZS5jb3BpbG90a2l0LnJlbW92ZVRvb2wodG9vbElkKTtcbiAgICAgIGlmIChjdXJyZW50VG9vbC5yZW5kZXIpIHtcbiAgICAgICAgc2VydmljZS51bnJlZ2lzdGVyVG9vbFJlbmRlcihjdXJyZW50VG9vbC5uYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBlbmhhbmNlZCByZW5kZXIgZnVuY3Rpb24gdGhhdCBpbmplY3RzIHRoZSByZXNwb25kIGZ1bmN0aW9uXG4gKiB3aGVuIHRoZSBzdGF0dXMgaXMgJ2V4ZWN1dGluZycuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUVuaGFuY2VkUmVuZGVyPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+PihcbiAgb3JpZ2luYWxSZW5kZXI6IFR5cGU8YW55PiB8IFRlbXBsYXRlUmVmPEh1bWFuSW5UaGVMb29wUHJvcHM8VD4+LFxuICBfc3RhdHVzU2lnbmFsOiBTaWduYWw8VG9vbENhbGxTdGF0dXM+LFxuICBfcmVzcG9uZDogKHJlc3VsdDogdW5rbm93bikgPT4gUHJvbWlzZTx2b2lkPlxuKTogVHlwZTxhbnk+IHwgVGVtcGxhdGVSZWY8YW55PiB7XG4gIC8vIEZvciBjb21wb25lbnQgY2xhc3Nlcywgd2UgbmVlZCB0byBjcmVhdGUgYSB3cmFwcGVyXG4gIGlmIChpc0NvbXBvbmVudENsYXNzKG9yaWdpbmFsUmVuZGVyKSkge1xuICAgIC8vIFJldHVybiBhIHdyYXBwZXIgY29tcG9uZW50IGZhY3RvcnlcbiAgICAvLyBUaGlzIGlzIGNvbXBsZXggaW4gQW5ndWxhciBhbmQgd291bGQgcmVxdWlyZSBkeW5hbWljIGNvbXBvbmVudCBjcmVhdGlvblxuICAgIC8vIEZvciBub3csIHdlJ2xsIHJldHVybiB0aGUgb3JpZ2luYWwgYW5kIHJlbHkgb24gcHJvcCBpbmplY3Rpb25cbiAgICByZXR1cm4gb3JpZ2luYWxSZW5kZXI7XG4gIH1cbiAgXG4gIC8vIEZvciB0ZW1wbGF0ZXMsIHdlIGNhbid0IGVhc2lseSB3cmFwIHRoZW1cbiAgLy8gVGhlIHRlbXBsYXRlIGNvbnRleHQgd2lsbCBiZSBlbmhhbmNlZCBpbiB0aGUgcmVuZGVyIGNvbXBvbmVudFxuICByZXR1cm4gb3JpZ2luYWxSZW5kZXI7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYSBjb21wb25lbnQgY2xhc3NcbiAqL1xuZnVuY3Rpb24gaXNDb21wb25lbnRDbGFzcyh2YWx1ZTogYW55KTogdmFsdWUgaXMgVHlwZTxhbnk+IHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiB2YWx1ZS5wcm90b3R5cGU7XG59XG5cbi8qKlxuICogRW5oYW5jZWQgY29tcG9uZW50IHdyYXBwZXIgZm9yIGh1bWFuLWluLXRoZS1sb29wLlxuICogVGhpcyB3b3VsZCBiZSB1c2VkIGludGVybmFsbHkgYnkgdGhlIHRvb2wgcmVuZGVyIGNvbXBvbmVudCB0byBpbmplY3RcbiAqIHRoZSByZXNwb25kIGZ1bmN0aW9uIGJhc2VkIG9uIHN0YXR1cy5cbiAqIFxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmhhbmNlUHJvcHNGb3JIdW1hbkluVGhlTG9vcDxUPihcbiAgcHJvcHM6IEh1bWFuSW5UaGVMb29wUHJvcHM8VD4sXG4gIHN0YXR1czogVG9vbENhbGxTdGF0dXMsXG4gIHJlc3BvbmQ/OiAocmVzdWx0OiB1bmtub3duKSA9PiBQcm9taXNlPHZvaWQ+XG4pOiBIdW1hbkluVGhlTG9vcFByb3BzPFQ+IHtcbiAgaWYgKHN0YXR1cyA9PT0gVG9vbENhbGxTdGF0dXMuRXhlY3V0aW5nICYmIHJlc3BvbmQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBzdGF0dXM6IFRvb2xDYWxsU3RhdHVzLkV4ZWN1dGluZyxcbiAgICAgIHJlc3BvbmRcbiAgICB9IGFzIEh1bWFuSW5UaGVMb29wUHJvcHM8VD47XG4gIH1cbiAgXG4gIGlmIChzdGF0dXMgPT09IFRvb2xDYWxsU3RhdHVzLkNvbXBsZXRlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgc3RhdHVzOiBUb29sQ2FsbFN0YXR1cy5Db21wbGV0ZSxcbiAgICAgIHJlc3VsdDogdHlwZW9mIHByb3BzLnJlc3VsdCA9PT0gJ3N0cmluZycgPyBwcm9wcy5yZXN1bHQgOiAnJyxcbiAgICAgIHJlc3BvbmQ6IHVuZGVmaW5lZFxuICAgIH0gYXMgSHVtYW5JblRoZUxvb3BQcm9wczxUPjtcbiAgfVxuICBcbiAgLy8gSW5Qcm9ncmVzc1xuICByZXR1cm4ge1xuICAgIC4uLnByb3BzLFxuICAgIHN0YXR1czogVG9vbENhbGxTdGF0dXMuSW5Qcm9ncmVzcyxcbiAgICByZXN1bHQ6IHVuZGVmaW5lZCxcbiAgICByZXNwb25kOiB1bmRlZmluZWRcbiAgfSBhcyBIdW1hbkluVGhlTG9vcFByb3BzPFQ+O1xufSJdfQ==