tas-uell-sdk 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +94 -53
  2. package/esm2020/lib/components/tas-avatar/tas-avatar.component.mjs +75 -0
  3. package/esm2020/lib/components/tas-btn/tas-btn.component.mjs +156 -63
  4. package/esm2020/lib/components/tas-floating-call/tas-floating-call.component.mjs +48 -23
  5. package/esm2020/lib/components/tas-videocall/tas-videocall.component.mjs +109 -18
  6. package/esm2020/lib/components/tas-waiting-room/tas-waiting-room.component.mjs +163 -131
  7. package/esm2020/lib/config/tas.config.mjs +1 -1
  8. package/esm2020/lib/interfaces/tas.interfaces.mjs +39 -2
  9. package/esm2020/lib/services/tas.service.mjs +363 -34
  10. package/esm2020/lib/tas-uell-sdk.module.mjs +20 -18
  11. package/esm2020/public-api.mjs +2 -1
  12. package/fesm2015/tas-uell-sdk.mjs +951 -270
  13. package/fesm2015/tas-uell-sdk.mjs.map +1 -1
  14. package/fesm2020/tas-uell-sdk.mjs +946 -268
  15. package/fesm2020/tas-uell-sdk.mjs.map +1 -1
  16. package/lib/components/tas-avatar/tas-avatar.component.d.ts +9 -0
  17. package/lib/components/tas-btn/tas-btn.component.d.ts +33 -15
  18. package/lib/components/tas-floating-call/tas-floating-call.component.d.ts +5 -1
  19. package/lib/components/tas-videocall/tas-videocall.component.d.ts +23 -2
  20. package/lib/components/tas-waiting-room/tas-waiting-room.component.d.ts +30 -26
  21. package/lib/config/tas.config.d.ts +4 -0
  22. package/lib/interfaces/tas.interfaces.d.ts +103 -35
  23. package/lib/services/tas.service.d.ts +86 -9
  24. package/lib/tas-uell-sdk.module.d.ts +4 -2
  25. package/package.json +1 -1
  26. package/public-api.d.ts +1 -0
  27. package/src/lib/styles/tas-global.scss +27 -28
  28. package/INSTALL_AND_TEST.md +0 -427
@@ -1,7 +1,6 @@
1
1
  import { Component, Input } from '@angular/core';
2
2
  import { Subscription } from 'rxjs';
3
- import { switchMap } from 'rxjs/operators';
4
- import { TasRoomType, TasSessionType, TasUserRole, ViewMode } from '../../interfaces/tas.interfaces';
3
+ import { TasRoomType, TasBusinessRole, TasUserRole, } from '../../interfaces/tas.interfaces';
5
4
  import { TasVideocallComponent } from '../tas-videocall/tas-videocall.component';
6
5
  import * as i0 from "@angular/core";
7
6
  import * as i1 from "@ng-bootstrap/ng-bootstrap";
@@ -9,127 +8,192 @@ import * as i2 from "../../services/tas.service";
9
8
  import * as i3 from "@angular/common";
10
9
  export var WaitingRoomState;
11
10
  (function (WaitingRoomState) {
12
- WaitingRoomState["IDLE"] = "IDLE";
13
- WaitingRoomState["CREATING_ROOM"] = "CREATING_ROOM";
14
- WaitingRoomState["GETTING_TOKEN"] = "GETTING_TOKEN";
11
+ WaitingRoomState["CHECKING_STATUS"] = "CHECKING_STATUS";
12
+ WaitingRoomState["WAITING_FOR_OWNER"] = "WAITING_FOR_OWNER";
15
13
  WaitingRoomState["READY"] = "READY";
14
+ WaitingRoomState["GETTING_TOKEN"] = "GETTING_TOKEN";
16
15
  WaitingRoomState["ERROR"] = "ERROR";
17
16
  })(WaitingRoomState || (WaitingRoomState = {}));
