simpo-component-library 3.6.996 → 3.6.999

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.
@@ -91,6 +91,13 @@ export class AppointmentBookingComponent extends BaseSection {
91
91
  };
92
92
  this.serviceData = [];
93
93
  this.locationData = [];
94
+ // True once the wizard has detoured through staffListing for the current cart (ambiguous
95
+ // staff pool) and returned to dateSelection to show times - NOT just "slots have been
96
+ // fetched", since the simple/unambiguous path also fetches slots on its one and only visit to
97
+ // dateSelection and should keep showing the full "Select Date" card there, unchanged. Only the
98
+ // staffListing detour makes the date card redundant on the return visit (the date was already
99
+ // picked and locked in before the detour even started).
100
+ this.cameFromStaffListing = false;
94
101
  this.staffSearchQuery = '';
95
102
  this.staffData = [];
96
103
  this.loader = false;
@@ -136,6 +143,33 @@ export class AppointmentBookingComponent extends BaseSection {
136
143
  get reviewTotal() {
137
144
  return this.servicesSubtotal + this.homeVisitCharge;
138
145
  }
146
+ /** Mirrors appointment_service's DepositUtils#getServiceDepositAmount exactly, so this preview
147
+ * matches what BookingGroupService#holdBooking will actually compute into serviceDepositTotal.
148
+ * Uses priceDetails.totalPrice (tax-inclusive), same as the backend - not servicePrice()'s
149
+ * pre-tax `.price`, which would understate a percent-based deposit. */
150
+ serviceDepositAmount(serviceId) {
151
+ const service = this.cartServices.find((s) => s.serviceId === serviceId);
152
+ const d = service?.depositAmount;
153
+ if (!d || !d.depositRequired)
154
+ return 0;
155
+ if (d.fixedAmount > 0)
156
+ return d.fixedAmount;
157
+ return (d.depositPercent / 100) * (service?.priceDetails?.totalPrice ?? 0);
158
+ }
159
+ get depositTotal() {
160
+ return this.resolvedLines.reduce((sum, l) => sum + (l.services || []).reduce((s, sv) => s + this.serviceDepositAmount(sv.id), 0), 0);
161
+ }
162
+ /** What's actually due at booking time for a live customer (serviceDepositTotal + home visit
163
+ * charge, matching BookingGroupService#holdBooking's totalCollectedAtBooking) - shown as an
164
+ * informational preview for admin bookings too, even though those collect ₹0 online and record
165
+ * the full amount in person later; this still previews the same policy that'll land on the
166
+ * booking's own detail page once created. */
167
+ get dueAtBookingTotal() {
168
+ return this.depositTotal + this.homeVisitCharge;
169
+ }
170
+ get pendingAtAppointmentTotal() {
171
+ return Math.max(0, this.reviewTotal - this.dueAtBookingTotal);
172
+ }
139
173
  get bookingTotal() {
140
174
  return (this.bookingGroup?.totalPayable ?? 0) + (this.bookingGroup?.homeVisitCharge ?? 0);
141
175
  }
@@ -200,6 +234,7 @@ export class AppointmentBookingComponent extends BaseSection {
200
234
  resetWizard() {
201
235
  this.cartServices = [];
202
236
  this.resolvedLines = [];
237
+ this.cameFromStaffListing = false;
203
238
  this.selectedLocation = null;
204
239
  this.selectedDate = null;
205
240
  this.selectedDateStr = '';
@@ -375,15 +410,17 @@ export class AppointmentBookingComponent extends BaseSection {
375
410
  this.restService.getAllAppointmentService(servicePayload).subscribe((res) => {
376
411
  this.skeletonLoader = false;
377
412
  let services = (res.content || []).filter((service) => service.active === true);
378
- // availableOnline/homeAppointmentAvailable control what a customer can self-serve book on
379
- // the live website - they don't apply when a staff member is creating a booking on the
380
- // customer's behalf from the admin panel.
381
- if (!this.isAdminBooking) {
382
- if (this.selectedMode === 'HOME_VISIT')
383
- services = services.filter((s) => s.homeAppointmentAvailable);
384
- if (this.selectedMode === 'VIDEO_CALL')
385
- services = services.filter((s) => s.videoCallAvailable);
386
- }
413
+ // homeAppointmentAvailable/videoCallAvailable/storeIds are mode-CAPABILITY flags - whether
414
+ // a service can be delivered that way at all (e.g. a haircut can't be done over video) -
415
+ // not a customer-self-service permission, so these apply unconditionally, including for
416
+ // isAdminBooking. (availableOnline is the actual self-service-only flag, and is
417
+ // intentionally not filtered here - an admin can still book it on the customer's behalf.)
418
+ if (this.selectedMode === 'HOME_VISIT')
419
+ services = services.filter((s) => s.homeAppointmentAvailable);
420
+ if (this.selectedMode === 'VIDEO_CALL')
421
+ services = services.filter((s) => s.videoCallAvailable);
422
+ if (this.selectedMode === 'STORE_VISIT')
423
+ services = services.filter((s) => (s.storeIds?.length ?? 0) > 0);
387
424
  services.forEach((service) => service.selected = false);
388
425
  this.serviceData = services;
389
426
  this.cartServices = [];
@@ -437,6 +474,7 @@ export class AppointmentBookingComponent extends BaseSection {
437
474
  this.barWidth = '43.57';
438
475
  this.activeButton = false;
439
476
  this.resolvedLines = [];
477
+ this.cameFromStaffListing = false;
440
478
  }
441
479
  get filteredStaff() {
442
480
  if (!this.staffSearchQuery.trim()) {
@@ -482,6 +520,7 @@ export class AppointmentBookingComponent extends BaseSection {
482
520
  this.staffSearchQuery = '';
483
521
  this.selectedTab = 'staffListing';
484
522
  this.barWidth = '43.57';
523
+ this.cameFromStaffListing = true;
485
524
  // Picking is optional - Continue is enabled immediately either way, and the backend
486
525
  // auto-assigns the least-busy eligible staff for any line left unpicked.
487
526
  this.activeButton = true;
@@ -512,6 +551,7 @@ export class AppointmentBookingComponent extends BaseSection {
512
551
  this.staffData.forEach((staff) => staff.selected = false);
513
552
  this.selectedTab = 'staffListing';
514
553
  this.barWidth = '43.57';
554
+ this.cameFromStaffListing = true;
515
555
  // Optional - Continue enables immediately, the customer can still pick if they want.
516
556
  this.activeButton = true;
517
557
  }, () => { this.loader = false; });
@@ -626,7 +666,11 @@ export class AppointmentBookingComponent extends BaseSection {
626
666
  // Defensive re-check (mirrors cart.component.ts's proceedToPayment() guard) - the entry
627
667
  // check in ngOnInit() should make this unreachable in practice, but a long slot-picking
628
668
  // session could still let the login session expire before the customer reaches this step.
629
- if (!this.edit && !this.storageService.getUser()) {
669
+ // Must exclude isAdminBooking same as ngOnInit's guard - a staff member booking on a
670
+ // customer's behalf is never logged in via storageService.getUser(), so without this check
671
+ // every admin booking hit this redirect on confirm (router.navigate(['/login']) throws
672
+ // NG04002 in the admin app, which has no such route).
673
+ if (!this.edit && !this.storageService.getUser() && !this.isAdminBooking) {
630
674
  this.router.navigate(['/login'], { queryParams: { redirectTo: this.router.url } });
631
675
  return;
632
676
  }
@@ -726,11 +770,11 @@ export class AppointmentBookingComponent extends BaseSection {
726
770
  this.resetWizard();
727
771
  }
728
772
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppointmentBookingComponent, deps: [{ token: i1.RestService }, { token: i2.EventsService }, { token: i3.Router }, { token: i4.MessageService }, { token: i5.BookingProductCartService }, { token: i6.StorageServiceService }, { token: i7.MatDialog }, { token: i7.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
729
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppointmentBookingComponent, isStandalone: true, selector: "simpo-appointment-booking", inputs: { data: "data", index: "index", edit: "edit", isAdminBooking: "isAdminBooking", delete: "delete", customClass: "customClass", nextComponentColor: "nextComponentColor", prefillContact: "prefillContact" }, host: { listeners: { "window: resize": "getScreenSize($event)", "document:click": "closeOnOutsideClick()" } }, providers: [MessageService], usesInheritance: true, ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"serviceData.length === 0\">\n <mat-icon>inventory_2</mat-icon>\n <h4>No services available</h4>\n <p *ngIf=\"selectedMode === 'HOME_VISIT'\">No services are currently available for home visits.</p>\n <p *ngIf=\"selectedMode === 'VIDEO_CALL'\">No services are currently available for video calls.</p>\n <p *ngIf=\"selectedMode === 'STORE_VISIT'\">This business hasn't added any services yet.</p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"locationData.length === 0\">\n <mat-icon>storefront</mat-icon>\n <h4>No locations available</h4>\n <p>There's no location available for this service right now.</p>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional, or skip to have us assign the best available one</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"filteredStaff.length === 0\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>There's no staff member available for this service right now.</p>\n </div>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"!line.candidateStaffPool?.length\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>No staff member is available for {{line.services.length}} service(s) in this line.</p>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"resolvedLines[0].slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName || 'To be assigned'}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"line.slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngFor=\"let s of line.services\">\n <div class=\"summary-label\">{{s.name}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{servicePrice(s.id)}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n\n <h2 class=\"summary-title\">Payment</h2>\n <div class=\"summary-row\" *ngIf=\"homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{homeVisitCharge}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{reviewTotal}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"bookingGroup?.homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{bookingGroup.homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.empty-state-mini{width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:6px;padding:48px 16px;color:var(--slate-500)}.empty-state-mini mat-icon{font-size:32px;height:32px;width:32px;color:var(--slate-300);margin-bottom:4px}.empty-state-mini h4{margin:0;font-size:15px;font-weight:600;color:var(--slate-700)}.empty-state-mini p{margin:0;font-size:13px;color:var(--slate-500)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i8.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i8.SlicePipe, name: "slice" }, { kind: "pipe", type: i8.TitleCasePipe, name: "titlecase" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i9.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i10.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i10.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i10.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i10.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: LettersOnlyDirective, selector: "[simpoLettersOnly]" }, { kind: "directive", type: NumbersOnlyDirective, selector: "[simpoNumbersOnly]" }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: HoverDirective, selector: "[simpoHover]", outputs: ["hovering"] }, { kind: "component", type: HoverElementsComponent, selector: "simpo-hover-elements", inputs: ["data", "index", "editOptions", "isMerged", "isEcommerce"], outputs: ["edit"] }, { kind: "directive", type: BackgroundDirective, selector: "[simpoBackground]", inputs: ["simpoBackground", "scrollValue"] }] }); }
773
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppointmentBookingComponent, isStandalone: true, selector: "simpo-appointment-booking", inputs: { data: "data", index: "index", edit: "edit", isAdminBooking: "isAdminBooking", delete: "delete", customClass: "customClass", nextComponentColor: "nextComponentColor", prefillContact: "prefillContact" }, host: { listeners: { "window: resize": "getScreenSize($event)", "document:click": "closeOnOutsideClick()" } }, providers: [MessageService], usesInheritance: true, ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"serviceData.length === 0\">\n <mat-icon>inventory_2</mat-icon>\n <h4>No services available</h4>\n <p *ngIf=\"selectedMode === 'HOME_VISIT'\">No services are currently available for home visits.</p>\n <p *ngIf=\"selectedMode === 'VIDEO_CALL'\">No services are currently available for video calls.</p>\n <p *ngIf=\"selectedMode === 'STORE_VISIT'\">This business hasn't added any services yet.</p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"locationData.length === 0\">\n <mat-icon>storefront</mat-icon>\n <h4>No locations available</h4>\n <p>There's no location available for this service right now.</p>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional, or skip to have us assign the best available one</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"filteredStaff.length === 0\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>There's no staff member available for this service right now.</p>\n </div>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"!line.candidateStaffPool?.length\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>No staff member is available for {{line.services.length}} service(s) in this line.</p>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\" *ngIf=\"!cameFromStaffListing\">Choose when you'd like your appointment</p>\n <p class=\"datetime-subtitle mb-0\" *ngIf=\"cameFromStaffListing\">\uD83D\uDCC5 {{selectedDateStr}}</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div *ngIf=\"!cameFromStaffListing\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 && !cameFromStaffListing, 'w-100':screenWidth < 475 || cameFromStaffListing}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"resolvedLines[0].slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName || 'To be assigned'}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"line.slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngFor=\"let s of line.services\">\n <div class=\"summary-label\">{{s.name}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{servicePrice(s.id)}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n\n <h2 class=\"summary-title\">Payment</h2>\n <div class=\"summary-row\" *ngIf=\"depositTotal > 0\">\n <div class=\"summary-label\">Service deposit</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{depositTotal}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{homeVisitCharge}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{reviewTotal}}</div>\n </div>\n <ng-container *ngIf=\"pendingAtAppointmentTotal > 0\">\n <div class=\"summary-row\">\n <div class=\"summary-label\">Deposit</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{dueAtBookingTotal}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Pending at appointment</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{pendingAtAppointmentTotal}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"bookingGroup?.homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{bookingGroup.homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.empty-state-mini{width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:6px;padding:48px 16px;color:var(--slate-500)}.empty-state-mini mat-icon{font-size:32px;height:32px;width:32px;color:var(--slate-300);margin-bottom:4px}.empty-state-mini h4{margin:0;font-size:15px;font-weight:600;color:var(--slate-700)}.empty-state-mini p{margin:0;font-size:13px;color:var(--slate-500)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i8.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i8.SlicePipe, name: "slice" }, { kind: "pipe", type: i8.TitleCasePipe, name: "titlecase" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i9.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i10.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i10.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i10.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i10.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: LettersOnlyDirective, selector: "[simpoLettersOnly]" }, { kind: "directive", type: NumbersOnlyDirective, selector: "[simpoNumbersOnly]" }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: HoverDirective, selector: "[simpoHover]", outputs: ["hovering"] }, { kind: "component", type: HoverElementsComponent, selector: "simpo-hover-elements", inputs: ["data", "index", "editOptions", "isMerged", "isEcommerce"], outputs: ["edit"] }, { kind: "directive", type: BackgroundDirective, selector: "[simpoBackground]", inputs: ["simpoBackground", "scrollValue"] }] }); }
730
774
  }
731
775
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppointmentBookingComponent, decorators: [{
732
776
  type: Component,
733
- args: [{ selector: 'simpo-appointment-booking', standalone: true, imports: [CdkDragPlaceholder, CommonModule, MatIcon, MatFormFieldModule, MatDatepickerModule, FormsModule, MatNativeDateModule, MatInputModule, MatDialogModule, LettersOnlyDirective, NumbersOnlyDirective, ToastModule, HoverDirective, HoverElementsComponent, BackgroundDirective], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"serviceData.length === 0\">\n <mat-icon>inventory_2</mat-icon>\n <h4>No services available</h4>\n <p *ngIf=\"selectedMode === 'HOME_VISIT'\">No services are currently available for home visits.</p>\n <p *ngIf=\"selectedMode === 'VIDEO_CALL'\">No services are currently available for video calls.</p>\n <p *ngIf=\"selectedMode === 'STORE_VISIT'\">This business hasn't added any services yet.</p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"locationData.length === 0\">\n <mat-icon>storefront</mat-icon>\n <h4>No locations available</h4>\n <p>There's no location available for this service right now.</p>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional, or skip to have us assign the best available one</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"filteredStaff.length === 0\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>There's no staff member available for this service right now.</p>\n </div>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"!line.candidateStaffPool?.length\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>No staff member is available for {{line.services.length}} service(s) in this line.</p>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"resolvedLines[0].slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName || 'To be assigned'}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"line.slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngFor=\"let s of line.services\">\n <div class=\"summary-label\">{{s.name}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{servicePrice(s.id)}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n\n <h2 class=\"summary-title\">Payment</h2>\n <div class=\"summary-row\" *ngIf=\"homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{homeVisitCharge}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{reviewTotal}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"bookingGroup?.homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{bookingGroup.homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.empty-state-mini{width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:6px;padding:48px 16px;color:var(--slate-500)}.empty-state-mini mat-icon{font-size:32px;height:32px;width:32px;color:var(--slate-300);margin-bottom:4px}.empty-state-mini h4{margin:0;font-size:15px;font-weight:600;color:var(--slate-700)}.empty-state-mini p{margin:0;font-size:13px;color:var(--slate-500)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"] }]
777
+ args: [{ selector: 'simpo-appointment-booking', standalone: true, imports: [CdkDragPlaceholder, CommonModule, MatIcon, MatFormFieldModule, MatDatepickerModule, FormsModule, MatNativeDateModule, MatInputModule, MatDialogModule, LettersOnlyDirective, NumbersOnlyDirective, ToastModule, HoverDirective, HoverElementsComponent, BackgroundDirective], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"serviceData.length === 0\">\n <mat-icon>inventory_2</mat-icon>\n <h4>No services available</h4>\n <p *ngIf=\"selectedMode === 'HOME_VISIT'\">No services are currently available for home visits.</p>\n <p *ngIf=\"selectedMode === 'VIDEO_CALL'\">No services are currently available for video calls.</p>\n <p *ngIf=\"selectedMode === 'STORE_VISIT'\">This business hasn't added any services yet.</p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"locationData.length === 0\">\n <mat-icon>storefront</mat-icon>\n <h4>No locations available</h4>\n <p>There's no location available for this service right now.</p>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional, or skip to have us assign the best available one</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"filteredStaff.length === 0\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>There's no staff member available for this service right now.</p>\n </div>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"empty-state-mini\" *ngIf=\"!line.candidateStaffPool?.length\">\n <mat-icon>badge</mat-icon>\n <h4>No staff available</h4>\n <p>No staff member is available for {{line.services.length}} service(s) in this line.</p>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\" *ngIf=\"!cameFromStaffListing\">Choose when you'd like your appointment</p>\n <p class=\"datetime-subtitle mb-0\" *ngIf=\"cameFromStaffListing\">\uD83D\uDCC5 {{selectedDateStr}}</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div *ngIf=\"!cameFromStaffListing\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 && !cameFromStaffListing, 'w-100':screenWidth < 475 || cameFromStaffListing}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"resolvedLines[0].slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName || 'To be assigned'}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n <p class=\"mb-0\" *ngIf=\"line.slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngFor=\"let s of line.services\">\n <div class=\"summary-label\">{{s.name}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{servicePrice(s.id)}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n\n <h2 class=\"summary-title\">Payment</h2>\n <div class=\"summary-row\" *ngIf=\"depositTotal > 0\">\n <div class=\"summary-label\">Service deposit</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{depositTotal}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{homeVisitCharge}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{reviewTotal}}</div>\n </div>\n <ng-container *ngIf=\"pendingAtAppointmentTotal > 0\">\n <div class=\"summary-row\">\n <div class=\"summary-label\">Deposit</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{dueAtBookingTotal}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Pending at appointment</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{pendingAtAppointmentTotal}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"bookingGroup?.homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{bookingGroup.homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.empty-state-mini{width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:6px;padding:48px 16px;color:var(--slate-500)}.empty-state-mini mat-icon{font-size:32px;height:32px;width:32px;color:var(--slate-300);margin-bottom:4px}.empty-state-mini h4{margin:0;font-size:15px;font-weight:600;color:var(--slate-700)}.empty-state-mini p{margin:0;font-size:13px;color:var(--slate-500)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"] }]
734
778
  }], ctorParameters: () => [{ type: i1.RestService }, { type: i2.EventsService }, { type: i3.Router }, { type: i4.MessageService }, { type: i5.BookingProductCartService }, { type: i6.StorageServiceService }, { type: i7.MatDialog }, { type: i7.MatDialogRef, decorators: [{
735
779
  type: Optional
736
780
  }] }], propDecorators: { data: [{
@@ -756,4 +800,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
756
800
  type: HostListener,
757
801
  args: ['document:click']
758
802
  }] } });
759
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwb2ludG1lbnQtYm9va2luZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaW1wby11aS9zcmMvbGliL3NlY3Rpb25zL2FwcG9pbnRtZW50LWZvcm0vYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nL2FwcG9pbnRtZW50LWJvb2tpbmcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2ltcG8tdWkvc3JjL2xpYi9zZWN0aW9ucy9hcHBvaW50bWVudC1mb3JtL2FwcG9pbnRtZW50LWJvb2tpbmcvYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0QsT0FBTyxFQUFhLGVBQWUsRUFBZ0IsTUFBTSwwQkFBMEIsQ0FBQztBQUlwRixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHekQsT0FBTyxFQUFFLG9CQUFvQixF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SztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBRUcsY0FBYztzQkFBdEIsS0FBSztnQkE4SE4sYUFBYTtzQkFEWixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQUsxQyxtQkFBbUI7c0JBRGxCLFlBQVk7dUJBQUMsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkluaXQsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ2RrRHJhZ1BsYWNlaG9sZGVyIH0gZnJvbSBcIkBhbmd1bGFyL2Nkay9kcmFnLWRyb3BcIjtcbmltcG9ydCB7IE1hdEljb24gfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvblwiO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZFwiO1xuaW1wb3J0IHsgTWF0RGF0ZXBpY2tlck1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyXCI7XG5pbXBvcnQgeyBNYXROYXRpdmVEYXRlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgeyBNYXREaWFsb2csIE1hdERpYWxvZ01vZHVsZSwgTWF0RGlhbG9nUmVmIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IFJlc3RTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvcmVzdC5zZXJ2aWNlJztcbmltcG9ydCB7IEV2ZW50c1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9ldmVudHMuc2VydmljZSc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBCYW5uZXJDb250ZW50TW9kZWwsIEJhbm5lclNlY3Rpb25Nb2RlbCB9IGZyb20gJy4uLy4uL2FwcG9pbnRtZW50LWZvcm0ubW9kZWwnO1xuaW1wb3J0IHsgQmFja2dyb3VuZE1vZGVsLCBCYW5uZXJTdHlsZXNNb2RlbCB9IGZyb20gJy4uLy4uLy4uLy4uL3N0eWxlcy9zdHlsZS5tb2RlbCc7XG5pbXBvcnQgeyBMZXR0ZXJzT25seURpcmVjdGl2ZSB9IGZyb20gJy4uLy4uLy4uLy4uL2RpcmVjdGl2ZS9sZXR0ZXJzLW9ubHkuZGlyZWN0aXZlJztcbmltcG9ydCB7IE51bWJlcnNPbmx5RGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vLi4vLi4vZGlyZWN0aXZlL251bWJlcnMtb25seS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgVG9hc3RNb2R1bGUgfSBmcm9tIFwicHJpbWVuZy90b2FzdFwiO1xuaW1wb3J0IHsgTWVzc2FnZVNlcnZpY2UgfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQgeyBCb29raW5nUHJvZHVjdENhcnRTZXJ2aWNlLCBCb29raW5nQ2FydE1vZGUgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9ib29raW5nLXByb2R1Y3QtY2FydC5zZXJ2aWNlJztcbmltcG9ydCB7IFN0b3JhZ2VTZXJ2aWNlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL3N0b3JhZ2Uuc2VydmljZSc7XG5pbXBvcnQgeyBBZGRyZXNzQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vZWNvbW1lcmNlL3NlY3Rpb25zL2FkZHJlc3MvYWRkcmVzcy5jb21wb25lbnQnO1xuaW1wb3J0IHsgQWRkcmVzc0xpc3RDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9lbGVtZW50cy9hZGRyZXNzLWxpc3QvYWRkcmVzcy1saXN0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBZGRyZXNzRGV0YWlscywgVXNlciB9IGZyb20gJy4uLy4uLy4uLy4uL2Vjb21tZXJjZS9zdHlsZXMvdXNlci5tb2RhbCc7XG5pbXBvcnQgQmFzZVNlY3Rpb24gZnJvbSAnLi4vLi4vLi4vQmFzZVNlY3Rpb24nO1xuaW1wb3J0IHsgSG92ZXJEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi8uLi8uLi9kaXJlY3RpdmUvaG92ZXItZWxlbWVudC1kaXJlY3RpdmUnO1xuaW1wb3J0IHsgSG92ZXJFbGVtZW50c0NvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uLy4uL2NvbXBvbmVudHMvaG92ZXItZWxlbWVudHMvaG92ZXItZWxlbWVudHMuY29tcG9uZW50JztcbmltcG9ydCB7IEJhY2tncm91bmREaXJlY3RpdmUgfSBmcm9tICcuLi8uLi8uLi8uLi9kaXJlY3RpdmUvYmFja2dyb3VuZC1kaXJlY3RpdmUnO1xuXG50eXBlIEJvb2tpbmdNb2RlID0gJ1NUT1JFX1ZJU0lUJyB8ICdIT01FX1ZJU0lUJyB8ICdWSURFT19DQUxMJztcblxuaW50ZXJmYWNlIFJlc29sdmVkTGluZSB7XG4gIHNlcnZpY2VzOiB7IGlkOiBzdHJpbmcsIG5hbWU6IHN0cmluZyB9W107XG4gIHRvdGFsRHVyYXRpb25NaW51dGVzOiBudW1iZXI7XG4gIHN0YWZmSWQ/OiBzdHJpbmc7XG4gIHN0YWZmTmFtZT86IHN0cmluZztcbiAgY2FuZGlkYXRlU3RhZmZQb29sPzogeyBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcgfVtdO1xuICBzZWxlY3RlZFN0YWZmSWQ/OiBzdHJpbmc7XG4gIHNlbGVjdGVkU3RhZmZOYW1lPzogc3RyaW5nO1xuICBzbG90czogYW55W107XG4gIHNlbGVjdGVkU2xvdD86IGFueTtcbiAgc2xvdHNMb2FkaW5nPzogYm9vbGVhbjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2ltcG8tYXBwb2ludG1lbnQtYm9va2luZycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDZGtEcmFnUGxhY2Vob2xkZXIsIENvbW1vbk1vZHVsZSwgTWF0SWNvbiwgTWF0Rm9ybUZpZWxkTW9kdWxlLCBNYXREYXRlcGlja2VyTW9kdWxlLCBGb3Jtc01vZHVsZSwgTWF0TmF0aXZlRGF0ZU1vZHVsZSwgTWF0SW5wdXRNb2R1bGUsIE1hdERpYWxvZ01vZHVsZSwgTGV0dGVyc09ubHlEaXJlY3RpdmUsIE51bWJlcnNPbmx5RGlyZWN0aXZlLCBUb2FzdE1vZHVsZSwgSG92ZXJEaXJlY3RpdmUsIEhvdmVyRWxlbWVudHNDb21wb25lbnQsIEJhY2tncm91bmREaXJlY3RpdmVdLFxuICBwcm92aWRlcnM6IFtNZXNzYWdlU2VydmljZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9hcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2FwcG9pbnRtZW50LWJvb2tpbmcuY29tcG9uZW50LmNzcydcbn0pXG5leHBvcnQgY2xhc3MgQXBwb2ludG1lbnRCb29raW5nQ29tcG9uZW50IGV4dGVuZHMgQmFzZVNlY3Rpb24gaW1wbGVtZW50cyBPbkluaXQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlc3RTZXJ2aWNlOiBSZXN0U2VydmljZSxcbiAgICBwcml2YXRlIF9ldmVudFNlcnZpY2U6IEV2ZW50c1NlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXI6IFJvdXRlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2U6IEJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlU2VydmljZTogU3RvcmFnZVNlcnZpY2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWF0RGlhbG9nOiBNYXREaWFsb2csXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSByZWFkb25seSBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxBcHBvaW50bWVudEJvb2tpbmdDb21wb25lbnQ+XG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cbiAgQElucHV0KCkgZGF0YT86IEJhbm5lclNlY3Rpb25Nb2RlbDtcbiAgQElucHV0KCkgaW5kZXg/OiBudW1iZXI7XG4gIGNvbnRlbnQ/OiBCYW5uZXJDb250ZW50TW9kZWw7XG4gIEBJbnB1dCgpIGVkaXQ/OiBib29sZWFuO1xuICAvKiogU2V0IGJ5IHRoZSBhZG1pbiBwYW5lbCdzIFwiQm9vayBOZXcgQXBwb2ludG1lbnRcIiB0b29sIC0gYSBzdGFmZiBtZW1iZXIgY3JlYXRpbmcgYSBib29raW5nIG9uXG4gICAqIGEgY3VzdG9tZXIncyBiZWhhbGYsIG5vdCBhIGxpdmUgY3VzdG9tZXIgc2VsZi1zZXJ2aWNlIGZsb3cuIFNraXBzIHRoZSBjdXN0b21lci1mYWNpbmdcbiAgICogYXZhaWxhYmxlT25saW5lL2hvbWVBcHBvaW50bWVudEF2YWlsYWJsZSBzZXJ2aWNlIGZpbHRlcnMsIHdoaWNoIG9ubHkgbWFrZSBzZW5zZSBmb3Igd2hhdCBhXG4gICAqIGN1c3RvbWVyIGNhbiBzZWxmLXNlcnZlIGJvb2sgb24gdGhlIGxpdmUgd2Vic2l0ZS4gKi9cbiAgQElucHV0KCkgaXNBZG1pbkJvb2tpbmc/OiBib29sZWFuO1xuICBASW5wdXQoKSBkZWxldGU/OiBib29sZWFuO1xuICBASW5wdXQoKSBjdXN0b21DbGFzcz86IHN0cmluZztcbiAgQElucHV0KCkgbmV4dENvbXBvbmVudENvbG9yPzogQmFja2dyb3VuZE1vZGVsO1xuICAvKiogTGV0cyBhIGxhdW5jaGluZyBkaWFsb2cgKGUuZy4gdGhlIHZpZGVvLWNhbGwgcHJvZHVjdCBwaWNrZXIpIGNhcnJ5IG92ZXIgbmFtZS9waG9uZSBhbHJlYWR5IGNvbGxlY3RlZCwgc28gdGhlIGN1c3RvbWVyIGlzbid0IGFza2VkIHR3aWNlLiAqL1xuICBASW5wdXQoKSBwcmVmaWxsQ29udGFjdD86IHsgbmFtZT86IHN0cmluZywgcGhvbmVOdW1iZXI/OiBzdHJpbmcgfTtcbiAgc3R5bGVzPzogQmFubmVyU3R5bGVzTW9kZWw7XG5cbiAgLyoqIEVkaXRvci1jb25maWd1cmFibGUgYmFja2dyb3VuZCAtIGZhbGxzIGJhY2sgdG8gdW5kZWZpbmVkIChsZXR0aW5nIHRoZSBjb21wb25lbnQncyBvd24gQ1NTXG4gICAqIGRlZmF1bHRzIHNob3cgdGhyb3VnaCB1bmNoYW5nZWQpIGZvciBleGlzdGluZyBwYWdlcyBzYXZlZCBiZWZvcmUgdGhpcyBzZWN0aW9uIHN1cHBvcnRlZFxuICAgKiBjdXN0b20gY29sb3JzLiAqL1xuICBnZXQgYmFja2dyb3VuZEluZm8oKTogQmFja2dyb3VuZE1vZGVsIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhPy5zdHlsZXM/LmJhY2tncm91bmQ7XG4gIH1cbiAgLyoqIE92ZXJyaWRlcyB0aGlzIGNvbXBvbmVudCdzIG93biAtLWNvbG9yLWFjY2VudC1ncmFkaWVudCBDU1MgdmFyaWFibGUgKHNjb3BlZCB0byBpdHMgOmhvc3QsXG4gICAqIHNlZSBhcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5jc3MpIHdoZW4gYSBidXNpbmVzcyBoYXMgcGlja2VkIGEgY3VzdG9tIGFjY2VudCBjb2xvciAtXG4gICAqIG51bGwgd2hlbiB1bnNldCwgc28gdGhlIFtzdHlsZS4tLWNvbG9yLWFjY2VudC1ncmFkaWVudF0gYmluZGluZyByZW1vdmVzIHRoZSBpbmxpbmUgb3ZlcnJpZGVcbiAgICogZW50aXJlbHkgYW5kIHRoZSBDU1MgZGVmYXVsdCBzaG93cyB0aHJvdWdoLCByYXRoZXIgdGhhbiBmb3JjaW5nIGFuIGVtcHR5IHZhbHVlLiAqL1xuICBnZXQgYWNjZW50Q29sb3IoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YT8uc3R5bGVzPy5iYWNrZ3JvdW5kPy5hY2NlbnRDb2xvciB8fCBudWxsO1xuICB9XG5cbiAgZ2V0IGhvbWVWaXNpdENoYXJnZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ0hPTUVfVklTSVQnID8gKHRoaXMuYnVzaW5lc3NTZXR0aW5ncz8uaG9tZVZpc2l0Q2hhcmdlID8/IDApIDogMDtcbiAgfVxuICAvKiogUHJpY2UgZm9yIG9uZSByZXNvbHZlZC1saW5lIHNlcnZpY2UsIGxvb2tlZCB1cCBmcm9tIGBjYXJ0U2VydmljZXNgICh0aGUgc2VydmljZS1saXN0aW5nXG4gICAqIHNlbGVjdGlvbiwgd2hpY2ggY2FycmllcyBgcHJpY2VEZXRhaWxzYCkgc2luY2UgYHJlc29sdmVkTGluZXNbXS5zZXJ2aWNlc2Agb25seSBjYXJyaWVzIGlkK25hbWVcbiAgICogYmFjayBmcm9tIHRoZSBzbG90LXJlc29sdXRpb24gQVBJLiAqL1xuICBzZXJ2aWNlUHJpY2Uoc2VydmljZUlkOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNhcnRTZXJ2aWNlcy5maW5kKChzOiBhbnkpID0+IHMuc2VydmljZUlkID09PSBzZXJ2aWNlSWQpPy5wcmljZURldGFpbHM/LnByaWNlID8/IDA7XG4gIH1cbiAgbGluZVNlcnZpY2VUb3RhbChsaW5lOiBSZXNvbHZlZExpbmUpOiBudW1iZXIge1xuICAgIHJldHVybiAobGluZS5zZXJ2aWNlcyB8fCBbXSkucmVkdWNlKChzdW06IG51bWJlciwgczogYW55KSA9PiBzdW0gKyB0aGlzLnNlcnZpY2VQcmljZShzLmlkKSwgMCk7XG4gIH1cbiAgZ2V0IHNlcnZpY2VzU3VidG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZExpbmVzLnJlZHVjZSgoc3VtOiBudW1iZXIsIGw6IFJlc29sdmVkTGluZSkgPT4gc3VtICsgdGhpcy5saW5lU2VydmljZVRvdGFsKGwpLCAwKTtcbiAgfVxuICBnZXQgcmV2aWV3VG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zZXJ2aWNlc1N1YnRvdGFsICsgdGhpcy5ob21lVmlzaXRDaGFyZ2U7XG4gIH1cbiAgZ2V0IGJvb2tpbmdUb3RhbCgpOiBudW1iZXIge1xuICAgIHJldHVybiAodGhpcy5ib29raW5nR3JvdXA/LnRvdGFsUGF5YWJsZSA/PyAwKSArICh0aGlzLmJvb2tpbmdHcm91cD8uaG9tZVZpc2l0Q2hhcmdlID8/IDApO1xuICB9XG4gIGdldCBib29raW5nUGFpZCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmJvb2tpbmdHcm91cD8udG90YWxDb2xsZWN0ZWRBdEJvb2tpbmcgPz8gMDtcbiAgfVxuICBnZXQgYm9va2luZ0R1ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLm1heCgwLCB0aGlzLmJvb2tpbmdUb3RhbCAtIHRoaXMuYm9va2luZ1BhaWQpO1xuICB9XG5cbiAgbG9hZEJ1c2luZXNzU2V0dGluZ3MoKSB7XG4gICAgaWYgKCF0aGlzLmJ1c2luZXNzSWQpIHJldHVybjtcbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmdldEJ1c2luZXNzQXBwb2ludG1lbnRTZXR0aW5ncyh0aGlzLmJ1c2luZXNzSWQpLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuYnVzaW5lc3NTZXR0aW5ncyA9IHJlcztcbiAgICB9LCAoKSA9PiB7XG4gICAgICAvLyBOb24tZmF0YWwgLSB0aGUgcmV2aWV3IHN0ZXAganVzdCB3b24ndCBwcmV2aWV3IGEgaG9tZSB2aXNpdCBjaGFyZ2UgYW1vdW50LlxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgLy8gTG9naW4gaXMgcmVxdWlyZWQgYmVmb3JlIGVudGVyaW5nIHRoZSB3aXphcmQgYXQgYWxsIChub3QgbWlkLWZsb3csIGxpa2UgY2FydCdzXG4gICAgLy8gY2hlY2tvdXQtY29tbWl0IGdhdGUpIC0gdGhlIHdpemFyZCdzIHNlbGVjdGlvbnMgbGl2ZSBvbmx5IGluIGNvbXBvbmVudCBtZW1vcnksIHNvIGFcbiAgICAvLyByZWRpcmVjdC1hbmQtYmFjayBwYXJ0d2F5IHRocm91Z2ggd291bGQgc2lsZW50bHkgd2lwZSB3aGF0ZXZlciB0aGUgY3VzdG9tZXIgaGFkIGFscmVhZHlcbiAgICAvLyBwaWNrZWQuIENoZWNraW5nIGhlcmUsIGJlZm9yZSBhbnl0aGluZyBpcyBwaWNrZWQsIG1lYW5zIHRoZXJlJ3Mgbm90aGluZyB0byBsb3NlLiBTa2lwcGVkXG4gICAgLy8gaW4gYnVpbGRlciBlZGl0L3ByZXZpZXcgbW9kZSAoYGVkaXRgIGlzIHRydWUgd2hlbiBhIGJ1c2luZXNzIG93bmVyIGlzIGVkaXRpbmcgdGhlaXIgc2l0ZSxcbiAgICAvLyBub3QgYSByZWFsIGN1c3RvbWVyIHNlc3Npb24pIC0gdGhlIHNhbWUgZ3VhcmQgcGF0dGVybiB1c2VkIGVsc2V3aGVyZSBpbiB0aGlzIGNvZGViYXNlXG4gICAgLy8gKGUuZy4gQXV0aGVudGljYXRpb25SZXF1aXJlZENvbXBvbmVudCdzIG93biBzdWJtaXQgaGFuZGxlcnMpLlxuICAgIGlmICghdGhpcy5lZGl0ICYmICF0aGlzLnN0b3JhZ2VTZXJ2aWNlLmdldFVzZXIoKSAmJiAhdGhpcy5pc0FkbWluQm9va2luZykge1xuICAgICAgLy8gdGhpcy5kaWFsb2dSZWY/LmNsb3NlKCk7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9sb2dpbiddLCB7IHF1ZXJ5UGFyYW1zOiB7IHJlZGlyZWN0VG86IHRoaXMucm91dGVyLnVybCB9IH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmdldFNjcmVlblNpemUoKTtcbiAgICAvLyBQcmVmaWxsIENvbnRhY3QgRGV0YWlscyBmcm9tIHRoZSBsb2dnZWQtaW4gY3VzdG9tZXIncyBvd24gYWNjb3VudCAobmFtZS9lbWFpbC9waG9uZSBzdGF5XG4gICAgLy8gZWRpdGFibGUsIGUuZy4gZm9yIGJvb2tpbmcgb24gYmVoYWxmIG9mIHNvbWVvbmUgZWxzZSkgaW5zdGVhZCBvZiBhbHdheXMgc2hvd2luZyBhIGJsYW5rXG4gICAgLy8gZm9ybSAtIG1hdGNoZXMgQm9va0FwcG9pbnRtZW50Q29tcG9uZW50J3MgcGF0dGVybi4gU2tpcHBlZCBlbnRpcmVseSBmb3IgaXNBZG1pbkJvb2tpbmc6XG4gICAgLy8gc3RhZmYgYXJlbid0IGxvZ2dlZCBpbiBhcyB0aGUgY3VzdG9tZXIgdGhleSdyZSBib29raW5nIGZvciwgc28gdGhlcmUncyBubyBhY2NvdW50IGhlcmUgdG9cbiAgICAvLyByZWFkIC0gbGVhdmUgdGhlIGZvcm0gYmxhbmsgZm9yIG1hbnVhbCBlbnRyeSwgc2FtZSBhcyBiZWZvcmUgdGhpcyBwcmVmaWxsIGV4aXN0ZWQuXG4gICAgaWYgKCF0aGlzLmlzQWRtaW5Cb29raW5nKSB7XG4gICAgICB0aGlzLnVzZXJEZXRhaWxzID0gdGhpcy5zdG9yYWdlU2VydmljZS5nZXRVc2VyKCkgYXMgVXNlcjtcbiAgICAgIGlmICh0aGlzLnVzZXJEZXRhaWxzPy5jb250YWN0KSB7XG4gICAgICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLm5hbWUgPSB0aGlzLnVzZXJEZXRhaWxzLmNvbnRhY3QubmFtZSA/PyAnJztcbiAgICAgICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwucGhvbmVOdW1iZXIgPSB0aGlzLnVzZXJEZXRhaWxzLmNvbnRhY3QubW9iaWxlID8/ICcnO1xuICAgICAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5lbWFpbCA9IHRoaXMudXNlckRldGFpbHMuY29udGFjdC5lbWFpbCA/PyAnJztcbiAgICAgIH1cbiAgICAgIHRoaXMucmVmcmVzaERlZmF1bHRBZGRyZXNzKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnByZWZpbGxDb250YWN0KSB7XG4gICAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lID0gdGhpcy5wcmVmaWxsQ29udGFjdC5uYW1lID8/IHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLm5hbWU7XG4gICAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlciA9IHRoaXMucHJlZmlsbENvbnRhY3QucGhvbmVOdW1iZXIgPz8gdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwucGhvbmVOdW1iZXI7XG4gICAgfVxuICAgIC8vIFJldXNlZCBieSBnb0JhY2soKSBhbmQgYnkgdGhlIGRvbmUtc2NyZWVuJ3MgYWRtaW4tdnMtd2Vic2l0ZSBidXR0b24gYnJhbmNoIC0gdGhlIGFkbWluXG4gICAgLy8gcGFuZWwgbG9hZHMgdGhpcyBjb21wb25lbnQgdmlhIFZpZXdDb250YWluZXJSZWYgKG5vdCBhIHJvdXRlKSwgc28gaXQgY2FuJ3QgYmUgdG9sZCBhcGFydFxuICAgIC8vIGZyb20gdGhlIGxpdmUgd2Vic2l0ZSBieSBVUkw7IFJFUVVFU1RfRlJPTSBpcyB0aGUgZXhpc3RpbmcgZmxhZyB0aGUgYWRtaW4gc2hlbGwgYWxyZWFkeVxuICAgIC8vIHNldHMgZm9yIHRoaXMgcHVycG9zZS5cbiAgICB0aGlzLmlzQWRtaW5Db250ZXh0ID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJSRVFVRVNUX0ZST01cIikgPT09ICdFQ09NTUVSQ0UnO1xuICAgIHRoaXMucmVzZXRXaXphcmQoKTtcbiAgICB0aGlzLmxvYWRCdXNpbmVzc1NldHRpbmdzKCk7XG4gIH1cblxuICBpc0FkbWluQ29udGV4dDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIFJlc3RvcmVzIHRoZSB3aXphcmQgdG8gaXRzIHN0YXJ0IHN0YXRlIC0gdXNlZCBmb3IgaW5pdGlhbCBsb2FkIChuZ09uSW5pdCkgYW5kIGZvciBcIkJvb2tcbiAgLy8gQW5vdGhlclwiIG9uIHRoZSBkb25lIHNjcmVlbiwgc28gYSBzZWNvbmQgYm9va2luZyBkb2Vzbid0IGluaGVyaXQgdGhlIHByZXZpb3VzIG9uZSdzXG4gIC8vIHNlcnZpY2VzL3Nsb3QvYWRkcmVzcyBzZWxlY3Rpb25zLlxuICByZXNldFdpemFyZCgpIHtcbiAgICB0aGlzLmNhcnRTZXJ2aWNlcyA9IFtdO1xuICAgIHRoaXMucmVzb2x2ZWRMaW5lcyA9IFtdO1xuICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiA9IG51bGw7XG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlU3RyID0gJyc7XG4gICAgdGhpcy5ib29raW5nR3JvdXAgPSBudWxsO1xuICAgIHRoaXMuYXBpU3RhdHVzID0gZmFsc2U7XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMgPSAnJztcbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IGZhbHNlO1xuICAgIHRoaXMuYWNjZXNzZWRUYWJzID0geyBzZXJ2aWNlTGlzdGluZzogZmFsc2UsIGxvY2F0aW9uTGlzdGluZzogZmFsc2UsIHN0YWZmTGlzdGluZzogZmFsc2UgfTtcblxuICAgIC8vIEEgYnVzaW5lc3MgY2FuIHBpbiB0aGlzIHNlY3Rpb24gdG8gb25lIG1vZGUgdmlhIHNhdmVkIGNvbnRlbnQgY29uZmlnLiBUaGVyZSdzIG5vIGVkaXRvclxuICAgIC8vIFVJIHlldCB0byBzZXQgdGhpcyBmaWVsZCAodGhlIHNlY3Rpb24gY29udGVudC1lZGl0b3IgZG9lc24ndCBoYXZlIGEgbW9kZSBwaWNrZXIgYnVpbHQpIC1cbiAgICAvLyByZWFkaW5nIGl0IGhlcmUganVzdCBrZWVwcyB0aGUgY29tcG9uZW50IGZvcndhcmQtY29tcGF0aWJsZSBvbmNlIG9uZSBleGlzdHMuXG4gICAgY29uc3QgcGlubmVkTW9kZSA9ICh0aGlzLmRhdGE/LmNvbnRlbnQgYXMgYW55KT8ubW9kZTtcbiAgICBpZiAocGlubmVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyB8fCBwaW5uZWRNb2RlID09PSAnSE9NRV9WSVNJVCcgfHwgcGlubmVkTW9kZSA9PT0gJ1ZJREVPX0NBTEwnKSB7XG4gICAgICB0aGlzLm1vZGVQaW5uZWQgPSB0cnVlO1xuICAgICAgdGhpcy5zZWxlY3RNb2RlKHBpbm5lZE1vZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ21vZGVTZWxlY3Rpb24nO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICcxMCc7XG4gICAgfVxuICB9XG4gIHNjcmVlbldpZHRoOiBudW1iZXIgPSAwO1xuICBASG9zdExpc3RlbmVyKFwid2luZG93OiByZXNpemVcIiwgW1wiJGV2ZW50XCJdKVxuICBnZXRTY3JlZW5TaXplKCkge1xuICAgIHRoaXMuc2NyZWVuV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgfVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycpXG4gIGNsb3NlT25PdXRzaWRlQ2xpY2soKSB7XG4gICAgdGhpcy5zaG93Q2FsZW5kYXIgPSBmYWxzZTtcbiAgfVxuICBhY2Nlc3NlZFRhYnMgPSB7XG4gICAgc2VydmljZUxpc3Rpbmc6IGZhbHNlLFxuICAgIGxvY2F0aW9uTGlzdGluZzogZmFsc2UsXG4gICAgc3RhZmZMaXN0aW5nOiBmYWxzZVxuICB9XG4gIHNrZWxldG9uTG9hZGVyOiBib29sZWFuID0gZmFsc2U7XG4gIGJ1c2luZXNzTmFtZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdidXNpbmVzc05hbWUnKSA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdidXNpbmVzc05hbWUnKSA6IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYk5hbWUnKSA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdiTmFtZScpIDogJycpO1xuICBidXNpbmVzc0lkOiBhbnkgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYnVzaW5lc3NJZCcpID8gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2J1c2luZXNzSWQnKSA6IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYklkJykgPyBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYklkJykgOiAnJyk7XG4gIGFjdGl2ZUJ1dHRvbjogYm9vbGVhbiA9IGZhbHNlO1xuICBzZWxlY3RlZFRhYjogc3RyaW5nID0gJyc7XG4gIGJhcldpZHRoOiBzdHJpbmcgPSAnJztcbiAgc2hvd0NhbmNlbGxhdGlvblBvbGljeTogYm9vbGVhbiA9IGZhbHNlO1xuICBzaG93UmVkdWNpbmdQb2xpY3k6IGJvb2xlYW4gPSBmYWxzZTtcbiAgYnVzaW5lc3NTZXR0aW5nczogYW55ID0gbnVsbDtcblxuICBzZWxlY3RlZE1vZGU6IEJvb2tpbmdNb2RlID0gJ1NUT1JFX1ZJU0lUJztcbiAgbW9kZVBpbm5lZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIENhcnQgb2Ygc2VydmljZXMgcGlja2VkIGluIHNlcnZpY2VMaXN0aW5nIC0gY2xpY2tpbmcgYSBjYXJkIHRvZ2dsZXMgbWVtYmVyc2hpcC4gVGhpcyBpcyBhXG4gIC8vIHN0cmFpZ2h0Zm9yd2FyZCBzdXBlcnNldCBvZiB0aGUgb2xkIHNpbmdsZS1zZWxlY3RlZFNlcnZpY2UgYmVoYXZpb3I6IHdpdGggZXhhY3RseSBvbmVcbiAgLy8gc2VydmljZSBjbGlja2VkIGl0J3MgdGhlIGV4YWN0IHNhbWUgMi1jbGljayAoc2VsZWN0LCBjb250aW51ZSkgZmxvdyBhcyBiZWZvcmUuXG4gIGNhcnRTZXJ2aWNlczogYW55W10gPSBbXTtcbiAgcmVzb2x2ZWRMaW5lczogUmVzb2x2ZWRMaW5lW10gPSBbXTtcbiAgcmVzb2x2aW5nQ2FydDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIFByb2R1Y3RzIGFkZGVkIHRvIHRoZSBjYXJ0IGJlZm9yZSBlbnRlcmluZyB0aGUgd2l6YXJkIChlLmcuIFwiVHJ5IGF0IEhvbWVcIiBvbiBhIHByb2R1Y3RcbiAgLy8gcGFnZSkgLSBsb2FkZWQgZnJvbSB0aGUgbG9jYWwgYm9va2luZy1wcm9kdWN0LWNhcnQgb25jZSB0aGUgbW9kZSBpcyBrbm93bi5cbiAgcHJvZHVjdENhcnRJdGVtczogYW55W10gPSBbXTtcblxuICBzZWxlY3RlZExvY2F0aW9uOiBhbnk7XG4gIC8vIFRoZSBsb2dnZWQtaW4gY3VzdG9tZXIncyByZWFsIGFjY291bnQgLSBzYW1lIHNvdXJjZSBBZGRyZXNzQ29tcG9uZW50L0FkZHJlc3NMaXN0Q29tcG9uZW50XG4gIC8vIHVzZWQgYXQgcHJvZHVjdC1wdXJjaGFzZSBjaGVja291dCBhbmQgaW4gQm9va0FwcG9pbnRtZW50Q29tcG9uZW50LCBpbnN0ZWFkIG9mIGEgdHlwZWQtaW5cbiAgLy8gYWRkcmVzcyBmb3JtLiBOb3QgdXNlZCBmb3IgaXNBZG1pbkJvb2tpbmcsIHdoaWNoIGhhcyBubyBsb2dnZWQtaW4gY3VzdG9tZXIgYWNjb3VudCB0byByZWFkIC1cbiAgLy8gc2VlIGhvbWVWaXNpdEFkZHJlc3MgYmVsb3cgZm9yIHRoYXQgY2FzZS5cbiAgdXNlckRldGFpbHM6IFVzZXIgfCBudWxsID0gbnVsbDtcbiAgZGVmYXVsdEFkZHJlc3M6IEFkZHJlc3NEZXRhaWxzIHwgbnVsbCA9IG51bGw7XG4gIC8vIE1hbnVhbCBlbnRyeSwgdXNlZCBvbmx5IGZvciBpc0FkbWluQm9va2luZyAtIHN0YWZmIHR5cGluZyBhbiBhZGRyZXNzIG9uIHRoZSBjdXN0b21lcidzXG4gIC8vIGJlaGFsZiwgd2l0aCBubyBhY2NvdW50L3NhdmVkLWFkZHJlc3MtYm9vayB0byBzZWxlY3QgZnJvbS5cbiAgaG9tZVZpc2l0QWRkcmVzczogYW55ID0geyByZWNlaXZlck5hbWU6ICcnLCByZWNlaXZlclBob25lOiAnJywgYWRkcmVzc0xpbmUxOiAnJywgYWRkcmVzc0xpbmUyOiAnJywgY2l0eTogJycsIHN0YXRlOiAnJywgemlwQ29kZTogJycgfTtcbiAgaW5zdHJ1Y3Rpb25zOiBzdHJpbmcgPSAnJztcbiAgT2JqZWN0ID0gT2JqZWN0O1xuICBzaG93Q2FsZW5kYXIgPSBmYWxzZTtcbiAgc2VsZWN0ZWREYXRlOiBEYXRlIHwgbnVsbCA9IG51bGw7XG4gIHNlbGVjdGVkRGF0ZVN0ciA9ICcnO1xuXG4gIGJvb2tpbmdHcm91cDogYW55ID0gbnVsbDtcblxuICBkYXRlRmlsdGVyID0gKGQ6IERhdGUgfCBudWxsKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgZGF0ZSA9IChkIHx8IG5ldyBEYXRlKCkpO1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICB0b2RheS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgICByZXR1cm4gZGF0ZS5nZXRUaW1lKCkgPj0gdG9kYXkuZ2V0VGltZSgpO1xuICB9XG4gIHRvZ2dsZUNhbGVuZGFyKGV2ZW50PzogRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuc2hvd0NhbGVuZGFyID0gIXRoaXMuc2hvd0NhbGVuZGFyO1xuICB9XG5cbiAgb25EYXRlU2VsZWN0ZWQoZGF0ZTogYW55KSB7XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSBmYWxzZTtcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IGRhdGU7XG4gICAgdGhpcy5zZWxlY3RlZERhdGVTdHIgPSB0aGlzLmZvcm1hdERhdGUoZGF0ZSk7XG4gICAgdGhpcy5zaG93Q2FsZW5kYXIgPSBmYWxzZTtcbiAgICB0aGlzLnJlc29sdmVDYXJ0KCk7XG4gIH1cbiAgcHJpdmF0ZSBmb3JtYXREYXRlKGQ6IERhdGUpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRkID0gU3RyaW5nKGQuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IG1tID0gU3RyaW5nKGQuZ2V0TW9udGgoKSArIDEpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgeXl5eSA9IGQuZ2V0RnVsbFllYXIoKTtcbiAgICByZXR1cm4gYCR7ZGR9LSR7bW19LSR7eXl5eX1gO1xuICB9XG4gIHByaXZhdGUgdG9Jc29EYXRlKGQ6IERhdGUgfCBudWxsKTogc3RyaW5nIHtcbiAgICBjb25zdCBkYXRlID0gZCA/PyBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IHl5eXkgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgY29uc3QgbW0gPSBTdHJpbmcoZGF0ZS5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBkZCA9IFN0cmluZyhkYXRlLmdldERhdGUoKSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCR7eXl5eX0tJHttbX0tJHtkZH1UMDA6MDA6MDAuMDAwWmA7XG4gIH1cblxuICBzZWxlY3RNb2RlKG1vZGU6IEJvb2tpbmdNb2RlKSB7XG4gICAgdGhpcy5zZWxlY3RlZE1vZGUgPSBtb2RlO1xuICAgIHRoaXMubG9hZFByb2R1Y3RDYXJ0Rm9yTW9kZSgpO1xuICAgIHRoaXMuZ2V0QWxsU2VydmljZXMoKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWRQcm9kdWN0Q2FydEZvck1vZGUoKSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnKSB7XG4gICAgICB0aGlzLnByb2R1Y3RDYXJ0SXRlbXMgPSBbXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5wcm9kdWN0Q2FydEl0ZW1zID0gYXdhaXQgdGhpcy5ib29raW5nUHJvZHVjdENhcnRTZXJ2aWNlLmdldEl0ZW1zKHRoaXMuc2VsZWN0ZWRNb2RlIGFzIEJvb2tpbmdDYXJ0TW9kZSk7XG4gIH1cblxuICBzZWxlY3RTZXJ2aWNlKHNlcnZpY2U6IGFueSkge1xuICAgIGNvbnN0IGlkeCA9IHRoaXMuY2FydFNlcnZpY2VzLmZpbmRJbmRleCgoczogYW55KSA9PiBzLnNlcnZpY2VJZCA9PT0gc2VydmljZS5zZXJ2aWNlSWQpO1xuICAgIGlmIChpZHggPj0gMCkge1xuICAgICAgdGhpcy5jYXJ0U2VydmljZXMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICBzZXJ2aWNlLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2FydFNlcnZpY2VzLnB1c2goc2VydmljZSk7XG4gICAgICBzZXJ2aWNlLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0aGlzLmNhcnRTZXJ2aWNlcy5sZW5ndGggPiAwIHx8IHRoaXMucHJvZHVjdENhcnRJdGVtcy5sZW5ndGggPiAwO1xuICB9XG4gIHNlbGVjdExvY2F0aW9uKGxvY2F0aW9uOiBhbnkpIHtcbiAgICBsb2NhdGlvbi5zZWxlY3RlZCA9IHRydWU7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiAmJiBsb2NhdGlvbi5pZCAhPSB0aGlzLnNlbGVjdGVkTG9jYXRpb24uaWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbi5zZWxlY3RlZCA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uID0gbG9jYXRpb247XG4gIH1cblxuICBuZXh0U3RlcCgpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ3NlcnZpY2VMaXN0aW5nJykge1xuICAgICAgdGhpcy5hY2Nlc3NlZFRhYnMuc2VydmljZUxpc3RpbmcgPSB0cnVlO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnKSB7XG4gICAgICAgIHRoaXMuZ2V0QWxsTG9jYXRpb25zKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdvVG9EYXRlU2VsZWN0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdsb2NhdGlvbkxpc3RpbmcnKSB7XG4gICAgICB0aGlzLmFjY2Vzc2VkVGFicy5sb2NhdGlvbkxpc3RpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5nb1RvRGF0ZVNlbGVjdGlvbigpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnc3RhZmZMaXN0aW5nJykge1xuICAgICAgdGhpcy5hY2Nlc3NlZFRhYnMuc3RhZmZMaXN0aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuZmV0Y2hBbGxMaW5lU2xvdHMoKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ2RhdGVTZWxlY3Rpb24nKSB7XG4gICAgICB0aGlzLmNoZWNrUmVxdWlyZWRWYWx1ZXMoKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnY29udGFjdERldGFpbHMnO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc3MC41NydcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ2NvbnRhY3REZXRhaWxzJykge1xuICAgICAgdGhpcy5jaGVja1JlcXVpcmVkVmFsdWVzKCk7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3BheW1lbnRUYWInO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc4NS41NydcbiAgICB9XG4gIH1cbiAgcHJldmlvdXNTdGVwKCkge1xuICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdtb2RlU2VsZWN0aW9uJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnc2VydmljZUxpc3RpbmcnKSB7XG4gICAgICBpZiAoIXRoaXMubW9kZVBpbm5lZCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ21vZGVTZWxlY3Rpb24nO1xuICAgICAgICB0aGlzLmJhcldpZHRoID0gJzEwJztcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnbG9jYXRpb25MaXN0aW5nJykge1xuICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzZXJ2aWNlTGlzdGluZyc7XG4gICAgICB0aGlzLmJhcldpZHRoID0gJzE0LjI4JztcbiAgICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiA9IG51bGw7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdzdGFmZkxpc3RpbmcnKSB7XG4gICAgICB0aGlzLnJlc29sdmVkTGluZXMuZm9yRWFjaCgobDogUmVzb2x2ZWRMaW5lKSA9PiB7IGwuc2VsZWN0ZWRTdGFmZklkID0gdW5kZWZpbmVkOyBsLnNlbGVjdGVkU3RhZmZOYW1lID0gdW5kZWZpbmVkOyB9KTtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyAmJiB0aGlzLmFjY2Vzc2VkVGFicy5sb2NhdGlvbkxpc3RpbmcpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdsb2NhdGlvbkxpc3RpbmcnO1xuICAgICAgICB0aGlzLmJhcldpZHRoID0gJzI5LjI4JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xuICAgICAgICB0aGlzLmJhcldpZHRoID0gJzE0LjI4JztcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ2RhdGVTZWxlY3Rpb24nKSB7XG4gICAgICBjb25zdCBuZWVkc1N0YWZmUGljayA9IHRoaXMucmVzb2x2ZWRMaW5lcy5zb21lKChsOiBSZXNvbHZlZExpbmUpID0+ICEhbC5jYW5kaWRhdGVTdGFmZlBvb2w/Lmxlbmd0aCk7XG4gICAgICBpZiAobmVlZHNTdGFmZlBpY2spIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzdGFmZkxpc3RpbmcnO1xuICAgICAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnICYmIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZykge1xuICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2xvY2F0aW9uTGlzdGluZyc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMjkuMjgnO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xuICAgICAgICB0aGlzLmJhcldpZHRoID0gJzE0LjI4JztcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ2NvbnRhY3REZXRhaWxzJykge1xuICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdkYXRlU2VsZWN0aW9uJztcbiAgICAgIHRoaXMuYmFyV2lkdGggPSAnNTguNTcnO1xuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAncGF5bWVudFRhYicpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnY29udGFjdERldGFpbHMnO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc3MC41Nyc7XG4gICAgfVxuICB9XG4gIHNlcnZpY2VEYXRhOiBhbnlbXSA9IFtdO1xuICBnZXRBbGxTZXJ2aWNlcygpIHtcbiAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gdHJ1ZVxuICAgIGxldCBzZXJ2aWNlUGF5bG9hZDogYW55ID0ge1xuICAgICAgYnVzaW5lc3NJZDogdGhpcy5idXNpbmVzc0lkID8/IFwiXCIsXG4gICAgICBwYWdlTm86IDAsXG4gICAgICBzaXplOiAxMDBcbiAgICB9XG4gICAgdGhpcy5yZXN0U2VydmljZS5nZXRBbGxBcHBvaW50bWVudFNlcnZpY2Uoc2VydmljZVBheWxvYWQpLnN1YnNjcmliZShcbiAgICAgIChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gZmFsc2U7XG4gICAgICAgIGxldCBzZXJ2aWNlcyA9IChyZXMuY29udGVudCB8fCBbXSkuZmlsdGVyKChzZXJ2aWNlOiBhbnkpID0+IHNlcnZpY2UuYWN0aXZlID09PSB0cnVlKTtcbiAgICAgICAgLy8gYXZhaWxhYmxlT25saW5lL2hvbWVBcHBvaW50bWVudEF2YWlsYWJsZSBjb250cm9sIHdoYXQgYSBjdXN0b21lciBjYW4gc2VsZi1zZXJ2ZSBib29rIG9uXG4gICAgICAgIC8vIHRoZSBsaXZlIHdlYnNpdGUgLSB0aGV5IGRvbid0IGFwcGx5IHdoZW4gYSBzdGFmZiBtZW1iZXIgaXMgY3JlYXRpbmcgYSBib29raW5nIG9uIHRoZVxuICAgICAgICAvLyBjdXN0b21lcidzIGJlaGFsZiBmcm9tIHRoZSBhZG1pbiBwYW5lbC5cbiAgICAgICAgaWYgKCF0aGlzLmlzQWRtaW5Cb29raW5nKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnSE9NRV9WSVNJVCcpIHNlcnZpY2VzID0gc2VydmljZXMuZmlsdGVyKChzOiBhbnkpID0+IHMuaG9tZUFwcG9pbnRtZW50QXZhaWxhYmxlKTtcbiAgICAgICAgICBpZiAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdWSURFT19DQUxMJykgc2VydmljZXMgPSBzZXJ2aWNlcy5maWx0ZXIoKHM6IGFueSkgPT4gcy52aWRlb0NhbGxBdmFpbGFibGUpO1xuICAgICAgICB9XG4gICAgICAgIHNlcnZpY2VzLmZvckVhY2goKHNlcnZpY2U6IGFueSkgPT4gc2VydmljZS5zZWxlY3RlZCA9IGZhbHNlKTtcbiAgICAgICAgdGhpcy5zZXJ2aWNlRGF0YSA9IHNlcnZpY2VzO1xuICAgICAgICB0aGlzLmNhcnRTZXJ2aWNlcyA9IFtdO1xuICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3NlcnZpY2VMaXN0aW5nJztcbiAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcxNC4yOCc7XG4gICAgICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdGhpcy5wcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDA7XG4gICAgICB9LFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcbiAgICAgIH1cbiAgICApO1xuICB9XG4gIGxvY2F0aW9uRGF0YTogYW55W10gPSBbXTtcbiAgZ2V0QWxsTG9jYXRpb25zKCkge1xuICAgIHRoaXMubG9hZGVyID0gdHJ1ZTtcbiAgICB0aGlzLmxvY2F0aW9uRGF0YSA9IFtdO1xuICAgIGxldCBwYXlsb2FkID0geyBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQgPz8gXCJcIiB9XG4gICAgdGhpcy5yZXN0U2VydmljZS5nZXRBbGxTdG9yZXMocGF5bG9hZCkuc3Vic2NyaWJlKFxuICAgICAgKHJlczogYW55KSA9PiB7XG4gICAgICAgIGlmIChyZXMuZGF0YS5kYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBsZXQgbG9jYXRpb25zID0gcmVzLmRhdGEuZGF0YS5maWx0ZXIoKHN0b3JlOiBhbnkpID0+IHsgcmV0dXJuIHN0b3JlLnN0YXR1cyA9PT0gJ0FDVElWRScgfSk7XG4gICAgICAgICAgLy8gTG9jYXRpb24taW50ZXJzZWN0aW9uIGNoZWNrIChkZXNpZ24gZG9jIMKnMmMpOiBvbmx5IG9mZmVyIHN0b3JlcyB0aGF0IGNhcnJ5IGV2ZXJ5XG4gICAgICAgICAgLy8gc2VydmljZSBjdXJyZW50bHkgaW4gdGhlIGNhcnQsIG5vdCBqdXN0IHRoZSBmaXJzdCBvbmUuXG4gICAgICAgICAgbG9jYXRpb25zID0gbG9jYXRpb25zLmZpbHRlcigobG9jYXRpb246IGFueSkgPT5cbiAgICAgICAgICAgIHRoaXMuY2FydFNlcnZpY2VzLmV2ZXJ5KChzOiBhbnkpID0+IHMuc3RvcmVJZHM/LmluY2x1ZGVzKGxvY2F0aW9uLmlkKSlcbiAgICAgICAgICApO1xuICAgICAgICAgIGxvY2F0aW9ucy5mb3JFYWNoKChsOiBhbnkpID0+IGwuc2VsZWN0ZWQgPSBmYWxzZSk7XG4gICAgICAgICAgdGhpcy5sb2NhdGlvbkRhdGEgPSBsb2NhdGlvbnM7XG4gICAgICAgICAgaWYgKHRoaXMubG9jYXRpb25EYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ05vIExvY2F0aW9uJywgZGV0YWlsOiAnVGhlc2Ugc2VydmljZXMgYXJlblxcJ3QgYWxsIGF2YWlsYWJsZSBhdCBvbmUgbG9jYXRpb24gLSByZW1vdmUgb25lIGFuZCBib29rIGl0IHNlcGFyYXRlbHknIH0pO1xuICAgICAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMubG9jYXRpb25EYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uID0gdGhpcy5sb2NhdGlvbkRhdGFbMF07XG4gICAgICAgICAgICB0aGlzLmxvYWRlciA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5hY2Nlc3NlZFRhYnMubG9jYXRpb25MaXN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmdvVG9EYXRlU2VsZWN0aW9uKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnbG9jYXRpb25MaXN0aW5nJztcbiAgICAgICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMjkuMjgnO1xuICAgICAgICAgICAgdGhpcy5hY2Nlc3NlZFRhYnMubG9jYXRpb25MaXN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ05vIExvY2F0aW9uJywgZGV0YWlsOiAnTm8gTG9jYXRpb24gYWRkZWQgZm9yIHNlbGVjdGVkIHNlcnZpY2UnIH0pO1xuICAgICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgZ29Ub0RhdGVTZWxlY3Rpb24oKSB7XG4gICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdkYXRlU2VsZWN0aW9uJztcbiAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IGZhbHNlO1xuICAgIHRoaXMucmVzb2x2ZWRMaW5lcyA9IFtdO1xuICB9XG5cbiAgc3RhZmZTZWFyY2hRdWVyeTogc3RyaW5nID0gJyc7XG4gIGdldCBmaWx0ZXJlZFN0YWZmKCk6IGFueVtdIHtcbiAgICBpZiAoIXRoaXMuc3RhZmZTZWFyY2hRdWVyeS50cmltKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0YWZmRGF0YTtcbiAgICB9XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnN0YWZmU2VhcmNoUXVlcnkudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gICAgcmV0dXJuIHRoaXMuc3RhZmZEYXRhLmZpbHRlcihzdGFmZiA9PlxuICAgICAgc3RhZmY/LnN0YWZmTmFtZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxdWVyeSlcbiAgICApO1xuICB9XG4gIHN0YWZmRGF0YTogYW55W10gPSBbXTtcblxuICByZXNvbHZlQ2FydCgpIHtcbiAgICBpZiAodGhpcy5jYXJ0U2VydmljZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBQdXJlIHByb2R1Y3Qtb25seSBsaW5lIChIb21lIFZpc2l0IC8gVmlkZW8gQ2FsbCB3aXRoIG5vIHNlcnZpY2VzIGF0dGFjaGVkKSAtIHJlc29sdXRpb25cbiAgICAgIC8vIGlzIGJ1aWx0IGFyb3VuZCBzZXJ2aWNlIHBvb2xzLCBzbyB0aGlzIG5lZWRzIGFuIGV4cGxpY2l0IHN0YWZmIHBpY2sgaW5zdGVhZC4gT25lIGxpbmUsXG4gICAgICAvLyBubyBzZXJ2aWNlcywganVzdCBhIHN0YWZmK3RpbWUgdG8gY2FycnkgdGhlIGZsYXQgcHJvZHVjdC12aWV3aW5nIGFsbG93YW5jZS5cbiAgICAgIHRoaXMucmVzb2x2ZWRMaW5lcyA9IFt7IHNlcnZpY2VzOiBbXSwgdG90YWxEdXJhdGlvbk1pbnV0ZXM6IDAsIHNsb3RzOiBbXSB9XTtcbiAgICAgIHRoaXMuZ2V0QWxsU3RhZmZGb3JQcm9kdWN0T25seUxpbmUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZXNvbHZpbmdDYXJ0ID0gdHJ1ZTtcbiAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkOiBhbnkgPSB7XG4gICAgICBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQsXG4gICAgICBtb2RlOiB0aGlzLnNlbGVjdGVkTW9kZSxcbiAgICAgIHN0b3JlSWQ6IHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnID8gdGhpcy5zZWxlY3RlZExvY2F0aW9uPy5pZCA6IHVuZGVmaW5lZCxcbiAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXG4gICAgICBzZXJ2aWNlSXRlbXM6IHRoaXMuY2FydFNlcnZpY2VzLm1hcCgoczogYW55KSA9PiAoeyBzZXJ2aWNlSWQ6IHMuc2VydmljZUlkIH0pKVxuICAgIH07XG4gICAgdGhpcy5yZXN0U2VydmljZS5yZXNvbHZlQ2FydChwYXlsb2FkKS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XG4gICAgICB0aGlzLnJlc29sdmluZ0NhcnQgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMucmVzb2x2ZWRMaW5lcyA9IChyZXMgfHwgW10pLm1hcCgobGluZTogYW55KSA9PiAoe1xuICAgICAgICBzZXJ2aWNlczogbGluZS5zZXJ2aWNlcyxcbiAgICAgICAgdG90YWxEdXJhdGlvbk1pbnV0ZXM6IGxpbmUudG90YWxEdXJhdGlvbk1pbnV0ZXMsXG4gICAgICAgIHN0YWZmSWQ6IGxpbmUuc3RhZmZJZCxcbiAgICAgICAgc3RhZmZOYW1lOiBsaW5lLnN0YWZmTmFtZSxcbiAgICAgICAgY2FuZGlkYXRlU3RhZmZQb29sOiBsaW5lLmNhbmRpZGF0ZVN0YWZmUG9vbCxcbiAgICAgICAgc2xvdHM6IFtdXG4gICAgICB9KSk7XG4gICAgICBjb25zdCBhbWJpZ3VvdXMgPSB0aGlzLnJlc29sdmVkTGluZXMuc29tZSgobDogUmVzb2x2ZWRMaW5lKSA9PiAhIWwuY2FuZGlkYXRlU3RhZmZQb29sPy5sZW5ndGgpO1xuICAgICAgLy8gQnVzaW5lc3NTZXR0aW5ncyNhbGxvd1N0YWZmU2VsZWN0aW9uIGRlZmF1bHRzIHRvIHRydWUgKHNlZSBkb2NzL3VuaWZpZWQtYXBwb2ludG1lbnQtam91cm5leS5tZFxuICAgICAgLy8gwqc1ZCkgLSBhIGJ1c2luZXNzIHRoYXQncyBuZXZlciB0b3VjaGVkIHRoaXMgc2V0dGluZyBrZWVwcyB0b2RheSdzIHBpY2tlciBiZWhhdmlvci5cbiAgICAgIGNvbnN0IGFsbG93UGljayA9IHRoaXMuYnVzaW5lc3NTZXR0aW5ncz8uYWxsb3dTdGFmZlNlbGVjdGlvbiAhPT0gZmFsc2U7XG4gICAgICBpZiAoYW1iaWd1b3VzICYmIGFsbG93UGljaykge1xuICAgICAgICB0aGlzLnN0YWZmU2VhcmNoUXVlcnkgPSAnJztcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzdGFmZkxpc3RpbmcnO1xuICAgICAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcbiAgICAgICAgLy8gUGlja2luZyBpcyBvcHRpb25hbCAtIENvbnRpbnVlIGlzIGVuYWJsZWQgaW1tZWRpYXRlbHkgZWl0aGVyIHdheSwgYW5kIHRoZSBiYWNrZW5kXG4gICAgICAgIC8vIGF1dG8tYXNzaWducyB0aGUgbGVhc3QtYnVzeSBlbGlnaWJsZSBzdGFmZiBmb3IgYW55IGxpbmUgbGVmdCB1bnBpY2tlZC5cbiAgICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5mZXRjaEFsbExpbmVTbG90cygpO1xuICAgICAgfVxuICAgIH0sIChlcnJvcjogYW55KSA9PiB7XG4gICAgICB0aGlzLnJlc29sdmluZ0NhcnQgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdVbmFibGUgdG8gY2hlY2sgYXZhaWxhYmlsaXR5JywgZGV0YWlsOiBlcnJvci5lcnJvcj8ubWVzc2FnZSA/PyAnUGxlYXNlIHRyeSBhZ2FpbicgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRBbGxTdGFmZkZvclByb2R1Y3RPbmx5TGluZSgpIHtcbiAgICAvLyBCdXNpbmVzc1NldHRpbmdzI2FsbG93U3RhZmZTZWxlY3Rpb24gb2ZmIC0gc2tpcCB0aGUgcGlja2VyIGVudGlyZWx5LCBzYW1lIGFzIHRoZVxuICAgIC8vIGFtYmlndW91cy1idXQtZGlzYWJsZWQgc2VydmljZS1saW5lIGNhc2UgaW4gcmVzb2x2ZUNhcnQoKS4gVGhlIGJhY2tlbmQgYXV0by1hc3NpZ25zIHRoZVxuICAgIC8vIGxlYXN0LWJ1c3kgZWxpZ2libGUgc3RhZmYgZm9yIHRoaXMgbGluZSBhdCBob2xkIHRpbWUgKHNlZSBkb2NzL3VuaWZpZWQtYXBwb2ludG1lbnQtam91cm5leS5tZCDCpzVkKS5cbiAgICBpZiAodGhpcy5idXNpbmVzc1NldHRpbmdzPy5hbGxvd1N0YWZmU2VsZWN0aW9uID09PSBmYWxzZSkge1xuICAgICAgdGhpcy5mZXRjaEFsbExpbmVTbG90cygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxvYWRlciA9IHRydWU7XG4gICAgY29uc3QgcGF5bG9hZCA9IHsgc2VydmljZUlkOiAnJywgc3RvcmVJZDogdGhpcy5zZWxlY3RlZExvY2F0aW9uPy5pZCA/PyAnJywgYnVzaW5lc3NJZDogdGhpcy5idXNpbmVzc0lkID8/ICcnIH07XG4gICAgdGhpcy5yZXN0U2VydmljZS5nZXRBbGxTdGFmZihwYXlsb2FkKS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XG4gICAgICB0aGlzLmxvYWRlciA9IGZhbHNlO1xuICAgICAgdGhpcy5zdGFmZkRhdGEgPSAocmVzIHx8IFtdKS5maWx0ZXIoKHN0YWZmOiBhbnkpID0+XG4gICAgICAgIHN0YWZmLmFjdGl2ZSA9PT0gdHJ1ZSAmJiBzdGFmZi5ib29raW5nQWxsb3dlZCAmJlxuICAgICAgICAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdIT01FX1ZJU0lUJyA/IHN0YWZmLmhvbWVWaXNpdENhcGFibGUgOiBzdGFmZi52aWRlb0NhbGxDYXBhYmxlKSk7XG4gICAgICB0aGlzLnN0YWZmRGF0YS5mb3JFYWNoKChzdGFmZjogYW55KSA9PiBzdGFmZi5zZWxlY3RlZCA9IGZhbHNlKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc3RhZmZMaXN0aW5nJztcbiAgICAgIHRoaXMuYmFyV2lkdGggPSAnNDMuNTcnO1xuICAgICAgLy8gT3B0aW9uYWwgLSBDb250aW51ZSBlbmFibGVzIGltbWVkaWF0ZWx5LCB0aGUgY3VzdG9tZXIgY2FuIHN0aWxsIHBpY2sgaWYgdGhleSB3YW50LlxuICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgIH0sICgpID0+IHsgdGhpcy5sb2FkZXIgPSBmYWxzZTsgfSk7XG4gIH1cblxuICBzZWxlY3RTdGFmZkZvclByb2R1Y3RPbmx5TGluZShzdGFmZjogYW55KSB7XG4gICAgdGhpcy5zdGFmZkRhdGEuZm9yRWFjaCgoczogYW55KSA9PiBzLnNlbGVjdGVkID0gZmFsc2UpO1xuICAgIHN0YWZmLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlc29sdmVkTGluZXNbMF0uc2VsZWN0ZWRTdGFmZklkID0gc3RhZmYuc3RhZmZJZDtcbiAgICB0aGlzLnJlc29sdmVkTGluZXNbMF0uc2VsZWN0ZWRTdGFmZk5hbWUgPSBzdGFmZi5zdGFmZk5hbWU7XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICB9XG5cbiAgc2VsZWN0U3RhZmZGb3JMaW5lKGxpbmU6IFJlc29sdmVkTGluZSwgc3RhZmY6IGFueSkge1xuICAgIGxpbmUuc2VsZWN0ZWRTdGFmZklkID0gc3RhZmYuaWQ7XG4gICAgbGluZS5zZWxlY3RlZFN0YWZmTmFtZSA9IHN0YWZmLm5hbWU7XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0aGlzLnJlc29sdmVkTGluZXMuZXZlcnkoKGw6IFJlc29sdmVkTGluZSkgPT4gISEobC5zdGFmZklkIHx8IGwuc2VsZWN0ZWRTdGFmZklkKSk7XG4gIH1cblxuICBmZXRjaEFsbExpbmVTbG90cygpIHtcbiAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2RhdGVTZWxlY3Rpb24nO1xuICAgIHRoaXMuYmFyV2lkdGggPSAnNTguNTcnO1xuICAgIGxldCBwZW5kaW5nID0gdGhpcy5yZXNvbHZlZExpbmVzLmxlbmd0aDtcbiAgICB0aGlzLnJlc29sdmVkTGluZXMuZm9yRWFjaCgobGluZTogUmVzb2x2ZWRMaW5lKSA9PiB7XG4gICAgICBjb25zdCBzdGFmZklkID0gbGluZS5zdGFmZklkIHx8IGxpbmUuc2VsZWN0ZWRTdGFmZklkO1xuICAgICAgY29uc3QgcGF5bG9hZDogYW55ID0ge1xuICAgICAgICBzdG9yZUlkOiB0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyA/IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbj8uaWQgOiB1bmRlZmluZWQsXG4gICAgICAgIHNlcnZpY2VJZHM6IGxpbmUuc2VydmljZXMubWFwKChzOiBhbnkpID0+IHMuaWQpLFxuICAgICAgICBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQsXG4gICAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXG4gICAgICAgIHN0YWZmSWQsXG4gICAgICAgIG1vZGU6IHRoaXMuc2VsZWN0ZWRNb2RlXG4gICAgICB9O1xuICAgICAgbGluZS5zbG90c0xvYWRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5yZXN0U2VydmljZS5nZXRCb29raW5nU2xvdHMocGF5bG9hZCkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xuICAgICAgICBsaW5lLnNsb3RzID0gKHJlcyB8fCBbXSkubWFwKCh2OiBzdHJpbmcpID0+ICh7IHNlbGVjdGVkOiBmYWxzZSwgdmFsdWU6IHYgfSkpO1xuICAgICAgICBsaW5lLnNsb3RzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICBwZW5kaW5nLS07XG4gICAgICAgIGlmIChwZW5kaW5nIDw9IDApIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcbiAgICAgIH0sICgpID0+IHtcbiAgICAgICAgbGluZS5zbG90c0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgcGVuZGluZy0tO1xuICAgICAgICBpZiAocGVuZGluZyA8PSAwKSB0aGlzLnNrZWxldG9uTG9hZGVyID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHNlbGVjdFNsb3RGb3JMaW5lKGxpbmU6IFJlc29sdmVkTGluZSwgc2xvdDogYW55KSB7XG4gICAgbGluZS5zbG90cy5mb3JFYWNoKChzOiBhbnkpID0+IHMuc2VsZWN0ZWQgPSBmYWxzZSk7XG4gICAgc2xvdC5zZWxlY3RlZCA9IHRydWU7XG4gICAgbGluZS5zZWxlY3RlZFNsb3QgPSBzbG90O1xuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdGhpcy5yZXNvbHZlZExpbmVzLmV2ZXJ5KChsOiBSZXNvbHZlZExpbmUpID0+ICEhbC5zZWxlY3RlZFNsb3QpO1xuICB9XG5cblxuICBjb252ZXJ0VG8yNEhvdXIodGltZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBbaG91ck1pbiwgbW9kaWZpZXJSYXddID0gdGltZS5zcGxpdCgnICcpO1xuICAgIGNvbnN0IG1vZGlmaWVyID0gbW9kaWZpZXJSYXcudG9VcHBlckNhc2UoKTsgLy8gXCJBTVwiIG9yIFwiUE1cIlxuICAgIGxldCBbaG91cnMsIG1pbnV0ZXNdID0gaG91ck1pbi5zcGxpdCgnOicpLm1hcChOdW1iZXIpO1xuXG4gICAgaWYgKG1vZGlmaWVyID09PSAnUE0nICYmIGhvdXJzIDwgMTIpIHtcbiAgICAgIGhvdXJzICs9IDEyO1xuICAgIH1cbiAgICBpZiAobW9kaWZpZXIgPT09ICdBTScgJiYgaG91cnMgPT09IDEyKSB7XG4gICAgICBob3VycyA9IDA7XG4gICAgfVxuXG4gICAgY29uc3QgaGggPSBob3Vycy50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgbW0gPSBtaW51dGVzLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCR7aGh9OiR7bW19ICR7bW9kaWZpZXJ9YDtcbiAgfVxuICBsb2FkZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNQcm9jZXNzaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIHRlcm1zQW5kQ29uZGl0aW9uczogYm9vbGVhbiA9IGZhbHNlO1xuICBjaGVja1JlcXVpcmVkVmFsdWVzKCkge1xuICAgIGNvbnN0IGlzRW1haWxWYWxpZCA9IHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLmVtYWlsICYmXG4gICAgICAvXlthLXowLTkuXyUrLV0rQFthLXowLTkuLV0rXFwuW2Etel17Miw0fSQvLnRlc3QodGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwuZW1haWwpO1xuXG4gICAgY29uc3QgYW55UG9saWN5ID0gdGhpcy5jYXJ0U2VydmljZXMuc29tZSgoczogYW55KSA9PiBzPy5jYW5jZWxsYXRpb25Qb2xpY3k/Lmxlbmd0aCA+IDAgfHwgcz8ucmVzY2hlZHVsZVBvbGljeT8ubGVuZ3RoID4gMCk7XG5cbiAgICBjb25zdCBhZGRyZXNzT2sgPSB0aGlzLnNlbGVjdGVkTW9kZSAhPT0gJ0hPTUVfVklTSVQnIHx8ICh0aGlzLmlzQWRtaW5Cb29raW5nXG4gICAgICA/ICEhKHRoaXMuaG9tZVZpc2l0QWRkcmVzcy5yZWNlaXZlck5hbWUgJiYgdGhpcy5ob21lVmlzaXRBZGRyZXNzLmFkZHJlc3NMaW5lMSAmJiB0aGlzLmhvbWVWaXNpdEFkZHJlc3MuY2l0eSAmJiB0aGlzLmhvbWVWaXNpdEFkZHJlc3MuemlwQ29kZSlcbiAgICAgIDogISF0aGlzLmRlZmF1bHRBZGRyZXNzKTtcblxuICAgIGlmICh0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lICYmXG4gICAgICBpc0VtYWlsVmFsaWQgJiZcbiAgICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyLmxlbmd0aCA9PT0gMTAgJiZcbiAgICAgIGFkZHJlc3NPaykge1xuICAgICAgaWYgKGFueVBvbGljeSkge1xuICAgICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMudGVybXNBbmRDb25kaXRpb25zID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVmcmVzaERlZmF1bHRBZGRyZXNzKCkge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLnVzZXJEZXRhaWxzPy5hZGRyZXNzRGV0YWlsc0xpc3QgPz8gW107XG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmRlZmF1bHRBZGRyZXNzID0gbnVsbDtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaWR4ID0gbGlzdC5maW5kSW5kZXgoKGE6IEFkZHJlc3NEZXRhaWxzKSA9PiBhLmRlZmF1bHQgPT09IHRydWUpO1xuICAgIHRoaXMuZGVmYXVsdEFkZHJlc3MgPSBpZHggIT09IC0xID8gbGlzdFtpZHhdIDogbGlzdFswXTtcbiAgICB0aGlzLmNoZWNrUmVxdWlyZWRWYWx1ZXMoKTtcbiAgfVxuXG4gIGNoYW5nZUFkZHJlc3MoKSB7XG4gICAgdGhpcy5tYXREaWFsb2cub3BlbihBZGRyZXNzTGlzdENvbXBvbmVudCwgeyBwYW5lbENsYXNzOiAnc2lkZXBhbmVsLWNsYXNzJywgZGF0YTogeyBhZGRyZXNzTGlzdDogdGhpcy51c2VyRGV0YWlscz8uYWRkcmVzc0RldGFpbHNMaXN0ID8/IFtdIH0gfSkuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy51c2VyRGV0YWlscyA9IHRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0VXNlcigpIGFzIFVzZXI7XG4gICAgICB0aGlzLnJlZnJlc2hEZWZhdWx0QWRkcmVzcygpO1xuICAgIH0pO1xuICB9XG5cbiAgYWRkQWRkcmVzcygpIHtcbiAgICB0aGlzLm1hdERpYWxvZy5vcGVuKEFkZHJlc3NDb21wb25lbnQsIHsgcGFuZWxDbGFzczogWydzaWRlcGFuZWwtY2xhc3MnLCAnYWRkcmVzcy1jbGFzcyddLCBkYXRhOiB7IGFkZHJlc3NMaXN0OiB0aGlzLnVzZXJEZXRhaWxzPy5hZGRyZXNzRGV0YWlsc0xpc3QgPz8gW10sIGVkaXRJbmRleDogLTEgfSB9KS5hZnRlckNsb3NlZCgpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnVzZXJEZXRhaWxzID0gdGhpcy5zdG9yYWdlU2VydmljZS5nZXRVc2VyKCkgYXMgVXNlcjtcbiAgICAgIHRoaXMucmVmcmVzaERlZmF1bHRBZGRyZXNzKCk7XG4gICAgfSk7XG4gIH1cblxuICBhcHBvaW50bWVudFBheWxvYWQ6IGFueSA9IHtcbiAgICBjdXN0b21lckRldGFpbDoge1xuICAgICAgbmFtZTogJycsXG4gICAgICBwaG9uZU51bWJlcjogJycsXG4gICAgICBlbWFpbDogJydcbiAgICB9XG4gIH1cbiAgYXBpU3RhdHVzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgY29uZmlybUJvb2tpbmcoKSB7XG4gICAgLy8gRGVmZW5zaXZlIHJlLWNoZWNrIChtaXJyb3JzIGNhcnQuY29tcG9uZW50LnRzJ3MgcHJvY2VlZFRvUGF5bWVudCgpIGd1YXJkKSAtIHRoZSBlbnRyeVxuICAgIC8vIGNoZWNrIGluIG5nT25Jbml0KCkgc2hvdWxkIG1ha2UgdGhpcyB1bnJlYWNoYWJsZSBpbiBwcmFjdGljZSwgYnV0IGEgbG9uZyBzbG90LXBpY2tpbmdcbiAgICAvLyBzZXNzaW9uIGNvdWxkIHN0aWxsIGxldCB0aGUgbG9naW4gc2Vzc2lvbiBleHBpcmUgYmVmb3JlIHRoZSBjdXN0b21lciByZWFjaGVzIHRoaXMgc3RlcC5cbiAgICBpZiAoIXRoaXMuZWRpdCAmJiAhdGhpcy5zdG9yYWdlU2VydmljZS5nZXRVc2VyKCkpIHtcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2xvZ2luJ10sIHsgcXVlcnlQYXJhbXM6IHsgcmVkaXJlY3RUbzogdGhpcy5yb3V0ZXIudXJsIH0gfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBsaW5lcyA9IHRoaXMucmVzb2x2ZWRMaW5lcy5tYXAoKGw6IFJlc29sdmVkTGluZSkgPT4ge1xuICAgICAgY29uc3Qgc2xvdCA9IGwuc2VsZWN0ZWRTbG90O1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2VydmljZUlkczogbC5zZXJ2aWNlcy5tYXAoKHM6IGFueSkgPT4gcy5pZCksXG4gICAgICAgIHN0YWZmSWQ6IGwuc3RhZmZJZCB8fCBsLnNlbGVjdGVkU3RhZmZJZCxcbiAgICAgICAgc3RhcnRUaW1lOiBzbG90ID8gdGhpcy5jb252ZXJ0VG8yNEhvdXIoc2xvdC52YWx1ZSkuc2xpY2UoMCwgNSkgOiB1bmRlZmluZWRcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBob2xkUGF5bG9hZDogYW55ID0ge1xuICAgICAgYnVzaW5lc3NJZDogdGhpcy5idXNpbmVzc0lkLFxuICAgICAgbW9kZTogdGhpcy5zZWxlY3RlZE1vZGUsXG4gICAgICBzdG9yZUlkOiB0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyA/IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbj8uaWQgOiB1bmRlZmluZWQsXG4gICAgICBib29raW5nRGF0ZTogdGhpcy50b0lzb0RhdGUodGhpcy5zZWxlY3RlZERhdGUpLFxuICAgICAgY3VzdG9tZXJEZXRhaWw6IHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLFxuICAgICAgLy8gTmV2ZXIgdHJ1c3QgYSBzdHJheSBcInVzZXJcIiBjb29raWUgZm9yIGFuIGFkbWluLWNyZWF0ZWQgYm9va2luZyAtIHN0YWZmIGFyZW4ndCBsb2dnZWQgaW5cbiAgICAgIC8vIGFzIHRoZSBjdXN0b21lciB0aGV5J3JlIGJvb2tpbmcgZm9yLCBzbyB0aGlzIG11c3QgcmVzb2x2ZSBzZXJ2ZXItc2lkZSBmcm9tIHRoZSB0eXBlZFxuICAgICAgLy8gcGhvbmUgbnVtYmVyIGluc3RlYWQgKHNlZSBDdXN0b21lcklkZW50aXR5U2VydmljZSksIG5vdCB3aGF0ZXZlciBoYXBwZW5zIHRvIGJlIHNpdHRpbmdcbiAgICAgIC8vIGluIHRoaXMgYnJvd3NlcidzIHN0b3JhZ2UgKGUuZy4gbGVmdG92ZXIgZnJvbSB0ZXN0aW5nIHRoZSBsaXZlIHN0b3JlZnJvbnQpLlxuICAgICAgdXNlcklkOiB0aGlzLmlzQWRtaW5Cb29raW5nID8gdW5kZWZpbmVkIDogKHRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0VXNlcigpIGFzIGFueSk/LnVzZXJJZCxcbiAgICAgIGxpbmVzLFxuICAgICAgcHJvZHVjdExpbmVzOiB0aGlzLnByb2R1Y3RDYXJ0SXRlbXMubWFwKChwOiBhbnkpID0+IHRoaXMuYm9va2luZ1Byb2R1Y3RDYXJ0U2VydmljZS50b1Byb2R1Y3RMaW5lKHApKSxcbiAgICAgIGFkZHJlc3NEZXRhaWxzOiB0aGlzLnNlbGVjdGVkTW9kZSAhPT0gJ0hPTUVfVklTSVQnID8gdW5kZWZpbmVkIDpcbiAgICAgICAgdGhpcy5pc0FkbWluQm9va2luZyA/IHsgLi4udGhpcy5ob21lVmlzaXRBZGRyZXNzLCBpbnN0cnVjdGlvbnM6IHRoaXMuaW5zdHJ1Y3Rpb25zIH0gOlxuICAgICAgICB0aGlzLmRlZmF1bHRBZGRyZXNzID8ge1xuICAgICAgICAgIHJlY2VpdmVyTmFtZTogdGhpcy5kZWZhdWx0QWRkcmVzcy5yZWNlaXZlck5hbWUsXG4gICAgICAgICAgcmVjZWl2ZXJQaG9uZTogdGhpcy5kZWZhdWx0QWRkcmVzcy5yZWNlaXZlclBob25lLFxuICAgICAgICAgIGFkZHJlc3NMaW5lMTogdGhpcy5kZWZhdWx0QWRkcmVzcy5hZGRyZXNzTGluZTEsXG4gICAgICAgICAgY2l0eTogdGhpcy5kZWZhdWx0QWRkcmVzcy5jaXR5TmFtZSxcbiAgICAgICAgICBzdGF0ZTogdGhpcy5kZWZhdWx0QWRkcmVzcy5zdGF0ZU5hbWUsXG4gICAgICAgICAgemlwQ29kZTogdGhpcy5kZWZhdWx0QWRkcmVzcy56aXBDb2RlLFxuICAgICAgICAgIGluc3RydWN0aW9uczogdGhpcy5pbnN0cnVjdGlvbnNcbiAgICAgICAgfSA6IHVuZGVmaW5lZCxcbiAgICAgIC8vIFNraXBzIG9ubGluZSBkZXBvc2l0IGNvbGxlY3Rpb24gc2VydmVyLXNpZGUgKHNlZSBCb29raW5nR3JvdXBTZXJ2aWNlI2J1aWxkR3JvdXApIC0gYVxuICAgICAgLy8gc3RhZmYtY3JlYXRlZCBib29raW5nIGNhbid0IGNvbXBsZXRlIGEgQ2FzaGZyZWUgY2hlY2tvdXQgaW5saW5lIHRoZSB3YXkgdGhlIGxpdmUgc2l0ZVxuICAgICAgLy8gZG9lcywgc28gaXQgbXVzdCBuZXZlciBiZSByb3V0ZWQgdGhyb3VnaCB0aGUgcGF5bWVudCBnYXRld2F5OyBhbnkgYmFsYW5jZSBpcyBjb2xsZWN0ZWRcbiAgICAgIC8vIGluIHBlcnNvbiAvIHJlY29yZGVkIGxhdGVyIHZpYSB0aGUgaW52b2ljZSBpbnN0ZWFkLlxuICAgICAgYWRtaW5Cb29raW5nOiB0aGlzLmlzQWRtaW5Cb29raW5nIHx8IHRoaXMuaXNBZG1pbkNvbnRleHQsXG4gICAgfTtcblxuICAgIGNvbnN0IGlzQWRtaW4gPSB0aGlzLmlzQWRtaW5Cb29raW5nIHx8IHRoaXMuaXNBZG1pbkNvbnRleHQ7XG4gICAgdGhpcy5yZXN0U2VydmljZS5ob2xkQm9va2luZyhob2xkUGF5bG9hZCkuc3Vic2NyaWJlKChncm91cDogYW55KSA9PiB7XG4gICAgICB0aGlzLmJvb2tpbmdHcm91cCA9IGdyb3VwO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlICE9PSAnU1RPUkVfVklTSVQnICYmIHRoaXMucHJvZHVjdENhcnRJdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuYm9va2luZ1Byb2R1Y3RDYXJ0U2VydmljZS5jbGVhcih0aGlzLnNlbGVjdGVkTW9kZSBhcyBCb29raW5nQ2FydE1vZGUpO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0FkbWluICYmIGdyb3VwLnN0YXR1cyA9PT0gJ0hPTEQnICYmIGdyb3VwLnRvdGFsQ29sbGVjdGVkQXRCb29raW5nID4gMCkge1xuICAgICAgICAvLyBNdXN0IGFjdCBvbiB0aGlzIGltbWVkaWF0ZWx5IC0gdGhlIGhvbGQgZXhwaXJlcyBpbiAxMCBtaW51dGVzLlxuICAgICAgICB0aGlzLnJlc3RTZXJ2aWNlLmdlbmVyYXRlUGF5bWVudFRva2VuKGdyb3VwLmdyb3VwSWQpLnN1YnNjcmliZSgob3JkZXI6IGFueSkgPT4ge1xuICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdhcHBvaW50bWVudFBheW1lbnRJZCcsIG9yZGVyLnBnT3JkZXJJZCk7XG4gICAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLl9ldmVudFNlcnZpY2UuY2FzaEZyZWVFdmVudC5lbWl0KHsgZGF0YTogeyBvcmRlclNpZ25hdHVyZTogb3JkZXIub3JkZXJTaWduYXR1cmUgfSB9KTtcbiAgICAgICAgfSwgKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdQYXltZW50IEZhaWxlZCcsIGRldGFpbDogZXJyb3IuZXJyb3I/Lm1lc3NhZ2UgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChpc0FkbWluICYmIGdyb3VwLnN0YXR1cyA9PT0gJ0hPTEQnKSB7XG4gICAgICAgIC8vIFVuZXhwZWN0ZWQ6IHRoZSBiYWNrZW5kIHNob3VsZCBoYXZlIGF1dG8tY29uZmlybWVkIHRoaXMgYWRtaW4gYm9va2luZyB3aXRoIHplcm9cbiAgICAgICAgLy8gZGVwb3NpdC4gU3VyZmFjZSBhbiBlcnJvciByYXRoZXIgdGhhbiBzaWxlbnRseSBzaG93aW5nIHN1Y2Nlc3MgZm9yIGEgYm9va2luZyB0aGF0J3NcbiAgICAgICAgLy8gc3RpbGwgZXhwaXJpbmcgdW5jb25maXJtZWQuXG4gICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdCb29raW5nIEZhaWxlZCcsIGRldGFpbDogJ1RoaXMgYm9va2luZyByZXF1aXJlcyBhIGRlcG9zaXQgYW5kIGNvdWxkIG5vdCBiZSBhdXRvLWNvbmZpcm1lZC4gUGxlYXNlIHRyeSBhZ2FpbiBvciBjb250YWN0IHN1cHBvcnQuJyB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYXBpU3RhdHVzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzdGF0dXNUZW1wbGF0ZSc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTAwJztcbiAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9LCAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuYXBpU3RhdHVzID0gZmFsc2U7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IHNldmVyaXR5OiAnZXJyb3InLCBzdW1tYXJ5OiAnQm9va2luZyBGYWlsZWQnLCBkZXRhaWw6IGVycm9yLmVycm9yPy5tZXNzYWdlIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ29CYWNrKCkge1xuICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcIlJFUVVFU1RfRlJPTVwiKSA9PT0gJ0VDT01NRVJDRScpIHtcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2FkbWluL2FwcG9pbnRtZW50cy9saXN0LWFwcG9pbnRtZW50cyddKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnJ10pXG4gICAgfVxuICB9XG5cbiAgZ29Ub015Qm9va2luZ3MoKSB7XG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvcHJvZmlsZSddLCB7IHF1ZXJ5UGFyYW1zOiB7IHRhYjogJ015IEJvb2tpbmdzJyB9IH0pO1xuICB9XG5cbiAgZ29Ub0xpc3RpbmcoKSB7XG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycnXSk7XG4gIH1cblxuICBnb1RvQXBwb2ludG1lbnRzTGlzdCgpIHtcbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9hZG1pbi9hcHBvaW50bWVudHMvbGlzdC1hcHBvaW50bWVudHMnXSk7XG4gIH1cblxuICBib29rQW5vdGhlcigpIHtcbiAgICB0aGlzLnJlc2V0V2l6YXJkKCk7XG4gIH1cbn1cbiIsIjxwLXRvYXN0IHBvc2l0aW9uPVwiYm90dG9tLXJpZ2h0XCIgW2Jhc2VaSW5kZXhdPVwiMTAwMDAwMDAwMDBcIiBbYXV0b1pJbmRleF09XCJ0cnVlXCJcbiAgICBbc2hvd1RyYW5zZm9ybU9wdGlvbnNdPVwic2NyZWVuV2lkdGggPCA0NzUgPyAndHJhbnNsYXRlWSgtMTAwJSknIDogJydcIj48L3AtdG9hc3Q+XG48c2VjdGlvbiBjbGFzcz1cIm1haW5fc2VjdGlvblwiIFtpZF09XCJkYXRhPy5pZFwiIHNpbXBvSG92ZXIgKGhvdmVyaW5nKT1cInNob3dFZGl0VGFicygkZXZlbnQpXCJcbiAgICBbc2ltcG9CYWNrZ3JvdW5kXT1cImJhY2tncm91bmRJbmZvXCIgW3N0eWxlLi0tY29sb3ItYWNjZW50LWdyYWRpZW50XT1cImFjY2VudENvbG9yXCI+XG4gICAgPGRpdiBbbmdDbGFzc109XCJ7J2hvdmVyX2VmZmVjdCc6IGVkaXR9XCIgKm5nSWY9XCJzaG93RWRpdG9yc1wiPlxuICAgICAgICA8c2ltcG8taG92ZXItZWxlbWVudHMgW2RhdGFdPVwiZGF0YVwiIFtpbmRleF09XCJpbmRleFwiIFtlZGl0T3B0aW9uc109XCJlZGl0XCI+PC9zaW1wby1ob3Zlci1lbGVtZW50cz5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibWFpbl9oZWFkZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmFjay1idG4gZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgYWxpZ24taXRlbXMtY2VudGVyIGN1cnNvci1wb2ludGVyIGdhcC0yIG1iLTNcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJnb0JhY2soKVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9iYWNrc3BhY2U8L21hdC1pY29uPjxzcGFuICpuZ0lmPVwic2NyZWVuV2lkdGggPiA0NzVcIj5CYWNrIHRvIEhvbWU8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItdGl0bGVcIj5cbiAgICAgICAgICAgICAgICA8aDE+Qm9vayBOZXcgQXBwb2ludG1lbnQ8L2gxPlxuICAgICAgICAgICAgICAgIDxwPnt7YnVzaW5lc3NOYW1lID8/IFwiTi9BXCIgfX08L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhclwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWZpbGxcIiBbc3R5bGUud2lkdGhdPVwiYmFyV2lkdGggKyAnJSdcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm1haW5fYm9keSB3LTEwMCBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdtb2RlU2VsZWN0aW9uJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1vZGVTZWxlY3Rpb25cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ3NlcnZpY2VMaXN0aW5nJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFza2VsZXRvbkxvYWRlclwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzZXJ2aWNlTGlzdGluZ1wiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdsb2NhdGlvbkxpc3RpbmcnXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9jYXRpb25MaXN0aW5nXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdzdGFmZkxpc3RpbmcnXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic3RhZmZMaXN0aW5nXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdkYXRlU2VsZWN0aW9uJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRhdGVTZWxlY3Rpb25cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYj09PSdjb250YWN0RGV0YWlscydcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb250YWN0RGV0YWlsc1wiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiPT09J3BheW1lbnRUYWInXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicGF5bWVudFRhYlwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiPT09J3N0YXR1c1RlbXBsYXRlJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInN0YXR1c1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJtYWluX2Zvb3RlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAqbmdJZj1cInNlbGVjdGVkVGFiIT09J3N0YXR1c1RlbXBsYXRlJyAmJiBzZWxlY3RlZFRhYiE9PSdtb2RlU2VsZWN0aW9uJ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9vdGVyLWJ1dHRvbnNcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwieydqdXN0aWZ5LWNvbnRlbnQnOiBzZWxlY3RlZFRhYiAhPSAnc2VydmljZUxpc3RpbmcnID8gJ3NwYWNlLWJldHdlZW4nIDogJ2VuZCd9XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhY2stZm9vdGVyLWJ0biBjdXJzb3ItcG9pbnRlclwiIChjbGljayk9XCJwcmV2aW91c1N0ZXAoKVwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJzZWxlY3RlZFRhYiAhPSAnc2VydmljZUxpc3RpbmcnXCI+QmFjazwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjb250aW51ZS1idG5cIiBbZGlzYWJsZWRdPVwiIWFjdGl2ZUJ1dHRvblwiIChjbGljayk9XCJuZXh0U3RlcCgpXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNlbGVjdGVkVGFiIT0ncGF5bWVudFRhYidcIj57eyFsb2FkZXIgPyAnQ29udGludWUnIDogJ0xvYWRpbmcuLi4nfX08L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWV2ZW5seSBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWI9PT0ncGF5bWVudFRhYidcIiAoY2xpY2spPVwiY29uZmlybUJvb2tpbmcoKVwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsncGF5LW5vdy1idG4nIDogYm9va2luZ0dyb3VwPy50b3RhbENvbGxlY3RlZEF0Qm9va2luZyA+IDAgfHwgIWJvb2tpbmdHcm91cCwnY29tcGxldGVfYm9va2luZycgOiBib29raW5nR3JvdXAgJiYgIWJvb2tpbmdHcm91cD8udG90YWxDb2xsZWN0ZWRBdEJvb2tpbmd9XCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzMwNDAxMmMxNzUzNDQwMDg3OTk2QmFja2dyb3VuZC5wbmdcIj5cbiAgICAgICAgICAgICAgICB7e2lzUHJvY2Vzc2luZyA/ICdQbGVhc2Ugd2FpdC4uLicgOiAnQ29uZmlybSBCb29raW5nJ319XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L3NlY3Rpb24+XG5cbjxuZy10ZW1wbGF0ZSAjbW9kZVNlbGVjdGlvbj5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBzZXJ2aWNlX3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2Utc2VsZWN0aW9uXCI+XG4gICAgICAgICAgICA8aDI+SG93IHdvdWxkIHlvdSBsaWtlIHRoaXM/PC9oMj5cbiAgICAgICAgICAgIDxwPkNob29zZSBob3cgeW91J2QgbGlrZSB0byBiZSBzZXJ2ZWQ8L3A+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZXMtZ3JpZFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWNhcmRcIiAoY2xpY2spPVwic2VsZWN0TW9kZSgnU1RPUkVfVklTSVQnKVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWljb25cIj48bWF0LWljb24+c3RvcmVmcm9udDwvbWF0LWljb24+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtdGl0bGVcIj5WaXNpdCBvdXIgU3RvcmU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtZGVzY3JpcHRpb25cIj5Db21lIHRvIHVzIGF0IG9uZSBvZiBvdXIgbG9jYXRpb25zPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY2FyZFwiIChjbGljayk9XCJzZWxlY3RNb2RlKCdIT01FX1ZJU0lUJylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pY29uXCI+PG1hdC1pY29uPmhvbWU8L21hdC1pY29uPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXRpdGxlXCI+V2UgY29tZSB0byB5b3U8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtZGVzY3JpcHRpb25cIj5BIHByb2Zlc3Npb25hbCB2aXNpdHMgeW91ciBhZGRyZXNzPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY2FyZFwiIChjbGljayk9XCJzZWxlY3RNb2RlKCdWSURFT19DQUxMJylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pY29uXCI+PG1hdC1pY29uPnZpZGVvY2FtPC9tYXQtaWNvbj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS10aXRsZVwiPlZpZGVvIGNvbnN1bHRhdGlvbjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kZXNjcmlwdGlvblwiPkNvbm5lY3Qgb3ZlciBhIHZpZGVvIGNhbGw8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjc2VydmljZUxpc3Rpbmc+XG4gICAgPGRpdiBjbGFzcz1cInctNjAgc2VydmljZV9zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXNlbGVjdGlvblwiPlxuICAgICAgICAgICAgPGgyPlNlbGVjdCBhIFNlcnZpY2U8L2gyPlxuICAgICAgICAgICAgPHA+Q2hvb3NlIHRoZSBzZXJ2aWNlKHMpIHlvdSdkIGxpa2UgdG8gYm9vazxzcGFuICpuZ0lmPVwiY2FydFNlcnZpY2VzLmxlbmd0aCA+IDBcIj4g4oCUIHt7Y2FydFNlcnZpY2VzLmxlbmd0aH19IHNlbGVjdGVkPC9zcGFuPjwvcD5cbiAgICAgICAgICAgIDxwICpuZ0lmPVwicHJvZHVjdENhcnRJdGVtcy5sZW5ndGggPiAwXCIgY2xhc3M9XCJjYXJ0LWhpbnRcIj57e3Byb2R1Y3RDYXJ0SXRlbXMubGVuZ3RofX0gcHJvZHVjdChzKSBhbHJlYWR5IGluIHlvdXIgY2FydCDigJQgeW91IGNhbiBjb250aW51ZSB3aXRob3V0IHBpY2tpbmcgYSBzZXJ2aWNlLjwvcD5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2VzLWdyaWRcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzZXJ2aWNlIG9mIHNlcnZpY2VEYXRhXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJcIiAoY2xpY2spPVwic2VsZWN0U2VydmljZShzZXJ2aWNlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzZXJ2aWNlLWNhcmQtc2VsZWN0ZWQnIDogc2VydmljZT8uc2VsZWN0ZWQsICdzZXJ2aWNlLWNhcmQnOiAhc2VydmljZT8uc2VsZWN0ZWQgfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIiBzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWljb25cIj48bWF0LWljb24+cGVyc29uX291dGxpbmU8L21hdC1pY29uPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtdGl0bGVcIj57e3NlcnZpY2U/Lm5hbWUgPyBzZXJ2aWNlPy5uYW1lIDogJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXByaWNlXCI+4oK5e3tzZXJ2aWNlPy5wcmljZURldGFpbHM/LnByaWNlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZpY2U/LnByaWNlRGV0YWlscz8ucHJpY2UgOiAnTi9BJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kdXJhdGlvblwiPnt7c2VydmljZT8uZHVyYXRpb24gPyBzZXJ2aWNlPy5kdXJhdGlvbiA6ICdOL0EnfX0gbWluXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kZXNjcmlwdGlvblwiICpuZ0lmPVwic2VydmljZT8uZGVzY3JpcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3NlcnZpY2U/LmRlc2NyaXB0aW9uID8gc2VydmljZT8uZGVzY3JpcHRpb24gOiAnTi9BJ319XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJob21lLXZpc2l0XCIgKm5nSWY9XCJzZWxlY3RlZE1vZGUgPT09ICdTVE9SRV9WSVNJVCcgJiYgc2VydmljZT8uaG9tZUFwcG9pbnRtZW50QXZhaWxhYmxlXCI+PGltZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzk4MjEyNmMxNzU4NjI4ODYzMTI5ZnVybml0dXJlXzE2NDA2MTAzLnBuZ1wiPkhvbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWaXNpdCBBdmFpbGFibGU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlLW1pbmlcIiAqbmdJZj1cInNlcnZpY2VEYXRhLmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+aW52ZW50b3J5XzI8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8aDQ+Tm8gc2VydmljZXMgYXZhaWxhYmxlPC9oND5cbiAgICAgICAgICAgICAgICAgICAgPHAgKm5nSWY9XCJzZWxlY3RlZE1vZGUgPT09ICdIT01FX1ZJU0lUJ1wiPk5vIHNlcnZpY2VzIGFyZSBjdXJyZW50bHkgYXZhaWxhYmxlIGZvciBob21lIHZpc2l0cy48L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwic2VsZWN0ZWRNb2RlID09PSAnVklERU9fQ0FMTCdcIj5ObyBzZXJ2aWNlcyBhcmUgY3VycmVudGx5IGF2YWlsYWJsZSBmb3IgdmlkZW8gY2FsbHMuPC9wPlxuICAgICAgICAgICAgICAgICAgICA8cCAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJ1wiPlRoaXMgYnVzaW5lc3MgaGFzbid0IGFkZGVkIGFueSBzZXJ2aWNlcyB5ZXQuPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNsb2NhdGlvbkxpc3Rpbmc+XG4gICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uX3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlciBmbGV4LWNvbHVtbiBhbGlnbi1pdGVtcy1zdGFydFwiPlxuICAgICAgICAgICAgPGgxPkNob29zZSBMb2NhdGlvbjwvaDE+XG4gICAgICAgICAgICA8cD5TZWxlY3Qgd2hlcmUgeW91J2QgbGlrZSB0byByZWNlaXZlIHRoZSBzZXJ2aWNlPC9wPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24tbGlzdFwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgbG9jYXRpb24gb2YgbG9jYXRpb25EYXRhXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwic2VsZWN0TG9jYXRpb24obG9jYXRpb24pXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnbG9jYXRpb24tY2FyZC1zZWxlY3RlZCcgOiBsb2NhdGlvbj8uc2VsZWN0ZWQsICdsb2NhdGlvbi1jYXJkJzogIWxvY2F0aW9uPy5zZWxlY3RlZCB9XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24taW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1pY29uXCI+PGltZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjPVwiaHR0cHM6Ly9kMno5NDk3eHA4eGIxMi5jbG91ZGZyb250Lm5ldC9wcm9kLWltYWdlcy80MjcyMjZjMTc1ODYyOTE1Nzc1OHN0b3JlXzMxNzE1MTAucG5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWRldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMz57e2xvY2F0aW9uPy5zdG9yZU5hbWUgPyBsb2NhdGlvbj8uc3RvcmVOYW1lIDogJ04vQSd9fTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD57e2xvY2F0aW9uPy5hZGRyZXNzRGV0YWlscz8uYWRkcmVzc0xpbmV9fSwge3tsb2NhdGlvbj8uYWRkcmVzc0RldGFpbHM/LmNpdHl9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7bG9jYXRpb24/LmFkZHJlc3NEZXRhaWxzPy5zdGF0ZX19IHt7bG9jYXRpb24/LnBpbmNvZGV9fTwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlLW1pbmlcIiAqbmdJZj1cImxvY2F0aW9uRGF0YS5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24+c3RvcmVmcm9udDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPGg0Pk5vIGxvY2F0aW9ucyBhdmFpbGFibGU8L2g0PlxuICAgICAgICAgICAgICAgIDxwPlRoZXJlJ3Mgbm8gbG9jYXRpb24gYXZhaWxhYmxlIGZvciB0aGlzIHNlcnZpY2UgcmlnaHQgbm93LjwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjc3RhZmZMaXN0aW5nPlxuICAgIDxkaXYgY2xhc3M9XCJ3LTYwIG92ZXJmbG93LWhpZGRlbiBzdGFmZi1saXN0aW5nXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggdy0xMDAgaC0xMDBcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTEwMFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1oZWFkZXIgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8aDE+U2VsZWN0IFN0YWZmIE1lbWJlcjwvaDE+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwic3RhZmYtc3VidGl0bGUgbWItMFwiPkNob29zZSB5b3VyIHByZWZlcnJlZCBwcm9mZXNzaW9uYWwsIG9yIHNraXAgdG8gaGF2ZSB1cyBhc3NpZ24gdGhlIGJlc3QgYXZhaWxhYmxlIG9uZTwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWFyY2gtY29udGFpbmVyIG1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlYXJjaC1pbnB1dC13cmFwcGVyIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInNlYXJjaC1pY29uIG1lLTJcIj5zZWFyY2g8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJzZWFyY2gtaW5wdXQgYm9yZGVyLTAgZmxleC1ncm93LTFcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaCBzdGFmZiBtZW1iZXIgYnkgbmFtZS4uLlwiIFsobmdNb2RlbCldPVwic3RhZmZTZWFyY2hRdWVyeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY2xlYXItaWNvbiBjdXJzb3ItcG9pbnRlciBtcy0yXCIgKm5nSWY9XCJzdGFmZlNlYXJjaFF1ZXJ5XCIgKGNsaWNrKT1cInN0YWZmU2VhcmNoUXVlcnkgPSAnJ1wiPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIFB1cmUgcHJvZHVjdC1vbmx5IGxpbmU6IG9uZSBmbGF0IHN0YWZmIGxpc3QsIHNhbWUgYXMgdGhlIG9sZCBzaW5nbGUtc2VydmljZSBmbG93IC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1saXN0XCIgKm5nSWY9XCJjYXJ0U2VydmljZXMubGVuZ3RoID09PSAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHN0YWZmIG9mIGZpbHRlcmVkU3RhZmZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkIHJvdW5kZWQtMyBwLTNcIiAoY2xpY2spPVwic2VsZWN0U3RhZmZGb3JQcm9kdWN0T25seUxpbmUoc3RhZmYpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzdGFmZi1jYXJkLXNlbGVjdGVkJyA6IHN0YWZmPy5zZWxlY3RlZCwgJ3N0YWZmLWNhcmQnOiAhc3RhZmY/LnNlbGVjdGVkIH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiB3LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWF2YXRhciByb3VuZGVkLWNpcmNsZSBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXIgbWUtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7c3RhZmY/LnN0YWZmTmFtZS5zbGljZSgwLDIpLnRvVXBwZXJDYXNlKCl9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtZGV0YWlscyBmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInN0YWZmLW5hbWVcIj57eyhzdGFmZj8uc3RhZmZOYW1lID8gc3RhZmY/LnN0YWZmTmFtZSA6ICdOL0EnKSB8IHRpdGxlY2FzZX19PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInN0YWZmLXNwZWNpYWx0eVwiPnt7KGJ1c2luZXNzTmFtZSAmJiBidXNpbmVzc05hbWUgIT09ICdOL0EnKSA/IGJ1c2luZXNzTmFtZSA6ICdCb29raW5nIFNwZWNpYWxpc3QnfX08L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWxlY3Rpb24taW5kaWNhdG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hlY2ttYXJrLWNpcmNsZS1taW5pIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiIFtjbGFzcy5zZWxlY3RlZF09XCJzdGFmZj8uc2VsZWN0ZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJzdGFmZj8uc2VsZWN0ZWRcIj5jaGVjazwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbXB0eS1zdGF0ZS1taW5pXCIgKm5nSWY9XCJmaWx0ZXJlZFN0YWZmLmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmJhZGdlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxoND5ObyBzdGFmZiBhdmFpbGFibGU8L2g0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHA+VGhlcmUncyBubyBzdGFmZiBtZW1iZXIgYXZhaWxhYmxlIGZvciB0aGlzIHNlcnZpY2UgcmlnaHQgbm93LjwvcD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIEJ1bmRsZWQgY2FydDogb25lIHBvb2wgcGVyIGxpbmUgdGhhdCByZXNvbHV0aW9uIGNvdWxkbid0IGNvbGxhcHNlIHRvIGEgc2luZ2xlIHByb3ZpZGVyIC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjYXJ0U2VydmljZXMubGVuZ3RoID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtbGluZS1ncm91cCBtYi00XCIgKm5nRm9yPVwibGV0IGxpbmUgb2YgcmVzb2x2ZWRMaW5lc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxpbmUuY2FuZGlkYXRlU3RhZmZQb29sPy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XCJtYi0yXCI+Rm9yIHt7bGluZS5zZXJ2aWNlcy5sZW5ndGh9fSBzZXJ2aWNlKHMpOiB7eyAobGluZS5zZXJ2aWNlcyB8IHNsaWNlOjA6MykubGVuZ3RoID8gJycgOiAnJyB9fTxzcGFuICpuZ0Zvcj1cImxldCBzIG9mIGxpbmUuc2VydmljZXM7IGxldCBsYXN0ID0gbGFzdFwiPnt7cy5uYW1lfX17e2xhc3QgPyAnJyA6ICcsICd9fTwvc3Bhbj48L2g0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1saXN0IG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3RhZmYgb2YgbGluZS5jYW5kaWRhdGVTdGFmZlBvb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkIHJvdW5kZWQtMyBwLTNcIiAoY2xpY2spPVwic2VsZWN0U3RhZmZGb3JMaW5lKGxpbmUsIHN0YWZmKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc3RhZmYtY2FyZC1zZWxlY3RlZCcgOiBsaW5lLnNlbGVjdGVkU3RhZmZJZCA9PT0gc3RhZmYuaWQsICdzdGFmZi1jYXJkJzogbGluZS5zZWxlY3RlZFN0YWZmSWQgIT09IHN0YWZmLmlkIH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiB3LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWF2YXRhciByb3VuZGVkLWNpcmNsZSBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXIgbWUtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7c3RhZmY/Lm5hbWU/LnNsaWNlKDAsMik/LnRvVXBwZXJDYXNlKCl9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtZGV0YWlscyBmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInN0YWZmLW5hbWVcIj57eyhzdGFmZj8ubmFtZSA/IHN0YWZmPy5uYW1lIDogJ04vQScpIHwgdGl0bGVjYXNlfX08L2gzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0aW9uLWluZGljYXRvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoZWNrbWFyay1jaXJjbGUtbWluaSBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwibGluZS5zZWxlY3RlZFN0YWZmSWQgPT09IHN0YWZmLmlkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwibGluZS5zZWxlY3RlZFN0YWZmSWQgPT09IHN0YWZmLmlkXCI+Y2hlY2s8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktc3RhdGUtbWluaVwiICpuZ0lmPVwiIWxpbmUuY2FuZGlkYXRlU3RhZmZQb29sPy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YmFkZ2U8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoND5ObyBzdGFmZiBhdmFpbGFibGU8L2g0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPk5vIHN0YWZmIG1lbWJlciBpcyBhdmFpbGFibGUgZm9yIHt7bGluZS5zZXJ2aWNlcy5sZW5ndGh9fSBzZXJ2aWNlKHMpIGluIHRoaXMgbGluZS48L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2RhdGVTZWxlY3Rpb24+XG4gICAgPGRpdiBjbGFzcz1cInctNjAgZGF0ZV9zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3cganVzdGlmeS1jb250ZW50LWNlbnRlciBoLTEwMFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC0xMiBoLTEwMFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkYXRldGltZS1oZWFkZXIgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICA8aDE+U2VsZWN0IERhdGUgJiBUaW1lPC9oMT5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJkYXRldGltZS1zdWJ0aXRsZSBtYi0wXCI+Q2hvb3NlIHdoZW4geW91J2QgbGlrZSB5b3VyIGFwcG9pbnRtZW50PC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtNCBtYWluX2NvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsndy01MCcgOiBzY3JlZW5XaWR0aCA+IDQ3NSAsICd3LTEwMCc6c2NyZWVuV2lkdGggPCA0NzV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1jYXJkIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInNlY3Rpb24tdGl0bGVcIj5TZWxlY3QgRGF0ZTwvaDM+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItY29udGFpbmVyIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZGF0ZS1pbnB1dCBib3JkZXItMCByb3VuZGVkLTJcIiBwbGFjZWhvbGRlcj1cImRkLW1tLXl5eXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkRGF0ZVN0clwiIHJlYWRvbmx5IChjbGljayk9XCJ0b2dnbGVDYWxlbmRhcigkZXZlbnQpXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXMtMlwiIChjbGljayk9XCJ0b2dnbGVDYWxlbmRhcigkZXZlbnQpXCI+Y2FsZW5kYXJfdG9kYXk8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwb3NpdGlvbi1yZWxhdGl2ZVwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGVwaWNrZXItcG9wb3ZlclwiICpuZ0lmPVwic2hvd0NhbGVuZGFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNhbGVuZGFyIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkRGF0ZVwiIFtkYXRlRmlsdGVyXT1cImRhdGVGaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZENoYW5nZSk9XCJvbkRhdGVTZWxlY3RlZCgkZXZlbnQpXCIgY2xhc3M9XCJkYXRlcGlja2VyLWNhbGVuZGFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBPbmUgc2xvdC1waWNrZXIgcGVyIHJlc29sdmVkIGxpbmUsIHNpZGUgYnkgc2lkZSB3aGVuIHRoZXJlJ3MgbW9yZSB0aGFuIG9uZSAoZGVzaWduIGRvYyDCpzNiKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWVfc2VsZWN0aW9uXCIgW25nQ2xhc3NdPVwieyd3LTUwJyA6IHNjcmVlbldpZHRoID4gNDc1ICwgJ3ctMTAwJzpzY3JlZW5XaWR0aCA8IDQ3NX1cIiAqbmdJZj1cInJlc29sdmVkTGluZXMubGVuZ3RoIDw9IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLWNhcmQgY2FyZCBoLTEwMCByb3VuZGVkLTMgcC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPkF2YWlsYWJsZSBUaW1lczwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBnLTIgbWItNCBvdmVyZmxvdy1zY3JvbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFza2VsZXRvbkxvYWRlciAmJiByZXNvbHZlZExpbmVzWzBdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTRcIiAqbmdGb3I9XCJsZXQgdGltZSBvZiByZXNvbHZlZExpbmVzWzBdLnNsb3RzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdCByb3VuZGVkLTJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwidGltZS5zZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RTbG90Rm9yTGluZShyZXNvbHZlZExpbmVzWzBdLCB0aW1lKVwiPnt7dGltZSA/IHRpbWU/LnZhbHVlIDogJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIiAqbmdJZj1cInJlc29sdmVkTGluZXNbMF0uc2xvdHMubGVuZ3RoID09PSAwXCI+Tm8gc2xvdHMgYXZhaWxhYmxlIGZvciB0aGlzIGRhdGUuPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gTXVsdGktbGluZSBjYXNlOiBlYWNoIGxpbmUgZ2V0cyBpdHMgb3duIGZ1bGwtd2lkdGggY2FyZCB3aXRoIGEgc3RhZmYgaGVhZGVyIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTQgbWFpbl9jb250YWluZXIgZmxleC13cmFwXCIgKm5nSWY9XCJyZXNvbHZlZExpbmVzLmxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwXCIgKm5nRm9yPVwibGV0IGxpbmUgb2YgcmVzb2x2ZWRMaW5lc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tY2FyZCBjYXJkIHJvdW5kZWQtMyBwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+UHJvZmVzc2lvbmFsOiB7e2xpbmUuc3RhZmZOYW1lIHx8IGxpbmUuc2VsZWN0ZWRTdGFmZk5hbWUgfHwgJ1RvIGJlIGFzc2lnbmVkJ319PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTJcIiAqbmdJZj1cImxpbmUuc2VydmljZXMubGVuZ3RoXCI+PHNwYW4gKm5nRm9yPVwibGV0IHMgb2YgbGluZS5zZXJ2aWNlczsgbGV0IGxhc3QgPSBsYXN0XCI+e3tzLm5hbWV9fXt7bGFzdCA/ICcnIDogJywgJ319PC9zcGFuPjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IGctMiBtYi0yIG92ZXJmbG93LXNjcm9sbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxpbmUuc2xvdHNMb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTRcIiAqbmdGb3I9XCJsZXQgdGltZSBvZiBsaW5lLnNsb3RzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdCByb3VuZGVkLTJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwidGltZS5zZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RTbG90Rm9yTGluZShsaW5lLCB0aW1lKVwiPnt7dGltZSA/IHRpbWU/LnZhbHVlIDogJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIiAqbmdJZj1cImxpbmUuc2xvdHMubGVuZ3RoID09PSAwXCI+Tm8gc2xvdHMgYXZhaWxhYmxlIGZvciB0aGlzIGRhdGUuPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjY29udGFjdERldGFpbHM+XG4gICAgPGRpdiBjbGFzcz1cInctNjAgY29udGFjdF9zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb250YWN0LWhlYWRlciBtYi0yXCI+XG4gICAgICAgICAgICA8aDE+Q29udGFjdCBEZXRhaWxzPC9oMT5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY29udGFjdC1zdWJ0aXRsZSBtYi0wXCI+UHJvdmlkZSB5b3VyIGNvbnRhY3QgaW5mb3JtYXRpb248L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTMgZGV0YWlsc19jb250YWluZXIgZmxleC1jb2x1bW4gdy0xMDBcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsndy01MCcgOiBzZWxlY3RlZE1vZGUgPT09ICdIT01FX1ZJU0lUJywgJ3ctMTAwJyA6IHNlbGVjdGVkTW9kZSAhPT0gJ0hPTUVfVklTSVQnfVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1zZWN0aW9uIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPlBlcnNvbmFsIEluZm9ybWF0aW9uPC9oMz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVsbCBOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVxdWlyZWQtYXN0ZXJpc2tcIj4qPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiY2hlY2tSZXF1aXJlZFZhbHVlcygpXCIgc2ltcG9MZXR0ZXJzT25seT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbWFpbCBBZGRyZXNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVxdWlyZWQtYXN0ZXJpc2tcIj4qPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJlbWFpbFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJhcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwuZW1haWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuPVwiXlthLXowLTkuXyUrLV0rQFthLXowLTkuLV0rXFwuW2Etel17Miw0fSRcIiAjZW1haWxGaWVsZD1cIm5nTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiZW1haWxcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQaG9uZSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXF1aXJlZC1hc3Rlcmlza1wiPio8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRlbFwiIGNsYXNzPVwiZm9ybS1jb250cm9sICByb3VuZGVkLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiIHNpbXBvTnVtYmVyc09ubHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtb2JpbGVfbnVtYmVyJyA6IGFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlci5sZW5ndGggIT0gMTB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBIb21lIFZpc2l0IGFkZHJlc3MuIEN1c3RvbWVyIGNvbnRleHQ6IHNhbWUgc2F2ZWQtYWRkcmVzcyBmbG93IGFzXG4gICAgICAgICAgICAgICAgICAgICBjaGVja291dC9Cb29rQXBwb2ludG1lbnRDb21wb25lbnQuIEFkbWluIGNvbnRleHQgKGlzQWRtaW5Cb29raW5nKTogbm9cbiAgICAgICAgICAgICAgICAgICAgIGxvZ2dlZC1pbiBjdXN0b21lciBhY2NvdW50IHRvIHJlYWQgYSBzYXZlZCBhZGRyZXNzIGJvb2sgZnJvbSwgc28gc3RhZmYgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgdGhlIGFkZHJlc3MgbWFudWFsbHkgaW5zdGVhZC4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIiAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ0hPTUVfVklTSVQnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXNlY3Rpb24gY2FyZCByb3VuZGVkLTMgcC00IGgtMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+SG9tZSBWaXNpdCBEZXRhaWxzPC9oMz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0FkbWluQm9va2luZzsgZWxzZSBtYW51YWxIb21lVmlzaXRBZGRyZXNzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNoaXBwaW5nLWluZm9cIiAqbmdJZj1cImRlZmF1bHRBZGRyZXNzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRyZXNzLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRyZXNzLW5hbWVcIj57e2RlZmF1bHRBZGRyZXNzPy5yZWNlaXZlck5hbWV9fSAoe3tkZWZhdWx0QWRkcmVzcz8uYWRkcmVzc1R5cGV9fSk8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRyZXNzLWRldGFpbHNcIj57e2RlZmF1bHRBZGRyZXNzPy5hZGRyZXNzTGluZTF9fSwge3tkZWZhdWx0QWRkcmVzcz8uY2l0eU5hbWV9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2RlZmF1bHRBZGRyZXNzPy5zdGF0ZU5hbWV9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vYmlsZS1udW1iZXJcIj5Nb2JpbGU6IHt7ZGVmYXVsdEFkZHJlc3M/LnJlY2VpdmVyUGhvbmV9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNoYW5nZS1hZGRyZXNzLWJ0biB3LTEwMFwiIChjbGljayk9XCJjaGFuZ2VBZGRyZXNzKClcIiAqbmdJZj1cImRlZmF1bHRBZGRyZXNzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQU5HRSBPUiBBREQgQUREUkVTU1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFkZExpbmtzXCIgKm5nSWY9XCIhZGVmYXVsdEFkZHJlc3NcIiAoY2xpY2spPVwiYWRkQWRkcmVzcygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1zLTJcIj5BZGQgYW4gYWRkcmVzczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI21hbnVhbEhvbWVWaXNpdEFkZHJlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+UmVjZWl2ZXIgTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnJlY2VpdmVyTmFtZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlJlY2VpdmVyIFBob25lPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZWxcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIHNpbXBvTnVtYmVyc09ubHkgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnJlY2VpdmVyUGhvbmVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5BZGRyZXNzIExpbmUgMTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLmFkZHJlc3NMaW5lMVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPkFkZHJlc3MgTGluZSAyIChvcHRpb25hbCk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIFsobmdNb2RlbCldPVwiaG9tZVZpc2l0QWRkcmVzcy5hZGRyZXNzTGluZTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPkNpdHk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIiBbKG5nTW9kZWwpXT1cImhvbWVWaXNpdEFkZHJlc3MuY2l0eVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlN0YXRlPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnN0YXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlBpbmNvZGU8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIHNpbXBvTnVtYmVyc09ubHkgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnppcENvZGVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0wIG10LTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5TcGVjaWFsIEluc3RydWN0aW9uczwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tdGV4dGFyZWEgcm91bmRlZC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJBbnkgc3BlY2lhbCBpbnN0cnVjdGlvbnMgZm9yIHRoZSBwcm9mZXNzaW9uYWwgKG9wdGlvbmFsKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaW5zdHJ1Y3Rpb25zXCI+PC90ZXh0YXJlYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljaWVzLWNvbnRhaW5lclwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJjYXJ0U2VydmljZXNbMF0/LmNhbmNlbGxhdGlvblBvbGljeT8ubGVuZ3RoID4gMCB8fCBjYXJ0U2VydmljZXNbMF0/LnJlc2NoZWR1bGVQb2xpY3k/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgIDxoMiBjbGFzcz1cInBvbGljaWVzLXRpdGxlXCI+UG9saWNpZXMgJiBUZXJtczwvaDI+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWl0ZW1zLWNvbnRhaW5lciBkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljeS1pdGVtIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNob3dDYW5jZWxsYXRpb25Qb2xpY3kgPSAhc2hvd0NhbmNlbGxhdGlvblBvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwicG9saWN5LXRpdGxlXCI+Q2FuY2VsbGF0aW9uIFBvbGljeTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWFycm93IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPjxtYXQtaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFzaG93Q2FuY2VsbGF0aW9uUG9saWN5XCI+a2V5Ym9hcmRfYXJyb3dfcmlnaHQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInNob3dDYW5jZWxsYXRpb25Qb2xpY3lcIj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbmNlbGxhdGlvbl9wb2xpY2llcyBkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTIgZnctNTAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2hvd0NhbmNlbGxhdGlvblBvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nRm9yPVwibGV0IHBvbGljeSBvZiBjYXJ0U2VydmljZXNbMF0/LmNhbmNlbGxhdGlvblBvbGljeVwiPiYjODIyNjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3BvbGljeX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWl0ZW0gZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd1JlZHVjaW5nUG9saWN5ID0gIXNob3dSZWR1Y2luZ1BvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwicG9saWN5LXRpdGxlXCI+UmVzY2hlZHVsaW5nIFBvbGljeTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWFycm93IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPjxtYXQtaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFzaG93UmVkdWNpbmdQb2xpY3lcIj5rZXlib2FyZF9hcnJvd19yaWdodDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwic2hvd1JlZHVjaW5nUG9saWN5XCI+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW5jZWxsYXRpb25fcG9saWNpZXMgZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0yIGZ3LTUwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dSZWR1Y2luZ1BvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nRm9yPVwibGV0IHBvbGljeSBvZiBjYXJ0U2VydmljZXNbMF0/LnJlc2NoZWR1bGVQb2xpY3lcIj4mIzgyMjY7IHt7cG9saWN5fX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjY2VwdGFuY2Utc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJjdXN0b20tY2hlY2tib3hcIiBbKG5nTW9kZWwpXT1cInRlcm1zQW5kQ29uZGl0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJhY2NlcHRhbmNlLXRleHRcIiBzdHlsZT1cIm1hcmdpbi1ib3R0b206MHB4ICFpbXBvcnRhbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEkgdW5kZXJzdGFuZCBhbmQgYWNjZXB0IHRoZSBjYW5jZWxsYXRpb24gJiByZXNjaGVkdWxpbmcgcG9saWNpZXMuXG4gICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjcGF5bWVudFRhYj5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBwYXltZW50X3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwIGgtMTAwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xMDAgZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBheW1lbnQtaGVhZGVyIG1iLTMgdy0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgxIHN0eWxlPVwiZm9udC1zaXplOjI0cHg7Zm9udC13ZWlnaHQ6IDYwMDtcIj5Cb29raW5nIFN1bW1hcnk8L2gxPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInBheW1lbnQtc3VidGl0bGUgbWItMFwiPlJldmlldyB5b3VyIGJvb2tpbmcgYmVmb3JlIGNvbmZpcm1pbmc8L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9va2luZy1zdW1tYXJ5LWNhcmRcIiBbbmdDbGFzc109XCJ7J3ctMTAwJyA6IHNjcmVlbldpZHRoIDwgNDc1LCd3LTUwJzpzY3JlZW5XaWR0aCA+IDQ3NX1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbGluZSBvZiByZXNvbHZlZExpbmVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJzdW1tYXJ5LXRpdGxlXCIgKm5nSWY9XCJyZXNvbHZlZExpbmVzLmxlbmd0aCA+IDFcIj5MaW5lIHt7aSArIDF9fTwvaDI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIiAqbmdGb3I9XCJsZXQgcyBvZiBsaW5lLnNlcnZpY2VzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj57e3MubmFtZX19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiBjbGFzcz1cImN1cnJlbmN5LXN5bWJvbFwiPuKCuTwvc3Bhbj57e3NlcnZpY2VQcmljZShzLmlkKX19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0lmPVwibGluZS5zdGFmZk5hbWUgfHwgbGluZS5zZWxlY3RlZFN0YWZmTmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+UHJvZmVzc2lvbmFsPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57e2xpbmUuc3RhZmZOYW1lIHx8IGxpbmUuc2VsZWN0ZWRTdGFmZk5hbWV9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIiAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+TG9jYXRpb248L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPnt7c2VsZWN0ZWRMb2NhdGlvbj8uc3RvcmVOYW1lID8/ICdOL0EnfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5EYXRlICYgVGltZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3tzZWxlY3RlZERhdGVTdHJ9fSBhdCB7e2xpbmUuc2VsZWN0ZWRTbG90Py52YWx1ZSA/PyAnTi9BJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb2R1Y3RDYXJ0SXRlbXMubGVuZ3RoID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgyIGNsYXNzPVwic3VtbWFyeS10aXRsZVwiPlByb2R1Y3RzPC9oMj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0Zvcj1cImxldCBwIG9mIHByb2R1Y3RDYXJ0SXRlbXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPnt7cC5pdGVtTmFtZX19IHh7e3AucXVhbnRpdHl9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+PHNwYW4gY2xhc3M9XCJjdXJyZW5jeS1zeW1ib2xcIj7igrk8L3NwYW4+e3socC5zZWxsaW5nUHJpY2UgPz8gcC5wcmljZSA/PyAwKSAqIChwLnF1YW50aXR5ID8/IDEpfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJzdW1tYXJ5LXRpdGxlXCI+UGF5bWVudDwvaDI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0lmPVwiaG9tZVZpc2l0Q2hhcmdlID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5Ib21lIHZpc2l0IGNoYXJnZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiBjbGFzcz1cImN1cnJlbmN5LXN5bWJvbFwiPuKCuTwvc3Bhbj57e2hvbWVWaXNpdENoYXJnZX19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+VG90YWw8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+PHNwYW4gY2xhc3M9XCJjdXJyZW5jeS1zeW1ib2xcIj7igrk8L3NwYW4+e3tyZXZpZXdUb3RhbH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNzdGF0dXNUZW1wbGF0ZT5cbiAgICA8ZGl2IGNsYXNzPVwiYm9va2luZy1jb25maXJtYXRpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInN1Y2Nlc3MtaWNvblwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoZWNrbWFyay1jaXJjbGVcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvODgxMjkzYzE3NTg2OTU1Nzg1MThzdWNjZXNzLmdpZlwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0xMDAgaC0xMDBcIiAqbmdJZj1cImFwaVN0YXR1c1wiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiaHR0cHM6Ly9kMno5NDk3eHA4eGIxMi5jbG91ZGZyb250Lm5ldC9wcm9kLWltYWdlcy8zMjUwMDBjMTc1ODY5NTU2NDUxOGZhaWwuZ2lmXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTEwMCBoLTEwMFwiICpuZ0lmPVwiIWFwaVN0YXR1c1wiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb25maXJtYXRpb24tY29udGVudFwiPlxuICAgICAgICAgICAgPGgxIGNsYXNzPVwiY29uZmlybWF0aW9uLXRpdGxlXCI+e3thcGlTdGF0dXMgPyAnQm9va2luZyBDb25maXJtZWQhJyA6ICdCb29raW5nIEZhaWxlZCd9fTwvaDE+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImNvbmZpcm1hdGlvbi1tZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAge3thcGlTdGF0dXMgPyAnWW91ciBhcHBvaW50bWVudCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYm9va2VkLic6J0ZhaWxlZCB0byBib29rIHlvdSBhcHBvaW50bWVudC4gUGxlYXNlXG4gICAgICAgICAgICAgICAgdHJ5IGFnYWluIGxhdGVyJ319XG4gICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgIDwhLS0gVmlkZW8gQ2FsbCBsaW5rLCB3aGVuIGFscmVhZHkgcHJlc2VudCBvbiB0aGUgY29uZmlybWVkIGdyb3VwIChhIHBhaWQgVmlkZW8gQ2FsbCdzXG4gICAgICAgICAgICAgICAgIGxpbmsgb25seSBhcHBlYXJzIG9uY2UgcGF5bWVudCB2ZXJpZmljYXRpb24gY29tcGxldGVzLCBoYW5kbGVkIGVsc2V3aGVyZSAtIHNlZVxuICAgICAgICAgICAgICAgICB2ZXJpZnktcGF5bWVudC5jb21wb25lbnQudHMsIG5vdCB0aGlzIHNjcmVlbikuIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZpZGVvLWNhbGwtbGluay1jYXJkIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzICYmIHNlbGVjdGVkTW9kZSA9PT0gJ1ZJREVPX0NBTEwnICYmIGJvb2tpbmdHcm91cD8udmlkZW9DYWxsTGlua1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLWNhcmRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZGV0YWlscy10aXRsZVwiPllvdXIgVmlkZW8gQ2FsbCBMaW5rPC9oMz5cbiAgICAgICAgICAgICAgICAgICAgPGEgW2hyZWZdPVwiYm9va2luZ0dyb3VwLnZpZGVvQ2FsbExpbmtcIiB0YXJnZXQ9XCJfYmxhbmtcIj57e2Jvb2tpbmdHcm91cC52aWRlb0NhbGxMaW5rfX08L2E+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCB3LTEwMCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtY2FyZFwiPlxuICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJkZXRhaWxzLXRpdGxlXCI+QXBwb2ludG1lbnQgRGV0YWlsczwvaDM+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLXJvd1wiICpuZ0Zvcj1cImxldCBsaW5lIG9mIHJlc29sdmVkTGluZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+e3tsaW5lLnNlcnZpY2VzLmxlbmd0aCA/IChsaW5lLnNlcnZpY2VzWzBdLm5hbWUpIDogJ1Byb2R1Y3RzJ319PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57e3NlbGVjdGVkRGF0ZVN0cn19IGF0IHt7bGluZS5zZWxlY3RlZFNsb3Q/LnZhbHVlID8/ICdOL0EnfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggdy0xMDAgYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIiAqbmdJZj1cImFwaVN0YXR1c1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLWNhcmRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZGV0YWlscy10aXRsZVwiPlBheW1lbnQ8L2gzPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIiAqbmdJZj1cImJvb2tpbmdHcm91cD8uaG9tZVZpc2l0Q2hhcmdlID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5Ib21lIHZpc2l0IGNoYXJnZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+4oK5e3tib29raW5nR3JvdXAuaG9tZVZpc2l0Q2hhcmdlfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+VG90YWw8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPuKCuXt7Ym9va2luZ1RvdGFsfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+UGFpZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+4oK5e3tib29raW5nUGFpZH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtcm93XCIgKm5nSWY9XCJib29raW5nRHVlID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5EdWU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPuKCuXt7Ym9va2luZ0R1ZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG9uZS1hY3Rpb25zIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0FkbWluQ29udGV4dDsgZWxzZSBhZG1pbkRvbmVBY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZG9uZS1idG4gZG9uZS1idG4tcHJpbWFyeVwiIChjbGljayk9XCJnb1RvTXlCb29raW5ncygpXCI+VmlldyBteSBib29raW5nczwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImRvbmUtYnRuIGRvbmUtYnRuLXNlY29uZGFyeVwiIChjbGljayk9XCJnb1RvTGlzdGluZygpXCI+S2VlcCBzaG9wcGluZzwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjYWRtaW5Eb25lQWN0aW9ucz5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJkb25lLWJ0biBkb25lLWJ0bi1wcmltYXJ5XCIgKGNsaWNrKT1cImdvVG9BcHBvaW50bWVudHNMaXN0KClcIj5CYWNrIHRvIEFwcG9pbnRtZW50cyBMaXN0PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZG9uZS1idG4gZG9uZS1idG4tc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImJvb2tBbm90aGVyKClcIj5Cb29rIEFub3RoZXI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
803
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwb2ludG1lbnQtYm9va2luZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaW1wby11aS9zcmMvbGliL3NlY3Rpb25zL2FwcG9pbnRtZW50LWZvcm0vYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nL2FwcG9pbnRtZW50LWJvb2tpbmcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2ltcG8tdWkvc3JjL2xpYi9zZWN0aW9ucy9hcHBvaW50bWVudC1mb3JtL2FwcG9pbnRtZW50LWJvb2tpbmcvYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0QsT0FBTyxFQUFhLGVBQWUsRUFBZ0IsTUFBTSwwQkFBMEIsQ0FBQztBQUlwRixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHekQsT0FBTyxFQUFFLG9CQUFvQixF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QUFFLG1CQUFtQiw4QkFBRSxjQUFjLDhCQUFFLGVBQWUsK0JBQUUsb0JBQW9CLCtEQUFFLG9CQUFvQiw4REFBRSxXQUFXLHlXQUFFLGNBQWMsZ0ZBQUUsc0JBQXNCLHlKQUFFLG1CQUFtQjs7NEZBSzFRLDJCQUEyQjtrQkFSdkMsU0FBUzsrQkFDRSwyQkFBMkIsY0FDekIsSUFBSSxXQUNQLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLHNCQUFzQixFQUFFLG1CQUFtQixDQUFDLGFBQzNRLENBQUMsY0FBYyxDQUFDOzswQkFheEIsUUFBUTt5Q0FJRixJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFNRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFFRyxjQUFjO3NCQUF0QixLQUFLO2dCQXlKTixhQUFhO3NCQURaLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBSzFDLG1CQUFtQjtzQkFEbEIsWUFBWTt1QkFBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE9uSW5pdCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDZGtEcmFnUGxhY2Vob2xkZXIgfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL2RyYWctZHJvcFwiO1xuaW1wb3J0IHsgTWF0SWNvbiB9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9pY29uXCI7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkXCI7XG5pbXBvcnQgeyBNYXREYXRlcGlja2VyTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2RhdGVwaWNrZXJcIjtcbmltcG9ydCB7IE1hdE5hdGl2ZURhdGVNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcbmltcG9ydCB7IE1hdERpYWxvZywgTWF0RGlhbG9nTW9kdWxlLCBNYXREaWFsb2dSZWYgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgUmVzdFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9yZXN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgRXZlbnRzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2V2ZW50cy5zZXJ2aWNlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IEJhbm5lckNvbnRlbnRNb2RlbCwgQmFubmVyU2VjdGlvbk1vZGVsIH0gZnJvbSAnLi4vLi4vYXBwb2ludG1lbnQtZm9ybS5tb2RlbCc7XG5pbXBvcnQgeyBCYWNrZ3JvdW5kTW9kZWwsIEJhbm5lclN0eWxlc01vZGVsIH0gZnJvbSAnLi4vLi4vLi4vLi4vc3R5bGVzL3N0eWxlLm1vZGVsJztcbmltcG9ydCB7IExldHRlcnNPbmx5RGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vLi4vLi4vZGlyZWN0aXZlL2xldHRlcnMtb25seS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTnVtYmVyc09ubHlEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi8uLi8uLi9kaXJlY3RpdmUvbnVtYmVycy1vbmx5LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBUb2FzdE1vZHVsZSB9IGZyb20gXCJwcmltZW5nL3RvYXN0XCI7XG5pbXBvcnQgeyBNZXNzYWdlU2VydmljZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IEJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UsIEJvb2tpbmdDYXJ0TW9kZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2Jvb2tpbmctcHJvZHVjdC1jYXJ0LnNlcnZpY2UnO1xuaW1wb3J0IHsgU3RvcmFnZVNlcnZpY2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvc3RvcmFnZS5zZXJ2aWNlJztcbmltcG9ydCB7IEFkZHJlc3NDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9lY29tbWVyY2Uvc2VjdGlvbnMvYWRkcmVzcy9hZGRyZXNzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBBZGRyZXNzTGlzdENvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uLy4uL2VsZW1lbnRzL2FkZHJlc3MtbGlzdC9hZGRyZXNzLWxpc3QuY29tcG9uZW50JztcbmltcG9ydCB7IEFkZHJlc3NEZXRhaWxzLCBVc2VyIH0gZnJvbSAnLi4vLi4vLi4vLi4vZWNvbW1lcmNlL3N0eWxlcy91c2VyLm1vZGFsJztcbmltcG9ydCBCYXNlU2VjdGlvbiBmcm9tICcuLi8uLi8uLi9CYXNlU2VjdGlvbic7XG5pbXBvcnQgeyBIb3ZlckRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uLy4uLy4uL2RpcmVjdGl2ZS9ob3Zlci1lbGVtZW50LWRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBIb3ZlckVsZW1lbnRzQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vY29tcG9uZW50cy9ob3Zlci1lbGVtZW50cy9ob3Zlci1lbGVtZW50cy5jb21wb25lbnQnO1xuaW1wb3J0IHsgQmFja2dyb3VuZERpcmVjdGl2ZSB9IGZyb20gJy4uLy4uLy4uLy4uL2RpcmVjdGl2ZS9iYWNrZ3JvdW5kLWRpcmVjdGl2ZSc7XG5cbnR5cGUgQm9va2luZ01vZGUgPSAnU1RPUkVfVklTSVQnIHwgJ0hPTUVfVklTSVQnIHwgJ1ZJREVPX0NBTEwnO1xuXG5pbnRlcmZhY2UgUmVzb2x2ZWRMaW5lIHtcbiAgc2VydmljZXM6IHsgaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nIH1bXTtcbiAgdG90YWxEdXJhdGlvbk1pbnV0ZXM6IG51bWJlcjtcbiAgc3RhZmZJZD86IHN0cmluZztcbiAgc3RhZmZOYW1lPzogc3RyaW5nO1xuICBjYW5kaWRhdGVTdGFmZlBvb2w/OiB7IGlkOiBzdHJpbmcsIG5hbWU6IHN0cmluZyB9W107XG4gIHNlbGVjdGVkU3RhZmZJZD86IHN0cmluZztcbiAgc2VsZWN0ZWRTdGFmZk5hbWU/OiBzdHJpbmc7XG4gIHNsb3RzOiBhbnlbXTtcbiAgc2VsZWN0ZWRTbG90PzogYW55O1xuICBzbG90c0xvYWRpbmc/OiBib29sZWFuO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzaW1wby1hcHBvaW50bWVudC1ib29raW5nJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0Nka0RyYWdQbGFjZWhvbGRlciwgQ29tbW9uTW9kdWxlLCBNYXRJY29uLCBNYXRGb3JtRmllbGRNb2R1bGUsIE1hdERhdGVwaWNrZXJNb2R1bGUsIEZvcm1zTW9kdWxlLCBNYXROYXRpdmVEYXRlTW9kdWxlLCBNYXRJbnB1dE1vZHVsZSwgTWF0RGlhbG9nTW9kdWxlLCBMZXR0ZXJzT25seURpcmVjdGl2ZSwgTnVtYmVyc09ubHlEaXJlY3RpdmUsIFRvYXN0TW9kdWxlLCBIb3ZlckRpcmVjdGl2ZSwgSG92ZXJFbGVtZW50c0NvbXBvbmVudCwgQmFja2dyb3VuZERpcmVjdGl2ZV0sXG4gIHByb3ZpZGVyczogW01lc3NhZ2VTZXJ2aWNlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2FwcG9pbnRtZW50LWJvb2tpbmcuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vYXBwb2ludG1lbnQtYm9va2luZy5jb21wb25lbnQuY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBBcHBvaW50bWVudEJvb2tpbmdDb21wb25lbnQgZXh0ZW5kcyBCYXNlU2VjdGlvbiBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVzdFNlcnZpY2U6IFJlc3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgX2V2ZW50U2VydmljZTogRXZlbnRzU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWVzc2FnZVNlcnZpY2U6IE1lc3NhZ2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYm9va2luZ1Byb2R1Y3RDYXJ0U2VydmljZTogQm9va2luZ1Byb2R1Y3RDYXJ0U2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JhZ2VTZXJ2aWNlOiBTdG9yYWdlU2VydmljZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBtYXREaWFsb2c6IE1hdERpYWxvZyxcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIHJlYWRvbmx5IGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPEFwcG9pbnRtZW50Qm9va2luZ0NvbXBvbmVudD5cbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuICBASW5wdXQoKSBkYXRhPzogQmFubmVyU2VjdGlvbk1vZGVsO1xuICBASW5wdXQoKSBpbmRleD86IG51bWJlcjtcbiAgY29udGVudD86IEJhbm5lckNvbnRlbnRNb2RlbDtcbiAgQElucHV0KCkgZWRpdD86IGJvb2xlYW47XG4gIC8qKiBTZXQgYnkgdGhlIGFkbWluIHBhbmVsJ3MgXCJCb29rIE5ldyBBcHBvaW50bWVudFwiIHRvb2wgLSBhIHN0YWZmIG1lbWJlciBjcmVhdGluZyBhIGJvb2tpbmcgb25cbiAgICogYSBjdXN0b21lcidzIGJlaGFsZiwgbm90IGEgbGl2ZSBjdXN0b21lciBzZWxmLXNlcnZpY2UgZmxvdy4gU3RpbGwgcmVzcGVjdHMgZXZlcnkgc2VydmljZSdzXG4gICAqIG1vZGUtY2FwYWJpbGl0eSBmbGFncyAoaG9tZUFwcG9pbnRtZW50QXZhaWxhYmxlL3ZpZGVvQ2FsbEF2YWlsYWJsZS9zdG9yZUlkcykgc2FtZSBhcyB0aGUgbGl2ZVxuICAgKiB3ZWJzaXRlLCBzaW5jZSB0aG9zZSBhcmUgYWJvdXQgd2hhdCBhIHNlcnZpY2UgY2FuIGFjdHVhbGx5IGJlIGRlbGl2ZXJlZCBhcywgbm90IHdobydzXG4gICAqIGFsbG93ZWQgdG8gYm9vayBpdDsgb25seSBza2lwcyB0aGUgbG9naW4gcmVxdWlyZW1lbnQgYW5kIGN1c3RvbWVyLWFjY291bnQgcHJlZmlsbC4gKi9cbiAgQElucHV0KCkgaXNBZG1pbkJvb2tpbmc/OiBib29sZWFuO1xuICBASW5wdXQoKSBkZWxldGU/OiBib29sZWFuO1xuICBASW5wdXQoKSBjdXN0b21DbGFzcz86IHN0cmluZztcbiAgQElucHV0KCkgbmV4dENvbXBvbmVudENvbG9yPzogQmFja2dyb3VuZE1vZGVsO1xuICAvKiogTGV0cyBhIGxhdW5jaGluZyBkaWFsb2cgKGUuZy4gdGhlIHZpZGVvLWNhbGwgcHJvZHVjdCBwaWNrZXIpIGNhcnJ5IG92ZXIgbmFtZS9waG9uZSBhbHJlYWR5IGNvbGxlY3RlZCwgc28gdGhlIGN1c3RvbWVyIGlzbid0IGFza2VkIHR3aWNlLiAqL1xuICBASW5wdXQoKSBwcmVmaWxsQ29udGFjdD86IHsgbmFtZT86IHN0cmluZywgcGhvbmVOdW1iZXI/OiBzdHJpbmcgfTtcbiAgc3R5bGVzPzogQmFubmVyU3R5bGVzTW9kZWw7XG5cbiAgLyoqIEVkaXRvci1jb25maWd1cmFibGUgYmFja2dyb3VuZCAtIGZhbGxzIGJhY2sgdG8gdW5kZWZpbmVkIChsZXR0aW5nIHRoZSBjb21wb25lbnQncyBvd24gQ1NTXG4gICAqIGRlZmF1bHRzIHNob3cgdGhyb3VnaCB1bmNoYW5nZWQpIGZvciBleGlzdGluZyBwYWdlcyBzYXZlZCBiZWZvcmUgdGhpcyBzZWN0aW9uIHN1cHBvcnRlZFxuICAgKiBjdXN0b20gY29sb3JzLiAqL1xuICBnZXQgYmFja2dyb3VuZEluZm8oKTogQmFja2dyb3VuZE1vZGVsIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhPy5zdHlsZXM/LmJhY2tncm91bmQ7XG4gIH1cbiAgLyoqIE92ZXJyaWRlcyB0aGlzIGNvbXBvbmVudCdzIG93biAtLWNvbG9yLWFjY2VudC1ncmFkaWVudCBDU1MgdmFyaWFibGUgKHNjb3BlZCB0byBpdHMgOmhvc3QsXG4gICAqIHNlZSBhcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5jc3MpIHdoZW4gYSBidXNpbmVzcyBoYXMgcGlja2VkIGEgY3VzdG9tIGFjY2VudCBjb2xvciAtXG4gICAqIG51bGwgd2hlbiB1bnNldCwgc28gdGhlIFtzdHlsZS4tLWNvbG9yLWFjY2VudC1ncmFkaWVudF0gYmluZGluZyByZW1vdmVzIHRoZSBpbmxpbmUgb3ZlcnJpZGVcbiAgICogZW50aXJlbHkgYW5kIHRoZSBDU1MgZGVmYXVsdCBzaG93cyB0aHJvdWdoLCByYXRoZXIgdGhhbiBmb3JjaW5nIGFuIGVtcHR5IHZhbHVlLiAqL1xuICBnZXQgYWNjZW50Q29sb3IoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YT8uc3R5bGVzPy5iYWNrZ3JvdW5kPy5hY2NlbnRDb2xvciB8fCBudWxsO1xuICB9XG5cbiAgZ2V0IGhvbWVWaXNpdENoYXJnZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ0hPTUVfVklTSVQnID8gKHRoaXMuYnVzaW5lc3NTZXR0aW5ncz8uaG9tZVZpc2l0Q2hhcmdlID8/IDApIDogMDtcbiAgfVxuICAvKiogUHJpY2UgZm9yIG9uZSByZXNvbHZlZC1saW5lIHNlcnZpY2UsIGxvb2tlZCB1cCBmcm9tIGBjYXJ0U2VydmljZXNgICh0aGUgc2VydmljZS1saXN0aW5nXG4gICAqIHNlbGVjdGlvbiwgd2hpY2ggY2FycmllcyBgcHJpY2VEZXRhaWxzYCkgc2luY2UgYHJlc29sdmVkTGluZXNbXS5zZXJ2aWNlc2Agb25seSBjYXJyaWVzIGlkK25hbWVcbiAgICogYmFjayBmcm9tIHRoZSBzbG90LXJlc29sdXRpb24gQVBJLiAqL1xuICBzZXJ2aWNlUHJpY2Uoc2VydmljZUlkOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNhcnRTZXJ2aWNlcy5maW5kKChzOiBhbnkpID0+IHMuc2VydmljZUlkID09PSBzZXJ2aWNlSWQpPy5wcmljZURldGFpbHM/LnByaWNlID8/IDA7XG4gIH1cbiAgbGluZVNlcnZpY2VUb3RhbChsaW5lOiBSZXNvbHZlZExpbmUpOiBudW1iZXIge1xuICAgIHJldHVybiAobGluZS5zZXJ2aWNlcyB8fCBbXSkucmVkdWNlKChzdW06IG51bWJlciwgczogYW55KSA9PiBzdW0gKyB0aGlzLnNlcnZpY2VQcmljZShzLmlkKSwgMCk7XG4gIH1cbiAgZ2V0IHNlcnZpY2VzU3VidG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZExpbmVzLnJlZHVjZSgoc3VtOiBudW1iZXIsIGw6IFJlc29sdmVkTGluZSkgPT4gc3VtICsgdGhpcy5saW5lU2VydmljZVRvdGFsKGwpLCAwKTtcbiAgfVxuICBnZXQgcmV2aWV3VG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zZXJ2aWNlc1N1YnRvdGFsICsgdGhpcy5ob21lVmlzaXRDaGFyZ2U7XG4gIH1cbiAgLyoqIE1pcnJvcnMgYXBwb2ludG1lbnRfc2VydmljZSdzIERlcG9zaXRVdGlscyNnZXRTZXJ2aWNlRGVwb3NpdEFtb3VudCBleGFjdGx5LCBzbyB0aGlzIHByZXZpZXdcbiAgICogbWF0Y2hlcyB3aGF0IEJvb2tpbmdHcm91cFNlcnZpY2UjaG9sZEJvb2tpbmcgd2lsbCBhY3R1YWxseSBjb21wdXRlIGludG8gc2VydmljZURlcG9zaXRUb3RhbC5cbiAgICogVXNlcyBwcmljZURldGFpbHMudG90YWxQcmljZSAodGF4LWluY2x1c2l2ZSksIHNhbWUgYXMgdGhlIGJhY2tlbmQgLSBub3Qgc2VydmljZVByaWNlKCknc1xuICAgKiBwcmUtdGF4IGAucHJpY2VgLCB3aGljaCB3b3VsZCB1bmRlcnN0YXRlIGEgcGVyY2VudC1iYXNlZCBkZXBvc2l0LiAqL1xuICBwcml2YXRlIHNlcnZpY2VEZXBvc2l0QW1vdW50KHNlcnZpY2VJZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCBzZXJ2aWNlID0gdGhpcy5jYXJ0U2VydmljZXMuZmluZCgoczogYW55KSA9PiBzLnNlcnZpY2VJZCA9PT0gc2VydmljZUlkKTtcbiAgICBjb25zdCBkID0gc2VydmljZT8uZGVwb3NpdEFtb3VudDtcbiAgICBpZiAoIWQgfHwgIWQuZGVwb3NpdFJlcXVpcmVkKSByZXR1cm4gMDtcbiAgICBpZiAoZC5maXhlZEFtb3VudCA+IDApIHJldHVybiBkLmZpeGVkQW1vdW50O1xuICAgIHJldHVybiAoZC5kZXBvc2l0UGVyY2VudCAvIDEwMCkgKiAoc2VydmljZT8ucHJpY2VEZXRhaWxzPy50b3RhbFByaWNlID8/IDApO1xuICB9XG4gIGdldCBkZXBvc2l0VG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZExpbmVzLnJlZHVjZSgoc3VtOiBudW1iZXIsIGw6IFJlc29sdmVkTGluZSkgPT5cbiAgICAgIHN1bSArIChsLnNlcnZpY2VzIHx8IFtdKS5yZWR1Y2UoKHM6IG51bWJlciwgc3Y6IGFueSkgPT4gcyArIHRoaXMuc2VydmljZURlcG9zaXRBbW91bnQoc3YuaWQpLCAwKSwgMCk7XG4gIH1cbiAgLyoqIFdoYXQncyBhY3R1YWxseSBkdWUgYXQgYm9va2luZyB0aW1lIGZvciBhIGxpdmUgY3VzdG9tZXIgKHNlcnZpY2VEZXBvc2l0VG90YWwgKyBob21lIHZpc2l0XG4gICAqIGNoYXJnZSwgbWF0Y2hpbmcgQm9va2luZ0dyb3VwU2VydmljZSNob2xkQm9va2luZydzIHRvdGFsQ29sbGVjdGVkQXRCb29raW5nKSAtIHNob3duIGFzIGFuXG4gICAqIGluZm9ybWF0aW9uYWwgcHJldmlldyBmb3IgYWRtaW4gYm9va2luZ3MgdG9vLCBldmVuIHRob3VnaCB0aG9zZSBjb2xsZWN0IOKCuTAgb25saW5lIGFuZCByZWNvcmRcbiAgICogdGhlIGZ1bGwgYW1vdW50IGluIHBlcnNvbiBsYXRlcjsgdGhpcyBzdGlsbCBwcmV2aWV3cyB0aGUgc2FtZSBwb2xpY3kgdGhhdCdsbCBsYW5kIG9uIHRoZVxuICAgKiBib29raW5nJ3Mgb3duIGRldGFpbCBwYWdlIG9uY2UgY3JlYXRlZC4gKi9cbiAgZ2V0IGR1ZUF0Qm9va2luZ1RvdGFsKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZGVwb3NpdFRvdGFsICsgdGhpcy5ob21lVmlzaXRDaGFyZ2U7XG4gIH1cbiAgZ2V0IHBlbmRpbmdBdEFwcG9pbnRtZW50VG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgdGhpcy5yZXZpZXdUb3RhbCAtIHRoaXMuZHVlQXRCb29raW5nVG90YWwpO1xuICB9XG4gIGdldCBib29raW5nVG90YWwoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMuYm9va2luZ0dyb3VwPy50b3RhbFBheWFibGUgPz8gMCkgKyAodGhpcy5ib29raW5nR3JvdXA/LmhvbWVWaXNpdENoYXJnZSA/PyAwKTtcbiAgfVxuICBnZXQgYm9va2luZ1BhaWQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5ib29raW5nR3JvdXA/LnRvdGFsQ29sbGVjdGVkQXRCb29raW5nID8/IDA7XG4gIH1cbiAgZ2V0IGJvb2tpbmdEdWUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgdGhpcy5ib29raW5nVG90YWwgLSB0aGlzLmJvb2tpbmdQYWlkKTtcbiAgfVxuXG4gIGxvYWRCdXNpbmVzc1NldHRpbmdzKCkge1xuICAgIGlmICghdGhpcy5idXNpbmVzc0lkKSByZXR1cm47XG4gICAgdGhpcy5yZXN0U2VydmljZS5nZXRCdXNpbmVzc0FwcG9pbnRtZW50U2V0dGluZ3ModGhpcy5idXNpbmVzc0lkKS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XG4gICAgICB0aGlzLmJ1c2luZXNzU2V0dGluZ3MgPSByZXM7XG4gICAgfSwgKCkgPT4ge1xuICAgICAgLy8gTm9uLWZhdGFsIC0gdGhlIHJldmlldyBzdGVwIGp1c3Qgd29uJ3QgcHJldmlldyBhIGhvbWUgdmlzaXQgY2hhcmdlIGFtb3VudC5cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIC8vIExvZ2luIGlzIHJlcXVpcmVkIGJlZm9yZSBlbnRlcmluZyB0aGUgd2l6YXJkIGF0IGFsbCAobm90IG1pZC1mbG93LCBsaWtlIGNhcnQnc1xuICAgIC8vIGNoZWNrb3V0LWNvbW1pdCBnYXRlKSAtIHRoZSB3aXphcmQncyBzZWxlY3Rpb25zIGxpdmUgb25seSBpbiBjb21wb25lbnQgbWVtb3J5LCBzbyBhXG4gICAgLy8gcmVkaXJlY3QtYW5kLWJhY2sgcGFydHdheSB0aHJvdWdoIHdvdWxkIHNpbGVudGx5IHdpcGUgd2hhdGV2ZXIgdGhlIGN1c3RvbWVyIGhhZCBhbHJlYWR5XG4gICAgLy8gcGlja2VkLiBDaGVja2luZyBoZXJlLCBiZWZvcmUgYW55dGhpbmcgaXMgcGlja2VkLCBtZWFucyB0aGVyZSdzIG5vdGhpbmcgdG8gbG9zZS4gU2tpcHBlZFxuICAgIC8vIGluIGJ1aWxkZXIgZWRpdC9wcmV2aWV3IG1vZGUgKGBlZGl0YCBpcyB0cnVlIHdoZW4gYSBidXNpbmVzcyBvd25lciBpcyBlZGl0aW5nIHRoZWlyIHNpdGUsXG4gICAgLy8gbm90IGEgcmVhbCBjdXN0b21lciBzZXNzaW9uKSAtIHRoZSBzYW1lIGd1YXJkIHBhdHRlcm4gdXNlZCBlbHNld2hlcmUgaW4gdGhpcyBjb2RlYmFzZVxuICAgIC8vIChlLmcuIEF1dGhlbnRpY2F0aW9uUmVxdWlyZWRDb21wb25lbnQncyBvd24gc3VibWl0IGhhbmRsZXJzKS5cbiAgICBpZiAoIXRoaXMuZWRpdCAmJiAhdGhpcy5zdG9yYWdlU2VydmljZS5nZXRVc2VyKCkgJiYgIXRoaXMuaXNBZG1pbkJvb2tpbmcpIHtcbiAgICAgIC8vIHRoaXMuZGlhbG9nUmVmPy5jbG9zZSgpO1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvbG9naW4nXSwgeyBxdWVyeVBhcmFtczogeyByZWRpcmVjdFRvOiB0aGlzLnJvdXRlci51cmwgfSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5nZXRTY3JlZW5TaXplKCk7XG4gICAgLy8gUHJlZmlsbCBDb250YWN0IERldGFpbHMgZnJvbSB0aGUgbG9nZ2VkLWluIGN1c3RvbWVyJ3Mgb3duIGFjY291bnQgKG5hbWUvZW1haWwvcGhvbmUgc3RheVxuICAgIC8vIGVkaXRhYmxlLCBlLmcuIGZvciBib29raW5nIG9uIGJlaGFsZiBvZiBzb21lb25lIGVsc2UpIGluc3RlYWQgb2YgYWx3YXlzIHNob3dpbmcgYSBibGFua1xuICAgIC8vIGZvcm0gLSBtYXRjaGVzIEJvb2tBcHBvaW50bWVudENvbXBvbmVudCdzIHBhdHRlcm4uIFNraXBwZWQgZW50aXJlbHkgZm9yIGlzQWRtaW5Cb29raW5nOlxuICAgIC8vIHN0YWZmIGFyZW4ndCBsb2dnZWQgaW4gYXMgdGhlIGN1c3RvbWVyIHRoZXkncmUgYm9va2luZyBmb3IsIHNvIHRoZXJlJ3Mgbm8gYWNjb3VudCBoZXJlIHRvXG4gICAgLy8gcmVhZCAtIGxlYXZlIHRoZSBmb3JtIGJsYW5rIGZvciBtYW51YWwgZW50cnksIHNhbWUgYXMgYmVmb3JlIHRoaXMgcHJlZmlsbCBleGlzdGVkLlxuICAgIGlmICghdGhpcy5pc0FkbWluQm9va2luZykge1xuICAgICAgdGhpcy51c2VyRGV0YWlscyA9IHRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0VXNlcigpIGFzIFVzZXI7XG4gICAgICBpZiAodGhpcy51c2VyRGV0YWlscz8uY29udGFjdCkge1xuICAgICAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lID0gdGhpcy51c2VyRGV0YWlscy5jb250YWN0Lm5hbWUgPz8gJyc7XG4gICAgICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyID0gdGhpcy51c2VyRGV0YWlscy5jb250YWN0Lm1vYmlsZSA/PyAnJztcbiAgICAgICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwuZW1haWwgPSB0aGlzLnVzZXJEZXRhaWxzLmNvbnRhY3QuZW1haWwgPz8gJyc7XG4gICAgICB9XG4gICAgICB0aGlzLnJlZnJlc2hEZWZhdWx0QWRkcmVzcygpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcmVmaWxsQ29udGFjdCkge1xuICAgICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwubmFtZSA9IHRoaXMucHJlZmlsbENvbnRhY3QubmFtZSA/PyB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lO1xuICAgICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwucGhvbmVOdW1iZXIgPSB0aGlzLnByZWZpbGxDb250YWN0LnBob25lTnVtYmVyID8/IHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyO1xuICAgIH1cbiAgICAvLyBSZXVzZWQgYnkgZ29CYWNrKCkgYW5kIGJ5IHRoZSBkb25lLXNjcmVlbidzIGFkbWluLXZzLXdlYnNpdGUgYnV0dG9uIGJyYW5jaCAtIHRoZSBhZG1pblxuICAgIC8vIHBhbmVsIGxvYWRzIHRoaXMgY29tcG9uZW50IHZpYSBWaWV3Q29udGFpbmVyUmVmIChub3QgYSByb3V0ZSksIHNvIGl0IGNhbid0IGJlIHRvbGQgYXBhcnRcbiAgICAvLyBmcm9tIHRoZSBsaXZlIHdlYnNpdGUgYnkgVVJMOyBSRVFVRVNUX0ZST00gaXMgdGhlIGV4aXN0aW5nIGZsYWcgdGhlIGFkbWluIHNoZWxsIGFscmVhZHlcbiAgICAvLyBzZXRzIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgdGhpcy5pc0FkbWluQ29udGV4dCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiUkVRVUVTVF9GUk9NXCIpID09PSAnRUNPTU1FUkNFJztcbiAgICB0aGlzLnJlc2V0V2l6YXJkKCk7XG4gICAgdGhpcy5sb2FkQnVzaW5lc3NTZXR0aW5ncygpO1xuICB9XG5cbiAgaXNBZG1pbkNvbnRleHQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyBSZXN0b3JlcyB0aGUgd2l6YXJkIHRvIGl0cyBzdGFydCBzdGF0ZSAtIHVzZWQgZm9yIGluaXRpYWwgbG9hZCAobmdPbkluaXQpIGFuZCBmb3IgXCJCb29rXG4gIC8vIEFub3RoZXJcIiBvbiB0aGUgZG9uZSBzY3JlZW4sIHNvIGEgc2Vjb25kIGJvb2tpbmcgZG9lc24ndCBpbmhlcml0IHRoZSBwcmV2aW91cyBvbmUnc1xuICAvLyBzZXJ2aWNlcy9zbG90L2FkZHJlc3Mgc2VsZWN0aW9ucy5cbiAgcmVzZXRXaXphcmQoKSB7XG4gICAgdGhpcy5jYXJ0U2VydmljZXMgPSBbXTtcbiAgICB0aGlzLnJlc29sdmVkTGluZXMgPSBbXTtcbiAgICB0aGlzLmNhbWVGcm9tU3RhZmZMaXN0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uID0gbnVsbDtcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IG51bGw7XG4gICAgdGhpcy5zZWxlY3RlZERhdGVTdHIgPSAnJztcbiAgICB0aGlzLmJvb2tpbmdHcm91cCA9IG51bGw7XG4gICAgdGhpcy5hcGlTdGF0dXMgPSBmYWxzZTtcbiAgICB0aGlzLmluc3RydWN0aW9ucyA9ICcnO1xuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gZmFsc2U7XG4gICAgdGhpcy5hY2Nlc3NlZFRhYnMgPSB7IHNlcnZpY2VMaXN0aW5nOiBmYWxzZSwgbG9jYXRpb25MaXN0aW5nOiBmYWxzZSwgc3RhZmZMaXN0aW5nOiBmYWxzZSB9O1xuXG4gICAgLy8gQSBidXNpbmVzcyBjYW4gcGluIHRoaXMgc2VjdGlvbiB0byBvbmUgbW9kZSB2aWEgc2F2ZWQgY29udGVudCBjb25maWcuIFRoZXJlJ3Mgbm8gZWRpdG9yXG4gICAgLy8gVUkgeWV0IHRvIHNldCB0aGlzIGZpZWxkICh0aGUgc2VjdGlvbiBjb250ZW50LWVkaXRvciBkb2Vzbid0IGhhdmUgYSBtb2RlIHBpY2tlciBidWlsdCkgLVxuICAgIC8vIHJlYWRpbmcgaXQgaGVyZSBqdXN0IGtlZXBzIHRoZSBjb21wb25lbnQgZm9yd2FyZC1jb21wYXRpYmxlIG9uY2Ugb25lIGV4aXN0cy5cbiAgICBjb25zdCBwaW5uZWRNb2RlID0gKHRoaXMuZGF0YT8uY29udGVudCBhcyBhbnkpPy5tb2RlO1xuICAgIGlmIChwaW5uZWRNb2RlID09PSAnU1RPUkVfVklTSVQnIHx8IHBpbm5lZE1vZGUgPT09ICdIT01FX1ZJU0lUJyB8fCBwaW5uZWRNb2RlID09PSAnVklERU9fQ0FMTCcpIHtcbiAgICAgIHRoaXMubW9kZVBpbm5lZCA9IHRydWU7XG4gICAgICB0aGlzLnNlbGVjdE1vZGUocGlubmVkTW9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnbW9kZVNlbGVjdGlvbic7XG4gICAgICB0aGlzLmJhcldpZHRoID0gJzEwJztcbiAgICB9XG4gIH1cbiAgc2NyZWVuV2lkdGg6IG51bWJlciA9IDA7XG4gIEBIb3N0TGlzdGVuZXIoXCJ3aW5kb3c6IHJlc2l6ZVwiLCBbXCIkZXZlbnRcIl0pXG4gIGdldFNjcmVlblNpemUoKSB7XG4gICAgdGhpcy5zY3JlZW5XaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICB9XG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJylcbiAgY2xvc2VPbk91dHNpZGVDbGljaygpIHtcbiAgICB0aGlzLnNob3dDYWxlbmRhciA9IGZhbHNlO1xuICB9XG4gIGFjY2Vzc2VkVGFicyA9IHtcbiAgICBzZXJ2aWNlTGlzdGluZzogZmFsc2UsXG4gICAgbG9jYXRpb25MaXN0aW5nOiBmYWxzZSxcbiAgICBzdGFmZkxpc3Rpbmc6IGZhbHNlXG4gIH1cbiAgc2tlbGV0b25Mb2FkZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgYnVzaW5lc3NOYW1lID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2J1c2luZXNzTmFtZScpID8gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2J1c2luZXNzTmFtZScpIDogKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdiTmFtZScpID8gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2JOYW1lJykgOiAnJyk7XG4gIGJ1c2luZXNzSWQ6IGFueSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdidXNpbmVzc0lkJykgPyBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYnVzaW5lc3NJZCcpIDogKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdiSWQnKSA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdiSWQnKSA6ICcnKTtcbiAgYWN0aXZlQnV0dG9uOiBib29sZWFuID0gZmFsc2U7XG4gIHNlbGVjdGVkVGFiOiBzdHJpbmcgPSAnJztcbiAgYmFyV2lkdGg6IHN0cmluZyA9ICcnO1xuICBzaG93Q2FuY2VsbGF0aW9uUG9saWN5OiBib29sZWFuID0gZmFsc2U7XG4gIHNob3dSZWR1Y2luZ1BvbGljeTogYm9vbGVhbiA9IGZhbHNlO1xuICBidXNpbmVzc1NldHRpbmdzOiBhbnkgPSBudWxsO1xuXG4gIHNlbGVjdGVkTW9kZTogQm9va2luZ01vZGUgPSAnU1RPUkVfVklTSVQnO1xuICBtb2RlUGlubmVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gQ2FydCBvZiBzZXJ2aWNlcyBwaWNrZWQgaW4gc2VydmljZUxpc3RpbmcgLSBjbGlja2luZyBhIGNhcmQgdG9nZ2xlcyBtZW1iZXJzaGlwLiBUaGlzIGlzIGFcbiAgLy8gc3RyYWlnaHRmb3J3YXJkIHN1cGVyc2V0IG9mIHRoZSBvbGQgc2luZ2xlLXNlbGVjdGVkU2VydmljZSBiZWhhdmlvcjogd2l0aCBleGFjdGx5IG9uZVxuICAvLyBzZXJ2aWNlIGNsaWNrZWQgaXQncyB0aGUgZXhhY3Qgc2FtZSAyLWNsaWNrIChzZWxlY3QsIGNvbnRpbnVlKSBmbG93IGFzIGJlZm9yZS5cbiAgY2FydFNlcnZpY2VzOiBhbnlbXSA9IFtdO1xuICByZXNvbHZlZExpbmVzOiBSZXNvbHZlZExpbmVbXSA9IFtdO1xuICByZXNvbHZpbmdDYXJ0OiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gUHJvZHVjdHMgYWRkZWQgdG8gdGhlIGNhcnQgYmVmb3JlIGVudGVyaW5nIHRoZSB3aXphcmQgKGUuZy4gXCJUcnkgYXQgSG9tZVwiIG9uIGEgcHJvZHVjdFxuICAvLyBwYWdlKSAtIGxvYWRlZCBmcm9tIHRoZSBsb2NhbCBib29raW5nLXByb2R1Y3QtY2FydCBvbmNlIHRoZSBtb2RlIGlzIGtub3duLlxuICBwcm9kdWN0Q2FydEl0ZW1zOiBhbnlbXSA9IFtdO1xuXG4gIHNlbGVjdGVkTG9jYXRpb246IGFueTtcbiAgLy8gVGhlIGxvZ2dlZC1pbiBjdXN0b21lcidzIHJlYWwgYWNjb3VudCAtIHNhbWUgc291cmNlIEFkZHJlc3NDb21wb25lbnQvQWRkcmVzc0xpc3RDb21wb25lbnRcbiAgLy8gdXNlZCBhdCBwcm9kdWN0LXB1cmNoYXNlIGNoZWNrb3V0IGFuZCBpbiBCb29rQXBwb2ludG1lbnRDb21wb25lbnQsIGluc3RlYWQgb2YgYSB0eXBlZC1pblxuICAvLyBhZGRyZXNzIGZvcm0uIE5vdCB1c2VkIGZvciBpc0FkbWluQm9va2luZywgd2hpY2ggaGFzIG5vIGxvZ2dlZC1pbiBjdXN0b21lciBhY2NvdW50IHRvIHJlYWQgLVxuICAvLyBzZWUgaG9tZVZpc2l0QWRkcmVzcyBiZWxvdyBmb3IgdGhhdCBjYXNlLlxuICB1c2VyRGV0YWlsczogVXNlciB8IG51bGwgPSBudWxsO1xuICBkZWZhdWx0QWRkcmVzczogQWRkcmVzc0RldGFpbHMgfCBudWxsID0gbnVsbDtcbiAgLy8gTWFudWFsIGVudHJ5LCB1c2VkIG9ubHkgZm9yIGlzQWRtaW5Cb29raW5nIC0gc3RhZmYgdHlwaW5nIGFuIGFkZHJlc3Mgb24gdGhlIGN1c3RvbWVyJ3NcbiAgLy8gYmVoYWxmLCB3aXRoIG5vIGFjY291bnQvc2F2ZWQtYWRkcmVzcy1ib29rIHRvIHNlbGVjdCBmcm9tLlxuICBob21lVmlzaXRBZGRyZXNzOiBhbnkgPSB7IHJlY2VpdmVyTmFtZTogJycsIHJlY2VpdmVyUGhvbmU6ICcnLCBhZGRyZXNzTGluZTE6ICcnLCBhZGRyZXNzTGluZTI6ICcnLCBjaXR5OiAnJywgc3RhdGU6ICcnLCB6aXBDb2RlOiAnJyB9O1xuICBpbnN0cnVjdGlvbnM6IHN0cmluZyA9ICcnO1xuICBPYmplY3QgPSBPYmplY3Q7XG4gIHNob3dDYWxlbmRhciA9IGZhbHNlO1xuICBzZWxlY3RlZERhdGU6IERhdGUgfCBudWxsID0gbnVsbDtcbiAgc2VsZWN0ZWREYXRlU3RyID0gJyc7XG5cbiAgYm9va2luZ0dyb3VwOiBhbnkgPSBudWxsO1xuXG4gIGRhdGVGaWx0ZXIgPSAoZDogRGF0ZSB8IG51bGwpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBkYXRlID0gKGQgfHwgbmV3IERhdGUoKSk7XG4gICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuICAgIHRvZGF5LnNldEhvdXJzKDAsIDAsIDAsIDApO1xuICAgIHJldHVybiBkYXRlLmdldFRpbWUoKSA+PSB0b2RheS5nZXRUaW1lKCk7XG4gIH1cbiAgdG9nZ2xlQ2FsZW5kYXIoZXZlbnQ/OiBFdmVudCkge1xuICAgIGlmIChldmVudCkgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5zaG93Q2FsZW5kYXIgPSAhdGhpcy5zaG93Q2FsZW5kYXI7XG4gIH1cblxuICBvbkRhdGVTZWxlY3RlZChkYXRlOiBhbnkpIHtcbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gZGF0ZTtcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZVN0ciA9IHRoaXMuZm9ybWF0RGF0ZShkYXRlKTtcbiAgICB0aGlzLnNob3dDYWxlbmRhciA9IGZhbHNlO1xuICAgIHRoaXMucmVzb2x2ZUNhcnQoKTtcbiAgfVxuICBwcml2YXRlIGZvcm1hdERhdGUoZDogRGF0ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgZGQgPSBTdHJpbmcoZC5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgbW0gPSBTdHJpbmcoZC5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCB5eXl5ID0gZC5nZXRGdWxsWWVhcigpO1xuICAgIHJldHVybiBgJHtkZH0tJHttbX0tJHt5eXl5fWA7XG4gIH1cbiAgcHJpdmF0ZSB0b0lzb0RhdGUoZDogRGF0ZSB8IG51bGwpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRhdGUgPSBkID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgeXl5eSA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtbSA9IFN0cmluZyhkYXRlLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IGRkID0gU3RyaW5nKGRhdGUuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIHJldHVybiBgJHt5eXl5fS0ke21tfS0ke2RkfVQwMDowMDowMC4wMDBaYDtcbiAgfVxuXG4gIHNlbGVjdE1vZGUobW9kZTogQm9va2luZ01vZGUpIHtcbiAgICB0aGlzLnNlbGVjdGVkTW9kZSA9IG1vZGU7XG4gICAgdGhpcy5sb2FkUHJvZHVjdENhcnRGb3JNb2RlKCk7XG4gICAgdGhpcy5nZXRBbGxTZXJ2aWNlcygpO1xuICB9XG5cbiAgYXN5bmMgbG9hZFByb2R1Y3RDYXJ0Rm9yTW9kZSgpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdTVE9SRV9WSVNJVCcpIHtcbiAgICAgIHRoaXMucHJvZHVjdENhcnRJdGVtcyA9IFtdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnByb2R1Y3RDYXJ0SXRlbXMgPSBhd2FpdCB0aGlzLmJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UuZ2V0SXRlbXModGhpcy5zZWxlY3RlZE1vZGUgYXMgQm9va2luZ0NhcnRNb2RlKTtcbiAgfVxuXG4gIHNlbGVjdFNlcnZpY2Uoc2VydmljZTogYW55KSB7XG4gICAgY29uc3QgaWR4ID0gdGhpcy5jYXJ0U2VydmljZXMuZmluZEluZGV4KChzOiBhbnkpID0+IHMuc2VydmljZUlkID09PSBzZXJ2aWNlLnNlcnZpY2VJZCk7XG4gICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICB0aGlzLmNhcnRTZXJ2aWNlcy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgIHNlcnZpY2Uuc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jYXJ0U2VydmljZXMucHVzaChzZXJ2aWNlKTtcbiAgICAgIHNlcnZpY2Uuc2VsZWN0ZWQgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMuY2FydFNlcnZpY2VzLmxlbmd0aCA+IDAgfHwgdGhpcy5wcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDA7XG4gIH1cbiAgc2VsZWN0TG9jYXRpb24obG9jYXRpb246IGFueSkge1xuICAgIGxvY2F0aW9uLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5zZWxlY3RlZExvY2F0aW9uICYmIGxvY2F0aW9uLmlkICE9IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbi5pZCkge1xuICAgICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdGVkTG9jYXRpb24gPSBsb2NhdGlvbjtcbiAgfVxuXG4gIG5leHRTdGVwKCkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnc2VydmljZUxpc3RpbmcnKSB7XG4gICAgICB0aGlzLmFjY2Vzc2VkVGFicy5zZXJ2aWNlTGlzdGluZyA9IHRydWU7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdTVE9SRV9WSVNJVCcpIHtcbiAgICAgICAgdGhpcy5nZXRBbGxMb2NhdGlvbnMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZ29Ub0RhdGVTZWxlY3Rpb24oKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ2xvY2F0aW9uTGlzdGluZycpIHtcbiAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZyA9IHRydWU7XG4gICAgICB0aGlzLmdvVG9EYXRlU2VsZWN0aW9uKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdzdGFmZkxpc3RpbmcnKSB7XG4gICAgICB0aGlzLmFjY2Vzc2VkVGFicy5zdGFmZkxpc3RpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5mZXRjaEFsbExpbmVTbG90cygpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnZGF0ZVNlbGVjdGlvbicpIHtcbiAgICAgIHRoaXMuY2hlY2tSZXF1aXJlZFZhbHVlcygpO1xuICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdjb250YWN0RGV0YWlscyc7XG4gICAgICB0aGlzLmJhcldpZHRoID0gJzcwLjU3J1xuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnY29udGFjdERldGFpbHMnKSB7XG4gICAgICB0aGlzLmNoZWNrUmVxdWlyZWRWYWx1ZXMoKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAncGF5bWVudFRhYic7XG4gICAgICB0aGlzLmJhcldpZHRoID0gJzg1LjU3J1xuICAgIH1cbiAgfVxuICBwcmV2aW91c1N0ZXAoKSB7XG4gICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ21vZGVTZWxlY3Rpb24nKSByZXR1cm47XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdzZXJ2aWNlTGlzdGluZycpIHtcbiAgICAgIGlmICghdGhpcy5tb2RlUGlubmVkKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnbW9kZVNlbGVjdGlvbic7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTAnO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRydWU7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdsb2NhdGlvbkxpc3RpbmcnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3NlcnZpY2VMaXN0aW5nJztcbiAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xuICAgICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uID0gbnVsbDtcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ3N0YWZmTGlzdGluZycpIHtcbiAgICAgIHRoaXMucmVzb2x2ZWRMaW5lcy5mb3JFYWNoKChsOiBSZXNvbHZlZExpbmUpID0+IHsgbC5zZWxlY3RlZFN0YWZmSWQgPSB1bmRlZmluZWQ7IGwuc2VsZWN0ZWRTdGFmZk5hbWUgPSB1bmRlZmluZWQ7IH0pO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnICYmIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZykge1xuICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2xvY2F0aW9uTGlzdGluZyc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMjkuMjgnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzZXJ2aWNlTGlzdGluZyc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnZGF0ZVNlbGVjdGlvbicpIHtcbiAgICAgIGNvbnN0IG5lZWRzU3RhZmZQaWNrID0gdGhpcy5yZXNvbHZlZExpbmVzLnNvbWUoKGw6IFJlc29sdmVkTGluZSkgPT4gISFsLmNhbmRpZGF0ZVN0YWZmUG9vbD8ubGVuZ3RoKTtcbiAgICAgIGlmIChuZWVkc1N0YWZmUGljaykge1xuICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3N0YWZmTGlzdGluZyc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnNDMuNTcnO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdTVE9SRV9WSVNJVCcgJiYgdGhpcy5hY2Nlc3NlZFRhYnMubG9jYXRpb25MaXN0aW5nKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnbG9jYXRpb25MaXN0aW5nJztcbiAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcyOS4yOCc7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzZXJ2aWNlTGlzdGluZyc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnY29udGFjdERldGFpbHMnKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2RhdGVTZWxlY3Rpb24nO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc1OC41Nyc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdwYXltZW50VGFiJykge1xuICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdjb250YWN0RGV0YWlscyc7XG4gICAgICB0aGlzLmJhcldpZHRoID0gJzcwLjU3JztcbiAgICB9XG4gIH1cbiAgc2VydmljZURhdGE6IGFueVtdID0gW107XG4gIGdldEFsbFNlcnZpY2VzKCkge1xuICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSB0cnVlXG4gICAgbGV0IHNlcnZpY2VQYXlsb2FkOiBhbnkgPSB7XG4gICAgICBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQgPz8gXCJcIixcbiAgICAgIHBhZ2VObzogMCxcbiAgICAgIHNpemU6IDEwMFxuICAgIH1cbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmdldEFsbEFwcG9pbnRtZW50U2VydmljZShzZXJ2aWNlUGF5bG9hZCkuc3Vic2NyaWJlKFxuICAgICAgKHJlczogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgbGV0IHNlcnZpY2VzID0gKHJlcy5jb250ZW50IHx8IFtdKS5maWx0ZXIoKHNlcnZpY2U6IGFueSkgPT4gc2VydmljZS5hY3RpdmUgPT09IHRydWUpO1xuICAgICAgICAvLyBob21lQXBwb2ludG1lbnRBdmFpbGFibGUvdmlkZW9DYWxsQXZhaWxhYmxlL3N0b3JlSWRzIGFyZSBtb2RlLUNBUEFCSUxJVFkgZmxhZ3MgLSB3aGV0aGVyXG4gICAgICAgIC8vIGEgc2VydmljZSBjYW4gYmUgZGVsaXZlcmVkIHRoYXQgd2F5IGF0IGFsbCAoZS5nLiBhIGhhaXJjdXQgY2FuJ3QgYmUgZG9uZSBvdmVyIHZpZGVvKSAtXG4gICAgICAgIC8vIG5vdCBhIGN1c3RvbWVyLXNlbGYtc2VydmljZSBwZXJtaXNzaW9uLCBzbyB0aGVzZSBhcHBseSB1bmNvbmRpdGlvbmFsbHksIGluY2x1ZGluZyBmb3JcbiAgICAgICAgLy8gaXNBZG1pbkJvb2tpbmcuIChhdmFpbGFibGVPbmxpbmUgaXMgdGhlIGFjdHVhbCBzZWxmLXNlcnZpY2Utb25seSBmbGFnLCBhbmQgaXNcbiAgICAgICAgLy8gaW50ZW50aW9uYWxseSBub3QgZmlsdGVyZWQgaGVyZSAtIGFuIGFkbWluIGNhbiBzdGlsbCBib29rIGl0IG9uIHRoZSBjdXN0b21lcidzIGJlaGFsZi4pXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ0hPTUVfVklTSVQnKSBzZXJ2aWNlcyA9IHNlcnZpY2VzLmZpbHRlcigoczogYW55KSA9PiBzLmhvbWVBcHBvaW50bWVudEF2YWlsYWJsZSk7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1ZJREVPX0NBTEwnKSBzZXJ2aWNlcyA9IHNlcnZpY2VzLmZpbHRlcigoczogYW55KSA9PiBzLnZpZGVvQ2FsbEF2YWlsYWJsZSk7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJykgc2VydmljZXMgPSBzZXJ2aWNlcy5maWx0ZXIoKHM6IGFueSkgPT4gKHMuc3RvcmVJZHM/Lmxlbmd0aCA/PyAwKSA+IDApO1xuICAgICAgICBzZXJ2aWNlcy5mb3JFYWNoKChzZXJ2aWNlOiBhbnkpID0+IHNlcnZpY2Uuc2VsZWN0ZWQgPSBmYWxzZSk7XG4gICAgICAgIHRoaXMuc2VydmljZURhdGEgPSBzZXJ2aWNlcztcbiAgICAgICAgdGhpcy5jYXJ0U2VydmljZXMgPSBbXTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzZXJ2aWNlTGlzdGluZyc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xuICAgICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMucHJvZHVjdENhcnRJdGVtcy5sZW5ndGggPiAwO1xuICAgICAgfSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gZmFsc2U7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuICBsb2NhdGlvbkRhdGE6IGFueVtdID0gW107XG4gIGdldEFsbExvY2F0aW9ucygpIHtcbiAgICB0aGlzLmxvYWRlciA9IHRydWU7XG4gICAgdGhpcy5sb2NhdGlvbkRhdGEgPSBbXTtcbiAgICBsZXQgcGF5bG9hZCA9IHsgYnVzaW5lc3NJZDogdGhpcy5idXNpbmVzc0lkID8/IFwiXCIgfVxuICAgIHRoaXMucmVzdFNlcnZpY2UuZ2V0QWxsU3RvcmVzKHBheWxvYWQpLnN1YnNjcmliZShcbiAgICAgIChyZXM6IGFueSkgPT4ge1xuICAgICAgICBpZiAocmVzLmRhdGEuZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbGV0IGxvY2F0aW9ucyA9IHJlcy5kYXRhLmRhdGEuZmlsdGVyKChzdG9yZTogYW55KSA9PiB7IHJldHVybiBzdG9yZS5zdGF0dXMgPT09ICdBQ1RJVkUnIH0pO1xuICAgICAgICAgIC8vIExvY2F0aW9uLWludGVyc2VjdGlvbiBjaGVjayAoZGVzaWduIGRvYyDCpzJjKTogb25seSBvZmZlciBzdG9yZXMgdGhhdCBjYXJyeSBldmVyeVxuICAgICAgICAgIC8vIHNlcnZpY2UgY3VycmVudGx5IGluIHRoZSBjYXJ0LCBub3QganVzdCB0aGUgZmlyc3Qgb25lLlxuICAgICAgICAgIGxvY2F0aW9ucyA9IGxvY2F0aW9ucy5maWx0ZXIoKGxvY2F0aW9uOiBhbnkpID0+XG4gICAgICAgICAgICB0aGlzLmNhcnRTZXJ2aWNlcy5ldmVyeSgoczogYW55KSA9PiBzLnN0b3JlSWRzPy5pbmNsdWRlcyhsb2NhdGlvbi5pZCkpXG4gICAgICAgICAgKTtcbiAgICAgICAgICBsb2NhdGlvbnMuZm9yRWFjaCgobDogYW55KSA9PiBsLnNlbGVjdGVkID0gZmFsc2UpO1xuICAgICAgICAgIHRoaXMubG9jYXRpb25EYXRhID0gbG9jYXRpb25zO1xuICAgICAgICAgIGlmICh0aGlzLmxvY2F0aW9uRGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdObyBMb2NhdGlvbicsIGRldGFpbDogJ1RoZXNlIHNlcnZpY2VzIGFyZW5cXCd0IGFsbCBhdmFpbGFibGUgYXQgb25lIGxvY2F0aW9uIC0gcmVtb3ZlIG9uZSBhbmQgYm9vayBpdCBzZXBhcmF0ZWx5JyB9KTtcbiAgICAgICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0aGlzLmxvY2F0aW9uRGF0YS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiA9IHRoaXMubG9jYXRpb25EYXRhWzBdO1xuICAgICAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5nb1RvRGF0ZVNlbGVjdGlvbigpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2xvY2F0aW9uTGlzdGluZyc7XG4gICAgICAgICAgICB0aGlzLmJhcldpZHRoID0gJzI5LjI4JztcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZyA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdObyBMb2NhdGlvbicsIGRldGFpbDogJ05vIExvY2F0aW9uIGFkZGVkIGZvciBzZWxlY3RlZCBzZXJ2aWNlJyB9KTtcbiAgICAgICAgICB0aGlzLmxvYWRlciA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8vIFRydWUgb25jZSB0aGUgd2l6YXJkIGhhcyBkZXRvdXJlZCB0aHJvdWdoIHN0YWZmTGlzdGluZyBmb3IgdGhlIGN1cnJlbnQgY2FydCAoYW1iaWd1b3VzXG4gIC8vIHN0YWZmIHBvb2wpIGFuZCByZXR1cm5lZCB0byBkYXRlU2VsZWN0aW9uIHRvIHNob3cgdGltZXMgLSBOT1QganVzdCBcInNsb3RzIGhhdmUgYmVlblxuICAvLyBmZXRjaGVkXCIsIHNpbmNlIHRoZSBzaW1wbGUvdW5hbWJpZ3VvdXMgcGF0aCBhbHNvIGZldGNoZXMgc2xvdHMgb24gaXRzIG9uZSBhbmQgb25seSB2aXNpdCB0b1xuICAvLyBkYXRlU2VsZWN0aW9uIGFuZCBzaG91bGQga2VlcCBzaG93aW5nIHRoZSBmdWxsIFwiU2VsZWN0IERhdGVcIiBjYXJkIHRoZXJlLCB1bmNoYW5nZWQuIE9ubHkgdGhlXG4gIC8vIHN0YWZmTGlzdGluZyBkZXRvdXIgbWFrZXMgdGhlIGRhdGUgY2FyZCByZWR1bmRhbnQgb24gdGhlIHJldHVybiB2aXNpdCAodGhlIGRhdGUgd2FzIGFscmVhZHlcbiAgLy8gcGlja2VkIGFuZCBsb2NrZWQgaW4gYmVmb3JlIHRoZSBkZXRvdXIgZXZlbiBzdGFydGVkKS5cbiAgY2FtZUZyb21TdGFmZkxpc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBnb1RvRGF0ZVNlbGVjdGlvbigpIHtcbiAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2RhdGVTZWxlY3Rpb24nO1xuICAgIHRoaXMuYmFyV2lkdGggPSAnNDMuNTcnO1xuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gZmFsc2U7XG4gICAgdGhpcy5yZXNvbHZlZExpbmVzID0gW107XG4gICAgdGhpcy5jYW1lRnJvbVN0YWZmTGlzdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgc3RhZmZTZWFyY2hRdWVyeTogc3RyaW5nID0gJyc7XG4gIGdldCBmaWx0ZXJlZFN0YWZmKCk6IGFueVtdIHtcbiAgICBpZiAoIXRoaXMuc3RhZmZTZWFyY2hRdWVyeS50cmltKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0YWZmRGF0YTtcbiAgICB9XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnN0YWZmU2VhcmNoUXVlcnkudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gICAgcmV0dXJuIHRoaXMuc3RhZmZEYXRhLmZpbHRlcihzdGFmZiA9PlxuICAgICAgc3RhZmY/LnN0YWZmTmFtZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxdWVyeSlcbiAgICApO1xuICB9XG4gIHN0YWZmRGF0YTogYW55W10gPSBbXTtcblxuICByZXNvbHZlQ2FydCgpIHtcbiAgICBpZiAodGhpcy5jYXJ0U2VydmljZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBQdXJlIHByb2R1Y3Qtb25seSBsaW5lIChIb21lIFZpc2l0IC8gVmlkZW8gQ2FsbCB3aXRoIG5vIHNlcnZpY2VzIGF0dGFjaGVkKSAtIHJlc29sdXRpb25cbiAgICAgIC8vIGlzIGJ1aWx0IGFyb3VuZCBzZXJ2aWNlIHBvb2xzLCBzbyB0aGlzIG5lZWRzIGFuIGV4cGxpY2l0IHN0YWZmIHBpY2sgaW5zdGVhZC4gT25lIGxpbmUsXG4gICAgICAvLyBubyBzZXJ2aWNlcywganVzdCBhIHN0YWZmK3RpbWUgdG8gY2FycnkgdGhlIGZsYXQgcHJvZHVjdC12aWV3aW5nIGFsbG93YW5jZS5cbiAgICAgIHRoaXMucmVzb2x2ZWRMaW5lcyA9IFt7IHNlcnZpY2VzOiBbXSwgdG90YWxEdXJhdGlvbk1pbnV0ZXM6IDAsIHNsb3RzOiBbXSB9XTtcbiAgICAgIHRoaXMuZ2V0QWxsU3RhZmZGb3JQcm9kdWN0T25seUxpbmUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZXNvbHZpbmdDYXJ0ID0gdHJ1ZTtcbiAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkOiBhbnkgPSB7XG4gICAgICBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQsXG4gICAgICBtb2RlOiB0aGlzLnNlbGVjdGVkTW9kZSxcbiAgICAgIHN0b3JlSWQ6IHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnID8gdGhpcy5zZWxlY3RlZExvY2F0aW9uPy5pZCA6IHVuZGVmaW5lZCxcbiAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXG4gICAgICBzZXJ2aWNlSXRlbXM6IHRoaXMuY2FydFNlcnZpY2VzLm1hcCgoczogYW55KSA9PiAoeyBzZXJ2aWNlSWQ6IHMuc2VydmljZUlkIH0pKVxuICAgIH07XG4gICAgdGhpcy5yZXN0U2VydmljZS5yZXNvbHZlQ2FydChwYXlsb2FkKS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XG4gICAgICB0aGlzLnJlc29sdmluZ0NhcnQgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMucmVzb2x2ZWRMaW5lcyA9IChyZXMgfHwgW10pLm1hcCgobGluZTogYW55KSA9PiAoe1xuICAgICAgICBzZXJ2aWNlczogbGluZS5zZXJ2aWNlcyxcbiAgICAgICAgdG90YWxEdXJhdGlvbk1pbnV0ZXM6IGxpbmUudG90YWxEdXJhdGlvbk1pbnV0ZXMsXG4gICAgICAgIHN0YWZmSWQ6IGxpbmUuc3RhZmZJZCxcbiAgICAgICAgc3RhZmZOYW1lOiBsaW5lLnN0YWZmTmFtZSxcbiAgICAgICAgY2FuZGlkYXRlU3RhZmZQb29sOiBsaW5lLmNhbmRpZGF0ZVN0YWZmUG9vbCxcbiAgICAgICAgc2xvdHM6IFtdXG4gICAgICB9KSk7XG4gICAgICBjb25zdCBhbWJpZ3VvdXMgPSB0aGlzLnJlc29sdmVkTGluZXMuc29tZSgobDogUmVzb2x2ZWRMaW5lKSA9PiAhIWwuY2FuZGlkYXRlU3RhZmZQb29sPy5sZW5ndGgpO1xuICAgICAgLy8gQnVzaW5lc3NTZXR0aW5ncyNhbGxvd1N0YWZmU2VsZWN0aW9uIGRlZmF1bHRzIHRvIHRydWUgKHNlZSBkb2NzL3VuaWZpZWQtYXBwb2ludG1lbnQtam91cm5leS5tZFxuICAgICAgLy8gwqc1ZCkgLSBhIGJ1c2luZXNzIHRoYXQncyBuZXZlciB0b3VjaGVkIHRoaXMgc2V0dGluZyBrZWVwcyB0b2RheSdzIHBpY2tlciBiZWhhdmlvci5cbiAgICAgIGNvbnN0IGFsbG93UGljayA9IHRoaXMuYnVzaW5lc3NTZXR0aW5ncz8uYWxsb3dTdGFmZlNlbGVjdGlvbiAhPT0gZmFsc2U7XG4gICAgICBpZiAoYW1iaWd1b3VzICYmIGFsbG93UGljaykge1xuICAgICAgICB0aGlzLnN0YWZmU2VhcmNoUXVlcnkgPSAnJztcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzdGFmZkxpc3RpbmcnO1xuICAgICAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcbiAgICAgICAgdGhpcy5jYW1lRnJvbVN0YWZmTGlzdGluZyA9IHRydWU7XG4gICAgICAgIC8vIFBpY2tpbmcgaXMgb3B0aW9uYWwgLSBDb250aW51ZSBpcyBlbmFibGVkIGltbWVkaWF0ZWx5IGVpdGhlciB3YXksIGFuZCB0aGUgYmFja2VuZFxuICAgICAgICAvLyBhdXRvLWFzc2lnbnMgdGhlIGxlYXN0LWJ1c3kgZWxpZ2libGUgc3RhZmYgZm9yIGFueSBsaW5lIGxlZnQgdW5waWNrZWQuXG4gICAgICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZmV0Y2hBbGxMaW5lU2xvdHMoKTtcbiAgICAgIH1cbiAgICB9LCAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgdGhpcy5yZXNvbHZpbmdDYXJ0ID0gZmFsc2U7XG4gICAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gZmFsc2U7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IHNldmVyaXR5OiAnZXJyb3InLCBzdW1tYXJ5OiAnVW5hYmxlIHRvIGNoZWNrIGF2YWlsYWJpbGl0eScsIGRldGFpbDogZXJyb3IuZXJyb3I/Lm1lc3NhZ2UgPz8gJ1BsZWFzZSB0cnkgYWdhaW4nIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0QWxsU3RhZmZGb3JQcm9kdWN0T25seUxpbmUoKSB7XG4gICAgLy8gQnVzaW5lc3NTZXR0aW5ncyNhbGxvd1N0YWZmU2VsZWN0aW9uIG9mZiAtIHNraXAgdGhlIHBpY2tlciBlbnRpcmVseSwgc2FtZSBhcyB0aGVcbiAgICAvLyBhbWJpZ3VvdXMtYnV0LWRpc2FibGVkIHNlcnZpY2UtbGluZSBjYXNlIGluIHJlc29sdmVDYXJ0KCkuIFRoZSBiYWNrZW5kIGF1dG8tYXNzaWducyB0aGVcbiAgICAvLyBsZWFzdC1idXN5IGVsaWdpYmxlIHN0YWZmIGZvciB0aGlzIGxpbmUgYXQgaG9sZCB0aW1lIChzZWUgZG9jcy91bmlmaWVkLWFwcG9pbnRtZW50LWpvdXJuZXkubWQgwqc1ZCkuXG4gICAgaWYgKHRoaXMuYnVzaW5lc3NTZXR0aW5ncz8uYWxsb3dTdGFmZlNlbGVjdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuZmV0Y2hBbGxMaW5lU2xvdHMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sb2FkZXIgPSB0cnVlO1xuICAgIGNvbnN0IHBheWxvYWQgPSB7IHNlcnZpY2VJZDogJycsIHN0b3JlSWQ6IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbj8uaWQgPz8gJycsIGJ1c2luZXNzSWQ6IHRoaXMuYnVzaW5lc3NJZCA/PyAnJyB9O1xuICAgIHRoaXMucmVzdFNlcnZpY2UuZ2V0QWxsU3RhZmYocGF5bG9hZCkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xuICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMuc3RhZmZEYXRhID0gKHJlcyB8fCBbXSkuZmlsdGVyKChzdGFmZjogYW55KSA9PlxuICAgICAgICBzdGFmZi5hY3RpdmUgPT09IHRydWUgJiYgc3RhZmYuYm9va2luZ0FsbG93ZWQgJiZcbiAgICAgICAgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnSE9NRV9WSVNJVCcgPyBzdGFmZi5ob21lVmlzaXRDYXBhYmxlIDogc3RhZmYudmlkZW9DYWxsQ2FwYWJsZSkpO1xuICAgICAgdGhpcy5zdGFmZkRhdGEuZm9yRWFjaCgoc3RhZmY6IGFueSkgPT4gc3RhZmYuc2VsZWN0ZWQgPSBmYWxzZSk7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3N0YWZmTGlzdGluZyc7XG4gICAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcbiAgICAgIHRoaXMuY2FtZUZyb21TdGFmZkxpc3RpbmcgPSB0cnVlO1xuICAgICAgLy8gT3B0aW9uYWwgLSBDb250aW51ZSBlbmFibGVzIGltbWVkaWF0ZWx5LCB0aGUgY3VzdG9tZXIgY2FuIHN0aWxsIHBpY2sgaWYgdGhleSB3YW50LlxuICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgIH0sICgpID0+IHsgdGhpcy5sb2FkZXIgPSBmYWxzZTsgfSk7XG4gIH1cblxuICBzZWxlY3RTdGFmZkZvclByb2R1Y3RPbmx5TGluZShzdGFmZjogYW55KSB7XG4gICAgdGhpcy5zdGFmZkRhdGEuZm9yRWFjaCgoczogYW55KSA9PiBzLnNlbGVjdGVkID0gZmFsc2UpO1xuICAgIHN0YWZmLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICB0aGlzLnJlc29sdmVkTGluZXNbMF0uc2VsZWN0ZWRTdGFmZklkID0gc3RhZmYuc3RhZmZJZDtcbiAgICB0aGlzLnJlc29sdmVkTGluZXNbMF0uc2VsZWN0ZWRTdGFmZk5hbWUgPSBzdGFmZi5zdGFmZk5hbWU7XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICB9XG5cbiAgc2VsZWN0U3RhZmZGb3JMaW5lKGxpbmU6IFJlc29sdmVkTGluZSwgc3RhZmY6IGFueSkge1xuICAgIGxpbmUuc2VsZWN0ZWRTdGFmZklkID0gc3RhZmYuaWQ7XG4gICAgbGluZS5zZWxlY3RlZFN0YWZmTmFtZSA9IHN0YWZmLm5hbWU7XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0aGlzLnJlc29sdmVkTGluZXMuZXZlcnkoKGw6IFJlc29sdmVkTGluZSkgPT4gISEobC5zdGFmZklkIHx8IGwuc2VsZWN0ZWRTdGFmZklkKSk7XG4gIH1cblxuICBmZXRjaEFsbExpbmVTbG90cygpIHtcbiAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2RhdGVTZWxlY3Rpb24nO1xuICAgIHRoaXMuYmFyV2lkdGggPSAnNTguNTcnO1xuICAgIGxldCBwZW5kaW5nID0gdGhpcy5yZXNvbHZlZExpbmVzLmxlbmd0aDtcbiAgICB0aGlzLnJlc29sdmVkTGluZXMuZm9yRWFjaCgobGluZTogUmVzb2x2ZWRMaW5lKSA9PiB7XG4gICAgICBjb25zdCBzdGFmZklkID0gbGluZS5zdGFmZklkIHx8IGxpbmUuc2VsZWN0ZWRTdGFmZklkO1xuICAgICAgY29uc3QgcGF5bG9hZDogYW55ID0ge1xuICAgICAgICBzdG9yZUlkOiB0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyA/IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbj8uaWQgOiB1bmRlZmluZWQsXG4gICAgICAgIHNlcnZpY2VJZHM6IGxpbmUuc2VydmljZXMubWFwKChzOiBhbnkpID0+IHMuaWQpLFxuICAgICAgICBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQsXG4gICAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXG4gICAgICAgIHN0YWZmSWQsXG4gICAgICAgIG1vZGU6IHRoaXMuc2VsZWN0ZWRNb2RlXG4gICAgICB9O1xuICAgICAgbGluZS5zbG90c0xvYWRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5yZXN0U2VydmljZS5nZXRCb29raW5nU2xvdHMocGF5bG9hZCkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xuICAgICAgICBsaW5lLnNsb3RzID0gKHJlcyB8fCBbXSkubWFwKCh2OiBzdHJpbmcpID0+ICh7IHNlbGVjdGVkOiBmYWxzZSwgdmFsdWU6IHYgfSkpO1xuICAgICAgICBsaW5lLnNsb3RzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICBwZW5kaW5nLS07XG4gICAgICAgIGlmIChwZW5kaW5nIDw9IDApIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcbiAgICAgIH0sICgpID0+IHtcbiAgICAgICAgbGluZS5zbG90c0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgcGVuZGluZy0tO1xuICAgICAgICBpZiAocGVuZGluZyA8PSAwKSB0aGlzLnNrZWxldG9uTG9hZGVyID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHNlbGVjdFNsb3RGb3JMaW5lKGxpbmU6IFJlc29sdmVkTGluZSwgc2xvdDogYW55KSB7XG4gICAgbGluZS5zbG90cy5mb3JFYWNoKChzOiBhbnkpID0+IHMuc2VsZWN0ZWQgPSBmYWxzZSk7XG4gICAgc2xvdC5zZWxlY3RlZCA9IHRydWU7XG4gICAgbGluZS5zZWxlY3RlZFNsb3QgPSBzbG90O1xuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdGhpcy5yZXNvbHZlZExpbmVzLmV2ZXJ5KChsOiBSZXNvbHZlZExpbmUpID0+ICEhbC5zZWxlY3RlZFNsb3QpO1xuICB9XG5cblxuICBjb252ZXJ0VG8yNEhvdXIodGltZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBbaG91ck1pbiwgbW9kaWZpZXJSYXddID0gdGltZS5zcGxpdCgnICcpO1xuICAgIGNvbnN0IG1vZGlmaWVyID0gbW9kaWZpZXJSYXcudG9VcHBlckNhc2UoKTsgLy8gXCJBTVwiIG9yIFwiUE1cIlxuICAgIGxldCBbaG91cnMsIG1pbnV0ZXNdID0gaG91ck1pbi5zcGxpdCgnOicpLm1hcChOdW1iZXIpO1xuXG4gICAgaWYgKG1vZGlmaWVyID09PSAnUE0nICYmIGhvdXJzIDwgMTIpIHtcbiAgICAgIGhvdXJzICs9IDEyO1xuICAgIH1cbiAgICBpZiAobW9kaWZpZXIgPT09ICdBTScgJiYgaG91cnMgPT09IDEyKSB7XG4gICAgICBob3VycyA9IDA7XG4gICAgfVxuXG4gICAgY29uc3QgaGggPSBob3Vycy50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgbW0gPSBtaW51dGVzLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCR7aGh9OiR7bW19ICR7bW9kaWZpZXJ9YDtcbiAgfVxuICBsb2FkZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNQcm9jZXNzaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIHRlcm1zQW5kQ29uZGl0aW9uczogYm9vbGVhbiA9IGZhbHNlO1xuICBjaGVja1JlcXVpcmVkVmFsdWVzKCkge1xuICAgIGNvbnN0IGlzRW1haWxWYWxpZCA9IHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLmVtYWlsICYmXG4gICAgICAvXlthLXowLTkuXyUrLV0rQFthLXowLTkuLV0rXFwuW2Etel17Miw0fSQvLnRlc3QodGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwuZW1haWwpO1xuXG4gICAgY29uc3QgYW55UG9saWN5ID0gdGhpcy5jYXJ0U2VydmljZXMuc29tZSgoczogYW55KSA9PiBzPy5jYW5jZWxsYXRpb25Qb2xpY3k/Lmxlbmd0aCA+IDAgfHwgcz8ucmVzY2hlZHVsZVBvbGljeT8ubGVuZ3RoID4gMCk7XG5cbiAgICBjb25zdCBhZGRyZXNzT2sgPSB0aGlzLnNlbGVjdGVkTW9kZSAhPT0gJ0hPTUVfVklTSVQnIHx8ICh0aGlzLmlzQWRtaW5Cb29raW5nXG4gICAgICA/ICEhKHRoaXMuaG9tZVZpc2l0QWRkcmVzcy5yZWNlaXZlck5hbWUgJiYgdGhpcy5ob21lVmlzaXRBZGRyZXNzLmFkZHJlc3NMaW5lMSAmJiB0aGlzLmhvbWVWaXNpdEFkZHJlc3MuY2l0eSAmJiB0aGlzLmhvbWVWaXNpdEFkZHJlc3MuemlwQ29kZSlcbiAgICAgIDogISF0aGlzLmRlZmF1bHRBZGRyZXNzKTtcblxuICAgIGlmICh0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lICYmXG4gICAgICBpc0VtYWlsVmFsaWQgJiZcbiAgICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyLmxlbmd0aCA9PT0gMTAgJiZcbiAgICAgIGFkZHJlc3NPaykge1xuICAgICAgaWYgKGFueVBvbGljeSkge1xuICAgICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMudGVybXNBbmRDb25kaXRpb25zID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVmcmVzaERlZmF1bHRBZGRyZXNzKCkge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLnVzZXJEZXRhaWxzPy5hZGRyZXNzRGV0YWlsc0xpc3QgPz8gW107XG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmRlZmF1bHRBZGRyZXNzID0gbnVsbDtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaWR4ID0gbGlzdC5maW5kSW5kZXgoKGE6IEFkZHJlc3NEZXRhaWxzKSA9PiBhLmRlZmF1bHQgPT09IHRydWUpO1xuICAgIHRoaXMuZGVmYXVsdEFkZHJlc3MgPSBpZHggIT09IC0xID8gbGlzdFtpZHhdIDogbGlzdFswXTtcbiAgICB0aGlzLmNoZWNrUmVxdWlyZWRWYWx1ZXMoKTtcbiAgfVxuXG4gIGNoYW5nZUFkZHJlc3MoKSB7XG4gICAgdGhpcy5tYXREaWFsb2cub3BlbihBZGRyZXNzTGlzdENvbXBvbmVudCwgeyBwYW5lbENsYXNzOiAnc2lkZXBhbmVsLWNsYXNzJywgZGF0YTogeyBhZGRyZXNzTGlzdDogdGhpcy51c2VyRGV0YWlscz8uYWRkcmVzc0RldGFpbHNMaXN0ID8/IFtdIH0gfSkuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy51c2VyRGV0YWlscyA9IHRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0VXNlcigpIGFzIFVzZXI7XG4gICAgICB0aGlzLnJlZnJlc2hEZWZhdWx0QWRkcmVzcygpO1xuICAgIH0pO1xuICB9XG5cbiAgYWRkQWRkcmVzcygpIHtcbiAgICB0aGlzLm1hdERpYWxvZy5vcGVuKEFkZHJlc3NDb21wb25lbnQsIHsgcGFuZWxDbGFzczogWydzaWRlcGFuZWwtY2xhc3MnLCAnYWRkcmVzcy1jbGFzcyddLCBkYXRhOiB7IGFkZHJlc3NMaXN0OiB0aGlzLnVzZXJEZXRhaWxzPy5hZGRyZXNzRGV0YWlsc0xpc3QgPz8gW10sIGVkaXRJbmRleDogLTEgfSB9KS5hZnRlckNsb3NlZCgpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnVzZXJEZXRhaWxzID0gdGhpcy5zdG9yYWdlU2VydmljZS5nZXRVc2VyKCkgYXMgVXNlcjtcbiAgICAgIHRoaXMucmVmcmVzaERlZmF1bHRBZGRyZXNzKCk7XG4gICAgfSk7XG4gIH1cblxuICBhcHBvaW50bWVudFBheWxvYWQ6IGFueSA9IHtcbiAgICBjdXN0b21lckRldGFpbDoge1xuICAgICAgbmFtZTogJycsXG4gICAgICBwaG9uZU51bWJlcjogJycsXG4gICAgICBlbWFpbDogJydcbiAgICB9XG4gIH1cbiAgYXBpU3RhdHVzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgY29uZmlybUJvb2tpbmcoKSB7XG4gICAgLy8gRGVmZW5zaXZlIHJlLWNoZWNrIChtaXJyb3JzIGNhcnQuY29tcG9uZW50LnRzJ3MgcHJvY2VlZFRvUGF5bWVudCgpIGd1YXJkKSAtIHRoZSBlbnRyeVxuICAgIC8vIGNoZWNrIGluIG5nT25Jbml0KCkgc2hvdWxkIG1ha2UgdGhpcyB1bnJlYWNoYWJsZSBpbiBwcmFjdGljZSwgYnV0IGEgbG9uZyBzbG90LXBpY2tpbmdcbiAgICAvLyBzZXNzaW9uIGNvdWxkIHN0aWxsIGxldCB0aGUgbG9naW4gc2Vzc2lvbiBleHBpcmUgYmVmb3JlIHRoZSBjdXN0b21lciByZWFjaGVzIHRoaXMgc3RlcC5cbiAgICAvLyBNdXN0IGV4Y2x1ZGUgaXNBZG1pbkJvb2tpbmcgc2FtZSBhcyBuZ09uSW5pdCdzIGd1YXJkIC0gYSBzdGFmZiBtZW1iZXIgYm9va2luZyBvbiBhXG4gICAgLy8gY3VzdG9tZXIncyBiZWhhbGYgaXMgbmV2ZXIgbG9nZ2VkIGluIHZpYSBzdG9yYWdlU2VydmljZS5nZXRVc2VyKCksIHNvIHdpdGhvdXQgdGhpcyBjaGVja1xuICAgIC8vIGV2ZXJ5IGFkbWluIGJvb2tpbmcgaGl0IHRoaXMgcmVkaXJlY3Qgb24gY29uZmlybSAocm91dGVyLm5hdmlnYXRlKFsnL2xvZ2luJ10pIHRocm93c1xuICAgIC8vIE5HMDQwMDIgaW4gdGhlIGFkbWluIGFwcCwgd2hpY2ggaGFzIG5vIHN1Y2ggcm91dGUpLlxuICAgIGlmICghdGhpcy5lZGl0ICYmICF0aGlzLnN0b3JhZ2VTZXJ2aWNlLmdldFVzZXIoKSAmJiAhdGhpcy5pc0FkbWluQm9va2luZykge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvbG9naW4nXSwgeyBxdWVyeVBhcmFtczogeyByZWRpcmVjdFRvOiB0aGlzLnJvdXRlci51cmwgfSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSB0cnVlO1xuICAgIGNvbnN0IGxpbmVzID0gdGhpcy5yZXNvbHZlZExpbmVzLm1hcCgobDogUmVzb2x2ZWRMaW5lKSA9PiB7XG4gICAgICBjb25zdCBzbG90ID0gbC5zZWxlY3RlZFNsb3Q7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzZXJ2aWNlSWRzOiBsLnNlcnZpY2VzLm1hcCgoczogYW55KSA9PiBzLmlkKSxcbiAgICAgICAgc3RhZmZJZDogbC5zdGFmZklkIHx8IGwuc2VsZWN0ZWRTdGFmZklkLFxuICAgICAgICBzdGFydFRpbWU6IHNsb3QgPyB0aGlzLmNvbnZlcnRUbzI0SG91cihzbG90LnZhbHVlKS5zbGljZSgwLCA1KSA6IHVuZGVmaW5lZFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGhvbGRQYXlsb2FkOiBhbnkgPSB7XG4gICAgICBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQsXG4gICAgICBtb2RlOiB0aGlzLnNlbGVjdGVkTW9kZSxcbiAgICAgIHN0b3JlSWQ6IHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnID8gdGhpcy5zZWxlY3RlZExvY2F0aW9uPy5pZCA6IHVuZGVmaW5lZCxcbiAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXG4gICAgICBjdXN0b21lckRldGFpbDogdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwsXG4gICAgICAvLyBOZXZlciB0cnVzdCBhIHN0cmF5IFwidXNlclwiIGNvb2tpZSBmb3IgYW4gYWRtaW4tY3JlYXRlZCBib29raW5nIC0gc3RhZmYgYXJlbid0IGxvZ2dlZCBpblxuICAgICAgLy8gYXMgdGhlIGN1c3RvbWVyIHRoZXkncmUgYm9va2luZyBmb3IsIHNvIHRoaXMgbXVzdCByZXNvbHZlIHNlcnZlci1zaWRlIGZyb20gdGhlIHR5cGVkXG4gICAgICAvLyBwaG9uZSBudW1iZXIgaW5zdGVhZCAoc2VlIEN1c3RvbWVySWRlbnRpdHlTZXJ2aWNlKSwgbm90IHdoYXRldmVyIGhhcHBlbnMgdG8gYmUgc2l0dGluZ1xuICAgICAgLy8gaW4gdGhpcyBicm93c2VyJ3Mgc3RvcmFnZSAoZS5nLiBsZWZ0b3ZlciBmcm9tIHRlc3RpbmcgdGhlIGxpdmUgc3RvcmVmcm9udCkuXG4gICAgICB1c2VySWQ6IHRoaXMuaXNBZG1pbkJvb2tpbmcgPyB1bmRlZmluZWQgOiAodGhpcy5zdG9yYWdlU2VydmljZS5nZXRVc2VyKCkgYXMgYW55KT8udXNlcklkLFxuICAgICAgbGluZXMsXG4gICAgICBwcm9kdWN0TGluZXM6IHRoaXMucHJvZHVjdENhcnRJdGVtcy5tYXAoKHA6IGFueSkgPT4gdGhpcy5ib29raW5nUHJvZHVjdENhcnRTZXJ2aWNlLnRvUHJvZHVjdExpbmUocCkpLFxuICAgICAgYWRkcmVzc0RldGFpbHM6IHRoaXMuc2VsZWN0ZWRNb2RlICE9PSAnSE9NRV9WSVNJVCcgPyB1bmRlZmluZWQgOlxuICAgICAgICB0aGlzLmlzQWRtaW5Cb29raW5nID8geyAuLi50aGlzLmhvbWVWaXNpdEFkZHJlc3MsIGluc3RydWN0aW9uczogdGhpcy5pbnN0cnVjdGlvbnMgfSA6XG4gICAgICAgIHRoaXMuZGVmYXVsdEFkZHJlc3MgPyB7XG4gICAgICAgICAgcmVjZWl2ZXJOYW1lOiB0aGlzLmRlZmF1bHRBZGRyZXNzLnJlY2VpdmVyTmFtZSxcbiAgICAgICAgICByZWNlaXZlclBob25lOiB0aGlzLmRlZmF1bHRBZGRyZXNzLnJlY2VpdmVyUGhvbmUsXG4gICAgICAgICAgYWRkcmVzc0xpbmUxOiB0aGlzLmRlZmF1bHRBZGRyZXNzLmFkZHJlc3NMaW5lMSxcbiAgICAgICAgICBjaXR5OiB0aGlzLmRlZmF1bHRBZGRyZXNzLmNpdHlOYW1lLFxuICAgICAgICAgIHN0YXRlOiB0aGlzLmRlZmF1bHRBZGRyZXNzLnN0YXRlTmFtZSxcbiAgICAgICAgICB6aXBDb2RlOiB0aGlzLmRlZmF1bHRBZGRyZXNzLnppcENvZGUsXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25zOiB0aGlzLmluc3RydWN0aW9uc1xuICAgICAgICB9IDogdW5kZWZpbmVkLFxuICAgICAgLy8gU2tpcHMgb25saW5lIGRlcG9zaXQgY29sbGVjdGlvbiBzZXJ2ZXItc2lkZSAoc2VlIEJvb2tpbmdHcm91cFNlcnZpY2UjYnVpbGRHcm91cCkgLSBhXG4gICAgICAvLyBzdGFmZi1jcmVhdGVkIGJvb2tpbmcgY2FuJ3QgY29tcGxldGUgYSBDYXNoZnJlZSBjaGVja291dCBpbmxpbmUgdGhlIHdheSB0aGUgbGl2ZSBzaXRlXG4gICAgICAvLyBkb2VzLCBzbyBpdCBtdXN0IG5ldmVyIGJlIHJvdXRlZCB0aHJvdWdoIHRoZSBwYXltZW50IGdhdGV3YXk7IGFueSBiYWxhbmNlIGlzIGNvbGxlY3RlZFxuICAgICAgLy8gaW4gcGVyc29uIC8gcmVjb3JkZWQgbGF0ZXIgdmlhIHRoZSBpbnZvaWNlIGluc3RlYWQuXG4gICAgICBhZG1pbkJvb2tpbmc6IHRoaXMuaXNBZG1pbkJvb2tpbmcgfHwgdGhpcy5pc0FkbWluQ29udGV4dCxcbiAgICB9O1xuXG4gICAgY29uc3QgaXNBZG1pbiA9IHRoaXMuaXNBZG1pbkJvb2tpbmcgfHwgdGhpcy5pc0FkbWluQ29udGV4dDtcbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmhvbGRCb29raW5nKGhvbGRQYXlsb2FkKS5zdWJzY3JpYmUoKGdyb3VwOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuYm9va2luZ0dyb3VwID0gZ3JvdXA7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZE1vZGUgIT09ICdTVE9SRV9WSVNJVCcgJiYgdGhpcy5wcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5ib29raW5nUHJvZHVjdENhcnRTZXJ2aWNlLmNsZWFyKHRoaXMuc2VsZWN0ZWRNb2RlIGFzIEJvb2tpbmdDYXJ0TW9kZSk7XG4gICAgICB9XG4gICAgICBpZiAoIWlzQWRtaW4gJiYgZ3JvdXAuc3RhdHVzID09PSAnSE9MRCcgJiYgZ3JvdXAudG90YWxDb2xsZWN0ZWRBdEJvb2tpbmcgPiAwKSB7XG4gICAgICAgIC8vIE11c3QgYWN0IG9uIHRoaXMgaW1tZWRpYXRlbHkgLSB0aGUgaG9sZCBleHBpcmVzIGluIDEwIG1pbnV0ZXMuXG4gICAgICAgIHRoaXMucmVzdFNlcnZpY2UuZ2VuZXJhdGVQYXltZW50VG9rZW4oZ3JvdXAuZ3JvdXBJZCkuc3Vic2NyaWJlKChvcmRlcjogYW55KSA9PiB7XG4gICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FwcG9pbnRtZW50UGF5bWVudElkJywgb3JkZXIucGdPcmRlcklkKTtcbiAgICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuX2V2ZW50U2VydmljZS5jYXNoRnJlZUV2ZW50LmVtaXQoeyBkYXRhOiB7IG9yZGVyU2lnbmF0dXJlOiBvcmRlci5vcmRlclNpZ25hdHVyZSB9IH0pO1xuICAgICAgICB9LCAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ1BheW1lbnQgRmFpbGVkJywgZGV0YWlsOiBlcnJvci5lcnJvcj8ubWVzc2FnZSB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzQWRtaW4gJiYgZ3JvdXAuc3RhdHVzID09PSAnSE9MRCcpIHtcbiAgICAgICAgLy8gVW5leHBlY3RlZDogdGhlIGJhY2tlbmQgc2hvdWxkIGhhdmUgYXV0by1jb25maXJtZWQgdGhpcyBhZG1pbiBib29raW5nIHdpdGggemVyb1xuICAgICAgICAvLyBkZXBvc2l0LiBTdXJmYWNlIGFuIGVycm9yIHJhdGhlciB0aGFuIHNpbGVudGx5IHNob3dpbmcgc3VjY2VzcyBmb3IgYSBib29raW5nIHRoYXQnc1xuICAgICAgICAvLyBzdGlsbCBleHBpcmluZyB1bmNvbmZpcm1lZC5cbiAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ0Jvb2tpbmcgRmFpbGVkJywgZGV0YWlsOiAnVGhpcyBib29raW5nIHJlcXVpcmVzIGEgZGVwb3NpdCBhbmQgY291bGQgbm90IGJlIGF1dG8tY29uZmlybWVkLiBQbGVhc2UgdHJ5IGFnYWluIG9yIGNvbnRhY3Qgc3VwcG9ydC4nIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hcGlTdGF0dXMgPSB0cnVlO1xuICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3N0YXR1c1RlbXBsYXRlJztcbiAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcxMDAnO1xuICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0sIChlcnJvcjogYW55KSA9PiB7XG4gICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICAgICAgdGhpcy5hcGlTdGF0dXMgPSBmYWxzZTtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdCb29raW5nIEZhaWxlZCcsIGRldGFpbDogZXJyb3IuZXJyb3I/Lm1lc3NhZ2UgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnb0JhY2soKSB7XG4gICAgaWYgKGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiUkVRVUVTVF9GUk9NXCIpID09PSAnRUNPTU1FUkNFJykge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvYWRtaW4vYXBwb2ludG1lbnRzL2xpc3QtYXBwb2ludG1lbnRzJ10pXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycnXSlcbiAgICB9XG4gIH1cblxuICBnb1RvTXlCb29raW5ncygpIHtcbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9wcm9maWxlJ10sIHsgcXVlcnlQYXJhbXM6IHsgdGFiOiAnTXkgQm9va2luZ3MnIH0gfSk7XG4gIH1cblxuICBnb1RvTGlzdGluZygpIHtcbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJyddKTtcbiAgfVxuXG4gIGdvVG9BcHBvaW50bWVudHNMaXN0KCkge1xuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2FkbWluL2FwcG9pbnRtZW50cy9saXN0LWFwcG9pbnRtZW50cyddKTtcbiAgfVxuXG4gIGJvb2tBbm90aGVyKCkge1xuICAgIHRoaXMucmVzZXRXaXphcmQoKTtcbiAgfVxufVxuIiwiPHAtdG9hc3QgcG9zaXRpb249XCJib3R0b20tcmlnaHRcIiBbYmFzZVpJbmRleF09XCIxMDAwMDAwMDAwMFwiIFthdXRvWkluZGV4XT1cInRydWVcIlxuICAgIFtzaG93VHJhbnNmb3JtT3B0aW9uc109XCJzY3JlZW5XaWR0aCA8IDQ3NSA/ICd0cmFuc2xhdGVZKC0xMDAlKScgOiAnJ1wiPjwvcC10b2FzdD5cbjxzZWN0aW9uIGNsYXNzPVwibWFpbl9zZWN0aW9uXCIgW2lkXT1cImRhdGE/LmlkXCIgc2ltcG9Ib3ZlciAoaG92ZXJpbmcpPVwic2hvd0VkaXRUYWJzKCRldmVudClcIlxuICAgIFtzaW1wb0JhY2tncm91bmRdPVwiYmFja2dyb3VuZEluZm9cIiBbc3R5bGUuLS1jb2xvci1hY2NlbnQtZ3JhZGllbnRdPVwiYWNjZW50Q29sb3JcIj5cbiAgICA8ZGl2IFtuZ0NsYXNzXT1cInsnaG92ZXJfZWZmZWN0JzogZWRpdH1cIiAqbmdJZj1cInNob3dFZGl0b3JzXCI+XG4gICAgICAgIDxzaW1wby1ob3Zlci1lbGVtZW50cyBbZGF0YV09XCJkYXRhXCIgW2luZGV4XT1cImluZGV4XCIgW2VkaXRPcHRpb25zXT1cImVkaXRcIj48L3NpbXBvLWhvdmVyLWVsZW1lbnRzPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJtYWluX2hlYWRlclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYWNrLWJ0biBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXIgY3Vyc29yLXBvaW50ZXIgZ2FwLTIgbWItM1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImdvQmFjaygpXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmtleWJvYXJkX2JhY2tzcGFjZTwvbWF0LWljb24+PHNwYW4gKm5nSWY9XCJzY3JlZW5XaWR0aCA+IDQ3NVwiPkJhY2sgdG8gSG9tZTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci10aXRsZVwiPlxuICAgICAgICAgICAgICAgIDxoMT5Cb29rIE5ldyBBcHBvaW50bWVudDwvaDE+XG4gICAgICAgICAgICAgICAgPHA+e3tidXNpbmVzc05hbWUgPz8gXCJOL0FcIiB9fTwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtZmlsbFwiIFtzdHlsZS53aWR0aF09XCJiYXJXaWR0aCArICclJ1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibWFpbl9ib2R5IHctMTAwIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ21vZGVTZWxlY3Rpb24nXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibW9kZVNlbGVjdGlvblwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAnc2VydmljZUxpc3RpbmcnXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXNrZWxldG9uTG9hZGVyXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInNlcnZpY2VMaXN0aW5nXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ2xvY2F0aW9uTGlzdGluZydcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2NhdGlvbkxpc3RpbmdcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ3N0YWZmTGlzdGluZydcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzdGFmZkxpc3RpbmdcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ2RhdGVTZWxlY3Rpb24nXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGF0ZVNlbGVjdGlvblwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiPT09J2NvbnRhY3REZXRhaWxzJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbnRhY3REZXRhaWxzXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWI9PT0ncGF5bWVudFRhYidcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJwYXltZW50VGFiXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWI9PT0nc3RhdHVzVGVtcGxhdGUnXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic3RhdHVzVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm1haW5fZm9vdGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWIhPT0nc3RhdHVzVGVtcGxhdGUnICYmIHNlbGVjdGVkVGFiIT09J21vZGVTZWxlY3Rpb24nXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb290ZXItYnV0dG9uc1wiXG4gICAgICAgICAgICBbbmdTdHlsZV09XCJ7J2p1c3RpZnktY29udGVudCc6IHNlbGVjdGVkVGFiICE9ICdzZXJ2aWNlTGlzdGluZycgPyAnc3BhY2UtYmV0d2VlbicgOiAnZW5kJ31cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFjay1mb290ZXItYnRuIGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cInByZXZpb3VzU3RlcCgpXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNlbGVjdGVkVGFiICE9ICdzZXJ2aWNlTGlzdGluZydcIj5CYWNrPC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImNvbnRpbnVlLWJ0blwiIFtkaXNhYmxlZF09XCIhYWN0aXZlQnV0dG9uXCIgKGNsaWNrKT1cIm5leHRTdGVwKClcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWIhPSdwYXltZW50VGFiJ1wiPnt7IWxvYWRlciA/ICdDb250aW51ZScgOiAnTG9hZGluZy4uLid9fTwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtZXZlbmx5IGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJzZWxlY3RlZFRhYj09PSdwYXltZW50VGFiJ1wiIChjbGljayk9XCJjb25maXJtQm9va2luZygpXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydwYXktbm93LWJ0bicgOiBib29raW5nR3JvdXA/LnRvdGFsQ29sbGVjdGVkQXRCb29raW5nID4gMCB8fCAhYm9va2luZ0dyb3VwLCdjb21wbGV0ZV9ib29raW5nJyA6IGJvb2tpbmdHcm91cCAmJiAhYm9va2luZ0dyb3VwPy50b3RhbENvbGxlY3RlZEF0Qm9va2luZ31cIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvMzA0MDEyYzE3NTM0NDAwODc5OTZCYWNrZ3JvdW5kLnBuZ1wiPlxuICAgICAgICAgICAgICAgIHt7aXNQcm9jZXNzaW5nID8gJ1BsZWFzZSB3YWl0Li4uJyA6ICdDb25maXJtIEJvb2tpbmcnfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvc2VjdGlvbj5cblxuPG5nLXRlbXBsYXRlICNtb2RlU2VsZWN0aW9uPlxuICAgIDxkaXYgY2xhc3M9XCJ3LTYwIHNlcnZpY2Vfc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1zZWxlY3Rpb25cIj5cbiAgICAgICAgICAgIDxoMj5Ib3cgd291bGQgeW91IGxpa2UgdGhpcz88L2gyPlxuICAgICAgICAgICAgPHA+Q2hvb3NlIGhvdyB5b3UnZCBsaWtlIHRvIGJlIHNlcnZlZDwvcD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlcy1ncmlkXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY2FyZFwiIChjbGljayk9XCJzZWxlY3RNb2RlKCdTVE9SRV9WSVNJVCcpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaWNvblwiPjxtYXQtaWNvbj5zdG9yZWZyb250PC9tYXQtaWNvbj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS10aXRsZVwiPlZpc2l0IG91ciBTdG9yZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kZXNjcmlwdGlvblwiPkNvbWUgdG8gdXMgYXQgb25lIG9mIG91ciBsb2NhdGlvbnM8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkXCIgKGNsaWNrKT1cInNlbGVjdE1vZGUoJ0hPTUVfVklTSVQnKVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWljb25cIj48bWF0LWljb24+aG9tZTwvbWF0LWljb24+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtdGl0bGVcIj5XZSBjb21lIHRvIHlvdTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kZXNjcmlwdGlvblwiPkEgcHJvZmVzc2lvbmFsIHZpc2l0cyB5b3VyIGFkZHJlc3M8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkXCIgKGNsaWNrKT1cInNlbGVjdE1vZGUoJ1ZJREVPX0NBTEwnKVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWljb25cIj48bWF0LWljb24+dmlkZW9jYW08L21hdC1pY29uPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXRpdGxlXCI+VmlkZW8gY29uc3VsdGF0aW9uPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWRlc2NyaXB0aW9uXCI+Q29ubmVjdCBvdmVyIGEgdmlkZW8gY2FsbDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNzZXJ2aWNlTGlzdGluZz5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBzZXJ2aWNlX3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2Utc2VsZWN0aW9uXCI+XG4gICAgICAgICAgICA8aDI+U2VsZWN0IGEgU2VydmljZTwvaDI+XG4gICAgICAgICAgICA8cD5DaG9vc2UgdGhlIHNlcnZpY2UocykgeW91J2QgbGlrZSB0byBib29rPHNwYW4gKm5nSWY9XCJjYXJ0U2VydmljZXMubGVuZ3RoID4gMFwiPiDigJQge3tjYXJ0U2VydmljZXMubGVuZ3RofX0gc2VsZWN0ZWQ8L3NwYW4+PC9wPlxuICAgICAgICAgICAgPHAgKm5nSWY9XCJwcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDBcIiBjbGFzcz1cImNhcnQtaGludFwiPnt7cHJvZHVjdENhcnRJdGVtcy5sZW5ndGh9fSBwcm9kdWN0KHMpIGFscmVhZHkgaW4geW91ciBjYXJ0IOKAlCB5b3UgY2FuIGNvbnRpbnVlIHdpdGhvdXQgcGlja2luZyBhIHNlcnZpY2UuPC9wPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZXMtZ3JpZFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHNlcnZpY2Ugb2Ygc2VydmljZURhdGFcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIlwiIChjbGljayk9XCJzZWxlY3RTZXJ2aWNlKHNlcnZpY2UpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NlcnZpY2UtY2FyZC1zZWxlY3RlZCcgOiBzZXJ2aWNlPy5zZWxlY3RlZCwgJ3NlcnZpY2UtY2FyZCc6ICFzZXJ2aWNlPy5zZWxlY3RlZCB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiIHNlcnZpY2UtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaWNvblwiPjxtYXQtaWNvbj5wZXJzb25fb3V0bGluZTwvbWF0LWljb24+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS10aXRsZVwiPnt7c2VydmljZT8ubmFtZSA/IHNlcnZpY2U/Lm5hbWUgOiAnTi9BJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtcHJpY2VcIj7igrl7e3NlcnZpY2U/LnByaWNlRGV0YWlscz8ucHJpY2UgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZT8ucHJpY2VEZXRhaWxzPy5wcmljZSA6ICdOL0EnIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWR1cmF0aW9uXCI+e3tzZXJ2aWNlPy5kdXJhdGlvbiA/IHNlcnZpY2U/LmR1cmF0aW9uIDogJ04vQSd9fSBtaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWRlc2NyaXB0aW9uXCIgKm5nSWY9XCJzZXJ2aWNlPy5kZXNjcmlwdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7c2VydmljZT8uZGVzY3JpcHRpb24gPyBzZXJ2aWNlPy5kZXNjcmlwdGlvbiA6ICdOL0EnfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhvbWUtdmlzaXRcIiAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyAmJiBzZXJ2aWNlPy5ob21lQXBwb2ludG1lbnRBdmFpbGFibGVcIj48aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvOTgyMTI2YzE3NTg2Mjg4NjMxMjlmdXJuaXR1cmVfMTY0MDYxMDMucG5nXCI+SG9tZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZpc2l0IEF2YWlsYWJsZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktc3RhdGUtbWluaVwiICpuZ0lmPVwic2VydmljZURhdGEubGVuZ3RoID09PSAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5pbnZlbnRvcnlfMjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgIDxoND5ObyBzZXJ2aWNlcyBhdmFpbGFibGU8L2g0PlxuICAgICAgICAgICAgICAgICAgICA8cCAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ0hPTUVfVklTSVQnXCI+Tm8gc2VydmljZXMgYXJlIGN1cnJlbnRseSBhdmFpbGFibGUgZm9yIGhvbWUgdmlzaXRzLjwvcD5cbiAgICAgICAgICAgICAgICAgICAgPHAgKm5nSWY9XCJzZWxlY3RlZE1vZGUgPT09ICdWSURFT19DQUxMJ1wiPk5vIHNlcnZpY2VzIGFyZSBjdXJyZW50bHkgYXZhaWxhYmxlIGZvciB2aWRlbyBjYWxscy48L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwic2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnXCI+VGhpcyBidXNpbmVzcyBoYXNuJ3QgYWRkZWQgYW55IHNlcnZpY2VzIHlldC48L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2xvY2F0aW9uTGlzdGluZz5cbiAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb25fc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyIGZsZXgtY29sdW1uIGFsaWduLWl0ZW1zLXN0YXJ0XCI+XG4gICAgICAgICAgICA8aDE+Q2hvb3NlIExvY2F0aW9uPC9oMT5cbiAgICAgICAgICAgIDxwPlNlbGVjdCB3aGVyZSB5b3UnZCBsaWtlIHRvIHJlY2VpdmUgdGhlIHNlcnZpY2U8L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1saXN0XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBsb2NhdGlvbiBvZiBsb2NhdGlvbkRhdGFcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJzZWxlY3RMb2NhdGlvbihsb2NhdGlvbilcIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdsb2NhdGlvbi1jYXJkLXNlbGVjdGVkJyA6IGxvY2F0aW9uPy5zZWxlY3RlZCwgJ2xvY2F0aW9uLWNhcmQnOiAhbG9jYXRpb24/LnNlbGVjdGVkIH1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWljb25cIj48aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzQyNzIyNmMxNzU4NjI5MTU3NzU4c3RvcmVfMzE3MTUxMC5wbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24tZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzPnt7bG9jYXRpb24/LnN0b3JlTmFtZSA/IGxvY2F0aW9uPy5zdG9yZU5hbWUgOiAnTi9BJ319PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPnt7bG9jYXRpb24/LmFkZHJlc3NEZXRhaWxzPy5hZGRyZXNzTGluZX19LCB7e2xvY2F0aW9uPy5hZGRyZXNzRGV0YWlscz8uY2l0eX19LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tsb2NhdGlvbj8uYWRkcmVzc0RldGFpbHM/LnN0YXRlfX0ge3tsb2NhdGlvbj8ucGluY29kZX19PC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktc3RhdGUtbWluaVwiICpuZ0lmPVwibG9jYXRpb25EYXRhLmxlbmd0aCA9PT0gMFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5zdG9yZWZyb250PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8aDQ+Tm8gbG9jYXRpb25zIGF2YWlsYWJsZTwvaDQ+XG4gICAgICAgICAgICAgICAgPHA+VGhlcmUncyBubyBsb2NhdGlvbiBhdmFpbGFibGUgZm9yIHRoaXMgc2VydmljZSByaWdodCBub3cuPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNzdGFmZkxpc3Rpbmc+XG4gICAgPGRpdiBjbGFzcz1cInctNjAgb3ZlcmZsb3ctaGlkZGVuIHN0YWZmLWxpc3RpbmdcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCB3LTEwMCBoLTEwMFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWhlYWRlciBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxoMT5TZWxlY3QgU3RhZmYgTWVtYmVyPC9oMT5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJzdGFmZi1zdWJ0aXRsZSBtYi0wXCI+Q2hvb3NlIHlvdXIgcHJlZmVycmVkIHByb2Zlc3Npb25hbCwgb3Igc2tpcCB0byBoYXZlIHVzIGFzc2lnbiB0aGUgYmVzdCBhdmFpbGFibGUgb25lPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlYXJjaC1jb250YWluZXIgbWItNFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VhcmNoLWlucHV0LXdyYXBwZXIgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwic2VhcmNoLWljb24gbWUtMlwiPnNlYXJjaDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInNlYXJjaC1pbnB1dCBib3JkZXItMCBmbGV4LWdyb3ctMVwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIHN0YWZmIG1lbWJlciBieSBuYW1lLi4uXCIgWyhuZ01vZGVsKV09XCJzdGFmZlNlYXJjaFF1ZXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjbGVhci1pY29uIGN1cnNvci1wb2ludGVyIG1zLTJcIiAqbmdJZj1cInN0YWZmU2VhcmNoUXVlcnlcIiAoY2xpY2spPVwic3RhZmZTZWFyY2hRdWVyeSA9ICcnXCI+Y2xvc2U8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gUHVyZSBwcm9kdWN0LW9ubHkgbGluZTogb25lIGZsYXQgc3RhZmYgbGlzdCwgc2FtZSBhcyB0aGUgb2xkIHNpbmdsZS1zZXJ2aWNlIGZsb3cgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWxpc3RcIiAqbmdJZj1cImNhcnRTZXJ2aWNlcy5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3RhZmYgb2YgZmlsdGVyZWRTdGFmZlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQgcm91bmRlZC0zIHAtM1wiIChjbGljayk9XCJzZWxlY3RTdGFmZkZvclByb2R1Y3RPbmx5TGluZShzdGFmZilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3N0YWZmLWNhcmQtc2VsZWN0ZWQnIDogc3RhZmY/LnNlbGVjdGVkLCAnc3RhZmYtY2FyZCc6ICFzdGFmZj8uc2VsZWN0ZWQgfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuIHctMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtYXZhdGFyIHJvdW5kZWQtY2lyY2xlIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlciBtZS00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tzdGFmZj8uc3RhZmZOYW1lLnNsaWNlKDAsMikudG9VcHBlckNhc2UoKX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1kZXRhaWxzIGZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic3RhZmYtbmFtZVwiPnt7KHN0YWZmPy5zdGFmZk5hbWUgPyBzdGFmZj8uc3RhZmZOYW1lIDogJ04vQScpIHwgdGl0bGVjYXNlfX08L2gzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwic3RhZmYtc3BlY2lhbHR5XCI+e3soYnVzaW5lc3NOYW1lICYmIGJ1c2luZXNzTmFtZSAhPT0gJ04vQScpID8gYnVzaW5lc3NOYW1lIDogJ0Jvb2tpbmcgU3BlY2lhbGlzdCd9fTwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlbGVjdGlvbi1pbmRpY2F0b3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGVja21hcmstY2lyY2xlLW1pbmkgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCIgW2NsYXNzLnNlbGVjdGVkXT1cInN0YWZmPy5zZWxlY3RlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInN0YWZmPy5zZWxlY3RlZFwiPmNoZWNrPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlLW1pbmlcIiAqbmdJZj1cImZpbHRlcmVkU3RhZmYubGVuZ3RoID09PSAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YmFkZ2U8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0Pk5vIHN0YWZmIGF2YWlsYWJsZTwvaDQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cD5UaGVyZSdzIG5vIHN0YWZmIG1lbWJlciBhdmFpbGFibGUgZm9yIHRoaXMgc2VydmljZSByaWdodCBub3cuPC9wPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gQnVuZGxlZCBjYXJ0OiBvbmUgcG9vbCBwZXIgbGluZSB0aGF0IHJlc29sdXRpb24gY291bGRuJ3QgY29sbGFwc2UgdG8gYSBzaW5nbGUgcHJvdmlkZXIgLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNhcnRTZXJ2aWNlcy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1saW5lLWdyb3VwIG1iLTRcIiAqbmdGb3I9XCJsZXQgbGluZSBvZiByZXNvbHZlZExpbmVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibGluZS5jYW5kaWRhdGVTdGFmZlBvb2w/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoNCBjbGFzcz1cIm1iLTJcIj5Gb3Ige3tsaW5lLnNlcnZpY2VzLmxlbmd0aH19IHNlcnZpY2Uocyk6IHt7IChsaW5lLnNlcnZpY2VzIHwgc2xpY2U6MDozKS5sZW5ndGggPyAnJyA6ICcnIH19PHNwYW4gKm5nRm9yPVwibGV0IHMgb2YgbGluZS5zZXJ2aWNlczsgbGV0IGxhc3QgPSBsYXN0XCI+e3tzLm5hbWV9fXt7bGFzdCA/ICcnIDogJywgJ319PC9zcGFuPjwvaDQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWxpc3QgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdGFmZiBvZiBsaW5lLmNhbmRpZGF0ZVN0YWZmUG9vbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQgcm91bmRlZC0zIHAtM1wiIChjbGljayk9XCJzZWxlY3RTdGFmZkZvckxpbmUobGluZSwgc3RhZmYpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzdGFmZi1jYXJkLXNlbGVjdGVkJyA6IGxpbmUuc2VsZWN0ZWRTdGFmZklkID09PSBzdGFmZi5pZCwgJ3N0YWZmLWNhcmQnOiBsaW5lLnNlbGVjdGVkU3RhZmZJZCAhPT0gc3RhZmYuaWQgfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuIHctMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtYXZhdGFyIHJvdW5kZWQtY2lyY2xlIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlciBtZS00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tzdGFmZj8ubmFtZT8uc2xpY2UoMCwyKT8udG9VcHBlckNhc2UoKX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1kZXRhaWxzIGZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic3RhZmYtbmFtZVwiPnt7KHN0YWZmPy5uYW1lID8gc3RhZmY/Lm5hbWUgOiAnTi9BJykgfCB0aXRsZWNhc2V9fTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWxlY3Rpb24taW5kaWNhdG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hlY2ttYXJrLWNpcmNsZS1taW5pIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiIFtjbGFzcy5zZWxlY3RlZF09XCJsaW5lLnNlbGVjdGVkU3RhZmZJZCA9PT0gc3RhZmYuaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJsaW5lLnNlbGVjdGVkU3RhZmZJZCA9PT0gc3RhZmYuaWRcIj5jaGVjazwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbXB0eS1zdGF0ZS1taW5pXCIgKm5nSWY9XCIhbGluZS5jYW5kaWRhdGVTdGFmZlBvb2w/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5iYWRnZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGg0Pk5vIHN0YWZmIGF2YWlsYWJsZTwvaDQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+Tm8gc3RhZmYgbWVtYmVyIGlzIGF2YWlsYWJsZSBmb3Ige3tsaW5lLnNlcnZpY2VzLmxlbmd0aH19IHNlcnZpY2UocykgaW4gdGhpcyBsaW5lLjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjZGF0ZVNlbGVjdGlvbj5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBkYXRlX3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGgtMTAwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyIGgtMTAwXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGV0aW1lLWhlYWRlciBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxoMT5TZWxlY3QgRGF0ZSAmIFRpbWU8L2gxPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImRhdGV0aW1lLXN1YnRpdGxlIG1iLTBcIiAqbmdJZj1cIiFjYW1lRnJvbVN0YWZmTGlzdGluZ1wiPkNob29zZSB3aGVuIHlvdSdkIGxpa2UgeW91ciBhcHBvaW50bWVudDwvcD5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJkYXRldGltZS1zdWJ0aXRsZSBtYi0wXCIgKm5nSWY9XCJjYW1lRnJvbVN0YWZmTGlzdGluZ1wiPvCfk4Uge3tzZWxlY3RlZERhdGVTdHJ9fTwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTQgbWFpbl9jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFjYW1lRnJvbVN0YWZmTGlzdGluZ1wiIFtuZ0NsYXNzXT1cInsndy01MCcgOiBzY3JlZW5XaWR0aCA+IDQ3NSAsICd3LTEwMCc6c2NyZWVuV2lkdGggPCA0NzV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1jYXJkIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInNlY3Rpb24tdGl0bGVcIj5TZWxlY3QgRGF0ZTwvaDM+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItY29udGFpbmVyIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZGF0ZS1pbnB1dCBib3JkZXItMCByb3VuZGVkLTJcIiBwbGFjZWhvbGRlcj1cImRkLW1tLXl5eXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkRGF0ZVN0clwiIHJlYWRvbmx5IChjbGljayk9XCJ0b2dnbGVDYWxlbmRhcigkZXZlbnQpXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXMtMlwiIChjbGljayk9XCJ0b2dnbGVDYWxlbmRhcigkZXZlbnQpXCI+Y2FsZW5kYXJfdG9kYXk8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwb3NpdGlvbi1yZWxhdGl2ZVwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGVwaWNrZXItcG9wb3ZlclwiICpuZ0lmPVwic2hvd0NhbGVuZGFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNhbGVuZGFyIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkRGF0ZVwiIFtkYXRlRmlsdGVyXT1cImRhdGVGaWx0ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZENoYW5nZSk9XCJvbkRhdGVTZWxlY3RlZCgkZXZlbnQpXCIgY2xhc3M9XCJkYXRlcGlja2VyLWNhbGVuZGFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBPbmUgc2xvdC1waWNrZXIgcGVyIHJlc29sdmVkIGxpbmUsIHNpZGUgYnkgc2lkZSB3aGVuIHRoZXJlJ3MgbW9yZSB0aGFuIG9uZSAoZGVzaWduIGRvYyDCpzNiKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWVfc2VsZWN0aW9uXCIgW25nQ2xhc3NdPVwieyd3LTUwJyA6IHNjcmVlbldpZHRoID4gNDc1ICYmICFjYW1lRnJvbVN0YWZmTGlzdGluZywgJ3ctMTAwJzpzY3JlZW5XaWR0aCA8IDQ3NSB8fCBjYW1lRnJvbVN0YWZmTGlzdGluZ31cIiAqbmdJZj1cInJlc29sdmVkTGluZXMubGVuZ3RoIDw9IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLWNhcmQgY2FyZCBoLTEwMCByb3VuZGVkLTMgcC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPkF2YWlsYWJsZSBUaW1lczwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBnLTIgbWItNCBvdmVyZmxvdy1zY3JvbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFza2VsZXRvbkxvYWRlciAmJiByZXNvbHZlZExpbmVzWzBdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTRcIiAqbmdGb3I9XCJsZXQgdGltZSBvZiByZXNvbHZlZExpbmVzWzBdLnNsb3RzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdCByb3VuZGVkLTJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwidGltZS5zZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RTbG90Rm9yTGluZShyZXNvbHZlZExpbmVzWzBdLCB0aW1lKVwiPnt7dGltZSA/IHRpbWU/LnZhbHVlIDogJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIiAqbmdJZj1cInJlc29sdmVkTGluZXNbMF0uc2xvdHMubGVuZ3RoID09PSAwXCI+Tm8gc2xvdHMgYXZhaWxhYmxlIGZvciB0aGlzIGRhdGUuPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gTXVsdGktbGluZSBjYXNlOiBlYWNoIGxpbmUgZ2V0cyBpdHMgb3duIGZ1bGwtd2lkdGggY2FyZCB3aXRoIGEgc3RhZmYgaGVhZGVyIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTQgbWFpbl9jb250YWluZXIgZmxleC13cmFwXCIgKm5nSWY9XCJyZXNvbHZlZExpbmVzLmxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwXCIgKm5nRm9yPVwibGV0IGxpbmUgb2YgcmVzb2x2ZWRMaW5lc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tY2FyZCBjYXJkIHJvdW5kZWQtMyBwLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+UHJvZmVzc2lvbmFsOiB7e2xpbmUuc3RhZmZOYW1lIHx8IGxpbmUuc2VsZWN0ZWRTdGFmZk5hbWUgfHwgJ1RvIGJlIGFzc2lnbmVkJ319PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTJcIiAqbmdJZj1cImxpbmUuc2VydmljZXMubGVuZ3RoXCI+PHNwYW4gKm5nRm9yPVwibGV0IHMgb2YgbGluZS5zZXJ2aWNlczsgbGV0IGxhc3QgPSBsYXN0XCI+e3tzLm5hbWV9fXt7bGFzdCA/ICcnIDogJywgJ319PC9zcGFuPjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IGctMiBtYi0yIG92ZXJmbG93LXNjcm9sbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxpbmUuc2xvdHNMb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTRcIiAqbmdGb3I9XCJsZXQgdGltZSBvZiBsaW5lLnNsb3RzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdCByb3VuZGVkLTJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwidGltZS5zZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RTbG90Rm9yTGluZShsaW5lLCB0aW1lKVwiPnt7dGltZSA/IHRpbWU/LnZhbHVlIDogJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIiAqbmdJZj1cImxpbmUuc2xvdHMubGVuZ3RoID09PSAwXCI+Tm8gc2xvdHMgYXZhaWxhYmxlIGZvciB0aGlzIGRhdGUuPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjY29udGFjdERldGFpbHM+XG4gICAgPGRpdiBjbGFzcz1cInctNjAgY29udGFjdF9zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb250YWN0LWhlYWRlciBtYi0yXCI+XG4gICAgICAgICAgICA8aDE+Q29udGFjdCBEZXRhaWxzPC9oMT5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY29udGFjdC1zdWJ0aXRsZSBtYi0wXCI+UHJvdmlkZSB5b3VyIGNvbnRhY3QgaW5mb3JtYXRpb248L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTMgZGV0YWlsc19jb250YWluZXIgZmxleC1jb2x1bW4gdy0xMDBcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsndy01MCcgOiBzZWxlY3RlZE1vZGUgPT09ICdIT01FX1ZJU0lUJywgJ3ctMTAwJyA6IHNlbGVjdGVkTW9kZSAhPT0gJ0hPTUVfVklTSVQnfVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1zZWN0aW9uIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPlBlcnNvbmFsIEluZm9ybWF0aW9uPC9oMz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVsbCBOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVxdWlyZWQtYXN0ZXJpc2tcIj4qPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiY2hlY2tSZXF1aXJlZFZhbHVlcygpXCIgc2ltcG9MZXR0ZXJzT25seT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbWFpbCBBZGRyZXNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVxdWlyZWQtYXN0ZXJpc2tcIj4qPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJlbWFpbFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJhcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwuZW1haWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuPVwiXlthLXowLTkuXyUrLV0rQFthLXowLTkuLV0rXFwuW2Etel17Miw0fSRcIiAjZW1haWxGaWVsZD1cIm5nTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiZW1haWxcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQaG9uZSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXF1aXJlZC1hc3Rlcmlza1wiPio8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRlbFwiIGNsYXNzPVwiZm9ybS1jb250cm9sICByb3VuZGVkLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiIHNpbXBvTnVtYmVyc09ubHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtb2JpbGVfbnVtYmVyJyA6IGFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlci5sZW5ndGggIT0gMTB9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBIb21lIFZpc2l0IGFkZHJlc3MuIEN1c3RvbWVyIGNvbnRleHQ6IHNhbWUgc2F2ZWQtYWRkcmVzcyBmbG93IGFzXG4gICAgICAgICAgICAgICAgICAgICBjaGVja291dC9Cb29rQXBwb2ludG1lbnRDb21wb25lbnQuIEFkbWluIGNvbnRleHQgKGlzQWRtaW5Cb29raW5nKTogbm9cbiAgICAgICAgICAgICAgICAgICAgIGxvZ2dlZC1pbiBjdXN0b21lciBhY2NvdW50IHRvIHJlYWQgYSBzYXZlZCBhZGRyZXNzIGJvb2sgZnJvbSwgc28gc3RhZmYgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgdGhlIGFkZHJlc3MgbWFudWFsbHkgaW5zdGVhZC4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIiAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ0hPTUVfVklTSVQnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXNlY3Rpb24gY2FyZCByb3VuZGVkLTMgcC00IGgtMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+SG9tZSBWaXNpdCBEZXRhaWxzPC9oMz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0FkbWluQm9va2luZzsgZWxzZSBtYW51YWxIb21lVmlzaXRBZGRyZXNzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNoaXBwaW5nLWluZm9cIiAqbmdJZj1cImRlZmF1bHRBZGRyZXNzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRyZXNzLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRyZXNzLW5hbWVcIj57e2RlZmF1bHRBZGRyZXNzPy5yZWNlaXZlck5hbWV9fSAoe3tkZWZhdWx0QWRkcmVzcz8uYWRkcmVzc1R5cGV9fSk8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGRyZXNzLWRldGFpbHNcIj57e2RlZmF1bHRBZGRyZXNzPy5hZGRyZXNzTGluZTF9fSwge3tkZWZhdWx0QWRkcmVzcz8uY2l0eU5hbWV9fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2RlZmF1bHRBZGRyZXNzPy5zdGF0ZU5hbWV9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vYmlsZS1udW1iZXJcIj5Nb2JpbGU6IHt7ZGVmYXVsdEFkZHJlc3M/LnJlY2VpdmVyUGhvbmV9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNoYW5nZS1hZGRyZXNzLWJ0biB3LTEwMFwiIChjbGljayk9XCJjaGFuZ2VBZGRyZXNzKClcIiAqbmdJZj1cImRlZmF1bHRBZGRyZXNzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQU5HRSBPUiBBREQgQUREUkVTU1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFkZExpbmtzXCIgKm5nSWY9XCIhZGVmYXVsdEFkZHJlc3NcIiAoY2xpY2spPVwiYWRkQWRkcmVzcygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1zLTJcIj5BZGQgYW4gYWRkcmVzczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI21hbnVhbEhvbWVWaXNpdEFkZHJlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+UmVjZWl2ZXIgTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnJlY2VpdmVyTmFtZVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlJlY2VpdmVyIFBob25lPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZWxcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIHNpbXBvTnVtYmVyc09ubHkgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnJlY2VpdmVyUGhvbmVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5BZGRyZXNzIExpbmUgMTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLmFkZHJlc3NMaW5lMVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPkFkZHJlc3MgTGluZSAyIChvcHRpb25hbCk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIFsobmdNb2RlbCldPVwiaG9tZVZpc2l0QWRkcmVzcy5hZGRyZXNzTGluZTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPkNpdHk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIiBbKG5nTW9kZWwpXT1cImhvbWVWaXNpdEFkZHJlc3MuY2l0eVwiIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlN0YXRlPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnN0YXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlBpbmNvZGU8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIHNpbXBvTnVtYmVyc09ubHkgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnppcENvZGVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0wIG10LTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5TcGVjaWFsIEluc3RydWN0aW9uczwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tdGV4dGFyZWEgcm91bmRlZC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJBbnkgc3BlY2lhbCBpbnN0cnVjdGlvbnMgZm9yIHRoZSBwcm9mZXNzaW9uYWwgKG9wdGlvbmFsKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaW5zdHJ1Y3Rpb25zXCI+PC90ZXh0YXJlYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljaWVzLWNvbnRhaW5lclwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJjYXJ0U2VydmljZXNbMF0/LmNhbmNlbGxhdGlvblBvbGljeT8ubGVuZ3RoID4gMCB8fCBjYXJ0U2VydmljZXNbMF0/LnJlc2NoZWR1bGVQb2xpY3k/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgIDxoMiBjbGFzcz1cInBvbGljaWVzLXRpdGxlXCI+UG9saWNpZXMgJiBUZXJtczwvaDI+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWl0ZW1zLWNvbnRhaW5lciBkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljeS1pdGVtIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNob3dDYW5jZWxsYXRpb25Qb2xpY3kgPSAhc2hvd0NhbmNlbGxhdGlvblBvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwicG9saWN5LXRpdGxlXCI+Q2FuY2VsbGF0aW9uIFBvbGljeTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWFycm93IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPjxtYXQtaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFzaG93Q2FuY2VsbGF0aW9uUG9saWN5XCI+a2V5Ym9hcmRfYXJyb3dfcmlnaHQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInNob3dDYW5jZWxsYXRpb25Qb2xpY3lcIj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbmNlbGxhdGlvbl9wb2xpY2llcyBkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTIgZnctNTAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2hvd0NhbmNlbGxhdGlvblBvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nRm9yPVwibGV0IHBvbGljeSBvZiBjYXJ0U2VydmljZXNbMF0/LmNhbmNlbGxhdGlvblBvbGljeVwiPiYjODIyNjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3BvbGljeX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWl0ZW0gZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd1JlZHVjaW5nUG9saWN5ID0gIXNob3dSZWR1Y2luZ1BvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwicG9saWN5LXRpdGxlXCI+UmVzY2hlZHVsaW5nIFBvbGljeTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWFycm93IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPjxtYXQtaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFzaG93UmVkdWNpbmdQb2xpY3lcIj5rZXlib2FyZF9hcnJvd19yaWdodDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwic2hvd1JlZHVjaW5nUG9saWN5XCI+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW5jZWxsYXRpb25fcG9saWNpZXMgZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0yIGZ3LTUwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dSZWR1Y2luZ1BvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nRm9yPVwibGV0IHBvbGljeSBvZiBjYXJ0U2VydmljZXNbMF0/LnJlc2NoZWR1bGVQb2xpY3lcIj4mIzgyMjY7IHt7cG9saWN5fX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjY2VwdGFuY2Utc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJjdXN0b20tY2hlY2tib3hcIiBbKG5nTW9kZWwpXT1cInRlcm1zQW5kQ29uZGl0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJhY2NlcHRhbmNlLXRleHRcIiBzdHlsZT1cIm1hcmdpbi1ib3R0b206MHB4ICFpbXBvcnRhbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEkgdW5kZXJzdGFuZCBhbmQgYWNjZXB0IHRoZSBjYW5jZWxsYXRpb24gJiByZXNjaGVkdWxpbmcgcG9saWNpZXMuXG4gICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjcGF5bWVudFRhYj5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBwYXltZW50X3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwIGgtMTAwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xMDAgZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBheW1lbnQtaGVhZGVyIG1iLTMgdy0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgxIHN0eWxlPVwiZm9udC1zaXplOjI0cHg7Zm9udC13ZWlnaHQ6IDYwMDtcIj5Cb29raW5nIFN1bW1hcnk8L2gxPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInBheW1lbnQtc3VidGl0bGUgbWItMFwiPlJldmlldyB5b3VyIGJvb2tpbmcgYmVmb3JlIGNvbmZpcm1pbmc8L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9va2luZy1zdW1tYXJ5LWNhcmRcIiBbbmdDbGFzc109XCJ7J3ctMTAwJyA6IHNjcmVlbldpZHRoIDwgNDc1LCd3LTUwJzpzY3JlZW5XaWR0aCA+IDQ3NX1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbGluZSBvZiByZXNvbHZlZExpbmVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJzdW1tYXJ5LXRpdGxlXCIgKm5nSWY9XCJyZXNvbHZlZExpbmVzLmxlbmd0aCA+IDFcIj5MaW5lIHt7aSArIDF9fTwvaDI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIiAqbmdGb3I9XCJsZXQgcyBvZiBsaW5lLnNlcnZpY2VzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj57e3MubmFtZX19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiBjbGFzcz1cImN1cnJlbmN5LXN5bWJvbFwiPuKCuTwvc3Bhbj57e3NlcnZpY2VQcmljZShzLmlkKX19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0lmPVwibGluZS5zdGFmZk5hbWUgfHwgbGluZS5zZWxlY3RlZFN0YWZmTmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+UHJvZmVzc2lvbmFsPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57e2xpbmUuc3RhZmZOYW1lIHx8IGxpbmUuc2VsZWN0ZWRTdGFmZk5hbWV9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIiAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+TG9jYXRpb248L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPnt7c2VsZWN0ZWRMb2NhdGlvbj8uc3RvcmVOYW1lID8/ICdOL0EnfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5EYXRlICYgVGltZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3tzZWxlY3RlZERhdGVTdHJ9fSBhdCB7e2xpbmUuc2VsZWN0ZWRTbG90Py52YWx1ZSA/PyAnTi9BJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb2R1Y3RDYXJ0SXRlbXMubGVuZ3RoID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgyIGNsYXNzPVwic3VtbWFyeS10aXRsZVwiPlByb2R1Y3RzPC9oMj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0Zvcj1cImxldCBwIG9mIHByb2R1Y3RDYXJ0SXRlbXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPnt7cC5pdGVtTmFtZX19IHh7e3AucXVhbnRpdHl9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+PHNwYW4gY2xhc3M9XCJjdXJyZW5jeS1zeW1ib2xcIj7igrk8L3NwYW4+e3socC5zZWxsaW5nUHJpY2UgPz8gcC5wcmljZSA/PyAwKSAqIChwLnF1YW50aXR5ID8/IDEpfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJzdW1tYXJ5LXRpdGxlXCI+UGF5bWVudDwvaDI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0lmPVwiZGVwb3NpdFRvdGFsID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5TZXJ2aWNlIGRlcG9zaXQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+PHNwYW4gY2xhc3M9XCJjdXJyZW5jeS1zeW1ib2xcIj7igrk8L3NwYW4+e3tkZXBvc2l0VG90YWx9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktcm93XCIgKm5nSWY9XCJob21lVmlzaXRDaGFyZ2UgPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPkhvbWUgdmlzaXQgY2hhcmdlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPjxzcGFuIGNsYXNzPVwiY3VycmVuY3ktc3ltYm9sXCI+4oK5PC9zcGFuPnt7aG9tZVZpc2l0Q2hhcmdlfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5Ub3RhbDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiBjbGFzcz1cImN1cnJlbmN5LXN5bWJvbFwiPuKCuTwvc3Bhbj57e3Jldmlld1RvdGFsfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwZW5kaW5nQXRBcHBvaW50bWVudFRvdGFsID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5EZXBvc2l0PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiBjbGFzcz1cImN1cnJlbmN5LXN5bWJvbFwiPuKCuTwvc3Bhbj57e2R1ZUF0Qm9va2luZ1RvdGFsfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5QZW5kaW5nIGF0IGFwcG9pbnRtZW50PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiBjbGFzcz1cImN1cnJlbmN5LXN5bWJvbFwiPuKCuTwvc3Bhbj57e3BlbmRpbmdBdEFwcG9pbnRtZW50VG90YWx9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNzdGF0dXNUZW1wbGF0ZT5cbiAgICA8ZGl2IGNsYXNzPVwiYm9va2luZy1jb25maXJtYXRpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInN1Y2Nlc3MtaWNvblwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoZWNrbWFyay1jaXJjbGVcIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvODgxMjkzYzE3NTg2OTU1Nzg1MThzdWNjZXNzLmdpZlwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0xMDAgaC0xMDBcIiAqbmdJZj1cImFwaVN0YXR1c1wiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiaHR0cHM6Ly9kMno5NDk3eHA4eGIxMi5jbG91ZGZyb250Lm5ldC9wcm9kLWltYWdlcy8zMjUwMDBjMTc1ODY5NTU2NDUxOGZhaWwuZ2lmXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTEwMCBoLTEwMFwiICpuZ0lmPVwiIWFwaVN0YXR1c1wiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb25maXJtYXRpb24tY29udGVudFwiPlxuICAgICAgICAgICAgPGgxIGNsYXNzPVwiY29uZmlybWF0aW9uLXRpdGxlXCI+e3thcGlTdGF0dXMgPyAnQm9va2luZyBDb25maXJtZWQhJyA6ICdCb29raW5nIEZhaWxlZCd9fTwvaDE+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImNvbmZpcm1hdGlvbi1tZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAge3thcGlTdGF0dXMgPyAnWW91ciBhcHBvaW50bWVudCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYm9va2VkLic6J0ZhaWxlZCB0byBib29rIHlvdSBhcHBvaW50bWVudC4gUGxlYXNlXG4gICAgICAgICAgICAgICAgdHJ5IGFnYWluIGxhdGVyJ319XG4gICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgIDwhLS0gVmlkZW8gQ2FsbCBsaW5rLCB3aGVuIGFscmVhZHkgcHJlc2VudCBvbiB0aGUgY29uZmlybWVkIGdyb3VwIChhIHBhaWQgVmlkZW8gQ2FsbCdzXG4gICAgICAgICAgICAgICAgIGxpbmsgb25seSBhcHBlYXJzIG9uY2UgcGF5bWVudCB2ZXJpZmljYXRpb24gY29tcGxldGVzLCBoYW5kbGVkIGVsc2V3aGVyZSAtIHNlZVxuICAgICAgICAgICAgICAgICB2ZXJpZnktcGF5bWVudC5jb21wb25lbnQudHMsIG5vdCB0aGlzIHNjcmVlbikuIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInZpZGVvLWNhbGwtbGluay1jYXJkIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzICYmIHNlbGVjdGVkTW9kZSA9PT0gJ1ZJREVPX0NBTEwnICYmIGJvb2tpbmdHcm91cD8udmlkZW9DYWxsTGlua1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLWNhcmRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZGV0YWlscy10aXRsZVwiPllvdXIgVmlkZW8gQ2FsbCBMaW5rPC9oMz5cbiAgICAgICAgICAgICAgICAgICAgPGEgW2hyZWZdPVwiYm9va2luZ0dyb3VwLnZpZGVvQ2FsbExpbmtcIiB0YXJnZXQ9XCJfYmxhbmtcIj57e2Jvb2tpbmdHcm91cC52aWRlb0NhbGxMaW5rfX08L2E+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCB3LTEwMCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtY2FyZFwiPlxuICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJkZXRhaWxzLXRpdGxlXCI+QXBwb2ludG1lbnQgRGV0YWlsczwvaDM+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLXJvd1wiICpuZ0Zvcj1cImxldCBsaW5lIG9mIHJlc29sdmVkTGluZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+e3tsaW5lLnNlcnZpY2VzLmxlbmd0aCA/IChsaW5lLnNlcnZpY2VzWzBdLm5hbWUpIDogJ1Byb2R1Y3RzJ319PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57e3NlbGVjdGVkRGF0ZVN0cn19IGF0IHt7bGluZS5zZWxlY3RlZFNsb3Q/LnZhbHVlID8/ICdOL0EnfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggdy0xMDAgYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIiAqbmdJZj1cImFwaVN0YXR1c1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLWNhcmRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZGV0YWlscy10aXRsZVwiPlBheW1lbnQ8L2gzPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIiAqbmdJZj1cImJvb2tpbmdHcm91cD8uaG9tZVZpc2l0Q2hhcmdlID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5Ib21lIHZpc2l0IGNoYXJnZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+4oK5e3tib29raW5nR3JvdXAuaG9tZVZpc2l0Q2hhcmdlfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+VG90YWw8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPuKCuXt7Ym9va2luZ1RvdGFsfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+UGFpZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+4oK5e3tib29raW5nUGFpZH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtcm93XCIgKm5nSWY9XCJib29raW5nRHVlID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5EdWU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPuKCuXt7Ym9va2luZ0R1ZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG9uZS1hY3Rpb25zIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc0FkbWluQ29udGV4dDsgZWxzZSBhZG1pbkRvbmVBY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZG9uZS1idG4gZG9uZS1idG4tcHJpbWFyeVwiIChjbGljayk9XCJnb1RvTXlCb29raW5ncygpXCI+VmlldyBteSBib29raW5nczwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImRvbmUtYnRuIGRvbmUtYnRuLXNlY29uZGFyeVwiIChjbGljayk9XCJnb1RvTGlzdGluZygpXCI+S2VlcCBzaG9wcGluZzwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjYWRtaW5Eb25lQWN0aW9ucz5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJkb25lLWJ0biBkb25lLWJ0bi1wcmltYXJ5XCIgKGNsaWNrKT1cImdvVG9BcHBvaW50bWVudHNMaXN0KClcIj5CYWNrIHRvIEFwcG9pbnRtZW50cyBMaXN0PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZG9uZS1idG4gZG9uZS1idG4tc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImJvb2tBbm90aGVyKClcIj5Cb29rIEFub3RoZXI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==