@sinequa/assistant 3.9.0 → 3.9.2

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.
@@ -34,6 +34,8 @@ export declare abstract class ChatService {
34
34
  functions: GllmFunction[] | undefined;
35
35
  /** List of saved chats. */
36
36
  savedChats$: BehaviorSubject<SavedChat[]>;
37
+ /** Whether there is an error with saved chats. */
38
+ savedChatsError$: BehaviorSubject<boolean>;
37
39
  /** Emit the saved chat to load. */
38
40
  loadSavedChat$: BehaviorSubject<SavedChat | undefined>;
39
41
  /** Emit the quota each time the chat is invoked. */
@@ -1,4 +1,5 @@
1
1
  {
2
2
  "rename": "Rename",
3
- "delete": "Delete"
3
+ "delete": "Delete",
4
+ "error": "Oops! We're having trouble loading your past chats right now. Please try again later. If the problem persists, contact support for assistance."
4
5
  }
@@ -1,4 +1,5 @@
1
1
  {
2
2
  "rename": "Renommer",
3
- "delete": "Supprimer"
3
+ "delete": "Supprimer",
4
+ "error": "Oups ! Nous avons un problème pour charger vos anciennes conversations. Veuillez réessayer plus tard. Si le problème persiste, contactez le support pour assistance."
4
5
  }
@@ -5,6 +5,7 @@ export interface ConnectionOptions {
5
5
  withCredentials?: boolean;
6
6
  headers?: MessageHeaders;
7
7
  transport?: HttpTransportType | ITransport;
8
+ skipNegotiation?: boolean;
8
9
  accessTokenFactory?: () => string | Promise<string>;
9
10
  }
10
11
  /** A token that is used to inject the transports allowed to use by hub connection.
package/chat/types.d.ts CHANGED
@@ -144,6 +144,7 @@ export declare const connectionSettingsSchema: z.ZodEffects<z.ZodObject<{
144
144
  connectionErrorMessage: z.ZodString;
145
145
  restEndpoint: z.ZodOptional<z.ZodString>;
146
146
  websocketEndpoint: z.ZodOptional<z.ZodString>;
147
+ signalRSkipNegotiation: z.ZodOptional<z.ZodBoolean>;
147
148
  signalRTransport: z.ZodEnum<["WebSockets", "ServerSentEvents", "LongPolling", "None"]>;
148
149
  signalRLogLevel: z.ZodEnum<["Critical", "Debug", "Error", "Information", "None", "Trace", "Warning"]>;
149
150
  signalRServerTimeoutInMilliseconds: z.ZodOptional<z.ZodNumber>;
@@ -153,6 +154,7 @@ export declare const connectionSettingsSchema: z.ZodEffects<z.ZodObject<{
153
154
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
154
155
  restEndpoint?: string | undefined;
155
156
  websocketEndpoint?: string | undefined;
157
+ signalRSkipNegotiation?: boolean | undefined;
156
158
  signalRServerTimeoutInMilliseconds?: number | undefined;
157
159
  }, {
158
160
  connectionErrorMessage: string;
@@ -160,6 +162,7 @@ export declare const connectionSettingsSchema: z.ZodEffects<z.ZodObject<{
160
162
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
161
163
  restEndpoint?: string | undefined;
162
164
  websocketEndpoint?: string | undefined;
165
+ signalRSkipNegotiation?: boolean | undefined;
163
166
  signalRServerTimeoutInMilliseconds?: number | undefined;
164
167
  }>, {
165
168
  connectionErrorMessage: string;
@@ -167,6 +170,7 @@ export declare const connectionSettingsSchema: z.ZodEffects<z.ZodObject<{
167
170
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
168
171
  restEndpoint?: string | undefined;
169
172
  websocketEndpoint?: string | undefined;
173
+ signalRSkipNegotiation?: boolean | undefined;
170
174
  signalRServerTimeoutInMilliseconds?: number | undefined;
171
175
  }, {
172
176
  connectionErrorMessage: string;
@@ -174,6 +178,7 @@ export declare const connectionSettingsSchema: z.ZodEffects<z.ZodObject<{
174
178
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
175
179
  restEndpoint?: string | undefined;
176
180
  websocketEndpoint?: string | undefined;
181
+ signalRSkipNegotiation?: boolean | undefined;
177
182
  signalRServerTimeoutInMilliseconds?: number | undefined;
178
183
  }>;
179
184
  export type ConnectionSettings = z.infer<typeof connectionSettingsSchema>;
@@ -395,6 +400,7 @@ export declare const chatConfigSchema: z.ZodObject<{
395
400
  connectionErrorMessage: z.ZodString;
396
401
  restEndpoint: z.ZodOptional<z.ZodString>;
397
402
  websocketEndpoint: z.ZodOptional<z.ZodString>;
403
+ signalRSkipNegotiation: z.ZodOptional<z.ZodBoolean>;
398
404
  signalRTransport: z.ZodEnum<["WebSockets", "ServerSentEvents", "LongPolling", "None"]>;
399
405
  signalRLogLevel: z.ZodEnum<["Critical", "Debug", "Error", "Information", "None", "Trace", "Warning"]>;
400
406
  signalRServerTimeoutInMilliseconds: z.ZodOptional<z.ZodNumber>;
@@ -404,6 +410,7 @@ export declare const chatConfigSchema: z.ZodObject<{
404
410
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
405
411
  restEndpoint?: string | undefined;
406
412
  websocketEndpoint?: string | undefined;
413
+ signalRSkipNegotiation?: boolean | undefined;
407
414
  signalRServerTimeoutInMilliseconds?: number | undefined;
408
415
  }, {
409
416
  connectionErrorMessage: string;
@@ -411,6 +418,7 @@ export declare const chatConfigSchema: z.ZodObject<{
411
418
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
412
419
  restEndpoint?: string | undefined;
413
420
  websocketEndpoint?: string | undefined;
421
+ signalRSkipNegotiation?: boolean | undefined;
414
422
  signalRServerTimeoutInMilliseconds?: number | undefined;
415
423
  }>, {
416
424
  connectionErrorMessage: string;
@@ -418,6 +426,7 @@ export declare const chatConfigSchema: z.ZodObject<{
418
426
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
419
427
  restEndpoint?: string | undefined;
420
428
  websocketEndpoint?: string | undefined;
429
+ signalRSkipNegotiation?: boolean | undefined;
421
430
  signalRServerTimeoutInMilliseconds?: number | undefined;
422
431
  }, {
423
432
  connectionErrorMessage: string;
@@ -425,6 +434,7 @@ export declare const chatConfigSchema: z.ZodObject<{
425
434
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
426
435
  restEndpoint?: string | undefined;
427
436
  websocketEndpoint?: string | undefined;
437
+ signalRSkipNegotiation?: boolean | undefined;
428
438
  signalRServerTimeoutInMilliseconds?: number | undefined;
429
439
  }>;
430
440
  defaultValues: z.ZodObject<{
@@ -642,6 +652,7 @@ export declare const chatConfigSchema: z.ZodObject<{
642
652
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
643
653
  restEndpoint?: string | undefined;
644
654
  websocketEndpoint?: string | undefined;
655
+ signalRSkipNegotiation?: boolean | undefined;
645
656
  signalRServerTimeoutInMilliseconds?: number | undefined;
646
657
  };
647
658
  defaultValues: {
@@ -708,6 +719,7 @@ export declare const chatConfigSchema: z.ZodObject<{
708
719
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
709
720
  restEndpoint?: string | undefined;
710
721
  websocketEndpoint?: string | undefined;
722
+ signalRSkipNegotiation?: boolean | undefined;
711
723
  signalRServerTimeoutInMilliseconds?: number | undefined;
712
724
  };
713
725
  defaultValues: {
@@ -285,7 +285,7 @@ export class ChatMessageComponent {
285
285
  });
286
286
  }
287
287
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatMessageComponent, deps: [{ token: i1.UIService }, { token: i2.PrincipalService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
288
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChatMessageComponent, isStandalone: true, selector: "sq-chat-message", inputs: { message: "message", conversation: "conversation", suggestedActions: "suggestedActions", assistantMessageIcon: "assistantMessageIcon", userMessageIcon: "userMessageIcon", connectionErrorMessageIcon: "connectionErrorMessageIcon", searchWarningMessageIcon: "searchWarningMessageIcon", streaming: "streaming", canEdit: "canEdit", canRegenerate: "canRegenerate", canCopy: "canCopy", canDebug: "canDebug", canLike: "canLike", canDislike: "canDislike" }, outputs: { openDocument: "openDocument", openPreview: "openPreview", suggestAction: "suggestAction", edit: "edit", copy: "copy", regenerate: "regenerate", like: "like", dislike: "dislike", debug: "debug" }, providers: [provideTranslocoScope('chat-message')], usesOnChanges: true, ngImport: i0, template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n <remark *ngIf=\"(message?.role === 'assistant' && message.messageType !== 'CHART') || message?.role === 'connection-error' || message?.role === 'search-warning'\" [markdown]=\"message.content | messageContent\" [processor]=\"processor\">\n\n <!-- Chat reference (badge with file and part number) -->\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n @let attachment = referenceMap.get(ref.refId);\n @if (attachment) {\n <a\n class=\"reference\"\n role=\"button\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n (click)=\"openAttachmentPreview(attachment, ref.refId)\"\n >\n {{ref.refId}}\n </a>\n }\n @else {\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ ref.refId }}</span>\n </ng-template>\n }\n </ng-template>\n\n <!-- Embedded reference image -->\n <ng-template remarkTemplate=\"embedded-image-reference\" let-ref>\n @let refObj = getEmbeddedImageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"imageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Img-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Embedded reference page -->\n <ng-template remarkTemplate=\"embedded-page-reference\" let-ref>\n @let refObj = getEmbeddedPageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"pageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Page-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Blinking cursor -->\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyCode(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> {{ 'chatMessage.copyCode' | transloco }}</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n <ng-template remarkTemplate=\"link\" let-node>\n <a [href]=\"node.url\" target=\"_blank\" rel=\"noopener noreferrer\">{{getLinkText(node)}}</a>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message?.role === 'user'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @if (references?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!showReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of references; track $index) {\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n @for (imageReference of imageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlineImageReference\n [id]=\"imageReference[0]\"\n [ref]=\"imageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n @for (pageReference of pageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlinePageReference\n [id]=\"pageReference[0]\"\n [ref]=\"pageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked === true\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i class=\"fa-thumbs-up {{message.additionalProperties.$liked === true ? 'fas' : 'far'}}\"></i>\n </button>\n <button class=\"btn btn-sm bounce\" [class.bounce]=\"message.additionalProperties.$disliked === true\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i class=\"fa-thumbs-down {{message.additionalProperties.$disliked === true ? 'fas' : 'far'}}\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas fa-clipboard-question\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n <ng-template #imageTooltipTpl let-ref>\n <InlineImageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #pageTooltipTpl let-ref>\n <InlinePageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference\n *ngIf=\"!hiddenTooltip\"\n class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openAttachmentPreview($event, ref.$partId)\"\n (openDocument)=\"openOriginalAttachment($event, ref.$partId)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "ngmodule", type: RemarkModule }, { kind: "component", type: i4.RemarkComponent, selector: "remark", inputs: ["markdown", "processor", "debug"] }, { kind: "directive", type: i4.RemarkTemplateDirective, selector: "[remarkTemplate]", inputs: ["remarkTemplate"] }, { kind: "component", type: InitialsAvatarComponent, selector: "sq-initials-avatar", inputs: ["fullName", "size"] }, { kind: "component", type: ChatReferenceComponent, selector: "sq-chat-reference", inputs: ["reference", "attachment", "partId"], outputs: ["openDocument", "openPreview"] }, { kind: "component", type: ChartComponent, selector: "sq-assistant-chart", inputs: ["rawChartData"] }, { kind: "pipe", type: MessageContentPipe, name: "messageContent" }, { kind: "component", type: InlineImageReferenceComponent, selector: "InlineImageReference", inputs: ["id", "ref"], outputs: ["openPreview", "openDocument", "openModal"] }, { kind: "component", type: InlinePageReferenceComponent, selector: "InlinePageReference", inputs: ["id", "ref"], outputs: ["openPreview", "openDocument", "openModal"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
288
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChatMessageComponent, isStandalone: true, selector: "sq-chat-message", inputs: { message: "message", conversation: "conversation", suggestedActions: "suggestedActions", assistantMessageIcon: "assistantMessageIcon", userMessageIcon: "userMessageIcon", connectionErrorMessageIcon: "connectionErrorMessageIcon", searchWarningMessageIcon: "searchWarningMessageIcon", streaming: "streaming", canEdit: "canEdit", canRegenerate: "canRegenerate", canCopy: "canCopy", canDebug: "canDebug", canLike: "canLike", canDislike: "canDislike" }, outputs: { openDocument: "openDocument", openPreview: "openPreview", suggestAction: "suggestAction", edit: "edit", copy: "copy", regenerate: "regenerate", like: "like", dislike: "dislike", debug: "debug" }, providers: [provideTranslocoScope('chat-message')], usesOnChanges: true, ngImport: i0, template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n <remark *ngIf=\"(message?.role === 'assistant' && message.messageType !== 'CHART') || message?.role === 'connection-error' || message?.role === 'search-warning'\" [markdown]=\"message.content | messageContent\" [processor]=\"processor\">\n\n <!-- Chat reference (badge with file and part number) -->\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n @let attachment = referenceMap.get(ref.refId);\n @if (attachment) {\n <a\n class=\"reference\"\n role=\"button\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n (click)=\"openAttachmentPreview(attachment, ref.refId)\"\n >\n {{ref.refId}}\n </a>\n }\n @else {\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ ref.refId }}</span>\n </ng-template>\n }\n </ng-template>\n\n <!-- Embedded reference image -->\n <ng-template remarkTemplate=\"embedded-image-reference\" let-ref>\n @let refObj = getEmbeddedImageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"imageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Img-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Embedded reference page -->\n <ng-template remarkTemplate=\"embedded-page-reference\" let-ref>\n @let refObj = getEmbeddedPageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"pageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Page-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Blinking cursor -->\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyCode(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> {{ 'chatMessage.copyCode' | transloco }}</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n <ng-template remarkTemplate=\"link\" let-node>\n <a [href]=\"node.url\" target=\"_blank\" rel=\"noopener noreferrer\">{{getLinkText(node)}}</a>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message?.role === 'user'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @if (references?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!showReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of references; track $index) {\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n @for (imageReference of imageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlineImageReference\n [id]=\"imageReference[0]\"\n [ref]=\"imageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n @for (pageReference of pageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlinePageReference\n [id]=\"pageReference[0]\"\n [ref]=\"pageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i *ngIf=\"!message.additionalProperties.$liked\" class=\"far fa-thumbs-up \"></i>\n <i *ngIf=\"message.additionalProperties.$liked\" class=\"fas fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$disliked\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i *ngIf=\"!message.additionalProperties.$disliked\" class=\"far fa-thumbs-down \"></i>\n <i *ngIf=\"message.additionalProperties.$disliked\" class=\"fas fa-thumbs-down\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas fa-clipboard-question\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n <ng-template #imageTooltipTpl let-ref>\n <InlineImageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #pageTooltipTpl let-ref>\n <InlinePageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference\n *ngIf=\"!hiddenTooltip\"\n class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openAttachmentPreview($event, ref.$partId)\"\n (openDocument)=\"openOriginalAttachment($event, ref.$partId)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "ngmodule", type: RemarkModule }, { kind: "component", type: i4.RemarkComponent, selector: "remark", inputs: ["markdown", "processor", "debug"] }, { kind: "directive", type: i4.RemarkTemplateDirective, selector: "[remarkTemplate]", inputs: ["remarkTemplate"] }, { kind: "component", type: InitialsAvatarComponent, selector: "sq-initials-avatar", inputs: ["fullName", "size"] }, { kind: "component", type: ChatReferenceComponent, selector: "sq-chat-reference", inputs: ["reference", "attachment", "partId"], outputs: ["openDocument", "openPreview"] }, { kind: "component", type: ChartComponent, selector: "sq-assistant-chart", inputs: ["rawChartData"] }, { kind: "pipe", type: MessageContentPipe, name: "messageContent" }, { kind: "component", type: InlineImageReferenceComponent, selector: "InlineImageReference", inputs: ["id", "ref"], outputs: ["openPreview", "openDocument", "openModal"] }, { kind: "component", type: InlinePageReferenceComponent, selector: "InlinePageReference", inputs: ["id", "ref"], outputs: ["openPreview", "openDocument", "openModal"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
289
289
  }
290
290
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatMessageComponent, decorators: [{
291
291
  type: Component,
@@ -300,7 +300,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
300
300
  InlineImageReferenceComponent,
301
301
  InlinePageReferenceComponent,
302
302
  TranslocoPipe
303
- ], providers: [provideTranslocoScope('chat-message')], template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n <remark *ngIf=\"(message?.role === 'assistant' && message.messageType !== 'CHART') || message?.role === 'connection-error' || message?.role === 'search-warning'\" [markdown]=\"message.content | messageContent\" [processor]=\"processor\">\n\n <!-- Chat reference (badge with file and part number) -->\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n @let attachment = referenceMap.get(ref.refId);\n @if (attachment) {\n <a\n class=\"reference\"\n role=\"button\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n (click)=\"openAttachmentPreview(attachment, ref.refId)\"\n >\n {{ref.refId}}\n </a>\n }\n @else {\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ ref.refId }}</span>\n </ng-template>\n }\n </ng-template>\n\n <!-- Embedded reference image -->\n <ng-template remarkTemplate=\"embedded-image-reference\" let-ref>\n @let refObj = getEmbeddedImageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"imageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Img-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Embedded reference page -->\n <ng-template remarkTemplate=\"embedded-page-reference\" let-ref>\n @let refObj = getEmbeddedPageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"pageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Page-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Blinking cursor -->\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyCode(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> {{ 'chatMessage.copyCode' | transloco }}</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n <ng-template remarkTemplate=\"link\" let-node>\n <a [href]=\"node.url\" target=\"_blank\" rel=\"noopener noreferrer\">{{getLinkText(node)}}</a>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message?.role === 'user'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @if (references?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!showReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of references; track $index) {\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n @for (imageReference of imageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlineImageReference\n [id]=\"imageReference[0]\"\n [ref]=\"imageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n @for (pageReference of pageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlinePageReference\n [id]=\"pageReference[0]\"\n [ref]=\"pageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked === true\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i class=\"fa-thumbs-up {{message.additionalProperties.$liked === true ? 'fas' : 'far'}}\"></i>\n </button>\n <button class=\"btn btn-sm bounce\" [class.bounce]=\"message.additionalProperties.$disliked === true\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i class=\"fa-thumbs-down {{message.additionalProperties.$disliked === true ? 'fas' : 'far'}}\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas fa-clipboard-question\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n <ng-template #imageTooltipTpl let-ref>\n <InlineImageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #pageTooltipTpl let-ref>\n <InlinePageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference\n *ngIf=\"!hiddenTooltip\"\n class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openAttachmentPreview($event, ref.$partId)\"\n (openDocument)=\"openOriginalAttachment($event, ref.$partId)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"] }]
303
+ ], providers: [provideTranslocoScope('chat-message')], template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n <remark *ngIf=\"(message?.role === 'assistant' && message.messageType !== 'CHART') || message?.role === 'connection-error' || message?.role === 'search-warning'\" [markdown]=\"message.content | messageContent\" [processor]=\"processor\">\n\n <!-- Chat reference (badge with file and part number) -->\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n @let attachment = referenceMap.get(ref.refId);\n @if (attachment) {\n <a\n class=\"reference\"\n role=\"button\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n (click)=\"openAttachmentPreview(attachment, ref.refId)\"\n >\n {{ref.refId}}\n </a>\n }\n @else {\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ ref.refId }}</span>\n </ng-template>\n }\n </ng-template>\n\n <!-- Embedded reference image -->\n <ng-template remarkTemplate=\"embedded-image-reference\" let-ref>\n @let refObj = getEmbeddedImageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"imageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Img-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Embedded reference page -->\n <ng-template remarkTemplate=\"embedded-page-reference\" let-ref>\n @let refObj = getEmbeddedPageReference(ref.value);\n @if (refObj && refObj.url) {\n <span\n [ngClass]=\"{ 'reference': true, 'has-bounding-box': ref.boundingBox }\"\n [sqTooltip]=\"{ obj: refObj, id: ref.value }\"\n [sqTooltipTemplate]=\"pageTooltipTpl\"\n [hoverableTooltip]=\"true\"\n >\n Page-{{ ref.value }}\n </span>\n }\n </ng-template>\n\n <!-- Blinking cursor -->\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyCode(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> {{ 'chatMessage.copyCode' | transloco }}</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n <ng-template remarkTemplate=\"link\" let-node>\n <a [href]=\"node.url\" target=\"_blank\" rel=\"noopener noreferrer\">{{getLinkText(node)}}</a>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message?.role === 'user'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @if (references?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!showReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of references; track $index) {\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n @for (imageReference of imageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlineImageReference\n [id]=\"imageReference[0]\"\n [ref]=\"imageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n @for (pageReference of pageReferencesMap.entries(); track $index) {\n <li style=\"list-style-type: none;\">\n <InlinePageReference\n [id]=\"pageReference[0]\"\n [ref]=\"pageReference[1]\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </li>\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i *ngIf=\"!message.additionalProperties.$liked\" class=\"far fa-thumbs-up \"></i>\n <i *ngIf=\"message.additionalProperties.$liked\" class=\"fas fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$disliked\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i *ngIf=\"!message.additionalProperties.$disliked\" class=\"far fa-thumbs-down \"></i>\n <i *ngIf=\"message.additionalProperties.$disliked\" class=\"fas fa-thumbs-down\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas fa-clipboard-question\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n <ng-template #imageTooltipTpl let-ref>\n <InlineImageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #pageTooltipTpl let-ref>\n <InlinePageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference\n *ngIf=\"!hiddenTooltip\"\n class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openAttachmentPreview($event, ref.$partId)\"\n (openDocument)=\"openOriginalAttachment($event, ref.$partId)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"] }]
304
304
  }], ctorParameters: () => [{ type: i1.UIService }, { type: i2.PrincipalService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { message: [{
305
305
  type: Input
306
306
  }], conversation: [{
@@ -348,4 +348,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
348
348
  }], debug: [{
349
349
  type: Output
350
350
  }] } });
351
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQtbWVzc2FnZS9jaGF0LW1lc3NhZ2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNzaXN0YW50L2NoYXQvY2hhdC1tZXNzYWdlL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDMUMsT0FBTyxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLDZDQUE2QyxDQUFDO0FBQ3JELE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQztBQUNuQyxPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFhLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUU3QyxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDakUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDcEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkUsT0FBTyxFQUFFLDZCQUE2QixFQUFF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b0JBQW9CO3NCQUE1QixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csMEJBQTBCO3NCQUFsQyxLQUFLO2dCQUNHLHdCQUF3QjtzQkFBaEMsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNJLFlBQVk7c0JBQXJCLE1BQU07Z0JBSUcsV0FBVztzQkFBcEIsTUFBTTtnQkFJRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLElBQUk7c0JBQWIsTUFBTTtnQkFDRyxJQUFJO3NCQUFiLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxJQUFJO3NCQUFiLE1BQU07Z0JBQ0csT0FBTztzQkFBaEIsTUFBTTtnQkFDRyxLQUFLO3NCQUFkLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBwcm92aWRlVHJhbnNsb2NvU2NvcGUsIFRyYW5zbG9jb1BpcGUgfSBmcm9tICdAanN2ZXJzZS90cmFuc2xvY28nO1xuaW1wb3J0IHsgQ29udGVudCwgUGFyZW50LCBUZXh0IH0gZnJvbSBcIm1kYXN0XCI7XG5pbXBvcnQgeyBSZW1hcmtNb2R1bGUgfSBmcm9tIFwibmd4LXJlbWFya1wiO1xuaW1wb3J0IFwicHJpc21qcy1jb21wb25lbnRzLWltcG9ydGVyL2VzbVwiO1xuaW1wb3J0IFwicHJpc21qcy9wbHVnaW5zL2F1dG9sb2FkZXIvcHJpc20tYXV0b2xvYWRlclwiO1xuaW1wb3J0IHJlbWFya0dmbSBmcm9tIFwicmVtYXJrLWdmbVwiO1xuaW1wb3J0IHJlbWFya1BhcnNlIGZyb20gXCJyZW1hcmstcGFyc2VcIjtcbmltcG9ydCB7IFByb2Nlc3NvciwgdW5pZmllZCB9IGZyb20gXCJ1bmlmaWVkXCI7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSBcInVuaXN0XCI7XG5pbXBvcnQgeyBDT05USU5VRSwgRVhJVCwgdmlzaXQgfSBmcm9tIFwidW5pc3QtdXRpbC12aXNpdFwiO1xuXG5pbXBvcnQgeyBDaGFydENvbXBvbmVudCB9IGZyb20gXCIuLi9jaGFydHMvY2hhcnQvY2hhcnQuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBDaGF0UmVmZXJlbmNlQ29tcG9uZW50IH0gZnJvbSBcIi4uL2NoYXQtcmVmZXJlbmNlL2NoYXQtcmVmZXJlbmNlLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgSW5pdGlhbHNBdmF0YXJDb21wb25lbnQgfSBmcm9tIFwiLi4vaW5pdGlhbHMtYXZhdGFyL2luaXRpYWxzLWF2YXRhci5jb21wb25lbnRcIjtcbmltcG9ydCB7IE1lc3NhZ2VDb250ZW50UGlwZSB9IGZyb20gXCIuLi9waXBlcy9tZXNzYWdlLWNvbnRlbnQucGlwZVwiO1xuaW1wb3J0IHsgSW5saW5lSW1hZ2VSZWZlcmVuY2VDb21wb25lbnQgfSBmcm9tIFwiLi4vcmVmZXJlbmNlcy9pbmxpbmUtaW1hZ2UtcmVmZXJlbmNlXCI7XG5pbXBvcnQgeyBJbmxpbmVQYWdlUmVmZXJlbmNlQ29tcG9uZW50IH0gZnJvbSBcIi4uL3JlZmVyZW5jZXMvaW5saW5lLXBhZ2UtcmVmZXJlbmNlXCI7XG5pbXBvcnQgeyBQcmluY2lwYWxTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3ByaW5jaXBhbC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBVSVNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZXMvdWkuc2VydmljZVwiO1xuaW1wb3J0IHsgVG9vbHRpcERpcmVjdGl2ZSB9IGZyb20gXCIuLi90b29sdGlwL3Rvb2x0aXAuZGlyZWN0aXZlXCI7XG5pbXBvcnQgeyBDaGF0Q29udGV4dEF0dGFjaG1lbnQsIENoYXRNZXNzYWdlLCBTdWdnZXN0ZWRBY3Rpb24gfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFRleHRNZXNzYWdlQ29udGVudCB9IGZyb20gXCIuLi90eXBlcy9tZXNzYWdlLWNvbnRlbnQudHlwZXNcIjtcbmltcG9ydCB7IE1lc3NhZ2VJbWFnZVJlZmVyZW5jZSB9IGZyb20gXCIuLi90eXBlcy9tZXNzYWdlLXJlZmVyZW5jZS50eXBlc1wiO1xuaW1wb3J0IGVtYmVkZGVkSW1hZ2VSZWZlcmVuY2VQbHVnaW4gZnJvbSBcIi4uL3VuaWZpZWQtcGx1Z2lucy9lbWJlZGRlZC1pbWFnZS1yZWZlcmVuY2UucGx1Z2luXCI7XG5pbXBvcnQgZW1iZWRkZWRQYWdlUmVmZXJlbmNlUGx1Z2luIGZyb20gXCIuLi91bmlmaWVkLXBsdWdpbnMvZW1iZWRkZWQtcGFnZS1yZWZlcmVuY2UucGx1Z2luXCI7XG5cbmRlY2xhcmUgbW9kdWxlIFByaXNtIHtcbiAgZnVuY3Rpb24gaGlnaGxpZ2h0QWxsVW5kZXIoZWw6IEhUTUxFbGVtZW50KTogdm9pZDtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcInNxLWNoYXQtbWVzc2FnZVwiLFxuICB0ZW1wbGF0ZVVybDogXCIuL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5zY3NzXCJdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBUb29sdGlwRGlyZWN0aXZlLFxuICAgIFJlbWFya01vZHVsZSxcbiAgICBJbml0aWFsc0F2YXRhckNvbXBvbmVudCxcbiAgICBDaGF0UmVmZXJlbmNlQ29tcG9uZW50LFxuICAgIENoYXJ0Q29tcG9uZW50LFxuICAgIE1lc3NhZ2VDb250ZW50UGlwZSxcbiAgICBJbmxpbmVJbWFnZVJlZmVyZW5jZUNvbXBvbmVudCxcbiAgICBJbmxpbmVQYWdlUmVmZXJlbmNlQ29tcG9uZW50LFxuICAgIFRyYW5zbG9jb1BpcGVcbiAgXSxcbiAgcHJvdmlkZXJzOiBbcHJvdmlkZVRyYW5zbG9jb1Njb3BlKCdjaGF0LW1lc3NhZ2UnKV0sXG59KVxuZXhwb3J0IGNsYXNzIENoYXRNZXNzYWdlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcbiAgQElucHV0KCkgbWVzc2FnZTogQ2hhdE1lc3NhZ2U7XG4gIEBJbnB1dCgpIGNvbnZlcnNhdGlvbjogQ2hhdE1lc3NhZ2VbXTtcbiAgQElucHV0KCkgc3VnZ2VzdGVkQWN0aW9uczogU3VnZ2VzdGVkQWN0aW9uW10gfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGFzc2lzdGFudE1lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHVzZXJNZXNzYWdlSWNvbjogc3RyaW5nO1xuICBASW5wdXQoKSBjb25uZWN0aW9uRXJyb3JNZXNzYWdlSWNvbjogc3RyaW5nO1xuICBASW5wdXQoKSBzZWFyY2hXYXJuaW5nTWVzc2FnZUljb246IHN0cmluZztcbiAgQElucHV0KCkgc3RyZWFtaW5nOiBib29sZWFuO1xuICBASW5wdXQoKSBjYW5FZGl0OiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNhblJlZ2VuZXJhdGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY2FuQ29weTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjYW5EZWJ1ZzogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjYW5MaWtlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNhbkRpc2xpa2U6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQE91dHB1dCgpIG9wZW5Eb2N1bWVudCA9IG5ldyBFdmVudEVtaXR0ZXI8e1xuICAgIHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50O1xuICAgIHBhcnRJZD86IG51bWJlcjtcbiAgfT4oKTtcbiAgQE91dHB1dCgpIG9wZW5QcmV2aWV3ID0gbmV3IEV2ZW50RW1pdHRlcjx7XG4gICAgcmVmZXJlbmNlOiBDaGF0Q29udGV4dEF0dGFjaG1lbnQ7XG4gICAgcGFydElkPzogbnVtYmVyO1xuICB9PigpO1xuICBAT3V0cHV0KCkgc3VnZ2VzdEFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8U3VnZ2VzdGVkQWN0aW9uPigpO1xuICBAT3V0cHV0KCkgZWRpdCA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XG4gIEBPdXRwdXQoKSBjb3B5ID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0TWVzc2FnZT4oKTtcbiAgQE91dHB1dCgpIHJlZ2VuZXJhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRNZXNzYWdlPigpO1xuICBAT3V0cHV0KCkgbGlrZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGRpc2xpa2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkZWJ1ZyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XG5cbiAgcHJvY2Vzc29yOiBQcm9jZXNzb3I7XG5cbiAgcmVmZXJlbmNlczogc3RyaW5nW10gPSBbXTtcbiAgcmVmZXJlbmNlTWFwID0gbmV3IE1hcDxzdHJpbmcsIENoYXRDb250ZXh0QXR0YWNobWVudD4oKTtcbiAgaW1hZ2VSZWZlcmVuY2VzTWFwID0gbmV3IE1hcDxzdHJpbmcsIE1lc3NhZ2VJbWFnZVJlZmVyZW5jZT4oKTtcbiAgcGFnZVJlZmVyZW5jZXNNYXAgPSBuZXcgTWFwPHN0cmluZywgTWVzc2FnZUltYWdlUmVmZXJlbmNlPigpO1xuICBzaG93UmVmZXJlbmNlczogYm9vbGVhbiA9IHRydWU7XG4gIGNvbGxhcHNlUHJvZ3Jlc3M6IGJvb2xlYW47XG4gIGljb25TaXplID0gMjQ7XG5cbiAgaGlkZGVuVG9vbHRpcDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyB1aTogVUlTZXJ2aWNlLFxuICAgIHB1YmxpYyBwcmluY2lwYWxTZXJ2aWNlOiBQcmluY2lwYWxTZXJ2aWNlLFxuICAgIHB1YmxpYyBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHB1YmxpYyBlbDogRWxlbWVudFJlZlxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzLnN0cmVhbWluZykge1xuICAgICAgdGhpcy5jb2xsYXBzZVByb2dyZXNzID0gIXRoaXMuc3RyZWFtaW5nO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1lc3NhZ2U/LnJvbGUgPT09IFwiYXNzaXN0YW50XCIpIHtcbiAgICAgIHRoaXMucmVmZXJlbmNlcyA9IFtdO1xuICAgICAgdGhpcy5yZWZlcmVuY2VNYXAuY2xlYXIoKTtcbiAgICAgIGZvciAobGV0IG0gb2YgdGhpcy5jb252ZXJzYXRpb24pIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIG0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQgJiZcbiAgICAgICAgICBtLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50Lmxlbmd0aCA+IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBhdHRhY2htZW50IG9mIG0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQpIHtcbiAgICAgICAgICAgIC8vIHNraXAgZW1wdHkgYXR0YWNobWVudFxuICAgICAgICAgICAgaWYgKCFhdHRhY2htZW50KSBjb250aW51ZTtcblxuICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VNYXAuc2V0KFwiXCIgKyBhdHRhY2htZW50LmNvbnRleHRJZCwge1xuICAgICAgICAgICAgICAuLi5hdHRhY2htZW50LFxuICAgICAgICAgICAgICAkcGFydElkOiBhdHRhY2htZW50LnBhcnRzPy5bMF0/LnBhcnRJZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhYXR0YWNobWVudC5wYXJ0cyAmJiBhdHRhY2htZW50LnBhcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRhY2htZW50LnBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmSWQgPSBgJHthdHRhY2htZW50LmNvbnRleHRJZH0uJHthdHRhY2htZW50LnBhcnRzW2ldLnBhcnRJZH1gO1xuICAgICAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlTWFwLnNldChyZWZJZCwge1xuICAgICAgICAgICAgICAgICAgLi4uYXR0YWNobWVudCxcbiAgICAgICAgICAgICAgICAgICRwYXJ0SWQ6IGF0dGFjaG1lbnQucGFydHM/LltpXT8ucGFydElkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wcm9jZXNzTWVzc2FnZVR5cGUobSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucHJvY2Vzc29yID0gdW5pZmllZCgpXG4gICAgICAgIC51c2UocmVtYXJrUGFyc2UpXG4gICAgICAgIC51c2UocmVtYXJrR2ZtKVxuICAgICAgICAudXNlKCgpID0+IHRoaXMucmVmZXJlbmNlUGx1Z2luKVxuICAgICAgICAudXNlKCgpID0+IGVtYmVkZGVkSW1hZ2VSZWZlcmVuY2VQbHVnaW4pXG4gICAgICAgIC51c2UoKCkgPT4gZW1iZWRkZWRQYWdlUmVmZXJlbmNlUGx1Z2luKTtcblxuICAgICAgaWYgKHRoaXMuc3RyZWFtaW5nKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc29yID0gdGhpcy5wcm9jZXNzb3IudXNlKCgpID0+IHRoaXMucGxhY2Vob2xkZXJQbHVnaW4pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBQcmlzbT8uaGlnaGxpZ2h0QWxsVW5kZXI/Lih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgZ2V0RW1iZWRkZWRJbWFnZVJlZmVyZW5jZShyZWY6IHN0cmluZyk6IE1lc3NhZ2VJbWFnZVJlZmVyZW5jZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgW2RvYywgcGFydCwgaW1hZ2VdID0gcmVmLnNwbGl0KFwiLlwiKTtcbiAgICBjb25zdCBpbWFnZXMgPSB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucGFydHM/LlsrcGFydCAtIDFdPy5pbWFnZXM7XG5cbiAgICBpZiAoIWltYWdlcyB8fCBpbWFnZXMubGVuZ3RoID09PSAwIHx8IHR5cGVvZiBpbWFnZXNbMF0gIT09IFwib2JqZWN0XCIpXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgbWVzc2FnZUltYWdlUmVmZXJlbmNlOiBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICBhcnRpY2xlOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkLFxuICAgICAgICBhcnRpY2xlSWQ6IHRoaXMucmVmZXJlbmNlTWFwLmdldChkb2MpPy5yZWNvcmRJZCxcbiAgICAgIH0sXG4gICAgICBpbWFnZXNbK2ltYWdlIC0gMV1cbiAgICApO1xuXG4gICAgLy8gc2F2ZSByZWZlcmVuY2UgaW4gbWFwIGZvciByZWZlcmVuY2UgbGlzdFxuICAgIGlmICghdGhpcy5pbWFnZVJlZmVyZW5jZXNNYXAuaGFzKHJlZikpXG4gICAgICB0aGlzLmltYWdlUmVmZXJlbmNlc01hcC5zZXQocmVmLCBtZXNzYWdlSW1hZ2VSZWZlcmVuY2UpO1xuXG4gICAgcmV0dXJuIG1lc3NhZ2VJbWFnZVJlZmVyZW5jZTtcbiAgfVxuXG4gIGdldEVtYmVkZGVkUGFnZVJlZmVyZW5jZShyZWY6IHN0cmluZyk6IE1lc3NhZ2VJbWFnZVJlZmVyZW5jZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgW2RvYywgcGFnZV0gPSByZWYuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IHBhZ2VSZWYgPSB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucGFnZXM/LmZpbmQoeCA9PiB4LnBhZ2VOdW1iZXIgPT09ICtwYWdlKTtcbiAgICBcbiAgICBpZiAoIXBhZ2VSZWYgfHwgdHlwZW9mIHBhZ2VSZWYgIT09IFwib2JqZWN0XCIpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBtZXNzYWdlUGFnZVJlZmVyZW5jZTogTWVzc2FnZUltYWdlUmVmZXJlbmNlID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHtcbiAgICAgICAgYXJ0aWNsZTogdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnJlY29yZCxcbiAgICAgICAgYXJ0aWNsZUlkOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkSWQsXG4gICAgICB9LFxuICAgICAgcGFnZVJlZlxuICAgICk7XG5cbiAgICAvLyBzYXZlIHJlZmVyZW5jZSBpbiBtYXAgZm9yIHJlZmVyZW5jZSBsaXN0XG4gICAgaWYgKCF0aGlzLnBhZ2VSZWZlcmVuY2VzTWFwLmhhcyhyZWYpKVxuICAgICAgdGhpcy5wYWdlUmVmZXJlbmNlc01hcC5zZXQocmVmLCBtZXNzYWdlUGFnZVJlZmVyZW5jZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZVBhZ2VSZWZlcmVuY2U7XG4gIH1cblxuICBnZXQgbmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAhdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbFxuICAgICAgPyBcIlwiXG4gICAgICA6ICh0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsW1wiZnVsbE5hbWVcIl0gYXMgc3RyaW5nKSB8fFxuICAgICAgICAgIHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwubmFtZTtcbiAgfVxuXG4gIGdldCBpc0FkbWluKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsPy5pc0FkbWluaXN0cmF0b3IgfHwgZmFsc2U7XG4gIH1cblxuICBwcm9jZXNzTWVzc2FnZVR5cGUobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcbiAgICAvLyBQcm9jZXNzIG1lc3NhZ2UgdHlwZSB3aGVuIHNwZWMgaXMgZG9uZVxuICAgIC8vIG5vcCBmb3IgbmV3IG1lc3NhZ2UgdHlwZXNcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuO1xuXG4gICAgLy8gTGVnYWN5IG1lc3NhZ2UgdHlwZVxuICAgIGlmIChtZXNzYWdlLmNvbnRlbnQuc3RhcnRzV2l0aChcIjxjaGFydGpzPlwiKSkge1xuICAgICAgbWVzc2FnZS5tZXNzYWdlVHlwZSA9IFwiQ0hBUlRcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVzc2FnZS5tZXNzYWdlVHlwZSA9IFwiTUFSS0RPV05cIjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBVbmlmaWVkIHBsdWdpbiBsb29rcyBhIHRleHQgbm9kZXMgYW5kIHJlcGxhY2VzIGFueSByZWZlcmVuY2UgaW4gdGhlXG4gICAqIGZvcm0gWzFdLCBbMi4zXSwgZXRjLiB3aXRoIGN1c3RvbSBub2RlcyBvZiB0eXBlIFwiY2hhdC1yZWZlcmVuY2VcIi5cbiAgICovXG4gIHJlZmVyZW5jZVBsdWdpbiA9ICh0cmVlOiBOb2RlKSA9PiB7XG4gICAgY29uc3QgcmVmZXJlbmNlcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuXG4gICAgLy8gVmlzaXQgYWxsIHRleHQgbm9kZXNcbiAgICB2aXNpdCh0cmVlLCBcInRleHRcIiwgKG5vZGU6IFRleHQsIGluZGV4OiBudW1iZXIsIHBhcmVudDogUGFyZW50KSA9PiB7XG4gICAgICBsZXQgdGV4dCA9IG5vZGUudmFsdWU7XG5cbiAgICAgIHRleHQgPSB0aGlzLnJlZm9ybWF0UmVmZXJlbmNlcyh0ZXh0KTtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLmdldFJlZmVyZW5jZU1hdGNoZXModGV4dCk7XG5cbiAgICAgIC8vIFF1aXQgaWYgbm8gcmVmZXJlbmNlcyB3ZXJlIGZvdW5kXG4gICAgICBpZiAobWF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIENPTlRJTlVFO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlczogKENvbnRlbnQgJiB7IGVuZDogbnVtYmVyIH0pW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBtYXRjaCBvZiBtYXRjaGVzKSB7XG4gICAgICAgIGNvbnN0IHJlZklkID0gbWF0Y2hbMV0udHJpbSgpO1xuICAgICAgICBjb25zdCBbcmVmXSA9IHJlZklkLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgLy8gV2UgZmluZCBhIHZhbGlkIHJlZmVyZW5jZSBpbiB0aGUgdGV4dFxuICAgICAgICBpZiAoIWlzTmFOKCtyZWYpKSB7XG4gICAgICAgICAgcmVmZXJlbmNlcy5hZGQoK3JlZik7IC8vIEFkZCBpdCB0byB0aGUgc2V0IG9mIHVzZWQgcmVmZXJlbmNlc1xuXG4gICAgICAgICAgLy8gSWYgbmVlZGVkLCBpbnNlcnQgYSB0ZXh0IG5vZGUgYmVmb3JlIHRoZSByZWZlcmVuY2VcbiAgICAgICAgICBjb25zdCBjdXJyZW50ID0gbm9kZXMuYXQoLTEpID8/IHsgZW5kOiAwIH07XG4gICAgICAgICAgaWYgKG1hdGNoLmluZGV4ISA+IGN1cnJlbnQuZW5kKSB7XG4gICAgICAgICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHZhbHVlOiB0ZXh0LnN1YnN0cmluZyhjdXJyZW50LmVuZCwgbWF0Y2guaW5kZXghKSxcbiAgICAgICAgICAgICAgZW5kOiBtYXRjaC5pbmRleCEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBBZGQgYSBjdXN0b20gcmVmZXJlbmNlIG5vZGVcbiAgICAgICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6IFwiY2hhdC1yZWZlcmVuY2VcIixcbiAgICAgICAgICAgIHJlZklkLFxuICAgICAgICAgICAgZW5kOiBtYXRjaC5pbmRleCEgKyBtYXRjaFswXS5sZW5ndGgsXG4gICAgICAgICAgfSBhcyBhbnkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFF1aXQgaWYgbm8gcmVmZXJlbmNlcyB3ZXJlIGZvdW5kXG4gICAgICBpZiAobm9kZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBDT05USU5VRTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVzLmF0KC0xKSEuZW5kIDwgdGV4dC5sZW5ndGgpIHtcbiAgICAgICAgbm9kZXMucHVzaCh7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdmFsdWU6IHRleHQuc3Vic3RyaW5nKG5vZGVzLmF0KC0xKSEuZW5kLCB0ZXh0Lmxlbmd0aCksXG4gICAgICAgICAgZW5kOiB0ZXh0Lmxlbmd0aCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIERlbGV0ZSB0aGUgY3VycmVudCB0ZXh0IG5vZGUgZnJvbSB0aGUgcGFyZW50IGFuZCByZXBsYWNlIGl0IHdpdGggdGhlIG5ldyBub2Rlc1xuICAgICAgcGFyZW50LmNoaWxkcmVuLnNwbGljZShpbmRleCwgMSwgLi4ubm9kZXMpO1xuXG4gICAgICByZXR1cm4gaW5kZXggKyBub2Rlcy5sZW5ndGg7IC8vIFZpc2l0IHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGluc2VydGVkIG9uZXNcbiAgICB9KTtcblxuICAgIGlmIChyZWZlcmVuY2VzLnNpemUgPiAwKSB7XG4gICAgICB0aGlzLnJlZmVyZW5jZXMgPSBBcnJheS5mcm9tKHJlZmVyZW5jZXMudmFsdWVzKCkpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhIC0gYilcbiAgICAgICAgLm1hcCgocikgPT4gXCJcIiArIHIpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIHJldHVybiB0cmVlO1xuICB9O1xuXG4gIHBsYWNlaG9sZGVyUGx1Z2luID0gKHRyZWU6IE5vZGUpID0+IHtcbiAgICB2aXNpdChcbiAgICAgIHRyZWUsXG4gICAgICBcInRleHRcIixcbiAgICAgIChub2RlOiBUZXh0LCBpbmRleDogbnVtYmVyLCBwYXJlbnQ6IFBhcmVudCkgPT4ge1xuICAgICAgICBwYXJlbnQuY2hpbGRyZW4ucHVzaCh7IHR5cGU6IFwic3RyZWFtaW5nLXBsYWNlaG9sZGVyXCIgfSBhcyBhbnkpO1xuICAgICAgICByZXR1cm4gRVhJVDtcbiAgICAgIH0sXG4gICAgICB0cnVlXG4gICAgKTtcblxuICAgIHJldHVybiB0cmVlO1xuICB9O1xuXG4gIGdldExpbmtUZXh0KG5vZGU6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKG5vZGUudGV4dCkge1xuICAgICAgcmV0dXJuIG5vZGUudGV4dDsgLy8gUmV0dXJuIGRpcmVjdGx5IGlmIHRleHQgaXMgcHJvdmlkZWQgaW4gbm9kZS50ZXh0IChbRXhhbXBsZSBsaW5rXShodHRwczovL2V4YW1wbGUuY29tKSlcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGRyZW4gJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBSZWN1cnNpdmVseSBzZWFyY2ggZm9yIHRleHQgY29udGVudCBpbiBjaGlsZCBub2Rlc1xuICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBub2RlLmNoaWxkcmVuKSB7XG4gICAgICAgIGlmIChjaGlsZC50eXBlID09PSBcInRleHRcIiAmJiBjaGlsZC52YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBjaGlsZC52YWx1ZTsgLy8gUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgdGV4dCBub2RlIGZvdW5kIChbKipFbXBoYXNpemVkIExpbmsgVGV4dCoqXShodHRwczovL2V4YW1wbGUuY29tKSlcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5jaGlsZHJlbiAmJiBjaGlsZC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgdGV4dENvbnRlbnQgPSB0aGlzLmdldExpbmtUZXh0KGNoaWxkKTsgLy8gUmVjdXJzaXZlbHkgc2VhcmNoIGNoaWxkIG5vZGVzIChbIVtFeGFtcGxlIGltYWdlXShodHRwczovL2V4YW1wbGUuY29tL2ltYWdlLnBuZyldKGh0dHBzOi8vZXhhbXBsZS5jb20pKVxuICAgICAgICAgIGlmICh0ZXh0Q29udGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRleHRDb250ZW50OyAvLyBSZXR1cm4gdGV4dCBjb250ZW50IGlmIGZvdW5kXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBcImxpbmtcIjsgLy8gUmV0dXJuIGVtcHR5IHN0cmluZyBpZiBubyB0ZXh0IGNvbnRlbnQgaXMgZm91bmRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZvcm1hdCBbaWRzOiAxMi4yLCA0Mi41XSB0byBbMTIuMl1bNDIuNV1cbiAgICovXG4gIHJlZm9ybWF0UmVmZXJlbmNlcyhjb250ZW50OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKFxuICAgICAgL1xcWyg/Omlkcz86P1xccyopPyg/OmRvY3VtZW50cz86P1xccyopPyhcXHMqKD86LD9cXHMqXFxkKyg/OlxcLlxcZCspPyg/OlxcLnBhcnQpP1xccyopKylcXF0vZyxcbiAgICAgIChzdHIsIG1hdGNoOiBzdHJpbmcpID0+XG4gICAgICAgIGBbJHttYXRjaFxuICAgICAgICAgIC5yZXBsYWNlKC9cXC5wYXJ0L2csIFwiXCIpXG4gICAgICAgICAgLnNwbGl0KFwiLFwiKVxuICAgICAgICAgIC5qb2luKFwiXSBbXCIpfV1gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXRjaCBhbGwgcmVmZXJlbmNlcyBpbiBhIGdpdmVuIG1lc3NhZ2VcbiAgICovXG4gIGdldFJlZmVyZW5jZU1hdGNoZXMoY29udGVudDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oY29udGVudC5tYXRjaEFsbCgvXFxbKFxccypcXGQrKD86XFwuXFxkKyk/XFxzKilcXF0vZykpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29weVRvQ2xpcGJvYXJkKGNvbnRlbnQ6IHN0cmluZykge1xuICAgIHRoaXMudWkuY29weVRvQ2xpcGJvYXJkKGNvbnRlbnQpO1xuICB9XG5cbiAgY29weU1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcbiAgICBsZXQgY29udGVudDogc3RyaW5nID0gXCJcIjtcblxuICAgIGlmICh0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSBcInN0cmluZ1wiKVxuICAgICAgY29udGVudCA9IG1lc3NhZ2UuY29udGVudDtcbiAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KG1lc3NhZ2UuY29udGVudCkpXG4gICAgICBjb250ZW50ID0gKG1lc3NhZ2UuY29udGVudFswXSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpLnRleHQ7XG4gICAgZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiVW5zdXBwb3J0ZWQgbWVzc2FnZSBjb250ZW50IHR5cGVcIiwgdHlwZW9mIG1lc3NhZ2UuY29udGVudCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2VBbGwoL1xccytcXFsuKz9cXF0vZywgXCJcIik7XG5cbiAgICB0aGlzLl9jb3B5VG9DbGlwYm9hcmQoY29udGVudCk7XG4gICAgdGhpcy5jb3B5LmVtaXQobWVzc2FnZSk7XG4gIH1cblxuICBjb3B5Q29kZShjb2RlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9jb3B5VG9DbGlwYm9hcmQoY29kZSk7XG4gIH1cblxuICBvcGVuQXR0YWNobWVudFByZXZpZXcoYXR0YWNobWVudDogQ2hhdENvbnRleHRBdHRhY2htZW50LCBwYXJ0SWQ/OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZW5QcmV2aWV3LmVtaXQoeyByZWZlcmVuY2U6IGF0dGFjaG1lbnQsIHBhcnRJZCB9KTtcbiAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gIH1cblxuICBvcGVuT3JpZ2luYWxBdHRhY2htZW50KGF0dGFjaG1lbnQ6IENoYXRDb250ZXh0QXR0YWNobWVudCwgcGFydElkPzogbnVtYmVyKSB7XG4gICAgdGhpcy5vcGVuRG9jdW1lbnQuZW1pdCh7IHJlZmVyZW5jZTogYXR0YWNobWVudCwgcGFydElkIH0pO1xuICAgIHRoaXMuaGlkZVRvb2x0aXAoKTtcbiAgfVxuXG4gIGhpZGVUb29sdGlwKCk6IHZvaWQge1xuICAgIHRoaXMuaGlkZGVuVG9vbHRpcCA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmhpZGRlblRvb2x0aXAgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxufVxuIiwiPCEtLSBNZXNzYWdlIGljb24gLS0+XG48c3BhbiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFt0aXRsZV09XCJtZXNzYWdlPy5yb2xlXCI+XG4gIDxpIGNsYXNzPVwiZC1ibG9ja1wiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiICpuZ0lmPVwiIW1lc3NhZ2VcIj48L2k+XG4gIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cIm1lc3NhZ2U/LnJvbGVcIj5cbiAgICA8IS0tIEZvciAnYXNzaXN0YW50JyAtLT5cbiAgICA8aSAqbmdTd2l0Y2hDYXNlPVwiJ2Fzc2lzdGFudCdcIiBbbmdDbGFzc109XCJhc3Npc3RhbnRNZXNzYWdlSWNvblwiIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIj48L2k+XG5cbiAgICA8IS0tIEZvciAndXNlcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3VzZXInXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhdXNlck1lc3NhZ2VJY29uOyBlbHNlIGluaXRpYWxzQXZhdGFyXCIgW25nQ2xhc3NdPVwidXNlck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjaW5pdGlhbHNBdmF0YXI+XG4gICAgICAgIDxzcS1pbml0aWFscy1hdmF0YXIgW2Z1bGxOYW1lXT1cIm5hbWVcIj48L3NxLWluaXRpYWxzLWF2YXRhcj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnY29ubmVjdGlvbi1lcnJvcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2Nvbm5lY3Rpb24tZXJyb3InXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdEVycm9ySWNvblwiIFtuZ0NsYXNzXT1cImNvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEVycm9ySWNvbj5cbiAgICAgICAgPHN2ZyBbc3R5bGUuLS1zcS1zaXplLnB4XT1cImljb25TaXplXCIgY2xhc3M9XCJjb25uZWN0aW9uLWVycm9yXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgNTEyIDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTE3LjEgMjkyYy0xMi45LTIyLjMtMTIuOS00OS43IDAtNzJMMTA1LjQgNjcuMWMxMi45LTIyLjMgMzYuNi0zNiA2Mi40LTM2bDE3Ni42IDBjMjUuNyAwIDQ5LjUgMTMuNyA2Mi40IDM2TDQ5NC45IDIyMGMxMi45IDIyLjMgMTIuOSA0OS43IDAgNzJMNDA2LjYgNDQ0LjljLTEyLjkgMjIuMy0zNi42IDM2LTYyLjQgMzZsLTE3Ni42IDBjLTI1LjcgMC00OS41LTEzLjctNjIuNC0zNkwxNy4xIDI5MnpNMjU2IDEyOGMtMTMuMyAwLTI0IDEwLjctMjQgMjRsMCAxMTJjMCAxMy4zIDEwLjcgMjQgMjQgMjRzMjQtMTAuNyAyNC0yNGwwLTExMmMwLTEzLjMtMTAuNy0yNC0yNC0yNHptMzIgMjI0YTMyIDMyIDAgMSAwIC02NCAwIDMyIDMyIDAgMSAwIDY0IDB6XCIvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnc2VhcmNoLXdhcm5pbmcnIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzZWFyY2gtd2FybmluZydcIj5cbiAgICAgIDxpICpuZ0lmPVwiISFzZWFyY2hXYXJuaW5nTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdFdhcm5pbmdJY29uXCIgW25nQ2xhc3NdPVwic2VhcmNoV2FybmluZ01lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFdhcm5pbmdJY29uPlxuICAgICAgICA8c3ZnIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIiBjbGFzcz1cInNlYXJjaC13YXJuaW5nXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMzg0IDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTI3MiAzODRjOS42LTMxLjkgMjkuNS01OS4xIDQ5LjItODYuMmMwIDAgMCAwIDAgMGM1LjItNy4xIDEwLjQtMTQuMiAxNS40LTIxLjRjMTkuOC0yOC41IDMxLjQtNjMgMzEuNC0xMDAuM0MzNjggNzguOCAyODkuMiAwIDE5MiAwUzE2IDc4LjggMTYgMTc2YzAgMzcuMyAxMS42IDcxLjkgMzEuNCAxMDAuM2M1IDcuMiAxMC4yIDE0LjMgMTUuNCAyMS40YzAgMCAwIDAgMCAwYzE5LjggMjcuMSAzOS43IDU0LjQgNDkuMiA4Ni4ybDE2MCAwek0xOTIgNTEyYzQ0LjIgMCA4MC0zNS44IDgwLTgwbDAtMTYtMTYwIDAgMCAxNmMwIDQ0LjIgMzUuOCA4MCA4MCA4MHptMC00NDhjMTMuMyAwIDI0IDEwLjcgMjQgMjRsMCAxMTJjMCAxMy4zLTEwLjcgMjQtMjQgMjRzLTI0LTEwLjctMjQtMjRsMC0xMTJjMC0xMy4zIDEwLjctMjQgMjQtMjR6TTE2MCAyODhhMzIgMzIgMCAxIDEgNjQgMCAzMiAzMiAwIDEgMSAtNjQgMHpcIi8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L3NwYW4+XG5cbjwhLS0gTWVzc2FnZSBib2R5IC0tPlxuPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xIHBvc2l0aW9uLXJlbGF0aXZlIHJlbGF0aXZlXCIgc3R5bGU9XCJtaW4td2lkdGg6IDA7XCIgW25nQ2xhc3NdPVwiJ21lc3NhZ2UtJyttZXNzYWdlLnJvbGVcIj5cblxuICA8IS0tIFByb2dyZXNzIHN0ZXBzIC0tPlxuICA8ZGl2ICpuZ0lmPVwibWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kcHJvZ3Jlc3MgYXMgcHJvZ3Jlc3NcIiBjbGFzcz1cInNtYWxsIG1zLTMgbWItMlwiPlxuICAgIDxkZXRhaWxzIHJvbGU9XCJidXR0b25cIiBjbGFzcz1cInNlbGVjdC1ub25lXCIgW29wZW5dPVwiIWNvbGxhcHNlUHJvZ3Jlc3NcIj5cbiAgICAgIDxzdW1tYXJ5IGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgICAgICB7eyAnY2hhdE1lc3NhZ2Uudmlld1Byb2dyZXNzJyB8IHRyYW5zbG9jbyB9fVxuICAgICAgPC9zdW1tYXJ5PlxuICAgICAgPHVsIGNsYXNzPVwibGlzdC11bnN0eWxlZFwiPlxuICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHN0ZXAgb2YgcHJvZ3Jlc3NcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1mdyBmYS1jaGVjayB0ZXh0LXN1Y2Nlc3NcIiAqbmdJZj1cInN0ZXAuZG9uZVwiPjwvaT5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zcGlubmVyIGZhLXB1bHNlIHN0ZXAtb25nb2luZ1wiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiBzdHJlYW1pbmdcIj48L2k+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYS1zb2xpZCBmYS1iYW4gc3RlcC1lcnJvclwiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiAhc3RyZWFtaW5nXCI+PC9pPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXMtMiBmdy1ib2xkXCI+e3tzdGVwLnRpdGxlfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdGVwLmNvbnRlbnRcIiBbaW5uZXJIVE1MXT1cIic6ICcgKyBzdGVwLmNvbnRlbnRcIj48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGV0YWlscz5cbiAgPC9kaXY+XG5cbiAgPCEtLSBNZXNzYWdlIGNvbnRlbnQgLS0+XG4gIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWNvbnRlbnRcIiAqbmdJZj1cIm1lc3NhZ2UuY29udGVudFwiPlxuXG4gICAgPCEtLSBDdXN0b20gcmVuZGVyaW5nIGZvciBXUFMsIHRvIGJlIHJlbW92ZSB3aXRoIGh0dHBzOi8vc2luZXF1YS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9FUy0yMzcxMCAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwibWVzc2FnZT8ucm9sZSA9PT0gJ2Fzc2lzdGFudCcgJiYgbWVzc2FnZS5tZXNzYWdlVHlwZSA9PT0gJ0NIQVJUJ1wiPlxuICAgICAgPHNxLWFzc2lzdGFudC1jaGFydCBbcmF3Q2hhcnREYXRhXT1cIm1lc3NhZ2UuY29udGVudFwiPjwvc3EtYXNzaXN0YW50LWNoYXJ0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBUaGlzIHNlY3Rpb24gaXMgcmVzcG9uc2libGUgZm9yIGN1c3RvbWl6aW5nIHRoZSB0ZW1wbGF0ZSBub2RlcyB1c2VkIGluIHRoZSBhcHBsaWNhdGlvbi5cbiAgICAgICAgVGVtcGxhdGUgbm9kZXMgYXJlIHByZWRlZmluZWQgc3RydWN0dXJlcyB0aGF0IHNlcnZlIGFzIGJsdWVwcmludHMgZm9yIGNyZWF0aW5nL2N1c3RvbWl6aW5nIGR5bmFtaWMgY29udGVudCAtLT5cbiAgICA8cmVtYXJrICpuZ0lmPVwiKG1lc3NhZ2U/LnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIG1lc3NhZ2UubWVzc2FnZVR5cGUgIT09ICdDSEFSVCcpIHx8IG1lc3NhZ2U/LnJvbGUgPT09ICdjb25uZWN0aW9uLWVycm9yJyB8fCBtZXNzYWdlPy5yb2xlID09PSAnc2VhcmNoLXdhcm5pbmcnXCIgW21hcmtkb3duXT1cIm1lc3NhZ2UuY29udGVudCB8IG1lc3NhZ2VDb250ZW50XCIgW3Byb2Nlc3Nvcl09XCJwcm9jZXNzb3JcIj5cblxuICAgICAgPCEtLSBDaGF0IHJlZmVyZW5jZSAoYmFkZ2Ugd2l0aCBmaWxlIGFuZCBwYXJ0IG51bWJlcikgLS0+XG4gICAgICA8bmctdGVtcGxhdGUgcmVtYXJrVGVtcGxhdGU9XCJjaGF0LXJlZmVyZW5jZVwiIGxldC1yZWY+XG4gICAgICAgIEBsZXQgYXR0YWNobWVudCA9IHJlZmVyZW5jZU1hcC5nZXQocmVmLnJlZklkKTtcbiAgICAgICAgQGlmIChhdHRhY2htZW50KSB7XG4gICAgICAgICAgPGFcbiAgICAgICAgICAgIGNsYXNzPVwicmVmZXJlbmNlXCJcbiAgICAgICAgICAgIHJvbGU9XCJidXR0b25cIlxuICAgICAgICAgICAgW3NxVG9vbHRpcF09XCJhdHRhY2htZW50XCJcbiAgICAgICAgICAgIFtzcVRvb2x0aXBUZW1wbGF0ZV09XCJ0b29sdGlwVHBsXCJcbiAgICAgICAgICAgIFtob3ZlcmFibGVUb29sdGlwXT1cInRydWVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5BdHRhY2htZW50UHJldmlldyhhdHRhY2htZW50LCByZWYucmVmSWQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7e3JlZi5yZWZJZH19XG4gICAgICAgICAgPC9hPlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8bmctdGVtcGxhdGUgI3N0YXRpY1JlZlRwbD5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVmZXJlbmNlXCI+e3sgcmVmLnJlZklkIH19PC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIH1cbiAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDwhLS0gRW1iZWRkZWQgcmVmZXJlbmNlIGltYWdlIC0tPlxuICAgICAgPG5nLXRlbXBsYXRlIHJlbWFya1RlbXBsYXRlPVwiZW1iZWRkZWQtaW1hZ2UtcmVmZXJlbmNlXCIgbGV0LXJlZj5cbiAgICAgICAgQGxldCByZWZPYmogPSBnZXRFbWJlZGRlZEltYWdlUmVmZXJlbmNlKHJlZi52YWx1ZSk7XG4gICAgICAgIEBpZiAocmVmT2JqICYmIHJlZk9iai51cmwpIHtcbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAncmVmZXJlbmNlJzogdHJ1ZSwgJ2hhcy1ib3VuZGluZy1ib3gnOiByZWYuYm91bmRpbmdCb3ggfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwXT1cInsgb2JqOiByZWZPYmosIGlkOiByZWYudmFsdWUgfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwVGVtcGxhdGVdPVwiaW1hZ2VUb29sdGlwVHBsXCJcbiAgICAgICAgICAgIFtob3ZlcmFibGVUb29sdGlwXT1cInRydWVcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEltZy17eyByZWYudmFsdWUgfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDwhLS0gRW1iZWRkZWQgcmVmZXJlbmNlIHBhZ2UgLS0+XG4gICAgICA8bmctdGVtcGxhdGUgcmVtYXJrVGVtcGxhdGU9XCJlbWJlZGRlZC1wYWdlLXJlZmVyZW5jZVwiIGxldC1yZWY+XG4gICAgICAgIEBsZXQgcmVmT2JqID0gZ2V0RW1iZWRkZWRQYWdlUmVmZXJlbmNlKHJlZi52YWx1ZSk7XG4gICAgICAgIEBpZiAocmVmT2JqICYmIHJlZk9iai51cmwpIHtcbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAncmVmZXJlbmNlJzogdHJ1ZSwgJ2hhcy1ib3VuZGluZy1ib3gnOiByZWYuYm91bmRpbmdCb3ggfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwXT1cInsgb2JqOiByZWZPYmosIGlkOiByZWYudmFsdWUgfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwVGVtcGxhdGVdPVwicGFnZVRvb2x0aXBUcGxcIlxuICAgICAgICAgICAgW2hvdmVyYWJsZVRvb2x0aXBdPVwidHJ1ZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgUGFnZS17eyByZWYudmFsdWUgfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDwhLS0gQmxpbmtpbmcgY3Vyc29yIC0tPlxuICAgICAgPG5nLXRlbXBsYXRlIHJlbWFya1RlbXBsYXRlPVwic3RyZWFtaW5nLXBsYWNlaG9sZGVyXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwicGxhY2Vob2xkZXItZ2xvd1wiICpuZ0lmPVwic3RyZWFtaW5nXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbGFjZWhvbGRlciBtcy0xXCI+PC9zcGFuPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICA8bmctdGVtcGxhdGUgcmVtYXJrVGVtcGxhdGU9XCJjb2RlXCIgbGV0LW5vZGU+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkIG1iLTJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgPHNwYW4+e3tub2RlLmxhbmd9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpZ2h0IGJ0bi1zbVwiIChjbGljayk9XCJjb3B5Q29kZShub2RlLnZhbHVlKVwiPjxpIGNsYXNzPVwiZmFyIGZhLWZ3IGZhLWNsaXBib2FyZFwiPjwvaT4ge3sgJ2NoYXRNZXNzYWdlLmNvcHlDb2RlJyB8IHRyYW5zbG9jbyB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxwcmUgY2xhc3M9XCJsYW5ndWFnZS17e25vZGUubGFuZ319IG15LTAgcm91bmRlZC0wIHJvdW5kZWQtYm90dG9tXCI+PGNvZGUgY2xhc3M9XCJsYW5ndWFnZS17e25vZGUubGFuZ319XCI+e3tub2RlLnZhbHVlfX08L2NvZGU+PC9wcmU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPG5nLXRlbXBsYXRlIHJlbWFya1RlbXBsYXRlPVwibGlua1wiIGxldC1ub2RlPlxuICAgICAgICA8YSBbaHJlZl09XCJub2RlLnVybFwiIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIj57e2dldExpbmtUZXh0KG5vZGUpfX08L2E+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPC9yZW1hcms+XG5cbiAgICA8cCAqbmdJZj1cIm1lc3NhZ2U/LnJvbGUgPT09ICd1c2VyJ1wiPnt7IG1lc3NhZ2UuY29udGVudCB8IG1lc3NhZ2VDb250ZW50IH19PC9wPlxuXG4gICAgPCEtLSBMaXN0IG9mIHJlZmVyZW5jZSwgaWYgYW55IC0tPlxuICAgIEBpZiAocmVmZXJlbmNlcz8ubGVuZ3RoID4gMCB8fCBpbWFnZVJlZmVyZW5jZXNNYXA/LnNpemUgPiAwIHx8IHBhZ2VSZWZlcmVuY2VzTWFwPy5zaXplID4gMCkge1xuICAgICAgPGRpdiBjbGFzcz1cInJlZmVyZW5jZXNcIj5cbiAgICAgICAgPGRldGFpbHMgcm9sZT1cImJ1dHRvblwiIGNsYXNzPVwic2VsZWN0LW5vbmVcIiBbb3Blbl09XCIhc2hvd1JlZmVyZW5jZXNcIj5cbiAgICAgICAgICA8c3VtbWFyeSBjbGFzcz1cInJlZmVyZW5jZXMtdGl0bGVcIj57eyAnY2hhdE1lc3NhZ2UucmVmZXJlbmNlcycgfCB0cmFuc2xvY28gfX08L3N1bW1hcnk+XG4gICAgICAgICAgPHVsPlxuICAgICAgICAgICAgQGZvciAocmVmZXJlbmNlIG9mIHJlZmVyZW5jZXM7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgICA8bGkgKm5nSWY9XCJyZWZlcmVuY2VNYXAuZ2V0KHJlZmVyZW5jZSkgYXMgYXR0YWNobWVudFwiICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICA8c3EtY2hhdC1yZWZlcmVuY2VcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5leHBhbmRlZF09XCJhdHRhY2htZW50LiRleHBhbmRlZFwiXG4gICAgICAgICAgICAgICAgICBbYXR0YWNobWVudF09XCJhdHRhY2htZW50XCJcbiAgICAgICAgICAgICAgICAgIFtyZWZlcmVuY2VdPVwicmVmZXJlbmNlXCJcbiAgICAgICAgICAgICAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgIDwvc3EtY2hhdC1yZWZlcmVuY2U+XG4gICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChpbWFnZVJlZmVyZW5jZSBvZiBpbWFnZVJlZmVyZW5jZXNNYXAuZW50cmllcygpOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgPGxpIHN0eWxlPVwibGlzdC1zdHlsZS10eXBlOiBub25lO1wiPlxuICAgICAgICAgICAgICAgIDxJbmxpbmVJbWFnZVJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgW2lkXT1cImltYWdlUmVmZXJlbmNlWzBdXCJcbiAgICAgICAgICAgICAgICAgIFtyZWZdPVwiaW1hZ2VSZWZlcmVuY2VbMV1cIlxuICAgICAgICAgICAgICAgICAgKG9wZW5QcmV2aWV3KT1cIm9wZW5BdHRhY2htZW50UHJldmlldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChvcGVuRG9jdW1lbnQpPVwib3Blbk9yaWdpbmFsQXR0YWNobWVudCgkZXZlbnQsICRldmVudC4kcGFydElkKVwiXG4gICAgICAgICAgICAgICAgICAob3Blbk1vZGFsKT1cImhpZGVUb29sdGlwKClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChwYWdlUmVmZXJlbmNlIG9mIHBhZ2VSZWZlcmVuY2VzTWFwLmVudHJpZXMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIDxsaSBzdHlsZT1cImxpc3Qtc3R5bGUtdHlwZTogbm9uZTtcIj5cbiAgICAgICAgICAgICAgICA8SW5saW5lUGFnZVJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgW2lkXT1cInBhZ2VSZWZlcmVuY2VbMF1cIlxuICAgICAgICAgICAgICAgICAgW3JlZl09XCJwYWdlUmVmZXJlbmNlWzFdXCJcbiAgICAgICAgICAgICAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgICAgICAgICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cblxuICAgIDwhLS0gRWRpdCAvIFJlZ2VuZXJhdGUgZmxvYXRpbmcgYWN0aW9ucyAtLT5cbiAgPGRpdiBjbGFzcz1cInNxLWNoYXQtbWVzc2FnZS1hY3Rpb25zXCIgKm5nSWY9XCJtZXNzYWdlXCI+XG4gICAgPCEtLSBDb21tb24gYWN0aW9uIGJ1dHRvbnMgZm9yIFwidXNlclwiICYgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgKm5nSWY9XCJjYW5Db3B5XCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2UuY29weVRleHQnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImNvcHlNZXNzYWdlKG1lc3NhZ2UpXCI+XG4gICAgICA8aSBjbGFzcz1cImZhciBmYS1jbGlwYm9hcmRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJ1c2VyXCIgbWVzc2FnZSAtLT5cbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbVwiICpuZ0lmPVwiY2FuRWRpdFwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmVkaXRNZXNzYWdlJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJlZGl0LmVtaXQobWVzc2FnZSlcIj5cbiAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWVkaXRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgW2NsYXNzLmJvdW5jZV09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZCA9PT0gdHJ1ZVwiICpuZ0lmPVwiY2FuTGlrZVwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmxpa2VBbnN3ZXInIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImxpa2UuZW1pdCgpXCI+XG4gICAgICA8aSBjbGFzcz1cImZhLXRodW1icy11cCB7e21lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGxpa2VkID09PSB0cnVlID8gJ2ZhcycgOiAnZmFyJ319XCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtIGJvdW5jZVwiICBbY2xhc3MuYm91bmNlXT1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGRpc2xpa2VkID09PSB0cnVlXCIgKm5nSWY9XCJjYW5EaXNsaWtlXCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2UucmVwb3J0SXNzdWUnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImRpc2xpa2UuZW1pdCgpXCI+XG4gICAgICA8aSBjbGFzcz1cImZhLXRodW1icy1kb3duIHt7bWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGlzbGlrZWQgPT09IHRydWUgPyAnZmFzJyA6ICdmYXInfX1cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhblJlZ2VuZXJhdGVcIiBbc3FUb29sdGlwXT1cIidjaGF0TWVzc2FnZS5yZWdlbmVyYXRlUmVzcG9uc2UnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cInJlZ2VuZXJhdGUuZW1pdChtZXNzYWdlKVwiPlxuICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtc3luYy1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhbkRlYnVnXCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2Uuc2hvd0xvZ0luZm9ybWF0aW9uJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJkZWJ1Zy5lbWl0KG1lc3NhZ2UpO1wiPlxuICAgICAgPGkgY2xhc3M9XCJmYXIgZmEtbGlzdC1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gTGlzdCBvZiBzdWdnZXN0ZWQgYWN0aW9ucywgaWYgYW55IC0tPlxuICA8ZGl2ICpuZ0lmPVwic3VnZ2VzdGVkQWN0aW9uc1wiIGNsYXNzPVwibXQtMiBtZXNzYWdlLXN1Z2dlc3Rpb25cIj5cbiAgICA8ZGl2IGNsYXNzPVwic3VnZ2VzdGVkLWFjdGlvblwiICpuZ0Zvcj1cImxldCBzdWdnZXN0ZWRBY3Rpb24gb2Ygc3VnZ2VzdGVkQWN0aW9uc1wiIChjbGljayk9XCJzdWdnZXN0QWN0aW9uLmVtaXQoc3VnZ2VzdGVkQWN0aW9uKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtY29udGVudFwiPlxuICAgICAgICA8cD48aSBjbGFzcz1cImZhcyBmYS1jbGlwYm9hcmQtcXVlc3Rpb25cIj48L2k+IHt7c3VnZ2VzdGVkQWN0aW9uLmNvbnRlbnR9fTwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8bmctdGVtcGxhdGUgI2ltYWdlVG9vbHRpcFRwbCBsZXQtcmVmPlxuICAgIDxJbmxpbmVJbWFnZVJlZmVyZW5jZVxuICAgICAgc3R5bGU9XCJtYXgtd2lkdGg6IDMwdnc7XCJcbiAgICAgIFtpZF09XCJyZWYuaWRcIlxuICAgICAgW3JlZl09XCJyZWYub2JqXCJcbiAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAvPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZSAjcGFnZVRvb2x0aXBUcGwgbGV0LXJlZj5cbiAgICA8SW5saW5lUGFnZVJlZmVyZW5jZVxuICAgICAgc3R5bGU9XCJtYXgtd2lkdGg6IDMwdnc7XCJcbiAgICAgIFtpZF09XCJyZWYuaWRcIlxuICAgICAgW3JlZl09XCJyZWYub2JqXCJcbiAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAvPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZSAjdG9vbHRpcFRwbCBsZXQtcmVmPlxuICAgIDxzcS1jaGF0LXJlZmVyZW5jZVxuICAgICAgKm5nSWY9XCIhaGlkZGVuVG9vbHRpcFwiXG4gICAgICBjbGFzcz1cImV4cGFuZGVkXCJcbiAgICAgIFthdHRhY2htZW50XT1cInJlZlwiXG4gICAgICBbcmVmZXJlbmNlXT1cInJlZi5jb250ZXh0SWRcIlxuICAgICAgW3BhcnRJZF09XCJyZWYuJHBhcnRJZFwiXG4gICAgICAob3BlblByZXZpZXcpPVwib3BlbkF0dGFjaG1lbnRQcmV2aWV3KCRldmVudCwgcmVmLiRwYXJ0SWQpXCJcbiAgICAgIChvcGVuRG9jdW1lbnQpPVwib3Blbk9yaWdpbmFsQXR0YWNobWVudCgkZXZlbnQsIHJlZi4kcGFydElkKVwiPlxuICAgIDwvc3EtY2hhdC1yZWZlcmVuY2U+XG4gIDwvbmctdGVtcGxhdGU+XG5cbjwvZGl2PlxuIl19
351
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQtbWVzc2FnZS9jaGF0LW1lc3NhZ2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNzaXN0YW50L2NoYXQvY2hhdC1tZXNzYWdlL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDMUMsT0FBTyxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLDZDQUE2QyxDQUFDO0FBQ3JELE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQztBQUNuQyxPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFhLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUU3QyxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDakUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDcEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkUsT0FBTyxFQUFFLDZCQUE2QixFQUFF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b0JBQW9CO3NCQUE1QixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csMEJBQTBCO3NCQUFsQyxLQUFLO2dCQUNHLHdCQUF3QjtzQkFBaEMsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNJLFlBQVk7c0JBQXJCLE1BQU07Z0JBSUcsV0FBVztzQkFBcEIsTUFBTTtnQkFJRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLElBQUk7c0JBQWIsTUFBTTtnQkFDRyxJQUFJO3NCQUFiLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxJQUFJO3NCQUFiLE1BQU07Z0JBQ0csT0FBTztzQkFBaEIsTUFBTTtnQkFDRyxLQUFLO3NCQUFkLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBwcm92aWRlVHJhbnNsb2NvU2NvcGUsIFRyYW5zbG9jb1BpcGUgfSBmcm9tICdAanN2ZXJzZS90cmFuc2xvY28nO1xuaW1wb3J0IHsgQ29udGVudCwgUGFyZW50LCBUZXh0IH0gZnJvbSBcIm1kYXN0XCI7XG5pbXBvcnQgeyBSZW1hcmtNb2R1bGUgfSBmcm9tIFwibmd4LXJlbWFya1wiO1xuaW1wb3J0IFwicHJpc21qcy1jb21wb25lbnRzLWltcG9ydGVyL2VzbVwiO1xuaW1wb3J0IFwicHJpc21qcy9wbHVnaW5zL2F1dG9sb2FkZXIvcHJpc20tYXV0b2xvYWRlclwiO1xuaW1wb3J0IHJlbWFya0dmbSBmcm9tIFwicmVtYXJrLWdmbVwiO1xuaW1wb3J0IHJlbWFya1BhcnNlIGZyb20gXCJyZW1hcmstcGFyc2VcIjtcbmltcG9ydCB7IFByb2Nlc3NvciwgdW5pZmllZCB9IGZyb20gXCJ1bmlmaWVkXCI7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSBcInVuaXN0XCI7XG5pbXBvcnQgeyBDT05USU5VRSwgRVhJVCwgdmlzaXQgfSBmcm9tIFwidW5pc3QtdXRpbC12aXNpdFwiO1xuXG5pbXBvcnQgeyBDaGFydENvbXBvbmVudCB9IGZyb20gXCIuLi9jaGFydHMvY2hhcnQvY2hhcnQuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBDaGF0UmVmZXJlbmNlQ29tcG9uZW50IH0gZnJvbSBcIi4uL2NoYXQtcmVmZXJlbmNlL2NoYXQtcmVmZXJlbmNlLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgSW5pdGlhbHNBdmF0YXJDb21wb25lbnQgfSBmcm9tIFwiLi4vaW5pdGlhbHMtYXZhdGFyL2luaXRpYWxzLWF2YXRhci5jb21wb25lbnRcIjtcbmltcG9ydCB7IE1lc3NhZ2VDb250ZW50UGlwZSB9IGZyb20gXCIuLi9waXBlcy9tZXNzYWdlLWNvbnRlbnQucGlwZVwiO1xuaW1wb3J0IHsgSW5saW5lSW1hZ2VSZWZlcmVuY2VDb21wb25lbnQgfSBmcm9tIFwiLi4vcmVmZXJlbmNlcy9pbmxpbmUtaW1hZ2UtcmVmZXJlbmNlXCI7XG5pbXBvcnQgeyBJbmxpbmVQYWdlUmVmZXJlbmNlQ29tcG9uZW50IH0gZnJvbSBcIi4uL3JlZmVyZW5jZXMvaW5saW5lLXBhZ2UtcmVmZXJlbmNlXCI7XG5pbXBvcnQgeyBQcmluY2lwYWxTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3ByaW5jaXBhbC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBVSVNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZXMvdWkuc2VydmljZVwiO1xuaW1wb3J0IHsgVG9vbHRpcERpcmVjdGl2ZSB9IGZyb20gXCIuLi90b29sdGlwL3Rvb2x0aXAuZGlyZWN0aXZlXCI7XG5pbXBvcnQgeyBDaGF0Q29udGV4dEF0dGFjaG1lbnQsIENoYXRNZXNzYWdlLCBTdWdnZXN0ZWRBY3Rpb24gfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFRleHRNZXNzYWdlQ29udGVudCB9IGZyb20gXCIuLi90eXBlcy9tZXNzYWdlLWNvbnRlbnQudHlwZXNcIjtcbmltcG9ydCB7IE1lc3NhZ2VJbWFnZVJlZmVyZW5jZSB9IGZyb20gXCIuLi90eXBlcy9tZXNzYWdlLXJlZmVyZW5jZS50eXBlc1wiO1xuaW1wb3J0IGVtYmVkZGVkSW1hZ2VSZWZlcmVuY2VQbHVnaW4gZnJvbSBcIi4uL3VuaWZpZWQtcGx1Z2lucy9lbWJlZGRlZC1pbWFnZS1yZWZlcmVuY2UucGx1Z2luXCI7XG5pbXBvcnQgZW1iZWRkZWRQYWdlUmVmZXJlbmNlUGx1Z2luIGZyb20gXCIuLi91bmlmaWVkLXBsdWdpbnMvZW1iZWRkZWQtcGFnZS1yZWZlcmVuY2UucGx1Z2luXCI7XG5cbmRlY2xhcmUgbW9kdWxlIFByaXNtIHtcbiAgZnVuY3Rpb24gaGlnaGxpZ2h0QWxsVW5kZXIoZWw6IEhUTUxFbGVtZW50KTogdm9pZDtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcInNxLWNoYXQtbWVzc2FnZVwiLFxuICB0ZW1wbGF0ZVVybDogXCIuL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5zY3NzXCJdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBUb29sdGlwRGlyZWN0aXZlLFxuICAgIFJlbWFya01vZHVsZSxcbiAgICBJbml0aWFsc0F2YXRhckNvbXBvbmVudCxcbiAgICBDaGF0UmVmZXJlbmNlQ29tcG9uZW50LFxuICAgIENoYXJ0Q29tcG9uZW50LFxuICAgIE1lc3NhZ2VDb250ZW50UGlwZSxcbiAgICBJbmxpbmVJbWFnZVJlZmVyZW5jZUNvbXBvbmVudCxcbiAgICBJbmxpbmVQYWdlUmVmZXJlbmNlQ29tcG9uZW50LFxuICAgIFRyYW5zbG9jb1BpcGVcbiAgXSxcbiAgcHJvdmlkZXJzOiBbcHJvdmlkZVRyYW5zbG9jb1Njb3BlKCdjaGF0LW1lc3NhZ2UnKV0sXG59KVxuZXhwb3J0IGNsYXNzIENoYXRNZXNzYWdlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcbiAgQElucHV0KCkgbWVzc2FnZTogQ2hhdE1lc3NhZ2U7XG4gIEBJbnB1dCgpIGNvbnZlcnNhdGlvbjogQ2hhdE1lc3NhZ2VbXTtcbiAgQElucHV0KCkgc3VnZ2VzdGVkQWN0aW9uczogU3VnZ2VzdGVkQWN0aW9uW10gfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGFzc2lzdGFudE1lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHVzZXJNZXNzYWdlSWNvbjogc3RyaW5nO1xuICBASW5wdXQoKSBjb25uZWN0aW9uRXJyb3JNZXNzYWdlSWNvbjogc3RyaW5nO1xuICBASW5wdXQoKSBzZWFyY2hXYXJuaW5nTWVzc2FnZUljb246IHN0cmluZztcbiAgQElucHV0KCkgc3RyZWFtaW5nOiBib29sZWFuO1xuICBASW5wdXQoKSBjYW5FZGl0OiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNhblJlZ2VuZXJhdGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY2FuQ29weTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjYW5EZWJ1ZzogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjYW5MaWtlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNhbkRpc2xpa2U6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQE91dHB1dCgpIG9wZW5Eb2N1bWVudCA9IG5ldyBFdmVudEVtaXR0ZXI8e1xuICAgIHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50O1xuICAgIHBhcnRJZD86IG51bWJlcjtcbiAgfT4oKTtcbiAgQE91dHB1dCgpIG9wZW5QcmV2aWV3ID0gbmV3IEV2ZW50RW1pdHRlcjx7XG4gICAgcmVmZXJlbmNlOiBDaGF0Q29udGV4dEF0dGFjaG1lbnQ7XG4gICAgcGFydElkPzogbnVtYmVyO1xuICB9PigpO1xuICBAT3V0cHV0KCkgc3VnZ2VzdEFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8U3VnZ2VzdGVkQWN0aW9uPigpO1xuICBAT3V0cHV0KCkgZWRpdCA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XG4gIEBPdXRwdXQoKSBjb3B5ID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0TWVzc2FnZT4oKTtcbiAgQE91dHB1dCgpIHJlZ2VuZXJhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRNZXNzYWdlPigpO1xuICBAT3V0cHV0KCkgbGlrZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGRpc2xpa2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkZWJ1ZyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XG5cbiAgcHJvY2Vzc29yOiBQcm9jZXNzb3I7XG5cbiAgcmVmZXJlbmNlczogc3RyaW5nW10gPSBbXTtcbiAgcmVmZXJlbmNlTWFwID0gbmV3IE1hcDxzdHJpbmcsIENoYXRDb250ZXh0QXR0YWNobWVudD4oKTtcbiAgaW1hZ2VSZWZlcmVuY2VzTWFwID0gbmV3IE1hcDxzdHJpbmcsIE1lc3NhZ2VJbWFnZVJlZmVyZW5jZT4oKTtcbiAgcGFnZVJlZmVyZW5jZXNNYXAgPSBuZXcgTWFwPHN0cmluZywgTWVzc2FnZUltYWdlUmVmZXJlbmNlPigpO1xuICBzaG93UmVmZXJlbmNlczogYm9vbGVhbiA9IHRydWU7XG4gIGNvbGxhcHNlUHJvZ3Jlc3M6IGJvb2xlYW47XG4gIGljb25TaXplID0gMjQ7XG5cbiAgaGlkZGVuVG9vbHRpcDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyB1aTogVUlTZXJ2aWNlLFxuICAgIHB1YmxpYyBwcmluY2lwYWxTZXJ2aWNlOiBQcmluY2lwYWxTZXJ2aWNlLFxuICAgIHB1YmxpYyBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHB1YmxpYyBlbDogRWxlbWVudFJlZlxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzLnN0cmVhbWluZykge1xuICAgICAgdGhpcy5jb2xsYXBzZVByb2dyZXNzID0gIXRoaXMuc3RyZWFtaW5nO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1lc3NhZ2U/LnJvbGUgPT09IFwiYXNzaXN0YW50XCIpIHtcbiAgICAgIHRoaXMucmVmZXJlbmNlcyA9IFtdO1xuICAgICAgdGhpcy5yZWZlcmVuY2VNYXAuY2xlYXIoKTtcbiAgICAgIGZvciAobGV0IG0gb2YgdGhpcy5jb252ZXJzYXRpb24pIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIG0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQgJiZcbiAgICAgICAgICBtLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50Lmxlbmd0aCA+IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBhdHRhY2htZW50IG9mIG0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQpIHtcbiAgICAgICAgICAgIC8vIHNraXAgZW1wdHkgYXR0YWNobWVudFxuICAgICAgICAgICAgaWYgKCFhdHRhY2htZW50KSBjb250aW51ZTtcblxuICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VNYXAuc2V0KFwiXCIgKyBhdHRhY2htZW50LmNvbnRleHRJZCwge1xuICAgICAgICAgICAgICAuLi5hdHRhY2htZW50LFxuICAgICAgICAgICAgICAkcGFydElkOiBhdHRhY2htZW50LnBhcnRzPy5bMF0/LnBhcnRJZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhYXR0YWNobWVudC5wYXJ0cyAmJiBhdHRhY2htZW50LnBhcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRhY2htZW50LnBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmSWQgPSBgJHthdHRhY2htZW50LmNvbnRleHRJZH0uJHthdHRhY2htZW50LnBhcnRzW2ldLnBhcnRJZH1gO1xuICAgICAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlTWFwLnNldChyZWZJZCwge1xuICAgICAgICAgICAgICAgICAgLi4uYXR0YWNobWVudCxcbiAgICAgICAgICAgICAgICAgICRwYXJ0SWQ6IGF0dGFjaG1lbnQucGFydHM/LltpXT8ucGFydElkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wcm9jZXNzTWVzc2FnZVR5cGUobSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucHJvY2Vzc29yID0gdW5pZmllZCgpXG4gICAgICAgIC51c2UocmVtYXJrUGFyc2UpXG4gICAgICAgIC51c2UocmVtYXJrR2ZtKVxuICAgICAgICAudXNlKCgpID0+IHRoaXMucmVmZXJlbmNlUGx1Z2luKVxuICAgICAgICAudXNlKCgpID0+IGVtYmVkZGVkSW1hZ2VSZWZlcmVuY2VQbHVnaW4pXG4gICAgICAgIC51c2UoKCkgPT4gZW1iZWRkZWRQYWdlUmVmZXJlbmNlUGx1Z2luKTtcblxuICAgICAgaWYgKHRoaXMuc3RyZWFtaW5nKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc29yID0gdGhpcy5wcm9jZXNzb3IudXNlKCgpID0+IHRoaXMucGxhY2Vob2xkZXJQbHVnaW4pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBQcmlzbT8uaGlnaGxpZ2h0QWxsVW5kZXI/Lih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgZ2V0RW1iZWRkZWRJbWFnZVJlZmVyZW5jZShyZWY6IHN0cmluZyk6IE1lc3NhZ2VJbWFnZVJlZmVyZW5jZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgW2RvYywgcGFydCwgaW1hZ2VdID0gcmVmLnNwbGl0KFwiLlwiKTtcbiAgICBjb25zdCBpbWFnZXMgPSB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucGFydHM/LlsrcGFydCAtIDFdPy5pbWFnZXM7XG5cbiAgICBpZiAoIWltYWdlcyB8fCBpbWFnZXMubGVuZ3RoID09PSAwIHx8IHR5cGVvZiBpbWFnZXNbMF0gIT09IFwib2JqZWN0XCIpXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgbWVzc2FnZUltYWdlUmVmZXJlbmNlOiBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICBhcnRpY2xlOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkLFxuICAgICAgICBhcnRpY2xlSWQ6IHRoaXMucmVmZXJlbmNlTWFwLmdldChkb2MpPy5yZWNvcmRJZCxcbiAgICAgIH0sXG4gICAgICBpbWFnZXNbK2ltYWdlIC0gMV1cbiAgICApO1xuXG4gICAgLy8gc2F2ZSByZWZlcmVuY2UgaW4gbWFwIGZvciByZWZlcmVuY2UgbGlzdFxuICAgIGlmICghdGhpcy5pbWFnZVJlZmVyZW5jZXNNYXAuaGFzKHJlZikpXG4gICAgICB0aGlzLmltYWdlUmVmZXJlbmNlc01hcC5zZXQocmVmLCBtZXNzYWdlSW1hZ2VSZWZlcmVuY2UpO1xuXG4gICAgcmV0dXJuIG1lc3NhZ2VJbWFnZVJlZmVyZW5jZTtcbiAgfVxuXG4gIGdldEVtYmVkZGVkUGFnZVJlZmVyZW5jZShyZWY6IHN0cmluZyk6IE1lc3NhZ2VJbWFnZVJlZmVyZW5jZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgW2RvYywgcGFnZV0gPSByZWYuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IHBhZ2VSZWYgPSB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucGFnZXM/LmZpbmQoeCA9PiB4LnBhZ2VOdW1iZXIgPT09ICtwYWdlKTtcbiAgICBcbiAgICBpZiAoIXBhZ2VSZWYgfHwgdHlwZW9mIHBhZ2VSZWYgIT09IFwib2JqZWN0XCIpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBtZXNzYWdlUGFnZVJlZmVyZW5jZTogTWVzc2FnZUltYWdlUmVmZXJlbmNlID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHtcbiAgICAgICAgYXJ0aWNsZTogdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnJlY29yZCxcbiAgICAgICAgYXJ0aWNsZUlkOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkSWQsXG4gICAgICB9LFxuICAgICAgcGFnZVJlZlxuICAgICk7XG5cbiAgICAvLyBzYXZlIHJlZmVyZW5jZSBpbiBtYXAgZm9yIHJlZmVyZW5jZSBsaXN0XG4gICAgaWYgKCF0aGlzLnBhZ2VSZWZlcmVuY2VzTWFwLmhhcyhyZWYpKVxuICAgICAgdGhpcy5wYWdlUmVmZXJlbmNlc01hcC5zZXQocmVmLCBtZXNzYWdlUGFnZVJlZmVyZW5jZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZVBhZ2VSZWZlcmVuY2U7XG4gIH1cblxuICBnZXQgbmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAhdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbFxuICAgICAgPyBcIlwiXG4gICAgICA6ICh0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsW1wiZnVsbE5hbWVcIl0gYXMgc3RyaW5nKSB8fFxuICAgICAgICAgIHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwubmFtZTtcbiAgfVxuXG4gIGdldCBpc0FkbWluKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsPy5pc0FkbWluaXN0cmF0b3IgfHwgZmFsc2U7XG4gIH1cblxuICBwcm9jZXNzTWVzc2FnZVR5cGUobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcbiAgICAvLyBQcm9jZXNzIG1lc3NhZ2UgdHlwZSB3aGVuIHNwZWMgaXMgZG9uZVxuICAgIC8vIG5vcCBmb3IgbmV3IG1lc3NhZ2UgdHlwZXNcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuO1xuXG4gICAgLy8gTGVnYWN5IG1lc3NhZ2UgdHlwZVxuICAgIGlmIChtZXNzYWdlLmNvbnRlbnQuc3RhcnRzV2l0aChcIjxjaGFydGpzPlwiKSkge1xuICAgICAgbWVzc2FnZS5tZXNzYWdlVHlwZSA9IFwiQ0hBUlRcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVzc2FnZS5tZXNzYWdlVHlwZSA9IFwiTUFSS0RPV05cIjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBVbmlmaWVkIHBsdWdpbiBsb29rcyBhIHRleHQgbm9kZXMgYW5kIHJlcGxhY2VzIGFueSByZWZlcmVuY2UgaW4gdGhlXG4gICAqIGZvcm0gWzFdLCBbMi4zXSwgZXRjLiB3aXRoIGN1c3RvbSBub2RlcyBvZiB0eXBlIFwiY2hhdC1yZWZlcmVuY2VcIi5cbiAgICovXG4gIHJlZmVyZW5jZVBsdWdpbiA9ICh0cmVlOiBOb2RlKSA9PiB7XG4gICAgY29uc3QgcmVmZXJlbmNlcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuXG4gICAgLy8gVmlzaXQgYWxsIHRleHQgbm9kZXNcbiAgICB2aXNpdCh0cmVlLCBcInRleHRcIiwgKG5vZGU6IFRleHQsIGluZGV4OiBudW1iZXIsIHBhcmVudDogUGFyZW50KSA9PiB7XG4gICAgICBsZXQgdGV4dCA9IG5vZGUudmFsdWU7XG5cbiAgICAgIHRleHQgPSB0aGlzLnJlZm9ybWF0UmVmZXJlbmNlcyh0ZXh0KTtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLmdldFJlZmVyZW5jZU1hdGNoZXModGV4dCk7XG5cbiAgICAgIC8vIFF1aXQgaWYgbm8gcmVmZXJlbmNlcyB3ZXJlIGZvdW5kXG4gICAgICBpZiAobWF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIENPTlRJTlVFO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlczogKENvbnRlbnQgJiB7IGVuZDogbnVtYmVyIH0pW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBtYXRjaCBvZiBtYXRjaGVzKSB7XG4gICAgICAgIGNvbnN0IHJlZklkID0gbWF0Y2hbMV0udHJpbSgpO1xuICAgICAgICBjb25zdCBbcmVmXSA9IHJlZklkLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgLy8gV2UgZmluZCBhIHZhbGlkIHJlZmVyZW5jZSBpbiB0aGUgdGV4dFxuICAgICAgICBpZiAoIWlzTmFOKCtyZWYpKSB7XG4gICAgICAgICAgcmVmZXJlbmNlcy5hZGQoK3JlZik7IC8vIEFkZCBpdCB0byB0aGUgc2V0IG9mIHVzZWQgcmVmZXJlbmNlc1xuXG4gICAgICAgICAgLy8gSWYgbmVlZGVkLCBpbnNlcnQgYSB0ZXh0IG5vZGUgYmVmb3JlIHRoZSByZWZlcmVuY2VcbiAgICAgICAgICBjb25zdCBjdXJyZW50ID0gbm9kZXMuYXQoLTEpID8/IHsgZW5kOiAwIH07XG4gICAgICAgICAgaWYgKG1hdGNoLmluZGV4ISA+IGN1cnJlbnQuZW5kKSB7XG4gICAgICAgICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICAgIHZhbHVlOiB0ZXh0LnN1YnN0cmluZyhjdXJyZW50LmVuZCwgbWF0Y2guaW5kZXghKSxcbiAgICAgICAgICAgICAgZW5kOiBtYXRjaC5pbmRleCEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBBZGQgYSBjdXN0b20gcmVmZXJlbmNlIG5vZGVcbiAgICAgICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6IFwiY2hhdC1yZWZlcmVuY2VcIixcbiAgICAgICAgICAgIHJlZklkLFxuICAgICAgICAgICAgZW5kOiBtYXRjaC5pbmRleCEgKyBtYXRjaFswXS5sZW5ndGgsXG4gICAgICAgICAgfSBhcyBhbnkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFF1aXQgaWYgbm8gcmVmZXJlbmNlcyB3ZXJlIGZvdW5kXG4gICAgICBpZiAobm9kZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBDT05USU5VRTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVzLmF0KC0xKSEuZW5kIDwgdGV4dC5sZW5ndGgpIHtcbiAgICAgICAgbm9kZXMucHVzaCh7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdmFsdWU6IHRleHQuc3Vic3RyaW5nKG5vZGVzLmF0KC0xKSEuZW5kLCB0ZXh0Lmxlbmd0aCksXG4gICAgICAgICAgZW5kOiB0ZXh0Lmxlbmd0aCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIERlbGV0ZSB0aGUgY3VycmVudCB0ZXh0IG5vZGUgZnJvbSB0aGUgcGFyZW50IGFuZCByZXBsYWNlIGl0IHdpdGggdGhlIG5ldyBub2Rlc1xuICAgICAgcGFyZW50LmNoaWxkcmVuLnNwbGljZShpbmRleCwgMSwgLi4ubm9kZXMpO1xuXG4gICAgICByZXR1cm4gaW5kZXggKyBub2Rlcy5sZW5ndGg7IC8vIFZpc2l0IHRoZSBuZXh0IG5vZGUgYWZ0ZXIgdGhlIGluc2VydGVkIG9uZXNcbiAgICB9KTtcblxuICAgIGlmIChyZWZlcmVuY2VzLnNpemUgPiAwKSB7XG4gICAgICB0aGlzLnJlZmVyZW5jZXMgPSBBcnJheS5mcm9tKHJlZmVyZW5jZXMudmFsdWVzKCkpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhIC0gYilcbiAgICAgICAgLm1hcCgocikgPT4gXCJcIiArIHIpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIHJldHVybiB0cmVlO1xuICB9O1xuXG4gIHBsYWNlaG9sZGVyUGx1Z2luID0gKHRyZWU6IE5vZGUpID0+IHtcbiAgICB2aXNpdChcbiAgICAgIHRyZWUsXG4gICAgICBcInRleHRcIixcbiAgICAgIChub2RlOiBUZXh0LCBpbmRleDogbnVtYmVyLCBwYXJlbnQ6IFBhcmVudCkgPT4ge1xuICAgICAgICBwYXJlbnQuY2hpbGRyZW4ucHVzaCh7IHR5cGU6IFwic3RyZWFtaW5nLXBsYWNlaG9sZGVyXCIgfSBhcyBhbnkpO1xuICAgICAgICByZXR1cm4gRVhJVDtcbiAgICAgIH0sXG4gICAgICB0cnVlXG4gICAgKTtcblxuICAgIHJldHVybiB0cmVlO1xuICB9O1xuXG4gIGdldExpbmtUZXh0KG5vZGU6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKG5vZGUudGV4dCkge1xuICAgICAgcmV0dXJuIG5vZGUudGV4dDsgLy8gUmV0dXJuIGRpcmVjdGx5IGlmIHRleHQgaXMgcHJvdmlkZWQgaW4gbm9kZS50ZXh0IChbRXhhbXBsZSBsaW5rXShodHRwczovL2V4YW1wbGUuY29tKSlcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGRyZW4gJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBSZWN1cnNpdmVseSBzZWFyY2ggZm9yIHRleHQgY29udGVudCBpbiBjaGlsZCBub2Rlc1xuICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBub2RlLmNoaWxkcmVuKSB7XG4gICAgICAgIGlmIChjaGlsZC50eXBlID09PSBcInRleHRcIiAmJiBjaGlsZC52YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBjaGlsZC52YWx1ZTsgLy8gUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgdGV4dCBub2RlIGZvdW5kIChbKipFbXBoYXNpemVkIExpbmsgVGV4dCoqXShodHRwczovL2V4YW1wbGUuY29tKSlcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5jaGlsZHJlbiAmJiBjaGlsZC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgdGV4dENvbnRlbnQgPSB0aGlzLmdldExpbmtUZXh0KGNoaWxkKTsgLy8gUmVjdXJzaXZlbHkgc2VhcmNoIGNoaWxkIG5vZGVzIChbIVtFeGFtcGxlIGltYWdlXShodHRwczovL2V4YW1wbGUuY29tL2ltYWdlLnBuZyldKGh0dHBzOi8vZXhhbXBsZS5jb20pKVxuICAgICAgICAgIGlmICh0ZXh0Q29udGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRleHRDb250ZW50OyAvLyBSZXR1cm4gdGV4dCBjb250ZW50IGlmIGZvdW5kXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBcImxpbmtcIjsgLy8gUmV0dXJuIGVtcHR5IHN0cmluZyBpZiBubyB0ZXh0IGNvbnRlbnQgaXMgZm91bmRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZvcm1hdCBbaWRzOiAxMi4yLCA0Mi41XSB0byBbMTIuMl1bNDIuNV1cbiAgICovXG4gIHJlZm9ybWF0UmVmZXJlbmNlcyhjb250ZW50OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKFxuICAgICAgL1xcWyg/Omlkcz86P1xccyopPyg/OmRvY3VtZW50cz86P1xccyopPyhcXHMqKD86LD9cXHMqXFxkKyg/OlxcLlxcZCspPyg/OlxcLnBhcnQpP1xccyopKylcXF0vZyxcbiAgICAgIChzdHIsIG1hdGNoOiBzdHJpbmcpID0+XG4gICAgICAgIGBbJHttYXRjaFxuICAgICAgICAgIC5yZXBsYWNlKC9cXC5wYXJ0L2csIFwiXCIpXG4gICAgICAgICAgLnNwbGl0KFwiLFwiKVxuICAgICAgICAgIC5qb2luKFwiXSBbXCIpfV1gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXRjaCBhbGwgcmVmZXJlbmNlcyBpbiBhIGdpdmVuIG1lc3NhZ2VcbiAgICovXG4gIGdldFJlZmVyZW5jZU1hdGNoZXMoY29udGVudDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oY29udGVudC5tYXRjaEFsbCgvXFxbKFxccypcXGQrKD86XFwuXFxkKyk/XFxzKilcXF0vZykpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29weVRvQ2xpcGJvYXJkKGNvbnRlbnQ6IHN0cmluZykge1xuICAgIHRoaXMudWkuY29weVRvQ2xpcGJvYXJkKGNvbnRlbnQpO1xuICB9XG5cbiAgY29weU1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcbiAgICBsZXQgY29udGVudDogc3RyaW5nID0gXCJcIjtcblxuICAgIGlmICh0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSBcInN0cmluZ1wiKVxuICAgICAgY29udGVudCA9IG1lc3NhZ2UuY29udGVudDtcbiAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KG1lc3NhZ2UuY29udGVudCkpXG4gICAgICBjb250ZW50ID0gKG1lc3NhZ2UuY29udGVudFswXSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpLnRleHQ7XG4gICAgZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiVW5zdXBwb3J0ZWQgbWVzc2FnZSBjb250ZW50IHR5cGVcIiwgdHlwZW9mIG1lc3NhZ2UuY29udGVudCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2VBbGwoL1xccytcXFsuKz9cXF0vZywgXCJcIik7XG5cbiAgICB0aGlzLl9jb3B5VG9DbGlwYm9hcmQoY29udGVudCk7XG4gICAgdGhpcy5jb3B5LmVtaXQobWVzc2FnZSk7XG4gIH1cblxuICBjb3B5Q29kZShjb2RlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9jb3B5VG9DbGlwYm9hcmQoY29kZSk7XG4gIH1cblxuICBvcGVuQXR0YWNobWVudFByZXZpZXcoYXR0YWNobWVudDogQ2hhdENvbnRleHRBdHRhY2htZW50LCBwYXJ0SWQ/OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZW5QcmV2aWV3LmVtaXQoeyByZWZlcmVuY2U6IGF0dGFjaG1lbnQsIHBhcnRJZCB9KTtcbiAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gIH1cblxuICBvcGVuT3JpZ2luYWxBdHRhY2htZW50KGF0dGFjaG1lbnQ6IENoYXRDb250ZXh0QXR0YWNobWVudCwgcGFydElkPzogbnVtYmVyKSB7XG4gICAgdGhpcy5vcGVuRG9jdW1lbnQuZW1pdCh7IHJlZmVyZW5jZTogYXR0YWNobWVudCwgcGFydElkIH0pO1xuICAgIHRoaXMuaGlkZVRvb2x0aXAoKTtcbiAgfVxuXG4gIGhpZGVUb29sdGlwKCk6IHZvaWQge1xuICAgIHRoaXMuaGlkZGVuVG9vbHRpcCA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmhpZGRlblRvb2x0aXAgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxufVxuIiwiPCEtLSBNZXNzYWdlIGljb24gLS0+XG48c3BhbiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFt0aXRsZV09XCJtZXNzYWdlPy5yb2xlXCI+XG4gIDxpIGNsYXNzPVwiZC1ibG9ja1wiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiICpuZ0lmPVwiIW1lc3NhZ2VcIj48L2k+XG4gIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cIm1lc3NhZ2U/LnJvbGVcIj5cbiAgICA8IS0tIEZvciAnYXNzaXN0YW50JyAtLT5cbiAgICA8aSAqbmdTd2l0Y2hDYXNlPVwiJ2Fzc2lzdGFudCdcIiBbbmdDbGFzc109XCJhc3Npc3RhbnRNZXNzYWdlSWNvblwiIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIj48L2k+XG5cbiAgICA8IS0tIEZvciAndXNlcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3VzZXInXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhdXNlck1lc3NhZ2VJY29uOyBlbHNlIGluaXRpYWxzQXZhdGFyXCIgW25nQ2xhc3NdPVwidXNlck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjaW5pdGlhbHNBdmF0YXI+XG4gICAgICAgIDxzcS1pbml0aWFscy1hdmF0YXIgW2Z1bGxOYW1lXT1cIm5hbWVcIj48L3NxLWluaXRpYWxzLWF2YXRhcj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnY29ubmVjdGlvbi1lcnJvcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2Nvbm5lY3Rpb24tZXJyb3InXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdEVycm9ySWNvblwiIFtuZ0NsYXNzXT1cImNvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEVycm9ySWNvbj5cbiAgICAgICAgPHN2ZyBbc3R5bGUuLS1zcS1zaXplLnB4XT1cImljb25TaXplXCIgY2xhc3M9XCJjb25uZWN0aW9uLWVycm9yXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgNTEyIDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTE3LjEgMjkyYy0xMi45LTIyLjMtMTIuOS00OS43IDAtNzJMMTA1LjQgNjcuMWMxMi45LTIyLjMgMzYuNi0zNiA2Mi40LTM2bDE3Ni42IDBjMjUuNyAwIDQ5LjUgMTMuNyA2Mi40IDM2TDQ5NC45IDIyMGMxMi45IDIyLjMgMTIuOSA0OS43IDAgNzJMNDA2LjYgNDQ0LjljLTEyLjkgMjIuMy0zNi42IDM2LTYyLjQgMzZsLTE3Ni42IDBjLTI1LjcgMC00OS41LTEzLjctNjIuNC0zNkwxNy4xIDI5MnpNMjU2IDEyOGMtMTMuMyAwLTI0IDEwLjctMjQgMjRsMCAxMTJjMCAxMy4zIDEwLjcgMjQgMjQgMjRzMjQtMTAuNyAyNC0yNGwwLTExMmMwLTEzLjMtMTAuNy0yNC0yNC0yNHptMzIgMjI0YTMyIDMyIDAgMSAwIC02NCAwIDMyIDMyIDAgMSAwIDY0IDB6XCIvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnc2VhcmNoLXdhcm5pbmcnIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzZWFyY2gtd2FybmluZydcIj5cbiAgICAgIDxpICpuZ0lmPVwiISFzZWFyY2hXYXJuaW5nTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdFdhcm5pbmdJY29uXCIgW25nQ2xhc3NdPVwic2VhcmNoV2FybmluZ01lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFdhcm5pbmdJY29uPlxuICAgICAgICA8c3ZnIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIiBjbGFzcz1cInNlYXJjaC13YXJuaW5nXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMzg0IDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTI3MiAzODRjOS42LTMxLjkgMjkuNS01OS4xIDQ5LjItODYuMmMwIDAgMCAwIDAgMGM1LjItNy4xIDEwLjQtMTQuMiAxNS40LTIxLjRjMTkuOC0yOC41IDMxLjQtNjMgMzEuNC0xMDAuM0MzNjggNzguOCAyODkuMiAwIDE5MiAwUzE2IDc4LjggMTYgMTc2YzAgMzcuMyAxMS42IDcxLjkgMzEuNCAxMDAuM2M1IDcuMiAxMC4yIDE0LjMgMTUuNCAyMS40YzAgMCAwIDAgMCAwYzE5LjggMjcuMSAzOS43IDU0LjQgNDkuMiA4Ni4ybDE2MCAwek0xOTIgNTEyYzQ0LjIgMCA4MC0zNS44IDgwLTgwbDAtMTYtMTYwIDAgMCAxNmMwIDQ0LjIgMzUuOCA4MCA4MCA4MHptMC00NDhjMTMuMyAwIDI0IDEwLjcgMjQgMjRsMCAxMTJjMCAxMy4zLTEwLjcgMjQtMjQgMjRzLTI0LTEwLjctMjQtMjRsMC0xMTJjMC0xMy4zIDEwLjctMjQgMjQtMjR6TTE2MCAyODhhMzIgMzIgMCAxIDEgNjQgMCAzMiAzMiAwIDEgMSAtNjQgMHpcIi8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L3NwYW4+XG5cbjwhLS0gTWVzc2FnZSBib2R5IC0tPlxuPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xIHBvc2l0aW9uLXJlbGF0aXZlIHJlbGF0aXZlXCIgc3R5bGU9XCJtaW4td2lkdGg6IDA7XCIgW25nQ2xhc3NdPVwiJ21lc3NhZ2UtJyttZXNzYWdlLnJvbGVcIj5cblxuICA8IS0tIFByb2dyZXNzIHN0ZXBzIC0tPlxuICA8ZGl2ICpuZ0lmPVwibWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kcHJvZ3Jlc3MgYXMgcHJvZ3Jlc3NcIiBjbGFzcz1cInNtYWxsIG1zLTMgbWItMlwiPlxuICAgIDxkZXRhaWxzIHJvbGU9XCJidXR0b25cIiBjbGFzcz1cInNlbGVjdC1ub25lXCIgW29wZW5dPVwiIWNvbGxhcHNlUHJvZ3Jlc3NcIj5cbiAgICAgIDxzdW1tYXJ5IGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgICAgICB7eyAnY2hhdE1lc3NhZ2Uudmlld1Byb2dyZXNzJyB8IHRyYW5zbG9jbyB9fVxuICAgICAgPC9zdW1tYXJ5PlxuICAgICAgPHVsIGNsYXNzPVwibGlzdC11bnN0eWxlZFwiPlxuICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHN0ZXAgb2YgcHJvZ3Jlc3NcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1mdyBmYS1jaGVjayB0ZXh0LXN1Y2Nlc3NcIiAqbmdJZj1cInN0ZXAuZG9uZVwiPjwvaT5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zcGlubmVyIGZhLXB1bHNlIHN0ZXAtb25nb2luZ1wiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiBzdHJlYW1pbmdcIj48L2k+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYS1zb2xpZCBmYS1iYW4gc3RlcC1lcnJvclwiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiAhc3RyZWFtaW5nXCI+PC9pPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXMtMiBmdy1ib2xkXCI+e3tzdGVwLnRpdGxlfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdGVwLmNvbnRlbnRcIiBbaW5uZXJIVE1MXT1cIic6ICcgKyBzdGVwLmNvbnRlbnRcIj48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGV0YWlscz5cbiAgPC9kaXY+XG5cbiAgPCEtLSBNZXNzYWdlIGNvbnRlbnQgLS0+XG4gIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWNvbnRlbnRcIiAqbmdJZj1cIm1lc3NhZ2UuY29udGVudFwiPlxuXG4gICAgPCEtLSBDdXN0b20gcmVuZGVyaW5nIGZvciBXUFMsIHRvIGJlIHJlbW92ZSB3aXRoIGh0dHBzOi8vc2luZXF1YS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9FUy0yMzcxMCAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwibWVzc2FnZT8ucm9sZSA9PT0gJ2Fzc2lzdGFudCcgJiYgbWVzc2FnZS5tZXNzYWdlVHlwZSA9PT0gJ0NIQVJUJ1wiPlxuICAgICAgPHNxLWFzc2lzdGFudC1jaGFydCBbcmF3Q2hhcnREYXRhXT1cIm1lc3NhZ2UuY29udGVudFwiPjwvc3EtYXNzaXN0YW50LWNoYXJ0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBUaGlzIHNlY3Rpb24gaXMgcmVzcG9uc2libGUgZm9yIGN1c3RvbWl6aW5nIHRoZSB0ZW1wbGF0ZSBub2RlcyB1c2VkIGluIHRoZSBhcHBsaWNhdGlvbi5cbiAgICAgICAgVGVtcGxhdGUgbm9kZXMgYXJlIHByZWRlZmluZWQgc3RydWN0dXJlcyB0aGF0IHNlcnZlIGFzIGJsdWVwcmludHMgZm9yIGNyZWF0aW5nL2N1c3RvbWl6aW5nIGR5bmFtaWMgY29udGVudCAtLT5cbiAgICA8cmVtYXJrICpuZ0lmPVwiKG1lc3NhZ2U/LnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIG1lc3NhZ2UubWVzc2FnZVR5cGUgIT09ICdDSEFSVCcpIHx8IG1lc3NhZ2U/LnJvbGUgPT09ICdjb25uZWN0aW9uLWVycm9yJyB8fCBtZXNzYWdlPy5yb2xlID09PSAnc2VhcmNoLXdhcm5pbmcnXCIgW21hcmtkb3duXT1cIm1lc3NhZ2UuY29udGVudCB8IG1lc3NhZ2VDb250ZW50XCIgW3Byb2Nlc3Nvcl09XCJwcm9jZXNzb3JcIj5cblxuICAgICAgPCEtLSBDaGF0IHJlZmVyZW5jZSAoYmFkZ2Ugd2l0aCBmaWxlIGFuZCBwYXJ0IG51bWJlcikgLS0+XG4gICAgICA8bmctdGVtcGxhdGUgcmVtYXJrVGVtcGxhdGU9XCJjaGF0LXJlZmVyZW5jZVwiIGxldC1yZWY+XG4gICAgICAgIEBsZXQgYXR0YWNobWVudCA9IHJlZmVyZW5jZU1hcC5nZXQocmVmLnJlZklkKTtcbiAgICAgICAgQGlmIChhdHRhY2htZW50KSB7XG4gICAgICAgICAgPGFcbiAgICAgICAgICAgIGNsYXNzPVwicmVmZXJlbmNlXCJcbiAgICAgICAgICAgIHJvbGU9XCJidXR0b25cIlxuICAgICAgICAgICAgW3NxVG9vbHRpcF09XCJhdHRhY2htZW50XCJcbiAgICAgICAgICAgIFtzcVRvb2x0aXBUZW1wbGF0ZV09XCJ0b29sdGlwVHBsXCJcbiAgICAgICAgICAgIFtob3ZlcmFibGVUb29sdGlwXT1cInRydWVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5BdHRhY2htZW50UHJldmlldyhhdHRhY2htZW50LCByZWYucmVmSWQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7e3JlZi5yZWZJZH19XG4gICAgICAgICAgPC9hPlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8bmctdGVtcGxhdGUgI3N0YXRpY1JlZlRwbD5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVmZXJlbmNlXCI+e3sgcmVmLnJlZklkIH19PC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIH1cbiAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDwhLS0gRW1iZWRkZWQgcmVmZXJlbmNlIGltYWdlIC0tPlxuICAgICAgPG5nLXRlbXBsYXRlIHJlbWFya1RlbXBsYXRlPVwiZW1iZWRkZWQtaW1hZ2UtcmVmZXJlbmNlXCIgbGV0LXJlZj5cbiAgICAgICAgQGxldCByZWZPYmogPSBnZXRFbWJlZGRlZEltYWdlUmVmZXJlbmNlKHJlZi52YWx1ZSk7XG4gICAgICAgIEBpZiAocmVmT2JqICYmIHJlZk9iai51cmwpIHtcbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAncmVmZXJlbmNlJzogdHJ1ZSwgJ2hhcy1ib3VuZGluZy1ib3gnOiByZWYuYm91bmRpbmdCb3ggfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwXT1cInsgb2JqOiByZWZPYmosIGlkOiByZWYudmFsdWUgfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwVGVtcGxhdGVdPVwiaW1hZ2VUb29sdGlwVHBsXCJcbiAgICAgICAgICAgIFtob3ZlcmFibGVUb29sdGlwXT1cInRydWVcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEltZy17eyByZWYudmFsdWUgfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDwhLS0gRW1iZWRkZWQgcmVmZXJlbmNlIHBhZ2UgLS0+XG4gICAgICA8bmctdGVtcGxhdGUgcmVtYXJrVGVtcGxhdGU9XCJlbWJlZGRlZC1wYWdlLXJlZmVyZW5jZVwiIGxldC1yZWY+XG4gICAgICAgIEBsZXQgcmVmT2JqID0gZ2V0RW1iZWRkZWRQYWdlUmVmZXJlbmNlKHJlZi52YWx1ZSk7XG4gICAgICAgIEBpZiAocmVmT2JqICYmIHJlZk9iai51cmwpIHtcbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAncmVmZXJlbmNlJzogdHJ1ZSwgJ2hhcy1ib3VuZGluZy1ib3gnOiByZWYuYm91bmRpbmdCb3ggfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwXT1cInsgb2JqOiByZWZPYmosIGlkOiByZWYudmFsdWUgfVwiXG4gICAgICAgICAgICBbc3FUb29sdGlwVGVtcGxhdGVdPVwicGFnZVRvb2x0aXBUcGxcIlxuICAgICAgICAgICAgW2hvdmVyYWJsZVRvb2x0aXBdPVwidHJ1ZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgUGFnZS17eyByZWYudmFsdWUgfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgIDwhLS0gQmxpbmtpbmcgY3Vyc29yIC0tPlxuICAgICAgPG5nLXRlbXBsYXRlIHJlbWFya1RlbXBsYXRlPVwic3RyZWFtaW5nLXBsYWNlaG9sZGVyXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwicGxhY2Vob2xkZXItZ2xvd1wiICpuZ0lmPVwic3RyZWFtaW5nXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbGFjZWhvbGRlciBtcy0xXCI+PC9zcGFuPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICA8bmctdGVtcGxhdGUgcmVtYXJrVGVtcGxhdGU9XCJjb2RlXCIgbGV0LW5vZGU+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkIG1iLTJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgPHNwYW4+e3tub2RlLmxhbmd9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpZ2h0IGJ0bi1zbVwiIChjbGljayk9XCJjb3B5Q29kZShub2RlLnZhbHVlKVwiPjxpIGNsYXNzPVwiZmFyIGZhLWZ3IGZhLWNsaXBib2FyZFwiPjwvaT4ge3sgJ2NoYXRNZXNzYWdlLmNvcHlDb2RlJyB8IHRyYW5zbG9jbyB9fTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxwcmUgY2xhc3M9XCJsYW5ndWFnZS17e25vZGUubGFuZ319IG15LTAgcm91bmRlZC0wIHJvdW5kZWQtYm90dG9tXCI+PGNvZGUgY2xhc3M9XCJsYW5ndWFnZS17e25vZGUubGFuZ319XCI+e3tub2RlLnZhbHVlfX08L2NvZGU+PC9wcmU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPG5nLXRlbXBsYXRlIHJlbWFya1RlbXBsYXRlPVwibGlua1wiIGxldC1ub2RlPlxuICAgICAgICA8YSBbaHJlZl09XCJub2RlLnVybFwiIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIj57e2dldExpbmtUZXh0KG5vZGUpfX08L2E+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPC9yZW1hcms+XG5cbiAgICA8cCAqbmdJZj1cIm1lc3NhZ2U/LnJvbGUgPT09ICd1c2VyJ1wiPnt7IG1lc3NhZ2UuY29udGVudCB8IG1lc3NhZ2VDb250ZW50IH19PC9wPlxuXG4gICAgPCEtLSBMaXN0IG9mIHJlZmVyZW5jZSwgaWYgYW55IC0tPlxuICAgIEBpZiAocmVmZXJlbmNlcz8ubGVuZ3RoID4gMCB8fCBpbWFnZVJlZmVyZW5jZXNNYXA/LnNpemUgPiAwIHx8IHBhZ2VSZWZlcmVuY2VzTWFwPy5zaXplID4gMCkge1xuICAgICAgPGRpdiBjbGFzcz1cInJlZmVyZW5jZXNcIj5cbiAgICAgICAgPGRldGFpbHMgcm9sZT1cImJ1dHRvblwiIGNsYXNzPVwic2VsZWN0LW5vbmVcIiBbb3Blbl09XCIhc2hvd1JlZmVyZW5jZXNcIj5cbiAgICAgICAgICA8c3VtbWFyeSBjbGFzcz1cInJlZmVyZW5jZXMtdGl0bGVcIj57eyAnY2hhdE1lc3NhZ2UucmVmZXJlbmNlcycgfCB0cmFuc2xvY28gfX08L3N1bW1hcnk+XG4gICAgICAgICAgPHVsPlxuICAgICAgICAgICAgQGZvciAocmVmZXJlbmNlIG9mIHJlZmVyZW5jZXM7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgICA8bGkgKm5nSWY9XCJyZWZlcmVuY2VNYXAuZ2V0KHJlZmVyZW5jZSkgYXMgYXR0YWNobWVudFwiICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICA8c3EtY2hhdC1yZWZlcmVuY2VcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5leHBhbmRlZF09XCJhdHRhY2htZW50LiRleHBhbmRlZFwiXG4gICAgICAgICAgICAgICAgICBbYXR0YWNobWVudF09XCJhdHRhY2htZW50XCJcbiAgICAgICAgICAgICAgICAgIFtyZWZlcmVuY2VdPVwicmVmZXJlbmNlXCJcbiAgICAgICAgICAgICAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgIDwvc3EtY2hhdC1yZWZlcmVuY2U+XG4gICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChpbWFnZVJlZmVyZW5jZSBvZiBpbWFnZVJlZmVyZW5jZXNNYXAuZW50cmllcygpOyB0cmFjayAkaW5kZXgpIHtcbiAgICAgICAgICAgICAgPGxpIHN0eWxlPVwibGlzdC1zdHlsZS10eXBlOiBub25lO1wiPlxuICAgICAgICAgICAgICAgIDxJbmxpbmVJbWFnZVJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgW2lkXT1cImltYWdlUmVmZXJlbmNlWzBdXCJcbiAgICAgICAgICAgICAgICAgIFtyZWZdPVwiaW1hZ2VSZWZlcmVuY2VbMV1cIlxuICAgICAgICAgICAgICAgICAgKG9wZW5QcmV2aWV3KT1cIm9wZW5BdHRhY2htZW50UHJldmlldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChvcGVuRG9jdW1lbnQpPVwib3Blbk9yaWdpbmFsQXR0YWNobWVudCgkZXZlbnQsICRldmVudC4kcGFydElkKVwiXG4gICAgICAgICAgICAgICAgICAob3Blbk1vZGFsKT1cImhpZGVUb29sdGlwKClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChwYWdlUmVmZXJlbmNlIG9mIHBhZ2VSZWZlcmVuY2VzTWFwLmVudHJpZXMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIDxsaSBzdHlsZT1cImxpc3Qtc3R5bGUtdHlwZTogbm9uZTtcIj5cbiAgICAgICAgICAgICAgICA8SW5saW5lUGFnZVJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgW2lkXT1cInBhZ2VSZWZlcmVuY2VbMF1cIlxuICAgICAgICAgICAgICAgICAgW3JlZl09XCJwYWdlUmVmZXJlbmNlWzFdXCJcbiAgICAgICAgICAgICAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgICAgICAgICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cblxuICAgIDwhLS0gRWRpdCAvIFJlZ2VuZXJhdGUgZmxvYXRpbmcgYWN0aW9ucyAtLT5cbiAgPGRpdiBjbGFzcz1cInNxLWNoYXQtbWVzc2FnZS1hY3Rpb25zXCIgKm5nSWY9XCJtZXNzYWdlXCI+XG4gICAgPCEtLSBDb21tb24gYWN0aW9uIGJ1dHRvbnMgZm9yIFwidXNlclwiICYgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgKm5nSWY9XCJjYW5Db3B5XCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2UuY29weVRleHQnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImNvcHlNZXNzYWdlKG1lc3NhZ2UpXCI+XG4gICAgICA8aSBjbGFzcz1cImZhciBmYS1jbGlwYm9hcmRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJ1c2VyXCIgbWVzc2FnZSAtLT5cbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbVwiICpuZ0lmPVwiY2FuRWRpdFwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmVkaXRNZXNzYWdlJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJlZGl0LmVtaXQobWVzc2FnZSlcIj5cbiAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWVkaXRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgW2NsYXNzLmJvdW5jZV09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZFwiICpuZ0lmPVwiY2FuTGlrZVwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmxpa2VBbnN3ZXInIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImxpa2UuZW1pdCgpXCI+XG4gICAgICA8aSAqbmdJZj1cIiFtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZFwiIGNsYXNzPVwiZmFyIGZhLXRodW1icy11cCBcIj48L2k+XG4gICAgICA8aSAqbmdJZj1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGxpa2VkXCIgY2xhc3M9XCJmYXMgZmEtdGh1bWJzLXVwXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgW2NsYXNzLmJvdW5jZV09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkaXNsaWtlZFwiICpuZ0lmPVwiY2FuRGlzbGlrZVwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLnJlcG9ydElzc3VlJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJkaXNsaWtlLmVtaXQoKVwiPlxuICAgICAgPGkgKm5nSWY9XCIhbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGlzbGlrZWRcIiBjbGFzcz1cImZhciBmYS10aHVtYnMtZG93biBcIj48L2k+XG4gICAgICA8aSAqbmdJZj1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGRpc2xpa2VkXCIgY2xhc3M9XCJmYXMgZmEtdGh1bWJzLWRvd25cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhblJlZ2VuZXJhdGVcIiBbc3FUb29sdGlwXT1cIidjaGF0TWVzc2FnZS5yZWdlbmVyYXRlUmVzcG9uc2UnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cInJlZ2VuZXJhdGUuZW1pdChtZXNzYWdlKVwiPlxuICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtc3luYy1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhbkRlYnVnXCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2Uuc2hvd0xvZ0luZm9ybWF0aW9uJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJkZWJ1Zy5lbWl0KG1lc3NhZ2UpO1wiPlxuICAgICAgPGkgY2xhc3M9XCJmYXIgZmEtbGlzdC1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gTGlzdCBvZiBzdWdnZXN0ZWQgYWN0aW9ucywgaWYgYW55IC0tPlxuICA8ZGl2ICpuZ0lmPVwic3VnZ2VzdGVkQWN0aW9uc1wiIGNsYXNzPVwibXQtMiBtZXNzYWdlLXN1Z2dlc3Rpb25cIj5cbiAgICA8ZGl2IGNsYXNzPVwic3VnZ2VzdGVkLWFjdGlvblwiICpuZ0Zvcj1cImxldCBzdWdnZXN0ZWRBY3Rpb24gb2Ygc3VnZ2VzdGVkQWN0aW9uc1wiIChjbGljayk9XCJzdWdnZXN0QWN0aW9uLmVtaXQoc3VnZ2VzdGVkQWN0aW9uKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtY29udGVudFwiPlxuICAgICAgICA8cD48aSBjbGFzcz1cImZhcyBmYS1jbGlwYm9hcmQtcXVlc3Rpb25cIj48L2k+IHt7c3VnZ2VzdGVkQWN0aW9uLmNvbnRlbnR9fTwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8bmctdGVtcGxhdGUgI2ltYWdlVG9vbHRpcFRwbCBsZXQtcmVmPlxuICAgIDxJbmxpbmVJbWFnZVJlZmVyZW5jZVxuICAgICAgc3R5bGU9XCJtYXgtd2lkdGg6IDMwdnc7XCJcbiAgICAgIFtpZF09XCJyZWYuaWRcIlxuICAgICAgW3JlZl09XCJyZWYub2JqXCJcbiAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAvPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZSAjcGFnZVRvb2x0aXBUcGwgbGV0LXJlZj5cbiAgICA8SW5saW5lUGFnZVJlZmVyZW5jZVxuICAgICAgc3R5bGU9XCJtYXgtd2lkdGg6IDMwdnc7XCJcbiAgICAgIFtpZF09XCJyZWYuaWRcIlxuICAgICAgW3JlZl09XCJyZWYub2JqXCJcbiAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAvPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZSAjdG9vbHRpcFRwbCBsZXQtcmVmPlxuICAgIDxzcS1jaGF0LXJlZmVyZW5jZVxuICAgICAgKm5nSWY9XCIhaGlkZGVuVG9vbHRpcFwiXG4gICAgICBjbGFzcz1cImV4cGFuZGVkXCJcbiAgICAgIFthdHRhY2htZW50XT1cInJlZlwiXG4gICAgICBbcmVmZXJlbmNlXT1cInJlZi5jb250ZXh0SWRcIlxuICAgICAgW3BhcnRJZF09XCJyZWYuJHBhcnRJZFwiXG4gICAgICAob3BlblByZXZpZXcpPVwib3BlbkF0dGFjaG1lbnRQcmV2aWV3KCRldmVudCwgcmVmLiRwYXJ0SWQpXCJcbiAgICAgIChvcGVuRG9jdW1lbnQpPVwib3Blbk9yaWdpbmFsQXR0YWNobWVudCgkZXZlbnQsIHJlZi4kcGFydElkKVwiPlxuICAgIDwvc3EtY2hhdC1yZWZlcmVuY2U+XG4gIDwvbmctdGVtcGxhdGU+XG5cbjwvZGl2PlxuIl19