18
17
  export class TasWaitingRoomComponent {
19
- constructor(activeModal, tasService, modalService) {
18
+ constructor(activeModal, tasService, modalService, cdr) {
20
19
  this.activeModal = activeModal;
21
20
  this.tasService = tasService;
22
21
  this.modalService = modalService;
23
- // Room configuration inputs
24
- this.appointmentId = 1;
25
- this.product = 'uell';
26
- this.tenantId = '';
27
- this.regularUserIds = [];
28
- this.moderatorUserIds = [];
29
- /** Optional: If provided, skips room creation and goes directly to getting a token */
30
- this.existingSessionId = '';
22
+ this.cdr = cdr;
23
+ // Status endpoint params
24
+ this.roomType = TasRoomType.TAS;
25
+ this.businessRole = TasBusinessRole.USER;
31
26
  // Component state
32
- this.state = WaitingRoomState.IDLE;
27
+ this.state = WaitingRoomState.CHECKING_STATUS;
33
28
  this.WaitingRoomState = WaitingRoomState; // Expose enum to template
34
29
  this.errorMessage = '';
35
- /** Whether we have an existing session (skip room creation) */
36
- this.hasExistingSession = false;
37
- // Session data
38
- this.sessionId = '';
30
+ // Session data from status response
31
+ this.resolvedSessionId = '';
32
+ this.resolvedAppointmentId = null;
39
33
  this.token = '';
40
- this.users = [];
34
+ this.videoCallId = null;
35
+ // Subscriptions
41
36
  this.subscriptions = new Subscription();
42
37
  this.videoCallModalRef = null;
43
38
  }
39
+ /** Whether current user is an owner */
40
+ get isOwner() {
41
+ return this.currentUser?.role === TasUserRole.OWNER;
42
+ }
44
43
  ngOnInit() {
45
- this.buildUsersArray();
46
- this.setupViewModeSubscription();
47
- // Check if we have an existing session
48
- if (this.existingSessionId && this.existingSessionId.trim() !== '') {
49
- this.hasExistingSession = true;
50
- this.sessionId = this.existingSessionId;
51
- }
44
+ console.log('[TAS DEBUG] TasWaitingRoomComponent.ngOnInit');
45
+ this.checkStatus();
52
46
  }
53
47
  ngOnDestroy() {
48
+ console.log('[TAS DEBUG] TasWaitingRoomComponent.ngOnDestroy');
54
49
  this.subscriptions.unsubscribe();
50
+ this.tasService.stopStatusPolling();
55
51
  }
56
52
  /**
57
- * Creates the room and fetches the token (new session flow)
53
+ * Check status to get session info
58
54
  */
59
- createRoom() {
60
- if (!this.tenantId || !this.currentUser?.name) {
61
- this.state = WaitingRoomState.ERROR;
62
- this.errorMessage = 'Missing configuration data (tenant or user)';
63
- return;
64
- }
65
- this.state = WaitingRoomState.CREATING_ROOM;
55
+ checkStatus() {
56
+ console.log('[TAS DEBUG] checkStatus called with:', {
57
+ roomType: this.roomType,
58
+ entityId: this.entityId,
59
+ tenant: this.tenant,
60
+ businessRole: this.businessRole,
61
+ currentUser: this.currentUser,
62
+ });
63
+ this.state = WaitingRoomState.CHECKING_STATUS;
66
64
  this.errorMessage = '';
67
- const body = {
68
- roomType: TasRoomType.TAS,
69
- type: TasSessionType.SPONTANEOUS,
70
- tenant: this.tenantId,
71
- appointmentId: this.appointmentId,
72
- users: this.users,
73
- product: this.product
65
+ const statusParams = {
66
+ roomType: this.roomType,
67
+ entityId: this.entityId,
68
+ tenant: this.tenant,
69
+ businessRole: this.businessRole,
74
70
  };
75
- this.subscriptions.add(this.tasService.createRoom(body).pipe(switchMap(response => {
76
- this.sessionId = response.content.sessionId;
77
- this.state = WaitingRoomState.GETTING_TOKEN;
78
- return this.tasService.generateToken({
79
- sessionId: this.sessionId,
80
- name: this.currentUser.name,
81
- lastname: this.currentUser.lastname,
82
- roleVC: this.currentUser.role
83
- });
84
- })).subscribe({
85
- next: (tokenResponse) => {
86
- this.token = tokenResponse.content.token;
87
- this.state = WaitingRoomState.READY;
71
+ console.log('[TAS DEBUG] Calling getProxyVideoStatus...');
72
+ this.subscriptions.add(this.tasService.getProxyVideoStatus(statusParams).subscribe({
73
+ next: (response) => {
74
+ const content = response.content;
75
+ // Store session info from response
76
+ this.resolvedSessionId = content.sessionId;
77
+ this.resolvedAppointmentId = content.appointmentId;
78
+ this.videoCallId = content.videoCallId;
79
+ console.log('[TAS DEBUG] Status response:', content);
80
+ // Start polling for status updates
81
+ this.tasService.startStatusPolling(statusParams);
82
+ // Subscribe to joinable status
83
+ this.subscriptions.add(this.tasService.joinable$.subscribe((joinable) => {
84
+ this.handleJoinableChange(joinable);
85
+ }));
88
86
  },
89
87
  error: (err) => {
90
- console.error('Error creating room or getting token:', err);
88
+ console.error('[TAS DEBUG] Status check failed:', err);
91
89
  this.state = WaitingRoomState.ERROR;
92
- this.errorMessage = 'Error creating room. Please try again.';
93
- }
90
+ this.errorMessage = 'Error checking session status. Please try again.';
91
+ },
94
92
  }));
95
93
  }
96
94
  /**
97
- * Gets a token for an existing session (existing session flow)
95
+ * Handle changes to joinable status
98
96
  */
99
- getTokenForExistingSession() {
100
- if (!this.sessionId || !this.currentUser?.name) {
97
+ handleJoinableChange(joinable) {
98
+ console.log('[TAS DEBUG] handleJoinableChange called', {
99
+ joinable,
100
+ currentState: this.state,
101
+ isOwner: this.isOwner,
102
+ isBackoffice: this.isBackoffice,
103
+ resolvedSessionId: this.resolvedSessionId,
104
+ });
105
+ // Don't update state if already getting token, ready, or in error
106
+ if (this.state === WaitingRoomState.GETTING_TOKEN ||
107
+ this.state === WaitingRoomState.READY ||
108
+ this.state === WaitingRoomState.ERROR) {
109
+ console.log('[TAS DEBUG] Skipping state update - already in:', this.state);
110
+ return;
111
+ }
112
+ if (this.isOwner || this.isBackoffice) {
113
+ console.log('[TAS DEBUG] User is owner/backoffice, calling getTokenForOwner');
114
+ // Owner/Backoffice: call /start to get token first, then show join button
115
+ if (this.state === WaitingRoomState.CHECKING_STATUS) {
116
+ this.getTokenForOwner();
117
+ }
118
+ }
119
+ else {
120
+ // Non-owner: wait until joinable is true
121
+ if (joinable) {
122
+ console.log('[TAS DEBUG] Non-owner: joinable is true, getting token');
123
+ this.getTokenForOwner(); // Also get token when joinable
124
+ }
125
+ else {
126
+ console.log('[TAS DEBUG] Non-owner: waiting for owner');
127
+ this.state = WaitingRoomState.WAITING_FOR_OWNER;
128
+ this.cdr.detectChanges();
129
+ }
130
+ }
131
+ }
132
+ /**
133
+ * Check if user has owner/backoffice role
134
+ */
135
+ get isBackoffice() {
136
+ return (this.businessRole === TasBusinessRole.BACKOFFICE ||
137
+ this.businessRole === TasBusinessRole.ADMIN_MANAGER ||
138
+ this.businessRole === TasBusinessRole.MANAGER);
139
+ }
140
+ /**
141
+ * Get token for owner/backoffice - call /start endpoint
142
+ */
143
+ getTokenForOwner() {
144
+ if (!this.resolvedSessionId) {
101
145
  this.state = WaitingRoomState.ERROR;
102
- this.errorMessage = 'Missing session ID or user data';
146
+ this.errorMessage = 'Session ID not available';
147
+ this.tasService.stopStatusPolling();
148
+ this.cdr.detectChanges();
103
149
  return;
104
150
  }
105
151
  this.state = WaitingRoomState.GETTING_TOKEN;
106
152
  this.errorMessage = '';
107
- this.subscriptions.add(this.tasService.generateToken({
108
- sessionId: this.sessionId,
153
+ console.log('[TAS DEBUG] Calling /start for session:', this.resolvedSessionId);
154
+ this.subscriptions.add(this.tasService
155
+ .startProxyVideoSession({
156
+ sessionId: this.resolvedSessionId,
109
157
  name: this.currentUser.name,
110
158
  lastname: this.currentUser.lastname,
111
- roleVC: this.currentUser.role
112
- }).subscribe({
159
+ })
160
+ .subscribe({
113
161
  next: (tokenResponse) => {
162
+ console.log('[TAS DEBUG] Token response:', tokenResponse);
163
+ // Handle case where HTTP adapter returns error in next instead of error handler
164
+ if (!tokenResponse?.content?.token) {
165
+ console.error('[TAS DEBUG] Invalid token response:', tokenResponse);
166
+ this.state = WaitingRoomState.ERROR;
167
+ this.errorMessage = tokenResponse?.message || 'Error al iniciar la sesión. Respuesta inválida.';
168
+ this.tasService.stopStatusPolling();
169
+ this.cdr.detectChanges();
170
+ return;
171
+ }
172
+ console.log('[TAS DEBUG] Token obtained successfully');
114
173
  this.token = tokenResponse.content.token;
115
174
  this.state = WaitingRoomState.READY;
175
+ this.cdr.detectChanges();
116
176
  },
117
177
  error: (err) => {
118
- console.error('Error getting token:', err);
178
+ console.error('[TAS DEBUG] /start request failed:', err);
119
179
  this.state = WaitingRoomState.ERROR;
120
- this.errorMessage = 'Error getting session token. Please try again.';
121
- }
180
+ this.errorMessage = err?.error?.message || err?.message || 'Error al iniciar la sesión. Por favor, intente nuevamente.';
181
+ this.tasService.stopStatusPolling();
182
+ console.log('[TAS DEBUG] State set to ERROR, errorMessage:', this.errorMessage);
183
+ this.cdr.detectChanges();
184
+ },
122
185
  }));
123
186
  }
124
187
  /**
125
- * Joins the video call session
188
+ * Join the session - token already obtained
126
189
  */
127
190
  joinSession() {
128
- if (!this.sessionId || !this.token) {
129
- this.errorMessage = 'Cannot join session. Incomplete data.';
191
+ if (!this.resolvedSessionId || !this.token) {
192
+ this.errorMessage = 'Session not ready';
130
193
  return;
131
194
  }
132
195
  // Close waiting room and open video call
196
+ this.tasService.stopStatusPolling();
133
197
  this.activeModal.close('joining');
134
198
  this.openVideoCallModal();
135
199
  }
@@ -137,85 +201,53 @@ export class TasWaitingRoomComponent {
137
201
  * Closes the waiting room
138
202
  */
139
203
  cancel() {
204
+ this.tasService.stopStatusPolling();
140
205
  this.activeModal.dismiss('cancel');
141
206
  }
142
207
  /**
143
208
  * Retry after an error
144
209
  */
145
210
  retry() {
146
- this.state = WaitingRoomState.IDLE;
211
+ this.state = WaitingRoomState.CHECKING_STATUS;
147
212
  this.errorMessage = '';
148
213
  this.token = '';
149
- // Only reset sessionId if we don't have an existing one
150
- if (!this.hasExistingSession) {
151
- this.sessionId = '';
152
- }
153
- }
154
- // Private Methods
155
- buildUsersArray() {
156
- this.users = [];
157
- // Add owners from input
158
- this.ownerUserIds.forEach(id => {
159
- this.users.push({ userExternalId: id, rol: TasUserRole.OWNER });
160
- });
161
- // Add regular users from input
162
- this.regularUserIds.forEach(id => {
163
- this.users.push({ userExternalId: id, rol: TasUserRole.USER });
164
- });
165
- // Add moderators from input
166
- this.moderatorUserIds.forEach(id => {
167
- this.users.push({ userExternalId: id, rol: TasUserRole.MODERATOR });
168
- });
169
- }
170
- setupViewModeSubscription() {
171
- this.subscriptions.add(this.tasService.viewMode$.subscribe(mode => {
172
- // Re-open video call modal when returning from PiP mode
173
- if (mode === ViewMode.FULLSCREEN &&
174
- this.tasService.isCallActive() &&
175
- !this.videoCallModalRef) {
176
- const sessionId = this.tasService.sessionId;
177
- const token = this.tasService.token;
178
- if (sessionId && token) {
179
- this.openVideoCallModal(true);
180
- }
181
- }
182
- }));
214
+ this.checkStatus();
183
215
  }
184
- openVideoCallModal(isReturningFromPip = false) {
216
+ openVideoCallModal() {
185
217
  this.videoCallModalRef = this.modalService.open(TasVideocallComponent, {
186
218
  size: 'xl',
187
219
  windowClass: 'tas-video-modal',
188
220
  backdrop: 'static',
189
- keyboard: false
221
+ keyboard: false,
222
+ });
223
+ this.videoCallModalRef.componentInstance.sessionId = this.resolvedSessionId;
224
+ this.videoCallModalRef.componentInstance.token = this.token;
225
+ this.videoCallModalRef.componentInstance.appointmentId = this.resolvedAppointmentId;
226
+ this.videoCallModalRef.componentInstance.videoCallId = this.videoCallId;
227
+ this.videoCallModalRef.componentInstance.tenant = this.tenant;
228
+ this.videoCallModalRef.componentInstance.businessRole = this.businessRole;
229
+ this.videoCallModalRef.componentInstance.isReturningFromPip = false;
230
+ this.videoCallModalRef.result.then(() => {
231
+ this.videoCallModalRef = null;
232
+ }, () => {
233
+ this.videoCallModalRef = null;
190
234
  });
191
- const sessionIdToUse = this.sessionId || this.tasService.sessionId;
192
- const tokenToUse = this.token || this.tasService.token;
193
- this.videoCallModalRef.componentInstance.sessionId = sessionIdToUse;
194
- this.videoCallModalRef.componentInstance.token = tokenToUse;
195
- this.videoCallModalRef.componentInstance.isReturningFromPip = isReturningFromPip;
196
- this.videoCallModalRef.result.then(() => { this.videoCallModalRef = null; }, () => { this.videoCallModalRef = null; });
197
235
  }
198
236
  }
199
- TasWaitingRoomComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasWaitingRoomComponent, deps: [{ token: i1.NgbActiveModal }, { token: i2.TasService }, { token: i1.NgbModal }], target: i0.ɵɵFactoryTarget.Component });
200
- TasWaitingRoomComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasWaitingRoomComponent, selector: "tas-waiting-room", inputs: { appointmentId: "appointmentId", product: "product", tenantId: "tenantId", currentUser: "currentUser", ownerUserIds: "ownerUserIds", regularUserIds: "regularUserIds", moderatorUserIds: "moderatorUserIds", existingSessionId: "existingSessionId" }, ngImport: i0, template: "<div class=\"tas-waiting-room\">\n\t<!-- Header -->\n\t<div class=\"waiting-room-header\">\n\t\t<div class=\"header-icon\">\n\t\t\t<i class=\"fa fa-video-camera\"></i>\n\t\t</div>\n\t\t<h2 class=\"header-title\">Waiting Room</h2>\n\t\t<p class=\"header-subtitle\">Prepare for your video call</p>\n\t\t<button type=\"button\" class=\"close-btn\" (click)=\"cancel()\" aria-label=\"Close\">\n\t\t\t<span aria-hidden=\"true\">&times;</span>\n\t\t</button>\n\t</div>\n\n\t<!-- Content -->\n\t<div class=\"waiting-room-content\">\n\t\t<!-- IDLE State - New Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.IDLE && !hasExistingSession\">\n\t\t\t<div class=\"state-icon idle\">\n\t\t\t\t<i class=\"fa fa-plus-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreate a new video call room\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tPress the button to begin\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn create-btn\"\n\t\t\t\t(click)=\"createRoom()\">\n\t\t\t\t<i class=\"fa fa-plus\"></i>\n\t\t\t\tCreate Room\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- IDLE State - Existing Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.IDLE && hasExistingSession\">\n\t\t\t<div class=\"state-icon idle\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tJoin existing video call room\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tPress the button to get access\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn create-btn\"\n\t\t\t\t(click)=\"getTokenForExistingSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Room\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- CREATING_ROOM State (only for new sessions) -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.CREATING_ROOM\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreating video call room...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Creating</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- GETTING_TOKEN State - New Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN && !hasExistingSession\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tPreparing room access...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- GETTING_TOKEN State - Existing Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN && hasExistingSession\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tGetting room access...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Connecting</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- READY State - New Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY && !hasExistingSession\">\n\t\t\t<div class=\"state-icon ready\">\n\t\t\t\t<i class=\"fa fa-check-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message success\">\n\t\t\t\tRoom is ready!\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tYou can join the video call when ready\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn join-btn\"\n\t\t\t\t(click)=\"joinSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Session\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- READY State - Existing Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY && hasExistingSession\">\n\t\t\t<div class=\"state-icon ready\">\n\t\t\t\t<i class=\"fa fa-check-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message success\">\n\t\t\t\tReady to join!\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tYou can join the video call when ready\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Connected</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn join-btn\"\n\t\t\t\t(click)=\"joinSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Session\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- ERROR State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.ERROR\">\n\t\t\t<div class=\"state-icon error\">\n\t\t\t\t<i class=\"fa fa-exclamation-triangle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message error\">\n\t\t\t\tAn error occurred\n\t\t\t</p>\n\t\t\t<p class=\"error-details\" *ngIf=\"errorMessage\">\n\t\t\t\t{{ errorMessage }}\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn retry-btn\"\n\t\t\t\t(click)=\"retry()\">\n\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\tRetry\n\t\t\t</button>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer -->\n\t<div class=\"waiting-room-footer\">\n\t\t<button \n\t\t\ttype=\"button\" \n\t\t\tclass=\"btn cancel-btn\"\n\t\t\t(click)=\"cancel()\">\n\t\t\tCancel\n\t\t</button>\n\t</div>\n</div>\n", styles: [".tas-waiting-room{display:flex;flex-direction:column;min-height:420px;background:#ffffff;border-radius:5px;overflow:hidden}.waiting-room-header{position:relative;padding:32px 40px 24px;text-align:center;border-bottom:1px solid #e9ecef}.waiting-room-header .header-icon{width:72px;height:72px;margin:0 auto 16px;background:linear-gradient(135deg,#1da4b1 0%,#0077b3 100%);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #1da4b140}.waiting-room-header .header-icon i{font-size:28px;color:#fff}.waiting-room-header .header-title{margin:0 0 8px;font-size:20px;font-weight:700;line-height:28px;color:#212529}.waiting-room-header .header-subtitle{margin:0;font-size:14px;color:#6c757d;font-weight:400}.waiting-room-header .close-btn{position:absolute;top:16px;right:16px;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#6c757d;cursor:pointer;transition:all .2s ease;font-size:20px}.waiting-room-header .close-btn:hover{background:#f8f9fa;color:#212529}.waiting-room-content{flex:1;display:flex;align-items:center;justify-content:center;padding:32px 40px;background:#ffffff}.state-container{text-align:center;max-width:360px;width:100%}.state-icon{width:80px;height:80px;margin:0 auto 24px;border-radius:50%;display:flex;align-items:center;justify-content:center}.state-icon i{font-size:36px}.state-icon.idle{background:rgba(29,164,177,.1);border:2px dashed #1da4b1}.state-icon.idle i{color:#1da4b1}.state-icon.loading{background:rgba(29,164,177,.1);border:2px solid #1da4b1}.state-icon.ready{background:linear-gradient(135deg,#1da4b1 0%,#38b89a 100%);box-shadow:0 4px 16px #1da4b14d}.state-icon.ready i{color:#fff}.state-icon.error{background:rgba(238,49,107,.1);border:2px solid #ee316b}.state-icon.error i{color:#ee316b}.spinner{width:40px;height:40px;border:3px solid #e9ecef;border-top-color:#1da4b1;border-radius:50%;animation:spin 1s linear infinite}.state-message{font-size:16px;font-weight:600;margin:0 0 8px;color:#212529;line-height:24px}.state-message.success{color:#1da4b1}.state-message.error{color:#ee316b}.state-submessage{font-size:14px;color:#6c757d;margin:0 0 24px;font-weight:400}.error-details{font-size:13px;color:#ee316b;margin:0 0 24px;padding:12px 16px;background:rgba(238,49,107,.08);border-radius:8px;border:1px solid rgba(238,49,107,.2)}.progress-steps{display:flex;justify-content:center;gap:24px;margin:24px 0 32px}.step{display:flex;flex-direction:column;align-items:center;gap:8px}.step .step-indicator{width:32px;height:32px;border-radius:50%;background:#f8f9fa;border:2px solid #e9ecef;display:flex;align-items:center;justify-content:center;transition:all .3s ease}.step .step-indicator i{font-size:12px;color:#fff}.step .step-label{font-size:11px;color:#6c757d;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.step.active .step-indicator{background:rgba(29,164,177,.1);border-color:#1da4b1;animation:pulse-active 1.5s infinite}.step.active .step-label{color:#1da4b1;font-weight:600}.step.completed .step-indicator{background:#1da4b1;border-color:#1da4b1}.step.completed .step-label{color:#1da4b1;font-weight:600}.action-btn{padding:12px 32px;font-size:16px;font-weight:600;border-radius:4px;border:none;cursor:pointer;transition:all .2s ease;display:inline-flex;align-items:center;gap:10px}.action-btn i{font-size:16px}.action-btn.create-btn{background:#0077b3;color:#fff;box-shadow:0 2px 8px #0077b340}.action-btn.create-btn:hover{background:#005c8a;box-shadow:0 4px 12px #0077b359}.action-btn.create-btn:active{transform:translateY(1px)}.action-btn.join-btn{background:#1da4b1;color:#fff;box-shadow:0 2px 8px #1da4b140;animation:pulse-ready 2s infinite}.action-btn.join-btn:hover{background:#17848e;box-shadow:0 4px 12px #1da4b159}.action-btn.join-btn:active{transform:translateY(1px)}.action-btn.retry-btn{background:transparent;color:#6c757d;border:1px solid #e9ecef}.action-btn.retry-btn:hover{background:#f8f9fa;border-color:#6c757d;color:#212529}.waiting-room-footer{padding:16px 40px 24px;background:#ffffff;border-top:1px solid #e9ecef;display:flex;justify-content:center}.waiting-room-footer .cancel-btn{padding:10px 24px;font-size:14px;font-weight:600;border-radius:4px;background:transparent;color:#6c757d;border:none;cursor:pointer;transition:all .2s ease}.waiting-room-footer .cancel-btn:hover{background:#f8f9fa;color:#212529}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-active{0%,to{box-shadow:0 0 #1da4b166}50%{box-shadow:0 0 0 8px #1da4b100}}@keyframes pulse-ready{0%,to{box-shadow:0 2px 8px #1da4b140}50%{box-shadow:0 4px 16px #1da4b166}}@media (max-width: 576px){.tas-waiting-room{min-height:380px}.waiting-room-header{padding:24px 24px 20px}.waiting-room-header .header-icon{width:56px;height:56px}.waiting-room-header .header-icon i{font-size:22px}.waiting-room-header .header-title{font-size:18px}.waiting-room-content{padding:24px}.state-icon{width:64px;height:64px}.state-icon i{font-size:28px}.spinner{width:32px;height:32px}.progress-steps{gap:12px}.step .step-indicator{width:28px;height:28px}.step .step-label{font-size:9px}.action-btn{padding:10px 24px;font-size:14px}.waiting-room-footer{padding:16px 24px 20px}}\n"], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
201
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasWaitingRoomComponent, decorators: [{
237
+ TasWaitingRoomComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TasWaitingRoomComponent, deps: [{ token: i1.NgbActiveModal }, { token: i2.TasService }, { token: i1.NgbModal }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
238
+ TasWaitingRoomComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: TasWaitingRoomComponent, selector: "tas-waiting-room", inputs: { roomType: "roomType", entityId: "entityId", tenant: "tenant", businessRole: "businessRole", currentUser: "currentUser" }, ngImport: i0, template: "<div class=\"tas-waiting-room\">\n <!-- Header -->\n <div class=\"waiting-room-header\">\n <h2 class=\"header-title\">Iniciar turno</h2>\n <button type=\"button\" class=\"close-btn\" (click)=\"cancel()\" aria-label=\"Close\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"waiting-room-content\">\n <!-- CHECKING_STATUS State -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.CHECKING_STATUS\">\n <div class=\"state-icon loading\">\n <div class=\"spinner\"></div>\n </div>\n <p class=\"state-message\">Verificando estado de la sesi\u00F3n...</p>\n </div>\n\n <!-- WAITING_FOR_OWNER State (Non-owner waiting) -->\n <div class=\"state-container waiting-for-owner\" *ngIf=\"state === WaitingRoomState.WAITING_FOR_OWNER\">\n <div class=\"state-icon loading\">\n <div class=\"spinner\"></div>\n </div>\n <p class=\"state-message waiting-title\">Medicina laboral te va a admitir en unos instantes...</p>\n <p class=\"state-submessage\">Por favor, permanec\u00E9 en esta pantalla hasta que inicie la consulta.</p>\n </div>\n\n <!-- READY State (Owner can join) -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY\">\n <div class=\"state-icon ready\">\n <i class=\"fa fa-check-circle\"></i>\n </div>\n <p class=\"state-message success\">\u00A1La sala est\u00E1 lista!</p>\n <p class=\"state-submessage\">Pod\u00E9s unirte a la videollamada cuando quieras</p>\n <button type=\"button\" class=\"btn action-btn join-btn\" (click)=\"joinSession()\">\n <i class=\"fa fa-sign-in\"></i>\n Unirse a la llamada\n </button>\n </div>\n\n <!-- GETTING_TOKEN State -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN\">\n <div class=\"state-icon loading\">\n <div class=\"spinner\"></div>\n </div>\n <p class=\"state-message\">Conectando...</p>\n </div>\n\n <!-- ERROR State -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.ERROR\">\n <div class=\"state-icon error\">\n <i class=\"fa fa-exclamation-triangle\"></i>\n </div>\n <p class=\"state-message error\">Ocurri\u00F3 un error</p>\n <p class=\"error-details\" *ngIf=\"errorMessage\">\n {{ errorMessage }}\n </p>\n <button type=\"button\" class=\"btn action-btn retry-btn\" (click)=\"retry()\">\n <i class=\"fa fa-refresh\"></i>\n Reintentar\n </button>\n </div>\n </div>\n</div>\n", styles: [".tas-waiting-room{display:flex;flex-direction:column;min-height:420px;background:#ffffff;border-radius:5px;overflow:hidden}.waiting-room-header{position:relative;padding:20px 40px;border-bottom:1px solid #e9ecef;display:flex;align-items:center;justify-content:space-between}.waiting-room-header .header-title{margin:0;font-size:18px;font-weight:600;line-height:24px;color:#212529}.waiting-room-header .close-btn{width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#6c757d;cursor:pointer;transition:all .2s ease;font-size:20px;display:flex;align-items:center;justify-content:center}.waiting-room-header .close-btn:hover{background:#f8f9fa;color:#212529}.waiting-title{font-size:16px;font-weight:600;color:#212529;margin-bottom:8px}.waiting-room-content{flex:1;display:flex;align-items:center;justify-content:center;padding:32px 40px;background:#ffffff}.state-container{text-align:center;max-width:400px;width:100%}.mode-tabs{display:flex;justify-content:center;gap:8px;margin-bottom:24px;padding:4px;background:#f8f9fa;border-radius:8px}.mode-tab{flex:1;padding:10px 16px;font-size:13px;font-weight:600;border:none;border-radius:6px;background:transparent;color:#6c757d;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;justify-content:center;gap:8px}.mode-tab i{font-size:14px}.mode-tab:hover{color:#212529}.mode-tab.active{background:#ffffff;color:#1da4b1;box-shadow:0 2px 8px #00000014}.mode-content{animation:fadeIn .3s ease}.session-input-container{display:flex;flex-direction:column;gap:16px;margin-top:8px}.session-input{width:100%;padding:14px 16px;font-size:14px;border:2px solid #e9ecef;border-radius:8px;background:#ffffff;color:#212529;transition:all .2s ease;text-align:center;font-family:Monaco,Consolas,monospace;letter-spacing:.5px}.session-input::placeholder{color:#6c757d;font-family:inherit;letter-spacing:normal}.session-input:focus{outline:none;border-color:#1da4b1;box-shadow:0 0 0 3px #1da4b126}.session-input:hover:not(:focus){border-color:#6c757d}@keyframes fadeIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.state-icon{width:80px;height:80px;margin:0 auto 24px;border-radius:50%;display:flex;align-items:center;justify-content:center}.state-icon i{font-size:36px}.state-icon.idle{background:rgba(29,164,177,.1);border:2px dashed #1da4b1}.state-icon.idle i{color:#1da4b1}.state-icon.loading{background:rgba(29,164,177,.1);border:2px solid #1da4b1}.state-icon.ready{background:linear-gradient(135deg,#1da4b1 0%,#38b89a 100%);box-shadow:0 4px 16px #1da4b14d}.state-icon.ready i{color:#fff}.state-icon.error{background:rgba(238,49,107,.1);border:2px solid #ee316b}.state-icon.error i{color:#ee316b}.spinner{width:40px;height:40px;border:3px solid #e9ecef;border-top-color:#1da4b1;border-radius:50%;animation:spin 1s linear infinite}.state-message{font-size:16px;font-weight:600;margin:0 0 8px;color:#212529;line-height:24px}.state-message.success{color:#1da4b1}.state-message.error{color:#ee316b}.state-submessage{font-size:14px;color:#6c757d;margin:0 0 24px;font-weight:400}.error-details{font-size:13px;color:#ee316b;margin:0 0 24px;padding:12px 16px;background:rgba(238,49,107,.08);border-radius:8px;border:1px solid rgba(238,49,107,.2)}.progress-steps{display:flex;justify-content:center;gap:24px;margin:24px 0 32px}.step{display:flex;flex-direction:column;align-items:center;gap:8px}.step .step-indicator{width:32px;height:32px;border-radius:50%;background:#f8f9fa;border:2px solid #e9ecef;display:flex;align-items:center;justify-content:center;transition:all .3s ease}.step .step-indicator i{font-size:12px;color:#fff}.step .step-label{font-size:11px;color:#6c757d;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.step.active .step-indicator{background:rgba(29,164,177,.1);border-color:#1da4b1;animation:pulse-active 1.5s infinite}.step.active .step-label{color:#1da4b1;font-weight:600}.step.completed .step-indicator{background:#1da4b1;border-color:#1da4b1}.step.completed .step-label{color:#1da4b1;font-weight:600}.action-btn{padding:12px 32px;font-size:16px;font-weight:600;border-radius:4px;border:none;cursor:pointer;transition:all .2s ease;display:inline-flex;align-items:center;gap:10px}.action-btn i{font-size:16px}.action-btn.create-btn{background:#0077b3;color:#fff;box-shadow:0 2px 8px #0077b340}.action-btn.create-btn:hover{background:#005c8a;box-shadow:0 4px 12px #0077b359}.action-btn.create-btn:active{transform:translateY(1px)}.action-btn.join-btn{background:#1da4b1;color:#fff;box-shadow:0 2px 8px #1da4b140;animation:pulse-ready 2s infinite}.action-btn.join-btn:hover{background:#17848e;box-shadow:0 4px 12px #1da4b159}.action-btn.join-btn:active{transform:translateY(1px)}.action-btn.retry-btn{background:transparent;color:#6c757d;border:1px solid #e9ecef}.action-btn.retry-btn:hover{background:#f8f9fa;border-color:#6c757d;color:#212529}.waiting-room-footer{padding:16px 40px 24px;background:#ffffff;border-top:1px solid #e9ecef;display:flex;justify-content:center}.waiting-room-footer .cancel-btn{padding:10px 24px;font-size:14px;font-weight:600;border-radius:4px;background:transparent;color:#6c757d;border:none;cursor:pointer;transition:all .2s ease}.waiting-room-footer .cancel-btn:hover{background:#f8f9fa;color:#212529}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-active{0%,to{box-shadow:0 0 #1da4b166}50%{box-shadow:0 0 0 8px #1da4b100}}@keyframes pulse-ready{0%,to{box-shadow:0 2px 8px #1da4b140}50%{box-shadow:0 4px 16px #1da4b166}}@media (max-width: 576px){.tas-waiting-room{min-height:380px}.waiting-room-header{padding:24px 24px 20px}.waiting-room-header .header-icon{width:56px;height:56px}.waiting-room-header .header-icon i{font-size:22px}.waiting-room-header .header-title{font-size:18px}.waiting-room-content{padding:24px}.state-icon{width:64px;height:64px}.state-icon i{font-size:28px}.spinner{width:32px;height:32px}.progress-steps{gap:12px}.step .step-indicator{width:28px;height:28px}.step .step-label{font-size:9px}.action-btn{padding:10px 24px;font-size:14px}.waiting-room-footer{padding:16px 24px 20px}}\n"], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TasWaitingRoomComponent, decorators: [{
202
240
  type: Component,
203
- args: [{ selector: 'tas-waiting-room', template: "<div class=\"tas-waiting-room\">\n\t<!-- Header -->\n\t<div class=\"waiting-room-header\">\n\t\t<div class=\"header-icon\">\n\t\t\t<i class=\"fa fa-video-camera\"></i>\n\t\t</div>\n\t\t<h2 class=\"header-title\">Waiting Room</h2>\n\t\t<p class=\"header-subtitle\">Prepare for your video call</p>\n\t\t<button type=\"button\" class=\"close-btn\" (click)=\"cancel()\" aria-label=\"Close\">\n\t\t\t<span aria-hidden=\"true\">&times;</span>\n\t\t</button>\n\t</div>\n\n\t<!-- Content -->\n\t<div class=\"waiting-room-content\">\n\t\t<!-- IDLE State - New Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.IDLE && !hasExistingSession\">\n\t\t\t<div class=\"state-icon idle\">\n\t\t\t\t<i class=\"fa fa-plus-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreate a new video call room\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tPress the button to begin\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn create-btn\"\n\t\t\t\t(click)=\"createRoom()\">\n\t\t\t\t<i class=\"fa fa-plus\"></i>\n\t\t\t\tCreate Room\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- IDLE State - Existing Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.IDLE && hasExistingSession\">\n\t\t\t<div class=\"state-icon idle\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tJoin existing video call room\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tPress the button to get access\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn create-btn\"\n\t\t\t\t(click)=\"getTokenForExistingSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Room\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- CREATING_ROOM State (only for new sessions) -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.CREATING_ROOM\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreating video call room...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Creating</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- GETTING_TOKEN State - New Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN && !hasExistingSession\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tPreparing room access...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- GETTING_TOKEN State - Existing Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN && hasExistingSession\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tGetting room access...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Connecting</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- READY State - New Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY && !hasExistingSession\">\n\t\t\t<div class=\"state-icon ready\">\n\t\t\t\t<i class=\"fa fa-check-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message success\">\n\t\t\t\tRoom is ready!\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tYou can join the video call when ready\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn join-btn\"\n\t\t\t\t(click)=\"joinSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Session\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- READY State - Existing Session -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY && hasExistingSession\">\n\t\t\t<div class=\"state-icon ready\">\n\t\t\t\t<i class=\"fa fa-check-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message success\">\n\t\t\t\tReady to join!\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tYou can join the video call when ready\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Connected</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn join-btn\"\n\t\t\t\t(click)=\"joinSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Session\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- ERROR State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.ERROR\">\n\t\t\t<div class=\"state-icon error\">\n\t\t\t\t<i class=\"fa fa-exclamation-triangle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message error\">\n\t\t\t\tAn error occurred\n\t\t\t</p>\n\t\t\t<p class=\"error-details\" *ngIf=\"errorMessage\">\n\t\t\t\t{{ errorMessage }}\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn retry-btn\"\n\t\t\t\t(click)=\"retry()\">\n\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\tRetry\n\t\t\t</button>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer -->\n\t<div class=\"waiting-room-footer\">\n\t\t<button \n\t\t\ttype=\"button\" \n\t\t\tclass=\"btn cancel-btn\"\n\t\t\t(click)=\"cancel()\">\n\t\t\tCancel\n\t\t</button>\n\t</div>\n</div>\n", styles: [".tas-waiting-room{display:flex;flex-direction:column;min-height:420px;background:#ffffff;border-radius:5px;overflow:hidden}.waiting-room-header{position:relative;padding:32px 40px 24px;text-align:center;border-bottom:1px solid #e9ecef}.waiting-room-header .header-icon{width:72px;height:72px;margin:0 auto 16px;background:linear-gradient(135deg,#1da4b1 0%,#0077b3 100%);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #1da4b140}.waiting-room-header .header-icon i{font-size:28px;color:#fff}.waiting-room-header .header-title{margin:0 0 8px;font-size:20px;font-weight:700;line-height:28px;color:#212529}.waiting-room-header .header-subtitle{margin:0;font-size:14px;color:#6c757d;font-weight:400}.waiting-room-header .close-btn{position:absolute;top:16px;right:16px;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#6c757d;cursor:pointer;transition:all .2s ease;font-size:20px}.waiting-room-header .close-btn:hover{background:#f8f9fa;color:#212529}.waiting-room-content{flex:1;display:flex;align-items:center;justify-content:center;padding:32px 40px;background:#ffffff}.state-container{text-align:center;max-width:360px;width:100%}.state-icon{width:80px;height:80px;margin:0 auto 24px;border-radius:50%;display:flex;align-items:center;justify-content:center}.state-icon i{font-size:36px}.state-icon.idle{background:rgba(29,164,177,.1);border:2px dashed #1da4b1}.state-icon.idle i{color:#1da4b1}.state-icon.loading{background:rgba(29,164,177,.1);border:2px solid #1da4b1}.state-icon.ready{background:linear-gradient(135deg,#1da4b1 0%,#38b89a 100%);box-shadow:0 4px 16px #1da4b14d}.state-icon.ready i{color:#fff}.state-icon.error{background:rgba(238,49,107,.1);border:2px solid #ee316b}.state-icon.error i{color:#ee316b}.spinner{width:40px;height:40px;border:3px solid #e9ecef;border-top-color:#1da4b1;border-radius:50%;animation:spin 1s linear infinite}.state-message{font-size:16px;font-weight:600;margin:0 0 8px;color:#212529;line-height:24px}.state-message.success{color:#1da4b1}.state-message.error{color:#ee316b}.state-submessage{font-size:14px;color:#6c757d;margin:0 0 24px;font-weight:400}.error-details{font-size:13px;color:#ee316b;margin:0 0 24px;padding:12px 16px;background:rgba(238,49,107,.08);border-radius:8px;border:1px solid rgba(238,49,107,.2)}.progress-steps{display:flex;justify-content:center;gap:24px;margin:24px 0 32px}.step{display:flex;flex-direction:column;align-items:center;gap:8px}.step .step-indicator{width:32px;height:32px;border-radius:50%;background:#f8f9fa;border:2px solid #e9ecef;display:flex;align-items:center;justify-content:center;transition:all .3s ease}.step .step-indicator i{font-size:12px;color:#fff}.step .step-label{font-size:11px;color:#6c757d;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.step.active .step-indicator{background:rgba(29,164,177,.1);border-color:#1da4b1;animation:pulse-active 1.5s infinite}.step.active .step-label{color:#1da4b1;font-weight:600}.step.completed .step-indicator{background:#1da4b1;border-color:#1da4b1}.step.completed .step-label{color:#1da4b1;font-weight:600}.action-btn{padding:12px 32px;font-size:16px;font-weight:600;border-radius:4px;border:none;cursor:pointer;transition:all .2s ease;display:inline-flex;align-items:center;gap:10px}.action-btn i{font-size:16px}.action-btn.create-btn{background:#0077b3;color:#fff;box-shadow:0 2px 8px #0077b340}.action-btn.create-btn:hover{background:#005c8a;box-shadow:0 4px 12px #0077b359}.action-btn.create-btn:active{transform:translateY(1px)}.action-btn.join-btn{background:#1da4b1;color:#fff;box-shadow:0 2px 8px #1da4b140;animation:pulse-ready 2s infinite}.action-btn.join-btn:hover{background:#17848e;box-shadow:0 4px 12px #1da4b159}.action-btn.join-btn:active{transform:translateY(1px)}.action-btn.retry-btn{background:transparent;color:#6c757d;border:1px solid #e9ecef}.action-btn.retry-btn:hover{background:#f8f9fa;border-color:#6c757d;color:#212529}.waiting-room-footer{padding:16px 40px 24px;background:#ffffff;border-top:1px solid #e9ecef;display:flex;justify-content:center}.waiting-room-footer .cancel-btn{padding:10px 24px;font-size:14px;font-weight:600;border-radius:4px;background:transparent;color:#6c757d;border:none;cursor:pointer;transition:all .2s ease}.waiting-room-footer .cancel-btn:hover{background:#f8f9fa;color:#212529}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-active{0%,to{box-shadow:0 0 #1da4b166}50%{box-shadow:0 0 0 8px #1da4b100}}@keyframes pulse-ready{0%,to{box-shadow:0 2px 8px #1da4b140}50%{box-shadow:0 4px 16px #1da4b166}}@media (max-width: 576px){.tas-waiting-room{min-height:380px}.waiting-room-header{padding:24px 24px 20px}.waiting-room-header .header-icon{width:56px;height:56px}.waiting-room-header .header-icon i{font-size:22px}.waiting-room-header .header-title{font-size:18px}.waiting-room-content{padding:24px}.state-icon{width:64px;height:64px}.state-icon i{font-size:28px}.spinner{width:32px;height:32px}.progress-steps{gap:12px}.step .step-indicator{width:28px;height:28px}.step .step-label{font-size:9px}.action-btn{padding:10px 24px;font-size:14px}.waiting-room-footer{padding:16px 24px 20px}}\n"] }]
204
- }], ctorParameters: function () { return [{ type: i1.NgbActiveModal }, { type: i2.TasService }, { type: i1.NgbModal }]; }, propDecorators: { appointmentId: [{
241
+ args: [{ selector: 'tas-waiting-room', template: "<div class=\"tas-waiting-room\">\n <!-- Header -->\n <div class=\"waiting-room-header\">\n <h2 class=\"header-title\">Iniciar turno</h2>\n <button type=\"button\" class=\"close-btn\" (click)=\"cancel()\" aria-label=\"Close\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"waiting-room-content\">\n <!-- CHECKING_STATUS State -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.CHECKING_STATUS\">\n <div class=\"state-icon loading\">\n <div class=\"spinner\"></div>\n </div>\n <p class=\"state-message\">Verificando estado de la sesi\u00F3n...</p>\n </div>\n\n <!-- WAITING_FOR_OWNER State (Non-owner waiting) -->\n <div class=\"state-container waiting-for-owner\" *ngIf=\"state === WaitingRoomState.WAITING_FOR_OWNER\">\n <div class=\"state-icon loading\">\n <div class=\"spinner\"></div>\n </div>\n <p class=\"state-message waiting-title\">Medicina laboral te va a admitir en unos instantes...</p>\n <p class=\"state-submessage\">Por favor, permanec\u00E9 en esta pantalla hasta que inicie la consulta.</p>\n </div>\n\n <!-- READY State (Owner can join) -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY\">\n <div class=\"state-icon ready\">\n <i class=\"fa fa-check-circle\"></i>\n </div>\n <p class=\"state-message success\">\u00A1La sala est\u00E1 lista!</p>\n <p class=\"state-submessage\">Pod\u00E9s unirte a la videollamada cuando quieras</p>\n <button type=\"button\" class=\"btn action-btn join-btn\" (click)=\"joinSession()\">\n <i class=\"fa fa-sign-in\"></i>\n Unirse a la llamada\n </button>\n </div>\n\n <!-- GETTING_TOKEN State -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN\">\n <div class=\"state-icon loading\">\n <div class=\"spinner\"></div>\n </div>\n <p class=\"state-message\">Conectando...</p>\n </div>\n\n <!-- ERROR State -->\n <div class=\"state-container\" *ngIf=\"state === WaitingRoomState.ERROR\">\n <div class=\"state-icon error\">\n <i class=\"fa fa-exclamation-triangle\"></i>\n </div>\n <p class=\"state-message error\">Ocurri\u00F3 un error</p>\n <p class=\"error-details\" *ngIf=\"errorMessage\">\n {{ errorMessage }}\n </p>\n <button type=\"button\" class=\"btn action-btn retry-btn\" (click)=\"retry()\">\n <i class=\"fa fa-refresh\"></i>\n Reintentar\n </button>\n </div>\n </div>\n</div>\n", styles: [".tas-waiting-room{display:flex;flex-direction:column;min-height:420px;background:#ffffff;border-radius:5px;overflow:hidden}.waiting-room-header{position:relative;padding:20px 40px;border-bottom:1px solid #e9ecef;display:flex;align-items:center;justify-content:space-between}.waiting-room-header .header-title{margin:0;font-size:18px;font-weight:600;line-height:24px;color:#212529}.waiting-room-header .close-btn{width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#6c757d;cursor:pointer;transition:all .2s ease;font-size:20px;display:flex;align-items:center;justify-content:center}.waiting-room-header .close-btn:hover{background:#f8f9fa;color:#212529}.waiting-title{font-size:16px;font-weight:600;color:#212529;margin-bottom:8px}.waiting-room-content{flex:1;display:flex;align-items:center;justify-content:center;padding:32px 40px;background:#ffffff}.state-container{text-align:center;max-width:400px;width:100%}.mode-tabs{display:flex;justify-content:center;gap:8px;margin-bottom:24px;padding:4px;background:#f8f9fa;border-radius:8px}.mode-tab{flex:1;padding:10px 16px;font-size:13px;font-weight:600;border:none;border-radius:6px;background:transparent;color:#6c757d;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;justify-content:center;gap:8px}.mode-tab i{font-size:14px}.mode-tab:hover{color:#212529}.mode-tab.active{background:#ffffff;color:#1da4b1;box-shadow:0 2px 8px #00000014}.mode-content{animation:fadeIn .3s ease}.session-input-container{display:flex;flex-direction:column;gap:16px;margin-top:8px}.session-input{width:100%;padding:14px 16px;font-size:14px;border:2px solid #e9ecef;border-radius:8px;background:#ffffff;color:#212529;transition:all .2s ease;text-align:center;font-family:Monaco,Consolas,monospace;letter-spacing:.5px}.session-input::placeholder{color:#6c757d;font-family:inherit;letter-spacing:normal}.session-input:focus{outline:none;border-color:#1da4b1;box-shadow:0 0 0 3px #1da4b126}.session-input:hover:not(:focus){border-color:#6c757d}@keyframes fadeIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.state-icon{width:80px;height:80px;margin:0 auto 24px;border-radius:50%;display:flex;align-items:center;justify-content:center}.state-icon i{font-size:36px}.state-icon.idle{background:rgba(29,164,177,.1);border:2px dashed #1da4b1}.state-icon.idle i{color:#1da4b1}.state-icon.loading{background:rgba(29,164,177,.1);border:2px solid #1da4b1}.state-icon.ready{background:linear-gradient(135deg,#1da4b1 0%,#38b89a 100%);box-shadow:0 4px 16px #1da4b14d}.state-icon.ready i{color:#fff}.state-icon.error{background:rgba(238,49,107,.1);border:2px solid #ee316b}.state-icon.error i{color:#ee316b}.spinner{width:40px;height:40px;border:3px solid #e9ecef;border-top-color:#1da4b1;border-radius:50%;animation:spin 1s linear infinite}.state-message{font-size:16px;font-weight:600;margin:0 0 8px;color:#212529;line-height:24px}.state-message.success{color:#1da4b1}.state-message.error{color:#ee316b}.state-submessage{font-size:14px;color:#6c757d;margin:0 0 24px;font-weight:400}.error-details{font-size:13px;color:#ee316b;margin:0 0 24px;padding:12px 16px;background:rgba(238,49,107,.08);border-radius:8px;border:1px solid rgba(238,49,107,.2)}.progress-steps{display:flex;justify-content:center;gap:24px;margin:24px 0 32px}.step{display:flex;flex-direction:column;align-items:center;gap:8px}.step .step-indicator{width:32px;height:32px;border-radius:50%;background:#f8f9fa;border:2px solid #e9ecef;display:flex;align-items:center;justify-content:center;transition:all .3s ease}.step .step-indicator i{font-size:12px;color:#fff}.step .step-label{font-size:11px;color:#6c757d;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.step.active .step-indicator{background:rgba(29,164,177,.1);border-color:#1da4b1;animation:pulse-active 1.5s infinite}.step.active .step-label{color:#1da4b1;font-weight:600}.step.completed .step-indicator{background:#1da4b1;border-color:#1da4b1}.step.completed .step-label{color:#1da4b1;font-weight:600}.action-btn{padding:12px 32px;font-size:16px;font-weight:600;border-radius:4px;border:none;cursor:pointer;transition:all .2s ease;display:inline-flex;align-items:center;gap:10px}.action-btn i{font-size:16px}.action-btn.create-btn{background:#0077b3;color:#fff;box-shadow:0 2px 8px #0077b340}.action-btn.create-btn:hover{background:#005c8a;box-shadow:0 4px 12px #0077b359}.action-btn.create-btn:active{transform:translateY(1px)}.action-btn.join-btn{background:#1da4b1;color:#fff;box-shadow:0 2px 8px #1da4b140;animation:pulse-ready 2s infinite}.action-btn.join-btn:hover{background:#17848e;box-shadow:0 4px 12px #1da4b159}.action-btn.join-btn:active{transform:translateY(1px)}.action-btn.retry-btn{background:transparent;color:#6c757d;border:1px solid #e9ecef}.action-btn.retry-btn:hover{background:#f8f9fa;border-color:#6c757d;color:#212529}.waiting-room-footer{padding:16px 40px 24px;background:#ffffff;border-top:1px solid #e9ecef;display:flex;justify-content:center}.waiting-room-footer .cancel-btn{padding:10px 24px;font-size:14px;font-weight:600;border-radius:4px;background:transparent;color:#6c757d;border:none;cursor:pointer;transition:all .2s ease}.waiting-room-footer .cancel-btn:hover{background:#f8f9fa;color:#212529}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-active{0%,to{box-shadow:0 0 #1da4b166}50%{box-shadow:0 0 0 8px #1da4b100}}@keyframes pulse-ready{0%,to{box-shadow:0 2px 8px #1da4b140}50%{box-shadow:0 4px 16px #1da4b166}}@media (max-width: 576px){.tas-waiting-room{min-height:380px}.waiting-room-header{padding:24px 24px 20px}.waiting-room-header .header-icon{width:56px;height:56px}.waiting-room-header .header-icon i{font-size:22px}.waiting-room-header .header-title{font-size:18px}.waiting-room-content{padding:24px}.state-icon{width:64px;height:64px}.state-icon i{font-size:28px}.spinner{width:32px;height:32px}.progress-steps{gap:12px}.step .step-indicator{width:28px;height:28px}.step .step-label{font-size:9px}.action-btn{padding:10px 24px;font-size:14px}.waiting-room-footer{padding:16px 24px 20px}}\n"] }]
242
+ }], ctorParameters: function () { return [{ type: i1.NgbActiveModal }, { type: i2.TasService }, { type: i1.NgbModal }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { roomType: [{
205
243
  type: Input
206
- }], product: [{
244
+ }], entityId: [{
207
245
  type: Input
208
- }], tenantId: [{
246
+ }], tenant: [{
209
247
  type: Input
210
- }], currentUser: [{
211
- type: Input
212
- }], ownerUserIds: [{
213
- type: Input
214
- }], regularUserIds: [{
248
+ }], businessRole: [{
215
249
  type: Input
216
- }], moderatorUserIds: [{
217
- type: Input
218
- }], existingSessionId: [{
250
+ }], currentUser: [{
219
251
  type: Input
220
252
  }] } });
221
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzLXdhaXRpbmctcm9vbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YXMtdWVsbC1zZGsvc3JjL2xpYi9jb21wb25lbnRzL3Rhcy13YWl0aW5nLXJvb20vdGFzLXdhaXRpbmctcm9vbS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YXMtdWVsbC1zZGsvc3JjL2xpYi9jb21wb25lbnRzL3Rhcy13YWl0aW5nLXJvb20vdGFzLXdhaXRpbmctcm9vbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFxQixLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHcEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUlOLFdBQVcsRUFDWCxjQUFjLEVBQ2QsV0FBVyxFQUNYLFFBQVEsRUFDUixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7OztBQUVqRixNQUFNLENBQU4sSUFBWSxnQkFNWDtBQU5ELFdBQVksZ0JBQWdCO0lBQzNCLGlDQUFhLENBQUE7SUFDYixtREFBK0IsQ0FBQTtJQUMvQixtREFBK0IsQ0FBQTtJQUMvQixtQ0FBZSxDQUFBO0lBQ2YsbUNBQWUsQ0FBQTtBQUNoQixDQUFDLEVBTlcsZ0JBQWdCLEtBQWhCLGdCQUFnQixRQU0zQjtBQU9ELE1BQU0sT0FBTyx1QkFBdUI7SUE0Qm5DLFlBQ1EsV0FBMkIsRUFDMUIsVUFBc0IsRUFDdEIsWUFBc0I7UUFGdkIsZ0JBQVcsR0FBWCxXQUFXLENBQWdCO1FBQzFCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsaUJBQVksR0FBWixZQUFZLENBQVU7UUE5Qi9CLDRCQUE0QjtRQUNuQixrQkFBYSxHQUFXLENBQUMsQ0FBQztRQUMxQixZQUFPLEdBQVcsTUFBTSxDQUFDO1FBQ3pCLGFBQVEsR0FBVyxFQUFFLENBQUM7UUFHdEIsbUJBQWMsR0FBYSxFQUFFLENBQUM7UUFDOUIscUJBQWdCLEdBQWEsRUFBRSxDQUFDO1FBRXpDLHNGQUFzRjtRQUM3RSxzQkFBaUIsR0FBVyxFQUFFLENBQUM7UUFFeEMsa0JBQWtCO1FBQ1gsVUFBSyxHQUFxQixnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7UUFDaEQscUJBQWdCLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQywwQkFBMEI7UUFDL0QsaUJBQVksR0FBVyxFQUFFLENBQUM7UUFFakMsK0RBQStEO1FBQ3hELHVCQUFrQixHQUFZLEtBQUssQ0FBQztRQUUzQyxlQUFlO1FBQ1AsY0FBUyxHQUFXLEVBQUUsQ0FBQztRQUN2QixVQUFLLEdBQVcsRUFBRSxDQUFDO1FBQ25CLFVBQUssR0FBcUIsRUFBRSxDQUFDO1FBQzdCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNuQyxzQkFBaUIsR0FBdUIsSUFBSSxDQUFDO0lBTWxELENBQUM7SUFFSixRQUFRO1FBQ1AsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBRWpDLHVDQUF1QztRQUN2QyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ25FLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7WUFDL0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7U0FDeEM7SUFDRixDQUFDO0lBRUQsV0FBVztRQUNWLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsVUFBVTtRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUU7WUFDOUMsSUFBSSxDQUFDLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUM7WUFDcEMsSUFBSSxDQUFDLFlBQVksR0FBRyw2Q0FBNkMsQ0FBQztZQUNsRSxPQUFPO1NBQ1A7UUFFRCxJQUFJLENBQUMsS0FBSyxHQUFHLGdCQUFnQixDQUFDLGFBQWEsQ0FBQztRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUV2QixNQUFNLElBQUksR0FBc0I7WUFDL0IsUUFBUSxFQUFFLFdBQVcsQ0FBQyxHQUFHO1lBQ3pCLElBQUksRUFBRSxjQUFjLENBQUMsV0FBVztZQUNoQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDckIsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO1lBQ2pDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87U0FDckIsQ0FBQztRQUVGLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUNyQixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQ3BDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUNwQixJQUFJLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO1lBQzVDLElBQUksQ0FBQyxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsYUFBYSxDQUFDO1lBRTVDLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7Z0JBQ3BDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDekIsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSTtnQkFDM0IsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUTtnQkFDbkMsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSTthQUM3QixDQUFDLENBQUM7UUFDSixDQUFDLENBQUMsQ0FDRixDQUFDLFNBQVMsQ0FBQztZQUNYLElBQUksRUFBRSxDQUFDLGFBQWEsRUFBRSxFQUFFO2dCQUN2QixJQUFJLENBQUMsS0FBSyxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO2dCQUN6QyxJQUFJLENBQUMsS0FBSyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQztZQUNyQyxDQUFDO1lBQ0QsS0FBSyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQ2QsT0FBTyxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDNUQsSUFBSSxDQUFDLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQUcsd0NBQXdDLENBQUM7WUFDOUQsQ0FBQztTQUNELENBQUMsQ0FDRixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsMEJBQTBCO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUU7WUFDL0MsSUFBSSxDQUFDLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUM7WUFDcEMsSUFBSSxDQUFDLFlBQVksR0FBRyxpQ0FBaUMsQ0FBQztZQUN0RCxPQUFPO1NBQ1A7UUFFRCxJQUFJLENBQUMsS0FBSyxHQUFHLGdCQUFnQixDQUFDLGFBQWEsQ0FBQztRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUV2QixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FDckIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7WUFDN0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3pCLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUk7WUFDM0IsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUTtZQUNuQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJO1NBQzdCLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDWixJQUFJLEVBQUUsQ0FBQyxhQUFhLEVBQUUsRUFBRTtnQkFDdkIsSUFBSSxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztnQkFDekMsSUFBSSxDQUFDLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUM7WUFDckMsQ0FBQztZQUNELEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNkLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDO2dCQUNwQyxJQUFJLENBQUMsWUFBWSxHQUFHLGdEQUFnRCxDQUFDO1lBQ3RFLENBQUM7U0FDRCxDQUFDLENBQ0YsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVc7UUFDVixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyx1Q0FBdUMsQ0FBQztZQUM1RCxPQUFPO1NBQ1A7UUFFRCx5Q0FBeUM7UUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTTtRQUNMLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUs7UUFDSixJQUFJLENBQUMsS0FBSyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQztRQUNuQyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUVoQix3REFBd0Q7UUFDeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztTQUNwQjtJQUNGLENBQUM7SUFFRCxrQkFBa0I7SUFDVixlQUFlO1FBQ3RCLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBRWhCLHdCQUF3QjtRQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUM5QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFFSCw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUNsQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3JFLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVPLHlCQUF5QjtRQUNoQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FDckIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzFDLHdEQUF3RDtZQUN4RCxJQUFJLElBQUksS0FBSyxRQUFRLENBQUMsVUFBVTtnQkFDL0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUU7Z0JBQzlCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO2dCQUN6QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQztnQkFDNUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7Z0JBQ3BDLElBQUksU0FBUyxJQUFJLEtBQUssRUFBRTtvQkFDdkIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUM5QjthQUNEO1FBQ0YsQ0FBQyxDQUFDLENBQ0YsQ0FBQztJQUNILENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxxQkFBOEIsS0FBSztRQUM3RCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUU7WUFDdEUsSUFBSSxFQUFFLElBQUk7WUFDVixXQUFXLEVBQUUsaUJBQWlCO1lBQzlCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLFFBQVEsRUFBRSxLQUFLO1NBQ2YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQztRQUNuRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBRXZELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDO1FBQzVELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztRQUVqRixJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDakMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDeEMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FDeEMsQ0FBQztJQUNILENBQUM7O29IQTlOVyx1QkFBdUI7d0dBQXZCLHVCQUF1Qix3VEM3QnBDLCtyT0EwTkE7MkZEN0xhLHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDQyxrQkFBa0I7cUpBTW5CLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUdHLGlCQUFpQjtzQkFBekIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBPbkRlc3Ryb3ksIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ2JBY3RpdmVNb2RhbCwgTmdiTW9kYWwsIE5nYk1vZGFsUmVmIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xuaW1wb3J0IHsgVGFzU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3Rhcy5zZXJ2aWNlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtcblx0Q3JlYXRlUm9vbVJlcXVlc3QsXG5cdENyZWF0ZVJvb21Vc2VyLFxuXHRUYXNDdXJyZW50VXNlcixcblx0VGFzUm9vbVR5cGUsXG5cdFRhc1Nlc3Npb25UeXBlLFxuXHRUYXNVc2VyUm9sZSxcblx0Vmlld01vZGVcbn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy90YXMuaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBUYXNWaWRlb2NhbGxDb21wb25lbnQgfSBmcm9tICcuLi90YXMtdmlkZW9jYWxsL3Rhcy12aWRlb2NhbGwuY29tcG9uZW50JztcblxuZXhwb3J0IGVudW0gV2FpdGluZ1Jvb21TdGF0ZSB7XG5cdElETEUgPSAnSURMRScsXG5cdENSRUFUSU5HX1JPT00gPSAnQ1JFQVRJTkdfUk9PTScsXG5cdEdFVFRJTkdfVE9LRU4gPSAnR0VUVElOR19UT0tFTicsXG5cdFJFQURZID0gJ1JFQURZJyxcblx0RVJST1IgPSAnRVJST1InXG59XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ3Rhcy13YWl0aW5nLXJvb20nLFxuXHR0ZW1wbGF0ZVVybDogJy4vdGFzLXdhaXRpbmctcm9vbS5jb21wb25lbnQuaHRtbCcsXG5cdHN0eWxlVXJsczogWycuL3Rhcy13YWl0aW5nLXJvb20uY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBUYXNXYWl0aW5nUm9vbUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblx0Ly8gUm9vbSBjb25maWd1cmF0aW9uIGlucHV0c1xuXHRASW5wdXQoKSBhcHBvaW50bWVudElkOiBudW1iZXIgPSAxO1xuXHRASW5wdXQoKSBwcm9kdWN0OiBzdHJpbmcgPSAndWVsbCc7XG5cdEBJbnB1dCgpIHRlbmFudElkOiBzdHJpbmcgPSAnJztcblx0QElucHV0KCkgY3VycmVudFVzZXIhOiBUYXNDdXJyZW50VXNlcjtcblx0QElucHV0KCkgb3duZXJVc2VySWRzITogbnVtYmVyW107XG5cdEBJbnB1dCgpIHJlZ3VsYXJVc2VySWRzOiBudW1iZXJbXSA9IFtdO1xuXHRASW5wdXQoKSBtb2RlcmF0b3JVc2VySWRzOiBudW1iZXJbXSA9IFtdO1xuXHRcblx0LyoqIE9wdGlvbmFsOiBJZiBwcm92aWRlZCwgc2tpcHMgcm9vbSBjcmVhdGlvbiBhbmQgZ29lcyBkaXJlY3RseSB0byBnZXR0aW5nIGEgdG9rZW4gKi9cblx0QElucHV0KCkgZXhpc3RpbmdTZXNzaW9uSWQ6IHN0cmluZyA9ICcnO1xuXG5cdC8vIENvbXBvbmVudCBzdGF0ZVxuXHRwdWJsaWMgc3RhdGU6IFdhaXRpbmdSb29tU3RhdGUgPSBXYWl0aW5nUm9vbVN0YXRlLklETEU7XG5cdHB1YmxpYyBXYWl0aW5nUm9vbVN0YXRlID0gV2FpdGluZ1Jvb21TdGF0ZTsgLy8gRXhwb3NlIGVudW0gdG8gdGVtcGxhdGVcblx0cHVibGljIGVycm9yTWVzc2FnZTogc3RyaW5nID0gJyc7XG5cdFxuXHQvKiogV2hldGhlciB3ZSBoYXZlIGFuIGV4aXN0aW5nIHNlc3Npb24gKHNraXAgcm9vbSBjcmVhdGlvbikgKi9cblx0cHVibGljIGhhc0V4aXN0aW5nU2Vzc2lvbjogYm9vbGVhbiA9IGZhbHNlO1xuXG5cdC8vIFNlc3Npb24gZGF0YVxuXHRwcml2YXRlIHNlc3Npb25JZDogc3RyaW5nID0gJyc7XG5cdHByaXZhdGUgdG9rZW46IHN0cmluZyA9ICcnO1xuXHRwcml2YXRlIHVzZXJzOiBDcmVhdGVSb29tVXNlcltdID0gW107XG5cdHByaXZhdGUgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblx0cHJpdmF0ZSB2aWRlb0NhbGxNb2RhbFJlZjogTmdiTW9kYWxSZWYgfCBudWxsID0gbnVsbDtcblxuXHRjb25zdHJ1Y3Rvcihcblx0XHRwdWJsaWMgYWN0aXZlTW9kYWw6IE5nYkFjdGl2ZU1vZGFsLFxuXHRcdHByaXZhdGUgdGFzU2VydmljZTogVGFzU2VydmljZSxcblx0XHRwcml2YXRlIG1vZGFsU2VydmljZTogTmdiTW9kYWxcblx0KSB7fVxuXG5cdG5nT25Jbml0KCk6IHZvaWQge1xuXHRcdHRoaXMuYnVpbGRVc2Vyc0FycmF5KCk7XG5cdFx0dGhpcy5zZXR1cFZpZXdNb2RlU3Vic2NyaXB0aW9uKCk7XG5cdFx0XG5cdFx0Ly8gQ2hlY2sgaWYgd2UgaGF2ZSBhbiBleGlzdGluZyBzZXNzaW9uXG5cdFx0aWYgKHRoaXMuZXhpc3RpbmdTZXNzaW9uSWQgJiYgdGhpcy5leGlzdGluZ1Nlc3Npb25JZC50cmltKCkgIT09ICcnKSB7XG5cdFx0XHR0aGlzLmhhc0V4aXN0aW5nU2Vzc2lvbiA9IHRydWU7XG5cdFx0XHR0aGlzLnNlc3Npb25JZCA9IHRoaXMuZXhpc3RpbmdTZXNzaW9uSWQ7XG5cdFx0fVxuXHR9XG5cblx0bmdPbkRlc3Ryb3koKTogdm9pZCB7XG5cdFx0dGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyB0aGUgcm9vbSBhbmQgZmV0Y2hlcyB0aGUgdG9rZW4gKG5ldyBzZXNzaW9uIGZsb3cpXG5cdCAqL1xuXHRjcmVhdGVSb29tKCk6IHZvaWQge1xuXHRcdGlmICghdGhpcy50ZW5hbnRJZCB8fCAhdGhpcy5jdXJyZW50VXNlcj8ubmFtZSkge1xuXHRcdFx0dGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuRVJST1I7XG5cdFx0XHR0aGlzLmVycm9yTWVzc2FnZSA9ICdNaXNzaW5nIGNvbmZpZ3VyYXRpb24gZGF0YSAodGVuYW50IG9yIHVzZXIpJztcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0aGlzLnN0YXRlID0gV2FpdGluZ1Jvb21TdGF0ZS5DUkVBVElOR19ST09NO1xuXHRcdHRoaXMuZXJyb3JNZXNzYWdlID0gJyc7XG5cblx0XHRjb25zdCBib2R5OiBDcmVhdGVSb29tUmVxdWVzdCA9IHtcblx0XHRcdHJvb21UeXBlOiBUYXNSb29tVHlwZS5UQVMsXG5cdFx0XHR0eXBlOiBUYXNTZXNzaW9uVHlwZS5TUE9OVEFORU9VUyxcblx0XHRcdHRlbmFudDogdGhpcy50ZW5hbnRJZCxcblx0XHRcdGFwcG9pbnRtZW50SWQ6IHRoaXMuYXBwb2ludG1lbnRJZCxcblx0XHRcdHVzZXJzOiB0aGlzLnVzZXJzLFxuXHRcdFx0cHJvZHVjdDogdGhpcy5wcm9kdWN0XG5cdFx0fTtcblxuXHRcdHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG5cdFx0XHR0aGlzLnRhc1NlcnZpY2UuY3JlYXRlUm9vbShib2R5KS5waXBlKFxuXHRcdFx0XHRzd2l0Y2hNYXAocmVzcG9uc2UgPT4ge1xuXHRcdFx0XHRcdHRoaXMuc2Vzc2lvbklkID0gcmVzcG9uc2UuY29udGVudC5zZXNzaW9uSWQ7XG5cdFx0XHRcdFx0dGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuR0VUVElOR19UT0tFTjtcblxuXHRcdFx0XHRcdHJldHVybiB0aGlzLnRhc1NlcnZpY2UuZ2VuZXJhdGVUb2tlbih7XG5cdFx0XHRcdFx0XHRzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuXHRcdFx0XHRcdFx0bmFtZTogdGhpcy5jdXJyZW50VXNlci5uYW1lLFxuXHRcdFx0XHRcdFx0bGFzdG5hbWU6IHRoaXMuY3VycmVudFVzZXIubGFzdG5hbWUsXG5cdFx0XHRcdFx0XHRyb2xlVkM6IHRoaXMuY3VycmVudFVzZXIucm9sZVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9KVxuXHRcdFx0KS5zdWJzY3JpYmUoe1xuXHRcdFx0XHRuZXh0OiAodG9rZW5SZXNwb25zZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMudG9rZW4gPSB0b2tlblJlc3BvbnNlLmNvbnRlbnQudG9rZW47XG5cdFx0XHRcdFx0dGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuUkVBRFk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdGVycm9yOiAoZXJyKSA9PiB7XG5cdFx0XHRcdFx0Y29uc29sZS5lcnJvcignRXJyb3IgY3JlYXRpbmcgcm9vbSBvciBnZXR0aW5nIHRva2VuOicsIGVycik7XG5cdFx0XHRcdFx0dGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuRVJST1I7XG5cdFx0XHRcdFx0dGhpcy5lcnJvck1lc3NhZ2UgPSAnRXJyb3IgY3JlYXRpbmcgcm9vbS4gUGxlYXNlIHRyeSBhZ2Fpbi4nO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBhIHRva2VuIGZvciBhbiBleGlzdGluZyBzZXNzaW9uIChleGlzdGluZyBzZXNzaW9uIGZsb3cpXG5cdCAqL1xuXHRnZXRUb2tlbkZvckV4aXN0aW5nU2Vzc2lvbigpOiB2b2lkIHtcblx0XHRpZiAoIXRoaXMuc2Vzc2lvbklkIHx8ICF0aGlzLmN1cnJlbnRVc2VyPy5uYW1lKSB7XG5cdFx0XHR0aGlzLnN0YXRlID0gV2FpdGluZ1Jvb21TdGF0ZS5FUlJPUjtcblx0XHRcdHRoaXMuZXJyb3JNZXNzYWdlID0gJ01pc3Npbmcgc2Vzc2lvbiBJRCBvciB1c2VyIGRhdGEnO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMuc3RhdGUgPSBXYWl0aW5nUm9vbVN0YXRlLkdFVFRJTkdfVE9LRU47XG5cdFx0dGhpcy5lcnJvck1lc3NhZ2UgPSAnJztcblxuXHRcdHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG5cdFx0XHR0aGlzLnRhc1NlcnZpY2UuZ2VuZXJhdGVUb2tlbih7XG5cdFx0XHRcdHNlc3Npb25JZDogdGhpcy5zZXNzaW9uSWQsXG5cdFx0XHRcdG5hbWU6IHRoaXMuY3VycmVudFVzZXIubmFtZSxcblx0XHRcdFx0bGFzdG5hbWU6IHRoaXMuY3VycmVudFVzZXIubGFzdG5hbWUsXG5cdFx0XHRcdHJvbGVWQzogdGhpcy5jdXJyZW50VXNlci5yb2xlXG5cdFx0XHR9KS5zdWJzY3JpYmUoe1xuXHRcdFx0XHRuZXh0OiAodG9rZW5SZXNwb25zZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMudG9rZW4gPSB0b2tlblJlc3BvbnNlLmNvbnRlbnQudG9rZW47XG5cdFx0XHRcdFx0dGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuUkVBRFk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdGVycm9yOiAoZXJyKSA9PiB7XG5cdFx0XHRcdFx0Y29uc29sZS5lcnJvcignRXJyb3IgZ2V0dGluZyB0b2tlbjonLCBlcnIpO1xuXHRcdFx0XHRcdHRoaXMuc3RhdGUgPSBXYWl0aW5nUm9vbVN0YXRlLkVSUk9SO1xuXHRcdFx0XHRcdHRoaXMuZXJyb3JNZXNzYWdlID0gJ0Vycm9yIGdldHRpbmcgc2Vzc2lvbiB0b2tlbi4gUGxlYXNlIHRyeSBhZ2Fpbi4nO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogSm9pbnMgdGhlIHZpZGVvIGNhbGwgc2Vzc2lvblxuXHQgKi9cblx0am9pblNlc3Npb24oKTogdm9pZCB7XG5cdFx0aWYgKCF0aGlzLnNlc3Npb25JZCB8fCAhdGhpcy50b2tlbikge1xuXHRcdFx0dGhpcy5lcnJvck1lc3NhZ2UgPSAnQ2Fubm90IGpvaW4gc2Vzc2lvbi4gSW5jb21wbGV0ZSBkYXRhLic7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gQ2xvc2Ugd2FpdGluZyByb29tIGFuZCBvcGVuIHZpZGVvIGNhbGxcblx0XHR0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCdqb2luaW5nJyk7XG5cdFx0dGhpcy5vcGVuVmlkZW9DYWxsTW9kYWwoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbG9zZXMgdGhlIHdhaXRpbmcgcm9vbVxuXHQgKi9cblx0Y2FuY2VsKCk6IHZvaWQge1xuXHRcdHRoaXMuYWN0aXZlTW9kYWwuZGlzbWlzcygnY2FuY2VsJyk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cnkgYWZ0ZXIgYW4gZXJyb3Jcblx0ICovXG5cdHJldHJ5KCk6IHZvaWQge1xuXHRcdHRoaXMuc3RhdGUgPSBXYWl0aW5nUm9vbVN0YXRlLklETEU7XG5cdFx0dGhpcy5lcnJvck1lc3NhZ2UgPSAnJztcblx0XHR0aGlzLnRva2VuID0gJyc7XG5cdFx0XG5cdFx0Ly8gT25seSByZXNldCBzZXNzaW9uSWQgaWYgd2UgZG9uJ3QgaGF2ZSBhbiBleGlzdGluZyBvbmVcblx0XHRpZiAoIXRoaXMuaGFzRXhpc3RpbmdTZXNzaW9uKSB7XG5cdFx0XHR0aGlzLnNlc3Npb25JZCA9ICcnO1xuXHRcdH1cblx0fVxuXG5cdC8vIFByaXZhdGUgTWV0aG9kc1xuXHRwcml2YXRlIGJ1aWxkVXNlcnNBcnJheSgpOiB2b2lkIHtcblx0XHR0aGlzLnVzZXJzID0gW107XG5cblx0XHQvLyBBZGQgb3duZXJzIGZyb20gaW5wdXRcblx0XHR0aGlzLm93bmVyVXNlcklkcy5mb3JFYWNoKGlkID0+IHtcblx0XHRcdHRoaXMudXNlcnMucHVzaCh7IHVzZXJFeHRlcm5hbElkOiBpZCwgcm9sOiBUYXNVc2VyUm9sZS5PV05FUiB9KTtcblx0XHR9KTtcblxuXHRcdC8vIEFkZCByZWd1bGFyIHVzZXJzIGZyb20gaW5wdXRcblx0XHR0aGlzLnJlZ3VsYXJVc2VySWRzLmZvckVhY2goaWQgPT4ge1xuXHRcdFx0dGhpcy51c2Vycy5wdXNoKHsgdXNlckV4dGVybmFsSWQ6IGlkLCByb2w6IFRhc1VzZXJSb2xlLlVTRVIgfSk7XG5cdFx0fSk7XG5cblx0XHQvLyBBZGQgbW9kZXJhdG9ycyBmcm9tIGlucHV0XG5cdFx0dGhpcy5tb2RlcmF0b3JVc2VySWRzLmZvckVhY2goaWQgPT4ge1xuXHRcdFx0dGhpcy51c2Vycy5wdXNoKHsgdXNlckV4dGVybmFsSWQ6IGlkLCByb2w6IFRhc1VzZXJSb2xlLk1PREVSQVRPUiB9KTtcblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgc2V0dXBWaWV3TW9kZVN1YnNjcmlwdGlvbigpOiB2b2lkIHtcblx0XHR0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuXHRcdFx0dGhpcy50YXNTZXJ2aWNlLnZpZXdNb2RlJC5zdWJzY3JpYmUobW9kZSA9PiB7XG5cdFx0XHRcdC8vIFJlLW9wZW4gdmlkZW8gY2FsbCBtb2RhbCB3aGVuIHJldHVybmluZyBmcm9tIFBpUCBtb2RlXG5cdFx0XHRcdGlmIChtb2RlID09PSBWaWV3TW9kZS5GVUxMU0NSRUVOICYmIFxuXHRcdFx0XHRcdHRoaXMudGFzU2VydmljZS5pc0NhbGxBY3RpdmUoKSAmJiBcblx0XHRcdFx0XHQhdGhpcy52aWRlb0NhbGxNb2RhbFJlZikge1xuXHRcdFx0XHRcdGNvbnN0IHNlc3Npb25JZCA9IHRoaXMudGFzU2VydmljZS5zZXNzaW9uSWQ7XG5cdFx0XHRcdFx0Y29uc3QgdG9rZW4gPSB0aGlzLnRhc1NlcnZpY2UudG9rZW47XG5cdFx0XHRcdFx0aWYgKHNlc3Npb25JZCAmJiB0b2tlbikge1xuXHRcdFx0XHRcdFx0dGhpcy5vcGVuVmlkZW9DYWxsTW9kYWwodHJ1ZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdCk7XG5cdH1cblxuXHRwcml2YXRlIG9wZW5WaWRlb0NhbGxNb2RhbChpc1JldHVybmluZ0Zyb21QaXA6IGJvb2xlYW4gPSBmYWxzZSk6IHZvaWQge1xuXHRcdHRoaXMudmlkZW9DYWxsTW9kYWxSZWYgPSB0aGlzLm1vZGFsU2VydmljZS5vcGVuKFRhc1ZpZGVvY2FsbENvbXBvbmVudCwge1xuXHRcdFx0c2l6ZTogJ3hsJyxcblx0XHRcdHdpbmRvd0NsYXNzOiAndGFzLXZpZGVvLW1vZGFsJyxcblx0XHRcdGJhY2tkcm9wOiAnc3RhdGljJyxcblx0XHRcdGtleWJvYXJkOiBmYWxzZVxuXHRcdH0pO1xuXG5cdFx0Y29uc3Qgc2Vzc2lvbklkVG9Vc2UgPSB0aGlzLnNlc3Npb25JZCB8fCB0aGlzLnRhc1NlcnZpY2Uuc2Vzc2lvbklkO1xuXHRcdGNvbnN0IHRva2VuVG9Vc2UgPSB0aGlzLnRva2VuIHx8IHRoaXMudGFzU2VydmljZS50b2tlbjtcblxuXHRcdHRoaXMudmlkZW9DYWxsTW9kYWxSZWYuY29tcG9uZW50SW5zdGFuY2Uuc2Vzc2lvbklkID0gc2Vzc2lvbklkVG9Vc2U7XG5cdFx0dGhpcy52aWRlb0NhbGxNb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS50b2tlbiA9IHRva2VuVG9Vc2U7XG5cdFx0dGhpcy52aWRlb0NhbGxNb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS5pc1JldHVybmluZ0Zyb21QaXAgPSBpc1JldHVybmluZ0Zyb21QaXA7XG5cblx0XHR0aGlzLnZpZGVvQ2FsbE1vZGFsUmVmLnJlc3VsdC50aGVuKFxuXHRcdFx0KCkgPT4geyB0aGlzLnZpZGVvQ2FsbE1vZGFsUmVmID0gbnVsbDsgfSxcblx0XHRcdCgpID0+IHsgdGhpcy52aWRlb0NhbGxNb2RhbFJlZiA9IG51bGw7IH1cblx0XHQpO1xuXHR9XG59XG4iLCI8ZGl2IGNsYXNzPVwidGFzLXdhaXRpbmctcm9vbVwiPlxuXHQ8IS0tIEhlYWRlciAtLT5cblx0PGRpdiBjbGFzcz1cIndhaXRpbmctcm9vbS1oZWFkZXJcIj5cblx0XHQ8ZGl2IGNsYXNzPVwiaGVhZGVyLWljb25cIj5cblx0XHRcdDxpIGNsYXNzPVwiZmEgZmEtdmlkZW8tY2FtZXJhXCI+PC9pPlxuXHRcdDwvZGl2PlxuXHRcdDxoMiBjbGFzcz1cImhlYWRlci10aXRsZVwiPldhaXRpbmcgUm9vbTwvaDI+XG5cdFx0PHAgY2xhc3M9XCJoZWFkZXItc3VidGl0bGVcIj5QcmVwYXJlIGZvciB5b3VyIHZpZGVvIGNhbGw8L3A+XG5cdFx0PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZS1idG5cIiAoY2xpY2spPVwiY2FuY2VsKClcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj5cblx0XHRcdDxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZ0aW1lczs8L3NwYW4+XG5cdFx0PC9idXR0b24+XG5cdDwvZGl2PlxuXG5cdDwhLS0gQ29udGVudCAtLT5cblx0PGRpdiBjbGFzcz1cIndhaXRpbmctcm9vbS1jb250ZW50XCI+XG5cdFx0PCEtLSBJRExFIFN0YXRlIC0gTmV3IFNlc3Npb24gLS0+XG5cdFx0PGRpdiBjbGFzcz1cInN0YXRlLWNvbnRhaW5lclwiICpuZ0lmPVwic3RhdGUgPT09IFdhaXRpbmdSb29tU3RhdGUuSURMRSAmJiAhaGFzRXhpc3RpbmdTZXNzaW9uXCI+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiBpZGxlXCI+XG5cdFx0XHRcdDxpIGNsYXNzPVwiZmEgZmEtcGx1cy1jaXJjbGVcIj48L2k+XG5cdFx0XHQ8L2Rpdj5cblx0XHRcdDxwIGNsYXNzPVwic3RhdGUtbWVzc2FnZVwiPlxuXHRcdFx0XHRDcmVhdGUgYSBuZXcgdmlkZW8gY2FsbCByb29tXG5cdFx0XHQ8L3A+XG5cdFx0XHQ8cCBjbGFzcz1cInN0YXRlLXN1Ym1lc3NhZ2VcIj5cblx0XHRcdFx0UHJlc3MgdGhlIGJ1dHRvbiB0byBiZWdpblxuXHRcdFx0PC9wPlxuXHRcdFx0PGJ1dHRvbiBcblx0XHRcdFx0dHlwZT1cImJ1dHRvblwiIFxuXHRcdFx0XHRjbGFzcz1cImJ0biBhY3Rpb24tYnRuIGNyZWF0ZS1idG5cIlxuXHRcdFx0XHQoY2xpY2spPVwiY3JlYXRlUm9vbSgpXCI+XG5cdFx0XHRcdDxpIGNsYXNzPVwiZmEgZmEtcGx1c1wiPjwvaT5cblx0XHRcdFx0Q3JlYXRlIFJvb21cblx0XHRcdDwvYnV0dG9uPlxuXHRcdDwvZGl2PlxuXG5cdFx0PCEtLSBJRExFIFN0YXRlIC0gRXhpc3RpbmcgU2Vzc2lvbiAtLT5cblx0XHQ8ZGl2IGNsYXNzPVwic3RhdGUtY29udGFpbmVyXCIgKm5nSWY9XCJzdGF0ZSA9PT0gV2FpdGluZ1Jvb21TdGF0ZS5JRExFICYmIGhhc0V4aXN0aW5nU2Vzc2lvblwiPlxuXHRcdFx0PGRpdiBjbGFzcz1cInN0YXRlLWljb24gaWRsZVwiPlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhIGZhLXNpZ24taW5cIj48L2k+XG5cdFx0XHQ8L2Rpdj5cblx0XHRcdDxwIGNsYXNzPVwic3RhdGUtbWVzc2FnZVwiPlxuXHRcdFx0XHRKb2luIGV4aXN0aW5nIHZpZGVvIGNhbGwgcm9vbVxuXHRcdFx0PC9wPlxuXHRcdFx0PHAgY2xhc3M9XCJzdGF0ZS1zdWJtZXNzYWdlXCI+XG5cdFx0XHRcdFByZXNzIHRoZSBidXR0b24gdG8gZ2V0IGFjY2Vzc1xuXHRcdFx0PC9wPlxuXHRcdFx0PGJ1dHRvbiBcblx0XHRcdFx0dHlwZT1cImJ1dHRvblwiIFxuXHRcdFx0XHRjbGFzcz1cImJ0biBhY3Rpb24tYnRuIGNyZWF0ZS1idG5cIlxuXHRcdFx0XHQoY2xpY2spPVwiZ2V0VG9rZW5Gb3JFeGlzdGluZ1Nlc3Npb24oKVwiPlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhIGZhLXNpZ24taW5cIj48L2k+XG5cdFx0XHRcdEpvaW4gUm9vbVxuXHRcdFx0PC9idXR0b24+XG5cdFx0PC9kaXY+XG5cblx0XHQ8IS0tIENSRUFUSU5HX1JPT00gU3RhdGUgKG9ubHkgZm9yIG5ldyBzZXNzaW9ucykgLS0+XG5cdFx0PGRpdiBjbGFzcz1cInN0YXRlLWNvbnRhaW5lclwiICpuZ0lmPVwic3RhdGUgPT09IFdhaXRpbmdSb29tU3RhdGUuQ1JFQVRJTkdfUk9PTVwiPlxuXHRcdFx0PGRpdiBjbGFzcz1cInN0YXRlLWljb24gbG9hZGluZ1wiPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwic3Bpbm5lclwiPjwvZGl2PlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8cCBjbGFzcz1cInN0YXRlLW1lc3NhZ2VcIj5cblx0XHRcdFx0Q3JlYXRpbmcgdmlkZW8gY2FsbCByb29tLi4uXG5cdFx0XHQ8L3A+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwicHJvZ3Jlc3Mtc3RlcHNcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInN0ZXAgYWN0aXZlXCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWluZGljYXRvclwiPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtbGFiZWxcIj5DcmVhdGluZzwvc3Bhbj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJzdGVwXCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWluZGljYXRvclwiPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtbGFiZWxcIj5BY2Nlc3M8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwic3RlcFwiPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwic3RlcC1pbmRpY2F0b3JcIj48L3NwYW4+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWxhYmVsXCI+UmVhZHk8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9kaXY+XG5cdFx0PC9kaXY+XG5cblx0XHQ8IS0tIEdFVFRJTkdfVE9LRU4gU3RhdGUgLSBOZXcgU2Vzc2lvbiAtLT5cblx0XHQ8ZGl2IGNsYXNzPVwic3RhdGUtY29udGFpbmVyXCIgKm5nSWY9XCJzdGF0ZSA9PT0gV2FpdGluZ1Jvb21TdGF0ZS5HRVRUSU5HX1RPS0VOICYmICFoYXNFeGlzdGluZ1Nlc3Npb25cIj5cblx0XHRcdDxkaXYgY2xhc3M9XCJzdGF0ZS1pY29uIGxvYWRpbmdcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInNwaW5uZXJcIj48L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PHAgY2xhc3M9XCJzdGF0ZS1tZXNzYWdlXCI+XG5cdFx0XHRcdFByZXBhcmluZyByb29tIGFjY2Vzcy4uLlxuXHRcdFx0PC9wPlxuXHRcdFx0PGRpdiBjbGFzcz1cInByb2dyZXNzLXN0ZXBzXCI+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJzdGVwIGNvbXBsZXRlZFwiPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwic3RlcC1pbmRpY2F0b3JcIj48aSBjbGFzcz1cImZhIGZhLWNoZWNrXCI+PC9pPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtbGFiZWxcIj5DcmVhdGVkPC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInN0ZXAgYWN0aXZlXCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWluZGljYXRvclwiPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtbGFiZWxcIj5BY2Nlc3M8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwic3RlcFwiPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwic3RlcC1pbmRpY2F0b3JcIj48L3NwYW4+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWxhYmVsXCI+UmVhZHk8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9kaXY+XG5cdFx0PC9kaXY+XG5cblx0XHQ8IS0tIEdFVFRJTkdfVE9LRU4gU3RhdGUgLSBFeGlzdGluZyBTZXNzaW9uIC0tPlxuXHRcdDxkaXYgY2xhc3M9XCJzdGF0ZS1jb250YWluZXJcIiAqbmdJZj1cInN0YXRlID09PSBXYWl0aW5nUm9vbVN0YXRlLkdFVFRJTkdfVE9LRU4gJiYgaGFzRXhpc3RpbmdTZXNzaW9uXCI+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiBsb2FkaW5nXCI+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJzcGlubmVyXCI+PC9kaXY+XG5cdFx0XHQ8L2Rpdj5cblx0XHRcdDxwIGNsYXNzPVwic3RhdGUtbWVzc2FnZVwiPlxuXHRcdFx0XHRHZXR0aW5nIHJvb20gYWNjZXNzLi4uXG5cdFx0XHQ8L3A+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwicHJvZ3Jlc3Mtc3RlcHNcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInN0ZXAgYWN0aXZlXCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWluZGljYXRvclwiPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtbGFiZWxcIj5Db25uZWN0aW5nPC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInN0ZXBcIj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtaW5kaWNhdG9yXCI+PC9zcGFuPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwic3RlcC1sYWJlbFwiPlJlYWR5PC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdDwvZGl2PlxuXG5cdFx0PCEtLSBSRUFEWSBTdGF0ZSAtIE5ldyBTZXNzaW9uIC0tPlxuXHRcdDxkaXYgY2xhc3M9XCJzdGF0ZS1jb250YWluZXJcIiAqbmdJZj1cInN0YXRlID09PSBXYWl0aW5nUm9vbVN0YXRlLlJFQURZICYmICFoYXNFeGlzdGluZ1Nlc3Npb25cIj5cblx0XHRcdDxkaXYgY2xhc3M9XCJzdGF0ZS1pY29uIHJlYWR5XCI+XG5cdFx0XHRcdDxpIGNsYXNzPVwiZmEgZmEtY2hlY2stY2lyY2xlXCI+PC9pPlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8cCBjbGFzcz1cInN0YXRlLW1lc3NhZ2Ugc3VjY2Vzc1wiPlxuXHRcdFx0XHRSb29tIGlzIHJlYWR5IVxuXHRcdFx0PC9wPlxuXHRcdFx0PHAgY2xhc3M9XCJzdGF0ZS1zdWJtZXNzYWdlXCI+XG5cdFx0XHRcdFlvdSBjYW4gam9pbiB0aGUgdmlkZW8gY2FsbCB3aGVuIHJlYWR5XG5cdFx0XHQ8L3A+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwicHJvZ3Jlc3Mtc3RlcHNcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInN0ZXAgY29tcGxldGVkXCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWluZGljYXRvclwiPjxpIGNsYXNzPVwiZmEgZmEtY2hlY2tcIj48L2k+PC9zcGFuPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwic3RlcC1sYWJlbFwiPkNyZWF0ZWQ8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwic3RlcCBjb21wbGV0ZWRcIj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtaW5kaWNhdG9yXCI+PGkgY2xhc3M9XCJmYSBmYS1jaGVja1wiPjwvaT48L3NwYW4+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWxhYmVsXCI+QWNjZXNzPC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInN0ZXAgY29tcGxldGVkXCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWluZGljYXRvclwiPjxpIGNsYXNzPVwiZmEgZmEtY2hlY2tcIj48L2k+PC9zcGFuPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwic3RlcC1sYWJlbFwiPlJlYWR5PC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PGJ1dHRvbiBcblx0XHRcdFx0dHlwZT1cImJ1dHRvblwiIFxuXHRcdFx0XHRjbGFzcz1cImJ0biBhY3Rpb24tYnRuIGpvaW4tYnRuXCJcblx0XHRcdFx0KGNsaWNrKT1cImpvaW5TZXNzaW9uKClcIj5cblx0XHRcdFx0PGkgY2xhc3M9XCJmYSBmYS1zaWduLWluXCI+PC9pPlxuXHRcdFx0XHRKb2luIFNlc3Npb25cblx0XHRcdDwvYnV0dG9uPlxuXHRcdDwvZGl2PlxuXG5cdFx0PCEtLSBSRUFEWSBTdGF0ZSAtIEV4aXN0aW5nIFNlc3Npb24gLS0+XG5cdFx0PGRpdiBjbGFzcz1cInN0YXRlLWNvbnRhaW5lclwiICpuZ0lmPVwic3RhdGUgPT09IFdhaXRpbmdSb29tU3RhdGUuUkVBRFkgJiYgaGFzRXhpc3RpbmdTZXNzaW9uXCI+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiByZWFkeVwiPlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhIGZhLWNoZWNrLWNpcmNsZVwiPjwvaT5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PHAgY2xhc3M9XCJzdGF0ZS1tZXNzYWdlIHN1Y2Nlc3NcIj5cblx0XHRcdFx0UmVhZHkgdG8gam9pbiFcblx0XHRcdDwvcD5cblx0XHRcdDxwIGNsYXNzPVwic3RhdGUtc3VibWVzc2FnZVwiPlxuXHRcdFx0XHRZb3UgY2FuIGpvaW4gdGhlIHZpZGVvIGNhbGwgd2hlbiByZWFkeVxuXHRcdFx0PC9wPlxuXHRcdFx0PGRpdiBjbGFzcz1cInByb2dyZXNzLXN0ZXBzXCI+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJzdGVwIGNvbXBsZXRlZFwiPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwic3RlcC1pbmRpY2F0b3JcIj48aSBjbGFzcz1cImZhIGZhLWNoZWNrXCI+PC9pPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtbGFiZWxcIj5Db25uZWN0ZWQ8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwic3RlcCBjb21wbGV0ZWRcIj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInN0ZXAtaW5kaWNhdG9yXCI+PGkgY2xhc3M9XCJmYSBmYS1jaGVja1wiPjwvaT48L3NwYW4+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJzdGVwLWxhYmVsXCI+UmVhZHk8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8YnV0dG9uIFxuXHRcdFx0XHR0eXBlPVwiYnV0dG9uXCIgXG5cdFx0XHRcdGNsYXNzPVwiYnRuIGFjdGlvbi1idG4gam9pbi1idG5cIlxuXHRcdFx0XHQoY2xpY2spPVwiam9pblNlc3Npb24oKVwiPlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhIGZhLXNpZ24taW5cIj48L2k+XG5cdFx0XHRcdEpvaW4gU2Vzc2lvblxuXHRcdFx0PC9idXR0b24+XG5cdFx0PC9kaXY+XG5cblx0XHQ8IS0tIEVSUk9SIFN0YXRlIC0tPlxuXHRcdDxkaXYgY2xhc3M9XCJzdGF0ZS1jb250YWluZXJcIiAqbmdJZj1cInN0YXRlID09PSBXYWl0aW5nUm9vbVN0YXRlLkVSUk9SXCI+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiBlcnJvclwiPlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhIGZhLWV4Y2xhbWF0aW9uLXRyaWFuZ2xlXCI+PC9pPlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8cCBjbGFzcz1cInN0YXRlLW1lc3NhZ2UgZXJyb3JcIj5cblx0XHRcdFx0QW4gZXJyb3Igb2NjdXJyZWRcblx0XHRcdDwvcD5cblx0XHRcdDxwIGNsYXNzPVwiZXJyb3ItZGV0YWlsc1wiICpuZ0lmPVwiZXJyb3JNZXNzYWdlXCI+XG5cdFx0XHRcdHt7IGVycm9yTWVzc2FnZSB9fVxuXHRcdFx0PC9wPlxuXHRcdFx0PGJ1dHRvbiBcblx0XHRcdFx0dHlwZT1cImJ1dHRvblwiIFxuXHRcdFx0XHRjbGFzcz1cImJ0biBhY3Rpb24tYnRuIHJldHJ5LWJ0blwiXG5cdFx0XHRcdChjbGljayk9XCJyZXRyeSgpXCI+XG5cdFx0XHRcdDxpIGNsYXNzPVwiZmEgZmEtcmVmcmVzaFwiPjwvaT5cblx0XHRcdFx0UmV0cnlcblx0XHRcdDwvYnV0dG9uPlxuXHRcdDwvZGl2PlxuXHQ8L2Rpdj5cblxuXHQ8IS0tIEZvb3RlciAtLT5cblx0PGRpdiBjbGFzcz1cIndhaXRpbmctcm9vbS1mb290ZXJcIj5cblx0XHQ8YnV0dG9uIFxuXHRcdFx0dHlwZT1cImJ1dHRvblwiIFxuXHRcdFx0Y2xhc3M9XCJidG4gY2FuY2VsLWJ0blwiXG5cdFx0XHQoY2xpY2spPVwiY2FuY2VsKClcIj5cblx0XHRcdENhbmNlbFxuXHRcdDwvYnV0dG9uPlxuXHQ8L2Rpdj5cbjwvZGl2PlxuIl19
253
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzLXdhaXRpbmctcm9vbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YXMtdWVsbC1zZGsvc3JjL2xpYi9jb21wb25lbnRzL3Rhcy13YWl0aW5nLXJvb20vdGFzLXdhaXRpbmctcm9vbS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YXMtdWVsbC1zZGsvc3JjL2xpYi9jb21wb25lbnRzL3Rhcy13YWl0aW5nLXJvb20vdGFzLXdhaXRpbmctcm9vbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFxQixLQUFLLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBR3ZGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUVMLFdBQVcsRUFDWCxlQUFlLEVBQ2YsV0FBVyxHQUNaLE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMENBQTBDLENBQUM7Ozs7O0FBRWpGLE1BQU0sQ0FBTixJQUFZLGdCQU1YO0FBTkQsV0FBWSxnQkFBZ0I7SUFDMUIsdURBQW1DLENBQUE7SUFDbkMsMkRBQXVDLENBQUE7SUFDdkMsbUNBQWUsQ0FBQTtJQUNmLG1EQUErQixDQUFBO0lBQy9CLG1DQUFlLENBQUE7QUFDakIsQ0FBQyxFQU5XLGdCQUFnQixLQUFoQixnQkFBZ0IsUUFNM0I7QUFPRCxNQUFNLE9BQU8sdUJBQXVCO0lBOEJsQyxZQUNTLFdBQTJCLEVBQzFCLFVBQXNCLEVBQ3RCLFlBQXNCLEVBQ3RCLEdBQXNCO1FBSHZCLGdCQUFXLEdBQVgsV0FBVyxDQUFnQjtRQUMxQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLGlCQUFZLEdBQVosWUFBWSxDQUFVO1FBQ3RCLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBakNoQyx5QkFBeUI7UUFD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aUIsR0FBRyxJQUFJLENBQUM7UUFDaEMsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDOztxSEExUVUsdUJBQXVCO3lHQUF2Qix1QkFBdUIsNExDekJwQyxna0ZBaUVBOzRGRHhDYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0Usa0JBQWtCO3FMQU1uQixRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBR0csV0FBVztzQkFBbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBPbkRlc3Ryb3ksIElucHV0LCBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmdiQWN0aXZlTW9kYWwsIE5nYk1vZGFsLCBOZ2JNb2RhbFJlZiB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7IFRhc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy90YXMuc2VydmljZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIFRhc0N1cnJlbnRVc2VyLFxuICBUYXNSb29tVHlwZSxcbiAgVGFzQnVzaW5lc3NSb2xlLFxuICBUYXNVc2VyUm9sZSxcbn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy90YXMuaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBUYXNWaWRlb2NhbGxDb21wb25lbnQgfSBmcm9tICcuLi90YXMtdmlkZW9jYWxsL3Rhcy12aWRlb2NhbGwuY29tcG9uZW50JztcblxuZXhwb3J0IGVudW0gV2FpdGluZ1Jvb21TdGF0ZSB7XG4gIENIRUNLSU5HX1NUQVRVUyA9ICdDSEVDS0lOR19TVEFUVVMnLFxuICBXQUlUSU5HX0ZPUl9PV05FUiA9ICdXQUlUSU5HX0ZPUl9PV05FUicsXG4gIFJFQURZID0gJ1JFQURZJyxcbiAgR0VUVElOR19UT0tFTiA9ICdHRVRUSU5HX1RPS0VOJyxcbiAgRVJST1IgPSAnRVJST1InLFxufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0YXMtd2FpdGluZy1yb29tJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Rhcy13YWl0aW5nLXJvb20uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90YXMtd2FpdGluZy1yb29tLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFRhc1dhaXRpbmdSb29tQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvLyBTdGF0dXMgZW5kcG9pbnQgcGFyYW1zXG4gIEBJbnB1dCgpIHJvb21UeXBlOiBUYXNSb29tVHlwZSA9IFRhc1Jvb21UeXBlLlRBUztcbiAgQElucHV0KCkgZW50aXR5SWQhOiBudW1iZXI7XG4gIEBJbnB1dCgpIHRlbmFudCE6IHN0cmluZztcbiAgQElucHV0KCkgYnVzaW5lc3NSb2xlOiBUYXNCdXNpbmVzc1JvbGUgPSBUYXNCdXNpbmVzc1JvbGUuVVNFUjtcblxuICAvLyBVc2VyIGluZm8gZm9yIHRva2VuIHJlcXVlc3RcbiAgQElucHV0KCkgY3VycmVudFVzZXIhOiBUYXNDdXJyZW50VXNlcjtcblxuICAvLyBDb21wb25lbnQgc3RhdGVcbiAgcHVibGljIHN0YXRlOiBXYWl0aW5nUm9vbVN0YXRlID0gV2FpdGluZ1Jvb21TdGF0ZS5DSEVDS0lOR19TVEFUVVM7XG4gIHB1YmxpYyBXYWl0aW5nUm9vbVN0YXRlID0gV2FpdGluZ1Jvb21TdGF0ZTsgLy8gRXhwb3NlIGVudW0gdG8gdGVtcGxhdGVcbiAgcHVibGljIGVycm9yTWVzc2FnZTogc3RyaW5nID0gJyc7XG5cbiAgLy8gU2Vzc2lvbiBkYXRhIGZyb20gc3RhdHVzIHJlc3BvbnNlXG4gIHByaXZhdGUgcmVzb2x2ZWRTZXNzaW9uSWQ6IHN0cmluZyA9ICcnO1xuICBwcml2YXRlIHJlc29sdmVkQXBwb2ludG1lbnRJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdG9rZW46IHN0cmluZyA9ICcnO1xuICBwcml2YXRlIHZpZGVvQ2FsbElkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAvLyBTdWJzY3JpcHRpb25zXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSB2aWRlb0NhbGxNb2RhbFJlZjogTmdiTW9kYWxSZWYgfCBudWxsID0gbnVsbDtcblxuICAvKiogV2hldGhlciBjdXJyZW50IHVzZXIgaXMgYW4gb3duZXIgKi9cbiAgcHVibGljIGdldCBpc093bmVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRVc2VyPy5yb2xlID09PSBUYXNVc2VyUm9sZS5PV05FUjtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBhY3RpdmVNb2RhbDogTmdiQWN0aXZlTW9kYWwsXG4gICAgcHJpdmF0ZSB0YXNTZXJ2aWNlOiBUYXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgbW9kYWxTZXJ2aWNlOiBOZ2JNb2RhbCxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdbVEFTIERFQlVHXSBUYXNXYWl0aW5nUm9vbUNvbXBvbmVudC5uZ09uSW5pdCcpO1xuICAgIHRoaXMuY2hlY2tTdGF0dXMoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdbVEFTIERFQlVHXSBUYXNXYWl0aW5nUm9vbUNvbXBvbmVudC5uZ09uRGVzdHJveScpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudGFzU2VydmljZS5zdG9wU3RhdHVzUG9sbGluZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHN0YXR1cyB0byBnZXQgc2Vzc2lvbiBpbmZvXG4gICAqL1xuICBwcml2YXRlIGNoZWNrU3RhdHVzKCk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdbVEFTIERFQlVHXSBjaGVja1N0YXR1cyBjYWxsZWQgd2l0aDonLCB7XG4gICAgICByb29tVHlwZTogdGhpcy5yb29tVHlwZSxcbiAgICAgIGVudGl0eUlkOiB0aGlzLmVudGl0eUlkLFxuICAgICAgdGVuYW50OiB0aGlzLnRlbmFudCxcbiAgICAgIGJ1c2luZXNzUm9sZTogdGhpcy5idXNpbmVzc1JvbGUsXG4gICAgICBjdXJyZW50VXNlcjogdGhpcy5jdXJyZW50VXNlcixcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhdGUgPSBXYWl0aW5nUm9vbVN0YXRlLkNIRUNLSU5HX1NUQVRVUztcbiAgICB0aGlzLmVycm9yTWVzc2FnZSA9ICcnO1xuXG4gICAgY29uc3Qgc3RhdHVzUGFyYW1zID0ge1xuICAgICAgcm9vbVR5cGU6IHRoaXMucm9vbVR5cGUsXG4gICAgICBlbnRpdHlJZDogdGhpcy5lbnRpdHlJZCxcbiAgICAgIHRlbmFudDogdGhpcy50ZW5hbnQsXG4gICAgICBidXNpbmVzc1JvbGU6IHRoaXMuYnVzaW5lc3NSb2xlLFxuICAgIH07XG5cbiAgICBjb25zb2xlLmxvZygnW1RBUyBERUJVR10gQ2FsbGluZyBnZXRQcm94eVZpZGVvU3RhdHVzLi4uJyk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy50YXNTZXJ2aWNlLmdldFByb3h5VmlkZW9TdGF0dXMoc3RhdHVzUGFyYW1zKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gcmVzcG9uc2UuY29udGVudDtcblxuICAgICAgICAgIC8vIFN0b3JlIHNlc3Npb24gaW5mbyBmcm9tIHJlc3BvbnNlXG4gICAgICAgICAgdGhpcy5yZXNvbHZlZFNlc3Npb25JZCA9IGNvbnRlbnQuc2Vzc2lvbklkO1xuICAgICAgICAgIHRoaXMucmVzb2x2ZWRBcHBvaW50bWVudElkID0gY29udGVudC5hcHBvaW50bWVudElkO1xuICAgICAgICAgIHRoaXMudmlkZW9DYWxsSWQgPSBjb250ZW50LnZpZGVvQ2FsbElkO1xuXG4gICAgICAgICAgY29uc29sZS5sb2coJ1tUQVMgREVCVUddIFN0YXR1cyByZXNwb25zZTonLCBjb250ZW50KTtcblxuICAgICAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgZm9yIHN0YXR1cyB1cGRhdGVzXG4gICAgICAgICAgdGhpcy50YXNTZXJ2aWNlLnN0YXJ0U3RhdHVzUG9sbGluZyhzdGF0dXNQYXJhbXMpO1xuXG4gICAgICAgICAgLy8gU3Vic2NyaWJlIHRvIGpvaW5hYmxlIHN0YXR1c1xuICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICAgICAgICB0aGlzLnRhc1NlcnZpY2Uuam9pbmFibGUkLnN1YnNjcmliZSgoam9pbmFibGUpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5oYW5kbGVKb2luYWJsZUNoYW5nZShqb2luYWJsZSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignW1RBUyBERUJVR10gU3RhdHVzIGNoZWNrIGZhaWxlZDonLCBlcnIpO1xuICAgICAgICAgIHRoaXMuc3RhdGUgPSBXYWl0aW5nUm9vbVN0YXRlLkVSUk9SO1xuICAgICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJ0Vycm9yIGNoZWNraW5nIHNlc3Npb24gc3RhdHVzLiBQbGVhc2UgdHJ5IGFnYWluLic7XG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGNoYW5nZXMgdG8gam9pbmFibGUgc3RhdHVzXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZUpvaW5hYmxlQ2hhbmdlKGpvaW5hYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coJ1tUQVMgREVCVUddIGhhbmRsZUpvaW5hYmxlQ2hhbmdlIGNhbGxlZCcsIHtcbiAgICAgIGpvaW5hYmxlLFxuICAgICAgY3VycmVudFN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgaXNPd25lcjogdGhpcy5pc093bmVyLFxuICAgICAgaXNCYWNrb2ZmaWNlOiB0aGlzLmlzQmFja29mZmljZSxcbiAgICAgIHJlc29sdmVkU2Vzc2lvbklkOiB0aGlzLnJlc29sdmVkU2Vzc2lvbklkLFxuICAgIH0pO1xuXG4gICAgLy8gRG9uJ3QgdXBkYXRlIHN0YXRlIGlmIGFscmVhZHkgZ2V0dGluZyB0b2tlbiwgcmVhZHksIG9yIGluIGVycm9yXG4gICAgaWYgKFxuICAgICAgdGhpcy5zdGF0ZSA9PT0gV2FpdGluZ1Jvb21TdGF0ZS5HRVRUSU5HX1RPS0VOIHx8XG4gICAgICB0aGlzLnN0YXRlID09PSBXYWl0aW5nUm9vbVN0YXRlLlJFQURZIHx8XG4gICAgICB0aGlzLnN0YXRlID09PSBXYWl0aW5nUm9vbVN0YXRlLkVSUk9SXG4gICAgKSB7XG4gICAgICBjb25zb2xlLmxvZygnW1RBUyBERUJVR10gU2tpcHBpbmcgc3RhdGUgdXBkYXRlIC0gYWxyZWFkeSBpbjonLCB0aGlzLnN0YXRlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc093bmVyIHx8IHRoaXMuaXNCYWNrb2ZmaWNlKSB7XG4gICAgICBjb25zb2xlLmxvZygnW1RBUyBERUJVR10gVXNlciBpcyBvd25lci9iYWNrb2ZmaWNlLCBjYWxsaW5nIGdldFRva2VuRm9yT3duZXInKTtcbiAgICAgIC8vIE93bmVyL0JhY2tvZmZpY2U6IGNhbGwgL3N0YXJ0IHRvIGdldCB0b2tlbiBmaXJzdCwgdGhlbiBzaG93IGpvaW4gYnV0dG9uXG4gICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gV2FpdGluZ1Jvb21TdGF0ZS5DSEVDS0lOR19TVEFUVVMpIHtcbiAgICAgICAgdGhpcy5nZXRUb2tlbkZvck93bmVyKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vbi1vd25lcjogd2FpdCB1bnRpbCBqb2luYWJsZSBpcyB0cnVlXG4gICAgICBpZiAoam9pbmFibGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tUQVMgREVCVUddIE5vbi1vd25lcjogam9pbmFibGUgaXMgdHJ1ZSwgZ2V0dGluZyB0b2tlbicpO1xuICAgICAgICB0aGlzLmdldFRva2VuRm9yT3duZXIoKTsgLy8gQWxzbyBnZXQgdG9rZW4gd2hlbiBqb2luYWJsZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tUQVMgREVCVUddIE5vbi1vd25lcjogd2FpdGluZyBmb3Igb3duZXInKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuV0FJVElOR19GT1JfT1dORVI7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdXNlciBoYXMgb3duZXIvYmFja29mZmljZSByb2xlXG4gICAqL1xuICBwcml2YXRlIGdldCBpc0JhY2tvZmZpY2UoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuYnVzaW5lc3NSb2xlID09PSBUYXNCdXNpbmVzc1JvbGUuQkFDS09GRklDRSB8fFxuICAgICAgdGhpcy5idXNpbmVzc1JvbGUgPT09IFRhc0J1c2luZXNzUm9sZS5BRE1JTl9NQU5BR0VSIHx8XG4gICAgICB0aGlzLmJ1c2luZXNzUm9sZSA9PT0gVGFzQnVzaW5lc3NSb2xlLk1BTkFHRVJcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0b2tlbiBmb3Igb3duZXIvYmFja29mZmljZSAtIGNhbGwgL3N0YXJ0IGVuZHBvaW50XG4gICAqL1xuICBwcml2YXRlIGdldFRva2VuRm9yT3duZXIoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlc29sdmVkU2Vzc2lvbklkKSB7XG4gICAgICB0aGlzLnN0YXRlID0gV2FpdGluZ1Jvb21TdGF0ZS5FUlJPUjtcbiAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJ1Nlc3Npb24gSUQgbm90IGF2YWlsYWJsZSc7XG4gICAgICB0aGlzLnRhc1NlcnZpY2Uuc3RvcFN0YXR1c1BvbGxpbmcoKTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlID0gV2FpdGluZ1Jvb21TdGF0ZS5HRVRUSU5HX1RPS0VOO1xuICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJyc7XG4gICAgY29uc29sZS5sb2coJ1tUQVMgREVCVUddIENhbGxpbmcgL3N0YXJ0IGZvciBzZXNzaW9uOicsIHRoaXMucmVzb2x2ZWRTZXNzaW9uSWQpO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMudGFzU2VydmljZVxuICAgICAgICAuc3RhcnRQcm94eVZpZGVvU2Vzc2lvbih7XG4gICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnJlc29sdmVkU2Vzc2lvbklkLFxuICAgICAgICAgIG5hbWU6IHRoaXMuY3VycmVudFVzZXIubmFtZSxcbiAgICAgICAgICBsYXN0bmFtZTogdGhpcy5jdXJyZW50VXNlci5sYXN0bmFtZSxcbiAgICAgICAgfSlcbiAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgbmV4dDogKHRva2VuUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbVEFTIERFQlVHXSBUb2tlbiByZXNwb25zZTonLCB0b2tlblJlc3BvbnNlKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gSGFuZGxlIGNhc2Ugd2hlcmUgSFRUUCBhZGFwdGVyIHJldHVybnMgZXJyb3IgaW4gbmV4dCBpbnN0ZWFkIG9mIGVycm9yIGhhbmRsZXJcbiAgICAgICAgICAgIGlmICghdG9rZW5SZXNwb25zZT8uY29udGVudD8udG9rZW4pIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignW1RBUyBERUJVR10gSW52YWxpZCB0b2tlbiByZXNwb25zZTonLCB0b2tlblJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuRVJST1I7XG4gICAgICAgICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gKHRva2VuUmVzcG9uc2UgYXMgYW55KT8ubWVzc2FnZSB8fCAnRXJyb3IgYWwgaW5pY2lhciBsYSBzZXNpw7NuLiBSZXNwdWVzdGEgaW52w6FsaWRhLic7XG4gICAgICAgICAgICAgIHRoaXMudGFzU2VydmljZS5zdG9wU3RhdHVzUG9sbGluZygpO1xuICAgICAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1tUQVMgREVCVUddIFRva2VuIG9idGFpbmVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy50b2tlbiA9IHRva2VuUmVzcG9uc2UuY29udGVudC50b2tlbjtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBXYWl0aW5nUm9vbVN0YXRlLlJFQURZO1xuICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tUQVMgREVCVUddIC9zdGFydCByZXF1ZXN0IGZhaWxlZDonLCBlcnIpO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuRVJST1I7XG4gICAgICAgICAgICB0aGlzLmVycm9yTWVzc2FnZSA9IGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgZXJyPy5tZXNzYWdlIHx8ICdFcnJvciBhbCBpbmljaWFyIGxhIHNlc2nDs24uIFBvciBmYXZvciwgaW50ZW50ZSBudWV2YW1lbnRlLic7XG4gICAgICAgICAgICB0aGlzLnRhc1NlcnZpY2Uuc3RvcFN0YXR1c1BvbGxpbmcoKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbVEFTIERFQlVHXSBTdGF0ZSBzZXQgdG8gRVJST1IsIGVycm9yTWVzc2FnZTonLCB0aGlzLmVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEpvaW4gdGhlIHNlc3Npb24gLSB0b2tlbiBhbHJlYWR5IG9idGFpbmVkXG4gICAqL1xuICBqb2luU2Vzc2lvbigpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVzb2x2ZWRTZXNzaW9uSWQgfHwgIXRoaXMudG9rZW4pIHtcbiAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJ1Nlc3Npb24gbm90IHJlYWR5JztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDbG9zZSB3YWl0aW5nIHJvb20gYW5kIG9wZW4gdmlkZW8gY2FsbFxuICAgIHRoaXMudGFzU2VydmljZS5zdG9wU3RhdHVzUG9sbGluZygpO1xuICAgIHRoaXMuYWN0aXZlTW9kYWwuY2xvc2UoJ2pvaW5pbmcnKTtcbiAgICB0aGlzLm9wZW5WaWRlb0NhbGxNb2RhbCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgd2FpdGluZyByb29tXG4gICAqL1xuICBjYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy50YXNTZXJ2aWNlLnN0b3BTdGF0dXNQb2xsaW5nKCk7XG4gICAgdGhpcy5hY3RpdmVNb2RhbC5kaXNtaXNzKCdjYW5jZWwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyeSBhZnRlciBhbiBlcnJvclxuICAgKi9cbiAgcmV0cnkoKTogdm9pZCB7XG4gICAgdGhpcy5zdGF0ZSA9IFdhaXRpbmdSb29tU3RhdGUuQ0hFQ0tJTkdfU1RBVFVTO1xuICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJyc7XG4gICAgdGhpcy50b2tlbiA9ICcnO1xuICAgIHRoaXMuY2hlY2tTdGF0dXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgb3BlblZpZGVvQ2FsbE1vZGFsKCk6IHZvaWQge1xuICAgIHRoaXMudmlkZW9DYWxsTW9kYWxSZWYgPSB0aGlzLm1vZGFsU2VydmljZS5vcGVuKFRhc1ZpZGVvY2FsbENvbXBvbmVudCwge1xuICAgICAgc2l6ZTogJ3hsJyxcbiAgICAgIHdpbmRvd0NsYXNzOiAndGFzLXZpZGVvLW1vZGFsJyxcbiAgICAgIGJhY2tkcm9wOiAnc3RhdGljJyxcbiAgICAgIGtleWJvYXJkOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIHRoaXMudmlkZW9DYWxsTW9kYWxSZWYuY29tcG9uZW50SW5zdGFuY2Uuc2Vzc2lvbklkID0gdGhpcy5yZXNvbHZlZFNlc3Npb25JZDtcbiAgICB0aGlzLnZpZGVvQ2FsbE1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLnRva2VuID0gdGhpcy50b2tlbjtcbiAgICB0aGlzLnZpZGVvQ2FsbE1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLmFwcG9pbnRtZW50SWQgPSB0aGlzLnJlc29sdmVkQXBwb2ludG1lbnRJZDtcbiAgICB0aGlzLnZpZGVvQ2FsbE1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLnZpZGVvQ2FsbElkID0gdGhpcy52aWRlb0NhbGxJZDtcbiAgICB0aGlzLnZpZGVvQ2FsbE1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLnRlbmFudCA9IHRoaXMudGVuYW50O1xuICAgIHRoaXMudmlkZW9DYWxsTW9kYWxSZWYuY29tcG9uZW50SW5zdGFuY2UuYnVzaW5lc3NSb2xlID0gdGhpcy5idXNpbmVzc1JvbGU7XG4gICAgdGhpcy52aWRlb0NhbGxNb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS5pc1JldHVybmluZ0Zyb21QaXAgPSBmYWxzZTtcblxuICAgIHRoaXMudmlkZW9DYWxsTW9kYWxSZWYucmVzdWx0LnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMudmlkZW9DYWxsTW9kYWxSZWYgPSBudWxsO1xuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgdGhpcy52aWRlb0NhbGxNb2RhbFJlZiA9IG51bGw7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInRhcy13YWl0aW5nLXJvb21cIj5cbiAgPCEtLSBIZWFkZXIgLS0+XG4gIDxkaXYgY2xhc3M9XCJ3YWl0aW5nLXJvb20taGVhZGVyXCI+XG4gICAgPGgyIGNsYXNzPVwiaGVhZGVyLXRpdGxlXCI+SW5pY2lhciB0dXJubzwvaDI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZS1idG5cIiAoY2xpY2spPVwiY2FuY2VsKClcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj5cbiAgICAgIDxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZ0aW1lczs8L3NwYW4+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gQ29udGVudCAtLT5cbiAgPGRpdiBjbGFzcz1cIndhaXRpbmctcm9vbS1jb250ZW50XCI+XG4gICAgPCEtLSBDSEVDS0lOR19TVEFUVVMgU3RhdGUgLS0+XG4gICAgPGRpdiBjbGFzcz1cInN0YXRlLWNvbnRhaW5lclwiICpuZ0lmPVwic3RhdGUgPT09IFdhaXRpbmdSb29tU3RhdGUuQ0hFQ0tJTkdfU1RBVFVTXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiBsb2FkaW5nXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyXCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwIGNsYXNzPVwic3RhdGUtbWVzc2FnZVwiPlZlcmlmaWNhbmRvIGVzdGFkbyBkZSBsYSBzZXNpw7NuLi4uPC9wPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBXQUlUSU5HX0ZPUl9PV05FUiBTdGF0ZSAoTm9uLW93bmVyIHdhaXRpbmcpIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzdGF0ZS1jb250YWluZXIgd2FpdGluZy1mb3Itb3duZXJcIiAqbmdJZj1cInN0YXRlID09PSBXYWl0aW5nUm9vbVN0YXRlLldBSVRJTkdfRk9SX09XTkVSXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiBsb2FkaW5nXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyXCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwIGNsYXNzPVwic3RhdGUtbWVzc2FnZSB3YWl0aW5nLXRpdGxlXCI+TWVkaWNpbmEgbGFib3JhbCB0ZSB2YSBhIGFkbWl0aXIgZW4gdW5vcyBpbnN0YW50ZXMuLi48L3A+XG4gICAgICA8cCBjbGFzcz1cInN0YXRlLXN1Ym1lc3NhZ2VcIj5Qb3IgZmF2b3IsIHBlcm1hbmVjw6kgZW4gZXN0YSBwYW50YWxsYSBoYXN0YSBxdWUgaW5pY2llIGxhIGNvbnN1bHRhLjwvcD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gUkVBRFkgU3RhdGUgKE93bmVyIGNhbiBqb2luKSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic3RhdGUtY29udGFpbmVyXCIgKm5nSWY9XCJzdGF0ZSA9PT0gV2FpdGluZ1Jvb21TdGF0ZS5SRUFEWVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInN0YXRlLWljb24gcmVhZHlcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1jaGVjay1jaXJjbGVcIj48L2k+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwIGNsYXNzPVwic3RhdGUtbWVzc2FnZSBzdWNjZXNzXCI+wqFMYSBzYWxhIGVzdMOhIGxpc3RhITwvcD5cbiAgICAgIDxwIGNsYXNzPVwic3RhdGUtc3VibWVzc2FnZVwiPlBvZMOpcyB1bmlydGUgYSBsYSB2aWRlb2xsYW1hZGEgY3VhbmRvIHF1aWVyYXM8L3A+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBhY3Rpb24tYnRuIGpvaW4tYnRuXCIgKGNsaWNrKT1cImpvaW5TZXNzaW9uKClcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1zaWduLWluXCI+PC9pPlxuICAgICAgICBVbmlyc2UgYSBsYSBsbGFtYWRhXG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gR0VUVElOR19UT0tFTiBTdGF0ZSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic3RhdGUtY29udGFpbmVyXCIgKm5nSWY9XCJzdGF0ZSA9PT0gV2FpdGluZ1Jvb21TdGF0ZS5HRVRUSU5HX1RPS0VOXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiBsb2FkaW5nXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyXCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxwIGNsYXNzPVwic3RhdGUtbWVzc2FnZVwiPkNvbmVjdGFuZG8uLi48L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEVSUk9SIFN0YXRlIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzdGF0ZS1jb250YWluZXJcIiAqbmdJZj1cInN0YXRlID09PSBXYWl0aW5nUm9vbVN0YXRlLkVSUk9SXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdGUtaWNvbiBlcnJvclwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWV4Y2xhbWF0aW9uLXRyaWFuZ2xlXCI+PC9pPlxuICAgICAgPC9kaXY+XG4gICAgICA8cCBjbGFzcz1cInN0YXRlLW1lc3NhZ2UgZXJyb3JcIj5PY3VycmnDsyB1biBlcnJvcjwvcD5cbiAgICAgIDxwIGNsYXNzPVwiZXJyb3ItZGV0YWlsc1wiICpuZ0lmPVwiZXJyb3JNZXNzYWdlXCI+XG4gICAgICAgIHt7IGVycm9yTWVzc2FnZSB9fVxuICAgICAgPC9wPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYWN0aW9uLWJ0biByZXRyeS1idG5cIiAoY2xpY2spPVwicmV0cnkoKVwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXJlZnJlc2hcIj48L2k+XG4gICAgICAgIFJlaW50ZW50YXJcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19