@cqa-lib/cqa-ui 1.1.43 → 1.1.45

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.
@@ -21,6 +21,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
21
21
  import * as i4 from '@angular/material/radio';
22
22
  import { MatRadioModule } from '@angular/material/radio';
23
23
  import { MatDatepickerModule } from '@angular/material/datepicker';
24
+ import * as i4$1 from '@angular/material/progress-spinner';
24
25
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
25
26
  import * as i2 from '@angular/material/tooltip';
26
27
  import { MatTooltipModule } from '@angular/material/tooltip';
@@ -7175,14 +7176,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
7175
7176
  }] } });
7176
7177
 
7177
7178
  class SimulatorComponent {
7178
- constructor() {
7179
+ constructor(sanitizer) {
7180
+ this.sanitizer = sanitizer;
7179
7181
  this.videoUrl = '';
7180
7182
  this.videoCurrentDuration = 0;
7181
7183
  this.stepMarkers = [];
7182
7184
  this.screenShotUrl = '';
7185
+ this.traceViewUrl = '';
7183
7186
  this.platformName = 'Web - Chrome';
7184
7187
  this.platformType = 'browser';
7185
7188
  this.isLive = false;
7189
+ this.liveStatus = 'In Progress';
7190
+ this.liveLoadingLabel = 'Loading...';
7191
+ this.isContentVideoLoading = false;
7192
+ this.failedStatusMessage = '';
7193
+ this.selectedView = 'video';
7186
7194
  this.videoTimeUpdate = new EventEmitter();
7187
7195
  this.videoPlay = new EventEmitter();
7188
7196
  this.videoPause = new EventEmitter();
@@ -7197,9 +7205,17 @@ class SimulatorComponent {
7197
7205
  ];
7198
7206
  this.videoEventListenerCleanup = null;
7199
7207
  this.lastSetDuration = -1;
7208
+ this.dragMouseMoveHandler = null;
7209
+ this.dragMouseUpHandler = null;
7210
+ this.traceViewerLoading = false;
7211
+ this.traceViewerError = false;
7212
+ this.safeTraceUrl = this.sanitizer.bypassSecurityTrustResourceUrl('');
7213
+ this.updateSegments();
7200
7214
  }
7201
7215
  ngAfterViewInit() {
7216
+ this.currentView = this.selectedView;
7202
7217
  this.attachVideoListeners();
7218
+ this.updateSafeTraceUrl();
7203
7219
  }
7204
7220
  ngOnChanges(changes) {
7205
7221
  var _a;
@@ -7209,11 +7225,22 @@ class SimulatorComponent {
7209
7225
  this.seekToTime(newDuration);
7210
7226
  }
7211
7227
  }
7228
+ if (changes['traceViewUrl']) {
7229
+ this.updateSafeTraceUrl();
7230
+ this.updateSegments();
7231
+ if (!this.traceViewUrl && this.currentView === 'trace') {
7232
+ this.currentView = 'video';
7233
+ }
7234
+ }
7235
+ if (changes['selectedView']) {
7236
+ this.currentView = changes['selectedView'].currentValue;
7237
+ }
7212
7238
  }
7213
7239
  ngOnDestroy() {
7214
7240
  if (this.videoEventListenerCleanup) {
7215
7241
  this.videoEventListenerCleanup();
7216
7242
  }
7243
+ this.removeDragListeners();
7217
7244
  }
7218
7245
  seekToTime(milliseconds) {
7219
7246
  var _a;
@@ -7254,8 +7281,10 @@ class SimulatorComponent {
7254
7281
  this.vplayer.nativeElement.currentTime = targetTimeSeconds;
7255
7282
  this.lastSetDuration = targetTimeSeconds * 1000;
7256
7283
  }
7257
- startDrag() {
7284
+ startDrag(event) {
7285
+ event.preventDefault();
7258
7286
  this.dragging = true;
7287
+ this.addDragListeners();
7259
7288
  }
7260
7289
  onDrag(event) {
7261
7290
  var _a;
@@ -7268,12 +7297,36 @@ class SimulatorComponent {
7268
7297
  }
7269
7298
  stopDrag() {
7270
7299
  var _a;
7271
- if (!this.dragging || !((_a = this.vplayer) === null || _a === void 0 ? void 0 : _a.nativeElement))
7300
+ if (!this.dragging)
7272
7301
  return;
7273
7302
  this.dragging = false;
7274
- const targetTimeSeconds = (this.progress / 100) * this.vplayer.nativeElement.duration;
7275
- this.vplayer.nativeElement.currentTime = targetTimeSeconds;
7276
- this.lastSetDuration = targetTimeSeconds * 1000;
7303
+ this.removeDragListeners();
7304
+ if ((_a = this.vplayer) === null || _a === void 0 ? void 0 : _a.nativeElement) {
7305
+ const targetTimeSeconds = (this.progress / 100) * this.vplayer.nativeElement.duration;
7306
+ this.vplayer.nativeElement.currentTime = targetTimeSeconds;
7307
+ this.lastSetDuration = targetTimeSeconds * 1000;
7308
+ }
7309
+ }
7310
+ addDragListeners() {
7311
+ this.removeDragListeners();
7312
+ this.dragMouseMoveHandler = (e) => {
7313
+ this.onDrag(e);
7314
+ };
7315
+ this.dragMouseUpHandler = () => {
7316
+ this.stopDrag();
7317
+ };
7318
+ document.addEventListener('mousemove', this.dragMouseMoveHandler);
7319
+ document.addEventListener('mouseup', this.dragMouseUpHandler);
7320
+ }
7321
+ removeDragListeners() {
7322
+ if (this.dragMouseMoveHandler) {
7323
+ document.removeEventListener('mousemove', this.dragMouseMoveHandler);
7324
+ this.dragMouseMoveHandler = null;
7325
+ }
7326
+ if (this.dragMouseUpHandler) {
7327
+ document.removeEventListener('mouseup', this.dragMouseUpHandler);
7328
+ this.dragMouseUpHandler = null;
7329
+ }
7277
7330
  }
7278
7331
  onVideoMetadataLoaded() {
7279
7332
  this.attachVideoListeners();
@@ -7281,6 +7334,10 @@ class SimulatorComponent {
7281
7334
  onVideoCanPlay() {
7282
7335
  this.attachVideoListeners();
7283
7336
  }
7337
+ onVideoEnded() {
7338
+ this.isPlaying = false;
7339
+ this.videoPause.emit();
7340
+ }
7284
7341
  attachVideoListeners() {
7285
7342
  if (this.videoEventListenerCleanup) {
7286
7343
  this.videoEventListenerCleanup();
@@ -7336,13 +7393,95 @@ class SimulatorComponent {
7336
7393
  const secs = Math.floor(seconds % 60);
7337
7394
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
7338
7395
  }
7396
+ getStatusBadgeClass() {
7397
+ const baseClasses = 'cqa-inline-flex cqa-items-center cqa-gap-1.5 cqa-px-[9px] cqa-py-[3px] cqa-rounded-[6px] cqa-h-[21px]';
7398
+ switch (this.liveStatus) {
7399
+ case 'In Progress':
7400
+ case 'Execution':
7401
+ return `${baseClasses} cqa-bg-[#E0F2FE] cqa-border cqa-border-[#7DD3FC]`;
7402
+ case 'Paused':
7403
+ return `${baseClasses} cqa-bg-[#FEF3C7] cqa-border cqa-border-[#FCD34D]`;
7404
+ case 'Aborted':
7405
+ return `${baseClasses} cqa-bg-[#FEE2E2] cqa-border cqa-border-[#FCA5A5]`;
7406
+ case 'Failed':
7407
+ return `${baseClasses} cqa-bg-[#FCD9D9] cqa-border cqa-border-[#F9BFBF]`;
7408
+ case 'Passed':
7409
+ return `${baseClasses} cqa-bg-[#D1FAE5] cqa-border cqa-border-[#6EE7B7]`;
7410
+ default:
7411
+ return `${baseClasses} cqa-bg-gray-200 cqa-border cqa-border-gray-300`;
7412
+ }
7413
+ }
7414
+ getStatusTextClass() {
7415
+ switch (this.liveStatus) {
7416
+ case 'In Progress':
7417
+ case 'Execution':
7418
+ return 'cqa-text-[10px] cqa-font-medium cqa-text-[#0284C7] cqa-leading-[15px]';
7419
+ case 'Paused':
7420
+ return 'cqa-text-[10px] cqa-font-medium cqa-text-[#D97706] cqa-leading-[15px]';
7421
+ case 'Aborted':
7422
+ return 'cqa-text-[10px] cqa-font-medium cqa-text-[#DC2626] cqa-leading-[15px]';
7423
+ case 'Failed':
7424
+ return 'cqa-text-[10px] cqa-font-medium cqa-text-[#C63535] cqa-leading-[15px]';
7425
+ case 'Passed':
7426
+ return 'cqa-text-[10px] cqa-font-medium cqa-text-[#059669] cqa-leading-[15px]';
7427
+ default:
7428
+ return 'cqa-text-[10px] cqa-font-medium cqa-text-gray-600 cqa-leading-[15px]';
7429
+ }
7430
+ }
7431
+ get processedTraceUrl() {
7432
+ if (!this.traceViewUrl)
7433
+ return '';
7434
+ if (this.traceViewUrl.endsWith('.zip')) {
7435
+ const urlParams = new URLSearchParams({
7436
+ trace: this.traceViewUrl,
7437
+ hideHeader: 'true',
7438
+ hideBranding: 'true',
7439
+ embed: 'true',
7440
+ minimal: 'true',
7441
+ noHeader: 'true'
7442
+ });
7443
+ return `https://trace.playwright.dev/?${urlParams.toString()}`;
7444
+ }
7445
+ return this.traceViewUrl;
7446
+ }
7447
+ updateSafeTraceUrl() {
7448
+ const url = this.processedTraceUrl;
7449
+ if (url) {
7450
+ this.traceViewerLoading = true;
7451
+ this.traceViewerError = false;
7452
+ this.safeTraceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
7453
+ }
7454
+ else {
7455
+ this.traceViewerLoading = false;
7456
+ this.traceViewerError = false;
7457
+ this.safeTraceUrl = this.sanitizer.bypassSecurityTrustResourceUrl('');
7458
+ }
7459
+ }
7460
+ onTraceViewerLoad() {
7461
+ this.traceViewerLoading = false;
7462
+ this.traceViewerError = false;
7463
+ }
7464
+ onTraceViewerError() {
7465
+ this.traceViewerLoading = false;
7466
+ this.traceViewerError = true;
7467
+ }
7468
+ updateSegments() {
7469
+ const baseSegments = [
7470
+ { label: 'Screenshots', value: 'screenshots', icon: 'photo' },
7471
+ { label: 'Video', value: 'video', icon: 'videocam' },
7472
+ ];
7473
+ if (this.traceViewUrl) {
7474
+ baseSegments.push({ label: 'Trace', value: 'trace', icon: 'graphic_eq' });
7475
+ }
7476
+ this.segments = baseSegments;
7477
+ }
7339
7478
  }
7340
- SimulatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: SimulatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7341
- SimulatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: SimulatorComponent, selector: "cqa-simulator", inputs: { videoUrl: "videoUrl", videoCurrentDuration: "videoCurrentDuration", stepMarkers: "stepMarkers", screenShotUrl: "screenShotUrl", platformName: "platformName", platformType: "platformType", isLive: "isLive" }, outputs: { videoTimeUpdate: "videoTimeUpdate", videoPlay: "videoPlay", videoPause: "videoPause" }, viewQueries: [{ propertyName: "vplayer", first: true, predicate: ["vplayer"], descendants: true }, { propertyName: "timelineBar", first: true, predicate: ["timelineBar"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-ui-root\" style=\"background-color: #F3F4F6; height: 100%; display: flex; flex-direction: column;\" [ngStyle]=\"{\n position: isFullScreen ? 'fixed' : null,\n inset: isFullScreen ? '1rem' : null,\n zIndex: isFullScreen ? '50' : null,\n boxShadow: isFullScreen ? '0px 13px 25px -12px rgba(0, 0, 0, 0.25)' : null,\n borderRadius: isFullScreen ? '.5rem' : null,\n border: isFullScreen ? '1px solid #E5E7EB' : null,\n width: isFullScreen ? 'calc(100% - 32px)' : null,\n height: isFullScreen ? 'calc(100% - 32px)' : '100%',\n overflow: isFullScreen ? 'hidden' : null\n}\">\n <div class=\"cqa-w-full cqa-py-1 cqa-px-2 cqa-bg-[#FFFFFF]\" style=\"border-bottom: 1px solid #E5E7EB;box-shadow: 0px 1px 2px 0px #0000000D;\">\n <div class=\"cqa-w-full cqa-flex cqa-items-center cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center\">\n <div *ngIf=\"isLive\" class=\"cqa-h-[21px] cqa-inline-flex cqa-items-center cqa-gap-1.5 cqa-mr-2 cqa-px-[9px] cqa-py-[3px] cqa-bg-[#FCD9D9] cqa-rounded-[6px]\" style=\"border: 1px solid #F9BFBF;\">\n <span class=\"cqa-relative cqa-w-2 cqa-h-2 cqa-rounded-full cqa-bg-[#F47F7F]\" style=\"flex-shrink: 0;\">\n <span class=\"cqa-absolute cqa-inset-0 cqa-rounded-full cqa-bg-[#F47F7F] cqa-opacity-75 cqa-animate-ping\"></span>\n </span>\n <span class=\"cqa-text-[10px] cqa-font-medium cqa-text-[#C63535] cqa-leading-[15px]\">Live</span>\n </div>\n <mat-icon *ngIf=\"platformType === 'browser'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <g clip-path=\"url(#clip0_935_15847)\">\n <path\n d=\"M0.625 5C0.625 6.16032 1.08594 7.27312 1.90641 8.09359C2.72688 8.91406 3.83968 9.375 5 9.375C6.16032 9.375 7.27312 8.91406 8.09359 8.09359C8.91406 7.27312 9.375 6.16032 9.375 5C9.375 3.83968 8.91406 2.72688 8.09359 1.90641C7.27312 1.08594 6.16032 0.625 5 0.625C3.83968 0.625 2.72688 1.08594 1.90641 1.90641C1.08594 2.72688 0.625 3.83968 0.625 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path\n d=\"M3.125 5C3.125 3.83968 3.32254 2.72688 3.67417 1.90641C4.02581 1.08594 4.50272 0.625 5 0.625C5.49728 0.625 5.97419 1.08594 6.32582 1.90641C6.67746 2.72688 6.875 3.83968 6.875 5C6.875 6.16032 6.67746 7.27312 6.32582 8.09359C5.97419 8.91406 5.49728 9.375 5 9.375C4.50272 9.375 4.02581 8.91406 3.67417 8.09359C3.32254 7.27312 3.125 6.16032 3.125 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path d=\"M0.9375 6.45866H9.0625M0.9375 3.54199H9.0625\" stroke=\"#9CA3AF\" stroke-width=\"0.6\"\n stroke-linecap=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_935_15847\">\n <rect width=\"10\" height=\"10\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </mat-icon>\n <mat-icon *ngIf=\"platformType === 'device'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M7.08325 0.833008H2.91659C2.45635 0.833008 2.08325 1.2061 2.08325 1.66634V8.33301C2.08325 8.79324 2.45635 9.16634 2.91659 9.16634H7.08325C7.54349 9.16634 7.91658 8.79324 7.91658 8.33301V1.66634C7.91658 1.2061 7.54349 0.833008 7.08325 0.833008Z\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.5H5.00417\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </mat-icon>\n <p class=\"cqa-text-sm !cqa-text-[10px] cqa-text-[#6B7280] cqa-ml-2\">{{ platformName }}</p>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <cqa-segment-control \n [segments]=\"segments\" \n [value]=\"currentView\"\n (valueChange)=\"onSegmentChange($event)\">\n </cqa-segment-control>\n \n <div *ngIf=\"!isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Expand\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M6.25 1.25H8.75V3.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.74992 1.25L5.83325 4.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 8.74967L4.16667 5.83301\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3.75 8.75H1.25V6.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <div *ngIf=\"isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Exit full screen\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M8.75 6.25H6.25V8.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.25008 6.25L9.16675 9.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M0.833252 0.833008L3.74992 3.74967\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 3.75H3.75V1.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n </div>\n </div>\n <div class=\"cqa-w-full cqa-bg-[#F3F4F6] cqa-h-[calc(100%-41px)]\">\n <div *ngIf=\"currentView === 'video'\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center\">\n <div class=\"cqa-w-full cqa-py-4 cqa-flex cqa-items-center cqa-max-h-[calc(100%-35px)]\" *ngIf=\"videoUrl\" [ngClass]=\"{'!cqa-h-full': platformType === 'device'}\">\n <video\n #vplayer\n class=\"cqa-object-contain cqa-w-full cqa-min-h-[250px] cqa-max-h-full cqa-block cqa-bg-black\"\n [src]=\"videoUrl\"\n type=\"video/webm\"\n (loadedmetadata)=\"onVideoMetadataLoaded()\"\n (canplay)=\"onVideoCanPlay()\"\n ></video>\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!videoUrl\">\n No video recording found\n </div>\n \n <div class=\"cqa-px-2 cqa-py-2 cqa-bg-white\" style=\"border-top: 1px solid #E5E7EB;\" *ngIf=\"videoUrl\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button \n type=\"button\"\n class=\"cqa-bg-transparent cqa-border-none cqa-cursor-pointer !cqa-px-0 cqa-flex cqa-items-center cqa-justify-center hover:cqa-opacity-70 cqa-transition-opacity cqa-outline-none\"\n style=\"pointer-events: auto;\"\n (click)=\"togglePlay()\">\n <span *ngIf=\"!isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 2L13 8L3 14V2Z\" fill=\"#374151\"/>\n </svg>\n </span>\n <span *ngIf=\"isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"3\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n <rect x=\"10\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n </svg>\n </span>\n </button>\n \n <span class=\"cqa-text-[#9CA3AF] cqa-text-[9px] cqa-font-normal cqa-whitespace-nowrap cqa-select-none cqa-mr-[20px]\">\n {{ formatTime(vplayer?.nativeElement?.currentTime || 0) }}\n </span>\n \n <div \n #timelineBar\n class=\"cqa-relative cqa-h-1 cqa-bg-gray-200 cqa-rounded-full cqa-cursor-pointer cqa-flex-1\"\n (click)=\"onTimelineClick($event)\" \n (mousemove)=\"onDrag($event)\"\n (mouseup)=\"stopDrag()\" \n (mouseleave)=\"stopDrag()\">\n \n <div \n *ngFor=\"let step of stepMarkers\" \n class=\"cqa-absolute cqa-w-1 cqa-h-full cqa-top-0 cqa-rounded-sm\"\n [style.left.%]=\"getStepLeftPosition(step)\"\n [style.background]=\"getStepColor(step)\"\n style=\"pointer-events: none; z-index: 20;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-h-full cqa-bg-green-500 cqa-rounded-full cqa-transition-[width] cqa-duration-100\"\n [style.width.%]=\"progress\"\n style=\"pointer-events: none; z-index: 2;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-top-1/2 cqa-w-3 cqa-h-3 cqa-bg-green-600 cqa-rounded-full cqa-cursor-grab active:cqa-cursor-grabbing cqa-shadow-md\"\n [style.left.%]=\"progress\"\n style=\"transform: translate(-50%, -50%); z-index: 10;\"\n (mousedown)=\"startDrag()\">\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"currentView === 'screenshots'\" class=\"cqa-h-full\">\n <div class=\"cqa-w-full cqa-py-4 cqa-h-full cqa-flex cqa-items-center\" *ngIf=\"screenShotUrl\">\n <img\n [src]=\"screenShotUrl\"\n alt=\"Screenshot\"\n class=\"cqa-object-contain cqa-w-full cqa-max-h-full cqa-block cqa-bg-black cqa-mx-auto\"\n />\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!screenShotUrl\">\n No screenshot available\n </div>\n </div>\n </div>\n</div>", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled"], outputs: ["valueChange"] }], directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
7479
+ SimulatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: SimulatorComponent, deps: [{ token: i1$2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
7480
+ SimulatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: SimulatorComponent, selector: "cqa-simulator", inputs: { videoUrl: "videoUrl", videoCurrentDuration: "videoCurrentDuration", stepMarkers: "stepMarkers", screenShotUrl: "screenShotUrl", traceViewUrl: "traceViewUrl", platformName: "platformName", platformType: "platformType", isLive: "isLive", liveStatus: "liveStatus", liveLoadingLabel: "liveLoadingLabel", isContentVideoLoading: "isContentVideoLoading", failedStatusMessage: "failedStatusMessage", selectedView: "selectedView" }, outputs: { videoTimeUpdate: "videoTimeUpdate", videoPlay: "videoPlay", videoPause: "videoPause" }, viewQueries: [{ propertyName: "vplayer", first: true, predicate: ["vplayer"], descendants: true }, { propertyName: "timelineBar", first: true, predicate: ["timelineBar"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-ui-root\" style=\"background-color: #F3F4F6; height: 100%; display: flex; flex-direction: column;\" [ngStyle]=\"{\n position: isFullScreen ? 'fixed' : null,\n inset: isFullScreen ? '1rem' : null,\n zIndex: isFullScreen ? '50' : null,\n boxShadow: isFullScreen ? '0px 13px 25px -12px rgba(0, 0, 0, 0.25)' : null,\n borderRadius: isFullScreen ? '.5rem' : null,\n border: isFullScreen ? '1px solid #E5E7EB' : null,\n width: isFullScreen ? 'calc(100% - 32px)' : null,\n height: isFullScreen ? 'calc(100% - 32px)' : '100%',\n overflow: isFullScreen ? 'hidden' : null\n}\">\n <div class=\"cqa-w-full cqa-py-1 cqa-px-2 cqa-bg-[#FFFFFF]\" style=\"border-bottom: 1px solid #E5E7EB;box-shadow: 0px 1px 2px 0px #0000000D;\">\n <div class=\"cqa-w-full cqa-flex cqa-items-center cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center\">\n <div *ngIf=\"isLive\" class=\"cqa-h-[21px] cqa-inline-flex cqa-items-center cqa-gap-1.5 cqa-mr-2 cqa-px-[9px] cqa-py-[3px] cqa-bg-[#FCD9D9] cqa-rounded-[6px]\" style=\"border: 1px solid #F9BFBF;\">\n <span class=\"cqa-relative cqa-w-2 cqa-h-2 cqa-rounded-full cqa-bg-[#F47F7F]\" style=\"flex-shrink: 0;\">\n <span class=\"cqa-absolute cqa-inset-0 cqa-rounded-full cqa-bg-[#F47F7F] cqa-opacity-75 cqa-animate-ping\"></span>\n </span>\n <span class=\"cqa-text-[10px] cqa-font-medium cqa-text-[#C63535] cqa-leading-[15px]\">Live</span>\n </div>\n <mat-icon *ngIf=\"platformType === 'browser'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <g clip-path=\"url(#clip0_935_15847)\">\n <path\n d=\"M0.625 5C0.625 6.16032 1.08594 7.27312 1.90641 8.09359C2.72688 8.91406 3.83968 9.375 5 9.375C6.16032 9.375 7.27312 8.91406 8.09359 8.09359C8.91406 7.27312 9.375 6.16032 9.375 5C9.375 3.83968 8.91406 2.72688 8.09359 1.90641C7.27312 1.08594 6.16032 0.625 5 0.625C3.83968 0.625 2.72688 1.08594 1.90641 1.90641C1.08594 2.72688 0.625 3.83968 0.625 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path\n d=\"M3.125 5C3.125 3.83968 3.32254 2.72688 3.67417 1.90641C4.02581 1.08594 4.50272 0.625 5 0.625C5.49728 0.625 5.97419 1.08594 6.32582 1.90641C6.67746 2.72688 6.875 3.83968 6.875 5C6.875 6.16032 6.67746 7.27312 6.32582 8.09359C5.97419 8.91406 5.49728 9.375 5 9.375C4.50272 9.375 4.02581 8.91406 3.67417 8.09359C3.32254 7.27312 3.125 6.16032 3.125 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path d=\"M0.9375 6.45866H9.0625M0.9375 3.54199H9.0625\" stroke=\"#9CA3AF\" stroke-width=\"0.6\"\n stroke-linecap=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_935_15847\">\n <rect width=\"10\" height=\"10\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </mat-icon>\n <mat-icon *ngIf=\"platformType === 'device'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M7.08325 0.833008H2.91659C2.45635 0.833008 2.08325 1.2061 2.08325 1.66634V8.33301C2.08325 8.79324 2.45635 9.16634 2.91659 9.16634H7.08325C7.54349 9.16634 7.91658 8.79324 7.91658 8.33301V1.66634C7.91658 1.2061 7.54349 0.833008 7.08325 0.833008Z\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.5H5.00417\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </mat-icon>\n <p class=\"cqa-text-sm !cqa-text-[10px] cqa-text-[#6B7280] cqa-ml-2\">{{ platformName }}</p>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div *ngIf=\"isLive\" [ngClass]=\"getStatusBadgeClass()\">\n <span [ngClass]=\"getStatusTextClass()\">{{ liveStatus }}</span>\n </div>\n\n <ng-container *ngIf=\"!isLive\">\n <cqa-segment-control \n [segments]=\"segments\" \n [value]=\"currentView\"\n (valueChange)=\"onSegmentChange($event)\">\n </cqa-segment-control>\n \n <div *ngIf=\"!isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Expand\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M6.25 1.25H8.75V3.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.74992 1.25L5.83325 4.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 8.74967L4.16667 5.83301\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3.75 8.75H1.25V6.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <div *ngIf=\"isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Exit full screen\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M8.75 6.25H6.25V8.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.25008 6.25L9.16675 9.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M0.833252 0.833008L3.74992 3.74967\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 3.75H3.75V1.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"cqa-w-full cqa-bg-[#F3F4F6] cqa-h-[calc(100%-41px)]\">\n <!-- Live Content View -->\n <div *ngIf=\"isLive\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center cqa-relative\">\n <!-- Loading State -->\n <div *ngIf=\"isContentVideoLoading\" class=\"cqa-p-10 cqa-text-center cqa-h-full cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <div class=\"cqa-mb-4\">\n <mat-progress-spinner mode=\"indeterminate\" diameter=\"40\"></mat-progress-spinner>\n </div>\n <p class=\"cqa-text-gray-400 cqa-text-sm\">{{ liveLoadingLabel }}</p>\n </div>\n\n <!-- Live Content (when not loading) -->\n <div *ngIf=\"!isContentVideoLoading\" class=\"cqa-w-full cqa-h-full cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-relative\">\n <div *ngIf=\"liveStatus === 'Failed' && failedStatusMessage\" class=\"cqa-p-6 cqa-text-center cqa-w-full\">\n <div class=\"cqa-inline-flex cqa-items-center cqa-gap-2 cqa-px-4 cqa-py-3 cqa-bg-[#FCD9D9] cqa-border cqa-border-[#F9BFBF] cqa-rounded-lg\">\n <mat-icon style=\"width: 18px; height: 18px; color: #C63535; font-size: 18px;\">error</mat-icon>\n <p class=\"cqa-text-[#C63535] cqa-text-sm cqa-font-medium cqa-m-0\">{{ failedStatusMessage }}</p>\n </div>\n </div>\n <ng-content *ngIf=\"liveStatus !== 'Failed' || !failedStatusMessage\"></ng-content>\n </div>\n </div>\n\n <!-- Normal Video View (when not live) -->\n <div *ngIf=\"!isLive && currentView === 'video'\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center\">\n <div class=\"cqa-w-full cqa-py-4 cqa-flex cqa-items-center cqa-max-h-[calc(100%-35px)]\" *ngIf=\"videoUrl\" [ngClass]=\"{'!cqa-h-full': platformType === 'device'}\">\n <video\n #vplayer\n class=\"cqa-object-contain cqa-w-full cqa-min-h-[250px] cqa-max-h-full cqa-block cqa-bg-black\"\n [src]=\"videoUrl\"\n type=\"video/webm\"\n (loadedmetadata)=\"onVideoMetadataLoaded()\"\n (canplay)=\"onVideoCanPlay()\"\n (ended)=\"onVideoEnded()\"\n ></video>\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!videoUrl\">\n No video recording found\n </div>\n \n <div class=\"cqa-px-2 cqa-py-2 cqa-bg-white\" style=\"border-top: 1px solid #E5E7EB;\" *ngIf=\"videoUrl && !isLive\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button \n type=\"button\"\n class=\"cqa-bg-transparent cqa-border-none cqa-cursor-pointer !cqa-px-0 cqa-flex cqa-items-center cqa-justify-center hover:cqa-opacity-70 cqa-transition-opacity cqa-outline-none\"\n style=\"pointer-events: auto;\"\n (click)=\"togglePlay()\">\n <span *ngIf=\"!isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 2L13 8L3 14V2Z\" fill=\"#374151\"/>\n </svg>\n </span>\n <span *ngIf=\"isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"3\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n <rect x=\"10\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n </svg>\n </span>\n </button>\n \n <span class=\"cqa-text-[#9CA3AF] cqa-text-[9px] cqa-font-normal cqa-whitespace-nowrap cqa-select-none cqa-mr-[20px]\">\n {{ formatTime(vplayer?.nativeElement?.currentTime || 0) }}\n </span>\n \n <div \n #timelineBar\n class=\"cqa-relative cqa-h-1 cqa-bg-gray-200 cqa-rounded-full cqa-cursor-pointer cqa-flex-1\"\n (click)=\"onTimelineClick($event)\">\n \n <div \n *ngFor=\"let step of stepMarkers\" \n class=\"cqa-absolute cqa-w-1 cqa-h-full cqa-top-0 cqa-rounded-sm\"\n [style.left.%]=\"getStepLeftPosition(step)\"\n [style.background]=\"getStepColor(step)\"\n style=\"pointer-events: none; z-index: 20;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-h-full cqa-bg-green-500 cqa-rounded-full\"\n [style.width.%]=\"progress\"\n [style.transition]=\"dragging ? 'none' : 'width 100ms'\"\n style=\"pointer-events: none; z-index: 2;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-top-1/2 cqa-w-3 cqa-h-3 cqa-bg-green-600 cqa-rounded-full cqa-cursor-grab active:cqa-cursor-grabbing cqa-shadow-md\"\n [style.left.%]=\"progress\"\n style=\"transform: translate(-50%, -50%); z-index: 10;\"\n (mousedown)=\"startDrag($event)\">\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!isLive && currentView === 'screenshots'\" class=\"cqa-h-full\">\n <div class=\"cqa-w-full cqa-py-4 cqa-h-full cqa-flex cqa-items-center\" *ngIf=\"screenShotUrl\">\n <img\n [src]=\"screenShotUrl\"\n alt=\"Screenshot\"\n class=\"cqa-object-contain cqa-w-full cqa-max-h-full cqa-block cqa-bg-black cqa-mx-auto\"\n />\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!screenShotUrl\">\n No screenshot available\n </div>\n </div>\n\n <div *ngIf=\"!isLive && currentView === 'trace'\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center\">\n <div class=\"cqa-w-full cqa-h-full cqa-py-4 cqa-flex cqa-items-center cqa-max-h-[calc(100%-35px)] cqa-relative\" *ngIf=\"traceViewUrl\" [ngClass]=\"{'!cqa-h-full': platformType === 'device'}\">\n <iframe \n [src]=\"safeTraceUrl\" \n title=\"Trace Viewer\"\n class=\"cqa-object-contain cqa-w-full cqa-min-h-[250px] cqa-max-h-full cqa-block cqa-bg-black\"\n frameborder=\"0\"\n allowfullscreen\n width=\"100%\"\n height=\"100%\"\n loading=\"lazy\"\n (load)=\"onTraceViewerLoad()\"\n (error)=\"onTraceViewerError()\">\n </iframe>\n \n <div *ngIf=\"traceViewerLoading\" class=\"cqa-absolute cqa-inset-0 cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center cqa-z-10\">\n <div class=\"cqa-text-center cqa-text-gray-400 cqa-text-sm\">\n Loading trace viewer...\n </div>\n </div>\n \n <div *ngIf=\"traceViewerError\" class=\"cqa-absolute cqa-inset-0 cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center cqa-z-10\">\n <div class=\"cqa-text-center cqa-text-gray-400 cqa-text-sm\">\n Failed to load trace viewer\n </div>\n </div>\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!traceViewUrl\">\n No trace available\n </div>\n </div>\n </div>\n</div>", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled"], outputs: ["valueChange"] }, { type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }], directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
7342
7481
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: SimulatorComponent, decorators: [{
7343
7482
  type: Component,
7344
- args: [{ selector: 'cqa-simulator', template: "<div class=\"cqa-ui-root\" style=\"background-color: #F3F4F6; height: 100%; display: flex; flex-direction: column;\" [ngStyle]=\"{\n position: isFullScreen ? 'fixed' : null,\n inset: isFullScreen ? '1rem' : null,\n zIndex: isFullScreen ? '50' : null,\n boxShadow: isFullScreen ? '0px 13px 25px -12px rgba(0, 0, 0, 0.25)' : null,\n borderRadius: isFullScreen ? '.5rem' : null,\n border: isFullScreen ? '1px solid #E5E7EB' : null,\n width: isFullScreen ? 'calc(100% - 32px)' : null,\n height: isFullScreen ? 'calc(100% - 32px)' : '100%',\n overflow: isFullScreen ? 'hidden' : null\n}\">\n <div class=\"cqa-w-full cqa-py-1 cqa-px-2 cqa-bg-[#FFFFFF]\" style=\"border-bottom: 1px solid #E5E7EB;box-shadow: 0px 1px 2px 0px #0000000D;\">\n <div class=\"cqa-w-full cqa-flex cqa-items-center cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center\">\n <div *ngIf=\"isLive\" class=\"cqa-h-[21px] cqa-inline-flex cqa-items-center cqa-gap-1.5 cqa-mr-2 cqa-px-[9px] cqa-py-[3px] cqa-bg-[#FCD9D9] cqa-rounded-[6px]\" style=\"border: 1px solid #F9BFBF;\">\n <span class=\"cqa-relative cqa-w-2 cqa-h-2 cqa-rounded-full cqa-bg-[#F47F7F]\" style=\"flex-shrink: 0;\">\n <span class=\"cqa-absolute cqa-inset-0 cqa-rounded-full cqa-bg-[#F47F7F] cqa-opacity-75 cqa-animate-ping\"></span>\n </span>\n <span class=\"cqa-text-[10px] cqa-font-medium cqa-text-[#C63535] cqa-leading-[15px]\">Live</span>\n </div>\n <mat-icon *ngIf=\"platformType === 'browser'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <g clip-path=\"url(#clip0_935_15847)\">\n <path\n d=\"M0.625 5C0.625 6.16032 1.08594 7.27312 1.90641 8.09359C2.72688 8.91406 3.83968 9.375 5 9.375C6.16032 9.375 7.27312 8.91406 8.09359 8.09359C8.91406 7.27312 9.375 6.16032 9.375 5C9.375 3.83968 8.91406 2.72688 8.09359 1.90641C7.27312 1.08594 6.16032 0.625 5 0.625C3.83968 0.625 2.72688 1.08594 1.90641 1.90641C1.08594 2.72688 0.625 3.83968 0.625 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path\n d=\"M3.125 5C3.125 3.83968 3.32254 2.72688 3.67417 1.90641C4.02581 1.08594 4.50272 0.625 5 0.625C5.49728 0.625 5.97419 1.08594 6.32582 1.90641C6.67746 2.72688 6.875 3.83968 6.875 5C6.875 6.16032 6.67746 7.27312 6.32582 8.09359C5.97419 8.91406 5.49728 9.375 5 9.375C4.50272 9.375 4.02581 8.91406 3.67417 8.09359C3.32254 7.27312 3.125 6.16032 3.125 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path d=\"M0.9375 6.45866H9.0625M0.9375 3.54199H9.0625\" stroke=\"#9CA3AF\" stroke-width=\"0.6\"\n stroke-linecap=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_935_15847\">\n <rect width=\"10\" height=\"10\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </mat-icon>\n <mat-icon *ngIf=\"platformType === 'device'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M7.08325 0.833008H2.91659C2.45635 0.833008 2.08325 1.2061 2.08325 1.66634V8.33301C2.08325 8.79324 2.45635 9.16634 2.91659 9.16634H7.08325C7.54349 9.16634 7.91658 8.79324 7.91658 8.33301V1.66634C7.91658 1.2061 7.54349 0.833008 7.08325 0.833008Z\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.5H5.00417\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </mat-icon>\n <p class=\"cqa-text-sm !cqa-text-[10px] cqa-text-[#6B7280] cqa-ml-2\">{{ platformName }}</p>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <cqa-segment-control \n [segments]=\"segments\" \n [value]=\"currentView\"\n (valueChange)=\"onSegmentChange($event)\">\n </cqa-segment-control>\n \n <div *ngIf=\"!isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Expand\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M6.25 1.25H8.75V3.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.74992 1.25L5.83325 4.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 8.74967L4.16667 5.83301\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3.75 8.75H1.25V6.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <div *ngIf=\"isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Exit full screen\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M8.75 6.25H6.25V8.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.25008 6.25L9.16675 9.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M0.833252 0.833008L3.74992 3.74967\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 3.75H3.75V1.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n </div>\n </div>\n <div class=\"cqa-w-full cqa-bg-[#F3F4F6] cqa-h-[calc(100%-41px)]\">\n <div *ngIf=\"currentView === 'video'\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center\">\n <div class=\"cqa-w-full cqa-py-4 cqa-flex cqa-items-center cqa-max-h-[calc(100%-35px)]\" *ngIf=\"videoUrl\" [ngClass]=\"{'!cqa-h-full': platformType === 'device'}\">\n <video\n #vplayer\n class=\"cqa-object-contain cqa-w-full cqa-min-h-[250px] cqa-max-h-full cqa-block cqa-bg-black\"\n [src]=\"videoUrl\"\n type=\"video/webm\"\n (loadedmetadata)=\"onVideoMetadataLoaded()\"\n (canplay)=\"onVideoCanPlay()\"\n ></video>\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!videoUrl\">\n No video recording found\n </div>\n \n <div class=\"cqa-px-2 cqa-py-2 cqa-bg-white\" style=\"border-top: 1px solid #E5E7EB;\" *ngIf=\"videoUrl\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button \n type=\"button\"\n class=\"cqa-bg-transparent cqa-border-none cqa-cursor-pointer !cqa-px-0 cqa-flex cqa-items-center cqa-justify-center hover:cqa-opacity-70 cqa-transition-opacity cqa-outline-none\"\n style=\"pointer-events: auto;\"\n (click)=\"togglePlay()\">\n <span *ngIf=\"!isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 2L13 8L3 14V2Z\" fill=\"#374151\"/>\n </svg>\n </span>\n <span *ngIf=\"isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"3\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n <rect x=\"10\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n </svg>\n </span>\n </button>\n \n <span class=\"cqa-text-[#9CA3AF] cqa-text-[9px] cqa-font-normal cqa-whitespace-nowrap cqa-select-none cqa-mr-[20px]\">\n {{ formatTime(vplayer?.nativeElement?.currentTime || 0) }}\n </span>\n \n <div \n #timelineBar\n class=\"cqa-relative cqa-h-1 cqa-bg-gray-200 cqa-rounded-full cqa-cursor-pointer cqa-flex-1\"\n (click)=\"onTimelineClick($event)\" \n (mousemove)=\"onDrag($event)\"\n (mouseup)=\"stopDrag()\" \n (mouseleave)=\"stopDrag()\">\n \n <div \n *ngFor=\"let step of stepMarkers\" \n class=\"cqa-absolute cqa-w-1 cqa-h-full cqa-top-0 cqa-rounded-sm\"\n [style.left.%]=\"getStepLeftPosition(step)\"\n [style.background]=\"getStepColor(step)\"\n style=\"pointer-events: none; z-index: 20;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-h-full cqa-bg-green-500 cqa-rounded-full cqa-transition-[width] cqa-duration-100\"\n [style.width.%]=\"progress\"\n style=\"pointer-events: none; z-index: 2;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-top-1/2 cqa-w-3 cqa-h-3 cqa-bg-green-600 cqa-rounded-full cqa-cursor-grab active:cqa-cursor-grabbing cqa-shadow-md\"\n [style.left.%]=\"progress\"\n style=\"transform: translate(-50%, -50%); z-index: 10;\"\n (mousedown)=\"startDrag()\">\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"currentView === 'screenshots'\" class=\"cqa-h-full\">\n <div class=\"cqa-w-full cqa-py-4 cqa-h-full cqa-flex cqa-items-center\" *ngIf=\"screenShotUrl\">\n <img\n [src]=\"screenShotUrl\"\n alt=\"Screenshot\"\n class=\"cqa-object-contain cqa-w-full cqa-max-h-full cqa-block cqa-bg-black cqa-mx-auto\"\n />\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!screenShotUrl\">\n No screenshot available\n </div>\n </div>\n </div>\n</div>", styles: [] }]
7345
- }], propDecorators: { videoUrl: [{
7483
+ args: [{ selector: 'cqa-simulator', template: "<div class=\"cqa-ui-root\" style=\"background-color: #F3F4F6; height: 100%; display: flex; flex-direction: column;\" [ngStyle]=\"{\n position: isFullScreen ? 'fixed' : null,\n inset: isFullScreen ? '1rem' : null,\n zIndex: isFullScreen ? '50' : null,\n boxShadow: isFullScreen ? '0px 13px 25px -12px rgba(0, 0, 0, 0.25)' : null,\n borderRadius: isFullScreen ? '.5rem' : null,\n border: isFullScreen ? '1px solid #E5E7EB' : null,\n width: isFullScreen ? 'calc(100% - 32px)' : null,\n height: isFullScreen ? 'calc(100% - 32px)' : '100%',\n overflow: isFullScreen ? 'hidden' : null\n}\">\n <div class=\"cqa-w-full cqa-py-1 cqa-px-2 cqa-bg-[#FFFFFF]\" style=\"border-bottom: 1px solid #E5E7EB;box-shadow: 0px 1px 2px 0px #0000000D;\">\n <div class=\"cqa-w-full cqa-flex cqa-items-center cqa-justify-between\">\n <div class=\"cqa-flex cqa-items-center\">\n <div *ngIf=\"isLive\" class=\"cqa-h-[21px] cqa-inline-flex cqa-items-center cqa-gap-1.5 cqa-mr-2 cqa-px-[9px] cqa-py-[3px] cqa-bg-[#FCD9D9] cqa-rounded-[6px]\" style=\"border: 1px solid #F9BFBF;\">\n <span class=\"cqa-relative cqa-w-2 cqa-h-2 cqa-rounded-full cqa-bg-[#F47F7F]\" style=\"flex-shrink: 0;\">\n <span class=\"cqa-absolute cqa-inset-0 cqa-rounded-full cqa-bg-[#F47F7F] cqa-opacity-75 cqa-animate-ping\"></span>\n </span>\n <span class=\"cqa-text-[10px] cqa-font-medium cqa-text-[#C63535] cqa-leading-[15px]\">Live</span>\n </div>\n <mat-icon *ngIf=\"platformType === 'browser'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <g clip-path=\"url(#clip0_935_15847)\">\n <path\n d=\"M0.625 5C0.625 6.16032 1.08594 7.27312 1.90641 8.09359C2.72688 8.91406 3.83968 9.375 5 9.375C6.16032 9.375 7.27312 8.91406 8.09359 8.09359C8.91406 7.27312 9.375 6.16032 9.375 5C9.375 3.83968 8.91406 2.72688 8.09359 1.90641C7.27312 1.08594 6.16032 0.625 5 0.625C3.83968 0.625 2.72688 1.08594 1.90641 1.90641C1.08594 2.72688 0.625 3.83968 0.625 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path\n d=\"M3.125 5C3.125 3.83968 3.32254 2.72688 3.67417 1.90641C4.02581 1.08594 4.50272 0.625 5 0.625C5.49728 0.625 5.97419 1.08594 6.32582 1.90641C6.67746 2.72688 6.875 3.83968 6.875 5C6.875 6.16032 6.67746 7.27312 6.32582 8.09359C5.97419 8.91406 5.49728 9.375 5 9.375C4.50272 9.375 4.02581 8.91406 3.67417 8.09359C3.32254 7.27312 3.125 6.16032 3.125 5Z\"\n stroke=\"#9CA3AF\" stroke-width=\"0.6\" stroke-linejoin=\"round\" />\n <path d=\"M0.9375 6.45866H9.0625M0.9375 3.54199H9.0625\" stroke=\"#9CA3AF\" stroke-width=\"0.6\"\n stroke-linecap=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_935_15847\">\n <rect width=\"10\" height=\"10\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </mat-icon>\n <mat-icon *ngIf=\"platformType === 'device'\" style=\"width: 10px; height: 10px;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M7.08325 0.833008H2.91659C2.45635 0.833008 2.08325 1.2061 2.08325 1.66634V8.33301C2.08325 8.79324 2.45635 9.16634 2.91659 9.16634H7.08325C7.54349 9.16634 7.91658 8.79324 7.91658 8.33301V1.66634C7.91658 1.2061 7.54349 0.833008 7.08325 0.833008Z\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.5H5.00417\" stroke=\"#6B7280\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </mat-icon>\n <p class=\"cqa-text-sm !cqa-text-[10px] cqa-text-[#6B7280] cqa-ml-2\">{{ platformName }}</p>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div *ngIf=\"isLive\" [ngClass]=\"getStatusBadgeClass()\">\n <span [ngClass]=\"getStatusTextClass()\">{{ liveStatus }}</span>\n </div>\n\n <ng-container *ngIf=\"!isLive\">\n <cqa-segment-control \n [segments]=\"segments\" \n [value]=\"currentView\"\n (valueChange)=\"onSegmentChange($event)\">\n </cqa-segment-control>\n \n <div *ngIf=\"!isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Expand\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M6.25 1.25H8.75V3.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8.74992 1.25L5.83325 4.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 8.74967L4.16667 5.83301\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M3.75 8.75H1.25V6.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <div *ngIf=\"isFullScreen\" \n class=\"cqa-p-1 cqa-cursor-pointer hover:cqa-bg-gray-100 cqa-rounded-sm cqa-transition-colors\"\n (click)=\"toggleFullScreen()\"\n title=\"Exit full screen\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\">\n <path d=\"M8.75 6.25H6.25V8.75\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.25008 6.25L9.16675 9.16667\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M0.833252 0.833008L3.74992 3.74967\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M1.25 3.75H3.75V1.25\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"cqa-w-full cqa-bg-[#F3F4F6] cqa-h-[calc(100%-41px)]\">\n <!-- Live Content View -->\n <div *ngIf=\"isLive\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center cqa-relative\">\n <!-- Loading State -->\n <div *ngIf=\"isContentVideoLoading\" class=\"cqa-p-10 cqa-text-center cqa-h-full cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <div class=\"cqa-mb-4\">\n <mat-progress-spinner mode=\"indeterminate\" diameter=\"40\"></mat-progress-spinner>\n </div>\n <p class=\"cqa-text-gray-400 cqa-text-sm\">{{ liveLoadingLabel }}</p>\n </div>\n\n <!-- Live Content (when not loading) -->\n <div *ngIf=\"!isContentVideoLoading\" class=\"cqa-w-full cqa-h-full cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-relative\">\n <div *ngIf=\"liveStatus === 'Failed' && failedStatusMessage\" class=\"cqa-p-6 cqa-text-center cqa-w-full\">\n <div class=\"cqa-inline-flex cqa-items-center cqa-gap-2 cqa-px-4 cqa-py-3 cqa-bg-[#FCD9D9] cqa-border cqa-border-[#F9BFBF] cqa-rounded-lg\">\n <mat-icon style=\"width: 18px; height: 18px; color: #C63535; font-size: 18px;\">error</mat-icon>\n <p class=\"cqa-text-[#C63535] cqa-text-sm cqa-font-medium cqa-m-0\">{{ failedStatusMessage }}</p>\n </div>\n </div>\n <ng-content *ngIf=\"liveStatus !== 'Failed' || !failedStatusMessage\"></ng-content>\n </div>\n </div>\n\n <!-- Normal Video View (when not live) -->\n <div *ngIf=\"!isLive && currentView === 'video'\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center\">\n <div class=\"cqa-w-full cqa-py-4 cqa-flex cqa-items-center cqa-max-h-[calc(100%-35px)]\" *ngIf=\"videoUrl\" [ngClass]=\"{'!cqa-h-full': platformType === 'device'}\">\n <video\n #vplayer\n class=\"cqa-object-contain cqa-w-full cqa-min-h-[250px] cqa-max-h-full cqa-block cqa-bg-black\"\n [src]=\"videoUrl\"\n type=\"video/webm\"\n (loadedmetadata)=\"onVideoMetadataLoaded()\"\n (canplay)=\"onVideoCanPlay()\"\n (ended)=\"onVideoEnded()\"\n ></video>\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!videoUrl\">\n No video recording found\n </div>\n \n <div class=\"cqa-px-2 cqa-py-2 cqa-bg-white\" style=\"border-top: 1px solid #E5E7EB;\" *ngIf=\"videoUrl && !isLive\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <button \n type=\"button\"\n class=\"cqa-bg-transparent cqa-border-none cqa-cursor-pointer !cqa-px-0 cqa-flex cqa-items-center cqa-justify-center hover:cqa-opacity-70 cqa-transition-opacity cqa-outline-none\"\n style=\"pointer-events: auto;\"\n (click)=\"togglePlay()\">\n <span *ngIf=\"!isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 2L13 8L3 14V2Z\" fill=\"#374151\"/>\n </svg>\n </span>\n <span *ngIf=\"isPlaying\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"3\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n <rect x=\"10\" y=\"2\" width=\"3\" height=\"12\" fill=\"#374151\"/>\n </svg>\n </span>\n </button>\n \n <span class=\"cqa-text-[#9CA3AF] cqa-text-[9px] cqa-font-normal cqa-whitespace-nowrap cqa-select-none cqa-mr-[20px]\">\n {{ formatTime(vplayer?.nativeElement?.currentTime || 0) }}\n </span>\n \n <div \n #timelineBar\n class=\"cqa-relative cqa-h-1 cqa-bg-gray-200 cqa-rounded-full cqa-cursor-pointer cqa-flex-1\"\n (click)=\"onTimelineClick($event)\">\n \n <div \n *ngFor=\"let step of stepMarkers\" \n class=\"cqa-absolute cqa-w-1 cqa-h-full cqa-top-0 cqa-rounded-sm\"\n [style.left.%]=\"getStepLeftPosition(step)\"\n [style.background]=\"getStepColor(step)\"\n style=\"pointer-events: none; z-index: 20;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-h-full cqa-bg-green-500 cqa-rounded-full\"\n [style.width.%]=\"progress\"\n [style.transition]=\"dragging ? 'none' : 'width 100ms'\"\n style=\"pointer-events: none; z-index: 2;\">\n </div>\n \n <div \n class=\"cqa-absolute cqa-top-1/2 cqa-w-3 cqa-h-3 cqa-bg-green-600 cqa-rounded-full cqa-cursor-grab active:cqa-cursor-grabbing cqa-shadow-md\"\n [style.left.%]=\"progress\"\n style=\"transform: translate(-50%, -50%); z-index: 10;\"\n (mousedown)=\"startDrag($event)\">\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!isLive && currentView === 'screenshots'\" class=\"cqa-h-full\">\n <div class=\"cqa-w-full cqa-py-4 cqa-h-full cqa-flex cqa-items-center\" *ngIf=\"screenShotUrl\">\n <img\n [src]=\"screenShotUrl\"\n alt=\"Screenshot\"\n class=\"cqa-object-contain cqa-w-full cqa-max-h-full cqa-block cqa-bg-black cqa-mx-auto\"\n />\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!screenShotUrl\">\n No screenshot available\n </div>\n </div>\n\n <div *ngIf=\"!isLive && currentView === 'trace'\" class=\"cqa-h-full cqa-flex cqa-flex-col cqa-justify-center\">\n <div class=\"cqa-w-full cqa-h-full cqa-py-4 cqa-flex cqa-items-center cqa-max-h-[calc(100%-35px)] cqa-relative\" *ngIf=\"traceViewUrl\" [ngClass]=\"{'!cqa-h-full': platformType === 'device'}\">\n <iframe \n [src]=\"safeTraceUrl\" \n title=\"Trace Viewer\"\n class=\"cqa-object-contain cqa-w-full cqa-min-h-[250px] cqa-max-h-full cqa-block cqa-bg-black\"\n frameborder=\"0\"\n allowfullscreen\n width=\"100%\"\n height=\"100%\"\n loading=\"lazy\"\n (load)=\"onTraceViewerLoad()\"\n (error)=\"onTraceViewerError()\">\n </iframe>\n \n <div *ngIf=\"traceViewerLoading\" class=\"cqa-absolute cqa-inset-0 cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center cqa-z-10\">\n <div class=\"cqa-text-center cqa-text-gray-400 cqa-text-sm\">\n Loading trace viewer...\n </div>\n </div>\n \n <div *ngIf=\"traceViewerError\" class=\"cqa-absolute cqa-inset-0 cqa-bg-[#F3F4F6] cqa-flex cqa-items-center cqa-justify-center cqa-z-10\">\n <div class=\"cqa-text-center cqa-text-gray-400 cqa-text-sm\">\n Failed to load trace viewer\n </div>\n </div>\n </div>\n \n <div class=\"cqa-p-10 cqa-text-center cqa-text-gray-400 cqa-text-sm cqa-h-full cqa-flex cqa-items-center cqa-justify-center\" *ngIf=\"!traceViewUrl\">\n No trace available\n </div>\n </div>\n </div>\n</div>", styles: [] }]
7484
+ }], ctorParameters: function () { return [{ type: i1$2.DomSanitizer }]; }, propDecorators: { videoUrl: [{
7346
7485
  type: Input
7347
7486
  }], videoCurrentDuration: [{
7348
7487
  type: Input
@@ -7350,12 +7489,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
7350
7489
  type: Input
7351
7490
  }], screenShotUrl: [{
7352
7491
  type: Input
7492
+ }], traceViewUrl: [{
7493
+ type: Input
7353
7494
  }], platformName: [{
7354
7495
  type: Input
7355
7496
  }], platformType: [{
7356
7497
  type: Input
7357
7498
  }], isLive: [{
7358
7499
  type: Input
7500
+ }], liveStatus: [{
7501
+ type: Input
7502
+ }], liveLoadingLabel: [{
7503
+ type: Input
7504
+ }], isContentVideoLoading: [{
7505
+ type: Input
7506
+ }], failedStatusMessage: [{
7507
+ type: Input
7508
+ }], selectedView: [{
7509
+ type: Input
7359
7510
  }], videoTimeUpdate: [{
7360
7511
  type: Output
7361
7512
  }], videoPlay: [{
@@ -8841,10 +8992,10 @@ class ProgressIndicatorComponent {
8841
8992
  }
8842
8993
  }
8843
8994
  ProgressIndicatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ProgressIndicatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8844
- ProgressIndicatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ProgressIndicatorComponent, selector: "cqa-progress-indicator", inputs: { variant: "variant", label: "label", icon: "icon", value: "value", progress: "progress", size: "size", strokeWidth: "strokeWidth" }, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-p-[21px] cqa-transition-colors cqa-w-1/2 cqa-rounded-xl cqa-bg-surface-default\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Progress Spinner SVG -->\n <div class=\"cqa-flex-shrink-0\" *ngIf=\"variant === 'progress' && !icon\">\n <svg \n [attr.width]=\"size\" \n [attr.height]=\"size\" \n class=\"cqa-transform cqa--rotate-90\"\n style=\"overflow: visible;\">\n <!-- Background circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n stroke=\"#D8D9FC\"\n [attr.stroke-width]=\"strokeWidth\"\n />\n <!-- Progress circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n [attr.stroke]=\"color\"\n [attr.stroke-width]=\"strokeWidth\"\n [attr.stroke-dasharray]=\"circleStyles.strokeDasharray\"\n [attr.stroke-dashoffset]=\"circleStyles.strokeDashoffset\"\n stroke-linecap=\"round\"\n class=\"cqa-transition-all cqa-duration-300 cqa-ease-in-out\"\n />\n </svg>\n </div>\n <div class=\"cqa-flex-shrink-0\" *ngIf=\"icon\">\n <mat-icon class=\"cqa-text-primary\">{{ icon }}</mat-icon>\n </div>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary-hover\">\n {{ label }}\n </span>\n <span *ngIf=\"variant === 'progress'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ progress }}%\n </span>\n <span *ngIf=\"variant === 'elapsed-time'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ value }}\n </span>\n </div>\n </div>\n</div>", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
8995
+ ProgressIndicatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ProgressIndicatorComponent, selector: "cqa-progress-indicator", inputs: { variant: "variant", label: "label", icon: "icon", value: "value", progress: "progress", size: "size", strokeWidth: "strokeWidth" }, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-p-[21px] cqa-transition-colors cqa-rounded-xl cqa-bg-surface-default\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Progress Spinner SVG -->\n <div class=\"cqa-flex-shrink-0\" *ngIf=\"variant === 'progress' && !icon\">\n <svg \n [attr.width]=\"size\" \n [attr.height]=\"size\" \n class=\"cqa-transform cqa--rotate-90\"\n style=\"overflow: visible;\">\n <!-- Background circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n stroke=\"#D8D9FC\"\n [attr.stroke-width]=\"strokeWidth\"\n />\n <!-- Progress circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n [attr.stroke]=\"color\"\n [attr.stroke-width]=\"strokeWidth\"\n [attr.stroke-dasharray]=\"circleStyles.strokeDasharray\"\n [attr.stroke-dashoffset]=\"circleStyles.strokeDashoffset\"\n stroke-linecap=\"round\"\n class=\"cqa-transition-all cqa-duration-300 cqa-ease-in-out\"\n />\n </svg>\n </div>\n <mat-icon *ngIf=\"icon\" class=\"cqa-text-primary !cqa-text-[32px] cqa-w-[32px] cqa-h-[32px]\">{{ icon }}</mat-icon>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary-hover\">\n {{ label }}\n </span>\n <span *ngIf=\"variant === 'progress'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ progress }}%\n </span>\n <span *ngIf=\"variant === 'elapsed-time'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ value }}\n </span>\n </div>\n </div>\n</div>", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
8845
8996
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ProgressIndicatorComponent, decorators: [{
8846
8997
  type: Component,
8847
- args: [{ selector: 'cqa-progress-indicator', template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-p-[21px] cqa-transition-colors cqa-w-1/2 cqa-rounded-xl cqa-bg-surface-default\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Progress Spinner SVG -->\n <div class=\"cqa-flex-shrink-0\" *ngIf=\"variant === 'progress' && !icon\">\n <svg \n [attr.width]=\"size\" \n [attr.height]=\"size\" \n class=\"cqa-transform cqa--rotate-90\"\n style=\"overflow: visible;\">\n <!-- Background circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n stroke=\"#D8D9FC\"\n [attr.stroke-width]=\"strokeWidth\"\n />\n <!-- Progress circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n [attr.stroke]=\"color\"\n [attr.stroke-width]=\"strokeWidth\"\n [attr.stroke-dasharray]=\"circleStyles.strokeDasharray\"\n [attr.stroke-dashoffset]=\"circleStyles.strokeDashoffset\"\n stroke-linecap=\"round\"\n class=\"cqa-transition-all cqa-duration-300 cqa-ease-in-out\"\n />\n </svg>\n </div>\n <div class=\"cqa-flex-shrink-0\" *ngIf=\"icon\">\n <mat-icon class=\"cqa-text-primary\">{{ icon }}</mat-icon>\n </div>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary-hover\">\n {{ label }}\n </span>\n <span *ngIf=\"variant === 'progress'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ progress }}%\n </span>\n <span *ngIf=\"variant === 'elapsed-time'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ value }}\n </span>\n </div>\n </div>\n</div>", styles: [] }]
8998
+ args: [{ selector: 'cqa-progress-indicator', template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-p-[21px] cqa-transition-colors cqa-rounded-xl cqa-bg-surface-default\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Progress Spinner SVG -->\n <div class=\"cqa-flex-shrink-0\" *ngIf=\"variant === 'progress' && !icon\">\n <svg \n [attr.width]=\"size\" \n [attr.height]=\"size\" \n class=\"cqa-transform cqa--rotate-90\"\n style=\"overflow: visible;\">\n <!-- Background circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n stroke=\"#D8D9FC\"\n [attr.stroke-width]=\"strokeWidth\"\n />\n <!-- Progress circle -->\n <circle\n [attr.cx]=\"circleStyles.cx\"\n [attr.cy]=\"circleStyles.cy\"\n [attr.r]=\"circleStyles.r\"\n fill=\"none\"\n [attr.stroke]=\"color\"\n [attr.stroke-width]=\"strokeWidth\"\n [attr.stroke-dasharray]=\"circleStyles.strokeDasharray\"\n [attr.stroke-dashoffset]=\"circleStyles.strokeDashoffset\"\n stroke-linecap=\"round\"\n class=\"cqa-transition-all cqa-duration-300 cqa-ease-in-out\"\n />\n </svg>\n </div>\n <mat-icon *ngIf=\"icon\" class=\"cqa-text-primary !cqa-text-[32px] cqa-w-[32px] cqa-h-[32px]\">{{ icon }}</mat-icon>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary-hover\">\n {{ label }}\n </span>\n <span *ngIf=\"variant === 'progress'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ progress }}%\n </span>\n <span *ngIf=\"variant === 'elapsed-time'\" class=\"cqa-text-2xl cqa-font-bold cqa-leading-tight cqa-tracking-[-0.2px] cqa-text-primary\">\n {{ value }}\n </span>\n </div>\n </div>\n</div>", styles: [] }]
8848
8999
  }], propDecorators: { variant: [{
8849
9000
  type: Input
8850
9001
  }], label: [{
@@ -8865,7 +9016,6 @@ class StepProgressCardComponent {
8865
9016
  constructor() {
8866
9017
  this.currentStep = 4;
8867
9018
  this.totalSteps = 6;
8868
- this.subText = 'This may take up to 30s. Preparing environment and dependencies...';
8869
9019
  }
8870
9020
  get progressPercentage() {
8871
9021
  return (this.currentStep / this.totalSteps) * 100;
@@ -8875,10 +9025,10 @@ class StepProgressCardComponent {
8875
9025
  }
8876
9026
  }
8877
9027
  StepProgressCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepProgressCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8878
- StepProgressCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepProgressCardComponent, selector: "cqa-step-progress-card", inputs: { currentStep: "currentStep", totalSteps: "totalSteps", subText: "subText" }, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-px-[25px] cqa-py-3 cqa-rounded-[14px] cqa-bg-surface-default cqa-flex cqa-flex-col cqa-gap-2 cqa-relative cqa-shadow\"\n [ngStyle]=\"{ border: '1px solid #E5E7EB' }\">\n <!-- Card Header with Title and Step Info -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-gap-2\">\n <span class=\"cqa-font-normal cqa-text-base cqa-leading-6 cqa-text-[#364153]\">Setup Progress</span>\n <span class=\"cqa-font-normal cqa-text-sm cqa-leading-[18px] cqa-text-metadata-key\">{{ stepText }}</span>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-full cqa-h-[10px] cqa-rounded-full cqa-bg-primary-surface cqa-overflow-hidden cqa-relative\">\n <div \n class=\"cqa-h-full cqa-bg-primary cqa-rounded-full cqa-transition-all cqa-duration-300 cqa-ease-in-out\" \n [style.width.%]=\"progressPercentage\">\n </div>\n </div>\n </div>\n\n <!-- Sub Text -->\n <div class=\"cqa-font-normal cqa-text-xs cqa-text-metadata-key cqa-mt-2 cqa-truncate cqa-whitespace-nowrap cqa-leading-tight\">\n {{ subText }}\n </div>\n </div>\n</div>\n", directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
9028
+ StepProgressCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepProgressCardComponent, selector: "cqa-step-progress-card", inputs: { currentStep: "currentStep", totalSteps: "totalSteps", subText: "subText" }, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-px-[25px] cqa-py-3 cqa-rounded-[14px] cqa-bg-surface-default cqa-flex cqa-flex-col cqa-relative cqa-shadow\"\n [ngStyle]=\"{ border: '1px solid #E5E7EB' }\">\n <!-- Card Header with Title and Step Info -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-font-normal cqa-text-base cqa-leading-6 cqa-text-[#364153]\">Setup Progress</span>\n <span class=\"cqa-font-normal cqa-text-sm cqa-leading-[18px] cqa-text-metadata-key\">{{ stepText }}</span>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-1\">\n <div class=\"cqa-w-full cqa-h-[10px] cqa-rounded-full cqa-bg-primary-surface cqa-overflow-hidden cqa-relative\">\n <div \n class=\"cqa-h-full cqa-bg-primary cqa-rounded-full cqa-transition-all cqa-duration-300 cqa-ease-in-out\" \n [style.width.%]=\"progressPercentage\">\n </div>\n </div>\n </div>\n\n <!-- Sub Text -->\n <div *ngIf=\"subText\" class=\"cqa-font-normal cqa-text-xs cqa-text-metadata-key cqa-mt-1 cqa-truncate cqa-whitespace-nowrap cqa-leading-tight\">\n {{ subText }}\n </div>\n </div>\n</div>\n", directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
8879
9029
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepProgressCardComponent, decorators: [{
8880
9030
  type: Component,
8881
- args: [{ selector: 'cqa-step-progress-card', template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-px-[25px] cqa-py-3 cqa-rounded-[14px] cqa-bg-surface-default cqa-flex cqa-flex-col cqa-gap-2 cqa-relative cqa-shadow\"\n [ngStyle]=\"{ border: '1px solid #E5E7EB' }\">\n <!-- Card Header with Title and Step Info -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-gap-2\">\n <span class=\"cqa-font-normal cqa-text-base cqa-leading-6 cqa-text-[#364153]\">Setup Progress</span>\n <span class=\"cqa-font-normal cqa-text-sm cqa-leading-[18px] cqa-text-metadata-key\">{{ stepText }}</span>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div class=\"cqa-w-full cqa-h-[10px] cqa-rounded-full cqa-bg-primary-surface cqa-overflow-hidden cqa-relative\">\n <div \n class=\"cqa-h-full cqa-bg-primary cqa-rounded-full cqa-transition-all cqa-duration-300 cqa-ease-in-out\" \n [style.width.%]=\"progressPercentage\">\n </div>\n </div>\n </div>\n\n <!-- Sub Text -->\n <div class=\"cqa-font-normal cqa-text-xs cqa-text-metadata-key cqa-mt-2 cqa-truncate cqa-whitespace-nowrap cqa-leading-tight\">\n {{ subText }}\n </div>\n </div>\n</div>\n", styles: [] }]
9031
+ args: [{ selector: 'cqa-step-progress-card', template: "<div class=\"cqa-ui-root\">\n <div class=\"cqa-px-[25px] cqa-py-3 cqa-rounded-[14px] cqa-bg-surface-default cqa-flex cqa-flex-col cqa-relative cqa-shadow\"\n [ngStyle]=\"{ border: '1px solid #E5E7EB' }\">\n <!-- Card Header with Title and Step Info -->\n <div class=\"cqa-flex cqa-justify-between cqa-items-center cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-font-normal cqa-text-base cqa-leading-6 cqa-text-[#364153]\">Setup Progress</span>\n <span class=\"cqa-font-normal cqa-text-sm cqa-leading-[18px] cqa-text-metadata-key\">{{ stepText }}</span>\n </div>\n\n <!-- Progress Bar -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-1\">\n <div class=\"cqa-w-full cqa-h-[10px] cqa-rounded-full cqa-bg-primary-surface cqa-overflow-hidden cqa-relative\">\n <div \n class=\"cqa-h-full cqa-bg-primary cqa-rounded-full cqa-transition-all cqa-duration-300 cqa-ease-in-out\" \n [style.width.%]=\"progressPercentage\">\n </div>\n </div>\n </div>\n\n <!-- Sub Text -->\n <div *ngIf=\"subText\" class=\"cqa-font-normal cqa-text-xs cqa-text-metadata-key cqa-mt-1 cqa-truncate cqa-whitespace-nowrap cqa-leading-tight\">\n {{ subText }}\n </div>\n </div>\n</div>\n", styles: [] }]
8882
9032
  }], propDecorators: { currentStep: [{
8883
9033
  type: Input
8884
9034
  }], totalSteps: [{
@@ -8892,6 +9042,7 @@ class StepStatusCardComponent {
8892
9042
  this.title = '';
8893
9043
  this.description = '';
8894
9044
  this.type = 'waiting';
9045
+ this.icon = '';
8895
9046
  }
8896
9047
  get statusConfig() {
8897
9048
  const configs = {
@@ -8910,7 +9061,7 @@ class StepStatusCardComponent {
8910
9061
  iconColor: '#1B1FEB',
8911
9062
  statusColor: '#1216CC',
8912
9063
  statusBgColor: '#D8D9FC',
8913
- icon: 'autorenew',
9064
+ icon: '',
8914
9065
  label: 'Running'
8915
9066
  },
8916
9067
  waiting: {
@@ -8926,17 +9077,18 @@ class StepStatusCardComponent {
8926
9077
  return configs[this.type];
8927
9078
  }
8928
9079
  get cardStyles() {
9080
+ var _a, _b;
8929
9081
  return {
8930
- 'border': '1px solid ' + this.statusConfig.borderColor,
8931
- 'background-color': this.statusConfig.bgColor
9082
+ 'border': '1px solid ' + (((_a = this.statusConfig) === null || _a === void 0 ? void 0 : _a.borderColor) || '#E5E7EB'),
9083
+ 'background-color': (((_b = this.statusConfig) === null || _b === void 0 ? void 0 : _b.bgColor) || '#FFFFFF')
8932
9084
  };
8933
9085
  }
8934
9086
  }
8935
9087
  StepStatusCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepStatusCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8936
- StepStatusCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepStatusCardComponent, selector: "cqa-step-status-card", inputs: { title: "title", description: "description", type: "type", icon: "icon" }, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-p-4 cqa-rounded-[14px] cqa-shadow cqa-flex cqa-items-center cqa-justify-between cqa-transition-all\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Left Section: Icon and Text -->\n <div class=\"cqa-flex cqa-items-start cqa-gap-3 cqa-flex-1\">\n <!-- Icon -->\n <div class=\"cqa-flex-shrink-0 cqa-mt-1\">\n <mat-icon \n class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\"\n [ngStyle]=\"{ color: statusConfig.iconColor }\">\n {{ icon || statusConfig.icon }}\n </mat-icon>\n </div>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-base cqa-leading-6 cqa-text-[#101828] cqa-tracking-normal\">\n {{ title }}\n </span>\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-[18px] cqa-text-[#4A5565] cqa-tracking-normal\">\n {{ description }}\n </span>\n </div>\n </div>\n \n <!-- Right Section: Status Badge -->\n <div class=\"cqa-flex-shrink-0\">\n <span \n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-leading-4 cqa-tracking-normal\"\n [ngStyle]=\"{ color: statusConfig.statusColor, backgroundColor: statusConfig.statusBgColor}\">\n {{ statusConfig.label }}\n </span>\n </div>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
9088
+ StepStatusCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StepStatusCardComponent, selector: "cqa-step-status-card", inputs: { title: "title", description: "description", type: "type", icon: "icon" }, ngImport: i0, template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-p-4 cqa-rounded-[14px] cqa-shadow cqa-flex cqa-items-center cqa-justify-between cqa-transition-all\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Left Section: Icon and Text -->\n <div class=\"cqa-flex cqa-items-start cqa-gap-3 cqa-flex-1\">\n <!-- Icon -->\n <div class=\"cqa-mt-1\">\n <mat-icon \n *ngIf=\"icon || statusConfig?.icon\"\n class=\"!cqa-text-[20px] cqa-w-[20px] cqa-h-[20px]\"\n [ngClass]=\"{ 'cqa-animate-spin': type === 'running' }\"\n [ngStyle]=\"{ color: statusConfig?.iconColor }\">\n {{ icon || statusConfig?.icon }}\n </mat-icon>\n\n <svg *ngIf=\"type === 'running' && !icon\" class=\"cqa-animate-spin\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" \n fill=\"none\" [attr.stroke]=\"statusConfig?.iconColor\" stroke-width=\"2\">\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\"></path>\n </svg>\n </div>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-base cqa-leading-6 cqa-text-[#101828] cqa-tracking-normal\">\n {{ title }}\n </span>\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-[18px] cqa-text-[#4A5565] cqa-tracking-normal\">\n {{ description }}\n </span>\n </div>\n </div>\n \n <!-- Right Section: Status Badge -->\n <div class=\"cqa-flex-shrink-0\">\n <span \n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-leading-4 cqa-tracking-normal\"\n [ngStyle]=\"{ color: statusConfig?.statusColor, backgroundColor: statusConfig?.statusBgColor}\">\n {{ statusConfig?.label }}\n </span>\n </div>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
8937
9089
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StepStatusCardComponent, decorators: [{
8938
9090
  type: Component,
8939
- args: [{ selector: 'cqa-step-status-card', template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-p-4 cqa-rounded-[14px] cqa-shadow cqa-flex cqa-items-center cqa-justify-between cqa-transition-all\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Left Section: Icon and Text -->\n <div class=\"cqa-flex cqa-items-start cqa-gap-3 cqa-flex-1\">\n <!-- Icon -->\n <div class=\"cqa-flex-shrink-0 cqa-mt-1\">\n <mat-icon \n class=\"cqa-text-[20px] cqa-w-5 cqa-h-5\"\n [ngStyle]=\"{ color: statusConfig.iconColor }\">\n {{ icon || statusConfig.icon }}\n </mat-icon>\n </div>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-base cqa-leading-6 cqa-text-[#101828] cqa-tracking-normal\">\n {{ title }}\n </span>\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-[18px] cqa-text-[#4A5565] cqa-tracking-normal\">\n {{ description }}\n </span>\n </div>\n </div>\n \n <!-- Right Section: Status Badge -->\n <div class=\"cqa-flex-shrink-0\">\n <span \n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-leading-4 cqa-tracking-normal\"\n [ngStyle]=\"{ color: statusConfig.statusColor, backgroundColor: statusConfig.statusBgColor}\">\n {{ statusConfig.label }}\n </span>\n </div>\n </div>\n</div>\n", styles: [] }]
9091
+ args: [{ selector: 'cqa-step-status-card', template: "<div class=\"cqa-ui-root\">\n <div \n class=\"cqa-p-4 cqa-rounded-[14px] cqa-shadow cqa-flex cqa-items-center cqa-justify-between cqa-transition-all\"\n [ngStyle]=\"cardStyles\">\n \n <!-- Left Section: Icon and Text -->\n <div class=\"cqa-flex cqa-items-start cqa-gap-3 cqa-flex-1\">\n <!-- Icon -->\n <div class=\"cqa-mt-1\">\n <mat-icon \n *ngIf=\"icon || statusConfig?.icon\"\n class=\"!cqa-text-[20px] cqa-w-[20px] cqa-h-[20px]\"\n [ngClass]=\"{ 'cqa-animate-spin': type === 'running' }\"\n [ngStyle]=\"{ color: statusConfig?.iconColor }\">\n {{ icon || statusConfig?.icon }}\n </mat-icon>\n\n <svg *ngIf=\"type === 'running' && !icon\" class=\"cqa-animate-spin\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" \n fill=\"none\" [attr.stroke]=\"statusConfig?.iconColor\" stroke-width=\"2\">\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\"></path>\n </svg>\n </div>\n \n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1\">\n <span class=\"cqa-text-base cqa-leading-6 cqa-text-[#101828] cqa-tracking-normal\">\n {{ title }}\n </span>\n <span class=\"cqa-text-sm cqa-font-normal cqa-leading-[18px] cqa-text-[#4A5565] cqa-tracking-normal\">\n {{ description }}\n </span>\n </div>\n </div>\n \n <!-- Right Section: Status Badge -->\n <div class=\"cqa-flex-shrink-0\">\n <span \n class=\"cqa-px-2 cqa-py-0.5 cqa-rounded-lg cqa-text-xs cqa-font-medium cqa-leading-4 cqa-tracking-normal\"\n [ngStyle]=\"{ color: statusConfig?.statusColor, backgroundColor: statusConfig?.statusBgColor}\">\n {{ statusConfig?.label }}\n </span>\n </div>\n </div>\n</div>\n", styles: [] }]
8940
9092
  }], propDecorators: { title: [{
8941
9093
  type: Input
8942
9094
  }], description: [{